Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

Verilog Synthesis Logic Synthesis

• Synthesis vs. Compilation • Verilog and VHDL started out as simulation languages, but soon
programs were written to automatically convert Verilog code into
• Descriptions mapped to hardware low-level circuit descriptions (netlists).
• Verilog design patterns for best synthesis
Verilog Synthesis circuit
HDL Tool 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

Fall 2005 Lec #10 -- HW Synthesis 1 Fall 2005 Lec #10 -- HW Synthesis 2

Why Perform Logic Synthesis? How Does It Work?


1. Automatically manages many details of the design process:
• Variety of general and ad-hoc (special case) methods:
• Fewer bugs – Instantiation: maintains a library of primitive modules ( AND, OR , etc.)
• Improves productivity and user defined modules
2. Abstracts the design data (HDL description) from any particular – “Macro expansion”/substitution: a large set of language operators
(+, -, Boolean operators, etc.) and constructs (if-else, case) expand into
implementation technology
special circuits
• Designs can be re-synthesized targeting different chip technologies;
– Inference: special patterns are detected in the language description
E.g.: first implement in FPGA then later in ASIC and treated specially (e.g.,: inferring memory blocks from variable
3. In some cases, leads to a more optimal design than could be declaration and read/write statements, FSM detection and generation
from “always @ (posedge clk)” blocks)
achieved by manual means (e.g.: logic optimization)
– Logic optimization: Boolean operations are grouped and optimized with
logic minimization techniques
– Structural reorganization: advanced techniques including sharing of
Why Not Logic Synthesis? operators, and retiming of circuits (moving FFs), and others

1. May lead to less than optimal designs in some cases

Fall 2005 Lec #10 -- HW Synthesis 3 Fall 2005 Lec #10 -- HW Synthesis 4

Operators Synthesis vs. Compilation


• Logical operators map into primitive
logic gates Levels of Representation • Compiler
Y = ~X << 2
• Arithmetic operators map into adders, – Recognizes all possible
subtractors, … temp = v[k]; constructs in a formally
High Level Language
– Unsigned 2s complement Program (e.g., C) v[k] = v[k+1]; defined program language
X[3] Y[5]
– Model carry: target is one-bit wider Compiler 61C v[k+1] = temp; – Translates them to a machine
that source X[2] Y[4] language representation of
Assembly Language lw $to, 0($2) execution process
– Watch out for *, %, and / Program (e.g.,MIPS)
lw $t1, 4($2)
X[1] Y[3]
• Relational operators generate Assembler
sw$t1, 0($2) • Synthesis
sw$t0, 4($2)
comparators X[0] Y[2] – Recognizes a target
• Shifts by constant amount are just
Machine Language 0000 1001 1100 0110 1010 1111 0101 1000
Y[1] Program (MIPS) 1010 1111 0101 1000 0000 1001 1100 0110 dependent subset of a
wire connections 1100
0101
0110
1000
1010
0000
1111
1001
0101
1100
1000
0110
0000
1010
1001
1111 hardware description language
Machine Interpretation
– No logic involved – Maps to collection of
• Variable shift amounts a whole
Control Signal
Y[0] Specification concrete hardware resources
different story --- shifter
°
° – Iterative tool in the design
15
• Conditional expression generates logic flow
or MUX
Fall 2005 Lec #10 -- HW Synthesis 5 Fall 2005 Lec #10 -- HW Synthesis 6

1
Simple Example Module Template
module foo (a,b,s0,s1,f); Synthesis tools expects to find modules in this format .
input [3:0] a; module <top_module_name>(<port list>);
input [3:0] b; /* Port declarations. followed by wire, reg, integer, task and function declarations */
/* Describe hardware with one or more continuous assignments, always blocks, module
input s0,s1; instantiations and gate instantiations */
output [3:0] f; // Continuous assignment
reg f; wire <result_signal_name>;
• Order of these statements is
assign <result_signal_name> = <expression>;
always @ (a or b or s0 or s1) // always block irrelevant, all execute concurrently
if (!s0 && s1 || s0) f=a; else f=b; always @(<event expression>)
endmodule begin • Statements between the begin and
// Procedural assignments
// if statements
end in an always block execute
• Should expand if-else into 4-bit wide multiplexer (a, b, f are 4-bit vectors) and // case, casex, and casez statements sequentially from top to bottom
optimize/minimize the control logic: // while, repeat and for loops
(however, beware of blocking versus
// user task and user function calls
end non-blocking assignment)
// Module instantiation
<module_name> <instance_name> (<port list>); • Statements within a fork-join
statement in an always block
// Instantiation of built-in gate primitive
gate_type_keyword (<port list>);
endmodule execute concurrently

Fall 2005 Lec #10 -- HW Synthesis 7 Fall 2005 Lec #10 -- HW Synthesis 8

Procedural Assignments Supported Verilog Constructs


