Advanced Verilog Coding
Advanced Verilog Coding
Sponsored by
Sunburst Design
Agenda
Sunburst Design
Sponsored by
The two details most misunderstood about Verilog A couple of important Verilog tips Efficient Verilog FSM coding styles Verilog-2001 enhancements
Enhancements already implemented by ModelSim
Sponsored by
Sunburst Design
Sunburst Design
Sponsored by
Sunburst Design
Sponsored by
Verilog "race" conditions Blocking and nonblocking assignment fundamentals 7 Guidelines to help avoid Verilog race conditions Verilog's "Stratified Event Queue" Examples:
Sequential pipeline Sequential LFSR (Linear Feedback Shift Register) Combining blocking & nonblocking assignments
Sunburst Design
Sponsored by
The correct spelling as noted in the IEEE 1364-1995 Verilog Standard is:
nonblocking
Spell-checkers do not recognize Verilog keywords
Sunburst Design
Sponsored by
which statements have a guaranteed order of execution ("Determinism", section 5.4.1) which statements do not have a guaranteed order of execution ("Nondeterminism", section 5.4.2 & "Race conditions", section 5.5)
A Verilog race condition occurs when two or more statements that are scheduled to execute in the same simulation timestep, would give different results when the order of statement execution is changed, as permitted by the Verilog Standard To avoid race conditions, it is important to understand the scheduling of Verilog blocking and nonblocking assignments
Blocking Assignments
Blocking assignment operator: =
Sunburst Design
Sponsored by
"Blocks" trailing assignments in the same always block from occurring until after the current assignment has completed
Sunburst Design
Sponsored by
Problem: Inter-dependent blocking assignments that execute in the same time step Execution order is not guarantee!!
module fbosc1 (y1, y2, clk, rst);
output y1, y2; input clk, rst; reg y1, y2;
rst y1
rst
y1 y1 y2
pre
always @(posedge clk or posedge rst) clk if (rst) y1 = 0; // reset else y1 = y2; On rst, y1=0 and y2=1 always @(posedge clk or posedge rst) if (rst) y2 = 1; // preset else y2 = y1; endmodule After rst, on next posedge clk, y1=1 (y2) and y2=y1=1 -ORy2=0 (y1) and y1=y2=0
rst y1 y2
pre
y2
clk
10
Nonblocking Assignments
Sunburst Design
Sponsored by
Nonblocking assignment operator: <= Execution of nonblocking assignments can be viewed as a two-step process:
Evaluate the RHS of nonblocking statements at the beginning of the time step Update the LHS of nonblocking statements at the end of the time step
Allows assignment scheduling without blocking evaluation and execution of other Verilog statements Only used in procedural blocks (not continuous assignments)
Syntax error! Illegal continuous assignment assign y <= a + b;
11
Sunburst Design
Sponsored by
No problem: Inter-dependent nonblocking assignments that execute in the same time step
On rst, y1=0 and y2=1 module fbosc2 (y1, y2, clk, rst);
output y1, y2; input clk, rst; reg y1, y2;
always @(posedge clk or posedge rst) if (rst) y1 <= 0; // reset else y1 <= y2; always @(posedge clk or posedge rst) if (rst) y2 <= 1; // preset else y2 <= y1; endmodule After rst, on next posedge clk, y1=1 (y2') and y2=0 (y1')
rst y1
pre
y2
12
7 Coding Guidelines
Sunburst Design Follow these guidelines to remove 90-100% of all Sponsored by Verilog race conditions
In general, following specific coding guidelines can eliminate Verilog race conditions:
Guideline #1: Sequential logic and latches - use nonblocking assignments Guideline #2: Combinational logic in an always block - use blocking assignments Guideline #3: Mixed sequential and combinational logic in the same always block is sequential logic - use nonblocking assignments Guideline #4: In general, do not mix blocking and nonblocking assignments in the same always block Guideline #5: Do not make assignments to the same variable from more than one always block Guideline #6: Use $strobe to display values that have been assigned using nonblocking assignments Guideline #7: Do not make #0 procedural assignments
13
Sunburst Design
Sponsored by
Nonblocking Events
Monitor Events
$monitor command execution $strobe command execution Other specific PLI commands
14
NOTE: contrived examples Sponsored by not the recommended coding module osc1 (clk); module osc2 (clk); style for clock oscillators! output clk; output clk; reg clk; reg clk; osc1 osc2 initial initial ------ -----#10 clk = 0; #10 clk = 0; 0: clk1=x clk2=x 10: clk1=0 clk2=0 always @(clk) always @(clk) 20: clk1=1 clk2=1 #10 clk = ~clk; #10 clk <= ~clk; 30: clk1=1 clk2=0 endmodule endmodule 40: clk1=1 clk2=1 50: clk1=1 clk2=0 60: clk1=1 clk2=1 module tb; osc1 x1 (.clk(clk1)); 70: clk1=1 clk2=0 osc2: nonblocking osc2 x2 (.clk(clk2)); 80: clk1=1 clk2=1 osc1: blocking assignment 90: clk1=1 clk2=0 assignment
initial begin $display(" osc1 osc2"); $display(" ------ ------"); $monitor("%d: clk1=%b clk2=%b", $stime, clk1, clk2); end
Self-Triggering Oscillators?
Sunburst Design
osc1: no oscillation!
osc2: oscillating!
15
Self-Triggering?
(not with blocking assignments)
osc2: nonblocking assignment initial #10 clk = 0; always @(clk) #10 clk <= ~clk; Active Events #10 clk=0 @(clk) (RHS=1) @(clk) clk<=1 (RHS=0) clk<=0 (continues) Blocking Assignment Trigger always block Blocking Assignment Wait for clk transition stopped! NB Events clk<=1 clk<=0
Sunburst Design
Sponsored by
Blocking Assignment Trigger always block Evaluate RHS of NBA Wait for clk transition activate NB events NBA assignment >(triggers @(clk)) Evaluate RHS of NBA activate NB events NBA assignment >(triggers @(clk)) oscillating! Update LHS of NBA Update LHS of NBA
16
Pipeline
Blocking Assignments Style #1
Active Events q1 = d; q2 = q1; // d q3 = q2; // d NB Events Blocking assignment Blocking assignment Blocking assignment
Sunburst Design
Sponsored by
module pipeb1 (q3, d, clk); output [7:0] q3; input [7:0] d; input clk; reg [7:0] q3, q2, q1; always @(posedge clk) begin q1 = d; q2 = q1; Three sequential q3 = q2; blocking assignments end but only one endmodule synthesized register
Monitor Events
Simulation result
Synthesis result!!
d clk
q1
q2
q3
d clk
q3
17
Pipeline
Blocking Assignments Style #2
Active Events q3 = q2; q2 = q1; q1 = d; // d NB Events Blocking assignment Blocking assignment Blocking assignment
Sunburst Design
Sponsored by
module pipeb2 (q3, d, clk); output [7:0] q3; input [7:0] d; input clk; reg [7:0] q3, q2, q1; always @(posedge clk) begin q3 = q2; This ordering q2 = q1; will work q1 = d; end endmodule
Monitor Events
Simulation result
Synthesis result
d clk
q1
q2
q3
d clk
q1
q2
q3
18
Pipeline
Blocking Assignments Style #3
Active Events q1 = d; q2 = q1; // d q3 = q2; // d NB Events Blocking assignment Blocking assignment Blocking assignment
Sunburst Design
Executes in any order
Sponsored by
module pipeb3 (q3, d, clk); output [7:0] q3; input [7:0] d; input clk; reg [7:0] q3, q2, q1; always @(posedge clk) q1=d; always @(posedge clk) q2=q1;
Monitor Events always @(posedge clk) q3=q2; endmodule This ordering might not work Synthesis result
Simulation result
d? clk
q1?
q2?
q3 ???
d clk
q1
q2
q3
19
Pipeline
Blocking Assignments Style #4
Active Events q2 = q1; q3 = q2; // q1 q1 = d; // q1 NB Events Blocking assignment Blocking assignment Blocking assignment
Sunburst Design
Executes in any order
Sponsored by
module pipeb4 (q3, d, clk); output [7:0] q3; input [7:0] d; input clk; reg [7:0] q3, q2, q1; always @(posedge clk) q2=q1; always @(posedge clk) q3=q2;
Monitor Events always @(posedge clk) q1=d; endmodule This ordering might not work Synthesis result
Simulation result
d? clk
q1?
q2?
q3 ???
d clk
q1
q2
q3
20
Sunburst Design
Sponsored by
Coding Style Blocking Assignments #1 Blocking Assignments #2 Blocking Assignments #3 Blocking Assignments #4 +
Synthesizes correctly
NO! Yes ? ?
21
Pipeline
Nonblocking Assignments Style #1
Active Events (RHS=d') (RHS=q1') (RHS=q2') NB Events q1 <= d' q2 <= q1' q3 <= q2' Monitor Events Update LHS of NBA Update LHS of NBA Update LHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA
Sunburst Design
Sponsored by
module pipen1 (q3, d, clk); output [7:0] q3; input [7:0] d; input clk; reg [7:0] q3, q2, q1; always @(posedge clk) begin q1 <= d; This ordering q2 <= q1; will work q3 <= q2; end endmodule Synthesis result
Simulation result
d clk
q1
q2
q3
d clk
q1
q2
q3
22
Pipeline
Nonblocking Assignments Style #2
Active Events (RHS=q2') (RHS=q1') (RHS=d') NB Events q3 <= q2' q2 <= q1' q1 <= d' Monitor Events Update LHS of NBA Update LHS of NBA Update LHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA
Sunburst Design
Sponsored by
module pipen2 (q3, d, clk); output [7:0] q3; input [7:0] d; input clk; reg [7:0] q3, q2, q1; always @(posedge clk) begin q3 <= q2; q2 <= q1; ANY ordering q1 <= d; will work end endmodule Synthesis result
Simulation result
d clk
q1
q2
q3
d clk
q1
q2
q3
23
Pipeline
Nonblocking Assignments Style #3
Active Events (RHS=d') (RHS=q1') (RHS=q2') NB Events q1 <= d' q2 <= q1' q3 <= q2' Monitor Events Update LHS of NBA Update LHS of NBA Update LHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA
Sunburst Design
Sponsored by
module pipen3 (q3, d, clk); output [7:0] q3; input [7:0] d; input clk; reg [7:0] q3, q2, q1; always @(posedge clk) q1<=d; always @(posedge clk) q2<=q1; always @(posedge clk) q3<=q2; endmodule
Simulation result
Synthesis result
d clk
q1
q2
q3
d clk
q1
q2
q3
24
Pipeline
Nonblocking Assignments Style #4
Active Events (RHS=q1') (RHS=q2') (RHS=d') NB Events q2 <= q1' q3 <= q2' q1 <= d' Monitor Events Update LHS of NBA Update LHS of NBA Update LHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA
Sunburst Design
Sponsored by
module pipen4 (q3, d, clk); output [7:0] q3; input [7:0] d; input clk; reg [7:0] q3, q2, q1; always @(posedge clk) q2<=q1; always @(posedge clk) q3<=q2; always @(posedge clk) q1<=d; endmodule
ANY NEW
Simulation result Synthesis result ordering will work q2 q3
d clk
q1
q2
q3
d clk
q1
25
Sunburst Design
Sponsored by
Coding Style Blocking Assignments #1 Blocking Assignments #2 Blocking Assignments #3 Blocking Assignments #4 + Nonblocking Assignments #1 Nonblocking Assignments #2 Nonblocking Assignments #3 Nonblocking Assignments #4 +
Synthesizes correctly
26
Sunburst Design
Sponsored by
This example is in most Verilog books (bad habit!) Bad coding style!
27
LFSR
Blocking Assignments Style #1
module lfsrb1 (q3, clk, pre_n); output q3; input clk, pre_n; reg q3, q2, q1; wire n1; assign n1 = q1 ^ q3; q3=1 q2=1 q1=1 n1=(1^1)=0 q3=(q2)=1 q2=(n1)=0 q1=(q3)=1 n1=(1^1)=0 q3=(q2)=0 q2=(n1)=0 q1=(q3)=0 q1-q2-q3 1 1 1
Sunburst Design
Active Events
Sponsored by
q1-q2-q3 1 0 1
always @(posedge clk or negedge pre_n) if (!pre_n) begin q3 = 1'b1; q1-q2-q3 q2 = 1'b1; 0 0 0 q1 = 1'b1; Wrong value! end pre_n Should be "1" else begin q3 = q2; q2 = n1; q1 = q3; end Synthesizes, but does endmodule not simulate correctly q3 clk
q3=1'b1 preset q2=1'b1 q1=1'b1 assign n1=q1^q3 q3=q2 clk q2=n1 q1=q3 assign n1=q1^q3 q3=q2 clk q2=n1 q1=q3
q1
q3
q2
q3
28
LFSR
Blocking Assignments Style #2
Active Events
module lfsrb2 (q3, clk, pre_n); output q3; input clk, pre_n; reg q3, q2, q1;
Sunburst Design
Sponsored by
always @(posedge clk or negedge pre_n) if (!pre_n) {q3,q2,q1} = 3'b111; else {q3,q2,q1} = {q2,(q1^q3),q3}; endmodule This will work ... but the equations pre_n can be confusing q3 clk q1 q3 q2 q3 Synthesizes and simulates correctly
preset clk
clk
clk
29
LFSR
Nonblocking Assignments Style #1
module lfsrn1 (q3, clk, pre_n); output q3; input clk, pre_n; reg q3, q2, q1; wire n1; assign n1 = q1 ^ q3; always @(posedge clk or negedge pre_n) if (!pre_n) begin q3 <= 1'b1; q2 <= 1'b1; q1 <= 1'b1; end pre_n else begin q3 <= q2; q2 <= n1; q3 q1 <= q3; end clk endmodule
Sunburst Design
Sponsored by
q1
q3
q2
q3
30
LFSR
Nonblocking Assignments Style #1
Active Events preset (RHS=1) (RHS=1) (RHS=1) q3<=1'b1 q2<=1'b1 q1<=1'b1 Activate NBA n1=(1^1)=0 (RHS=q2'=1) (RHS=n1=0) (RHS=q3'=1) assign n1=q1^q3 q3<=q2 q2<=n1 q1<=q3 Activate NBA n1<=(1^1)=0 (RHS=q2'=0) (RHS=n1=0) (RHS=q3'=1) assign n1=q1^q3 q3<=q2 q2<=n1 q1<=q3 Activate NBA NB Events q3<=1 q2<=1 q1<=1
Sunburst Design
Sponsored by
clk
clk
31
LFSR
Nonblocking Assignments Style #2
module lfsrn2 (q3, clk, pre_n); output q3; input clk, pre_n; reg q3, q2, q1; always @(posedge clk or negedge pre_n) if (!pre_n) {q3,q2,q1} <= 3'b111; else {q3,q2,q1} <= {q2,(q1^q3),q3}; endmodule
Sunburst Design
Sponsored by
pre_n q3 clk q1 q3 q2 q3
32
Sunburst Design
Sponsored by
Synthesizes correctly
NO! Yes
Cryptic coding style
Yes Yes
Yes Yes
Cryptic coding style
Yes Yes
33
Sunburst Design
Sponsored by
Guideline #1: Use nonblocking assignments in always blocks that are written to generate sequential and latching logic Guideline #2: Use blocking assignments in always blocks that are written to generate combinational logic
module nbex1 (q, a, b, clk, rst_n); output q; input clk, rst_n; input a, b; reg q, y; always @(a or b) y = a ^ b; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= y; endmodule
a b
Synthesized result! y q
clk rst_n
34
Sunburst Design
Sponsored by
Guideline #3: Use nonblocking assignments in always blocks that are written to generate sequential and combinational logic in the same always block
module nbex2 (q, a, b, clk, rst_n); output q; input clk, rst_n; input a, b; reg q; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= a ^ b; endmodule
35
Sunburst Design
Sponsored by
Using nonblocking assignments in purely combinational always blocks might be functionally wrong
Pre-synthesis simulation will be incorrect Synthesizes equivalent combinational logic with warnings about the sensitivity list
module ao4 (y, a, b, c, d); output y; input a, b, c, d; reg y, tmp1, tmp2; WRONG! a 0 b 1 c 0 e 0 tmp1 tmp2 0 0 y 0 0
1 1 0 0 1 0 always @(a or b or c or d) begin tmp1 <= a & b; tmp2 <= c & d; y <= tmp1 | tmp2; Previous values tmp1 and tmp2! end NOT the values calculated during endmodule the current pass through this
always block
a 0
b 1
c 0
d 0
tmp1 tmp2 0 0 0 0
y 0
36
Sunburst Design
0 1 module ao5 Sponsored by c, d); (y, a, b, output y; input a, b, c, d; reg y, tmp1, tmp2; always @(a or b or c or d or tmp1 or tmp2) begin tmp1 <= a & b; tmp2 <= c & d; y <= tmp1 | tmp2; end endmodule
Evaluate RHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA activate NB events NBA assignment Again - trigger always block Evaluate RHS of NBA Evaluate RHS of NBA Evaluate RHS of NBA NBA assignment NBA assignment activate NB events NBA assignment NBA assignment NBA assignment
NB Events tmp1<=1 tmp2<=0 y<=0 tmp1<=1 tmp2<=0 y<=1 Update LHS of NBA Update LHS of NBA Update LHS of NBA Update LHS of NBA Update LHS of NBA Update LHS of NBA
37
Sunburst Design
Sponsored by
module ao1 (y, a, b, c, d); output y; input a, b, c, d; reg y, tmp1, tmp2; always @(a or b or c or d) begin tmp1 = a & b; tmp2 = c & d; y = tmp1 | tmp2; end endmodule
always @(a or b or c or d or tmp1 or tmp2) begin tmp1 <= a & b; tmp2 <= c & d; All nonblocking y <= tmp1 | tmp2; assignments end endmodule
38
Sunburst Design
Sponsored by
39
Sunburst Design
Sponsored by
always @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= a & b; endmodule module ba_nba4 (q, a, b, clk, rst_n);
output input input reg wire q; a, b, rst_n; clk; q; tmp;
. . . or separate the combinational logic assignment into a separate continuous assignment and separate always block Not recommended: coding style with mixed blocking and nonblocking assignments in the same always block
assign tmp = a & b; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= tmp; endmodule
40
Sunburst Design
Sponsored by
Guideline #4: Do not mix blocking and nonblocking assignments in the same always block
module ba_nba6 (q, a, b, clk, rst_n); output q; input a, b, rst_n; Verilog simulators input clk; permit this! reg q, tmp; Synthesis syntax error!
always @(posedge clk or negedge rst_n) if (!rst_n) q = 1'b0; else begin tmp = a & b; Blocking q <= tmp; assignment to q end endmodule Nonblocking Error: A reg can only be assigned with assignment to q all RTL assignments or all procedural assignments near symbol ";" on line 11 in file ba_nba6.v
41
Sunburst Design
Sponsored by
module badcode1 (q, d1, d2, clk, rst_n); output q; input d1, d2, clk, rst_n; reg q; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= d1; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= d2; endmodule Warning: In design 'badcode1', there is 1 multiple-driver net with unknown wired-logic type.
Synthesis result !! d1
q d2
clk rst_n
42
Sponsored by
Sunburst Design
43
Sunburst Design
Sponsored by
Myth: Using the $display command with nonblocking assignments does not work Truth: Nonblocking assignments are updated after all $display commands
module display_cmds; reg a; initial $monitor("\$monitor: a = %b\n", a); initial begin $strobe ("\$strobe : a = %b\n", a); a = 0; a <= 1; $display ("\$display: a = %b\n", a); #1 $finish; end endmodule Actual output display $display: a = 0 $monitor: a = 1 $strobe : a = 1
44
#0 Assignments
Sunburst Design
Sponsored by
Myth: #0 forces an assignment to the end of a time step Truth: #0 forces an assignment to the "inactive events queue"
45
Scheduling Example
module nb_schedule1; reg a, b; initial begin a = 0; b = 1; a <= b; b <= a; $monitor $display $strobe #0 $display #1 $monitor $display $strobe $display #1 $finish; end endmodule Displayed output!! 0ns: 0ns: 0ns: 0ns: 1ns: 1ns: 1ns: 1ns: ("%0dns: ("%0dns: ("%0dns: ("%0dns: ("%0dns: ("%0dns: ("%0dns: ("%0dns:
Sunburst Design
$display: a=0 byb=1 Sponsored #0 : a=0 b=1 $monitor: a=1 b=0 $strobe : a=1 displayed What will be b=0 from this example? $display: a=1 b=0 #0 : a=1 b=0 $monitor: a=1 b=0 $strobe : a=1 b=0
\$monitor: a=%b b=%b", $stime, a, b); \$display: a=%b b=%b", $stime, a, b); \$strobe : a=%b b=%b\n", $stime, a, b); #0 : a=%b b=%b", $stime, a, b); \$monitor: a=%b b=%b", $stime, a, b); \$display: a=%b b=%b", $stime, a, b); \$strobe : a=%b b=%b\n", $stime, a, b); #0 : a=%b b=%b", $stime, a, b);
46
Sunburst Design
Sponsored by
initial begin a = 0; b = 1; a <= b; b <= a; $monitor $display $strobe #0 $display #1 $monitor $display $strobe $display #1 $finish; end ...; ...; ...; ...; ...; ...; ...; ...;
Inactive Events "a=0 b=1" Nonblocking Events Monitor Events a<=1 b<=0 "a=1 b=0" "a=1 b=0"
#0 display command Update LHS of NBA Update LHS of NBA $monitor command $strobe command
47
Sunburst Design
Sponsored by
Myth: Making multiple nonblocking assignments to the same variable in the same always block is undefined Truth: Making multiple nonblocking assignments to the same variable in the same always block is defined by the 1364 Verilog Standard
The last nonblocking assignment to the same variable wins!
48
Sunburst Design
Sponsored by
"Nonblocking assignments shall be performed in the order the statements were executed. Consider the following example: initial begin a <= 0; a <= 1; end When this block is executed, there will be two events added to the nonblocking assign update queue. The previous rule requires that they be entered on the queue in source order; this rule requires that they be taken from the queue and performed in source order as well. Hence, at the end of time-step 1, the variable a will be assigned 0 and then 1."
49
Sunburst Design
Sponsored by
Problem: different simulators and simulation options cause the simulation to behave differently at the beginning of a simulation Reasons:
reset is asserted, but not recognized at time 0
Guideline: set reset to 0 with a nonblocking assignment at time 0
50
`define cycle 100 `timescale 1ns / 1ns module reset_time0; reg d, clk, rst_n; reg q;
Sunburst Design
rst_n Sponsored by asserted with blocking assignment
initial begin $timeformat(-9,0,"ns",6); $monitor("%t: q=%b d=%b clk=%b rst_n=%b", $stime, q, d, clk, rst_n); rst_n = 0; d = 1; @(negedge clk) rst_n = 1; @(negedge clk) d = ~d; Might miss @(negedge clk) $finish; negedge rst_n end always @(posedge clk or negedge rst_n) if (!rst_n) q <= 0; else q <= d; initial @(negedge rst_n) $display("RESET at time 0"); endmodule
51
`define cycle 100 `timescale 1ns / 1ns module reset_time0; reg d, clk, rst_n; reg q;
Sunburst Design
Assert Sponsored by rst_n with nonblocking assignment
RESET at time 0 0ns: q=0 d=1 50ns: q=0 d=1 100ns: q=0 d=1 150ns: q=1 d=1 200ns: q=1 d=0 250ns: q=0 d=0
initial begin $timeformat(-9,0,"ns",6); $monitor("%t: q=%b d=%b clk=%b rst_n=%b", $stime, q, d, clk, rst_n); rst_n <= 0; d = 1; @(negedge clk) rst_n = 1; Negedge rst_n @(negedge clk) d = ~d; will be triggered @(negedge clk) $finish; end always @(posedge clk or negedge rst_n) if (!rst_n) q <= 0; else q <= d; initial @(negedge rst_n) $display("RESET at time 0"); endmodule
52
`define cycle 100 `timescale 1ns / 1ns module clk_time0; reg d, clk; reg q;
Sunburst Design
clk Sponsored by assigned with blocking assignment
initial begin clk = 1; forever #(`cycle/2) clk = ~clk; end initial begin $timeformat(-9,0,"ns",6); $monitor("%t: q=%b d=%b clk=%b", $stime, q, d, clk); d <= 1; @(negedge clk) d = ~d; @(negedge clk) d = ~d; @(negedge clk) $finish; end always @(posedge clk) q <= d;
0ns: q=x d=1 clk=1 50ns: q=x d=0 clk=0 CLK HIGH at time 0 100ns: q=0 d=0 clk=1 150ns: q=0 d=1 clk=0 200ns: q=1 d=1 clk=1
53
`define cycle 100 `timescale 1ns / 1ns module clk_time0; reg d, clk; reg q;
Sunburst Design
SponsoredAssign by
initial begin clk <= 1; forever #(`cycle/2) clk = ~clk; end initial begin $timeformat(-9,0,"ns",6); $monitor("%t: q=%b d=%b clk=%b", $stime, q, d, clk); d <= 1; @(negedge clk) d = ~d; @(negedge clk) d = ~d; @(negedge clk) $finish; end always @(posedge clk) q <= d;
CLK HIGH at time 0 0ns: q=1 d=1 clk=1 50ns: q=1 d=0 clk=0 100ns: q=0 d=0 clk=1 150ns: q=0 d=1 clk=0 200ns: q=1 d=1 clk=1
54
Sunburst Design
Sponsored by
Problem: the simulation ends before the last value is printed Reason: The $finish command was scheduled in the active events queue
55
Sunburst Design
Sponsored by
$monitor
initial begin $monitor ("MONITOR: cnt=%0d", cnt); cnt = 1; repeat (7) begin @(posedge clk) cnt = cnt+1; $strobe("STROBE : cnt=%0d", cnt); end $finish $finish; end command initial wait(cnt==8) $display("DISPLAY: cnt=%0d", cnt); endmodule
$strobe
56
Sunburst Design
Sponsored by
$monitor
initial begin $monitor ("MONITOR: cnt=%0d", cnt); cnt = 1; repeat (7) begin @(posedge clk) cnt = cnt+1; $strobe("STROBE : cnt=%0d", cnt); end #1 $finish #1 $finish; end command initial wait(cnt==8) $display("DISPLAY: cnt=%0d", cnt); endmodule
$strobe
57
Sunburst Design
Sponsored by
Guideline #6: Use $strobe to display values of variables that have been assigned by nonblocking assignments
Do not use $display to display variables assigned by nonblocking assignments
58
Sunburst Design
Sponsored by
Guideline #1: Sequential logic and latches - use nonblocking assignments Guideline #2: Combinational logic in an always block - use blocking assignments Guideline #3: Mixed sequential and combinational logic in the same always block is sequential logic - use nonblocking assignments Guideline #4: In general, do not mix blocking and nonblocking assignments in the same always block Guideline #5: Do not make assignments to the same variable from more than one always block Guideline #6: Use $strobe to display values that have been assigned using nonblocking assignments Guideline #7: Do not make #0 procedural assignments
Follow these guidelines to remove 90-100% of all Verilog race conditions
59
Sponsored by
Sunburst Design
60
Sunburst Design
Sponsored by
Verilog is case sensitive Make Verilog file names match the Verilog module names
Example: file name: asicTop.v module name: asicTop
Advantages
Easier to compile all necessary files using the -y library directory command line switch Easier to build synthesis scripts with a single list of designs that also serve as a list of file names
61
Sunburst Design
Sponsored by
case statement
case expression
always @(a or b or sela) begin case item case (sela) statements 1'b0: y = b; case items 1'b1: y = a; default: $display("%m: ERROR sela=%b", sela); endcase case default end endmodule
62
Sunburst Design
Sponsored module cx1 by (y, output [1:0] input reg [1:0]
a); y; a; y;
= = = =
0; 1; 2; 3;
= = = =
0; 1; 2; 3;
always @(a) begin casex (a) 1'b0: y casex 1'b1: y statement 1'bz: y 1'bx: y endcase end endmodule casex 0 1 0 0
= = = =
0; 1; 2; 3;
casez 0 1 0 3
63
Casex
module code6 (memce0, memce1, cs, en, addr); output memce0, memce1, cs; Sponsored by input en; input [31:30] addr; reg memce0, memce1, cs; always @(addr or en) begin {memce0, memce1, cs} = 3'b0; casex ({addr, en}) 3'b101: memce0 = 1'b1; 3'b111: memce1 = 1'b1; 3'b0?1: cs = 1'b1; endcase end endmodule addr[31:30] en memce0 memce1 cs 2'b10 1'bx
Sunburst Design
Wrong!
64
Casex
Synthesized result addr[31] addr[30] en
Sunburst Design
Sponsored by
memce1
memce0
cs
65
Casez
module code7 (memce0, memce1, cs, en, addr); output memce0, memce1, cs; Sponsored by input en; input [31:30] addr; reg memce0, memce1, cs; always @(addr or en) begin {memce0, memce1, cs} = 3'b0; casez ({addr, en}) 3'b101: memce0 = 1'b1; 3'b111: memce1 = 1'b1; 3'b0?1: cs = 1'b1; endcase end endmodule addr[31:30] en memce0 memce1 cs 2'b10 1'bz
Sunburst Design
Wrong!
66
Casez
Synthesized result addr[31] addr[30] en
Sunburst Design
Sponsored by
memce1
memce0
cs
67
Sunburst Design
Sponsored by
Guideline: Do not use casex for synthesizable code Guideline: Exercise caution when coding synthesizable models using the Verilog casez statement Coding Style Guideline: When coding a case statement with "don't cares":
use a casez statement use "?" characters instead of "z" characters in the case items to indicate "don't care" bits
68
Sunburst Design
Sponsored by
The "full_case" and "parallel_case" directives are ignored by simulation but change the behavior of synthesis tools
These switches can make some designs smaller and faster These switches can make some designs larger and slower These switches can change the functionality of the design THESE SWITCHES ARE ALWAYS MOST DANGEROUS WHEN THEY WORK!
69
Sponsored by
Sunburst Design
State Machines
Abbreviated FSMs (Finite State Machines)
70
Sunburst Design
Sponsored by
Moore - outputs are only a function of the present state Mealy - one or more of the outputs are a function of the present state and one or more of the inputs For an n-state FSM (examples on next slide):
Binary (highly encoded) = Ceiling log2n flip-flops 5 states -> 3 FFs (fewest number of FFs) One-Hot = n flip-flops 5 states -> 5 FFs (smaller combinational logic)
71
Sunburst Design
Sponsored by
IDLE
110 001 10000
IDLE
00010
READ
B1
READ
B1
011 010
00100 01000
B3
B2
B3
B2
72
Sunburst Design
Sponsored by
combinational logic
state
next
outputs
clock
73
Sunburst Design
Sponsored by
74
Sunburst Design
Sponsored by
Guideline: Make state assignments using parameters with symbolic state names
Generally better than `define state definitions (examples on next two slides)
75
Sunburst Design
Sponsored by
`define IDLE 2b00 `define READ 2b01 `define S2 2b10 module fsm2 ( ... ); ... endmodule Bad coding style!!
IDLE
IDLE
READ
B1
B3
B2
S2
READ
76
Sunburst Design
Sponsored by
module fsm2 ( ... ); ... parameter IDLE = 2b00, READ = 2b01, S2 = 2b10; ... endmodule Good coding style!!
IDLE
IDLE
READ
B1
B3
B2
S2
READ
77
Sunburst Design
Sponsored by
= = = = =
= = = = =
78
Sunburst Design
Sponsored by
(1) Code a sequential always block to represent the statevector register (2) Code a combinational always block to represent the nextstate combinational logic (3) Combinational outputs can be coded using either:
Continuous-assignment outputs - OR Include the output assignments in the combinational next-state always block
79
Sunburst Design
Sponsored by
DONE ds=1
READ rd=1
80
Sunburst Design
Sponsored by
module sm2a (rd, ds, go, ws, clk, rstN); output rd, ds; input go, ws, clk, rstN; parameter IDLE READ DLY DONE = = = = 2'b00, 2'b01, 2'b10, 2'b11;
reg [1:0] state, next; always @(posedge clk or negedge rstN) if (!rstN) state <= IDLE; else state <= next; ...
81
Sunburst Design
Sponsored by
82
Sunburst Design
Sponsored by
... always @(state or go or ws) begin next = 2'bx; rd = 1'b0; ds = 1'b0; Initial default case (state) value assignment IDLE : if (go) next = READ; - initializes the else next = IDLE; outputs to a READ : begin rd = 1'b1; default state next = DLY; end DLY : begin rd = 1'b1; if (!ws) next = DONE; else next = READ; end DONE : begin ds = 1'b1; next = IDLE; end endcase Output method #2 end (always-block assignments) endmodule
83
Sunburst Design
Sponsored by
Simulation/synthesis trick!
x-assignments are treated as dont-cares by synthesis x-assignments are treated as unknowns in simulation A missing next-state assignment will become obvious during simulation (FSM debugging trick!)
84
Sunburst Design
Sponsored by
85
Sunburst Design
Sponsored by
86
Sunburst Design
Sponsored by
87
Sunburst Design
Sponsored by go=0 Except where noted, outputs rd and IDLE ds equal 0 go=1 DONE ds=1 ws=0 READ rd=1
sequential logic
State registers
state
DLY rd=1
ws=1
outputs
Output FFs
Output registers
88
Registered Outputs
(Add a third (sequential) always block)
Sunburst Design
Sponsored by
always @(posedge clk or negedge rst_n) if (!rst_n) begin ds <= 1'b0; Easy to register outputs rd <= 1'b0; for Moore State Machines end else begin ds <= 1'b0; rd <= 1'b0; The next registered case (next) output depends on READ: rd <= 1'b1; the next state DLY: rd <= 1'b1; DONE: ds <= 1'b1; endcase end endmodule
State register, sequential always block Next state, combinational always block
89 module fsm1b (ds, rd, go, ws, clk, rst_n); output ds, rd; input go, ws; input clk, rst_n; reg ds, rd;
Sunburst Design
parameter [1:0] IDLE = 2'b00, READ = 2'b01, Sponsored=by DLY 2'b10, DONE = 2'b11; reg [1:0] state, next; always @(posedge clk or negedge rst_n) if (!rst_n) state <= IDLE; else state <= next; always @(state or go or ws) begin next = 2'bx; case (state) IDLE: if (go) next = READ; else next = IDLE; READ: DLY: next = DLY; if (ws) next = READ; else next = DONE; next = IDLE;
State registers
ws Output registers
DONE: endcase end
ds go rd clk rst_n
always @(posedge clk or negedge rst_n) if (!rst_n) begin ds <= 1'b0; rd <= 1'b0; end else begin ds <= 1'b0; rd <= 1'b0; case (next) READ: rd <= 1'b1; DLY: rd <= 1'b1; DONE: ds <= 1'b1; endcase end endmodule
90
Sunburst Design
Sponsored by
Mealy Machine - One or more outputs are a function of the Present State and one or more of the inputs How are Mealy outputs coded?
Continuous assignments
assign <out> = (state == READ) & !read_strobe_n;
91
Sunburst Design
Sponsored by
module sm1htfpa (rd, ds, go, ws, clk, rstN); output rd, ds; input go, ws, clk, rstN; Same example One-Hot coding style parameter IDLE = 0, READ = 1, DLY = 2, These are index DONE = 3; values into the state register reg [3:0] state, next; always @(posedge clk or negedge rstN) if (!rstN) begin state <= 4'b0; state[IDLE] <= 1'b1; end else state <= next; ...
92
Sunburst Design
Sponsored by
In general, full_case & parallel_case will make a ... size and speed difference always @(state or go or ws) begin next = 4'b0; case (1'b1) // synopsys full_case parallel_case state[IDLE] : if (go) next[READ] = 1'b1; else next[IDLE] = 1'b1; state[READ] : next[DLY] = 1'b1; state[DLY] : if (!ws) next[DONE] = 1'b1; else next[READ] = 1'b1; state[DONE] : next[IDLE] = 1'b1; endcase end assign rd = (state[READ] || state[DLY]); assign ds = (state[DONE]); endmodule
93
FSM Summary
Sunburst Design
Sponsored by
Many ways to infer state machines (many obscure ways!) One-Hot state machine using case (1'b1)
Style is unique to Verilog Using parallel_case directive makes a positive difference
94
Sponsored by
Sunburst Design
95
Sunburst Design
Sponsored by
96
Sunburst Design
Sponsored by
#1 - Verilog generate statement #2 - Multi-dimensional arrays #3 - Better Verilog file I/O #4 - Re-entrant tasks #5 - Better configuration control
NOTE: Verilog-2001 in this section is not fully tested! (waiting for a V2001 simulator!)
97
Sunburst Design
data1_0[1]
en
data1_1[1]
en
data1_2[1]
en
data1_3[1]
dout1[1]
data1_1[0]
en
data1_2[0]
en
data1_3[0]
dout1[0]
data0_1[1]
en
data0_2[1]
en
data0_3[1]
dout0[1]
data0_0[0]
en[1]
en
data0_1[0]
en
data0_2[0]
en
data0_3[0]
dout0[0]
en[0]
98
Sunburst Design
Sponsored by
module dualpipe (dout1, dout0, din, en, clk, rst_n); output [1:0] dout1, dout0; input [1:0] din, en; input clk, rst_n; wire [1:0] data0_0, data0_1, data0_2, data0_3, data1_0, data1_1, data1_2, data1_3;
2-bit assignments
dff u000 (.q(data0_1[0]), .d(data0_0[0]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u010 (.q(data0_2[0]), .d(data0_1[0]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u020 (.q(data0_3[0]), .d(data0_2[0]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u001 (.q(data0_1[1]), .d(data0_0[1]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u011 (.q(data0_2[1]), .d(data0_1[1]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u021 (.q(data0_3[1]), .d(data0_2[1]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u100 (.q(data1_1[0]), .d(data1_0[0]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u110 (.q(data1_2[0]), .d(data1_1[0]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u120 (.q(data1_3[0]), .d(data1_2[0]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u101 (.q(data1_1[1]), .d(data1_0[1]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u111 (.q(data1_2[1]), .d(data1_1[1]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u121 (.q(data1_3[1]), .d(data1_2[1]), .clk(clk), .en(en[1]), .rst_n(rst_n)); assign dout1 = data1_3; assign dout0 = data0_3; endmodule
99
Multi-Dimensional
Verilog-2001 Enhancement #2
Sunburst Design
Sponsored by
module dualpipe_v2k (dout1, dout0, din, en, clk, rst_n); output [1:0] dout1, dout0; input [1:0] din, en; input clk, rst_n; wire [1:0] data [1:0] [3:0];
Synthesizable Soon!
data[1][0][1]
en
data[1][1][1]
en
data[1][2][1]
en
data[1][3][1]
dout1[1]
data[1][1][0]
en
data[1][2][0]
en
data[1][3][0]
dout1[0]
data[0][1][1]
en
data[0][2][1]
en
data[0][3][1]
dout0[1]
data[0][0][0]
en[1]
en
data[0][1][0]
en
data[0][2][0]
en
data[0][3][0]
dout0[0]
en[0]
100
Sunburst Design
Sponsored by
module dualpipe_v2k (dout1, dout0, din, en, clk, rst_n); output [1:0] dout1, dout0; input [1:0] din, en; input clk, rst_n;
dff u000 (.q(data[0][1][0]), .d(data[0][0][0]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u010 (.q(data[0][2][0]), .d(data[0][1][0]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u020 (.q(data[0][3][0]), .d(data[0][2][0]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u001 (.q(data[0][1][1]), .d(data[0][0][1]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u011 (.q(data[0][2][1]), .d(data[0][1][1]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u021 (.q(data[0][3][1]), .d(data[0][2][1]), .clk(clk), .en(en[0]), .rst_n(rst_n)); dff u100 (.q(data[1][1][0]), .d(data[1][0][0]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u110 (.q(data[1][2][0]), .d(data[1][1][0]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u120 (.q(data[1][3][0]), .d(data[1][2][0]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u101 (.q(data[1][1][1]), .d(data[1][0][1]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u111 (.q(data[1][2][1]), .d(data[1][1][1]), .clk(clk), .en(en[1]), .rst_n(rst_n)); dff u121 (.q(data[1][3][1]), .d(data[1][2][1]), .clk(clk), .en(en[1]), .rst_n(rst_n)); assign dout1 = data[1][3]; assign dout0 = data[0][3]; endmodule
101
Generate Statement
Verilog-2001 Enhancement #1
module dualpipe (dout1, dout0, din, en, clk, rst_n); output [1:0] dout1, dout0; input [1:0] din, en; input clk, rst_n; genvar i, j, k; wire [1:0] data [1:0] [3:0]; assign data[1][0] = din; assign data[0][0] = din; generate for (i=0; i<=1; i=i+1) begin: ff1 generate for (j=0; j<=2; j=j+1) begin: ff2 generate for (k=0; k<=1; k=k+1) begin: ff3
Sunburst Design
Sponsored by
Synthesizable Soon!
Three genvar variables declared: i, j, k 3-dimensional wire array declaration Named blocks are required Three nested generate for-loops
dff u1 (.q(data[i][j+1][k]), .d(data[i][j][k]), .clk(clk), .en(en[i]), .rst_n(rst_n)); endgenerate endgenerate endgenerate assign dout1 = data[1][3]; assign dout0 = data[0][3]; endmodule
First generated dff instance name: ff1[0].ff2[0].ff3[0].u1 Last generated dff instance name: ff1[1].ff2[2].ff3[1].u1
102
Sunburst Design
Sponsored by
Restrictions
Genvars shall be declared within the module where they are used Genvars can be declared either inside or outside of a generate scope Genvars are positive integers that are local to and only used within a generate loop that uses them as index variables Genvars are only defined during the evaluation of the generate blocks Genvars do not exist during simulation of a Verilog design No nesting of generate loops that use the same genvar index variable The value of a genvar can be referenced in any context where the value of a parameter could be referenced
103
Sunburst Design
Sponsored by
Synthesizable Soon!
module ... generate if ((A_WIDTH < 8) || (B_WIDTH < 8)) CLA_multiplier u1 (...); // CLA multiplier else WALLACE_multiplier u1 (...); // Wallace-tree multiplier endgenerate ... endmodule
case-generate
module ... generate case (1'b1) (WIDTH<6) : adder1 u1 (...); ((WIDTH>5) && (WIDTH<10)): adder2 u1 (...); (WIDTH>10) : adder3 u1 (...); endgenerate ... endmodule
104
Sunburst Design
Sponsored by
Not Synthesizable
Verilog-2001 File Descriptor integer MSB="1" integer fd; initial begin fd = $fopen ("file_name", type); ... $fclose(fd); end
r w a r+ w+ a+
Verilog-2001 File Types open for reading truncate to zero length or create for writing append; open for writing at end of file, or create for writing open for update (reading and writing) truncate or create for update append; open or create for update at end-of-file
105
Sunburst Design
Sponsored by
Tasks that output values into files Tasks that output values into variables Tasks/functions that read from files and load into variables or memories New Verilog-2001
$ferror $fgetc $fgets $fread $fscanf $fseek $ftell $fungetc $fungetf $rewind $sformat $sscanf $swrite $ungetc file I/O commands
Verilog-2001 files and Verilog-1995 files can both be used in the same testbench
106
Sunburst Design
Sponsored by
Synthesizable Soon!
module ... task write1; ... endtask task automatic write2; ... endtask ... endmodule Verilog-1995 tasks use static variables
107
Sunburst Design
Sponsored by
Synthesizable Soon!
RTL Adder
Simulation specification #1 addertop.a1 - RTL model addertop.a2 - RTL model file: rtl.cfg config rtl; design rtlLib.addertop; default liblist rtlLib; endconfig
Simulation specification #2 addertop.a1 - RTL model addertop.a2 - gate-level model Libraries on the config mixed; next slide design rtlLib.addertop; default liblist rtlLib; instance addertop.a2 liblist gateLib; endconfig file: mixed.cfg
108
Simulation Configurations
Verilog-2001 Enhancement #5
Directory structure
proj1
Sunburst Design
Sponsored by
file: addertop.v
gates tb vlog
adder.vg
lib.map rtl.cfg
addertop.v adder.v
module addertop(); adder a1(...); adder a2(...); endmodule file: adder.v module adder(); // RTL adder // description endmodule
mixed.cfg
file: lib.map rtl.cfg & mixed.cfg on previous slide library rtlLib ../proj1/vlog/*.v library gateLib ../proj1/gates/*.vg
109
Sunburst Design
Sponsored by
Synthesizable Soon!
q - in the port list q - port type is "output" q - data type is "reg" Verbose port declarations
always @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= d; endmodule
module dffarn ( output reg q, input d, clk, rst_n); always @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= d; endmodule
110
Sunburst Design
Sponsored by
Synthesizable Soon!
module ram1 (addr, data, en, rw_n); parameter ADDR_SIZE = 10; parameter DATA_SIZE = 8; parameter MEM_DEPTH = 1<<ADDR_SIZE; output [DATA_SIZE-1:0] data; input [ADDR_SIZE-1:0] addr; input en, rw_n; reg [DATA_SIZE-1:0] mem [0:MEM_DEPTH-1];
assign data = (rw_n && en) ? mem[addr] : {DATA_SIZE{1'bz}}; always @(addr, data, rw_n, en) if (!rw_n && en) mem[addr] = data; endmodule Comma-separated sensitivity list
111
Sunburst Design
Sponsored by
module code1a (o, a, b); output o; Full sensitivity list input a, b; reg o; module code1b (o, a, b); output o; always @(a or b) Incomplete sensitivity list input a, b; o = a & b; reg o; endmodule "Warning: Variable 'b' ... always @(a) o = a & b; endmodule
does not occur in the timing control of the block ..."
Synthesized result!
module code1c (o, a, b); No sensitivity list output o; input a, b; "Warning: Variable 'a' ... does not occur in the timing reg o;
control of the block ..."
"Warning: Variable 'b' ... does not occur in the timing control of the block ..."
112
Sunburst Design
Sponsored by
module code1b (o, a, b); output o; input a, b; Pre-synthesis simulation reg o; does not match post-synthesis simulation always @(a) o = a & b; endmodule module code1c (o, a, b); output o; input a, b; Pre-synthesis reg o; simulation hangs! always o = a & b; endmodule
Synthesized result!
113
Sunburst Design
Sponsored by
Synthesized result!
114
Sunburst Design
Sponsored by
Synthesizable Soon!
module ram1 #(parameter ADDR_SIZE = parameter DATA_SIZE = localparam MEM_DEPTH = localparam(s) cannot be (output [DATA_SIZE-1:0] redefined when the input [ADDR_SIZE-1:0] model is instantiated input reg
assign data = (rw_n && en) ? mem[addr] : {DATA_SIZE{1'bz}}; always @* if (!rw_n && en) mem[addr] <= data; endmodule Combinational @* sensitivity list
115
Errata - @*
(Information Missing from the Verilog-2001 Standard)
module decoder ( output reg [7:0] y, input [2:0] a, input en); always @* begin y = 8'hff; y[a] = !en; end endmodule 3-to-8 decoder with enable @* is the same as @(a or en)
Sunburst Design
Sponsored by
... always @* begin next = 4'b0; Index variables should be case (1'b1) // synopsys parallel_case part of a combinational state[IDLE] : if (go) next[READ] = sensitivity list else next[IDLE] = state[READ] : next[DLY] = state[DLY] : if (!ws) next[DONE] = else next[READ] = Non-constant case-items state[DONE] : next[IDLE] = should be part of a endcase combinational sensitivity list end ...
116
Sunburst Design
module regblk (q, d, Sponsored byrst_n); ce, clk, parameter SIZE = 4; output [SIZE-1:0] q; input [SIZE-1:0] d; input ce, clk, rst_n; reg [SIZE-1:0] q; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 0; else if (ce) q <= d; endmodule
{d,n1} n1[7:0]
8
q
16
q[15:0]
d[7:0]
8
d q ce
ce_n
ce
ce clk rst_n
ce_n
117
defparam Redefinition
Verilog-1995
module demuxreg output [15:0] input [ 7:0] input wire [15:0] wire [ 7:0] (q, d, ce, clk, rst_n); q; d; A defparam can be ce, clk, rst_n; before the instance q; n1;
Sunburst Design
Sponsored by
not u0 (ce_n, ce); after the instance defparam u1.SIZE=8; regblk u1 (.q(n1), .d (d), .ce(ce), .clk(clk), .rst_n(rst_n)); regblk u2 (.q (q), .d({d,n1}), .ce(ce_n), .clk(clk), .rst_n(rst_n)); defparam u2.SIZE=16; endmodule A defparam can be in a whole separate file!!
A defparam can be
module regblk (q, d, ce, clk, rst_n); parameter SIZE = 4; output [SIZE-1:0] q; input [SIZE-1:0] d; input ce, clk, rst_n; reg [SIZE-1:0] q; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 0; else if (ce) q <= d; endmodule
118
Sunburst Design
Sponsored by
not u0 (ce_n, ce); regblk #( 8) u1 (.q(n1), .d (d), .ce(ce), .clk(clk), .rst_n(rst_n)); regblk #(16) u2 (.q (q), .d({d,n1}), .ce(ce_n), .clk(clk), .rst_n(rst_n)); endmodule
Passing parameters by position One serious disadvantage: When passing parameters by position, all parameters up to and including the changed parameters must be listed, even if some parameter values do not change!!
module regblk (q, d, ce, clk, rst_n); parameter SIZE = 4; output [SIZE-1:0] q; input [SIZE-1:0] d; input ce, clk, rst_n; reg [SIZE-1:0] q; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 0; else if (ce) q <= d; endmodule
119
Sunburst Design
Sponsored by
not u0 (ce_n, ce); regblk #( .SIZE(8)) u1 (.q(n1),.d (d), .ce(ce), .clk(clk),.rst_n(rst_n)); regblk #(.SIZE(16)) u2 (.q (q),.d({d,n1}),.ce(ce_n),.clk(clk),.rst_n(rst_n)); endmodule
Parameter redefinition using named parameters (same syntax as named port connections) Only the parameters that change must be listed
module regblk (q, d, ce, clk, rst_n); parameter SIZE = 4; output [SIZE-1:0] q; input [SIZE-1:0] d; input ce, clk, rst_n; reg [SIZE-1:0] q; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 0; else if (ce) q <= d; endmodule
120
Sunburst Design
Sponsored by
q
16
q[15:0]
d[7:0]
8
d q ce
n1[7:0]
8
ce_n
ce_n
not u0 (ce_n, ce); regblk #( .SIZE(8)) u1 (.q(n1),.d (d), .ce(ce), .clk(clk),.rst_n(rst_n)); regblk #(.SIZE(16)) u2 (.q (q),.d({d,n1}),.ce(ce_n),.clk(clk),.rst_n(rst_n)); endmodule
121
Parameter Redefinition
Guideline: Do not use defparam statements
Extra line of code Can be anywhere and in any file In-house tools are harder to implement
Sunburst Design
Sponsored by
Guideline: Use instantiated models with the new Verilog-2001 named parameter redefinition
122
Sunburst Design
module top_pads1 (pdata, paddr, pctl1, pctl2, pwr, pclk); Sponsored by input [15:0] pdata; // pad data bus inout [31:0] paddr; // pad addr bus input pctl1, pctl2, pwr, pclk; // pad signals wire [15:0] data; // data bus wire [31:0] addr; // addr bus main_blk u1 (.data(data), .addr(addr), .sig1(ctl1), .sig2(ctl2), .sig3(wr), .clk(clk)); IBUF IBUF IBUF IBUF c4 c3 c2 c1 (.O( wr), (.O(ctl2), (.O(ctl1), (.O( clk), .pI( pwr)); .pI(pctl2)); .pI(pctl1)); .pI( pclk));
BIDIR BIDIR ... BIDIR BIDIR IBUF IBUF IBUF ... IBUF IBUF IBUF
b15 (.N2(data[15]), .pN1(pdata[15]), .WR(wr)); b14 (.N2(data[14]), .pN1(pdata[14]), .WR(wr)); b1 b0 (.N2(data[ 1]), .pN1(pdata[ 1]), .WR(wr)); (.N2(data[ 0]), .pN1(pdata[ 0]), .WR(wr));
i31 (.O(addr[31]), .pI(paddr[31])); i30 (.O(addr[30]), .pI(paddr[30])); i29 (.O(addr[29]), .pI(paddr[29])); i2 i1 i0 (.O(addr[ 2]), .pI(paddr[ 2])); (.O(addr[ 1]), .pI(paddr[ 1])); (.O(addr[ 0]), .pI(paddr[ 0]));
endmodule
123
Sunburst Design
Sponsored by pwr, pclk); pad data bus pad addr bus pad signals data bus addr bus
module top_pads2 (pdata, paddr, pctl1, pctl2, input [15:0] pdata; // inout [31:0] paddr; // input pctl1, pctl2, pwr, pclk; // wire [15:0] data; // wire [31:0] addr; //
main_blk u1 (.data(data), .addr(addr), .sig1(ctl1), .sig2(ctl2), .sig3(wr), .clk(clk)); genvar i; IBUF IBUF IBUF IBUF c4 c3 c2 c1 (.O( wr), (.O(ctl2), (.O(ctl1), (.O( clk), .pI( pwr)); .pI(pctl2)); .pI(pctl1)); .pI( pclk));
generate for (i=0; i<16; i=i+1) begin: dat BIDIR b1 (.N2(data[i]), .pN1(pdata[i]), .WR(wr)); endgenerate generate for (i=0; i<32; i=i+1) begin: adr IBUF i1 (.O(addr[i]), .pI(paddr[i])); endgenerate endmodule
124
Synthesizable
module top_pads3 (pdata, paddr, pctl1, pctl2, input [15:0] pdata; // inout [31:0] paddr; // input pctl1, pctl2, pwr, pclk; // wire [15:0] data; // wire [31:0] addr; //
main_blk u1 (.data(data), .addr(addr), .sig1(ctl1), .sig2(ctl2), .sig3(wr), .clk(clk)); IBUF IBUF IBUF IBUF c4 c3 c2 c1 (.O( wr), (.O(ctl2), (.O(ctl1), (.O( clk), .pI( pwr)); .pI(pctl2)); .pI(pctl1)); .pI( pclk));
endmodule
125
Sunburst Design
Sponsored by pwr, pclk); pad data bus pad addr bus pad signals data bus addr bus
module top_pads3 (pdata, paddr, pctl1, pctl2, input [15:0] pdata; // inout [31:0] paddr; // input pctl1, pctl2, pwr, pclk; // wire [15:0] data; // wire [31:0] addr; //
main_blk u1 (@*, .sig1(ctl1), .sig2(ctl2), .sig3(wr)); IBUF IBUF IBUF IBUF c4 c3 c2 c1 (.O( wr), (.O(ctl2), (.O(ctl1), (.O( clk), .pI( pwr)); .pI(pctl2)); .pI(pctl1)); .pI( pclk));
BIDIR b[15:0] (.N2(data), .pN1(pdata), .WR(wr)); IBUF i[31:0] (.O(addr), .pI(paddr)); endmodule
126
Attributes
New tokens
(* *)
VSG members call these "funny braces"
Sunburst Design
Sponsored by
(* attribute_name = constant_expression *) -or(* attribute_name *) Synthetic comments require that all comments are parsed // rtl_synthesis full_case parallel_case replace with (* rtl_synthesis, full_case, parallel_case *) Put tool directives into attributes to eliminate the need to parse comments
127
Sunburst Design
Sponsored by
Mostly Synthesizable ??
Removed: net declaration requirement for LHS of continuous assignment to an internal net Added: `default_nettype none Initialize variables in the declaration Indexed vector part selects
128
Sunburst Design
Sponsored by
Two behavioral capabilities broke in Verilog-2001 File I/O (one corner case)
Verilog-1995 permits 31 open files, each open file sets one integer bit Verilog-2001 steals the integer-MSB for new file I/O file handles 1,000's of open files are now possible If a design uses exactly 31 open files, the new file I/O enhancement will cause a conflict Work-around: replace one of the open files with a Verilog-2001 file
129
Sunburst Design
Sponsored by
`bz assignments assign up to 32 Z's and then pad the MSBs with all 0's Any design that counts on this behavior deserves to be broken!
module tribuf (y, a, en); parameter SIZE = 64; output [SIZE-1:0] y; input [SIZE-1:0] a; input en; assign y = en ? a : 'bz; endmodule module tribuf (y, a, en); parameter SIZE = 64; output [SIZE-1:0] y; input [SIZE-1:0] a; input en; assign y = en ? a : {SIZE{1'bz}}; endmodule
Parameterized model: three-state driver (Works for both Verilog-1995 & Verilog-2001)
130
Errata
A Few Mistakes "Slipped" Into The LRM
Sunburst Design
Sponsored by
function integer clogb2; If depth = 0 the for-loop input depth; never executes ... integer i,result; begin for (i = 0; 2 ** i < depth; i = i + 1) result = i + 1; Simple 1-statement clogb2 = result; implementation end endfunction function integer clogb2; input [31:0] value; ... result is never for (clogb2=0; value>0; clogb2=clogb2+1) initialized and ... value = value>>1; endfunction ... clogb2 is assigned "X"
131
Sunburst Design
Sponsored by
Build a parameterized Barrel Shifter model (Verilog-1995) Convert the model into a parameterized Verilog-2001 model Instantiate the model into a Barrel-Shift register
132
Barrel Shifter
Example
Barrel Shifter model from a popular synthesis book
Sunburst Design
Sponsored by
module SHIFTER_BARREL (Rotate, A, Y); input [2:0] Rotate; input [5:0] A; function [5:0] rol6; output [5:0] Y; input [5:0] A; reg [5:0] Y; input [2:0] NoShifts; always @(Rotate or A) begin: COMB_BARREL_SHIFT case (Rotate) 0: Y = A; 1: Y = rol6(A, 1); 2: Y = rol6(A, 2); 3: Y = rol6(A, 3); 4: Y = rol6(A, 4); 5: Y = rol6(A, 5); default : Y = 6'bx; endcase end reg [6:0] A_ExtendLeft; integer N; begin A_ExtendLeft = {1'b0, A}; for (N=1; N<=NoShifts; N=N+1) begin A_ExtendLeft = A_ExtendLeft << 1; A_ExtendLeft[0] = A_ExtendLeft[6]; end rol6 = A_ExtendLeft[5:0]; end endfunction endmodule
133
Barrel Shifter
Better RTL Model
module barrel_shifter (y, a, rotate_cnt); output [5:0] y; input [2:0] rotate_cnt; input [5:0] a; wire [5:0] tmp; assign {y,tmp} = {a,a} << rotate_cnt; endmodule
Sunburst Design
Sponsored by
module SHIFTER_BARREL (Rotate, A, Y); input [2:0] Rotate; input [5:0] A; output [5:0] Y; reg [5:0] Y; always @(Rotate or A) begin: COMB_BARREL_SHIFT case (Rotate) 0: Y = A; 1: Y = {A[4:0],A[5]}; 2: Y = {A[3:0],A[5:4]}; 3: Y = {A[2:0],A[5:3]}; 4: Y = {A[1:0],A[5:2]}; 5: Y = {A[0] ,A[5:1]}; default : Y = 6'bx; endcase end endmodule
is equivalent to
{y,tmp} = {a[(WIDTH-1)-rotate_cnt:0],a[WIDTH-1:0],{rotate_cnt{1'b0}}}
134
Barrel Shifter
Two-Parameter RTL Model
module barrel_shifter (y, a, rotate_cnt); output [5:0] y; input [2:0] rotate_cnt; input [5:0] a; wire [5:0] tmp; assign {y,tmp} = {a,a} << rotate_cnt; endmodule module barrel_shifter (y, a, rotate_cnt); parameter WIDTH = 6; parameter CNT_SIZE = 3; output [WIDTH-1:0] y; input [CNT_SIZE-1:0] rotate_cnt; input [WIDTH-1:0] a; wire [WIDTH-1:0] tmp; assign {y,tmp} = {a,a} << rotate_cnt; endmodule
Sunburst Design
Sponsored by
135
Sunburst Design
module barrel_shifter #( parameter = WIDTH Sponsored by = 6, parameter = CNT_SIZE = 3); (output [WIDTH-1:0] y, input [CNT_SIZE-1:0] rotate_cnt, input [WIDTH-1:0] a ); wire [WIDTH-1:0] tmp; assign {y,tmp} = {a,a} << rotate_cnt; endmodule
One parameter WIDTH localparam and a constant function are used to set the CNT_SIZE
module barrel_shifter #( parameter WIDTH = 6, localparam CNT_SIZE = clogb2(WIDTH)); (output [WIDTH-1:0] y, input [CNT_SIZE-1:0] rotate_cnt, input [WIDTH-1:0] a ); wire [WIDTH-1:0] tmp; assign {y,tmp} = {a,a} << rotate_cnt; function integer clogb2; input [31:0] value; for (clogb2=0; value>0; clogb2=clogb2+1) value = value>>1; endfunction endmodule
136
ANSI-C
and ports
module barrel_shifter #( parameter WIDTH = 6, localparam CNT_SIZE = clogb2(WIDTH)); (output [WIDTH-1:0] y, input [CNT_SIZE-1:0] rotate_cnt, input [WIDTH-1:0] a ); wire [WIDTH-1:0] tmp; assign {y,tmp} = {a,a} << rotate_cnt; function integer clogb2; input [31:0] value; for (clogb2=0; value>0; clogb2=clogb2+1) value = value>>1; endfunction endmodule Constant
module barrel_reg ( output reg [7:0] input [7:0] input [2:0] input wire [7:0]
always @(posedge clk, negedge rst_n) if (!rst_n) q <= 8'b0; else q <= bs;
137
Sunburst Design
Sponsored by
always @(posedge clk, negedge rst_n) if (!rst_n) q <= 8'b0; else q <= bs; assign {bs,tmp} = {din,din} << rot; endmodule
138
Verilog-2001 Advantages
increased design productivity enhanced synthesis capability improved verification efficiency
Sunburst Design
Sponsored by
139
Sponsored by
Sunburst Design
140
141
Sunburst Design
Sponsored by
# vsim -do {run -all} -c tb # Loading work.tb # Loading work.myand2 # WARNING: myand2.v(5): [TFMPC] - Too few port connections. # Region: /tb/u1 ...
142
143
Sunburst Design
Sponsored by
To run ModelSim in speed-optimized mode, add two vlog command line switches:
vlog -fast -O5 <list of files or command-file> Very important for ModelSim users!
What's the difference? Module boundaries are flattened and loops are optimized so some levels of debugging hierarchy are eliminated
Significantly faster simulation performance
144
Sunburst Design
Sponsored by
`ifdef RTL reg q; always @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= d; `endif `ifdef UDP udpdff u1 (q, d, clk, rst_n); `endif endmodule
primitive udpdff (q, d, clk, rst_n); output q; input d, clk, rst_n; reg q; table // d clk rst_n : q : qnext ? ? 0 : ? : 0 ; 0 r 1 : ? : 0 ; 1 r 1 : ? : 1 ; // ignore falling transitions // on clk ? f 1 : ? : - ; // ignore transitions on d * ? ? : ? : - ; endtable endprimitive
145
146
Comparing Waveforms
The default file vsim.wlf will be re-written on the next simulation
Sunburst Design
Sponsored by
The "waves" window goes blank after executing the quit -sim command
147
Comparing Waveforms
Either quit the simulation (to create another valid vsim.wlf file) -ORrun comparison with the current data set (current simulation)
Comparing Waveforms
148
Sunburst Design
Sponsored by
Select a second .wlf file (example: udpbug.wlf) -ORUse the current simulation data set At the end of each step, click on Next>
149
Comparing Waveforms
Sunburst Design
Sponsored by
Click on Next> to use the signals from the two selected data sets
150
Comparing Waveforms
X marks
the spot! Expand the different signals The differences are highlighted
Sunburst Design
Sponsored by
151
Sunburst Design
Sponsored by
primitive udpdff (q, d, clk, rst_n); output q; input d, clk, rst_n; reg q; table // d clk rst_n : q : qnext ? ? 0 : ? : 0 ; 0 r 1 : ? : 0 ; 1 r 1 : ? : 1 ; // ignore falling transitions // on clk ? f 1 : ? : - ; // ignore transitions on d * ? ? : ? : - ; // ignore transitions on rst_n ? ? * : ? : - ; endtable endprimitive
152
Sunburst Design
Sponsored by
Some papers with more details can be found at the Sunburst Design web site:
www.sunburst-design.com/papers
(Bad web site that might improve some day!) Papers with more details about the Verilog Seminar topics:
CummingsHDLCON2001_Verilog2001_rev1_1.pdf CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf CummingsSNUG1999SJ_SynthMismatch_rev1_1.pdf CummingsSNUG2000Boston_FSM_rev1_1.pdf CummingsSNUG2000SJ_NBA_rev1_2.pdf