RTL Coding Hints
RTL Coding Hints
Think Synchronous
Synchronous designs run smoothly through synthesis, simulation and place-and-route Isolate necessary Asynchronous logic into separate blocks
ACK_SET ADDR_IN
ADDR DECODE
+5
GND
ACK
AS ACK_CLR
module GIZMO (A, CLK, Z); module GIZMO (A, CLK, Z); ... ... always @(A) begin : COMBO1... always @(A) begin : COMBO1... always @(posedge CLK)... always @(posedge CLK)... always @(B) begin : COMBO2... always @(B) begin : COMBO2... always @(posedge CLK) ... always @(posedge CLK) ... Verilog RTL Code end module; end module;
module EXAMPLE (DATA1,DATA2,CLK,Q) module EXAMPLE (DATA1,DATA2,CLK,Q) input DATA1,DATA2,CLK; input DATA1,DATA2,CLK; output Q; output Q; reg DATA, Q; reg DATA, Q; always @(DATA1 or DATA2) always @(DATA1 or DATA2) begin: COMBO begin: COMBO DATA <= GOBBLEDYGOOK(DATA1,DATA2); DATA <= GOBBLEDYGOOK(DATA1,DATA2); end end always @(posedge CLK) always @(posedge CLK) begin: SEQUENTIAL begin: SEQUENTIAL QQ <= DATA; <= DATA; end end endmodule endmodule Combinational Logic
DATA1 DATA2 CLK GOBBLEDY -GOOK DATA Q
Sequential Logic
IF Statements
IF statements infer multiplexer logic
always @(SEL or A or B) always @(SEL or A or B) if (SEL) if (SEL) D <= A; D <= A; else else D <= B; D <= B;
B A SEL
0 1
Latches are inferred unless all variables are assigned in all branches
always @(SEL or A) always @(SEL or A) if (SEL) if (SEL) D <= A; D <= A; 0 1
A SEL
IF Statements (cont.)
IF-ELSE-IF statements infer priority-encoded multiplexers
D
always @(SEL or A or B or C or D) always @(SEL or A or B or C or D) if (SEL[2] == 1b1) if (SEL[2] == 1b1) OUT <= A; OUT <= A; else if (SEL[1] == 1b1) else if (SEL[1] == 1b1) OUT <= B; OUT <= B; else if (SEL[0] == 1b1) else if (SEL[0] == 1b1) OUT <= C; OUT <= C; else else OUT <= D; OUT <= D;
C SEL B
0 1
SEL[0]=1
0 1
SEL[1]=1
A
SEL[2]=1
0 1
OUT
IF Statements (cont.)
Remove redundant conditions Use CASE statements if conditions are mutually exclusive
Dont
always @(A or B or C or D or E) always @(A or B or C or D or E) if (A < B) if (A < B) OUT <= C; OUT <= C; else if (A > B) else if (A > B) OUT <= D; OUT <= D; else if (A == B) else if (A == B) OUT <= E; OUT <= E;
Do
always @(A or B or C or D or E) always @(A or B or C or D or E) if (A < B) if (A < B) OUT <= C; OUT <= C; else if (A > B) else if (A > B) OUT <= D; OUT <= D; else else OUT <= E; OUT <= E;
CASE Statements
Verilog Directives
full_case indicates that all user-desired cases have been specified Do not use default for one-hot encoding
one hot
always @(SEL or AA or BB or C) always @(SEL or or or C) begin begin case (SEL) //synopsys full_case case (SEL) //synopsys full_case 3b001 :: OUT <= A; 3b001 OUT <= A; 3b010 :: OUT <= B; 3b010 OUT <= B; 3b100 :: OUT <= C; 3b100 OUT <= C; endcase endcase end end always @(SEL or AA or B) always @(SEL or or B) begin begin case (SEL) case (SEL) 3b001 :: OUT <= A; 3b001 OUT <= A; 3b010 :: OUT <= B; 3b010 OUT <= B; 3b100 :: OUT <= C; 3b100 OUT <= C; endcase endcase end end
CIC Training Manual
Infers latches for OUT because not all cases are specified
CASE Statements
always @(SEL or AA or BB or C) always @(SEL or or or C) begin begin case (SEL) //synopsys parallel_case case (SEL) //synopsys parallel_case AA :: OUT <= 3b001; OUT <= 3b001; BB :: OUT <= 3b010; OUT <= 3b010; CC :: OUT <= 3b100; OUT <= 3b100; endcase endcase end end
Infers a multiplexer
CASE Statements
CASE Statements
FSM Encoding
Use CASE statements to describe FSMs Use //synopsys parallel_case to indicate mutual exclusivity Use //synopsys full_case when not all possible states are covered (one-hot) Do not use default unless recovery state is desired
CASE Statements
FSM Encoding (cont.)
module EXAMPLE (RESET, CLK, OUT); module EXAMPLE (RESET, CLK, OUT); input RESET, CLK; input RESET, CLK; output [1:0] OUT; output [1:0] OUT; parameter IDLE=4b0001, GO=4b0010, YIELD=4b0100, parameter IDLE=4b0001, GO=4b0010, YIELD=4b0100, STOP=4b1000; STOP=4b1000; reg [3:0] CURRENT_STATE, NEXT_STATE; reg [3:0] CURRENT_STATE, NEXT_STATE; always @(CURRENT_STATE) always @(CURRENT_STATE) begin: COMBO begin: COMBO case (CURRENT_STATE) // synopsys full_case parallel_case case (CURRENT_STATE) // synopsys full_case parallel_case IDLE: begin NEXT_STATE = GO; OUT <= 2b01; end IDLE: begin NEXT_STATE = GO; OUT <= 2b01; end GO: begin NEXT_STATE = YIELD; OUT <= 2b11; end GO: begin NEXT_STATE = YIELD; OUT <= 2b11; end YIELD: begin NEXT_STATE = STOP; OUT <= 2b10; end YIELD: begin NEXT_STATE = STOP; OUT <= 2b10; end STOP: begin NEXT_STATE = IDLE; OUT <= 2b00; end STOP: begin NEXT_STATE = IDLE; OUT <= 2b00; end endcase endcase end end always @(posedge CLK or negedge RESET) always @(posedge CLK or negedge RESET) begin: SEQUENTIAL begin: SEQUENTIAL if (~RESET) if (~RESET) CURRENT_STATE <= IDLE; CURRENT_STATE <= IDLE; else else CURRENT_STATE <= NEXT_STATE CURRENT_STATE <= NEXT_STATE end end endmodule endmodule
CIC Training Manual
Use parameter statements to define state values Use CASE statements and // synopsys parallel_case full_case to describe FSM
CURRENT_STATE
STATE VECTOR
CASE Statements
CASE Statements
Multiplexers
Use IF or continuous assignment when select is a single-bit signal
always @(SEL or AA or B) always @(SEL or or B) if (SEL) if (SEL) DD <= A; <= A; else else DD <= B; <= B; --------------------------------------------assign DD == SEL ?? AA :: B; assign SEL B;
B A SEL
0 1
A B C D 2 SEL
00 01 10 11
OUT
Operators
Operators inferred from HDL
Adder, Subtractor, AddSub (+, -), Multiplier (*) Comparators (>, >=, <, <=, ==, !=) Incrementer, Decrementer, IncDec (+1, -1)
Example
module add (sum, a, b); module add (sum, a, b); output [15:0] sum; output [15:0] sum; input [15:0] a, b; input [15:0] a, b; assign sum == aa ++ bb ++ 1b1; assign sum 1b1; endmodule endmodule module add (sum, a, b); module add (sum, a, b); output [15:0] sum; output [15:0] sum; input [15:0] a, b; input [15:0] a, b; wire temp; wire temp; assign {sum, temp} = {a, 1b1} + {b, 1b1}; assign {sum, temp} = {a, 1b1} + {b, 1b1}; endmodule endmodule
CIC Training Manual HDL Coding Hints: Generic Coding Techniques & Considerations - 94
Operator Sharing
Operators can be shared within an always block by default Users can disable sharing
A Z
Operators
g arin h hS t Wi
Wi tho ut S har ing
+
C
MUX
B SEL
Smaller
+
B A
MUX
+
C
SEL
Larger
Operator Balancing
Use parenthesis to guide synthesis
Operators
A*B*C*D
(A*B)*(C*D)