Verilog Synthesis
Synthesis vs. Compilation
Descriptions mapped to hardware
Verilog design patterns for best synthesis
Spring 2007
Lec #8 -- HW
Logic Synthesis
Verilog and VHDL started out as simulation languages, but soon
programs were written to automatically convert Verilog code into
low-level circuit descriptions (netlists).
Verilog
HDL
Synthesis
Tool
circuit
netlist
Synthesis converts Verilog (or other HDL) descriptions to an
implementation using technology-specific primitives:
For FPGAs: LUTs, flip-flops, and RAM blocks
For ASICs: standard cell gate and flip-flop libraries, and memory
blocks
Spring 2007
Lec #8 -- HW
Why Perform Logic Synthesis?
1.
Automatically manages many details of the design process:
Fewer bugs
Improves productivity
2. Abstracts the design data (HDL description) from any particular
implementation technology
Designs can be re-synthesized targeting different chip technologies;
E.g.: first implement in FPGA then later in ASIC
3. In some cases, leads to a more optimal design than could be
achieved by manual means (e.g.: logic optimization)
Why Not Logic Synthesis?
1.
May lead to less than optimal designs in some cases
Spring 2007
Lec #8 -- HW
How Does It Work?
Variety of general and ad-hoc (special case) methods:
Instantiation: maintains a library of primitive modules (AND, OR, etc.)
and user defined modules
Macro expansion/substitution: a large set of language operators
(+, -, Boolean operators, etc.) and constructs (if-else, case) expand into
special circuits
Inference: special patterns are detected in the language description
and treated specially (e.g.,: inferring memory blocks from variable
declaration and read/write statements, FSM detection and generation
from always @ (posedge clk) blocks)
Logic optimization: Boolean operations are grouped and optimized with
logic minimization techniques
Structural reorganization: advanced techniques including sharing of
operators, and retiming of circuits (moving FFs), and others
Spring 2007
Lec #8 -- HW
Operators
Logical operators map into primitive
logic gates
Arithmetic operators map into adders,
subtractors,
Unsigned 2s complement
Model carry: target is one-bit wider
that source
Watch out for *, %, and /
Relational operators generate
comparators
Shifts by constant amount are just
wire connections
Y = ~X << 2
X[3]
Y[5]
X[2]
Y[4]
X[1]
Y[3]
X[0]
Y[2]
No logic involved
Variable shift amounts a whole
different story --- shifter
Conditional expression generates logic
or MUX
Spring 2007
Lec #8 -- HW
Y[1]
Y[0]
Synthesis vs. Compilation
Compiler
Levels of Representation
High Level Language
Program (e.g., C)
Compiler
61C
Assembly Language
Program (e.g.,MIPS)
Machine Language
Program (MIPS)
Machine Interpretation
temp = v[k];
v[k] = v[k+1];
v[k+1] = temp;
lw $to,
lw $t1,
sw$t1,
sw$t0,
Assembler
0000
1010
1100
0101
1001
1111
0110
1000
Recognizes all possible
constructs in a formally
defined program language
Translates them to a machine
language representation of
execution process
1100
0101
1010
0000
0($2)
4($2)
0($2)
4($2)
0110
1000
1111
1001
1010
0000
0101
1100
Synthesis
1111
1001
1000
0110
0101
1100
0000
1010
Recognizes a target
dependent subset of a
hardware description language
Maps to collection of concrete
hardware resources
Iterative tool in the design
flow
1000
0110
1001
1111
Control Signal
Specification
Spring 2007
15
Lec #8 -- HW
Simple Example
module foo (a,b,s0,s1,f);
input [3:0] a;
input [3:0] b;
input s0,s1;
output [3:0] f;
reg f;
always @ (a or b or s0 or s1)
if (!s0 && s1 || s0) f=a; else f=b;
endmodule
Should expand if-else into 4-bit wide multiplexer (a, b, f are 4-bit vectors) and
optimize/minimize the control logic:
Spring 2007
Lec #8 -- HW
Module Template
Synthesis tools expects to find modules in this format .
module<top_module_name>(<portlist>);
/* Port declarations. followed by wire, reg, integer, task and function declarations */
/* Describe hardware with one or more continuous assignments, always blocks, module
instantiations and gate instantiations */
// Continuous assignment
wire<result_signal_name>;
Order of these statements is
assign<result_signal_name>=<expression>;
// always block
irrelevant, all execute concurrently
always@(<eventexpression>)
Statements between the begin and
begin
// Procedural assignments
end in an always block execute
// if statements
sequentially from top to bottom
// case, casex, and casez statements
// while, repeat and for loops
(however, beware of blocking versus
// user task and user function calls
non-blocking assignment)
end
// Module instantiation
Statements within a fork-join
<module_name><instance_name>(<portlist>);
statement in an always block
// Instantiation of built-in gate primitive
gate_type_keyword(<portlist>);
execute concurrently
endmodule
Spring 2007
Lec #8 -- HW
Procedural Assignments
Verilog has two types of assignments within always blocks:
Blocking procedural assignment =
RHS is executed and assignment is completed before the next statement is
executed; e.g.,
Assume A holds the value 1 A=2; B=A; A is left with 2, B with 2.
Non-blocking procedural assignment <=
RHS is executed and assignment takes place at the end of the current time step
(not clock cycle); e.g.,
Assume A holds the value 1 A<=2; B<=A; A is left with 2, B with 1.
Notion of current time step is tricky in synthesis, so to guarantee that
your simulation matches the behavior of the synthesized circuit, follow
these rules:
i.
Use blocking assignments to model combinational logic within an always block
ii.
Use non-blocking assignments to implement sequential logic
iii. Do not mix blocking and non-blocking assignments in the same always block
iv. Do not make assignments to the same variable from more than one always block
Spring 2007
Lec #8 -- HW
Supported Verilog Constructs
Net types: wire, tri, supply1, supply0;
register types: reg, integer, time (64
bit reg); arrays of reg
Continuous assignments
Gate primitive and module
instantiations
always blocks, user tasks, user
functions
inputs, outputs, and inouts to a module
All operators (+, -, *, /, %, <, >, <=, >=,
==, !=, ===, !==, &&, ||, !, ~, &, ~&, |, ~|,
^~, ~^, ^, <<, >>, ?:, { }, {{ }}) [Note: /
and % are supported for compile-time
constants and constant powers of 2]
Procedural statements: if-else-if,
case, casex, casez, for, repeat, while,
forever, begin, end, fork, join
Spring 2007
Procedural assignments: blocking
assignments =, nonblocking
assignments <= (Note: <= cannot be
mixed with = for the same register).
Compiler directives: `define, `ifdef,
`else, `endif, `include, `undef
Miscellaneous:
Integer ranges and parameter
ranges
Local declarations to begin-end
block
Variable indexing of bit vectors
on the left and right sides of
assignments
Lec #8 -- HW
10
Unsupported Language Constructs
Generate error and halt synthesis
Net types: trireg, wor, trior, wand,
triand, tri0, tri1, and charge strength;
register type: real
Built-in unidirectional and
bidirectional switches, and pull-up,
pull-down
Procedural statements: assign
(different from the continuous
assignment), deassign, wait
Named events and event triggers
UDPs (user defined primitives) and
specify blocks
force, release, and hierarchical net
names (for simulation only)
Spring 2007
Simply ignored
Delay, delay control, and drive
strength
Scalared, vectored
Initial block
Compiler directives (except for
`define, `ifdef, `else, `endif,
`include, and `undef, which are
supported)
Calls to system tasks and system
functions (they are only for
simulation)
Lec #8 -- HW
11
Combinational Logic
CL can be generated using:
1.
Primitive gate instantiation:
AND, OR, etc.
2.
Continuous assignment (assign keyword), example:
Module adder_8 (cout, sum, a, b, cin);
output cout;
output [7:0] sum;
input cin;
input [7:0] a, b;
assign {cout, sum} = a + b + cin;
endmodule
3.
Always block:
always @ (event_expression)
begin
// procedural assignment statements, if statements,
// case statements, while, repeat, and for loops.
// Task and function calls
end
Spring 2007
Lec #8 -- HW
12
Combinational Logic Always Blocks
Make sure all signals assigned in a combinational always block are
explicitly assigned values every time that the always block
executes--otherwise latches will be generated to hold the last
value for the signals not assigned values!
Example:
Sel case value 2d2 omitted
Out is not updated when
select line has 2d2
Latch is added by tool to
hold the last value of out
under this condition
Spring 2007
module mux4to1 (out, a, b, c, d, sel);
output out;
input a, b, c, d;
input [1:0] sel;
reg out;
always @(sel or a or b or c or d)
begin
case (sel)
2'd0: out = a;
2'd1: out = b;
2'd3: out = d;
endcase
end
endmodule
Lec #8 -- HW
13
Combinational Logic Always Blocks (cont.)
To avoid synthesizing a latch in this case, add the missing select
line:
2'd2: out = c;
Or, in general, use the default case:
default:
out = foo;
default:
out = 1bx;
If you dont care about the assignment in a case (for instance
you know that it will never come up) then assign the value x to
the variable; E.g.:
The x is treated as a dont care for synthesis and will simplify
the logic
(The synthesis directive full_case will accomplish the same,
but can lead to differences between simulation and synthesis.)
Spring 2007
Lec #8 -- HW
14
Latch Rule
If a variable is not assigned in all possible executions of
an always statement then a latch is inferred
E.g., when not assigned in all branches of an if or case
Even a variable declared locally within an always is inferred as a
latch if incompletely assigned in a conditional statement
Spring 2007
Lec #8 -- HW
15
Encoder Example
Nested IF-ELSE might lead to priority logic
Example: 4-to-2 encoder
always @(x)
begin : encode
if (x == 4'b0001) y = 2'b00;
else if (x == 4'b0010) y = 2'b01;
else if (x == 4'b0100) y = 2'b10;
else if (x == 4'b1000) y = 2'b11;
else y = 2'bxx;
end
Spring 2007
This style of cascaded
logic may adversely
affect the performance
of the circuit
Lec #8 -- HW
16
Encoder Example (cont.)
To avoid priority logic use the case construct:
always @(x)
begin : encode
case (x)
4b0001: y = 2'b00;
4b0010: y = 2'b01;
4'b0100: y = 2'b10;
4'b1000: y = 2'b11;
default: y = 2'bxx;
endcase
end
All cases are matched in parallel
Note, you dont need the parallel case directive (except under
special circumstances, described later)
Spring 2007
Lec #8 -- HW
17
Encoder Example (cont.)
Circuit would be simplified during synthesis to take advantage of
constant values as follows and other Boolean equalities:
A similar simplification would be applied to the if-else version also
Spring 2007
Lec #8 -- HW
18
Encoder Example (cont.)
If you can guarantee that only one 1 appears in the input (one hot
encoding), then simpler logic can be generated:
always @(x)
begin : encode
if (x[0]) y = 2'b00;
else if (x[1]) y = 2'b01;
else if (x[2]) y = 2'b10;
else if (x[3]) y = 2'b11;
else y = 2'bxx;
end
If the input applied has more than one 1, then this version functions
as a priority encoder -- least significant 1 gets priority (the more
significant 1s are ignored); the circuit will be simplified when possible
Spring 2007
Lec #8 -- HW
19
Encoder Example (cont.)
Parallel version, assuming we can guarantee only one 1 in the input:
always @(x)
begin : encode
casex (x) // synthesis parallel_case
4bxxx1: y = 2'b00;
4bxx1x: y = 2'b01;
4'bx1xx: y = 2'b10;
4'b1xxx: y = 2'b11;
default: y = 2'bxx;
endcase
end
Note now more than one case might match the input
Therefore use parallel case directive: without it, synthesis adds
appropriate matching logic to force priority
Semantics of case construct says that the cases are evaluated from top
to bottom
Only an issue for synthesis when more than one case could match input
Spring 2007
Lec #8 -- HW
20
Encoder Example (cont.)
Parallel version of priority encoder:
always @(x)
begin : encode
casex (x)
4bxxx1: y = 2'b00;
4bxx1x: y = 2'b01;
4'bx1xx: y = 2'b10;
4'b1xxx: y = 2'b11;
default: y = 2'bxx;
endcase
end
Note: parallel case directive is not used, synthesis adds appropriate
matching logic to force priority
Just what we want for a priority encoder
Behavior matches that of the if-else version presented earlier
Spring 2007
Lec #8 -- HW
21
Sequential Logic
Example: D flip-flop with synchronous set/reset:
module dff(q, d, clk, set, rst);
input d, clk, set, rst;
output q;
reg q;
always @(posedge clk)
if (reset)
q <= 0;
else if (set)
q <= 1;
else
q <= d;
endmodule
We prefer synchronous set/reset,
but how would you specify
asynchronous preset/clear?
Spring 2007
@ (posedge clk) key to flipflop generation
Note in this case, priority
logic is appropriate
For Xilinx Virtex FPGAs, the
tool infers a native flip-flop
No extra logic needed for
set/reset
d
clk
Lec #8 -- HW
s
r
22
Finite State Machines
module FSM1(clk,rst, enable, data_in, data_out);
input clk, rst, enable;
input data_in;
Style guidelines
output data_out;
/* Defined state encoding;
this style preferred over defines */
parameter default=2'bxx;
parameter idle=2'b00;
parameter read=2'b01;
parameter write=2'b10;
reg data_out;
reg [1:0] state, next_state;
(some of
these are to get the right
result, and some just for
readability)
Must have reset
Use separate always blocks
for sequential and combination
logic parts
Represent states with defined
labels or enumerated types
/* always block for sequential logic */
always @(posedge clk)
if (rst) state <= idle;
else state <= next_state;
Spring 2007
Lec #8 -- HW
23
FSMs (cont.)
/* always block for CL */
always @(state or enable or data_in)
begin
case (state)
/* For each state def output and next */
idle : begin
data_out = 1b0;
if (enable)
next_state = read;
else next_state = idle;
end
read : begin end
write : begin
end
default : begin
next_state = default;
data_out = 1bx;
end
endcase
end
endmodule
Spring 2007
Use CASE statement in an
always to implement next
state and output logic
Always use default case and
assert the state variable
and output to bx:
Avoids implied latches
Allows use of dont cares
leading to simplified logic
FSM compiler within synthesis
tool can re-encode your states;
Process is controlled by using a
synthesis attribute (passed in a
comment).
Details in Synplify guide
Lec #8 -- HW
24
More Help
Online documentation for Synplify
Synthesis Tool:
Under Documents/General Documentation, see
Synplify Web Site/Literature:
[Link]
Online examples from Synplicity
Bhasker is a good synthesis reference
Trial and error with the synthesis tool
Synplify will display the output of synthesis in
schematic form for your inspection--try
different input and see what it produces
Spring 2007
Lec #8 -- HW
25
Bottom-line
Have the hardware design clear in your mind when you
write the verilog
Write the verilog to describe that HW
It is a Hardware Description Language not a Hardware
Imagination Language
If you are very clear, the synthesis tools are likely to
figure it out
Spring 2007
Lec #8 -- HW
26