Você está na página 1de 74

Verilog HDL

Compiled from the Web


Bil 361 Computer Architecture and
Organization
Introduction
• Hardware Description Language (HDL)
• Verilog is a useful and popular language
• Parallel not serial (Not like C language)
• Meaningful declaration
– parameter, port name, module name, …
• Case-sensitive Identifies
– “Even” and “even” are different
• Top-Down Methodology
• Bottom-up Target

Module 1 Module 2 Module 3

Basic Basic Basic Basic Basic Basic


Comp. Comp. Comp. Comp. Comp. Comp.
Design Flow
• What functions are you want to program ?
– Input and output
• Specify the Input/Output signals
• Separate the whole circuit into smaller ones
– Each block has its own function / purpose
• Connect all blocks/modules

B1 B2

B3
Verification Scenario
• Use test bench file to verify your design
Stimulus Response
& &
Control Signal Verification

Test-Bench Module Monitor Signals


What is a Module
• Module is a block of circuit
– Special function
– and, or, mux, adder, shifter…
• Most important
– Input and Output

Module
Verilog - Module
Module Declaration
• module module_name (input1, input2, …,
output1, output2, …);

endmodule
• Example
– module mux2(a, b, c);
endmodule
– module adder(x, y, z);
endmodule
• Nests
– wire [k-1:0] B;
Data
[0:k-1]B
types
• Registers
− reg [n-1:0] A; C[1:0] = {a,b}
• Integers
− 4’d3, 4’b0100, 6’h20
• Array
− reg [8:0] ram [0:9];
• Parameter
− parameter size = 16;
− wire [size-1:0] bus;

• Preprocessor Directive No “=”


