0% found this document useful (0 votes)
8 views52 pages

03 Systemverilog

Uploaded by

Heekwan Son
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views52 pages

03 Systemverilog

Uploaded by

Heekwan Son
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

Spring 2018 :: CSE 502

Introduction to
SystemVerilog
Nima Honarmand
(Slides adapted from Prof. Milder’s ESE-507 course)
Spring 2018 :: CSE 502

First Things First


• SystemVerilog is a superset of Verilog
– The SystemVeriog subset we use is 99% Verilog + a few
new constructs
– Familiarity with Verilog (or even VHDL) helps but is not
necessary

• SystemVerilog resources and tutorials on the course


“Assignments” web page
Spring 2018 :: CSE 502

Hardware Description Languages (HDL)


• HDLs are used for a variety of purposes in hardware design
– Functional simulation
– Timing simulation
– Hardware synthesis
– Testbench development
– …

• Many different features to accommodate all of these


– We focus on functional simulation

• With HDLs, you describe hardware in one of two styles (usually)


– Structural model (network of gates and transistors)
– Behavioral model (high-level statements such as assignments, if, while, …)

• We use behavioral modeling for the course project


– Much simpler than designing with gates
Spring 2018 :: CSE 502

HDLs vs. Programming Languages (1)


• Have syntactically similar constructs:
– Data types, variables, operators, assignments, if statements,
loops, …

• But very different mentality and semantic model


• Statements are evaluated in parallel (unless specified
otherwise)
– Statements model hardware
– Hardware is inherently parallel

Reset your mind! You are a HW developer now.


Stop thinking like a SW programmer!
Spring 2018 :: CSE 502

HDLs vs. Programming Languages (2)


• Software programs are organized as a set of
subroutines
– Subroutines call each other, passing arguments and
return values
– When in callee, caller’s execution is paused

• Hardware descriptions are organized as a hierarchy


of hardware modules
– A hierarchy of module instances connected to each
other using wires
– Modules are active at the same time
Spring 2018 :: CSE 502

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

6
Spring 2018 :: CSE 502

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

7
Spring 2018 :: CSE 502

Connecting Ports
• 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

8
Spring 2018 :: CSE 502

Review: Combinational vs. Sequential Logic


• In combinational logic, circuit outputs are pure
function of circuit inputs
– i.e., output values only determined by input values
– Examples: and, or, multiplexer, adder, etc.

• In sequential logic, there are “state” elements that


can “hold” their old values regardless of the input
changes
– Example: any circuit with a latch, flip-flop or any other
“memory” element in it
Spring 2018 :: CSE 502

Combinational Logic
Description
Spring 2018 :: CSE 502

Structural Description
• Example: multiplexor
– Output equals one of the inputs
– Depending on the value of “sel”

module mux(a, b, sel, f);


output f;
input a, b, sel; datatype for describing Boolean logic

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 2018 :: CSE 502

Behavioral: 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

12
Spring 2018 :: CSE 502

Behavioral: 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 2018 :: CSE 502

Procedural Behavioral Mux Description

module mux3(a, b, sel, f);


output logic f; If we are going to drive f this way,
input a, b, sel; 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 2018 :: CSE 502

Avoid 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 2018 :: CSE 502

Avoid 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 don’t know!

Don’t do this!
Spring 2018 :: CSE 502

Multi-Bit Values
• Can define inputs, outputs, or logic with multiple bits
– Also called bit vectors
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 2018 :: CSE 502

Multi-Bit Constants and Concatenation


• Can give constants with specified number bits
– In binary, decimal 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 = 4’b0010; // four bits, specified in binary
assign b = 4’hC; // four bits, specified in hex == 1100
assign c = 3; // == 0011
assign d = -2; // 2’s complement == 1110 as bits
assign e = {a, b}; // concatenate == 0010_1100
assign f = a[2 : 1]; // two bits from middle == 01
Spring 2018 :: CSE 502

Case Statements and “Don’t-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 “don’t
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 2018 :: CSE 502

Arithmetic Operators
• Standard arithmetic operators defined: + - * / %
• Many subtleties here, so be careful:
– four bit number + four bit number = five bit number
• Or just the lower four bits
– arbitrary division is difficult
Spring 2018 :: CSE 502

Addition and Subtraction (1)


• Be wary of overflow!
logic [3:0] d, e, f; logic [3:0] a, b;
logic [4:0] c;
assign f = d + e;
assign c = a + b;

4’b1000 + 4’b1000 = 4’b000 Five-bit output can prevent overflow:


In this case, overflows to zero 4’b1000 + 4’b1000 gives 5’b10000
Spring 2018 :: CSE 502

Addition and Subtraction (2)


• Use “signed” if you want values as 2’s complement

logic signed [3:0] g, h, i;


logic signed [4:0] j;

assign g = 4’b0001; // == 1
i == 4’b1010 == -6 assign h = 4’b0111; // == 7
j == 5’b11010 == -6 assign i = g – h;
assign j = g – h;
Spring 2018 :: CSE 502

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 = 8’b1111_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 = 4’0010 == 2
Spring 2018 :: CSE 502

Design Example
• Let’s say we want to compute f = a + b*c
– b and c are 4 bits, a is 8 bits, and f is 9 bits

• Let’s a combinational circuit using always_comb


module MAF(f, a, b, c); module MAF(f, a, b, c);
input [7:0] a input [7:0] a
input [3:0] b, c; input [3:0] b, c;
output logic [9:0] f; output logic [9:0] f;

