0% found this document useful (0 votes)
45 views33 pages

Chapter 4

1. Begin-end blocks allow grouping of multiple statements into a single statement and are commonly used with if, case, and for statements. 2. Named blocks allow declaring local parameters and variables within the block. The scope of these is limited to the named block. 3. If-else statements can cause latches if not coded properly. Always blocks should have both if and else conditions to avoid latches.

Uploaded by

s9222647
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
45 views33 pages

Chapter 4

1. Begin-end blocks allow grouping of multiple statements into a single statement and are commonly used with if, case, and for statements. 2. Named blocks allow declaring local parameters and variables within the block. The scope of these is limited to the named block. 3. If-else statements can cause latches if not coded properly. Always blocks should have both if and else conditions to avoid latches.

Uploaded by

s9222647
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

數位IC設計

RTL Coding – Part II


Begin_End Statements
Begin-end block statements: begin [: block_name
1. Block statements is a way of syntactically
grouping several statements into a single reg local_variable_l ;
statement.
integer local_variable_2 ;
2. Sequential blocks are delimited by the
keywords begin and end. These begin…end parameter local_variable_3 ;]
pairs are commonly used in conjunction with
. . . statements . . .
if, case, and for statements to group several
statements. end
3. Functions and always blocks that contain
Verilog allows you to declare
more than one statement require a
variables (reg, integer and
begin…end pair to group the statements.
parameter) locally within a
4. Verilog provides a construct called a named
named block but not in an
block. unnamed block.
Named Block (1/3)
module UNNAMED_BLOCK(A , B , E , Y); module NAMED_BLOCK(A , B , E , Y);
parameter F= 12; input [3 : 0]A; input [3 : 0]B;
input [3 : 0]A; input E; output [4 : 0]Y; reg [4 : 0] Y;
input [3 : 0]B;
input E; always @(A or B or E)
output [4 : 0]Y; begin
if(E)
reg [4 : 0]Y; begin: Add_And
parameter F = 12; // in a named block
always @(A or B or E) Y = (A + B) & F;
begin end
if(E) else
Y = (A + B) & F;
begin: Sub_And
else
parameter F= 2; // in a named block
Y = (A - B) & F;
Y = (A - B) & F;
end
end
endmodule
end
endmodule
Named Block (2/3)
module NAMED_BLOCK(A , B , E , Y); if(E)
input [3 : 0]A; input [3 : 0]B; begin: Add_And
input E; output [4 : 0]Y; parameter F1 = 12;
reg [4 : 0]Y; Y = (A + B) + F1; //F1 is 12 not 1
end
parameter F1 = 1; else
parameter F2 = 8; begin: Sub_And
always @(A or B or E) parameter F2= 2;
begin Y = (A +B) + F2; //F2 is 2 not 8
end end

assign Z = (A + B) + F1; //F1 is 1


endmodule
Named Block (3/3)
module LOCAL_GOL(IN_1 , IN_2 , OUT_1 , OUT_2);
input [3 : 0]IN_1;
input [3 : 0]IN_2;
output [4 : 0]OUT_1; parameter X = 1;
output [4 : 0]OUT_2;
reg [4 : 0]OUT_1; always @(IN_2)
reg [4 : 0]OUT_2; begin: Local_Value_2
parameter X = 8;
always @(IN_1) OUT_2 = IN_2 + X;
begin: Local_Value_1 end 8
parameter X = 7; endmodule
OUT_1 = IN_1 + X;
end 7
If-Else Statements (1/4)
1. The if statement is followed by a statement or If (expression)
begin
block of statements enclosed by begin and end.
. . . statements . . .
2. If the value of the expression is nonzero, the end
expression is true and the statement block that [eIse
follows is executed. If the value of the expression begin
. . . statements . . .
is zero, the expression is false and the statement end]
block following else is executed.
3. If..else statements can cause synthesis of latches.
1
module IF_ELSE(IN1 , IN2 , E , OUT); OUT
input IN1, IN2, E; 0
output [1 : 0] OUT; reg [1 : 0]OUT;
always @(IN1 or IN2 or E) E
begin
if(E == 1)
OUT = IN1 + IN2;
else
OUT = IN1; end
endmodule
Combinational vs. Sequential Circuit
Combinational Circuit
n inputs m outputs
A combinational circuit consists of logic gates
.. whose outputs at any time are determined
.. directly from the present combination of inputs
without regard to previous inputs.

