Verilog Overview

advertisement
Verilog Overview
EE5375 – ADD II
Prof. MacDonald
Verilog Overview
l 
l 
C-Like Language used to describe hardware
VHDL is main competitor
– 
– 
– 
l 
l 
l 
l 
VHDL is more rigorous and typed
VHDL takes longer to write
VHDL is used by 50% of US / most of the world
Verilog was originally owned by Cadence
Now an open language with standards
Used for ASIC design and FPGA programming
Verilog HDL : A Guide to Digital Design and
Synthesis by Samir Palnitkar
Simple Example
module counter (I_reset, I_clk, O_count);
input
I_reset;
input
I_clk;
output [3:0]
O_count;
reg [3:0]
O_count;
always @(posedge I_clk)
if (I_reset)
O_count <= 4’b0;
else
O_count <= O_count + 1;
endmodule
Testbench
any other inputs
reset gen
circuit
under
test (CUT)
count.v
monitors
clock gen
synthesizable code
unsynthesizable code –
artificial and for
verification only
waveform gen
tb.v testbench
Testbench
`timescale 1ns/1ps
module tb ();
reg
wire [3:0]
clk, reset;
count;
counter counter1 (.I_clk(clk), I_reset(reset), O_count(count));
initial clk = 0;
initial forever #10 clk = ~clk;
initial
begin
reset <= 1’b1;
#500
reset <= 1’b0;
#1000
$finish;
end
//clock generator
//clock generator
//main stimulus block
always @(count)
$display("counter value is now %x at time %t",count, $time);
initial begin
$dumpfile("verilog.dmp");
$dumpvars;
end
endmodule
Verilog command line
Output log (verilog.log)
Compiling source file "tb.v"
Compiling source file "counter.v"
Highest level modules:
tb
counter value is now 0 at time
5
counter value is now 1 at time
1005
counter value is now 2 at time
1015
counter value is now 3 at time
1025
counter value is now 4 at time
1035
counter value is now 5 at time
356085
counter value is now 6 at time
356095
counter value is now 7 at time
356105
counter value is now 8 at time
356115
counter value is now 9 at time
356125
counter value is now a at time
356135
counter value is now b at time
356145
counter value is now c at time
356155
counter value is now d at time
356165
counter value is now e at time
356175
counter value is now f at time
356185
counter value is now 0 at time
356195
counter value is now 1 at time
356205
VERILOG interrupt at time 356210
C1 > 0 simulation events (use +profile or +listcounts option to count)
CPU time: 0.2 secs to compile + 0.1 secs to link + 6.1 secs in simulation
End of VERILOG-XL 3.40.p001 Nov 16, 2004 09:58:09
Output Waves
Design Abstraction
l 
High Level Behavioral
– 
l 
Register Transfer Level (RTL)
– 
– 
l 
describes logic design with C like constructs
modern definition is that RTL is synthesizable
Gate level (netlist)
– 
l 
C or Matlab
describes design as a collection of logic gates connected
together – product of synthesizing RTL code
Transistor level (circuit design)
– 
– 
gates (primitives) used in synthesis
details are hidden “under the hood” from logic designers
Verilog RTL example
Verilog netlist example
n_119
n_37
i_62
a
b
y
NOR2X1
n_17
Layout example
Simple Design Flow (ASIC/FPGA)
Specification
Architecture
RTL Coding
Simulation
standard cell
library
Synthesis
Place, Route, and Timing
Arithmetic Operators
l 
l 
l 
l 
l 
l 
l 
- +, -, /, *, %
Arithmetic operators imply ALU in synthesis
Plus operator for addition +
Minus operator for subtraction –
Multiply operator for multiplication *
Division operator / (rarely used except in TBs)
Modulus operator %
Ensure input and output precision is appropriate
Logical Operators
l 
l 
l 
l 
Logical operators take two or more boolean vars and
provide a single boolean answer.
If input is a vector, then false if all zeros, otherwise true
AND is &&
OR is ||
wire [3:0]
wire
wire
inputA = 4’d3;
inputB = 1’b0;
C = inputA && inputB; // C = false or zero
Bitwise Operators
l 
l 
l 
l 
l 
l 
Bitwise operators work on each bit of vector
AND &
OR |
NOT ~
Exclusive OR ^
Exclusive NOR ~^ (compare)
wire [3:0] busA;
wire [3:0] busB;
wire [3:0] busAandB = busA & busB;
// 0101
// 0011
// 0001
Unary Operators
l 
l 
l 
l 
l 
Unary operators act on one input variable
Not – inverts boolean
AND – provides the logical AND of entire bus
OR – provides the logical OR of entire bus
XOR – provides the exclusive OR of entire bus
wire
wire [5:0]
assign
assign
assign
D;
C = 6’b0101010;
D = ^C; //D equals the parity of C
D = |C; // D equals 1
D = &C; //D equals 0
Shift Operators
l 
l 
l 
Shift <<, >> shifts the index of a bus
<vector> >> <number of bits>
Better approach is using concatenation
wire [3:0]
wire [3:0]
bus = 4’hA;
shifted_bus = bus >> 1; // 4’h5
Equality Operators
l 
l 
l 
l 
Takes two values and compares, provides boolean
=== compare with x and z values (simulation only)
== compares for equality, x or z result in x result
!= compares for inequality, x or z results in x
wire [3:0]
wire [3:0]
Wire
a
b
c
= 4’hA;
= 4’hA;
= (a == b); // true
Compare Operators
l 
l 
l 
l 
l 
Takes two values and compares, provides boolean
> greater than
< less than
=> greater than or equal
=< less than or equal
wire [3:0]
wire [3:0]
Wire
a
b
c
= 4’hA;
= 4’hA;
= (a => b); // true
Shift Operators
l 
l 
l 
Shift <<, >> shifts the index of a bus
<vector> >> <number of bits>
Better approach is using concatenation
wire [3:0]
wire [3:0]
bus = 4’hA;
shifted_bus = bus >> 1; // 4’h5
Concatenation Operator
l 
l 
Concatenation Operator {}
Used to splice busses together
wire [3:0]
wire [3:0]
wire [7:0]
assign
A = 4’hA;
B = 4’h5;
C;
C = {A, B};
// 8’hA5
OR
assign C = {1’b0, A, B[3:1]} // for shift with zero insert
Condition Operator (Mux)
l 
l 
l 
Condition operator used to imply muxes
<control> ? <selection1> : <selection0>;
Some consider this too dense and confusing for RTL
A = B ? C : D; // A = C if B=1 else A = D
A = B ? (D ? E : F) : D; // embedded condition operator is terrible
Verilog Data Types
l 
Nets are represented by wire data type
– 
– 
– 
l 
must be driven by an output
can be connected to any number of inputs
are defined by continuous assignment statements
Flip Flops and nets are represented by reg data type
– 
reg’s in verilog are not necessarily flip-flops
are defined by procedural blocks
always blocks with “posedge” are flip-flops
always blocks without “posedge” are wires
Initial blocks are for verification only (testbenches)
l 
Other less common data types include time, real,
– 
– 
– 
– 
integer
Verilog Data Types - busses
Wires and Regs can be defined as vectors or
busses
reg [7:0] counter;
// 8 bit register of flip-flops
wire [10:2] data_bus; // 9 bit bus
Can be individually addressed
assign output = data_bus[9];
or as a group
assign data_bus_out = data_bus;
Continuous Assignment Statements
Assignment statements assign values to wires and
can be used to describe combinatorial circuits only.
Any change on the right side, effects left side
immediately if no delay is specified.
Delay if specified is un-synthesizable and is for tb only.
Ex.
wire C;
assign C = (A & !B) | (!A & B);
Procedural Blocks
Procedural blocks are used to define reg data types and
can be used to describe combinatorial or sequential circuits.
Procedural blocks can use C-like constructs and begin with
always or initial key words.
Each block is an like an independent thread – all running in parallel.
reg Q;
always @(posedge CLK)
begin
if (reset) Q <= D;
else
Q <= 0;
end
Blocking vs. Non-blocking assignment
Regs is procedural blocks can be defined with blocking or nonblocking assignment.
Use non-blocking for flops and blocking for combinatorial.
always @(posedge CLK)
begin
A <= B;
C <= A;
Very common
end
interview
always @(A or B or Sel)
question
begin
A = B;
C = A;
end
Verilog Procedural Constructs
l 
l 
l 
l 
l 
If-then-else statement
case statement
for loop
while loop
System Calls
– 
– 
– 
– 
$display – dumps variable or string to standard output
$time – tells current simulation time
$stop – finishes the simulation
$dumpvar – creates a waveform file for subsequent viewing
State Machine Design Example
x
z
0
0
1
0
s0
0
0
s1
1
1
s2
1
0
0
0
X = 0 0 1 1 0 1 1 0 0 1 0 1 0 1 0 0
Z = 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0
Port list, Reg/Wire/Param declaration
module state_machine (
clk,
x,
z);
// clock
// input
// output
input x, clk;
output z;
// input declarations
// output declarations
reg [1:0] state;
reg [1:0] next_state;
reg z;
// 2 state flip flops
// 2 wires feeding FF inputs
// output
parameter IDLE = 2’b00;
parameter S1 = 2’b01;
parameter S2 = 2’b11;
Next State Logic Section
always @(state or x)
begin
case(state)
IDLE: begin
if ( x ) next_state = S1;
else next_state = IDLE;
end
S1 : begin
if ( x ) next_state = S1;
else next_state = S2;
end
S2 : begin
if ( x ) next_state = S1;
else next_state = IDLE;
end
end
Next State Logic Section
always @(state or x)
case(state)
IDLE:
S1 :
S2 :
if ( x ) next_state = S1;
else next_state = IDLE;
if ( x ) next_state = S1;
else next_state = S2;
if ( x ) next_state = S1;
else next_state = IDLE;
endcase
My personal preference is to use only single statements and
avoid the use of “Begin” and “End” – more readable.
State Sequential Section
always @(posedge CLK or posedge reset)
begin
if ( reset )
state <= IDLE;
else
state <= next_state;
end
Note that begin and end are not required here as the if-else
statement is a single statement
Output Logic Section
always @(state or x)
begin
case(state)
IDLE: begin
if ( x ) z = 0;
else z = 0;
end
S1 : begin
if ( x ) z = 0;
else z = 0;
end
S2 : begin
if ( x ) z = 1;
else z = 0;
end
end
endmodule // ending statement for last 4 slides
Alternative (better) Mealy
Module detector (clk, reset, in, out)
input
clk, reset, in;
output
out;
reg [1:0]
state;
wire
out = (state == 2) & in;
always @(posedge clk)
if (reset)
else case(state)
2’b00 : if (in)
else
2’b01 : if (in)
else
2’b10 : if (in)
else
endcase
endmodule
state <=0;
state <= 1;
state <= 0;
state <= 1;
state <= 2;
state <= 1;
state <= 0;
Alternative Style (moore)
Module detector (clk, reset, in, out)
input
clk, reset, in;
output
out;
reg [1:0]
state;
wire
out = (state == 3);
always @(posedge clk)
if (reset)
state <=0;
else case(state)
2’b00 : if (in)
state <= 1;
else
state <= 0;
2’b01 : if (in)
state <= 1;
else
state <= 2;
2’b10 : if (in)
state <= 3;
else
state <= 0;
2’b11 : if (in)
state <= 1;
else
state <= 2;
endcase
endmodule
Testbench
test_bench
sequence
generator
stimulus
clock
generator
state_machine
x
clk
z
checker
optional
reset
generator
circuit under test
Only state_machine is synthesizable. All else is for verification
purposes only.
Testbench example
module test_bench ( );
reg x, clk, reset;
// reg declarations
initial clk = 0;
always forever #100 clk = ~clk; // clk generation
initial begin
// sequence generation
reset = 1;
x = 0;
#(800) reset = 0; // better to use @(negedge clk) here, why?
#(200) x = 0;
#(200) x = 1;
#(200) x = 0;
$finish;
end
state_machine U0 (.X(x), .CLK(clk), .Z( ), .reset(reset));
endmodule
Testbench Tasks
Task adc_transaction ( );
// this task simulates a serial ADC off chip
input [7:0] sample;
begin
@(posedge convert) serial_data <= 0;
@(posedge sclk)
serial_data <= sample[7];
@(posedge sclk)
serial_data <= sample[6];
@(posedge sclk)
serial_data <= sample[5];
@(posedge sclk)
serial_data <= sample[4];
@(posedge sclk)
serial_data <= sample[3];
@(posedge sclk)
serial_data <= sample[2];
@(posedge sclk)
serial_data <= sample[1];
@(posedge sclk)
serial_data <= sample[0];
$display(“just transferred %x to ADC”, sample);
end
endtask
Testbench monitors for the log file
always @(posedge tb.dut.data_signal)
$display(“%d, %x, %x, %t”,
tb.dut.count,
tb.dut.var1,
tb.dut.var2,
tb.dut.var3,
$time);
Hierarchy (contrived example)
module top (clk, reset, in1, out1, out2)
input clk, reset, in1;
output out1, out2;
reg
out1;
reg [1:0]
count;
wire
out2;
wire [1:0] new_count = 2’b01;
always @(posedge clk)
if(reset)
else if (new_count == 2’b10)
else
// should be name of file top.v
// all ports as inputs defined
// all ports as outputs defined
// outputs can be defined as regs
// this is an internal reg
// outputs can be defined as wire
// this in an internal wire
out1 <= 0;
out1 <= in1 && out2;
out1 <= out1;
always @(posedge clk)
count <= count + 1;
assign out2 = in1 && out1;
// could be combined with wire
bottom bottom1 (.inA(count), .outB(new_count)); //instantiation
endmodule
Hierarchy (contrived example - 2)
module bottom (inA, outB)
input [1:0] inA;
output [1:0] outB;
wire [1:0] outB;
assign outB = inA + 2’b01;
endmodule
// should be name of file bottom.v
// all ports as inputs defined
// all ports as outputs defined
// outputs can be defined as wire
// could be combined with wire above
Synthesis effects
Continuous statements always result in combinatorial logic - no
flops or latches.
wire
start;
assign start = ready && request;
Synthesis effects
Continuous statements always result in combinatorial logic.
Here is a 32 bit comparator.
Note that the size of the netlist doesn’t necessarily correspond to
the number of lines of RTL
Wire [31:0]
Wire [31:0]
Wire
a;
b;
the_same ;
Assign the_same = a == b;
Synthesis effects
Always block without posedge statement is combinatorial.
Always @(D or S or E)
if (S) A = D;
else
A = E;
Always @(*) // verilog 2000
if (S) A = D;
else
A = E;
Synthesis effects
Always block without posedge statement is combinatorial.
This example will result in an ALU function.
Wire
Wire
Reg
[31:0]
[31:0]
[31:0]
ina;
inb;
out;
always @(ina or inb or subract)
if (subtract)
out = ina + (!inb + 32’h1);
else
out = ina + inb;
Synthesis effects
Always block without posedge statement is combinatorial.
This example will result in decoder.
always @(index)
case (index)
0:
decoder_out = 8’h01;
1:
decoder_out = 8’h02;
2:
decoder_out = 8’h04;
3:
decoder_out = 8’h08;
4:
decoder_out = 8’h10;
5:
decoder_out = 8’h20;
6:
decoder_out = 8’h40;
7:
decoder_out = 8’h80;
endcase
Synthesis effects
Always block without posedge statement is combinatorial.
This example will has a problem. All cases must be specified.
Here if enable is high, Q=D. What happens if enable is low?
Synthesis will add a latch to remember the old value of Q when it
is undefined by the if statement. Latches are rarely meant to
be used in logic and are a good sign of a problem when reported
by synthesis.
always @(*)
if (enable) Q = D;
// verilog 2000 format – much better
always @(enable or D) // original verilog
if (enable) Q = D;
Very common
interview
question
Synthesis effects
Always block with posedge clk statement is sequential.
This example will result in a simple non-resetable flip-flop.
Flip flops that define state or control should be reset, however
flip flops in the datapath can be left un-reset if data naturally
flows through to initialize.
always @(posedge clk)
A <= E;
Synthesis effects
Always block with posedge clk statement is sequential.
This example will result in a synchronous resetable flip-flop.
Requires a clock to register the reset – but glitch proof.
always @(posedge clk)
if (reset)
A <= 0;
else
A <= D;
reset
D
D FF
clk
Synthesis effects
Always block with posedge clk statement is sequential.
This example will result in a asynchronously resettable flip-flop.
The decision between asynch and synch resets is a religious one.
Asynch are immediate but glitch-prone.
Potential interview question.
always @(posedge clk or negedge reset)
if (reset)
A <= 0;
else
A <= E;
D
D FF
clk
reset
Synthesis effects
Always block with posedge clk statement is sequential but can
include some input combinatorial logic as shown.
always @(posedge clk)
if (reset)
A <= 0;
else
A <= E && C;
Synthesis effects
Shift register for parallel to serial conversion –
susceptible to hold time violations
module p2s (in, out, load, clk, reset)
input load, clk, reset;
input [7:0] in;
output
out;
reg [7:0] parallel_data;
wire
out = parallel_data[7];
always @(posedge clk)
if (reset)
parallel_data <= 0;
else if (load)
parallel_data <= in;
else
parallel_data <= {parallel[6:0], 1’b0};
endmodule
Synthesis effects - Latches
Always block with posedge clk statement is sequential.
This example will result in a transparent latch. Very unusual in
RTL.
Typically, latches in the synthesized netlist are the sign of mistakes.
always @(clk or in)
if (clk)
else
//unusual but intentional latch
A = in;
A = A;
always @(*) // typical unintentional latch
if (enable)
A = in;
Verilog Design Guidelines
l 
l 
l 
l 
l 
l 
l 
l 
l 
l 
l 
l 
Use meaningful names for signals and variables
Use “I_” and “O_” for port names – I for input / O for output
Modify regs in only one always block
Only use dedicated clock for posedge statements
Constants and Parameters should be all caps
Never use tabs but do line up text with spaces
Avoid mixing positive and negative edge-triggered flip-flops
Use parentheses to optimize logic structure
Use continuous assign statements for simple combo logic.
Use non-blocking for sequential and blocking for combo logic
Define if-else/case statements explicitly – all vars for all cases
Always instantiate modules with explicit port listing.
Most common student mistakes
l 
Synthesizable code should
– 
– 
l 
l 
l 
Define a reg in only one always block (otherwise ambiguity)
for loops are for spatial repeating - not temporal
Fully specify variables within an always block for readability
– 
– 
l 
l 
not have delays included (#)
only have always blocks and no initial blocks
i.e. if (X) Y = A, else Y = B. Define Y in all possible cases.
this may result in unwanted latches (as opposed to flip-flops)
Fully specify sensitivity list in combinatorial always blocks
Blocking vs. Non-blocking assignments
– 
rule of thumb
l 
l 
l 
if it has a posedge, use the “<=“ because it is sequential
otherwise use the “=“ because it is combinational
Really doesn’t matter if you only define a single variable in a block
Examples of bad code
In any always block, define all variables for all cases.
Not doing so can cause latches and in general is hard to follow.
always @(C or D or S or E)
begin
if (S) begin
A = D;
B = C;
end
else
A = E;
end
always @(C or D or S or E)
begin
if (S) begin
A = D;
B = C;
end
else
begin
A = E;
B = C;
end
end
Examples of bad code
Define any variable in only one always block.
Otherwise, sim and synth will mismatch.
always @(D or S)
if (S) A = D;
always @(G or E)
if (G) A = E;
always @(D or E or G or S)
if (S)
A = D;
else if (G)
A = E;
else
A = K;
Examples of bad code
Define only one if-else if-else statement per always block.
Confusing to follow. Better to have one block for each variable and
one variable per block.
always @(D or S or K or
J or E or C or G )
begin
if (S) A = D;
else if A = J;
else
A = K;
if (G) B <= E;
else
B <= C;
end
always @(D or E or G or S)
if (S) A = D;
else if A = J;
else
A = K;
always @(G or E or C)
if (G) B = E;
else
B = C;
Clocking
Best to use one universal clock for design – avoid using data
signals as clocks
One clock is better for static timing – can only time paths between
flops on the same clock.
Each clock tree has to be balanced – the fewer the better.
Some clever ideas bring ASIC methodologies to the knees.
D FF
D FF
D FF
Reference
l 
Verilog 2001 Standard – new features added
– 
– 
l 
port list and input/output declarations combined
sensitivity lists in always blocks need not be listed
Good reference web pages for Verilog
– 
– 
– 
– 
– 
– 
– 
– 
www.deepchip.com
www.deeps.org/verilog
www.edacafe.com
www.cadence.com
www.synopsys.com
www.mentor.com
www.magma-da.com
www.altera.com
www.xylinx.com
original company
most used synthesis tool
commonly used simulator
new synthesis tool
FPGA companies
FPGA companies
Download