Verilog HDL 11: A Counter
Verilog HDL 11: A Counter
VERILOG HDL 11
Key terms and concepts: syntax and semantics • operators • hierarchy • procedures and assign-
ments • timing controls and delay • tasks and functions • control statements • logic-gate modeling
• modeling delay • altering parameters • other Verilog features: PLI
History: Gateway Design Automation developed Verilog as a simulation language • Cadence
purchased Gateway in 1989 • Open Verilog International (OVI) was created to develop the
Verilog language as an IEEE standard • Verilog LRM, IEEE Std 1364-1995 • problems with a
normative LRM
11.1 A Counter
Key terms and concepts: Verilog keywords • simulation language • compilation • interpreted,
compiled, and native code simulators
escaped_identifier ::=
\ {Any_ASCII_character_except_white_space} white_space
white_space ::= space | tab | newline
case_sensitive = 1; //17
\/clock = 0; // An escaped identifier with \ breaks rules, //18
\a*b = 0; // but be careful to watch the spaces! //19
$display("Variable CASE_SENSITIVE= %d",CASE_SENSITIVE); //20
$display("Variable case_sensitive= %d",case_sensitive); //21
$display("Variable \/clock = %d",\/clock ); //22
$display("Variable \\a*b = %d",\a*b ); //23
end //24
endmodule //25
11.2.4 Numbers
Key terms and concepts: constant numbers are integer or real constants • integer constants
are written as width'radix value• radix (or base): decimal (d or D), hex (h or H), octal (o
or O), or binary (b or B) • sized or unsized (implementation dependent) • 1'bx and 1'bz for 'x'
6 SECTION 11 VERILOG HDL ASICS... THE COURSE
and 'z' • parameter (local scope) • real constants 100.0 or 1e2 (IEEE Std 754-1985) • reals
round to the nearest integer, ties away from zero
11.2.6 Strings
Key terms and concepts: ISO/ANSI defines characters, but not their appearance • problem
characters are quotes and accents • string constants • define directive is a compiler directive
(global scope)
end //19
endmodule //20
module define; //1
`define G_BUSWIDTH 32 // Bus width parameter (G_ for global). //2
/* Note: there is no semicolon at end of a compiler directive. The
character ` is ASCII 96 (hex 60), accent grave, it slopes down from
left to right. It is not the tick or apostrophe character ' (ASCII 39
or hex 27)*/ //3
wire [`G_BUSWIDTH:0]MyBus; // A 32-bit bus. //4
endmodule //5
11.3 Operators
Key terms and concepts: three types of operators: unary, binary, or a single ternary operator •
similar to C programming language (but no ++ or --)
// if a=(x or z), then (bitwise) f=0 if b=c=0, f=1 if b=c=1, else f=x
//33
reg H0, a, b, c; initial begin a=1; b=0; c=1; H0=a?b:c; end //34
reg[2:0] J01x, Jxxx, J01z, J011; //35
initial begin Jxxx = 3'bxxx; J01z = 3'b01z; J011 = 3'b011; //36
J01x = Jxxx ? J01z : J011; end // A bitwise result. //37
initial begin #1; //38
$display("A10xz=%b",A10xz," A01010101=%b",A01010101); //39
$display("A1=%0d",A1," A2=%0d",A2," A4=%0d",A4); //40
$display("B1=%b",B1," B0=%b",B0," A00x=%b",A00x); //41
$display("C1=%b",C1," Ax=%b",Ax," Bx=%b",Bx); //42
$display("D0=%b",D0," D1=%b",D1); //43
$display("E0=%b",E0," E1=%b",E1," F1=%b",F1); //44
$display("A00=%b",A00," G1=%b",G1," H0=%b",H0); //45
$display("J01x=%b",J01x); end //46
endmodule //47
11.3.1 Arithmetic
Key terms and concepts: arithmetic on n-bit objects is performed modulo 2n • arithmetic on
vectors (reg or wire) are predefined • once Verilog “loses” a sign, it cannot get it back
11.4 Hierarchy
Key terms and concepts: module • the module interface interconnects two Verilog modules
using ports • ports must be explicitly declared as input, output, or inout • a reg cannot be
input or inout port (to connection of a reg to another reg) • instantiation • ports are linked
using named association or positional association • hierarchical name ( m1.weekend) •
The compiler will first search downward (or inward) then upward (outward)
Verilog ports.
Verilog port input output inout
Characteris- wire (or other reg or wire (or other net) wire (or other
tics net) net)
We can read an output port inside a
module
statement executes repeatedly • an initial statement executes only once, so a sequential block
in an initial statement only executes once at the beginning of a simulation
T= 0 A=0 Y=0
T= 5 A=1 Y=1
T=10 A=0 Y=0
16 SECTION 11 VERILOG HDL ASICS... THE COURSE
x = #1 y; // intra-assignment delay
#1 x = y; // delayed assignment
t a b c d e f g bds bsd
0 1 0 x x x x x x x
1 1 1 x x x x x 1 0
2 1 1 1 x x x x 1 0
3 1 1 1 1 x x x 1 0
4 1 1 1 1 1 1 1 1 0
20 SECTION 11 VERILOG HDL ASICS... THE COURSE
if(switch) Y = 1; else Y = 0;
module test_mux; reg a, b, select; wire out; //1
mux mux_1(a, b, out, select); //2
initial begin #2; select = 0; a = 0; b = 1; //3
#2; select = 1'bx; #2; select = 1'bz; #2; select = 1;end //4
initial $monitor("T=%2g",$time," Select=",select," Out=",out); //5
initial #10 $finish; //6
endmodule //7
module mux(a, b, mux_output, mux_select);input a, b, mux_select; //1
output mux_output; reg mux_output; //2
always begin //3
case(mux_select) //4
0: mux_output = a; //5
1: mux_output = b; //6
default mux_output = 1'bx; // If select = x or z set output to
x. //7
endcase //8
#1; // Need some delay, otherwise we'll spin forever. //9
end //10
endmodule //11
casex (instruction_register[31:29])
3b'??1 : add;
3b'?1? : subtract;
3b'1?? : branch;
endcase
ASICs... THE COURSE 11.8 Control Statements 23
i = 0;
/* while(Execute next statement while this expression is true.) */
while(i <= 15) begin DataBus[i] = 1; i = i+1; end
i = 0;
/* repeat(Execute next statement the number of times corresponding to
the evaluation of this expression at the beginning of the loop.) */
repeat(16) begin DataBus[i] = 1; i = i+1; end
i = 0;
/* A forever statement loops continuously. */
forever begin : my_loop
DataBus[i] = 1;
if (i == 15) #1 disable my_loop; // Need to let time advance to
exit.
i = i+1;
end
24 SECTION 11 VERILOG HDL ASICS... THE COURSE
11.8.3 Disable
Key terms and concepts: The disable statement stops the execution of a labeled sequential
block and skips to the end of the block • difficult to implement in hardware
forever
begin: microprocessor_block // Labeled sequential block.
@(posedge clock)
if (reset) disable microprocessor_block; // Skip to end of block.
else Execute_code;
end
endtable //9
endprimitive //10
primitive DLatch(Q, Clock, Data); //1
output Q; reg Q; input Clock, Data; //2
table //3
//inputs : present state : output (next state) //4
1 0 : ? : 0; // ? represents 0,1, or x (input or present state). //5
1 1 : b : 1; // b represents 0 or 1 (input or present state). //6
1 1 : x : 1; // Could have combined this with previous line. //7
0 ? : ? : -; // - represents no change in an output. //8
endtable //9
endprimitive //10
primitive DFlipFlop(Q, Clock, Data); //1
output Q; reg Q; input Clock, Data; //2
table //3
//inputs : present state : output (next state) //4
r 0 : ? : 0 ; // rising edge, next state = output = 0 //5
r 1 : ? : 1 ; // rising edge, next state = output = 1 //6
(0x) 0 : 0 : 0 ; // rising edge, next state = output = 0 //7
(0x) 1 : 1 : 1 ; // rising edge, next state = output = 1 //8
(?0) ? : ? : - ; // falling edge, no change in output //9
? (??) : ? : - ; // no clock edge, no change in output //10
endtable //11
endprimitive //12
delay (to '0') • for a high-impedance output, we specify a triplet for rising, falling, and the delay
to transition to 'z' (from '0' or '1'), the delay for a three-state driver to turn off or float
/******************************************************/
/* module viterbi_encode */
/******************************************************/
/* This is the encoder. X2N (msb) and X1N form the 2-bit input
message, XN. Example: if X2N=1, X1N=0, then XN=2. Y2N (msb), Y1N, and
Y0N form the 3-bit encoded signal, YN (for a total constellation of 8
PSK signals that will be transmitted). The encoder uses a state
machine with four states to generate the 3-bit output, YN, from the
2-bit input, XN. Example: the repeated input sequence XN = (X2N, X1N)
= 0, 1, 2, 3 produces the repeated output sequence YN = (Y2N, Y1N,
Y0N) = 1, 0, 5, 4. */
module viterbi_encode(X2N,X1N,Y2N,Y1N,Y0N,clk,res);
input X2N,X1N,clk,res; output Y2N,Y1N,Y0N;
wire X1N_1,X1N_2,Y2N,Y1N,Y0N;
dff dff_1(X1N,X1N_1,clk,res); dff dff_2(X1N_1,X1N_2,clk,res);
assign Y2N=X2N; assign Y1N=X1N ^ X1N_2; assign Y0N=X1N_1;
endmodule
/******************************************************/
/* module viterbi_distances */
/******************************************************/
/* This module simulates the front end of a receiver. Normally the
received analog signal (with noise) is converted into a series of
distance measures from the known eight possible transmitted PSK
signals: s0,...,s7. We are not simulating the analog part or noise in
this version, so we just take the digitally encoded 3-bit signal, Y,
from the encoder and convert it directly to the distance measures.
d[N] is the distance from signal = N to signal = 0
d[N] = (2*sin(N*PI/8))**2 in 3-bit binary (on the scale 2=100)
Example: d[3] = 1.85**2 = 3.41 = 110
inN is the distance from signal = N to encoder signal.
30 SECTION 11 VERILOG HDL ASICS... THE COURSE
/*****************************************************/
/* module viterbi_test_CDD */
/*****************************************************/
/* This is the top-level module, viterbi_test_CDD, that models the
communications link. It contains three modules: viterbi_encode,
viterbi_distances, and viterbi. There is no analog and no noise in
this version. The 2-bit message, X, is encoded to a 3-bit signal, Y.
In this module the message X is generated using a simple counter.
The digital 3-bit signal Y is transmitted, received with noise as an
analog signal (not modeled here), and converted to a set of eight
3-bit distance measures, in0, ..., in7. The distance measures form
the input to the Viterbi decoder that reconstructs the transmitted
signal Y, with an error signal if the measures are inconsistent.
CDD = counter input, digital transmission, digital reception */
module viterbi_test_CDD;
wire Error; // decoder out
wire [2:0] Y, Out; // encoder out, decoder out
reg [1:0] X; // encoder inputs
reg Clk, Res; // clock and reset
wire [2:0] in0,in1,in2,in3,in4,in5,in6,in7;
always #500 $display("t Clk X Y Out Error");
initial $monitor("%4g",$time,,Clk,,,,X,,Y,,Out,,,,Error);
initial $dumpvars; initial #3000 $finish;
always #50 Clk = ~Clk; initial begin Clk = 0;
ASICs... THE COURSE 11.12 A Viterbi Decoder 31
/******************************************************/
/* module dff */
/******************************************************/
/* A D flip-flop module. */
/******************************************************/
/* This is the top level of the Viterbi decoder. The eight input
signals {in0,...,in7} represent the distance measures, ||r-si||**2.
The other input signals are clk and reset. The output signals are
out and error. */
module viterbi
(in0,in1,in2,in3,in4,in5,in6,in7,
out,clk,reset,error);
input [2:0] in0,in1,in2,in3,in4,in5,in6,in7;
output [2:0] out; input clk,reset; output error;
wire sout0,sout1,sout2,sout3;
wire [2:0] s0,s1,s2,s3;
wire [4:0] m_in0,m_in1,m_in2,m_in3;
wire [4:0] m_out0,m_out1,m_out2,m_out3;
wire [4:0] p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3;
wire ACS0,ACS1,ACS2,ACS3;
wire [4:0] out0,out1,out2,out3;
wire [1:0] control;
wire [2:0] p0,p1,p2,p3;
wire [11:0] path0;
subset_decode u1(in0,in1,in2,in3,in4,in5,in6,in7,
s0,s1,s2,s3,sout0,sout1,sout2,sout3,clk,reset);
metric u2(m_in0,m_in1,m_in2,m_in3,m_out0,
m_out1,m_out2,m_out3,clk,reset);
compute_metric u3(m_out0,m_out1,m_out2,m_out3,s0,s1,s2,s3,
p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3,error);
compare_select u4(p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3,
out0,out1,out2,out3,ACS0,ACS1,ACS2,ACS3);
reduce u5(out0,out1,out2,out3,
m_in0,m_in1,m_in2,m_in3,control);
pathin u6(sout0,sout1,sout2,sout3,
ACS0,ACS1,ACS2,ACS3,path0,clk,reset);
path_memory u7(p0,p1,p2,p3,path0,clk,reset,
ACS0,ACS1,ACS2,ACS3);
output_decision u8(p0,p1,p2,p3,control,out);
endmodule
/******************************************************/
/* module subset_decode */
/******************************************************/
ASICs... THE COURSE 11.12 A Viterbi Decoder 33
/******************************************************/
/* module compute_metric */
/******************************************************/
/* This module computes the sum of path memory and the distance for
each path entering a state of the trellis. For the four states,
there are two paths entering it; therefore eight sums are computed
in this module. The path metrics and output sums are 5 bits wide.
The output sum is bounded and should never be greater than 5 bits
for a valid input signal. The overflow from the sum is the error
output and indicates an invalid input signal.*/
module compute_metric
(m_out0,m_out1,m_out2,m_out3,
s0,s1,s2,s3,p0_0,p2_0,
p0_1,p2_1,p1_2,p3_2,p1_3,p3_3,
error);
input [4:0] m_out0,m_out1,m_out2,m_out3;
input [2:0] s0,s1,s2,s3;
output [4:0] p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3;
output error;
assign
p0_0 = m_out0 + s0,
p2_0 = m_out2 + s2,
p0_1 = m_out0 + s2,
p2_1 = m_out2 + s0,
p1_2 = m_out1 + s1,
p3_2 = m_out3 + s3,
p1_3 = m_out1 + s3,
p3_3 = m_out3 + s1;
else is_error = 0;
end
endfunction
/******************************************************/
/* module compare_select */
/******************************************************/
/* This module compares the summations from the compute_metric
module and selects the metric and path with the lowest value. The
output of this module is saved as the new path metric for each
state. The ACS output signals are used to control the path memory of
the decoder. */
module compare_select
(p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3,
out0,out1,out2,out3,
ACS0,ACS1,ACS2,ACS3);
input [4:0] p0_0,p2_0,p0_1,p2_1,p1_2,p3_2,p1_3,p3_3;
output [4:0] out0,out1,out2,out3;
output ACS0,ACS1,ACS2,ACS3;
/******************************************************/
/* module path */
/******************************************************/
/* This is the basic unit for the path memory of the Viterbi
decoder. It consists of four 3-bit D flip-flops in parallel. There
is a 2:1 mux at each D flip-flop input. The statement dff #(12)
instantiates a vector array of 12 flip-flops. */
module path(in,out,clk,reset,ACS0,ACS1,ACS2,ACS3);
input [11:0] in; output [11:0] out;
input clk,reset,ACS0,ACS1,ACS2,ACS3; wire [11:0] p_in;
dff #(12) path0(p_in,out,clk,reset);
function [2:0] shift_path; input [2:0] a,b; input control;
begin
if (control == 0) shift_path = a; else shift_path = b;
end
endfunction
/******************************************************/
/* module path_memory */
/******************************************************/
/* This module consists of an array of memory elements (D
flip-flops) that store and shift the path memory as new signals are
added to the four paths (or four most likely sequences of signals).
This module instantiates 11 instances of the path module. */
module path_memory
(p0,p1,p2,p3,
path0,clk,reset,
ACS0,ACS1,ACS2,ACS3);
output [2:0] p0,p1,p2,p3; input [11:0] path0;
ASICs... THE COURSE 11.12 A Viterbi Decoder 37
input clk,reset,ACS0,ACS1,ACS2,ACS3;
wire [11:0]out1,out2,out3,out4,out5,out6,out7,out8,out9,out10,out11;
path x1 (path0,out1 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x2 (out1, out2 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x3 (out2, out3 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x4 (out3, out4 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x5 (out4, out5 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x6 (out5, out6 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x7 (out6, out7 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x8 (out7, out8 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x9 (out8, out9 ,clk,reset,ACS0,ACS1,ACS2,ACS3),
x10(out9, out10,clk,reset,ACS0,ACS1,ACS2,ACS3),
x11(out10,out11,clk,reset,ACS0,ACS1,ACS2,ACS3);
assign p0 = out11[11:9];
assign p1 = out11[ 8:6];
assign p2 = out11[ 5:3];
assign p3 = out11[ 2:0];
endmodule
/******************************************************/
/* module pathin */
/******************************************************/
/* This module determines the input signal to the path for each of
the four paths. Control signals from the subset decoder and compare
select modules are used to store the correct signal. The statement
dff #(12) instantiates a vector array of 12 flip-flops. */
module pathin
(sout0,sout1,sout2,sout3,
ACS0,ACS1,ACS2,ACS3,
path0,clk,reset);
input sout0,sout1,sout2,sout3,ACS0,ACS1,ACS2,ACS3;
input clk,reset; output [11:0] path0;
wire [2:0] sig0,sig1,sig2,sig3; wire [11:0] path_in;
/******************************************************/
/* module metric */
/******************************************************/
/* The registers created in this module (using D flip-flops) store
the four path metrics. Each register is 5 bits wide. The statement
dff #(5) instantiates a vector array of 5 flip-flops. */
ASICs... THE COURSE 11.12 A Viterbi Decoder 39
module metric
(m_in0,m_in1,m_in2,m_in3,
m_out0,m_out1,m_out2,m_out3,
clk,reset);
input [4:0] m_in0,m_in1,m_in2,m_in3;
output [4:0] m_out0,m_out1,m_out2,m_out3;
input clk,reset;
dff #(5) metric3(m_in3, m_out3, clk, reset);
dff #(5) metric2(m_in2, m_out2, clk, reset);
dff #(5) metric1(m_in1, m_out1, clk, reset);
dff #(5) metric0(m_in0, m_out0, clk, reset);
endmodule
/******************************************************/
/* module output_decision */
/******************************************************/
/* This module decides the output signal based on the path that
corresponds to the smallest metric. The control signal comes from
the reduce module. */
module output_decision(p0,p1,p2,p3,control,out);
input [2:0] p0,p1,p2,p3; input [1:0] control; output [2:0] out;
function [2:0] decide;
input [2:0] p0,p1,p2,p3; input [1:0] control;
begin
if(control == 0) decide = p0;
else if(control == 1) decide = p1;
else if(control == 2) decide = p2;
else decide = p3;
end
endfunction
/******************************************************/
/* module reduce */
/******************************************************/
/* This module reduces the metrics after the addition and compare
operations. This algorithm selects the smallest metric and subtracts
it from all the other metrics. */
40 SECTION 11 VERILOG HDL ASICS... THE COURSE
module reduce
(in0,in1,in2,in3,
m_in0,m_in1,m_in2,m_in3,
control);
input [4:0] in0,in1,in2,in3;
output [4:0] m_in0,m_in1,m_in2,m_in3;
output [1:0] control; wire [4:0] smallest;
end endmodule
mem.dat
@2 1010_1111 @4 0101_1111 1010_1111 // @address in hex
x1x1_zzzz 1111_0000 /* x or z is OK */
'edge [01, 0x, x1] clock'is equivalent to 'posedge clock' • edge transitions with
'z' are treated the same as transitions with 'x'• notifier register (changed when a timing-
check task detects a violation)
// timescale tasks:
module a; initial $printtimescale(b.c1); endmodule
module b; c c1 (); endmodule
`timescale 10 ns / 1 fs
module c_dat; endmodule
`timescale 1 ms / 1 ns
module Ttime; initial $timeformat(-9, 5, " ns", 10); endmodule
/* $timeformat [ ( n, p, suffix , min_field_width ) ] ;
units = 1 second ** (-n), n = 0->15, e.g. for n = 9, units = ns
p = digits after decimal point for %t e.g. p = 5 gives 0.00000
suffix for %t (despite timescale directive)
min_field_width is number of character positions for %t */
44 SECTION 11 VERILOG HDL ASICS... THE COURSE
`timescale 100 fs / 1 fs
module dff(q, clock, data); output q; input clock, data; reg
notifier;
dff_udp(q1, clock, data, notifier); buf(q, q1);
specify
specparam tSU = 5, tH = 1, tPW = 20, tPLH = 4:5:6, tPHL = 4:5:6;
(clock *> q) = (tPLH, tPHL);
$setup(data, posedge clock, tSU, notifier); // setup: data to clock
$hold(posedge clock, data, tH, notifier); // hold: clock to data
$period(posedge clock, tPW, notifier); // clock: period
endspecify
endmodule
array.dat
1100000
46 SECTION 11 VERILOG HDL ASICS... THE COURSE
0011100
0000111
end endmodule
$stime ;
// returns 32-bit integer scaled to timescale unit of invoking module
$realtime ;
// returns real scaled to timescale unit of invoking module
end endmodule
2.000000 8 57 0 4 9
3.000000 7 3 0 2
11.14 Summary
Key terms and concepts: concurrent processes and sequential execution • difference between a
reg and a wire • scalars and vectors • arithmetic operations on reg and wire • data slip •
delays and events
ASICs... THE COURSE 11.14 Summary 51