A sequential circuit is a system whose outputs at any time are determined


from the present combination of inputs and the previous inputs or outputs.
Combinational Circuit
m output
n input .. .. variables
variables

Memory
Elements
states
⚫ Sequential components contain memory elements
⚫ The output values of sequential components depend on the input values
and the values stored in the memory elements
If-Else Statements (2/4)
Module Latch(In, Enable, Out); Watch for unintentional Latches
input Enable; Module Latch(In, Enable, Out);
Input [3:0] In; input Enable;
output [3:0] Out; input [3:0] In;
always @(In or Enable) output [3:0] Out;
begin
if(Enable) No latch inference always @(In or Enable)
Out=In;
else begin
Out=0; if(Enable)
end Out=In;
endmodule end
Always@ (In or endmodule
Enable) If Enable ==1
begin Out (new) = In
Out=0; If Enable==0
if(Enable) Out (new) = Out (old)
Out=In;
end // no latch
If-Else Statements (3/4)
module IF_ELSE_VALUE(IN , OUT); module IF_ELSE_VALUE(IN , OUT);
input [1 : 0]IN; input [1 : 0]IN;
output [1 : 0]OUT; IN=0,OUT=11 output [1 : 0]OUT;
reg [1 : 0]OUT; IN=0,OUT=11
reg [1 : 0]OUT; IN=1,OUT=00
always @(IN) always @(IN) IN=1,OUT=00
IN=2,OUT=11 begin IN=2,OUT=00
begin
IN=3,OUT=11 if(IN) IN=3,OUT=00
if(IN==1)
OUT = 2'b00; true OUT = 2'b00; nonzero true
else else
OUT = 2'b11; false OUT = 2'b11; zero false
end end
endmodule endmodule
What is the difference between them?
If-Else Statements (4/4)

if-then-else statement implies priority-encoded MUXs

d 0
always @(sel or a or b or c or d) c 1
if (sel[2] == 1’b1)
sel sel[0] = ‘1’
out = a; //sel=1XX 0
else if (sel[1] == 1’b1) b 1
out = b; //sel=01X
sel[1] = ‘1’
else if (sel[0] == 1’b1) 0
out
out = c; //sel=001 a 1
else
sel[2] = ‘1’
out = d; //sel=000
Resource Sharing (1/2)
◼ Assign similar operations to a common netlist cell
◼ reduce hardware

◼ may degrade performance

◼ resource sharing within the same always block

◼ resource sharing not done for conditional operator

Without resource sharing Resource sharing


assign z = sel_a ? a+t : b+t; if (sel_a)
z = a + t;
else
a z = b + t;
t + 1
z
b 0
+ t
sel_a
a 1
Hence, in this case you better use if + z
b 0
statement not conditional operator “?”
to save a lot of cost and area sel_a
Resource Sharing (2/2)
module share(v, w, z,k);
module noshare(v, w, x, z, k); input [2:0] k,v,w;
input [2:0]k,v,w; input x; output [3:0]z;
input x; reg [3:0] y,z;
output [3:0]z;
wire [3:0]y; always@(x or k or v or w)
begin
assign y=x?k+w:k+v; if(x)
assign z=x?y+w:y+v; y=k+w;
else
endmodule y=k+v;
end
always@(y or x or w or v)
Without resource sharing begin
if(x)
z=y+w;
else
z=y+v;
With resource sharing end
endmodule
Case Statements (1/4)
The case statement consists of the keyword case, followed case (expression)
by an expression in parentheses, followed by one or more
case_item 1:
case items (and associated statements to be executed), begin
followed by the keyword endcase. A case item consists of an . statements . .
expression (usually a simple constant) or a list of expressions end
case_item 2:
separated by commas, followed by a colon (: ). begin
module FULL_CASE(IN , OUT); . statements. .
module FULL_CASE(IN , OUT);
input [1 : 0]IN;output [3 : 0] OUT;
input [1 : 0]IN;output [3 : 0] OUT;
end
reg [3 : 0]OUT; .....
reg [3 : 0]OUT;
always @(IN) default:
always @(IN)
begin begin
begin
case(IN)
2'b00: OUT = 4'b0001;
case(IN) . statements. .
2'b00: OUT = 4'b0001; end
2'b01: OUT = 4'b0010;
2'b01: OUT = 4'b0010; endcase
2'b10: OUT = 4'b0100;
2'b10: OUT = 4'b0100;
2'b11: OUT = 4'b1000;
endcase // not full-case, latches are inferred
endcase
end
end
endmodule
endmodule
Case Statements (2/4)