• Verilog has two types of assignments within always blocks: – Net types: wire, tri, supply1, supply0; – Procedural assignments: blocking
• Blocking procedural assignment “=“ register types: reg, integer, time (64 assignments =, nonblocking
– RHS is executed and assignment is completed before the next bit reg); arrays of reg assignments <= (Note: <= cannot be
statement is executed; e.g., – Continuous assignments mixed with = for the same
register).
Assume A holds the value 1 … A=2; B=A; A is left with 2, B with 2. – Gate primitive and module
instantiations – Compiler directives: `define,
• Non-blocking procedural assignment “<=“ `ifdef, `else, `endif, `include,
RHS is executed and assignment takes place at the end of the current – always blocks, user tasks, user
– `undef
time step (not clock cycle); e.g., functions
– Miscellaneous:
– inputs, outputs, and inouts to a module
Assume A holds the value 1 … A<=2; B<=A; A is left with 2, B with 1. • Integer ranges and parameter
– All operators (+, -, *, /, %, <, >, <=, >=,
• Notion of “current time step” is tricky in synthesis, so to guarantee ==, !=, ===, !==, &&, ||, !, ~, &, ~&, |, ~|,
ranges
that your simulation matches the behavior of the synthesized ^~, ~^, ^, <<, >>, ?:, { }, {{ }}) [Note: / • Local declarations to begin-end
circuit, follow these rules: and % are supported for compile-time block
i. Use blocking assignments to model combinational logic within an always block constants and constant powers of 2] • Variable indexing of bit vectors
ii. Use non-blocking assignments to implement sequential logic – Procedural statements: if-else-if, on the left and right sides of
iii. Do not mix blocking and non-blocking assignments in the same always block case, casex, casez, for, repeat, while, assignments
iv. Do not make assignments to the same variable from more than one always forever, begin, end, fork, join
block

Fall 2005 Lec #10 -- HW Synthesis 9 Fall 2005 Lec #10 -- HW Synthesis 10

Unsupported Language Constructs Combinational Logic


CL can be generated using:
Generate error and halt synthesis Simply ignored
1. Primitive gate instantiation:
• Net types: trireg, wor, trior, wand, • Delay, delay control, and drive AND, OR, etc.
triand, tri0, tri1, and charge strength; strength
• register type: real • Scalared, vectored 2. Continuous assignment (assign keyword), example:
Module adder_8 (cout, sum, a, b, cin);
• Built-in unidirectional and
• Initial block output cout;
bidirectional switches, and pull-up,
pull-down • Compiler directives (except for output [7:0] sum;
input cin;
• Procedural statements: assign `define, `ifdef, `else, `endif,
input [7:0] a, b;
(different from the “continuous `include, and `undef, which are assign {cout, sum} = a + b + cin;
assignment”), deassign, wait supported) endmodule
• Named events and event triggers • Calls to system tasks and system
• UDPs (user defined primitives) and functions (they are only for 3. Always block:
specify blocks simulation) always @ (event_expression)
begin
• force, release, and hierarchical net
// procedural assignment statements, if statements,
names (for simulation only)
// case statements, while, repeat, and for loops.
// Task and function calls
end

Fall 2005 Lec #10 -- HW Synthesis 11 Fall 2005 Lec #10 -- HW Synthesis 12

2
Combinational Logic Always Blocks Combinational Logic Always Blocks (cont.)
• Make sure all signals assigned in a combinational always block are • To avoid synthesizing a latch in this case, add the missing select
explicitly assigned values every time that the always block line:
2'd2: out = c;
executes--otherwise latches will be generated to hold the last
• Or, in general, use the “default” case:
value for the signals not assigned values!
default: out = foo;
module mux4to1 (out, a, b, c, d, sel);
output out;
• If you don’t care about the assignment in a case (for instance
input a, b, c, d; you know that it will never come up) then assign the value “x” to
• Example: input [1:0] sel; the variable; E.g.:
– Sel case value 2’d2 omitted reg out; default: out = 1‘bx;
always @(sel or a or b or c or d)
– Out is not updated when begin The x is treated as a “don’t care” for synthesis and will simplify
select line has 2’d2 case (sel) the logic
– Latch is added by tool to 2'd0: out = a;
2'd1: out = b; (The synthesis directive “full_case” will accomplish the same,
hold the last value of out
under this condition
2'd3: out = d; but can lead to differences between simulation and synthesis.)
endcase
end
endmodule

Fall 2005 Lec #10 -- HW Synthesis 13 Fall 2005 Lec #10 -- HW Synthesis 14

Latch Rule Midterm #1 Results


• If a variable is not assigned in all possible executions of Midterm 1

an always statement then a latch is inferred 25


C C+ B- B B+ A- A
– E.g., when not assigned in all branches of an if or case A 15
A- 33
– Even a variable declared locally within an always is inferred as a 20

latch if incompletely assigned in a conditional statement B+ 37


15 B 14
Number

B- 2
10
C+ 2
C 2
5
GPA=3.43
0
38 39 40 41 42 43 44 45 46 47 48 49 50
Score

Mean
Fall 2005 Lec #10 -- HW Synthesis 15 Fall 2005 Lec #10 -- HW Synthesis 16

Encoder Example Encoder Example (cont.)