always_comb begin OR logic [7:0] temp;


f = a + b * c;
end always_comb begin
endmodule temp = b * c;
f = a + temp;
end
endmodule
Spring 2018 :: CSE 502

Design Example 2
• Let’s say we want to compute f = (a ? b + 1 : c+2) * d
– a is 1 bit; b, c and d are 4 bits
– How wide should f be to avoid any overflows?

• Let’s a combinational circuit using always_comb


Spring 2018 :: CSE 502

Sequential Logic
Description
Spring 2018 :: CSE 502

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 2018 :: CSE 502

Edge-Triggered Events
• Variant of always block called always_ff
– Indicates that block will be sequential logic (flip flops)

• Procedural block activated only on a signal’s edge


– @(posedge …) or @(negedge …)
always_ff @(posedge clk, negedge reset_n) begin

// This block will be evaluated


// anytime clk goes from 0 to 1
// or anytime reset_n goes from 1 to 0

end
Spring 2018 :: CSE 502

Flip Flops (1)


• 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 2018 :: CSE 502

Flip Flops (2)


• With 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 2018 :: CSE 502

Flip Flops (3)


• With 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 2018 :: CSE 502

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 2018 :: CSE 502

Interlude: 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);
changes parameter to
my_flipflop #(12) f0(d, q, clk, rst_n);
12 for this instance
my_flipflop #(.WIDTH(12)) f0(d, q, clk, rst_n);
Spring 2018 :: CSE 502

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 2018 :: CSE 502

Non-Blocking vs. Blocking (1)


• 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 2018 :: CSE 502

Non-Blocking vs. Blocking (2)


• Blocking models flow of values in wires and through
gates in a combinational circuit
– Output of multiplier is input to
always_comb begin
adder (1) temp = b * c;
– That’s why with blocking, (2) f = a + temp;
(2) is evaluated after (1) end

• Non-blocking assignments model relation between


input and output of flip-flops
– All FFs clocked together → all outputs take new values
together
– That’s why (3) and (4) are always_ff @(posedge clk) begin
evaluated in parallel (3) b <= a;
(4) c <= b;
end
Spring 2018 :: CSE 502

Non-Blocking vs. Blocking (3)


• Do not mix blocking and non-blocking assignments
• Use only blocking assignments in always_comb
• Use only non-blocking assignments in always_ff
• And keep their differences in mind
Spring 2018 :: CSE 502

Design Example — Sequential


• Recall our previous example: f = a + b*c
– b and c are 4 bits, a is 8 bits, and f is 9 bits
– We built it as a combinational circuit

• Now, let’s add registers at its inputs and outputs


Spring 2018 :: CSE 502

Finite State Machines (1) reset

• State names 0

• Output values A/00


1

• Transition values
0
• Reset (initial) state D/10 B/00

0 1
1

1
0
C/11
Spring 2018 :: CSE 502

Finite State Machines (2)


• What does an FSM look like when implemented in HW?

• Combinational logic and registers (things we already


know how to do!)
Spring 2018 :: CSE 502

Full FSM Example (1)


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 2018 :: CSE 502

Full FSM Example (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 2018 :: CSE 502

Huffman Partitioning
• In my experience, for anything other than memories
(SRAM arrays), you should code according to Huffman
Partitioning of your module
input output

Combinational
Logic always_comb
blocks
next state present state
(n_state) (p_state)
always_ff
in out (usually, one is
Registers enough)

clk reset
Spring 2018 :: CSE 502

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; display
assign myarray[1][0] = 1'b0; (SystemVerilog’s
assign myarray[2][3:0] = 4'hC; printf)
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 2018 :: CSE 502

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 2018 :: CSE 502

Memory (Synchronous read)


module mymemory2(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;

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 2018 :: CSE 502

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


– Don’t have to manually check for these conditions
Spring 2018 :: CSE 502

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 2018 :: CSE 502

Assertions
• A procedural statement that checks an expression when
statement is executed
// general form
Use $error assertion_name: assert(expression) pass_code;
to print error, else fail_code;
or $fatal to
print and halt // example
always @(posedge clk) begin
simulation
assert((status_full == 0) || (wr_en == 0))
else $error("Tried to write to FIFO when full.");
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
Spring 2018 :: CSE 502

DOs and DON’Ts to Keep in Mind (1)


1) Always try to picture the hardware that corresponds to
your Verilog code (especially, always blocks)
– If you can’t, you’re probably doing something wrong
– Each hardware component is simple; the power is in their
connection and parallelism

2) Have a reset signal that is connected to all your flip-flops


– Do not make any assumptions about the initial state of your flip-
flops
– Instead, reset them explicitly

3) Avoid using loops to implement hardware functionality


– Okay to use them for display or assert statements
– But not for hardware functionality
Spring 2018 :: CSE 502

DOs and DON’Ts to Keep in Mind (2)


4) Do not mix blocking and non-blocking assignments
– Only use blocking assignments in always_comb
– Only use non-blocking assignments in always_ff
– And keep their differences in mind

5) Do not put any combinational logic in always_ff


– always_ff should only model flip flops
– Follow Huffman Partitioning rules
Spring 2018 :: CSE 502

DOs and DON’Ts to Keep in Mind (3)


6) Big modules and always blocks are sign of bad
design
– Just like big functions
– Keep each module simple to make it easy to test individually

7) Test, Test, Test


– Test each module independently before connecting it to
others
– If a module’s functionality is not independently-testable, it is
probably a bad design

You might also like