If the conditional expression used is mutually exclusive (i.e.


parallel) and the functional outputs are the same, then the
hardware synthesized will be same.

a 00
b 01 out
c 10
d 11

always @ (sel or a or b or c or d) 2 always @(sel or a or b or c or d)


begin sel if (sel == 2’b00)
case (sel) out = a;
2’b00: out = a; else if (sel == 2’b01)
2’b01: out = b; out = b;
2’b10: out = c; else if (sel == 2’b10)
default : out = d; out = c;
endcase else
end out = d;
Case Statements (3/4)
module FULL_CASE(IN , OUT); module FULL_CASE(IN , OUT);
input [1 : 0]IN; output [3 : 0] OUT; input [1 : 0]IN; output [3 : 0] OUT;
reg [3 : 0]OUT; reg [3 : 0]OUT;
always @(IN) always @(IN)
begin begin
case(IN) case(IN)
2'b00: OUT = 4'b0001; 2'b00: OUT = 4'b0001;
2'b01: OUT = 4'b0010; 2'b01: OUT = 4'b0010;
2'b10: OUT = 4'b0100; 2'b10: OUT = 4'b0100;
2'b11: OUT = 4'b1000; default: OUT = 4'b1000;
endcase endcase
end end
endmodule endmodule

It is always a good idea to use default-case-item in all conditions to


make sure no latch is inferred.
Case Statements (4/4)
Watch Out for Unintentional Latches
◼ Completely specify all clauses for every case and if
statement
◼ Completely specify all output for every clause of each
case or if statement
◼ Failure to do so will cause latches or flip-flops to be
synthesized
always @ (d)
begin
Missing Case case (d) Missing Outputs
2’b00: z = 1’b0;
2’b01: z = 1’b0;
d ==00 z=0 2’b10: ;
d ==01 z=0 endcase
d ==10 z(new)=z(old) end
d ==11 z(new)=z(old)
Casez and Casex Statements

casez (expression) casez: casex (expression)


The case item
case_item 1: case_item 1:
begin can use z or ? begin
. statements . . . statements . .
end end
case_item 2: case_item 2:
begin begin
. statements. . . statements. .
end casex: end
..... The case item .....
default: can use z, x, default:
begin or ? begin
. statements. . . statements. .
end end
endcase endcase

casez is one of the conditions in casex


Casex Statement
module FULL_CASEX(IN , OUT); always @(IN)
input [3 : 0] IN; begin
output [1 : 0] OUT; casex(IN)
4'b0001: OUT = 2'b00;
reg [1 : 0] OUT; 4'b001?: OUT = 2'b01;
4'b01??: OUT = 2'b10;
default: OUT = 2'b11;
endcase
end
endmodule
For Loop Statements (1/2)
The for loop repeatedly executes a single statement or block of statements. The
repetitions are performed over a range determined by the range expressions
assigned to an index. Two range expressions appear in each for loop: low_range
and high_range. In the syntax lines that follow, high_range is greater than or equal
to low_range. HDL Compiler recognizes incrementing as well as decrementing
loops. The statement to be duplicated is surrounded by begin and end statements.
for (index = low_range; index < high_range; index = index + step)
for (index = high_range; index > low_range; index = index - step)
for (index = low_range; index <= high_range; index = index + step)
for (index = high_range; index >= low_range; index = index - step)

for (i = 0; i <= 31; i = i +1)


