Spring 2015 :: CSE 502 Computer Architecture
A Brief
Introduction to
SystemVerilog
Instructor: Nima Honarmand
(Slides adapted from Prof. Milders ESE-507 course)
Spring 2015 :: CSE 502 Computer Architecture
First Things First
Assume you are familiar with the basics of digital
logic design
If not, you can read Appendix A of Hamacher et al.
SystemVerilog is a superset of another HDL: Verilog
Familiarity with Verilog (or even VHDL) helps a lot
Useful SystemVerilog resources and tutorials on the
course project web page
Including a link to a good Verilog tutorial
Spring 2015 :: CSE 502 Computer Architecture
Hardware Description Languages
Used for a variety of purposes in hardware design
High-level behavioral modeling
Register Transfer Level (RTL) behavioral modeling
Gate and transistor level netlists
Timing models for timing simulation
Design verification and testbench development
Many different features to accommodate all of these
We focus on RTL modeling for the course project
Much simpler than designing with gates
Still, helps you think like a hardware designer
Spring 2015 :: CSE 502 Computer Architecture
HDLs vs. Programming Languages
Have syntactically similar constructs:
Data types, variables, assignments, if statements, loops,
But very different mentality and semantic model:
everything runs in parallel, unless specified otherwise
Statement model hardware
Hardware is inherently parallel
Software programs are composed of subroutines(mostly)
Subroutines call each other
when in a callee, the callers execution is paused
Hardware descriptions are composed of modules (mostly)
A hierarchy of modules connected to each other
Modules are active at the same time
Spring 2015 :: CSE 502 Computer Architecture
Modules
The basic building block in SystemVerilog
Interfaces with outside using ports
Ports are either input or output (for now) all ports declared here
module name
module mymodule(a, b, c, f);
output f;
input a, b, c;
declare which // Description goes here
ports are inputs, endmodule
which are outputs
// alternatively
module mymodule(input a, b, c, output f);
// Description goes here
endmodule
5
Spring 2015 :: CSE 502 Computer Architecture
Module Instantiation
name of module mymodule(a, b, c, f);
module to output f;
instantiate input a, b, c;
module_name inst_name(port_connections);
endmodule
name of connect the ports
instance
You can instantiate your own modules or pre-defined gates
Always inside another module
Predefined: and, nand, or, nor, xor, xnor
for these gates, port order is (output, input(s))
For your modules, port order is however you defined it
6
Spring 2015 :: CSE 502 Computer Architecture
Connecting Ports (By Order or Name)
In module instantiation, can specify port connections
by name or by order
module mod1(input a, b, output f);
// ...
endmodule
// by order
module mod2(input c, d, output g);
mod1 i0(c, d, g);
endmodule Advice: Use
by-name
// by name connections
module mod3(input c, d, output g); (where possible)
mod1 i0(.f(g), .b(d), .a(c));
endmodule
7
Spring 2015 :: CSE 502 Computer Architecture
Combinational Logic
Description
Spring 2015 :: CSE 502 Computer Architecture
Structural Design
Example: multiplexor
Output equals an input
Which one depends on sel
module mux(a, b, sel, f);
output f;
input a, b, sel; datatype for describing logical value
logic c, d, not_sel;
not gate0(not_sel, sel);
and gate1(c, a, not_sel); Built-in gates:
and gate2(d, b, sel); port order is:
or gate3(f, c, d); output, input(s)
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Continuous Assignment
Specify logic behaviorally by writing an expression
to show how the signals are related to each other.
assign statement
module mux2(a, b, sel, f);
output f;
input a, b, sel;
logic c, d;
d
assign c = a & (~sel);
assign d = b & sel;
assign f = c | d;
c
// or alternatively
assign f = sel ? b : a;
endmodule
10
Spring 2015 :: CSE 502 Computer Architecture
Combinational Procedural Block
Can use always_comb procedural block to
describe combinational logic using a series of
sequential statements
All always_comb module mymodule(a, b, c, f);
output f;
blocks are input a, b, c;
independent and
always_comb begin
parallel to each other // Combinational logic
// described
// in C-like syntax
end
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Procedural Behavioral Mux Description
module mux3(a, b, sel, f);
output logic f; If we are going to drive f this
input a, b, sel; way, need to declare it as logic
always_comb begin
if (sel == 0) begin
f = a; Important: for behavior to be
end combinational, every output (f)
else begin must be assigned in all possible
f = b; control paths
end
end Why? Otherwise, would be a latch
endmodule and not combinational logic.
Spring 2015 :: CSE 502 Computer Architecture
Accidental Latch Description
module bad(a, b, f); This is not
output logic f;
input a, b; combinational, because
for certain values of b, f
always_comb begin
if (b == 1) begin
must remember its
f = a; previous value.
end
end
endmodule
This code describes a
latch. (If you want a
latch, you should define
it using
always_latch)
Spring 2015 :: CSE 502 Computer Architecture
Multiply-Assigned Values
module bad2(...); Both of these
... blocks execute
always_comb begin
b = ... something ... concurrently
end
always_comb begin So what is the
b = ... something else ...
end
value of b?
endmodule We dont know!
Dont do this!
Spring 2015 :: CSE 502 Computer Architecture
Multi-Bit Values
Can define inputs, outputs, or logic with multiple bits
module mux4(a, b, sel, f);
output logic [3:0] f;
input [3:0] a, b;
input sel;
always_comb begin
if (sel == 0) begin
f = a;
end
else begin
f = b;
end
end
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Multi-Bit Constants and Concatenation
Can give constants with specified number bits
In binary or hexadecimal
Can concatenate with { and }
logic [3:0] a, b, c;
Can
logic reverse
signed order
[3:0] d; (to index buffers left-to-right)
logic [7:0] e;
logic [1:0] f;
assign a = 4b0010; // four bits, specified in binary
assign b = 4hC; // four bits, specified in hex == 1100
assign c = 3; // == 0011
assign d = -2; // 2s complement == 1110 as bits
assign e = {a, b}; // concatenate == 0010_1100
assign f = a[2 : 1]; // two bits from middle == 01
Spring 2015 :: CSE 502 Computer Architecture
Case Statements and Dont-Cares
module newmod(out, in0, in1, in2);
input in0, in1, in2;
output logic out; output value is
undefined in this case
always_comb begin
case({in0, in1, in2})
3'b000: out = 1;
3'b001: out = 0; Last bit is a dont
3'b010: out = 0; care -- this line will
3'b011: out = x; be active for 100 OR
3'b10x: out = 1; 101
default: out = 0;
endcase default gives else
end behavior. Here active
endmodule if 110 or 111
Spring 2015 :: CSE 502 Computer Architecture
Arithmetic Operators
Standard arithmetic operators defined: + - * / %
Many subtleties here, so be careful:
four bit number + four bit number = five bit number
Or just the bottom four bits
arbitrary division is difficult
Spring 2015 :: CSE 502 Computer Architecture
Addition and Subtraction
Be wary of overflow!
logic [3:0] a, b;
logic [3:0] d, e, f; logic [4:0] c;
assign f = d + e; assign c = a + b;
4b1000 + 4b1000 = Five bit output can prevent overflow:
In this case, overflows to zero 4b1000 + 4b1000 gives 5b10000
Use signed if you want logic signed [3:0] g, h, i;
values as 2s logic signed [4:0] j;
assign g = 4b0001; // == 1
complement assign h = 4b0111; // == 7
i == 4b1010 == -6 assign i = g h;
j == 5b11010 == -6 assign j = g h;
Spring 2015 :: CSE 502 Computer Architecture
Multiplication
Multiply k bit number with m bit number
How many bits does the result have? k+m
logic signed [3:0] a, b;
logic signed [7:0] c;
assign a = 4'b1110; // -2
assign b = 4'b0111; // 7
assign c = a*b; c = 8b1111_0010 == -14
If you use fewer bits in your code
Gets least significant bits of the product
logic signed [3:0] a, b, d;
assign a = 4'b1110; // -2
assign b = 4'b0111; // 7
assign d = a*b; d = 40010 == 2 Underflow!
Spring 2015 :: CSE 502 Computer Architecture
Sequential Logic
Description
Spring 2015 :: CSE 502 Computer Architecture
Sequential Design
Everything so far was purely combinational
Stateless
What about sequential systems?
flip-flops, registers, finite state machines
New constructs
always_ff @(posedge clk, )
non-blocking assignment <=
Spring 2015 :: CSE 502 Computer Architecture
Edge-Triggered Events
Variant of always block called always_ff
Indicates that block will be sequential logic (flip flops)
Procedural block occurs only on a signals edge
@(posedge ) or @(negedge )
always_ff @(posedge clk, negedge reset_n) begin
// This procedure will be executed
// anytime clk goes from 0 to 1
// or anytime reset_n goes from 1 to 0
end
Spring 2015 :: CSE 502 Computer Architecture
Flip Flops (1/3)
q remembers what d was at the last clock edge
One bit of memory
Without reset:
module flipflop(d, q, clk);
input d, clk;
output logic q;
always_ff @(posedge clk) begin
q <= d;
end
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Flip Flops (2/3)
Asynchronous reset:
module flipflop_asyncr(d, q, clk, rst_n);
input d, clk, rst_n;
output logic q;
always_ff @(posedge clk, negedge rst_n) begin
if (rst_n == 0)
q <= 0;
else
q <= d;
end
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Flip Flops (3/3)
Synchronous reset:
module flipflop_syncr(d, q, clk, rst_n);
input d, clk, rst_n;
output logic q;
always_ff @(posedge clk) begin
if (rst_n == 0)
q <= 0;
else
q <= d;
end
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Multi-Bit Flip Flop
module flipflop_asyncr(d, q, clk, rst_n);
input [15:0] d;
input clk, rst_n;
output logic [15:0] q;
always_ff @(posedge clk, negedge rst_n) begin
if (rst_n == 0)
q <= 0;
else
q <= d;
end
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Digression: Module Parameters
Parameters allow modules to be easily changed
module my_flipflop(d, q, clk, rst_n);
parameter WIDTH=16;
input [WIDTH-1:0] d;
input clk, rst_n;
default value set to 16
output logic [WIDTH-1:0] q;
...
endmodule
Instantiate and set parameter: uses default value
my_flipflop f0(d, q, clk, rst_n);
my_flipflop #(12) f0(d, q, clk, rst_n); changes parameter to
12 for this instance
Spring 2015 :: CSE 502 Computer Architecture
Non-Blocking Assignment a <= b;
<= is the non-blocking assignment operator
All left-hand side values take new values concurrently
always_ff @(posedge clk) begin c gets the old value of b, not
b <= a; value assigned just above
c <= b;
end
This models synchronous logic!
Spring 2015 :: CSE 502 Computer Architecture
Non-Blocking vs. Blocking
Use non-blocking assignment <= to describe
edge-triggered (synchronous) assignments
always_ff @(posedge clk) begin
b <= a;
c <= b;
end
Use blocking assignment = to describe
combinational assignment
always_comb begin
b = a;
c = b;
end
Spring 2015 :: CSE 502 Computer Architecture
Design Example
Lets say we want to compute f = a + b*c
b and c are 4 bits, a is 8 bits, and f is 9 bits
First, we will build it as a combinational circuit
Then, we will add registers at its inputs and outputs
Spring 2015 :: CSE 502 Computer Architecture
Finite State Machines (1/2) reset
State names 0
Output values A/00
1
Transition values
0
Reset state D/10 B/00
0 1
1
1
0
C/11
Spring 2015 :: CSE 502 Computer Architecture
Finite State Machines (2/2)
What does an FSM look like when implemented?
Combinational logic and registers (things we
already know how to do!)
Spring 2015 :: CSE 502 Computer Architecture
Full FSM Example (1/2)
reset
module fsm(clk, rst, x, y);
0
input clk, rst, x;
output logic [1:0] y;
enum { STATEA=2'b00, STATEB=2'b01, STATEC=2'b10, A/00
1
STATED=2'b11 } state, next_state;
0
// next state logic D/10 B/00
always_comb begin
case(state) 1
0 1
STATEA: next_state = x ? STATEB : STATEA; 1
0
STATEB: next_state = x ? STATEC : STATED; C/11
STATEC: next_state = x ? STATED : STATEA;
STATED: next_state = x ? STATEC : STATEB;
endcase
end
// ... continued on next slide
Spring 2015 :: CSE 502 Computer Architecture
Full FSM Example (2/2)
reset
// ... continued from previous slide
0
// register
always_ff @(posedge clk) begin
if (rst) A/00
1
state <= STATEA;
else
state <= next_state; 0
D/10 B/00
end
// Output logic 1
0 1
always_comb begin 1
case(state) 0
C/11
STATEA: y = 2'b00;
STATEB: y = 2'b00;
STATEC: y = 2'b11;
STATED: y = 2'b10;
endcase
end
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Arrays
module multidimarraytest();
logic [3:0] myarray [2:0];
assign myarray[0] = 4'b0010;
assign myarray[1][3:2] = 2'b01;
assign myarray[1][1] = 1'b1;
assign myarray[1][0] = 1'b0;
assign myarray[2][3:0] = 4'hC;
initial begin
$display("myarray == %b", myarray);
$display("myarray[2:0] == %b", myarray[2:0]);
$display("myarray[1:0] == %b", myarray[1:0];
$display("myarray[1] == %b", myarray[1]);
$display("myarray[1][2] == %b", myarray[1][2]);
$display("myarray[2][1:0] == %b", myarray[2][1:0]);
end
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Memory (Combinational read)
module mymemory(clk, data_in, data_out,
r_addr, w_addr, wr_en);
parameter WIDTH=16, LOGSIZE=8;
localparam SIZE=2**LOGSIZE;
input [WIDTH-1:0] data_in;
output logic [WIDTH-1:0] data_out;
input clk, wr_en;
input [LOGSIZE-1:0] r_addr, w_addr;
Combinational read
logic [WIDTH-1:0] mem [SIZE-1:0];
assign data_out = mem[r_addr];
always_ff @(posedge clk) begin
if (wr_en)
mem[w_addr] <= data_in;
end
endmodule Synchronous write
Spring 2015 :: CSE 502 Computer Architecture
Memory (Synchronous read)
module mymemory2(clk, data_in, data_out,
r_addr, w_addr, wr_en);
parameter WIDTH=16, SIZE=256;
localparam SIZE=2**LOGSIZE;
input [WIDTH-1:0] data_in;
output logic [WIDTH-1:0] data_out;
input clk, wr_en;
input [LOGSIZE-1:0] r_addr, w_addr;
logic [WIDTH-1:0] mem [SIZE-1:0];
Synchronous read
always_ff @(posedge clk) begin
data_out <= mem[r_addr]; What happens if we
try to read and write
if (wr_en) the same address?
mem[w_addr] <= data_in;
end
endmodule
Spring 2015 :: CSE 502 Computer Architecture
Assertions
Assertions are test constructs
Automatically validated as design is simulated
Written for properties that must always be true
Makes it easier to test designs
Dont have to manually check for these conditions
Spring 2015 :: CSE 502 Computer Architecture
Example: A Good Place for Assertions
Imagine you have a FIFO queue
When queue is full, it sets status_full to true
When queue is empty, it sets status_empty to true
data_in data_out
wr_en FIFO status_full
rd_en status_empty
When status_full is true, wr_en must be false
When status_empty is true, rd_en must be false
Spring 2015 :: CSE 502 Computer Architecture
Assertions
A procedural statement that checks an expression when
statement is executed
// general form
Use $display assertion_name: assert(expression) pass_code;
to print text, else fail_code;
$error to
print error, or // example
always @(posedge clk) begin
$fatal to
assert((status_full == 0) || (wr_en == 0))
print and halt else $error("Tried to write to FIFO when full.");
simulation end
SV also has Concurrent Assertions that are continuously
monitored and can express temporal conditions
Complex but very powerful
See http://www.doulos.com/knowhow/sysverilog/tutorial/assertions/
for an introduction