Verilog HDL
HDLs Hardware Description Languages
Widely used in logic design Verilog and VHDL
Describe hardware using code Document logic functions Simulate logic before building Synthesize code into gates and layout
Requires a library of standard cells
Module portsModule name
Verilog keywords
Taste of Verilog
module Add_half ( sum, c_out, a, b ); input a, b;
output sum, c_out;wire c_out_bar;
xor (sum, a, b);nand (c_out_bar, a, b);not (c_out, c_out_bar);
endmodule
Declaration of port modes
Declaration of internal signal
Instantiation of primitive gates
c_out
ab sum
c_out_bar
Behavioral Descriptionmodule Add_half ( sum, c_out, a, b ); input a, b;
output sum, c_out;reg sum, c_out;always @ ( a or b ) begin
sum = a ^ b; // Exclusive orc_out = a & b; // And
endendmodule
a
bAdd_half
sumc_out
Example of Flip-flop
module Flip_flop ( q, data_in, clk, rst );input data_in, clk, rst;output q;reg q;
always @ ( posedge clk ) begin
if ( rst == 1) q = 0;else q = data_in;
endendmodule
data_in
q
rst
clk
Declaration of synchronous behavior
Procedural statement
Gate Delay and (yout, x1, x2); // default, zero gate delay and #3 (yout, x1, x2); // 3 units delay for all transitions and #(2,3) G1(yout, x1, x2); // rising, falling delay and #(2,3) G1(yout, x1, x2), G2(yout2, x3, x4);
// Multiple instances a_buffer #(3,5,2) (yout, x); // UDP, rise, fall, turnoff bufif1 #(3:4:5, 6:7:9, 5:7:8) (yout, xin, enable);
// min:typ:max / rise, fall, turnoff
•Simulators simulate with only one of min, typ and max delay values •Selection is made through compiler directives or user interfaces•Default delay is typ delay
Time Scales Time scale directive: ‘ timescale <time_unit>/<time_precision> time_unit -> physical unit of measure, time scale of delay time_precision -> time resolution/minimum step size during
simulation time_unit time_precision
Unit/precision Delay specification
Simulator time step
Delay value in simulation
1ns / 100ps #4 0.1ns 4.0ns100ns / ns #4 1ns 400ns10ns / 100ps #4.629 0.1ns 46.3ns
Net Delay… …wire #2 y_tran;and #3 (y_tran, x1, x2);buf #1 (buf_out, y_tran);and #3 (y_inertial, x1, x2);… …
x1x2
y_tran
y_inertial
buf_out
2 4 6 8 10
2 4 6 8 10
2 4 6 8 10
2 4 6 8 10
2 4 6 8 10
x1
x2
y_inertial
y_tran
buf_out
Structural vs. Behavioral Descriptions
module my_module(…); … assign …; // continuous assignment and (…); // instantiation of primitive adder_16 M(…); // instantiation of module
always @(…) begin … end initial begin … endendmodule
Structural, no order
Behavior, in order in each procedure
Behavioral Statements
initial | alwayssingle_statement; |
begin block_of_statements;end
initial Activated from tsim = 0 Executed once Initialize a simulation
always Activated from tsim = 0 Executed cyclically Continue till simulation
terminates
Example of Behavioral Statement
module clock1 ( clk );parameter half_cycle = 50;parameter max_time = 1000;output clk;reg clk;initial clk = 0;always begin#half_cycle clk = ~clk; endinitial #max_time $finish;
endmodule
clk
tsim50 100
150
200
Assignment Continuous assignment
Values are assigned to net variables due to some input variable changes
“assign …=… “
Procedural assignment Values are assigned to register variables when certain
statement is executed in a behavioral description Procedural assignment, “=“ Procedural continuous assignment, “assign …=…
[deassign] “ Non-blocking assignment, “<=“
Procedural Continuous Assignment Continuous assignment establishes static binding for
net variables
Procedural continuous assignment (PCA) establishes dynamic binding for variables “assign … deassign” for register variables only
“assign … deassign” PCA Binding takes effect
when PCA statement is executed
Can be overridden by another PCA statement
“deassign” is optional
“assign” takes control, “deassign” release control
module flop ( q, qbar, preset, clear, clock, data );…assign qbar = ~q;initial
q = 0;always @ ( negedge clk )
q = data;always @ ( clear or preset )
begin if ( !preset ) assign q = 1; else if ( !clear ) assign q = 0; else deassign q;end
endmodule
Example of assign
module mux4_PCA(a, b, c, d, select, y_out); input a, b, c, d; input [1:0] select; output y_out; reg y_out;
always @(select) begin if (select == 0) assign y_out=a; else if (select == 1) assign y_out=b; else if (select == 2) assign y_out=c; else if (select == 3) assign y_out=d; else assign y_out=1’bx; end
endmodule
y_out changes with a;
Alternative module mux4_PCA(a, b, c, d, select, y_out); input a, b, c, d; input [1:0] select; output y_out; reg y_out;
always @(select or a or b or c or d) begin if (select == 0) y_out=a; else if (select == 1) y_out=b; else if (select == 2) y_out=c; else if (select == 3) y_out=d; else y_out=1’bx; end
endmodule
Value of ‘a’ is assigned to y_out at this time
Blocking and Non-blocking Assignment
initial begin
a = 1;b = 0;a = b; // a = 0;b = a; // b = 0;
end initial begin
a = 1;b = 0;a <= b; // a = 0;b <= a; // b = 1;
end
Blocking assignment “=“ Statement order matters A statement has to be executed
before next statement
Non-blocking assignment “<=“ Concurrent assignment If there are multiple non-
blocking assignments to same variable in same behavior, latter overwrites previous
Delay Control Operator (#)initial
begin#0 in1 = 0; in2 = 1;#10 in3 = 1;#40 in4 = 0; in5 = 1;#60 in3 = 0;end
Event Control Operator (@)
…@ ( eventA or eventB ) begin … @ ( eventC ) begin … endend
Event -> identifier or expression
When “@” is reached Activity flow is suspended The event is monitored Other processes keep going
posedge: 0->1, 0->x, x->1 negedge: 1->0, 1->x, x->0
The “wait” Construct
module modA (…);…
always begin … wait ( enable ) ra = rb; … end
endmodule
Activity flow is suspended if expression is false
It resumes when the expression is true
Other processes keep going
Intra-assignment Delay: Blocking Assignment
// B = 0 at time 0// B = 1 at time 4…#5 A = B; // A = 1C = D;…A = #5 B; // A = 0C = D;…A = @(enable) B;C = D;…A = @(named_event) B;C= D;…
If timing control operator(#,@) on LHS Blocking delay RHS evaluated at (#,@) Assignment at (#,@)
If timing control operator(#,@) on RHS Intra-assignment delay RHS evaluated immediately Assignment at (#,@)
Indeterminate Assignmentmodule multi_assign();
reg a, b, c, d;initial begin #5 a = 1; b = 0; endalways @ ( posedge a ) begin c = a;
endalways @ ( posedge a ) begin c = b;
endalways @ ( posedge a ) begin d = b;
endalways @ ( posedge a ) begin d = a;
endendmodule
Multiple assignments are made to same variable in different behaviors
Value depends on code order or vendor specifications
Similar to race-conditions in hardware
Activity Flow Control ( if … else )if ( A == B ) P = d;if ( B < C );if ( a >= b ) begin … end
if ( A < B ) P = d;else P = k;
if ( A > B ) P = d;else if ( A < B ) P = k;else P = Q;
Syntax: if ( expression ) statement [ else statement ]
Value of expression 0, x or z => false Non-zero number => true
Conditional Operator ( ? … : )
always @ ( posedge clock ) yout = ( sel ) ? a + b : a – b;
Conditional operator can be applied in
• either continuous assignments • or behavioral descriptions
The case Statementmodule mux4 ( a, b, c, d, select, yout ); input a, b, c, d; input [1:0] select; output yout; reg yout; always @( a or b or c or d or select ) begin case ( select ) 0: yout = a;
1: yout = b; 2: yout = c;
3: yout = d; default yout = 1`bx; endcase
endmodule
Case items are examined in order
Exact match between case expression and case item
casez – treats “z” as don’t cares
casex – treats both “x” and “z” as don’t cares
The repeat Loop
…word_address = 0;repeat ( memory_size )
begin memory [word_address] = 0; word_address = word_address + 1;end
…
The for Loopreg [15:0] regA;integer k;…for ( k = 4; k; k = k – 1 )
begin regA [ k+10 ] = 0; regA [ k+2 ] = 1;end
…
Loop variables have to be either integer or reg
The while Loopbegin cnt1s reg [7:0] tmp; cnt = 0; tmp = regA; while ( tmp )
begin cnt = cnt + tmp[0]; tmp = tmp >> 1; end
end
module sth ( externalSig ); input externalSig;
always begin while ( externalSig ); end
endmodule
Loop activities suspend external activities
The disable Statement
begin k = 0; for ( k = 0; k <= 15; k = k + 1 )
if ( word[ k ] == 1 ) disable ;end
Terminate prematurely in a block of procedural statements
The forever Loopparameter half_cycle = 50;
initial begin : clock_loop clock = 0; forever
begin#half_cycle clock = 1;#half_cycle clock = 0; end
end
initial #350 disable clock_loop;
Task module bit_counter (data, count); input [7:0] data; output [3:0] count; reg [3:0] count;
always @(data) t(data, count);
task t; input [7:0] a; output [3:0] c; reg [3:0] c; reg [7:0] tmp; begin c = 0; tmp = a; while (tmp) begin c = c + tmp[0]; tmp = tmp >> 1; end end endtaskendmodule
Functionmodule word_aligner (w_in, w_out); input [7:0] w_in; output [7:0] w_out;
assign w_out = align (w_in);
function [7:0] align; input [7:0] word; begin align = word; if (align != 0) while (align[7] == 0) align = align << 1; end endfunctionendmodule
Switch Level NAND Gatemodule nand_2 ( Y, A, B );
output Y;input A, B;supply0 GND;supply1 PWR;wire w;
pmos ( Y, PWR, A );pmos ( Y, PWR, B );nmos ( Y, w, A );nmos ( w, GND, B );
endmodule
Y
Vdd
A
A
B
B
Assign Drive Strengthsnand ( pull1, strong0 ) G1( Y, A, B );wire ( pull0, weak1 ) A_wire = net1 || net2;assign ( pull1, weak0 ) A_net = reg_b;
Drive strength is specified through an unordered pair one value from { supply0, strong0, pull0, weak0 , highz0 } the other from { supply1, strong1, pull1, weak1, highz1 }
Only scalar nets may receive strength assignment
Latch Resulted from Unspecified Input State
module myMux( y, selA, selB, a, b );input selA, selB, a, b;output y;reg y;
always @ ( selA or selB or a or b ) case ( {selA, selB} )
2’b10: y = a;2’b01: y = b;
endcaseendmodule
b
a
selA’selB
selAselB’
latch
yen
Synthesis of Loops repeat, for, while, forever
Depends on Venders Timing control Data dependencies
A loop is static or data-independent if the number of iterations can by determined by the complier before simulation
Static Loops without Internal Timing Controls –> Combinational Logic
module count1sA ( bit_cnt, data, clk, rst );parameter data_width = 4; parameter cnt_width = 3;output [cnt_width-1:0] bit_cnt;input [data_width-1:0] data; input clk, rst;reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp;always @ ( posedge clk ) if ( rst ) begin cnt = 0; bit_cnt = 0; end else begin cnt = 0; tmp = data;
for ( i = 0; i < data_width; i = i + 1 ) begin if ( tmp[0] ) cnt = cnt + 1; tmp = tmp >> 1; endbit_cnt = cnt;
endendmodule
Static Loops with Internal Timing Controls –> Sequential Logic
module count1sB ( bit_cnt, data, clk, rst );parameter data_width = 4; parameter cnt_width = 3;output [cnt_width-1:0] bit_cnt;input [data_width-1:0] data; input clk, rst;reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp;always @ ( posedge clk ) if ( rst ) begin cnt = 0; bit_cnt = 0; end else begin
cnt = 0; tmp = data;for ( i = 0; i < data_width; i = i + 1 ) @ ( posedge clk ) begin if ( tmp[0] ) cnt = cnt + 1; tmp = tmp >> 1; endbit_cnt = cnt;
endendmodule
Non-Static Loops without Internal Timing Controls –> Not Synthesizable
module count1sC ( bit_cnt, data, clk, rst );parameter data_width = 4; parameter cnt_width = 3;output [cnt_width-1:0] bit_cnt;input [data_width-1:0] data; input clk, rst;reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp;always @ ( posedge clk ) if ( rst ) begin cnt = 0; bit_cnt = 0; end else begin
cnt = 0; tmp = data;for ( i = 0; tmp; i = i + 1 ) begin if ( tmp[0] ) cnt = cnt + 1; tmp = tmp >> 1; endbit_cnt = cnt;
endendmodule
Non-Static Loops with Internal Timing Controls –> Sequential Logic
module count1sD ( bit_cnt, data, clk, rst );parameter data_width = 4; parameter cnt_width = 3;output [cnt_width-1:0] bit_cnt;input [data_width-1:0] data; input clk, rst;reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp;always @ ( posedge clk ) if ( rst ) begin cnt = 0; bit_cnt = 0; end else begin: bit_counter
cnt = 0; tmp = data;while ( tmp ) @ ( posedge clk ) begin if ( rst ) begin cnt = 0; disable bit_counter; end else begin cnt = cnt + tmp[0]; tmp = tmp >> 1; end bit_cnt = cnt; end
endendmodule