begin For statement: unrolling the logic
s[i] = a[i] ^ b[I] ^ carry;
carry = (a[i] & b[i]) | (a[i] & carry) | (b[i] & carry);
end
For Loop Statements (2/2)
for loop are “unrolled”, and then synthesized.
integer i;
always @(a r b)
begin a[0]
example[0]
for (i = 0; i < 6; i = i+1) b[5]
example[i] <= a[i] & b[5-i]; a[1]
example[1]
end b[4]
a[2]
Verilog for loop example[2]
b[3]
a[3]
example[3]
example [0] <= a[0] and b[5]; b[2]
a[4]
example [1] <= a[1] and b[4]; example[4]
b[1]
example [2] <= a[2] and b[3];
a[5]
example [3] <= a[3] and b[2]; example[5]
b[0]
example [4] <= a[4] and b[1];
example [5] <= a[5] and b[0]; for loop synthesized to gates
for loop unrolled
Sorting Problem (1/2)
Bubble Sort: (four inputs)
always@(a or b or c or d)
1. (0)?(1) (compare temp[0] and temp [1],
begin
then the bigger value is stored in temp[1]) temp[0]=a;
(1)?(2) (compare temp[1] and temp [2],..) temp[1]=b;
temp[2]=c;
(2)?(3) (compare temp[2] and temp [3],..) temp[3]=d;
2. (0)?(1), (1)?(2) for(i=2;i>=0;i=i-1)
for(j=0;j<=i;j=j+1)
3. (0)?(1)
if(temp[j]>temp[j+1])
Totally, six comparators are needed begin
for parallel comparisons of 4 inputs buffer=temp[j+1];
temp[j+1]=temp[j];
module for_loop(a,b,c,d,out); temp[j]=buffer;
input [3:0]a,b,c,d; end
output [3:0]out; out=temp[3];
reg [3:0] temp [3:0]; end
reg [3:0] buffer,out; endmodule
integer i,j;
Sorting Problem (2/2)

Bubble Sort: (four inputs) Bubble Sort: (five inputs)


(0)?(1), (1)?(2), (2)?(3) (0)?(1), (1)?(2), (2)?(3), (3)?(4)
(0)?(1), (1)?(2) (0)?(1), (1)?(2), (2)?(3)
(0)?(1) critical path=6.01 ns (0)?(1), (1)?(2)
Totally, 6 comparators are needed (0)?(1) critical path=8.05 ns
for parallel comparisons Totally, 10 comparators are needed

The more inputs, the longer delay use one comparator and a suitable FSM
Always Block (1/3)
An always block can imply latches or flip-flops, or it can specify purely
combinational logic. An always block can contain logic triggered in
response to a change in a level (asynchronous triggers) or the rising or
falling edge of a signal (synchronous triggers).
The syntax of an always block is

always @ (event-expression )
begin
Completely specify sensitivity lists to avoid error
. . . statements . . .
end (combinational circuit)
Asynchronous triggers
x is recalculated as soon as always@ (a or b or c)
any input (a or b or c) has a begin
level transition (0 to 1 or 1 to 0). x=a | b | c;
end
Always Block (2/3)

always @ ( [posedge or negedge] event)


begin rising falling
edge edge
. . . statements . . . (posedge) (negedge)
end (sequential circuit)
a
+ x
Rising edge or positive edge (posedge) b
Falling edge or negative edge (negedge) c

Synchronous triggers
always@ (posedge c)
x is recalculated as soon as begin
c changes from 0 to 1 x=a +b;
end storage unit
Always Block (3/3)
module D_FF(Clk, D, Q);
module ALWAYS_BLOCK(IN , OUT);
input Clk, D;
input [3 : 0]IN; output OUT; reg OUT;
output Q;
Reg Q;
always @(IN)
begin
always @(posedge Clk)
OUT = (IN[0] | IN[1]) & (IN[2] | IN[3]);
begin
end
Q=D;
endmodule
end
endmodule

D Q

Clk

At every positive edge of signal Clk,


Q is set as D.
Variables
Nets:
wire a; // 1-bit wire
wire [3:0] b; // 4-bit wire
Three types of common variables in Verilog:
(1) register (default width is 1 bit)
(2) integer (default width is 32 bit)
(3) parameter (default width is 1 bit)
parameter [range] identifier=expression,
reg a; // 1-bit register
identifier=expression;
reg [3:0] b; // 4-bit register
integer c; // single 32-bit integer
parameter d=4, e=6;

Three variables (register, integer and parameter) are declared globally at the
module level, or locally at the function level and begin-end block.
Verilog allows you to assign the value of a reg variable only within a function
or an always block.
Function
function [range] name_of_function;
function declaration
statement
endfunction

1. Begin with function and end with endfunction