• Nested IF-ELSE might lead to “priority logic” • To avoid “priority logic” use the case construct:
– Example: 4-to-2 encoder
always @(x) • This style of cascaded
begin : encode logic may adversely always @(x)
if (x == 4'b0001) y = 2'b00; begin : encode
else if (x == 4'b0010) y = 2'b01; affect the performance case (x)
else if (x == 4'b0100) y = 2'b10; of the circuit 4’b0001: y = 2'b00;
else if (x == 4'b1000) y = 2'b11; 4’b0010: y = 2'b01;
else y = 2'bxx; 4'b0100: y = 2'b10;
end 4'b1000: y = 2'b11;
default: y = 2'bxx;
endcase
end

• All cases are matched in parallel


• Note, you don’t need the “parallel case” directive (except under
special circumstances, described later)
Fall 2005 Lec #10 -- HW Synthesis 17 Fall 2005 Lec #10 -- HW Synthesis 18

3
Encoder Example (cont.) Encoder Example (cont.)
• Circuit would be simplified during synthesis to take advantage of • If you can guarantee that only one 1 appears in the input (one hot
constant values as follows and other Boolean equalities: 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 1’s are ignored); the circuit will be simplified
A similar simplification would be applied to the if-else version also when possible

Fall 2005 Lec #10 -- HW Synthesis 19 Fall 2005 Lec #10 -- HW Synthesis 20

Encoder Example (cont.) Encoder Example (cont.)


• Parallel version, assuming we can guarantee only one 1 in the input: • Parallel version of “priority encoder”:

always @(x) always @(x)


begin : encode begin : encode
casex (x) // synthesis parallel_case casex (x)
4’bxxx1: y = 2'b00; 4’bxxx1: y = 2'b00;
4’bxx1x: y = 2'b01; 4’bxx1x: y = 2'b01;
4'bx1xx: y = 2'b10; 4'bx1xx: y = 2'b10;
4'b1xxx: y = 2'b11; 4'b1xxx: y = 2'b11;
default: y = 2'bxx; default: y = 2'bxx;
endcase endcase
end end

• Note now more than one case might match the input
• Therefore use “parallel case” directive: without it, synthesis adds • Note: “parallel case” directive is not used, synthesis adds appropriate
appropriate matching logic to force priority matching logic to force priority
– Semantics of case construct says that the cases are evaluated from – Just what we want for a priority encoder
top to bottom • Behavior matches that of the if-else version presented earlier
– Only an issue for synthesis when more than one case could match input

Fall 2005 Lec #10 -- HW Synthesis 21 Fall 2005 Lec #10 -- HW Synthesis 22

Sequential Logic Finite State Machines


• Example: D flip-flop with synchronous set/reset: module FSM1(clk,rst, enable, data_in, data_out);
input clk, rst, enable;
module dff(q, d, clk, set, rst); • “@ (posedge clk)” key to flip- input data_in;
input d, clk, set, rst; output data_out; • Style guidelines (some of
flop generation
output q; these are to get the right
reg q; • Note in this case, priority /* Defined state encoding;
result, and some just for
always @(posedge clk) this style preferred over ‘defines*/
if (reset) logic is appropriate parameter default=2'bxx; readability)
q <= 0; parameter idle=2'b00;
• For Xilinx Virtex FPGAs, the parameter read=2'b01; – Must have reset
else if (set)
q <= 1; tool infers a native flip-flop parameter write=2'b10; – Use separate always blocks
else reg data_out;
– No extra logic needed for reg [1:0] state, next_state; for sequential and combination
q <= d;
endmodule set/reset logic parts
/* always block for sequential logic*/
always @(posedge clk)
– Represent states with defined
We prefer synchronous set/reset, if (rst) state <= idle; labels or enumerated types
s
but how would you specify d q
else state <= next_state;

asynchronous preset/clear? clk


r

Fall 2005 Lec #10 -- HW Synthesis 23 Fall 2005 Lec #10 -- HW Synthesis 24

4
FSMs (cont.) More Help
/* always block for CL */ • Use CASE statement in an • Online documentation for Synplify
always @(state or enable or data_in)
begin always to implement next Synthesis Tool:
case (state) state and output logic – Under Documents/General Documentation, see
/* For each state def output and next */
idle : begin • Always use default case and Synplify Web Site/Literature:
data_out = 1’b0; http://www.synplicity.com/literature/index.html
assert the state variable
if (enable)
next_state = read; and output to ‘bx: – Online examples from Synplicity
else next_state = idle;
• Avoids implied latches
end • Bhasker is a good synthesis reference
read : begin … end • Allows use of don’t cares
write : begin … end leading to simplified logic • Trial and error with the synthesis tool
default : begin
• “FSM compiler” within synthesis – Synplify will display the output of synthesis in
next_state = default; tool can re-encode your states; schematic form for your inspection--try
data_out = 1’bx; Process is controlled by using a different input and see what it produces
end synthesis attribute (passed in a
endcase
end comment).
endmodule • Details in Synplify guide
Fall 2005 Lec #10 -- HW Synthesis 25 Fall 2005 Lec #10 -- HW Synthesis 26

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

Fall 2005 Lec #10 -- HW Synthesis 27

You might also like