− `define BEQ 4’b0100
Synthesizable Description
• Can be used in your RTL codes

`define `include module/endmodule


parameter input output

wire reg begin/end


always assign posedge/negedge
if/else case/casex
Un-synthesizable Description
• Can not be used in your RTL codes!
• Can be used in test bench

Delay initial Repeat


forever wait Foke
join event Time
deassign force Relace
primitive
Synthesizable Operator
• Binary (2 operands) • Logic (1 or 2 op.)
– & AND − !A not A
– ~& NAND − A&&B A and B
– | OR − A || B A or B
– ~| NOR
– ^ XOR
• Example
– ~^ XNOR
− assign a= 1;
• Example
− assign b= 0;
– a = 4’b0010;
then
then
a && b = 0
&a = 1’b0;
a || b = 1
^a = 1’b1;
Examples
 reg [3:0] a; • wire [3:0] a;
always @() begin assign a=b & c
a=b & c; b = 4’b0011
c = 4’b0101
end a = 4’b0001

• wire [3:0] a;
 wire [3:0] a = b | c;
assign a=b | c
b = 4’b0011
c = 4’b0101

a = 4’b0111
Synthesizable Operator (cont.)
• Binary Bitwise • Shift
– ~inverse − << shift left
– & and − >> shift right
– | or • Example
– ^ XOR − a= 4’b0010;
– ~^ XNOR a >>1 = 4’b0001;
• Example a <<2 = 4’b1000;
– assign a= ~b; • Conditional
if b = 4’b0010; − A = (condition) ? B : C;
then
• Concatenate
a = 4’b1101;
− A=2’b10; B=3’b110;
then {A, B} = 5’b10110
Numbers
• (size) ’ (base)(number)
a = 1’b0, 4’b0001, 8’hFF, 10’d700
• Negative number
-8’d34 = (-34)10, 5’d-4 (error)
• Underscore (_)
a = 20’b00001110110101101010;
a = 20’b00001_11011_01011_01010;
Logic Gates Level
• AND, Inverter, and OR gates
and g(z, x, y); not g(y, x); or g(z, x, y);

x z x
x y z
y y

x y z y z x y z
0 0 0 0 1 0 0 0
0 1 0 1 0 0 1 1
1 0 0 1 0 1
1 1 1 1 1 1
Program 1
• Purpose
– A circuit can calculate the addition and
subtraction of two 8 bits numbers
– Three inputs and one output
8
If op = 1
a
+ then s=a+b

Mux 8 s If op = 0
then s=a-b
-
b 8 1

op
Program 1 (cont.)
• /* A first program in Verilog */ comment
module adder_or_subtract( a, b, op, s);
parameter SIZE = 8; Model declaration
parameter ADD = 1’b1;
input op;
input [SIZE-1:0] a,b;
output [SIZE-1:0] s; add
a +
wire add, sub;
assign add = a+b; Mux s
assign sub = a-b; -
assign s = (op==ADD)? add : sub;b sub
endmodule
op
Program 1 (cont.)
module adder_or_subtract( a, b, op, s);
parameter SIZE = 8;
parameter ADD = 1’b1; add sub
input op;
input [SIZE-1:0] a,b;
output [SIZE-1:0] s;
assign s = (op==ADD)? a+b : a-a-b;
endmodule
Program 2
• 1-to-2 De-multiplexer
Select

y0
0 D y0
D
DMUX
1
y1
y1

Select y0 y1
0 D 0 Select
1 0 D
Program 2 (cont.)
• // A deMux program in Verilog Single Col. comment
module demux ( D, select, y0, y1);
Model declaration
input D;
input select;
D y0
output y0,y1;
wire y0,y1;
assign y0 = (~select) & D;
y1
assign y1 = select & D;
endmodule
Select
Program 2 (cont.)
• /* A deMux program in Verilog */ comment
module demux ( D, select, y0, y1);
Model declaration
input D;
input select; D g1 y0
output y0,y1; N
wire y0,y1,N; g0
and g1(y0, D, N);
and g2(y1, D, Select); g2 y1
not g0(N, Select);
endmodule
Select
Sub Module
• Complex circuit
• Many modules in a circuit
• Module, sub-module, sub-sub-module, …

B1 B2

B3
Example of Call Module
• module B1(a, b, c);
………………..
endmodule
• module B2(a, b, c, d);
……………….. B1 B2
endmodule
• module B3(x, y, z); B3

………………..
endmodule
Example of Call Module (cont.)
• module function(q, w, e, f);
……. • module B1(a, b, c);

B1 b1(q, w, a, b, c); ………………..


endmodule
B2 b2(a, b, d, e);
• module B2(a, b, c, d);
B3 b3(c, d, f); ………………..
…… endmodule
endmodule • module B3(x, y, z);
………………..
endmodule
Port Mapping Between Modules
• module B1(q, w, e, f);
• # of ports
input q, w;
• Width of each port
input [3:0] e;
• module output [1:0] f;
function(a,b,c,d);
……………….
…….
endmodule
B1 b1(w, q, a, c);
........
endmodule w q

q w f c
B1
a e
Port Mapping Between Modules (cont.)
• Port name should match the name in sub_module
• Prot connection
– module_name( .port1_m1(w1_or_r1),
.port2_m1(w2_or_r2),
.port3_m1(w3_or_r3),
.port4_m1(w4_or_r4),
)
– module_name( .port3_m1(w3_or_r3),
.port2_m1(w2_or_r2),
.port1_m1(w1_or_r1),
.port4_m1(w4_or_r4),
)
Connection Between Modules (cont.)
• Port connection
q q

• module function(a,b,c,d); w w B1 f c
a e
............................
B1 b1(q, w, a, c);
• module B1(q, w, e, f);
B1 b1(.q(q), .w(w), .e(a), .f(c));
input q, w;
B1 b1(.w(w), .q(q), .e(a), .f(c));
input [3:0] e;
............................
output [1:0] f;
endmodule
……………….
endmodule
Reuse Module
• Using the same module many times
• Example
– Constructing 4-bits adder with four 1-bit adder
b3 a3 b2 a2 b1 a1 b0 a0 a [3:0] b [3:0]

c3 c2 c1 0
A A A A Adder

s4 s3 s2 s1 s0
S [4:0]
4-bits Adder
y x
• module Adder(x, y, cin, sum, cout);
input x, y, c; cout cin
A
output sum, cout;
wire x, y, c, sum, cout; sum
assign sum = x ^ y ^ cin;
assign cout = (x & y) | (x & cin) | (y & cin);
assign {cout, sum} = x + y + cin;
endmodule
4-bists Adder (cont.)
b3 a3 b2 a2 b1 a1 b0 a0
• module Adder4(x, y, cin, sum);
input [3:0]x, y;
input cin;
c3 c2 c1 cin
output [4:0]sum; A A A A
wire [3:0] x, y;
wire cin;
wire [4:0] sum;
s4 s3 s2 s1 s0
wire c1, c2, c3;
Adder A1(x[0], y[0], cin, sum[0], c1);
Adder A2(x[1], y[1], c1, sum[1], c2);
Adder A3(x[2], y[2], c2, sum[2], c3);
Adder A4(x[3], y[3], c3, sum[3], sum[4]);
endmodule
Mistake
• module and endmodule
• begin and end
• module(); not Module();
• Miss “ ; ” symbol for the end of every statement
• Mismatch between the number of port or the
number of pins of some buses
• Syntax Always Block
– always @(event-expression)
assignment or block
• Level type
– always @(a or b or c)
• Edge type
– always @(posedge clock)
– always @(negedge clock)
• if-else and case statement are only in always
block
• wire and reg
• wire a; Example
reg b;
always @(x or y or z)
begin
a <= x & y; error
b <= x | z; correct
end
Program 2
Select
• 1-to-2 De-multiplexer
y0
0 D y0
D
DMUX
1
y1
y1

Select y0 y1
0 D 0 Select
1 0 D
Program 2 (cont.)
• module demux ( D, select, y0, y1);
input D, select;
D
output y0,y1;
y0
reg y0,y1;
always @( D or select ) begin
if( select == 1’b0) begin
y0 = D;
y1 y1 = 1’b0;
end else begin
y0 = 1’b0;
y1 = D;
Select end
end
endmodule
Blocking and Non-blocking
If-else and case
• If (condition 1) begin • reg [1:0] state;
.................. case (state)
end 2’b00: .........
else if (condition 2) begin
2’b01: .........
..................
end 2’b10: .........
else begin 2’b11: .........
.................. default: .........
end endcase
if statement
• Like C language
• Only in always block
reg out; wire out;
always @(sel or a or b) assign out = (sel)? a : b;
begin
if(sel == 1’b1) out = a;
else out = b;
end
Using of case and casex
• Multiplexer or selection
• Inside always block
• All possible condition
always @(sel or a or b or c or d)
a begin
b case (sel[1:0] )
out 2’b00 : out <= a;
c 2’b01 : out <= b;
d 2’b10 : out <= c;
2’b11 : out <= d;
Sel [1:0]
endcase
end
Using of case and casex (cont.)
a always @(sel or a or b or c or d)
begin
b case (sel[1:0] )
out 2’b00, 2’b11 : out <= a;
c 2’b01 : out <= b;
2’b10 : out <= c;
endcase
Sel [1:0] end
always @(sel or a or b or c or d)
a begin
casex (sel[2:0] )
b 3’b011 : out <= a;
out
c 3’b00x : out <= b;
3’b100 : out <= c;
d default : out <= d;
endcasex
Sel [2:0] end All others
Delay and Critical Path
• Each gate and wire may cause delay of circuit
• Longest path of the circuit is the critical path
– Speed of whole circuit
• Shorten the critical path can speedup the
circuit
• Input data rate higher than the speed of
circuit may cause some problems
Critical Path Example
• 5 inputs adder
–Z=a+b+c+d+e Z = (a + b) + (c + d) + e
a b
a b c d
+ c
+ +

+ d Four adders Three adders


+
e
+ e

+
+

Z
Z
Test-bench
• Input data of the circuit
• All inputs of original circuit are assigned “reg”
– Store data
• All outputs of original circuit are assigned
“wire”
• Assign inputs in different time
• Define time scale
Test-bench Example
• `timescale 1ns/10ps
module Adder_testbench;
reg [3:0] x,y; reg cin; wire [4:0] sum;
adder4 add(.x(x), .y(y), .cin(cin), .sum(sum)); Initialization
initial begin
#0 x = 4’d0; y = 4’d0; cin=1’b0;
#10 x = 4’d3; In 10ns x=3;
#5 y = 4’d10; y=0;
#10 x = 4’d1; y = 4’d5; sum=3;
end In 15ns x=3;
endmodule y=10;
sum=13;
module Adder4(x, y, cin, sum);
In 25ns x=1;
y=5;
sum=6;
Structural Vs Procedural
Structural Procedural
• textual description of circuit • Think like C code
• order does not matter
• Order of statements are
• Starts with assign important
statements • Starts with initial or always
statement
• Harder to code
• Need to work out logic • Easy to code
• Can use case, if, for