2. [Range] defines the width of the return value of the function (default is 1 bit)
Contain one or more statements (enclosed inside a begin-end pair)
3. You can call function in a continuous assignment, always block or other
functions

Function declaration:
Input declaration: specify the input signals for a function
Output: The output from a function is assigned to the function name.
Use concatenation operation to bundle several values for multi-outputs
Function Statements (1/4)
Procedure assignments are assignment statements used inside a function.
(It is similar to C language, Note: it cannot be used in module)
They are similar to the continuous assignments, except that the left side of
a procedural assignment can contain only reg and integer variables.

module FUN_STATE(A , B , C1 , C2 , C3 , C4 , C5); always @(A or B)


input [3 : 0]A; input [3 : 0]B; begin
output [6 : 0]C1; //0 C1 = Fn1(A , B);
output [2 : 0]C2; //discard end A C?
output [4 : 0]C3; //always always @(A or B) +
output [4 : 0]C4; //assign begin B
reg [6 : 0]C1; reg [2 : 0]C2; C2 = Fn1(A , B);
reg [4 : 0]C3; reg [4 : 0]C4; end
always @(A or B)
function [4 : 0]Fn1; begin
input [3 : 0]A; input [3 : 0]B; C3 = A + B;
Fn1 = A + B; // like C end
endfunction
assign C4 = A + B;

Three different ways to implement addition endmodule


Function Statements (2/4)
input [3 : 0]A; input [3 : 0]B; // A and B are 4-bit values
output [6 : 0]C1; // C1 is 7-bit values
output [2 : 0]C2; // C2 is 3-bit values

always @(A or B)
begin
C1 = A +B; // insert “0” in the first two bits
end
begin
C2 = A + B ; // discard the first two bits
end
Function Statements (3/4)
module test_n(a, b, x, y);
input a, b; output x, y; module test_n(a, b, x, y);
reg x, y; input a, b;
function Fn1; output x, y;
input a, b; assign x=a & b;
Fn1 = a & b; assign y=a | b;
/* begin-end is required endmodule
for more statements */
endfunction
module test_n(a, b, x, y);
function Fn2; input a, b;
input a, b; output x, y;
Fn2 = a | b; reg x, y;
endfunction always @(a or b)
always @(a or b) begin C language
begin x = a & b; x = a&b;
x = Fn1(a, b); y = a | b;
y = Fn2(a, b); end y = a | b;
end endmodule
endmodule
Function Statements (4/4)
module test_n(a1, a, b, x, y);
module test_n(a1, a, b, x, y);
input [7:0] a1;
input [7:0] a1;
input a, b;
input a, b;
output x, y;
output x, y;
reg x, y;
reg x, y;
function Fn1;
function Fn1;
parameter width=8;
input [width-1:0] a1;
input [width-1:0] a1; // OK
parameter width=8;//error message
input a, b;
input a, b;
Fn1 = a & b;
Fn1 = a & b;
endfunction
endfunction
always @(a or b)
always @(a or b)
begin
begin
x = Fn1(a1, a, b);
x = Fn1(a1, a, b);
end
end
endmodule
endmodule
Can we input width with scanf or input ??
Why?
Example-Function
function [4 : 0] Fn1;
input [3 : 0]F1 , F2;
module FUN_ALL(A , B , Y1 , Y2); begin
input [3 : 0] A,B;output [4 : 0] Y1, Y2; Fn1 = Fn2(F1 , F2) + 2;
reg [4 : 0] Y1, Y2; end
endfunction
function [4 : 0] Fn2;
input [3 : 0] F1 , F2; always @(A or B)
begin begin Y1=A+B+2
Fn2 = F1 + F2; Y1 = Fn1(A , B); Y2=A+B
end Y2 = Fn2(A , B);
endfunction end
endmodule
Example-Function with Many Outputs
function [9 : 0]Fn1;
input [3 : 0] F1 , F2;
reg [4 : 0] Y1_1; reg [4 : 0] Y2_1;
begin
Y1_1 = F1 + F2 + 5;
Y2 _1= F1 + F2 + 2;
Fn1 = {Y1_1 , Y2_1};
Y1=A+B+5
end
Y2=A+B+2
endfunction
assign {Y1 , Y2} = Fn1(A , B); Y1_1 and Y2_1 can be declared as
endmodule reg or integer, not wire

You might also like