Académique Documents
Professionnel Documents
Culture Documents
11/10/2013
Agenda
Overview of Digital Design with Verilog HDL Basic concepts Modules Hierarchical modeling concepts Gate-Level Modeling Dataflow Modeling Behavioral Modeling Tasks and Functions
11/10/2013
Agenda
Overview of Digital Design with Verilog HDL Basic concepts Modules Hierarchical modeling concepts Gate-Level Modeling Dataflow Modeling Behavioral Modeling Tasks and Functions
11/10/2013
Increased Computer-aid
BY HAND
Gate count was small
More sophisticated
Hundreds of gates
EDA began evolve in logic simulation EDA was critical
Thousands of gates
>100,000 transistors
11/10/2013
Emergence of HDLs
Programming languages (FORTRAN, C, )
describe
Computer programs
describe
Digital circuits
Logic synthesis
Model concurrency in hardware elements Simulate circuit quickly using simulators Translate to schematic circuit manually change
Use RTL (register transfer level) design in HDLs Automatically extract schematic circuit from RTL
Design methodology: + Describe complex circuit at abstract level by designing in HDLs + Logic synthesis tools would implement gates and gate interconnections
5
11/10/2013
+ Analyze the design in terms of FUNCTIONALITY, PERFORMANCE, Functional Verification & Testing COMPLIANCE to standards, and OTHER high-level issues + Often written with HDLs orSynthesis EDA tools (combine HDLs and object oriented Logic / Timing Verification languages such as C++)
Gate level netlist Logical Verification & Testing Floor Planning Automatic Place and Route Physical Layout Layout Verification Implementation
Design Specification Behavioral Description RTL Description (HDL) Functional Verification & Testing
Design Specification Behavioral Description RTL Description (HDL) Functional Verification & Testing Logic Synthesis / Timing Verification Gate level netlist Logical Verification & Testing
+ Logic synthesis tools ensure the the gate-level netlist MEETS timing, power specifications Physical Layout
Layout Verification Implementation
Design Specification Behavioral Description RTL Description (HDL) Functional Verification & Testing
+ Gate-level netlist is input toSynthesis an Automatic Place and Route tool to create the Logic / Timing Verification LAYOUT
level netlist + The layout is verified and thenGate fabricated on a chip. Logical Verification & Testing Floor Planning Automatic Place and Route Physical Layout Layout Verification Implementation
Importance of HDLs
HDLs are now the dominant method for large digital designs Compared to schematic-based design
Design can be described at a very abstract level by use of HDLs. Most design bugs are eliminated at RTL description cut down design cycle time Provides a concise presentation of the design, being analogous to computer programming
12
11/10/2013
13
11/10/2013
Agenda
Overview of Digital Design with Verilog HDL Basic concepts Modules Hierarchical modeling concepts Gate-Level Modeling Dataflow Modeling Behavioral Modeling Tasks and Functions
14
11/10/2013
Logic value
0, 1, x (unknown), z (high impedance) A 1-bit variable can take any one of these values. (In case of n-bit signal, each bit can take one of these values)
Vcc off 0 on off Vcc on 1 off Vcc off z Vcc on/off(?) x off/on (?)
Dont know
x can not be implemented into silicon. On silicon signal must be 0, 1, or z. It can not take the value x. That is, x has meaning only in simulator Assignment such as y = 1bx will be neglected by synthesis tool
15
11/10/2013
Numerical value
literal integer numbers 10hFA 1b0 6d30 15o10752 37 <bit width><base number><value> 10 bits hexadecimal number FA (00_1111_1010) 1 bit binary number 0 (0) 6 bits decimal number (011110), decimal 30 15 bits octal number (001,000,111,101,010), decimal 4586 32-bit decimal 37 4b0 is equal to 4b0000 padding to the left 4b1 is equal to 4b0001 4bz is equal to 4bzzzz 4bx is equal to 4bxxxx
16
11/10/2013
Variables
scalar vector in_out_control data_in[7:0]
upper_data_out[31:16]
in_out_control <= data_in[5];
data_in
LSB MSB in_out_control Least Significant Bit Most Significant Bit Vector can be declared at [high# : low#] or [low# : high#], but the left number in the squared brackets is always the most significant bit of the vector Note: Vectors can be declared only for nets and reg data types. (Vector declaration for integer, real, realtime, and time data types are illegal.)
17
11/10/2013
Variables
18
11/10/2013
Variables
Data types
Nets
Net data type can be declared by using wire keyword. Net data types are used to model physical connections. They do not store values. The net data types have the value of their drivers. If a net variable has no driver, then it has a high-impedance value (z). Net cannot be used as left-hand value of procedural assignments. wand, wor, tri, triand, trior, tri0, tri1, and more keyword are prepared to declare net data type. However, avoid using those other than wire, use wire as much as you can
20
11/10/2013
Data types
Nets
wire a; // Declare net a for the above circuit wire b,c; // Declare two wires b,c for the above Net a will continuously assume the value computed at the output of gate g1 Data type declaration and wire connection declaration can be done in one sentence as shown below. wire [7:0] q3 = (sel3==1b1)?q1:q2; wire [7:0] q3; assign q3 = (sel==1b1)?q1:q2; However, do not use this expression to avoid troubles. Write type declaration and connection separately In general, avoid type declaration with complex assignment.
21
11/10/2013
Data types
Registers
Register data type can be declared by using reg keyword
Register are data types that store assigned values until a new assignment occurs.
A new value can be assigned to registers only by using procedural assignments.
Register data type is intended to declare variables to hold their value, memorize the value.
However, depending the way you program, it may not result in memory elements. Write your declaration of reg separately for those memory elements and for those wiring reg ff1, ff2, sig1, ff3, sig2; reg ff1, ff2, ff3; // FF output signal reg sig1, sig2; //combinational logic signals
22
11/10/2013
Data types
declaration
real
time
Note: vector declaration for integer, real, and time data types are illegal
23
11/10/2013
Data types
Arrays
Arrays are allowed in Verilog for reg, integer, time, real and vector register data types Multi-dimensional arrays can also be declared with any number of dimensions. Each element of the array can be used in the same fashion as a scalar or vector net. Arrays are accessed by <array_name>[<subscript>] Note: A vector is a single element that is n-bits wide. On the other hand, arrays are multiple elements that are 1-bit or n-bits wide.
24
11/10/2013
Data types
Arrays
integer count[0:7]; // An array of 8 count variables reg bool[31:0]; // Array of 32 one-bit boolean register variables time chk_point[1:100]; // Array of 100 time checkpoint variables reg [4:0] port_id[0:7]; // Array of 8 port_ids; each port_id is 5 bits wide integer matrix[4:0][0:255]; // Two dimensional array of integers reg [63:0] array_4d [15:0][7:0][7:0][255:0]; //Four dimensional array wire [7:0] w_array2 [5:0]; // Declare an array of 8 bit vector wire wire w_array1[7:0][5:0]; // Declare an array of single bit wires count[5] = 0; // Reset 5th element of array of count variables chk_point[100] = 0; // Reset 100th time check point value port_id[3] = 0; // Reset 3rd element (a 5-bit value) of port_id array. matrix[1][0] = 33559; // Set value of element indexed by [1][0] to 33559 array_4d[0][0][0][0][15:0] = 0; //Clear bits 15:0 of the register accessed by //indices [0][0][0][0] port_id = 0; // Illegal syntax - Attempt to write the entire array matrix [1] = 0; // Illegal syntax - Attempt to write [1][0]..[1][255]
25
11/10/2013
Data types
Strings
Strings can be stored in reg Each character in the string takes up 8 bits (1 byte). If the width of the register is greater than the size of the string, Verilog fills bits to the left of the string with zeros If the register width is smaller than the string width, Verilog truncates the leftmost bits of the string
reg [8*18:1] string_value; // Declare a variable that is 18 bytes wide initial string_value = "Hello Verilog World"; // String can be stored // in variable
26
11/10/2013
System tasks
Verilog provides standard system tasks for certain routine operations in the form $<keyword>. Operations such as displaying on the screen, monitoring values of nets, stopping, and finishing are done by system tasks System tasks Usage Description
$display
$monitor $stop $finish
Refer to IEEE Standard Verilog Hardware Description Language specification for more
27
11/10/2013
Compiler Directives
All compiler directives are defined by using the `<keyword> construct.
Directives `define Example 'define S $stop; 'define WORD_SIZE 32 'define WORD_REG reg [31:0] 'include header.v ... ... Description Define text macros in Verilog
`include
Include entire contents of a Verilog source file in another Verilog file during compilation
`ifdef `timescale
Refer to IEEE Standard Verilog Hardware Description Language specification for more
28
11/10/2013
Agenda
Overview of Digital Design with Verilog HDL Basic concepts Hierarchical modeling concepts Modules Gate-Level Modeling Dataflow Modeling Behavioral Modeling Tasks and Functions
29
11/10/2013
Design Methodologies
Top-level block identify
enough to build
11/10/2013
Design Methodologies
Top-level block, the final block in design
build
Design Methodologies
32
11/10/2013
T-flipflop
Design Hierarchy
33
11/10/2013
Agenda
Overview of Digital Design with Verilog HDL Basic concepts Hierarchical modeling concepts Modules Gate-Level Modeling Dataflow Modeling Behavioral Modeling Tasks and Functions
34
11/10/2013
Modules
35
11/10/2013
T-flipflop
Module
Module
Design Hierarchy
36
11/10/2013
Modules
Module description
module module name ( port name, port name,); module_port declaration data type declaration logic description part A part of a chip, or whole the chip module
endmodule
A module definition The file name for RTL source must be module name.v
37
11/10/2013
Modules
module module name ( port name, port name,); module_port declaration Declare whether the ports are input and/or output
input <port_size> port name, port name, ; output <port_size> port name, port name, ; inout <port_size> port name, port name, ; module
module data_conv ( a, b, ); input [3:0] a; input [7:0] b; output [3:0] e, f; output [15:0] g; inout c, d; 4 8 1 1 a b c d
4 4 16
ports
38
11/10/2013
Modules
module module name ( port name, port name,); module_port declaration
Data type declaration Declare characteristics of variables for net data type wire <size> variable name, variable name, ;
wire <size> variable name, variable name, ;
module
wire [3:0] a; wire [7:0] b; wire c, d; wire [3:0] f; wire [7:0] q1, q2, q3, q4; wire sel3, ; .
39
11/10/2013
4 8 1 1
a b c d
q1 SEL q2 sel3
q3
e f g
4 4 16
Modules
module module name ( port name, port name,); module_port declaration Define signals which are output of FF, registers, and other memory elements as register type variable.
Data type declaration for register data type reg <size> variable name, variable name, ;
reg <size> variable name, variable name, ;
module
wire [3:0] e; wire [15:0] g; wire q2; 4 8 1 1
a
b c d
q2
e f g
4 4 16
Note: Output does not have to be declared as register data type Input (inout) must not be declared as register data type
40
11/10/2013
Modules
Note on register and net data type module1
reg
module2
wire
wire wire reg reg wire wire
module2_1 reg
reg
wire
Modules
Question: correct the type of the variables shown below module1
reg
reg reg wire wire wire
module2
reg reg reg
reg
module2_1 reg
wire
wire wire
reg
reg
reg wire
wire
reg wire
Assume gates are not defined by using always nor function statements Suppose this part is programmed by using always statement.
42
11/10/2013
Modules
A sample answer module1
wire reg reg wire reg wire wire
wire reg
wire reg
reg
module2_1
reg
wire reg
reg wire
wire reg
Explain later
reg wire
wire wire
Modules
module module name ( port name, port name,); module_port declaration Data type declaration Logic description part endmodule The main part of logic is written here.
4 8 1 1 a
module
e
f g
4
4 16
b
c d
Logic is coded in this part using various operator including connections to lower level blocks.
44
11/10/2013
Modules
High Internals of each module can be defined at four levels of abstraction, depending on the needs of the design.
The levels Behavioral or algorithmic level Description
- Focus on the desired design algorithm without concern for the Register transfer level (RTL): is acceptable hardware implementation details. to logic synthesis tools - Very similar to C programming
-A
Abstraction
Dataflow level
module is designed by specifying the data flow - Aware of how data flows between hardware registers and how the data is processed in the design The module is implemented in terms of logic gates and interconnections between these gates. - Similar to describing a design in terms of a gate-level logic diagram
-A
Low
Flexibility
Gate level
Switch level
module can be implemented in terms of switches, storage nodes, and the interconnections between them. - Requires knowledge of switch-level implementation details
Agenda
Overview of Digital Design with Verilog HDL Basic concepts Hierarchical modeling concepts Modules Gate-Level Modeling Dataflow Modeling Behavioral Modeling Tasks and Functions
46
11/10/2013
Gate Types
And/Or Gates
One scalar output Multiple scalar inputs The first terminal in the list of gate terminals is an output and the other terminals are inputs Terminal list
wire OUT, IN1, IN2; // basic gate instantiations. and a1(OUT, IN1, IN2); nand na1(OUT, IN1, IN2); or or1(OUT, IN1, IN2); nor nor1(OUT, IN1, IN2); xor x1(OUT, IN1, IN2); xnor nx1(OUT, IN1, IN2); // More than two inputs; 3 input nand gate nand na1_3inp(OUT, IN1, IN2, IN3); // gate instantiation without instance name and (OUT, IN1, IN2); // legal gate instantiation
47
11/10/2013
Gate Types
Buf/Not Gates
One scalar input One or more scalar outputs The last terminal in the port list is connected to the input
// basic gate instantiations. buf b1(OUT1, IN); not n1(OUT1, IN); // More than two outputs buf b1_2out(OUT1, OUT2, IN); // gate instantiation without instance name not (OUT1, IN); // legal gate instantiation
48
11/10/2013
Gate Types
Bufif/notif
Gates with an additional control signal on buf and not gates Propagate only if control signal is asserted. Propagate z if their control signal is deasserted
Gate Types
Array of Instances
wire [7:0] OUT, IN1, IN2; // basic gate instantiations. nand n_gate[7:0](OUT, IN1, IN2);
The instances differ from each other only by the index of the vector to which they are connected
// This is equivalent to the following 8 instantiations nand n_gate0(OUT[0], IN1[0], IN2[0]); nand n_gate1(OUT[1], IN1[1], IN2[1]); nand n_gate2(OUT[2], IN1[2], IN2[2]); nand n_gate3(OUT[3], IN1[3], IN2[3]); nand n_gate4(OUT[4], IN1[4], IN2[4]); nand n_gate5(OUT[5], IN1[5], IN2[5]); nand n_gate6(OUT[6], IN1[6], IN2[6]); nand n_gate7(OUT[7], IN1[7], IN2[7]);
50
11/10/2013
Gate Types
4-to-1 Multiplexer
51
11/10/2013
Gate Types
and (y3, i3, s1, s0); // 4-input or gate instantiated or (out, y0, y1, y2, y3); endmodule
52
11/10/2013
Gate Types
Gate Types
// Define a 4-bit full adder module fulladd4(sum, c_out, a, b, c_in); // I/O port declarations output [3:0] sum; output c_out; input[3:0] a, b; input c_in; // Internal nets wire c1, c2, c3;
// Instantiate four 1-bit full adders. fulladd fa0(sum[0], c1, a[0], b[0], c_in); fulladd fa1(sum[1], c2, a[1], b[1], c1); fulladd fa2(sum[2], c3, a[2], b[2], c2); fulladd fa3(sum[3], c_out, a[3], b[3], c3); endmodule
54
11/10/2013
Gate Delays
Fall delay
Turn-off delay
1, 0, x z
Gate Delays
If only one delay is specified, this value is used for all transitions. If two delays are specified, they refer to the rise and fall delay values. The turnoff delay is the minimum of the two. If all three delays are specified, they refer to rise, fall, and turn-off delay values. If no delays are specified, the default value is zero.
and #(5) a1(out, i1, i2); //Delay of 5 for all transitions and #(4,6) a2(out, i1, i2); // Rise = 4, Fall = 6 bufif0 #(3,4,5) b1 (out, in, control); // Rise = 3, Fall = 4, Turn-off = 5
56
11/10/2013
Gate Delays
Min/Typ/Max Values
For each type of delay three values, min, typ, and max, can be specified.
Min/typ/max values are used to model devices whose delays vary within a [min max] range because of the IC fabrication process variations.
min typ max The minimum delay value that the designer expects the gate to have The typical delay value that the designer expects the gate to have The maximum delay value that the designer expects the gate to have
Min, typ, or max values can be chosen at Verilog run time. Method of choosing a min/typ/max value may vary for different simulators or operating systems
57
11/10/2013
Gate Delays
Min/Typ/Max Values
With Verilog XLTM
// One delay
// if +mindelays, delay= 4
// if +typdelays, delay= 5 // if +maxdelays, delay= 6 and #(4:5:6) a1(out, i1, i2); // Two delays
Agenda
Overview of Digital Design with Verilog HDL Basic concepts Hierarchical modeling concepts Modules Gate-Level Modeling Dataflow Modeling Behavioral Modeling Tasks and Functions
59
11/10/2013
<Bit-wise operator>
& (and),
| (or),
~ (not),
^(eor),
~^(enor)
Operation is applied bit by bit for vector data. 10010101&00110110 00010100 10010101
60
11/10/2013
Use arithmetic operator to get better logic. Synthesis tool can create better circuit than human. <Shift operator> *2 << (left shift), >> (right shift)
*2: logic shift
Example:
assign A = B << C;
If C is 3, A is given the value of B shifted left 3 bits.
61
11/10/2013
=== (identical),
a === b will result in true if a = 01xx00 and b = 01xx00, where a == b will result in x.
11/10/2013
-> *1
Example:
(trigger an event)
*1: cannot be used for logic synthesis. For simulation only If (ctl == 1b1) begin sig_y = sig_w; end else begin sig_y = sig_q; sig_w sig_q
end
63
11/10/2013
Control statements can be used only in structural procedure, initial statement, always statement, task and function.
Use case instead of if as much as possible.
11/10/2013
value of ctl
expression if ( ctl == 1b1 ) sig_y = 2b10; else sig_y = 2b01;
1`b1
1`b0
1`bx
2`b10
2`b01
2`b01
2`b10
2`b01
2`bxx
65
11/10/2013
66
11/10/2013
Continuous Assignment
We can create various logic by connecting gates with wire. These connection are done by using assign statement as below
assign aa_signal = bb_signal; bb_signal aa_signal
assign aa_signal = (bb_signal ^ cc_signal) & dd_signal; bb_signal cc_signal dd_signal assign aa_signal = (cc_ctl)?bb_signal:dd_signal; bb_signal aa_signal
cc_ctl
dd_signal
67
aa_signal
Continuous Assignment
By using this assignment, we can write an RTL code as below
module eor_and example(bb_sig, cc_sig, dd_sig, aa_sig); input bb_sign, cc_sign, dd_sign; output aa_sign; wire bb_sign, cc_sign, dd_sign; wire aa_sign; wire sig_eor;
sig_eor
aa_sig
output
Continuous Assignment
By using this assignment, we can write an RTL code as below
module eor_and example(bb_sig, cc_sig, dd_sig, aa_sig); input bb_sign, cc_sign, dd_sign; Note: Because the assignment is output aa_sign; done always, exchanging the wire bb_sign, cc_sign, dd_sign; written order of the lines if wire aa_sign; continuous assignment has no wire sig_eor;
sig_eor
aa_sig
output
Continuous Assignment
Question: What shall be the result of the following assignment?
(1) wire [3:0] y; assign y[3:0] = -3;
(2)
(3)
(4)
(5) (6) (7)
In your program, always make bit width of left-hand side and right-hand side equal
70
11/10/2013
Continuous Assignment
A sample answer
(1) wire [3:0] y; assign y[3:0] = -3; y = 4b1101
(2)
(3)
(4)
(5) (6) (7)
y = 4b000x
y = 4bxxxx
y = 4b0001
Continuous Assignment
Question: Check if the following statements are correct or not?
(1) wire [7:0] a, b; assign b[7:0] = a[3:0] 4b0010; b[7:0] = 8b1111_1110 if a is 8h00 (2) wire [7:0] a; assign b[7:0] = 4b1110; a[7:0] 8hFE (3) wire [7:0] a, b; assign a[3:0] = b[7:0] 4b0100; a[3:0] = 4hC if b[7:0] is 8h00
In your program, always make bit width of left-hand side and right-hand side equal
72
11/10/2013
Continuous Assignment
A sample answer
(1) wire [7:0] a, b; assign b[7:0] = a[3:0] 4b0010; b[7:0] = 8b1111_1110 if a is 8h00 (2) wire [7:0] a; assign b[7:0] = 4b1110; a[7:0] 8hFE (3) wire [7:0] a, b; assign a[3:0] = b[7:0] 4b0100; a[3:0] = 4hC if b[7:0] is 8h00 Wrong, A[7:0] is 8h0E Correct, sign extended
Correct
Wrong,
b[7:0] is 8b1100_1111
There may be tool dependency. Do not assume the above is true in the future
73
11/10/2013
Continuous Assignment
Question: Write a Verilog RTL code for the gate diagram shown below. (Compile the
a
part.)
w3 w1 y
w4 wire a, b, c, y;
w2 c
assign y =
74
11/10/2013
Continuous Assignment
A sample answer
a w3 w1 b y
w4
w2 c wire a, b, c, y; wire w3, w4; assign w3 = ~(a & c); assign w4 = ((~a) & b) & (b | c); assign y = w3 ^ w4;
wire a, b, c, y; wire w1, w2, w3, w4; assign w1 = (~a) & b; assign w2 = b | c; assign w3 = ~(a & c); assign w4 = w1 & w2; assign y = w3 ^ w4;
75
11/10/2013
Continuous Assignment
However the code in the previous page is very much similar to gate level design. Writing logic using primitive gates only is less productive. To describe much sophisticated logic easily, structured assignment is available in Verilog RTL programming. Always statement, function, initial statement, and task are available as structured assignment. (See later) Assignments applicable in those structured procedure is different from the continuous assignment in the previous page. They are called procedural assignment.
76
11/10/2013
Delays
Delay values control the time between the change in a right-hand-side operand and when the new value is assigned to the left-hand side. Regular Assignment Delay
assign #10 out = in1 & in2;
Any change in values of in1 or in2 will result in a delay of 10 time units before recomputation of the expression in1 & in2, and the result will be assigned to out
A pulse of width less than the specified assignment delay is not propagated to the output (inertial delay)
77
11/10/2013
Delays
Implicit Continuous Assignment Delay
//implicit continuous assignment delay wire #10 out = in1 & in2; wire out; assign #10 out = in1 & in2;
//Net Delays wire # 10 out; assign out = in1 & in2; wire out; assign #10 out = in1 & in2;
78
11/10/2013
Agenda
Overview of Digital Design with Verilog HDL Basic concepts Hierarchical modeling concepts Modules Gate-Level Modeling Dataflow Modeling Behavioral Modeling Tasks and Functions
79
11/10/2013
Procedural assignments
Continuous assignment *1 Wire connection: Assignment is always done.
assign a_sig = b_sig;
Assignment
Execution of the next line is blocked until this assignment is done. Nonblocking procedural assignment
a_sig <= b_sig;
Only applicable in structured procedure: function, always, initial and task *1: Basically, continuous assignment is not applicable in structured procedure. However there is an assignment applicable in structured procedure, it is called structural continuous assignment. 80 11/10/2013
Procedural assignments
Restrictions of continuous / procedural assignment left-hand side must be net data type variable continuous assignment
wire a; assign a = ----;
11/10/2013
Procedural assignments
blocking vs. nonblocking procedural assignment In structured procedure, if there are more than one statement to execute, they must be grouped in one block. begin end and fork join are available. However, use begin end for logics which must be synthesized. The block defined by begin and end pair is called sequential block In a sequential block, statement are executed in serial, in order they are written. begin Statement are executed in the order they are written. end
82
11/10/2013
If no wk is given value outside this block, every time this block is executed because of change of a, their value change as below.
a1 a2 a3 a4 a5 a6 wk1 a1 a2 a3 a4 a5 a6 a1 a2 a3 a4 a5 wk2 x
wk3 x wk4 x y x x a1 a2 a3 a4
x
x
x
x
a1 a2 a3 x a1 a2
This simulation result shows that some elements are expected as shown below
Because execution of (3) is not blocked by (2) nor (1), (3)s right-hand side is evaluated before the execution of (2). And the evaluated value shall be x. Therefor wk3 becomes unknown (x).
wk2
wk3
wk4
In case of nonblocking procedural assignment, there is less order dependency. Because it does not block of execution of the next sentences. Depending on your coding, there may still be some dependency. You have to understand how the assignment works. Nonblocking procedural assignment does not block the execution of the next sentences. If the sequential block on the left is executed because of change of a, the result is same to the previous page.
The order of sentences is completely inverted from the example on the previous page
wk1 a
wk2
wk3
wk4
Question: Think if the logic on the right below works as intended. If not, correct the following program to save data to buf using a pointer ptr. ptr must be updated by one after data_in is stored to buf pointer by ptr.
buffr[0] ptr in_data (2) buffr[1] buffr[2] buffr[3] buffr[4] ptr (3)
If ptr = 2 before this sequential block is executed, then after this sequential block is executed, ptr must be updated to 3 and in_data must be stored to buf[2].
85
11/10/2013
A sample answer
Yes, it works as shown below. However, the sample program in the right is just for explanation. Do not program in this way. It is a confusing expression. begin ptr = prt + 1; buffr[ptr] = in_data;
ptr in_data
end
Yes, it works.
end
These two are equivalent
buffr[0]
(2)
end
Of course, the above will not work
86
11/10/2013
If no wk is given value outside this block, every time this block is executed because of change of a, their value change as below.
a1 a2 a3 a4 a5 wk1 a1 a2 a3 a4 a5 wk2 a1 a2 a3 a4 a5
a6 a6
a6
Because execution of (3) is blocked by (2), (3)s righthand side is evaluated after the execution of (2). (2) is executed after (1). Therefore wk2 in (3) shall be a1 and wk3 becomes a1.
wk2
wk3
wk4
87
11/10/2013
Blocking procedural assignment has order dependency. Check an example on the left if the sequential block is executed because of the change of a.
a1 a2 a3 a4 a5 a6 wk1 a1 a2 a3 a4 a5 a6 a1 a2 a3 a4 a5 wk2 x
wk3 x wk4 x y x x a1 a2 a3 a4
x
x
x
x
a1 a2 a3 x a1 a2
When (1) is executed wk4 is not given a value. When (3) is executed wk2 is not given a value yet, therefore wk3 becomes x
3rd time 2nd time 1st time wk1 a an element to keep the previous value
88
11/10/2013
wk2
wk3
wk4
d e c d e c
b a
b = d | e;
b a
end
If the sequential block on the left is executed because of the change of c, d or e, then the results are different depending on the order of those two statements
latch You must be very careful to write statements which have mutual dependency like these two sentences.
89
11/10/2013
Do not mix!!!
Synthesis tool may report error. a1 a2 a3 a4 a5 wk1 a1 a2 a3 a4 a5 wk2 a1 a2 a3 a4 a5
wk3 x wk4 x y x a1 a2 a3 a4 a1 a2 a3 a4 x a1 a2 a3
a6 a6
a6 a5 a5 a4
Because execution of (2) is blocked by (1), and the evaluation of (3)s right-hand side is not blocked by (2), wk3 becomes unknown (x)
wk2
wk3
wk4
90
11/10/2013
Question: Suppose the following sequential block is executed every time a is given new value. Complete the chart to show how wk are changed in simulation when a changes its value as show in the chart.
reg wk1, wk2, wk3, wk4, y; begin wk1 <= a; wk2 = wk1; wk3 <= wk2; wk4 = wk3; y end <= wk4;
a1 a2 a3 a4 a5
a6
Do not mix!!!
Synthesis tool may report error.
91
11/10/2013
A sample answer.
reg wk1, wk2, wk3, wk4, y; begin wk1 <= a; wk2 = wk1; wk3 <= wk2; wk4 = wk3; y end <= wk4;
Do not mix!!!
Synthesis tool may report error.
92
11/10/2013
Summary blocking vs. nonblocking 1. Use blocking procedural assignment to create combinational logic. nonblocking procedural assignment is not allowed in function. Use nonblocking procedural assignment in always statement for combinational logic. 2. Use nonblocking procedural assignment to create sequential logic.
(1) Control statements In structured procedure, we can use control statements, such as if and case statements. Difference from C language: break is not needed. if and case statement case expression if statement
if (Boolean expression) sentence1; syntax else sentence2;
Structured procedure
case statement
case (Variable1) value1: sentence1; value2: sentence2; case item default: sentence3; endcase
sentence1 is executed if the descri expression is true, if not, ption sentence2 is executed.
If variable1 is equal to value1 then sentence1 is executed. case statement uses === for comparison. Always wirte default part, to detect possible bugs and to avoid create latches. Use case statement as much as 94possible. Why? 11/10/2013
Note
To describe combinational logic by using if statements, else part shall not be dropped.
EDA tool handles case statement same to if statement, therefore an expression like below can work, however, avoid using the following expression. It can be used only when it is assured that case items never take the same value at the same time. case (2b01) indx_sig1: qreg_out <= 8h7F indx_sig2: qreg_out <= 8hA5 This case statement assign 7F to qreg_out, if indx_sig1 = 2`b01, or A5, if indx_sig2 = 2`b01 Check by yourself, what happens if both indx_sig1 and indx_sig2 is equal to 2b01
endcase
95
11/10/2013
case statement is processed as below; first, case is evaluated by using === (identical) if not match, next case is evaluated. if no case item match, then default part is executed. The following code is just to show how case works
begin case ( d ) 1bx : q <= 1bx; 1b0 : q <= 1b1; 1b1 : q <= 1b0;
Case statement use === to check the equality, therefore it can check x. If d is x, q becomes x If d is 0, q becomes 1 Synthesis tool ignores the line 1bx: 1 <= 1bx
96
11/10/2013
casex statement treats x, z and ? as the dont care values. This means that if case item is 3b1x0 as shown below then second bit of case expression is ignored in the comparison with the case item 3b1x0. if sel contains no x;
casex ( sel ) 3b1x0: ---; 3b011: ---; sel[2] === 1 & sel[0] === 0 sel[2] === 0 & sel[1] === 1 & sel[0] === 1
if sel contains x such as sel is 3b1x1; If case expression contains x, case items are compared as below casex ( sel ) dont care
3b110: ---; 3b011: ---; sel[2] === 1 & sel[0] === 0 sel[2] === 0 & sel[0] === 1
This is very dangerous, because if all bits of case expression are x (3bxxx) then first case item matches always.
3b1?0: ---;
3b011: ---;
if sel contains z such as sel is 3bz01; If case expression contains x, case items are compared as below casez ( sel ) dont care
3b1?0: ---; 3b011: ---; sel[0] === 0 sel[1] === 1 & sel[0] === 1
This is also dangerous, however sel has less chance to have z compared to having x. Use casez is not recommended. However if it is necessary to use wild card, use casez instead of casex. In verilog ? is a shorthand for z.
98
11/10/2013
By using casez, we can implement a truth table with many x (dont care) as below.
casez ( a[3:0] )
4b1??? : y = q1;
1
0 0 0
x 1 0 0 0
x x x 0 1
x
x 0 1
q1
q2 q3 q4 q5
4b01?? : y = q2;
4b00?0 : y = q3; 4b0001 : y = q4; 4b0011 : y = q5;
default : y = 4bxxxx;
endcase
However, from the reason explained in the previous page, avoid using casez. Use casez only in a situation that without using casez code may become very large to understand.
99
11/10/2013
First choice
Best style!!
case ( sel ) 3b000, 3b001, 3b100, 3b101 : y <= ---; 3b010 : y <= ---; 3b011 : y <= ---; 3b110, 3b111 : y <= ---; default : y <= xxx; endcase
case ( sel ) 3b000, 3b001, 3b100, 3b101 : y <= ---; 3b010 : y <= ---; 3b011 : y <= ---; 3b110, 3b111 : y <= ---; default : y <= xxx; endcase
Second choice
casez ( sel ) 3b?0? : y <= ---; 3b010 : y <= ---; 3b011 : y <= ---; 3b11? : y <= ---; default : y <= xxx; endcase
Third choice
If ( sel[1] == 1b0 ) y <= ---; else if ( sel[2] == 1b0 ) y <= ---; else if (sel[0] == 1b1) y <= ---; else y <= ---;
100
loop statement
We can use loop statement in verilog RTL programming. There are four loop instructions available. They are forever, repeat, while, and for. Syntax for loop instructions: forever statement; *1 Continuously repeat the statement forever. repeat (expression) statement; *1 Execute the statement a fixed number of times. The number of executions is set by the expression. If the expression evaluates to unknown, high-z, or a zero value, then no statement will be executed. while (expression) statement; *1 Execute the statement until the expression is true. If a while instruction starts with a false value, then no statement will be executed. *1: In many cases these are not synthesizable or there may be heavy tool dependency. Therefore avoid using these statements in a synthesizable code.
101
11/10/2013
You have to be aware that they are different from those in C programming language.
102
11/10/2013
for loop is used to reduce code lines where similar patterns are repeated.
addr_in[7:0] 8 addr_dcd
decoded_addr[255:0] 256 module addr_dcd (addr_in, decoded_addr); parameter ADDRESS = 8; parameter RAMSIZE = 256; input output integer reg [ADDRESS 1 : 0] addr_in; [RAMSIZE - 1 : 0] decoded_addr; i; [RAMSIZE 1 : 0] decoded_addr; for( i=0; i < RAMSIZE ; i=i+1) decoded_addr[ i ] = (addr_in == i); end endmodule
103
11/10/2013
Take an example of logic which create 256-bit one hot signal from 8-bit input data addr_in. For example, if addr_in = 5, decoded_addr = 256b0000----00100000. If addr_in = 255, decoded_addr = 256b1000---00000.
Question: Will the following code work same to the code on the previous page?
addr_in[7:0] module addr_dcd (addr_in, decoded_addr); parameter ADDRESS = 8; parameter RAMSIZE = 256; input output [ADDRESS 1 : 0] addr_in; [RAMSIZE - 1 : 0] decoded_addr; 8 decoded_addr[255:0] 256
addr_dcd
integer
reg
i;
[RAMSIZE 1 : 0] decoded_addr;
Because there is no order dependency in the code on the left. The code on the previous page will work properly.
end endmodule
105
11/10/2013
Note: In case of the program on the previous page, without using for loop, it can be written as below. Sometimes DA tools create smaller logic for the code below compared to the code on the previous page.
module addr_dcd (addr_in, decoded_addr); parameter ADDRESS = 8; parameter RAMSIZE = 256; input output integer reg [ADDRESS 1 : 0] addr_in; [RAMSIZE - 1 : 0] decoded_addr; i; [RAMSIZE 1 : 0] decoded_addr;
Question: Check if the following logic can find the maximum value in lst.
reg [3:0] mx; reg [3:0] lst [0:3]; always @ (lst[0] or lst[1] or lst[2] or lst[3]) begin mx <= 4b0000; //for ( i=0; I <=3; i=i+1) begin // if( lst[i] >= mx) mx <= lst[i]; // end if ( lst[0] >= mx ) mx <= lst[0]; if ( lst[0] >= mx ) mx <= lst[1]; if ( lst[0] >= mx ) mx <= lst[2]; if ( lst[0] >= mx ) mx <= lst[3]; end
107
11/10/2013
A sample answer This logic does not work as intended because the logic assume sequential execution of each lines.
reg [3:0] mx; reg [3:0] lst [0:3]; always @ (lst[0] or lst[1] or lst[2] or lst[3]) begin mx <= 4b0000; //for ( i=0; I <=3; i=i+1) begin // if( lst[i] >= mx) mx <= lst[i]; // end if ( lst[0] >= mx ) mx <= lst[0]; if ( lst[0] >= mx ) mx <= lst[1]; lst[0], lst[1], lst[2], lst[3]
108
11/10/2013
The RTL code shown below may result in the net list on the left.
lst[1] comp
lst[1]
sel
begin mx <= 4b0000; if ( lst[0] >= mx ) mx <= lst[0]; if ( lst[0] >= mx ) mx <= lst[0]; if ( lst[0] >= mx ) mx <= lst[0]; if ( lst[0] >= mx ) mx <= lst[0]; end
lst[2] comp
lst[2]
sel
mx lst[3] comp
109
lst[3]
sel
Question: Rewrite the code below so that it can find the maximum value in lst.
reg [3:0] mx; reg [3:0] lst [0:3]; always @ (lst[0] or lst[1] or lst[2] or lst[3]) begin mx <= 4b0000; if ( lst[0] >= mx ) mx <= lst[0]; if ( lst[0] >= mx ) mx <= lst[1]; if ( lst[0] >= mx ) mx <= lst[2]; if ( lst[0] >= mx ) mx <= lst[3]; end
110
11/10/2013
A sample answer Use blocking procedural assignment instead of nonblocking procedural assignment.
reg [3:0] mx; reg [3:0] lst [0:3]; always @ (lst[0] or lst[1] or lst[2] or lst[3]) begin mx <= 4b0000; //for ( i=0; I <=3; i=i+1) begin // if( lst[i] >= mx) mx = lst[i]; // end if ( lst[0] >= mx ) mx = lst[0]; if ( lst[0] >= mx ) mx = lst[1]; if ( lst[0] >= mx ) mx = lst[2]; if ( lst[0] >= mx ) mx = lst[3]; end
111
11/10/2013
The RTL code shown below may result in the net list on the left.
lst[1] comp
lst[1]
sel
begin mx <= 4b0000; if ( lst[0] >= mx ) mx = lst[0]; if ( lst[0] >= mx ) mx = lst[0]; if ( lst[0] >= mx ) mx = lst[0]; if ( lst[0] >= mx ) mx = lst[0]; end
lst[2] comp
lst[2]
sel
mx lst[3] comp
112
lst[3]
sel
(2) function
Function is one of structural procedures. It provides a means of splitting code into small parts that are frequently used in a model. We can use control statements, such as if, case, for, etc We must use procedural assignment. declaration of function function type_or_range identifier; This must be written inside a module declaration
input_declaration;
. . . statement; . . .
endfunction
register _declaration;
113
11/10/2013
function statement
wire [7:0] d1, d2, e1, e2;
bb_sign dd_sign select_one sel aa_sign wire c1, c2;
. . .
cc_ctl
Function description
select_one[7:0] = dd_sign[7:0];
. .
f2
module
. .
In function
(1) Control statements ( if and case statements ) can be used. (2) Assign must be blocking procedural assignment ( = ). Example; sig_a = mul_dt; sig_a <= mul_dt; assign sig_a = mul_dt; (3) FF / storage elements can not be created. Because nonblocking procedural assignment is not allowed in function, there is no way to create memory element in function. (4) Time-control statements are not allowed. (Can not use # nor @) (5) Net declarations are illegal. Declare all the right-hand side signals as input unless they are internal variables. If not declared, it refers to a signal outside the function directly.
115
11/10/2013
execute timing of a function In RTL simulation, function is executed whenever there is any change of the value of the parameters. When input parameter a, b, or c change their value, function assign sig_y = func_ff ( a, b, c ); func_ff will be executed.
When input parameter e, f, or g change their value, function func_ff will be executed.
. . . . .
end endfunction
The sequential block is executed whenever input variables changes their values.
116
11/10/2013
These internal variables must be declared as register data type, not wire data type.
117
11/10/2013
Function can not handle a memory element. However, if there is a path in which a variable is not given its value, RTL simulator will assign previous value for the variable in such path. This causes latching.
You have to give values to all variables in every paths.
function [1:0] abcde; input a, b; if ( a == 1b1) begin abcde[1] = 1b0; abcde[0] = b; end else If ( b == 1b0) begin abcde[1] = b; abcde[0] = ~a; end else begin abcde[1] = ~b; end endfunction
In the sample code on the left, when a=0 and b=1, abcde[0] is not given any value. A synthesis tool will create logic by treating abcde[0] as dont care in this path. Therefor, the result of gate level simulation and RTL simulation will be different.
For the same reason above, in the following example, default path is indispensable. function [3:0] dec2to4; input [1:0] d_code_in; begin case (d_code_in) 2b00: dec2to4 = 4h1; 2b01: dec2to4 = 4h2; default: dec2to4 = 4bxxxx; endcase end endfunction
118
11/10/2013
Question: Check the following code has any problem or not for creating combinational logic by function statement.
function [1:0] abcde; input a, b; begin if ( 1 == 1b1) begin abcde[1] = 1b0; abcde[0] = b; end else if ( b == 1b0 ) begin abcde[1] = b; abcde[0] = ~a; end end endfunction
119
11/10/2013
A sample answer
function [1:0] abcde; input a, b; begin if ( 1 == 1b1) begin abcde[1] = 1b0; abcde[0] = b; end else if ( b == 1b0 ) begin abcde[1] = b; abcde[0] = ~a; end end endfunction
120
11/10/2013
By adding @ ( ) to always statement, this always statement means wait for change of signals listed in the sensitivity list and when the change takes place, sequential block ( from begin to end ) is executed.
121
11/10/2013
execute timing of always statement always @ (..) begin sensitive list description always @ ( posedge clk ) end always @ ( negedge rst_n ) always @ ( a or b ) timing when signal clk rises when signal rst_n falls when signal a or b change edge signal Always statement is executed at time 0, and with @, waits for the event designated by a sensitivity list. Thus, the sequential block, begin-end part, is executed whenever the event happens.
level signal
Do not write edge signal (posedge / negedge) and level signal together.
@ and sensitivity list help us to control the execution timing of a structured procedure. Example:
reg wk1, wk2, wk3, wk4, y; begin wk1 <= a; wk2 <= wk1; wk3 <= wk2; wk4 <= wk3; y <= wk4; end
If no wk is given value outside this block, every time this block is executed because of the change of a, their value change as below. This can be implemented as below
always @ ( a ) begin wk1 <= a; wk2 <= wk1; wk3 <= wk2; wk4 <= wk3; y <= wk4; end
This code means that when a changes its value, sequential block, begin to end, shall be executed.
It is very critical what to write in a sensitivity list. Depending what you write in it, the resulting logic will different.
123
11/10/2013
reg wk1, wk2, wk3, wk4, y; always @ ( a ) begin wk1 <= a; wk2 <= wk1; wk3 <= wk2; wk4 <= wk3; y <= wk4; end
A simulation result of the code on the left will be same to logic shown below, as explained before. wk1 a wk2 wk3 wk4 y
Simulation result shows latches, however some synthesize tool may not create a latch.
What happen if we change this condition? always @ ( a ) Execute when a changes always @ ( a or wk1 or wk2 or wk3 or wk4 ) Execute when a or wk1 or wk2 or wk3 or wk4 change
124
11/10/2013
(1) (2)
reg wk1, wk2, wk3, wk4, y; always @ ( a or wk1 or wk2 or wk3 or wk4 ) begin wk1 <= a; wk2 <= wk1; wk3 <= wk2; wk4 <= wk3; y <= wk4; wk1 end a
A simulation result of the code on the left will be same to logic shown below. A synthesize tool will create the same logic as below.
wk2
wk3
wk4
Note that this part has not changed at all from the previous page.
When wk1 changes its value by (1), sequential block is invoked again because wk1 is written in the sensitivity list. When wk2 changes its value by (2), sequential block is invoked again because wk2 is written in the sensitivity list. And so on. As a result, y is always equal to a.
125
11/10/2013
always @ ( a or b or c or d or wk1 or wk2 ) begin wk1 <= a | b; wk2 <= c & d; a y <= wk1 ^ wk2; b end
equivalent
always @ ( a or b or c or d ) begin y <= (a | b) ^ (c & d); end
c d
Synthesis tool may create above gate even if we missed wk1 and wk2 in a sensitivity list, however do not omit them. If omitted, the result of RTL simulation may be different from the result of gate level simulation.
126
11/10/2013
To generate combinational logic as shown on the right, Style 1 is recommended compared to Style 2 because of the simulation efficiency.
a b c d
Style 1
reg a, b, c, d, y; reg wk1, wk2; always @ ( a or b or c or d ) begin wk1 = a | b; wk2 = c & d; y = wk1 ^ wk2; end reg a, b, c, d, y; reg wk1, wk2;
multiple passes
always @ ( a or b or c or d or wk1 or wk2 ) begin wk1 <= a | b; wk2 <= c & d; y <= wk1 ^ wk2; end
Always statement is executed whenever wk1 or wk2 change their values, causing slow simulation time.
127
11/10/2013
always statement and combinational logic As is shown in the previous pages, always statement can be used to define combinational logic To create combinational logic by using always statement, we have to: *1 (1) Declare all the signals in a sensitivity list used in the right hand side of the statements in always statement, and (2) Give values to all the signals appearing on the left hand side of the statements in any case, and then such always statement can generate combinational logic. Why? *1 If missing any signal in the list, simulation result may be different from the actual logic created.
128
11/10/2013
always statement and combinational logic To avoid troubles caused by poor sensitivity list, we can use * in a sensitivity list. By using *, the rule for always statements for combinational logic becomes a little bit simple as follows. To create combinational logic by using always statement, we have to: *1 (1) Use always statement always @ * begin end
(2) Give values to all the signals appearing on the left hand side of the statements in any case,
and then such always statement can generate combinational logic.
* is supported in Verilog 2001, check tools default setting supports Verilog 2001 or not before using * notation.
129
11/10/2013
a b
c d
wk1
y wk2
Acceptable style
always @ ( a or b or c or d ) begin wk1 = a | b; wk2 = c & d; y = wk1 ^ wk2; end
end
11/10/2013
Question: Draw a gate diagram for the logic created by the following RTL code.
some_logic d g q
module some_logic ( g, d, q ); input g, d; output q; wire g; wire d; reg q; always @ * begin if( g == 1b1) q = d; else q = ~d; end endmodule
132
11/10/2013
A sample answer
some_logic d g q
module some_logic ( g, d, q ); input g, d; output q; wire g; wire d; reg q; always @ * begin if( g == 1b1) q = d; else q = ~d; end endmodule
D G
133
11/10/2013
Important!!
Failing to give values to all variables in every path causes many trouble again and again. You must be careful in using always statement to create combinational logic.
134
11/10/2013
The following is a code intended to create combinational logic. Correct the code so that it will generate intended logic.
wire a, b, c; wire d; req q1, y; always @ ( a or b or c ) begin q1 = a ^ b; if( d == c) begin y = b | q1; end else begin q = ~d; end end
135
11/10/2013
A sample answer
wire a, b, c; wire d; req q1, y; always @ ( a or b or c ) begin q1 = a ^ b; if( d == c) begin y = b | q1; end else begin q = ~d; end end
136
11/10/2013
A sample code below will generate latch against the intention of a designer, because q2 is not given a value when a is not equal to b.
req q1, q2;
always @ ( a or b or c or d ) begin if( a == b) begin q1 = c; (1) q2 = d; end else begin q1 = d; (2) end end
137
11/10/2013
always @ * begin if( a == b) begin q1 = c; q2 = d; Define q2 in else path end same as true case else begin q1 = d; q2 = d; end end always @ * begin if( a == b) begin q1 = c; q2 = d; end Give x (unknown) value else begin q1 = d; tp q2 in else part q2 = 1bx; end end 11/10/2013
The best way to avoid latch in general cases is to give value to variables before any conditional branch takes place.
always @ * begin sig_y = ------; case ( ----) begin -----; begin sig_y = -----; end -----; begin sig_y = -----; end endcase end
By giving value to sig_y at first, we can assign value to sig_y only in paths where it has to be assigned different values.
139
11/10/2013
When using case statement, same care must be taken to prevent creating latches. always @ * begin case ( state ) yyy1: begin ww = ---; end yyy2: begin ww = -----------; end yyy3: begin ww = ------; end endcase end
If these case items listed does not cover all the possible cases, synthesis tool will create latches to take care of the cases that case expression does not match with any one of case items.
Question: The following is a part of a program intended to create combinational logic. Correct the code so that it will create combinational logic.
always @ (posedge clk or negedge rst_n) begin if(rst_n == 1b0) begin state <= INTL; a <= 12h000; end else begin
always @ (state or flick) begin case (state) INTL: begin if ( ! flick) next_state <= INTL; else begin next_a[0] <= 1b1; next_state <= UP_HIGH; end end UP_HIGH: begin if ( !a[11] ) begin next_a <= a << 1b1; next_state <= UP_HIGH; end else begin next_a[11] <= 1b0; next_a[10] <= 1b1; next_state = DWN_HIGH end end
141
11/10/2013
A sample answer
or a
always @ (state or flick ) begin case (state) INTL: begin if ( ! flick) next_state <= INTL; else begin next_a[0] <= 1b1; next_state <= UP_HIGH; end end UP_HIGH: begin if ( !a[11] ) begin next_a <= a << 1b1; next_state <= UP_HIGH; end else begin next_a[11] <= 1b0; next_a[10] <= 1b1; next_state = DWN_HIGH end end
142
next_a <= { 1b0, 1b1, a[9:0] }; Note: Using blocking procedural assignment = is recommended to create combinational logic
11/10/2013
Question: The following is a part of a program intended to create combinational logic. Correct the code so that it will create combinational logic.
always @ (posedge clk or negedge rst_n) begin if( rst_n == 1b0)
always @ ( f_state or a_lamp or flick ) begin case ( f_state ) 3b000: begin if ( flick == 1b1 ) next_lamp[7:0] <= 8b00000001; end 3b001: begin if ( a_lamp[0] == 1b0 ) next_lamp[3:0] <= {1b0, a_lamp[3:1]}; else begin if ( flick == 1b1 ) next_lamp [1:0] <= 2b10; else next_lamp [0] <= 1b0; end end
143
11/10/2013
A sample answer
always @ ( f_state or a_lamp or flick ) begin case ( f_state ) 3b000: begin
Question: In following code, if the other part of the logic work correctly, it is guaranteed that case expression never becomes 2b11. If so, the following code is OK or not?
always @ ( a ) begin
case ( a[1:0] )
2b00: begin b[1:0] = 2b10; end 2b01: begin b[1:0] = 2b00; end 2b10: begin b[1:0] = 201;
Case items cover only three cases, 00, 01, and 10, out of four possible cases. But it is guaranteed that 11 case will never happen.
end
endcase end
145
11/10/2013
A sample answer No, this code is not OK because synthesis tool will create a latch to keep value of b for such cases that case expression becomes 2b11. We have to use default to prevent creating latch. Synthesis tool can not know that a[1:0] never becomes 2b11.
always @ ( a ) begin case ( a[1:0] ) 2b00: begin b[1:0] = 2b10; end 2b01: begin b[1:0] = 2b00; end 2b10: begin b[1:0] = 201; end endcase end
146
11/10/2013
A sample answer (continued) We can add case item 2b11 to prevent creating latch. Because 11 case never happens, we may assign arbitrary value to b for 11 case.
always @ ( a ) begin case ( a[1:0] ) 2b00: begin b[1:0] = 2b10; end 2b01: begin b[1:0] = 2b00; end 2b10: begin b[1:0] = 201; end
2b11: begin b[1:0] = 2b01; end default: begin b[1:0] = 2bxx; end
147
endcase end
By adding 11 case, latch will not be created. But to checkout error case such as case expression becomes 2b1x, write default part
11/10/2013
148
11/10/2013
A sample answer
always @ ( a ) begin case ( a[1:0] ) 2b00: begin b[1:0] = 2b10; end 2b01: begin b[1:0] = 2b00; end 2b10: begin b[1:0] = 201; end 2b11: begin end default: begin b[1:0] = 2bxx; end endcase end
Yes, this code will create a latch because no value is given to b in 11 case
149
11/10/2013
150
What to use
function module
Comment
Function is best fitted for this case Functioncan not be called from other modules 11/10/2013
module
c1 c1
module c2
c1
c1
c2
c4 *1
153
11/10/2013
Used for generating clock signals and other signals Used to give initial value to the signals and to create signals in time sequence
154
11/10/2013
#HALF_CYCLE;
end
A sample code on the left generates a clock signal having 500*2 time units cycle time.
155
11/10/2013
# is used to define a delay time How to use of # delay All the signals propagate on d_bus are delayed by delay time units After delay time units, sig_origin is evaluated and assigned to sig_in First, sig_origin is evaluated and then after delay time units, it is assigned to sig_in
The next sentence is executed right after the first statement. Therefore, if there is no delay nor wait in the second sentence, the first and the second sentences ( and so on ) are executed at the same time. #20;
Control statements end can be written here to make branch or loop of the procedure When the execution reached the bottom, control is passed to the first sentence
Sig_a = 1b0;
Sig_b = 1b1; sig_c = 4b0101; #100 sig_d = 1b0;
All of the three signals are given the values at the same time.
Note that depending on assignment type (blocking / nonblocking) the behavior is different.
157
11/10/2013
sig_b = 1b1;
end
158
11/10/2013
A sample answer
This may hang up a simulator by infinite loop. Remember that always statement must have at least one procedural timing control
159
11/10/2013
The first sentence is executes at time zero. The next statement executed right after the first statement. Therefore, if there is no delay nor wait in the second sentence, the first and the second ( and so on ) is executed at the same time.
end
Control statement can be written here to make branch or loop of the procedure.
for (i = 0 ; i < 100; i = i + 1 ) begin #20 ss_in = s_data[i]; end
160
11/10/2013
Each sentences between begin and end are executed sequentially. $finish is a system task is to stop simulation.
initial begin rst_n = 1b0; s_rdy = 1b0;
sig_input = 1b0;
#100 #40 #5 rst_n = 1b1; s_in = 4h9; s_rdy = 1b1;
rst_n
s_rdy
s_in 9
100
40
$finish; end
161
11/10/2013
t=0
t = 10
t = 20
Using nonblocking assignment will result in the above waveform because all right hand sides are evaluated before executing each assignment.
end
Question: Are the two program given below same or not? If not, what is the difference?
a <= 1; a <= #20 1; a <= #10 0;
162
Several signal can be given by one initial sentence, however, it is better to use one initial statement for one signal.
initial begin //signal sig_aa
end
163
11/10/2013
If you want several statements executed in parallel in initial sentence, use fork join block
initial begin initial fork # 20 sig_in = 1b1; # 5 s_out = 1b0; # 15 aa_in = 8hFF;
join
164
11/10/2013
parameter_declaration; input_declaration;
Task arguments
Register data types Memory references Concatenations of register or memory references Bit-selects and part-selects of reg, integer and time registers.
endtask
In task
(1) Control statements ( if and case statements) can be used (2) Assign must be procedural assignment ( = or <= ). Example: sig_a = mul_dt;
With input arguments, values are given to the inputs when the task is enabled. If no argument given, it refers to external signals directly. Therefore, values are passed to the task when the signals are given values. Without input argument . With input argument bus_tsk;
. sig_a = b; sig_a = c;
. . bus_tsk ( sig_a ); . .
task bus_task; input in1; . a = in1; . endtask
.
task bus_task; . a = in1;
.
endtask
167
11/10/2013
With output arguments, outputs are given to values when the task is completed. Only the last assignment to an output or an inout argument is passed to the corresponding task enabling arguments. If no output argument given, it refers to external signals (global variables) directly. And the variables are given values when they are assigned values. In such case, all changes of these variables are effective immediately. With output argument Without output argument .
. bus_tsk ( sig_a ); . . task bus_task; output out1; . out1 = a; . out1 = b; . bus_tsk; .
b = sig_a;
. task bus_task; . sig_a = a; . endtask
168
endtask
Effective immediately
11/10/2013
Tasks can enable other tasks and functions. A task may be enabled several times in a module. If one task is enabled concurrently, then all registers and events declared in that task should be static, i.e., one variable for all instances. Care must be taken in case that two or more instances are enabled concurrently.
169
11/10/2013
Example of a task:
task cpu_bus_wrteg; input [3:0] addr; input [15:0] data; begin @ (posedge clk) ad <= #A_DLY addr; din <= #D_DLY data; @ (posedge clk) wr_n <= #W_DLY 1b0; din data ad D_DLY A_DLY addr
@ (posedge clk)
wr_n <= #W_DLY 1b1; end endtask W_DLY W_DLY
170
11/10/2013
always @ (posedge clk or complete_calc) begin if(complete_calc == 1b1) #delay_1 -> d_ready; end
initial begin . #delay ; .. @ d_ready req_d = 1b1; #..... . end
171
When complete_calc becomes on, then after delay_1 time units, event d_ready is set. And this event d_ready activates @ statement, which sets req_d on.
11/10/2013
Wait until event occurs, and when it occurs, assign 1 to signal_up. Wait delay time units Again, wait for event occurs, and when it occurs, assign 0 to signal_up.
Question: If an event is issued before an wait for the event is executed, what happens to the wait?
Do not write a sophisticated or tricky program using wait and other control statements. Always simple is the best
172
11/10/2013
Race condition The term, race condition, originates with the idea of two signals racing each other to influence the output first. Verilog RTL programming may cause race condition between two or more statements as shown below. t=0
reg [7:0] a, b, c;
wait executed first Wait for event Change of a or b event occurred first
a b c a b c
1 2 3 1 2 x
event
a and b change from x to 1 and 2 respectively.
173
Because there is no standard rule for execution sequence of statements, a simulation result may have tool dependency. Some tools execute from top to bottom, while others from bottom to top. This means that there is order dependency in what sequence those statements are coded. The following two programs may have different simulation results.
reg [7:0] a, b, c; always @ (a or b) begin c = a + b; end initial begin a = 1; b = 2; end
174
11/10/2013
One way to avoid race condition between always and initial statements, using #0, delay zero, may be recommended.
reg [7:0] a, b, c;
always @ (a or b) begin c = a + b; end initial #0 begin a = 1; b = 2; end
175
11/10/2013
Question: For the verilog RTL code shown below, draw the expected result on the time chart below.
reg clk; reg [7:0] a, b, c; always @ (posedge clk) begin c = a + b; end t=0 1 5 10 15 20 25 30
clk
a b
0
1 2
1
3 1
176
11/10/2013
A sample answer. There exists a race condition between the two always statements, the result may be different depending on tools. There are two possible results as shown below.
reg clk; reg [7:0] a, b, c;
always @ (a or b) begin c = a + b; end initial begin a = 1; b = 2; #15 a = 3; b = 1; end always begin clk = 1; #5 clk = 0; #5; end t=0 clk a b c
5
0 1 2 3 x
10
1
15
0
20
1 3 1
25
0
30
1
4 3 4
11/10/2013
Question: By using #0, avoid race condition as shown below. Which one of the codes will work without race condition? Code 1
reg clk; reg [7:0] a, b, c; always #0 @ (a or b) begin c = a + b; end initial begin a = 1; b = 2; #15 a = 3; b = 1; end
Code 2
reg clk; reg [7:0] a, b, c; always @ (a or b) begin c = a + b; end initial #0 begin a = 1; b = 2; #15 a = 3; b = 1; end
Code 3
reg clk; reg [7:0] a, b, c; always @ (a or b) begin c = a + b; end initial begin a = 1; b = 2; #15 a = 3; b = 1; end
A sample answer.
Code 1 and Code 3 may not cause racing. With code 2, wait is executed after the first clock rise. With code 3, clock rises after wait for clock rise is executed. Code 2 can not solve the racing between two always statements. From this viewpoint if eliminating x appearing in the result, code 3 may be better. Code 1 Code 2 Code 3
reg clk; reg [7:0] a, b, c; always #0 @ (a or b) begin c = a + b; end initial begin a = 1; b = 2; #15 a = 3; b = 1; end always begin clk = 1; #5 clk = 0; #5; end reg clk; reg [7:0] a, b, c; always @ (a or b) begin c = a + b; end initial #0 begin a = 1; b = 2; #15 a = 3; b = 1; end always begin clk = 1; #5 clk = 0; #5; end reg clk; reg [7:0] a, b, c; always @ (a or b) begin c = a + b; end initial begin a = 1; b = 2; #15 a = 3; b = 1; end always #0 begin clk = 1; #5 clk = 0; #5; end
11/10/2013
179
The result may be different because of race condition between clock and ctl_in.
0 5 10 15 20 25 30 35 40 t
initial begin clt_in = 0; #8 clt_in = 1; #10 clt_in = 0; #10 clt_in = 1; #10 clt_in = 0; end
Using delay for FF is recommended to avoid race condition. Setting delay is applicable to avoid race condition for FF.
clk en_clk
gatedclk
181
11/10/2013
In general, we must not use # in RTL code which will be synthesized, an example in the previous page is the only exception for this rule. We can use # for always statement for FF to avoid race condition. Do not use # for other purpose.
RTL code to create gated clock can be written as below;
always @ ( clk or en_clk ) begin gatedclk <= clk & en_clk; end
Using nonblocking procedural assignment may be better to reduce the possibility of racing. en_clk must be controlled not ot cause hazard.
Note: The above style does not guarantee that there shall be no racing
182
11/10/2013
$finish
This ends simulation. $strobe (format, signal_name1, signal_name2, ) This displays signal signal_namexx a terminal screen
183
11/10/2013
Note: signals in lower hierarchical module can be specified by instance name. instance name. signal name. Example: SP_converter_01.bit_count.
184
11/10/2013
Corner cases
185
11/10/2013
To do test, you must have the state transition matrix of your logic. You have to apply data which causes all the possible transition of the state.
state INTL input in1 in2 in3 . no-op ST1 ST2 . . .
ST1
ST2 ST3
ST2
ST3
186
11/10/2013
Example
For 8-bit numerical input data, 8h25, 8h74, 8h09, etc. may be typical input 8h00, 8hFF may be corner case input
For 1-bit control input data which is supposed to be 1 several times for certain period of time, Input sequence: 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, may be typical input, 1, 1, 1, 1, 1, 1, 1, 1, may be corner case input.
187
11/10/2013
Suppose testing logic which calculate average of four 4-bit positive integers. 4-bit output average must be rounded.
If we prepare the following data for testing, is it effective for finding bugs?
a1 a2 a3 a4
divide by 4
rounding
average
There are several ways to implement the logic. A diagram shown on the left may be one possible implementation
+ + +
rounding
error in handling carry reslt_num carry is neglected fraudulent carry is created 11_1101
error in round operation use another but than bit 1 possible of reslt_sum bugs
reslt_num 11_1101
00_0010
possible bugs
01_1110
00_0010
a1, a2, a3 and a4 shall be determined so that those reslt_sum are to be created.
189
11/10/2013
Question: For the logic below, we got output average 3, for the input a1=4, a2=2, a3=1, and a4=1. The result is looks OK. However what kind of bugs may exist in the logic. Imagine!!!
a1
a2 a3 a4
+ + +
rounding
190
11/10/2013
A sample answer.
a1=4 a2=2 a3=3 a4=3
reslt_sum
+ +
divide by 4 2
rounding
average
a1=4
a2=2 a3=3 a4=3
reslt_sum
+ +
6
divide by 4 2
rounding
average
191
11/10/2013
reslt_sum
+ +
6
divide by 4 2
rounding
average
Use your imaginative power, there is no limitation of absurdity of bugs. And they always try to go beyond your imaginative power
192
11/10/2013
Question: To test the logic below, all 1 data sequence, such as 8hff, 8hff, 8hff, and same fir the rest of data, as shown below is used. What do you think? Is this data sequence suitable for test data.
SW1 in_data
buffer_1
SW2 out_data
buffer_2 apply input data sequence; 8hff, 8hff, 8hff, 8hff, 8hff, 8hff, 8hff
193
11/10/2013
A sample answer SW1 in_data buffer_2 apply input data sequence; 8hff, 8hff, 8hff, 8hff, 8hff, 8hff, 8hff This data sequence has no sensitivity for detecting bugs such as SW2 is not controlled properly. At least apply sequence such as below: 8h01, 8h02, 8h03, 8h04, ,,,,,,,, , , , 8h3e , 8h3f , 8h40 , 8h41, ,,,, buffer_1 SW2 out_data
194
11/10/2013
Many kind of bugs escape through RTL simulation test. This means that we can not be sage from bugs even if simulation test looks OK. Therefore the following method is the most terrible way to fix bigs. Never do this way.
Whats wrong??
no
196
11/10/2013
Check if code and state transition matrix is identical. If not, correct code
Check state transition matrix and the result. Code was wrong?
197
11/10/2013
Software program: A software program code is principally executed one line by one line from top of the program to the bottom. If there is no explicit loop, the code is executed only once.
Hardware program: A hardware program code does not imply the execution sequence. It is intended to show how signals are connected through gates to one another The execution sequence is determined by the sequence how signals are propagating, which is determined by the signals connection defined by the RTL code. An RTL logic simulator analyzes the code and finds the code line related to the signal changed and calculate the resulting signal value, and again executes the code lines related to the newly changed signals. This means that RTL code is actually a data to be input to a simulator. RTL code is also an input data for a synthesize programs.
198
11/10/2013
Hardware program A RTL logic simulator which runs on a CPU An RTL simulator looks for the code line defining the value of signals which must be executed to determine updated values of the signals when any signals change their values. a <= 1b1; (1) . assign b = a&c; (2) . a <= 1b0; (3) .... When a is given the value by (1), code line (2) is executed to get bs value. And when (3) is executed and as value changes from 1 to 0, code line (2) is executed again to get new bs value
199
11/10/2013
How is it Instructions are taken into executed? a CPU and are executed one by one from the top line to the bottom line. example a = 100; b = fnc_calc ( a ); (1) . a = 20; (2) b = fnc_calc ( a ); (3) (1) Is executed only once. Therefore to get the new value of b for the as new value 20 given by (2), code line (3) is needed.
Hardware program
assign a = b & c; a b c assign a = a | d; a d This is OK Not allowed depending on tools assign a = b & c; c This is OK d assign a = d | f; f Not allowed depending on tools
f if ( c == 1b1 ) This is OK c a = f; else g a = g; This is OK b a
??
example
b not defined. c = b + 30; (1) b = 10; This is NG, because b is undefined at (1)
b is not given the value assign c = b & 4b1010; (1) b <= 4b1100; (2) This is OK, because (1) will be executed again when b is given its value by (2).
200
11/10/2013
(2)
When simulation starts, (1)s are executed. always @ ( a or ) begin Then assign w = f & g is executed because f and g are written on the right (11) q <= b; hand side of the statements. And module (10) subm is executed (2) (3), and then (4), (5) and then (6). end (6) invokes function call (7) and function assign a = func ( h ); func is executed (8), this will give the value (9) to a (9). The change of the value a will (7) function func; activate always statement because a is in the sensitivity list. Therefore (11) will be input b; (8) executed. This a simulator executes code func = xxx; lines tracing the change of the signals, not endfunction following the code line sequence written.
201
11/10/2013
Therefore you do not have to call (???) a module as shown on the left to give the new value to signals every time you change some signals.
case ( ) `state_a: begin a <= 4h0100; modl_sub modl_sub_01 ( .a ( a ) ,,,,,); end `state_b: begin a <= 4h0011; modl_sub modl_sub_02 ( .a ( a ) ,,,,,); end `state_c: begin a <= 4h1100; modl_sub modl_sub_03 ( .a ( a ) ,,,,,); end This code is just for explanation. A simulator may output error message for the above code.
202
.. modl_sub modl_sub_01 (.a ( a ),); .. case( ) `state_a: begin a <= 4h0100; end `state_b: begin a <= 4h0011; end `state_c: begin a <= 4h1100; end .. modl_sub will be invoked every time a is given its value.
11/10/2013
initial begin . a <= 4h0100; modl_sub modl_sub_01 ( .a ( a ),.); modl_sub modl_sub_01 ( .a ( a ) ,,,,,); . #50 a <= 4h0011; initial begin modl_sub modl_sub_02 ( .a ( a ) ,,,,,); a <= 4h0100; #30 a <= 4h1100; #50 a <= 4h0011; modl_sub modl_sub_03 ( .a ( a ) ,,,,,); #30 a <= 4h1100; .. .. end end This code is just for explanation. modl_sub will be invoked every A simulator may output error time a is given its value. message for the above code. c.f. initial begin a <= 4h0100; $strobe( ,,,, , a, b,,,,); #50 a <= 4h0011; Note that calling a task is a $strobe( ,,,, , a, b,,,,); different matter!!! #30 a <= 4h1100; $strobe( ,,,, , a, b,,,,); .. 203 11/10/2013 end
Note that all statements within sequential blocks, starting with begin and end with end, are execute in the order in which they are given.
begin .. .. .. end
begin (1) .. a = b & c; .. b = e | f; .. a will not be given a new value when b is given a new value by (2) (1)
(2)
end
(2)
end
204
11/10/2013