wire c, d; reg c, d;
assign c =a & b; always@ (a or b or c) begin
assign d = c |b; assign c =a & b;
assign d = c |b; end
46
Structural Vs Procedural
Procedural
reg [3:0] Q; Structural
wire [1:0] y; wire [3:0]Q;
always@(y) wire [1:0]y;
assign
begin
Q[0]=(~y[1])&(~y[0]),
Q=4’b0000;
Q[1]=(~y[1])&y[0],
case(y) begin
Q[2]=y[1]&(~y[0]),
2’b00: Q[0]=1; Q[3]=y[1]&y[0];
2’b01: Q[1]=1;
2’b10: Q[2]=1;
2’b11: Q[3]=1; Q[0]
endcase
end Q[1]

Q[2]

y[0]
Q[3]
y[1]
47
Blocking Vs Non-Blocking
Blocking Non-blocking
 <variable> = <statement>  <variable> <= <statement>

 Similar to C code  The inputs are stored once


the procedure is triggered
 The next assignment waits
until the present one is  Statements are executed in
finished parallel

 Used for combinational  Used for flip-flops, latches


logic and registers

Do not mix both assignments in one


procedure
48
Blocking Vs Non-Blocking
Initial
begin
#1 e=2;
#1 b=1;
#1 b<=0;
e<=b; // grabbed the old b
f=e; // used old e=2, did not wait e<=b

