Documente Academic
Documente Profesional
Documente Cultură
Verilog
What is Verilog
Hardware Description Language (HDL) Developed in 1984 Standard: IEEE 1364, Dec 1995
Transistor
module
Basic building block in Verilog module
- Created by declaration (cant be nested) - Used by instantiation
Interface is defined by ports Ports provide interface for by which a module can communicate with its environment May contain instances of other modules All modules run concurrently
module(Cont.)
in1 in2
my_module
out1
out2
f
inN outM
endmodule
Everything you write in Verilog must be inside a module exception: compiler directives
module(Cont.)
A
B Half Adder
S
C
wire S, C, A, B;
assign S = A ^ B; assign C = A & B; endmodule
User identifiers
Must not be keywords Maximum of 1024 characters in identifier Formed from {[A-Z], [a-z], [0-9], _, $}, but cant begin with $ or [0-9] myidentifier m_y_identifier 3my_identifier XXXXXX $my_identifier XXXXXX _myidentifier$ Case sensitivity myid Myid Keywords are lower case
Statement/declaration termination
Terminate statement/declaration with semicolon ;
Comments
// The rest of the line is a comment /* Multiple line comment */
*/
Free format
Free format within statement except for within quotes - Strings enclosed in double quotes and must be on a single line
Numbers in Verilog
<size><radix> <value>
No of bits Binary b or B Octal o or O Decimal d or D Hexadecimal h or H
Numbers in Verilog(Cont.)
You can insert _ for readability - 12b 000_111_010_100 Represent the same number - 12b 000111010100 - 12o 07_24 Bit extension - MS bit = 0, x or z extend this 4b x1 = 4b xx_x1 - MS bit = 1 zero extension 4b 1x = 4b 00_1x
Numbers in Verilog(Cont.)
If size is ommitted it - is inferred from the value or - takes the simulation specific number of bits or - takes the machine specific number of bits
Nets
Doesnt store value, just a connection Can be thought as hardware wires driven by logic Equal z when unconnected Various types of nets - wire - wand (wired-AND) - wor (wired-OR) - tri (tri-state) In following examples: Y is evaluated, automatically, every time A or B changes input, output and inout ports are default wire
Nets(Cont.)
A B Y
wire Y; // declaration assign Y = A & B;
A Y
B
wor Y; // declaration assign Y = A; assign Y = B;
dr A Y
tri Y; // declaration assign Y = (dr) ? A : z;
Registers
Variables that store values Event-driven modeling Do not represent real hardware but real hardware can be implemented with registers Only one type: reg reg A, C; // declaration // assignments are always done inside a procedure A = 1; C = A; // C gets the logical value 1 A = 0; // C is still 1 C = 0; // C is now 0
Vectors
Represent buses wire [3:0] busA; reg [1:4] busB; reg [1:0] busC; Left number is MS bit Slice management
busC = busA[2:1];
integers are not initialized reals are initialized to 0.0 integers are usually 32 bits
Arrays
Syntax reg var [-15: 16]; // 32 1-bit regs reg [7:0] mem [ 0:1023]; // 1024 8-bit regs Accessing array elements - Entire element: mem[10] = 8b 10101010; - Element subfield (needs temporary storage): reg [7:0] temp; .. Temp = mem[10]; var[6] = temp[2];
Arrays(Cont.)
Limitations:
No multi-dimentional arrays
reg var[1:10] [1:100]; // WRONG!! Arrays dont work for the Real data type
Declaration
time my_time; Use inside procedure
Strings
Implemented with regs: reg [8*13:1] string_val; // can hold up to 13 chars .. string_val = Hello Verilog ; string_val = hello; // MS Bytes are filled with 0 string_val = I am overflowed; // I is truncated
Escaped chars:
- \n - \t - %% - \\ - \ newline tab % \
Port assignments
module
input
reg or net
net
module
output
reg or net
net
module
inout
net
net
Operators
Logical Operators Bit-wise Operators Unary/Reduction Operators Shift Operators Concatenations Operator Relational Operators Equality Operators Conditional Operators Arithmetic Operators && , || , ! & , | , ~ , ^ , ~^ , ^~ & , | , ^ , ~& , ~| , ~^ , ^~ >> , << {} > , < , >= , <= == , != , === , !== ?: +, -,*,/,%
Operators(Cont.)
Logical Operators
&& logical AND || logical OR ! logical NOT Operands evaluated to ONE bit value: 0, 1 or x Result is ONE bit value: 0, 1 or x A = 6; A && B 1 && 0 0 B = 0; A || !B 1 || 1 1 C = x; C || B x || 0 x
but C&&B=0
Operators(Cont.)
Bitwise operators
& | ~ ^ ~^ or ^~ bitwise AND bitwise OR bitwise NOT bitwise XOR bitwise XNOR
Operators(Cont.)
Unary/Reduction Operators
& | ^ ~& ~| ~^ or ^~ AND OR XOR NAND NOR XNOR
Operators(Cont.)
>> shift right << shift left
Shift operators
1 1
A << 2 A >> 2
0 0
1 0
0 1
0 1
Operators(Cont.)
Concatenation operator
{op1, op2, ..} concatenates op1, op2, .. to single number Operands must be sized reg a; reg [2:0] b, c; a = 1b 1; b = 3b 010; c = 3b 101; catx = {a, b, c}; // catx = 1_010_101 caty = {b, 2b11, a}; // caty = 010_11_1 catz = {b, 1}; // WRONG !! Replication catr = {4{a}, b, 2{c}}; // catr = 1111_010_101101
Operators(Cont.)
Relational operators
> < >= <= greater than less than greater or equal than less or equal than
Operators(Cont.)
Equality operators
== != === !== logical equality logical inequality case equality case inequality
Return 0, 1 or x
Return 0 or 1
- 4b 1z0x == 4b 1z0x x - 4b 1z0x != 4b 1z0x x - 4b 1z0x === 4b 1z0x 1 - 4b 1z0x !== 4b 1z0x 0
Operators(Cont.)
Conditional operator
cond_expr ? true_expr : false_expr;
A B
1 0 sel
Y = (sel)? A : B;
Operators(Cont.)
Arithmetic operators
+, -, *, /, % If any operand is x the result is x Negative registers: - regs can be assigned negative but are treated as unsigned reg [15:0] regA; .. regA = -4d12; // stored as 216-12 = 65524
regA/3
// evaluates to 21861
Operators(Cont.)
Arithmetic operators(Cont.)
Negative integers: - can be assigned negative values
Operators(Cont.)
Operator Precedence
Continuous assignements
Syntax:
assign #delay <id> = <expr>;
optional net type !! wire S, C, A, B; assign S = A ^ B; assign C = A & B; module half_adder(S, C, A, B); output S, C; input A, B;
Properties:
- they all execute in parallel - are order independent - are continuously active
endmodule
A B Half Adder
S C
Instances
A module provides a template from which you can create actual objects. When a module is invoked, Verilog creates a unique object from the template. Each object has its own name, variables, parameters and I/O interface.
Instances(Cont.)
half_adder ha1(I1, I2, in1, in2); half_adder ha2(sum, I3, I1, cin); assign cout = I2 || I3; endmodule
Instance name
Instances(Cont.)
Port connections/associations
Connect/associate module port by order list Connect/associate module port by name (Recommended)
Gate level
Built-in gate primitives: - and, nand, nor, or, xor, xnor, buf, not, bufif0, bufif1, notif0, notif1 - No declaration; can only be instantiated - Instances of primitives may include delays buf b1(a, b); // Zero delay buf #3 b2(c, d); // Delay of 3 time unit buf #(4,5) b3(e, f); // Rise=4 time unit, fall=5 time unit buf #(3:4:5) b4(g, h); // Min-typical-max time unit Usage: nand (out, in1, in2); 2-input NAND without delay and #2 (out, in1, in2, in3); /* 3-input AND with 2 time unit delay */ //Usually better to provide instance name for debugging not #1 N1(out, in); /* NOT with 1 time unit delay and instance name */ xor X1(out, in1, in2); // 2-input XOR with instance name Write them inside module, outside procedures
Gate level(Cont.)
a1 a2
iv_sel
a1_o
o 1
out
wire iv_sel,a1_o,a2_o;
a2_o
sel
endmodule
Gate level(Cont.)
The first signal in the port list is always output. However, in the truth table the output signal value is at the end (after a colon). Input order in the truth table must follow the order given in the port list Combinational UDPs dont need initialization on the other side sequential UDPs need. Cannot be defined within modules.
Often simulate faster than using expressions, collections of primitive gates, etc. Most often used for specifying custom gate libraries
reg q;
Initial q=0; table // clk data q new-q (01) 0 : ? : 0; (01) 1 : ? : 1; (0x) 1 : 1 : 1; (0x) 0 : 0 : 0; (?0) ? : ? : -; (??) ? : ? : -; endtable endprimitive
// Latch a 0 // Latch a 1 // Hold when d and q both 1 // Hold when d and q both 0 // Hold when clk falls // Hold when clk stable
Execution Flow
Behavioral model(Cont.)
initial blocks
Start execution at simulation time zero and finish when their last statement executes
module nothing; initial $display(Im first); initial begin #50; $display(Really?); end endmodule
Will be displayed at sim time 0
Behavioral model(Cont.)
always blocks
Start execution at simulation time zero and continue until simulation finishes Sensitivity list specifies events on which signals activating always blocks
module
always begin
always begin
end
always begin
end
end
Behavioral model(Cont.)
Delays in procedures
Inter-assignment delay: Delay specified in front of procedural assignment statements (e.g. #3 a = b&c;) delay the execution of the entire statement.
module delayTest; integer a, b, c; initial begin a = 2; b = 3; end initial #3 a = 4; initial #5 c = a + b;
endmodule
Result: c=7
Intra-assignment delay: Delay specified right after = in procedural assignment statements (e.g. a = #3 b&c;) just delay the assignment operation. The evaluation of the right hand side expression is executed without delay.
module delayTest; integer a, b, c; initial begin a = 2; b = 3; end
initial #3 a = 4;
initial c = #5 a + b; endmodule Execution order: 1. evaluation 2. delay 3. assignment
Result: c=5
Behavioral model(Cont.)
Fundamental problem
In a synchronous system, all flip-flops sample simultaneously at positive edge of clock In Verilog, always @(posedge clk) blocks run in some undefined sequence
Behavioral model(Cont.)
Non-blocking assignments use <= as assignment symbol Non-blocking assignments are performed concurrently
initial begin #1 a <= 1; // assignment at time 1 #3 b <= 0; // assignment at time 3 #6 c <= 1; // assignment at time 6 end
reg d1, d2, d3, d4; always @(posedge clk) d2 <= d1; always @(posedge clk) d3 <= d2; always @(posedge clk) d4 <= d3;
Non-blocking rule: - RHS evaluated when assignment runs - LHS updated only after all events for the current instant have run
A sequence of nonblocking assignments dont communicate a<= 1; b<= a; c <= b; //a = 1 //b = old value of a //c = old value of b
1 a
a = 1; b = a; c = b; // a = b = c = 1
c
Behavioral model(Cont.)
Events
An event occurs when a net or register changes it value. The event can be further specified as a rising edge (by posedge) or falling edge (by negedge) of a signal.
execution triggers every time any signal changes execution triggers every time clk changes from 0 to 1 execution triggers every time clk changes from 1 to 0
Behavioral model(Cont.)
Behavioral model(Cont.)
Timing
initial begin #5 c = 1; #5 b = 0; #5 d = c; end
Each assignment is blocked by its previous one
d
c b
5
Time
10
15
Timing(Cont.)
d c b 0 5 Time 10 15
Procedural statements if
if (expr1) true_stmt1; else if (expr2) true_stmt2; .. else def_stmt;
Procedural statements(Cont.)
always @(in or sel) if (sel == 0) out = in[0]; else if (sel == 1) out = in[1]; else if (sel == 2) out = in[2]; else out = in[3]; endmodule
Procedural statements(Cont.)
case
case (expr)
item_1, .., item_n : stmt1; item_n+1, .., item_m : stmt2; .. default : def_stmt;
endcase
Procedural statements(Cont.)
Procedural statements(Cont.)
for
for (init_assignment; cond; step_assignment) stmt;
Procedural statements(Cont.)
while
module count(Y, start); output [3:0] Y; input start;
reg [3:0] Y; wire start; integer i; initial Y = 0; always @(posedge start) begin i = 0; while (i < 3) begin #10 Y = Y + 1; i = i + 1; end end endmodule
Procedural statements(Cont.)
repeat
module count(Y, start); output [3:0] Y; input start; repeat (times) stmt; reg [3:0] Y; wire start;
Can be either an integer or a variable
initial Y = 0;
always @(posedge start) repeat (4) #10 Y = Y + 1;
endmodule
Procedural statements(Cont.)
forever
module test; reg clk;
forever stmt;
Executes until Simulation finishes
Mixed model
module simple(Y, c, clk, res); output Y; input c, clk, res;
Code that contains various both gate, RTL, and behavioral styles
reg Y; wire c, clk, res; wire n; not( n, c); // gate-level always @(res or posedge clk) if (res) Y = 0; else Y = n; endmodule
Verilog subroutines
Subroutines lead to more readable code and make code-reuse easy Types of subroutines are: task and function Subroutines can be used only in behavioural blocks and contain behavioural statements Verilog offers a large set of system built-in tasks and functions
Verilog subroutines(Cont.)
tasks
Declared within a module Referenced only by a behavior within the module Parameters passed to task as input and inout and from task as output or inout Local variables can be declared Recursion is not supported
Task invocation
reg [31:0] result; reg [ 3:0] data; Factorial (result,data);
begin outfact = 1; for(count = n; count > 0 ;count = count-1) outfact = outfact * count; end endtask
Verilog subroutines(Cont.)
functions
Implement combinational behavior May call other functions with no recursion Reference in an expression, e.g. RHS No output or inout allowed Implicit register having name and range of function
Function call
reg [31:0] result; reg [ 3:0] data; result = Factorial (data);
begin Factorial = 1; for(count = n; count > 0 ;count = count-1) Factorial = Factorial*count; end endtask
System tasks
Always written inside procedures
Built-in system tasks or functions begin with $ $display( .., arg2, arg3, ..); - It much likes printf() in C, displays formatted string in std output when encountered $monitor( .., arg2, arg3, ..); - It likes $display(), but displays string each time any of arg2, arg3, .. Changes $stop; - It suspends simulation when encountered $finish; - It finishes simulation when encountered $fopen(filename); - It returns file descriptor (integer); then, you can use $fdisplay( fd, .., arg2, arg3, ..); or $fmonitor( fd, .., arg2, arg3, ..); to write to file $fclose(fd); - closes file $random(seed); - It returns random integer; give her an integer as a seed
System tasks(Cont.)
Compiler directives
`include filename - inserts contents of file into current file - write it anywhere in code `define <text1> <text2> - text1 substitutes text2;
- e.g. `define BUS reg [31:0] in declaration part: BUS data; 50ns
parameter
in[3:0] p_in[3:0]
out[1:0]
wu
clk
wd
endmodule
endmodule
Parameter(Cont.)
Implelementation without parameters
module top(out, in, clk); output [1:0] out; input [3:0] in; Input clk; wire [1:0] out; wire [3:0] in; wire clk; wire [3:0] p_in; wire wu, wd; assign wu = p_in[3] & p_in[2]; assign wd = p_in[1] & p_in[0]; dff4bit instA(p_in, in, clk); dff2bit instB(out, {wu, wd}, clk); /* notice the concatenation*/ endmodule // internal nets
Parameter(Cont.)
Implelementation with parameters
module dff(Q, D, clk); parameter WIDTH = 4; output [WIDTH-1:0] Q; input [WIDTH-1:0] D; input clk; reg [WIDTH-1:0] Q; wire [WIDTH-1:0] D; wire clk; always @(posedge clk) Q = D; endmodule
module top(out, in, clk); output [1:0] out; input [3:0] in; input clk;
wire [1:0] out; wire [3:0] in; wire clk; wire [3:0] p_in; wire wu, wd; assign wu = p_in[3] & p_in[2]; assign wd = p_in[1] & p_in[0]; dff instA(p_in, in, clk); /* WIDTH = 4, from declaration */
dff instB(out, {wu, wd}, clk); defparam instB.WIDTH = 2; /* We changed WIDTH for instB only */ endmodule
Testbench
Stimulus
Response
Verilog Simulator
Verilog Parser
..
User Interface Simulation Engine
d c b
10
15
initial begin // Generate remaining inputs $monitor($time, " %b -> %b", t_in, t_out); #5 t_in = 4'b0101; #20 t_in = 4'b1110; #20 t_in[0] = 1; #300 $finish; end endmodule
Discrete-event simulation
Basic idea: only do work when something changes Centered around an event queue - Contains events labeled with the simulated time at which they are to be executed Scheduler - Execute every event for the current simulated time - Doing this changes system state and may schedule events in the future - When there are no events left at the current time instance, advance simulated time soonest event in the queue
Discrete-event simulation(Cont.)
Non-preemptive, no priorities A process must explicitly request a context switch Events at a particular time unordered Undefined execution order convenient for implementing event queue Context switching behavior convenient for simulation Two types of events - Evaluation events compute functions of inputs - Update events change outputs - Split necessary for delays, non-blocking assignments, etc.
a <= b + c;
Update event writes new value of a and schedules any evaluation events that are sensitive to a change on a Evaluation event reads values of b and c, adds them, and schedules an update event
- This runs forever: no context switch allowed, so ready can never change
while (~ready) while (~ready)begin @(ready); count = count + 1; count = count + 1; #( clk_period ); end wait(ready);
thanks
digital design