Verilog Full
Verilog Full
4. Operators ---------------------------------------------------------------------------------------------------------------------------
Arithmetic Operators, Relational Operators, Bit-wise Operators, Logical Operators, Reduction Operators,
Shift Operators, Concatenation Operator, Conditional Operator, Operator Precedence
5. Operands ----------------------------------------------------------------------------------------------------------------------------
Literals, Wires, Regs, and Parameters, Bit-Selects “x[3]” and Part-Selects “x[5:3]”, Function Calls
8. Timing Controls-----------------------------------------------------------------------------------------------------------------------
Delay Control, Event Control, @, Wait Statement, Intra-Assignment Delay
• if and case statements are only allowed in procedural code. As a result, the synthesizers have been
constructed which can recognize certain styles of procedural code as actually combinational.
(i) Switch level (the switches are MOS transistors inside gates).
(ii) Gate level (interconnected AND, NOR etc.).
(iii) Register transfer level/Data Flow Level (RTL uses registers connected by Boolean equations).
(iv) Algorithmic level/Behavioral Level (much like c code with if, case and loop statements).
Example 1.3:
module inverter (IN, OUT);
input IN;
output OUT;
supply0 VSS;
supply1 VDD;
Example 1.4: A
Y1
module myDesign(A, B, Y); B
input A;
input B; A
output Y; Y2
and A1(Y1, A,B); B
nand NA1(Y2, A, B);
or O1(Y3, A,B); A
endmodule Y3
B
A 0
Example 1.5:
module myDesign(A, B, SEL, mux_out); mux_out
input A, B, SEL;
output mux_out;
assign mux_out = (SEL` & A) + (SEL & B); B 1
endmodule
SEL
Design Behavior
Example 1.6:
module myDesign(A, B, SEL, mux_out); Verilog Modeling
input A, B, SEL;
output mux_out;
reg mux_out;
always @(A, B, SEL)
if (SEL = 1) mux_out = B;
begin
else mux_out = A;
if(SEL)
mux_out = B;
else
mux_out = A;
end
Example 2.1 :
module sample (a, b, c, d);
input a; // space in the start is ignored
reg [8*6 :1] string = “Earth ” ; // would not be ignored
wire temp;
assign = (a & b &c) | (a & b &c) | (a & b &c) | (a & b &c) | (a & b &c) | (a
& b &c) ; //Multiple line statement
- Enclose comments between the characters /* and */ : This method allows you to continue
comments on more than one line
Example 2.2:
assign c = a & b; //This is a simple comment
2.3. Numbers:
- Number values can be specified in binary, octal, decimal or hexadecimal
- Number storage is defined as a number of bits
Example 2.3:
2.4. Identifiers :
- User defined words for variables, function names, module names, block names and instance names
- Begins with a letter or underscore
- Never begins with a number and $
- Identifiers are case-sensitive in Verilog
Example 2.4:
2.5. Operators:
- Operators are one, two or sometimes three characters
- Used to performs operations on variables
Example 2.5:
Example 2.6:
assign, always, case, while, wire, reg, and, or, module, begin, input, output, inout, posedge, negedge
3.2. Wire:
- Represents a physical wire in a circuit and is used to connect gates or modules.
- A value of a wire can be read but not assigned to, in a procedural block or in a function
- A wire does not store its value
- Must be driven by a continuous assignment statement
Example 3.1:
Syntax:
wire a; //simple 1 wire
wire b;
wire wire_variable_scaler;
wire c;
wire [MSB : LSB] wire_variable_vector;
wire [7:0] data; // A cable of 8 wires
assign c = a & b;
3.3. Reg:
- Declare type reg for all data objects on the left hand side of expressions in procedural
blocks (initial and always) and functions.
- Reg data type must be used for latches, flip-flops and memories
3.5. Integer:
- Integers are general purpose variables.
- They are mainly used for loop indices, parameters, and constants
- Implicitly they are type of reg but they store data as signed numbers however
explicitly declared reg types store data as unsigned
- Default size is 32 bits
- If they hold constants, during synthesis, synthesizer adjusts them to the minimum
width needed at compilation
3.7. Time:
- A 64-bits quantity that can be used in conjunction with the $time system task to hold
simulation time
- Time is not used for synthesis (Not Synthesizable) and hence only used for simulation
3.8. Parameter:
- Parameters allows constants like word length to be defined symbolically in one place.
This makes it easy to change the word length later, by changing only the parameter
Operators:
+ (addition) Example 4.1:
- (subtraction)
* (multiplication) c = a + b;
/ (division) d = a – b;
% (modulus) count = (count + 1) % 16 ;
<< (shift left) assign c = a << 2; /* c = a shifted left 2 bits; vacant positions are
>> (shift right) filled with 0’s */
5.1: Literals:
- Literals are constant-valued operands that can be used in Verilog expressions.
- The two common Verilog literals are:
1) String: A string literal is a one-dimensional array of characters enclosed in double quotes (“ “)
2) Numeric: constant numbers specified in binary, octal, decimal or hexadecimal.
Syntax:
Example 5.2:
reg variable_name;
reg a;
reg [MSB : LSB] vector_variable_name;
reg b;
wire wire_variable_name;
wire c;
parameter par1 = value;
parameter N = 4;
assign c = a + b;
assign c = a + N;
Module #05 : Verilog HDL Operands
2) by position, placing the ports in exactly the same positions in the port lists of both the design and
the instance
Example 6.3:
// Passing arguments(signals) by position.
module byposition (a, b, c);
...
// Module instantiation in a top level module
byposition bypositioninstance(x, y ,z);
- Macros do string substitutions and do many of the jobs parameters do. They are good for global
parameters because they do not have to be passed through modules
Syntax:
for (count = value1; count </<=/>/>= value2; count = count +/- step)
begin
Example 7 .7:
... statements ...
for (j = 0; j <= 7; j = j + 1)
end
begin
c[j] = a[j] & b[j];
d[j] = a[j] | b[j];
end
7.11: disable:
- Execution of a disable statement terminates a block and passes control to the next statement after the
block.
- It is like the C break statement except it can terminate any loop, not just the one in which it appears.
- Disable statements can only be used with named blocks.
7.13: case:
- The case statement allows a multipath branch based on comparing the expression with a list of case
choices.
- Statements in the default block executes when none of the case choice comparisons are true.
- With no default, if no comparisons are true, synthesizers will generate unwanted latches.
- Good practice says to make a habit of putting in a default whether you need it or not.
- If the defaults are don’t cares, define them as ‘x’ and the logic minimizer will treat them as don’t cares
and save area.
- Case choices may be a simple constant, expression, or a comma-separated list of same.
7.13: casex:
- In casex(a), when the case_choice constants contains z, x or ?, they match any value in “a”.
- With case(a), a = x (unknown) matches only a case_choice of x, not 1, 0 or z.
- Also a=z (3-state) matches only z. In short, case uses x to detect a signal value of a=‘x’(unknown).
- Casex uses x as a wild card which can match anything.
7.13: casez:
- Casez is the same as casex except only ? and z (not x) are used in the case choice constants as don’t
cares.
- Casez is favored over casex since in simulation, an inadvertent x signal, will not be matched by a 0 or 1
in the case choice.
Syntax: Example7.1:
for Procedural Assignment reg sum, a, b, c;
variable = expression sum = b ^ c; // execute now.
Delayed assignment sum = #15 b ^ c; /* b ^ c; evaluated now; sum changed
#∆t variable = expression; after 15 time units. */
Intra-assignment delay
#10 sum = b ^ c; ; /* 10 units after sum changes, b ^ c; is
variable = #∆t expression;
evaluated and sum changes. */
Syntax:
variable = expression;
variable = #∆t expression; //grab inputs now, deliver ans. later, don’t delay next statement
#∆t variable = expression; //grab inputs later, deliver ans. later; delay next statement by #∆t
Syntax:
variable <= expression;
variable <= #∆t expression; //grab inputs now, deliver ans. later, don’t delay next statement
#∆t variable <= expression; //grab inputs later, deliver ans. later, don’t delay next statement.
Example 9.1:
always @(a or b) // level-triggered; if a or b changes levels
always @(posedge clk); // edge-triggered: on +ve edge of clk
- Functions are declared within a module, and can be called from continuous assignments, always
blocks, or other functions.
- In a continuous assignment, they are evaluated when any of its declared inputs change.
- In a procedure, they are evaluated when invoked.
- Functions describe combinational logic, and do not generate latches.
- Functions are a good way to reuse procedural code, since modules cannot be invoked from within a
procedure.
Example 10.2:
wire [7:0] x;
wire [7:0] y;
assign y = my_func[x];
Example 10.3:
module simple_processor (instruction, outp);
input [31:0] instruction;
output [7:0] outp;
reg [7:0] outp;; // so it can be assigned in always block
reg func;
reg [7:0] opr1, opr2;
Example 12 .1:
d D Q q
always @(clk,d)
begin
if (clk)
q <=d; clk EN
end
Example 12 .2:
always @(clk or rst or d) d D Q q
begin
if (rst)
q <= 0;
clk EN
else if (clk) R
q <= d;
end rst
b
Example 12 .3: D Q a
c
always @(posedge clk)
begin; d
a <= b & c; clk CLK
R
end
Example 12 .4:
always @(posedge clk or negedge rst); b a
D Q
begin; c
if (! rst)
d
a < = 0; clk CLK
else R
a <= b & c;
end rst
Example 12 .5:
reg [7:0] count;
wire enable;
always @(posedge clk or posedge rst) // Do not include enable.
begin;
if (rst)
count <= 0;
else if (enable)
count <= count+1;
end; // 8 flip-flops will be generated
Example 12 .6: a 1
if (sel == 1)
y = a; y
else
y = b; b 0
sel
a
Example 12 .7:
b
case (sel) y
2’b00: y = a; c
2’b01: y = b;
d
2’b10: y = c;
default: y = d;
endcase sel[1 : 0]
a
+
Example 12 .8:
b 1
if (sel == 1)
y = a + b; y
else c
y = c + d; 0
+
d
sel
Example 12 .9:
if (sel == 1)
y = a + b; a
else
y = c + d; c
sel + y
d
sel
Example 12 .10: en
if (en == 1)
y = a;
else a y
y = 1’bz;
Inputs
Present
Next State Output
State
Melay Machine
Inputs
Present
Next State Output
State
1) Using a Single Process (Procedural Block) to Code Present State, Next State and Output Logic
2) Using Two Process, One to code Present State and Next State logic and another to code Output Logic,
3) Using Three Process each to code Present State, Next State and Output Logic
Note: When modeling finite state machines, it is recommended to separate the sequential current-state logic
from the combinational next-state and output logic.
reset 0
S0/0 S0 – On Reset
S1 – 1 is detected
0 1 S2 – 10 is detected
1 S3 – 100 is detected
0 S4 – 1001 is detected
S1/0
1 1
S4/1 S2/0
0
1 0
S3/0
S0/0 S0 – On Reset
S1 – 1 is detected
1 S2 – 10 is detected
1 S3 – 100 is detected
0 S4 – 1001 is detected
S1/0
1 1
0
S4/1 S2/0
0
1 0
S3/0
S0 S0 – On Reset
S1 – 1 is detected
1/0 S2 – 10 is detected
1/0 S3 – 100 is detected
S1 0/0
1/0
1/1 0/0 S2
0/0
S3
always @(posedge clk or posedge rst) always @(state or data_i) begin : output_logic
begin : register_generation case (state)
if (rst) state = S0; S0: data_o = 1’b0;
else state = nxt_st; S1: data_o = 1’b0;
end S2: data_o= 1’b0;
S3: begin
if(data_i) data_o = 1’b1;
else data_o = 1’b0;
end
default: data_o = 1’b0;; // default avoids latches
endcase
end
endmodule
S0 S0 – On Reset
S1 – 1 is detected
1/0 S2 – 10 is detected
1/0 S3 – 100 is detected
S1 0/0
0/0
1/0
1/1 S2
0/0
S3
always @(posedge clk or posedge rst) always @(state or data_i) begin : output_logic
begin : register_generation case (state)
if (rst) state = S0; S0: data_o = 1’b0;
else state = nxt_st; S1: data_o = 1’b0;
end S2: data_o= 1’b0;
S3: begin
if(data_i) data_o = 1’b1;
else data_o = 1’b0;
end
default: data_o = 1’b0;; // default avoids latches
endcase
end
endmodule
Examples :
1) Implementing different Low Power Modes in a SoC using State Machines
2) Transmitter and Receiver Logic Implementation ( UART, SPI etc )
Inputs
Present
Next State Output
State
Melay Machine
Inputs
Present
Next State Output
State
1) Using a Single Process (Procedural Block) to Code Present State, Next State and Output Logic
2) Using Two Process, One to code Present State and Next State logic and another to code Output Logic,
3) Using Three Process each to code Present State, Next State and Output Logic
Note: When modeling finite state machines, it is recommended to separate the sequential current-state logic
from the combinational next-state and output logic.
1) Using Parameters:
parameter state0 = 0, state1 = 1, state2 = 2, state3 = 3;
2) Using Macros:
`define state0 2'd0
`define state1 2'd1
`define state2 2’d2
`define state3 2'd3;
When using macro definitions one must put a back quote in front. For example:
case (state)
`state0: Z = 3’b000;
`state1: Z = 3’b101;
`state2: Z = 3’b111;
`state3: Z = 3’b001;
state3 state1
skip3 = 1
wait3 = 1 skip3 = 0
state2
Examples :
1) reg X [0 : 7]; // X is a scalar reg array of depth = 8 and each 1 - bit wide
3) reg [7 :0] X2 [0 : 1] [0 : 3] ; X2 is a 2-Dimensional Array with Rows = 2 and Columns = 4 , each 8 bit wide
Syntax:
reg [wordsize:0] array [0:arraysize]
readmemb(“file_name”, array_name);
readmemb(“file_name”, array_name, start_addr);
readmemb(“file_name”, array_name, start_addr, finish_addrs);
readmemh(“file_name”, array_name);
Example 15 .2:
`timescale 100ps/10ps shall have a #1 delay of 100ps while you can give #0.1 as the smallest
delay i.e. of 10ps.
`timescale 1ns/1ps shall have `#1` as 1ns and `#0.001ns` as 1ps as the smallest delay.
`timescale 10ps/1fs shall represent a #1 of 10ps delay and #0.001ps is the smallest measurable
delay.
`timescale 1ns/1ns ; #0.49 , which is less than half a time unit. However the time precision is
specified as 1ns and hence the simulator can not go smaller than 1ns which makes it to round
to 0ns
#0.51; will get rounded to 1ns
Example 15.2:
integer cur_time ;
cur_time = $time ;
integer cur_time ;
cur_time = $stime ;
real cur_time ;
cur_time = $realtime ;
Example 16.3:
$stop ; Suspend simulation and print message (default argument = 1)
#150 $finish(2) ; Exits simulator after 150 time units from the last executed
statement and prints message (argument == 2).
16.5: $deposit:
- $deposit sets a net to a particular value, overwriting what was put there by the “circuit”. Good for test
benches.
16.6: $random :
- $random generates a random integer every time it is called. If the sequence is to be repeatable, the first
time one invokes random give it a numerical argument (a seed). Otherwise the seed is derived from the
computer clock.
Syntax:
handle1=$fopen(“filenam1.suffix”)
handle2=$fopen(“filenam2.suffix”)
$fstrobe(handle1, format, variable list) //strobe data into filenam1.suffix
$fdisplay((handle2, format, variable list) //write data into filenam2.suffix
$fwrite((handle2, format, variable list) //write data into filenam2.suffix all on
// one line. Put \n in the format string
// where a new line is desired.
state3 state1
skip3 = 1
wait3 = 1 skip3 = 0
state2
Example 17.3:
/*** Send in a new value of x every 3rd clock cycle***/ // Wait for y to respond (change);
@(negedge clk)
always
// Check the result; print a warning if it is not as expected.
begin: data_in_proc if (x != y) $display (“x != y, x=%b, y=%b,” x , y);
@(posedge clk) I<=I+1;
if (I= =9) $finish; // End of simulation end
@(posedge clk) // Wait here for the 2nd clock edge. end // data_in_proc
@(posedge clk) // After the 3rd edge, execute begin ...
begin endmodule
#1; // Keeps data from changing on clock edge.
x <= data[I];
What is FSM ?
Moore and Mealy FSM Block Diagram
FSM Design Techniques
Verilog HDL Design
Synthesizing the Design
Test Bench Design
Analysing Simulation Waveforms
In Digital VLSI design, Finite State Machines play a very important role in implementing the correct
behaviour of the system during different operating modes.
The FSM enables the system to go through different operating modes as per the user requirements or
during the self booting process
Moore Machine
Inputs
Next State Present State Outputs
Output Logic
Logic Logic
Melay Machine
Inputs
Next State Present State Outputs
Output Logic
Logic Logic
If you find the content valuable, Please do not forget to hit the 👍 button
Also, please do subscribe my YouTube channel and enable the notification to get notified for next
such designs.
I would appreciate your suggestions, any queries and any digital design you would like to understand
starting from circuit to HDL design. Please write them down in the comment section !!!
X
How would you describe the behavior of this function in Verilog Code ?
always @ (X or Y or Z)
if(X) foo = Y | Z;
else foo = Y & Z; foo can change when any of X, Y or Z changes
So, code must be rerun whenever any of these changes
assign f = a ? b : c
Is same as
if(a) f = b;
else f = c;
Flip-Flop
D Q
Flip Flop Behavior -
For every positive edge of the clock Q changes to become equal to D Clock
Please Like, Comment, Share & Subscribe My Channel in Order to Reach Out the Content to a Larger Audience.
Thanks !!