49
Component Inference
Flip-Flops
always@(posedge clk)
begin
a<=b;
a<=b&c;
end
B D

Q A

clk CLK

51
D Flip-Flop with Asynchronous Reset
always@(posedge clk or
negedge rst)
begin
if (!rst) a<=0;
else a<=b; rst
end clr
B D

Q A

clk CLK

52
D Flip-flop with Synchronous reset and
Enable
always@(posedge clk)
begin
if (rst) a<=0;
else if (enable) a<=b;
end

53
Shift Registers
reg[3:0] Q;
always@(posedge clk or
posedge rset )
begin
if (rset) Q<=0;
else begin
Q <=Q << 1;
Q[0]<=Q[3];
end

54
Multiplexers

Method 1
assign a = (select ? b : c);

Method 2
always@(select or b or c) begin
0
if(select) a=b;
else a=c;
end
1
SL
Method 2b
case(select)
1’b1: a=b;
1’b0: a=c; select
endcase

55
Counters
reg [7:0] count;
wire enable;
always@(posedge clk or
negedge rst)
begin
if (rst) count<=0;
else if (enable)
count<=count+1;
end

56
Avoiding Unwanted Latches

Latches are BAD


Rule #1
If the procedure has several paths, every
path must evaluate all outputs
• Method1:
Set all outputs to some value at the start of the procedure.
Later on different values can overwrite those values.
always @(...
begin
x=0;y=0;z=0;
if (a) x=2; elseif (b) y=3; else z=4;
End
• Method2:
Be sure every branch of every if and case generate every output
always @(...
begin
if (a) begin x=2; y=0; z=0; end
elseif (b) begin x=0; y=3; z=0; end
else begin x=0; y=0; z=4; end
end
58
Rule #2

All inputs used in the procedure must appear


in the trigger list
• Right-hand side variables:
Except variables both calculated and used in the procedure.
always @(a or b or c or x or y)
begin
x=a; y=b; z=c;
w=x+y;
end
• Branch controlling variables:
Be sure every branch of every if and case generate every output
always @(a or b)
begin
if (a) begin x=2; y=0; z=0; end
elseif (b) begin x=0; y=3; z=0; end
else begin x=0; y=0; z=4; end
end

59
Rule #3

All possible inputs used control statements


must be covered
• End all case statements with the default case whether you
need it or not.
case(state)
...
default: next_state = reset;
endcase
• Do not forget the self loops in your state graph
if(a|b&c) next_state=S1;
elseif(c&d) next_state=S2;
else next_state=reset;
60
Finite State Machines
Standard Form for a Verilog FSM

// state flip-flops // REGISTER DEFINITION


reg [2:0] state, nxt_st; always@(posedge clk)
// state definitions begin
parameter reset=0,S1=1,S2=2,S3=3,..
state<=next_state;
end
// NEXT STATE CALCULATIONS
always@(state or inputs or ...)
// OUTPUT CALCULATIONS
begin
output= f(state, inputs)

next_state= ...

end

62
Example
module myFSM (clk, x, z) // NEXT STATE CALCULATIONS
input clk, x; output z; always @(state or x)
begin
// state flip-flops case (state)
reg [2:0] state, nxt_st; S0: if(x) nxt_st=S1;
// state definition else nxt_st=S0;
parameter S0=0,S1=1,S2=2,S3=3,S7=7 S1: if(x) nxt_st=S3;
else nxt_st=S2;
// REGISTER DEFINITION S2: if(x) nxt_st=S0;
always @(posedge clk) else nxt_st=S7;
begin S3: if(x) nxt_st=S2;
state<=nxt_st; else nxt_st=S7;
end S7: nxt_st=S0;
default: nxt_st = S0;
// OUTPUTCALCULATIONS endcase
assign z = (state==S7); end

endmodule

63
Test Benches
System tasks
• Used to generate input and output during simulation. Start
with $ sign.
• Display Selected Variables:
$display (“format_string”,par_1,par_2,...);
$monitor(“format_string”,par_1,par_2,...);
Example: $display(“Output z: %b”, z);
• Writing to a File:
$fopen, $fdisplay, $fmonitor and $fwrite
• Random number generator: $random (seed)
• Query current simulation time: $time

65
Test Benches
Overview Approach

1. Invoke the verilog under 1. Initialize all inputs


design
2. Set the clk signal
2. Simulate input vectors
3. Send test vectors
3. Implement the system tasks
to view the results 4. Specify when to end the
simulation.

66
Example
‘timescale1 ns /100 ps
// timeunit =1ns; precision=1/10ns; /****SPECIFY THE INPUT WAVEFORM x ****/
module my_fsm_tb; Initial begin
reg clk, rst, x; #1 x=0;
wire z; #400 x=1;
$display(“Output z: %b”, z);
/**** DESIGN TO SIMULATE (my_fsm) #100 x=0;
INSTANTIATION ****/ @(posedge clk) x=1;
myfsm dut1(clk, rst, x, z);
#1000 $finish; //stop simulation
/****RESET AND CLOCK SECTION****/ //without this, it will not stop
Initial end
begin endmodule
clk=0;
rst=0;
#1rst=1; /*The delay gives rst a posedge for sure.*/
#200 rst=0; //Deactivate reset after two clock cycles
+1ns*/
end
always #50clk=~clk; /* 10MHz clock (50*1ns*2) with
50% duty-cycle */

67
Synthesizable Description
• Can be used in your RTL codes

`define `include module/endmodule


parameter input output

wire reg begin/end


always assign posedge/negedge
if/else case/casex

68
Un-synthesizable Description
• Can not be used in your RTL codes!
• Can be used in test bench

Delay (#) initial Repeat


forever wait Foke
join event Time
deassign force Relace
primitive

69
Register
• Registers represent abstract storage elements.
• A register holds its value until a new value is
assigned to it.
• Registers are used extensively in behavior
modeling and in applying test patterns.
• Default value is “X” (unknown)

70
Blocking and Non-blocking
• Blocking assignments are executed sequentially,
much like a program in C language
• Non-blocking assignments evaluate the right-hand
side, and make the assignments when all right-
hand have been evaluated
Initial values: A = 3, B = 4, C = 5;

begin A = 3; begin A = 3;
B = A; B <= A;
C = B;
B = 3; C <= B;
B = 3;
end C = 3; end C = 4;

Blocking assignments “ = “ Non-Blocking assignments “ <= “

71
4-bits Shift Register Codes
module shifter (in, clock, reset, out);
input in, clock, reset; in R[0] R[1] R[2] R[3] out
output out;
reg [3:0] R;
assign out = R[3];
always @(posedge clock) begin
if (!reset) Reg[3:0] <= 4’d0;
else begin “<=” non-blocking
Reg[0] <= in; assignment
Reg[1] <= Reg[0];
Reg[2] <= Reg[1];
Reg[3] <= Reg[2]; Use non-blocking
end assignments
end in sequential circuits;
endmodule

72
4-bit Up Counter
input reset, enable, clock;
output [3:0] out; Synchronous
reg [3:0] out; Reset
always @(posedge clock) begin
if (reset) out[3:0] <= 4’d0;
else begin
if (enable) begin
if (out == 4’d15) out[3:0] <= 4’d0;
else out <= out + 1’b1;
else out <= out;
end
end
end

73
4-bit Up-Down Counter
always @(posedge clk) begin
if (reset) out[2:0] = 3’d0;
else begin
if (enable) begin
if (select) begin
if (out == 4’d15) out[3:0]<=4’d0;
else out <= out + 1’b1;
end
else begin
if (out == 4’d0) out[3:0]<=4’d15;
else out <= out - 1’b1;
end
end
end
end

74

Você também pode gostar