ece482 verilog introduction
TRANSCRIPT
BASIC BUILDING BLOCK - MODULES // single-line comments /* multi-line comments Don’t forget this “;” */ module name(input a,b,input [31:0] c,output z,output reg [3:0] s); // declarations of internal signals, registers // combinational logic: assign // sequential logic: always @ (posedge clock) // module instances endmodule
In Verilog we design modules, one of which will be identified as our top level module. Modules usually have named, directional ports (specified as input, output) which are used to communicate with the module.
WIRES We have to provide
declarations* for all our named wires (aka “nets”). We can create buses – indexed collections of wires –by specifying the allowable range of indices in the declaration:
wire a,b,z; // three 1-bit wires wire [31:0] memdata; // a 32-bit bus wire [7:0] b1,b2,b3,b4; // four 8-bit buses
Note that [0:7] and [7:0] are
both legitimate but it pays to develop a convention and stick with it. Common usage is [MSB:LSB] where MSB > LSB; usually LSB is 0.
The individual bits of wires
can be accessed using array-like notation. Thus, b1[7] is the most-significant (left-hand) bit of “b1" and b1[0] is the least significant bit. Further, b1[2:1] is a 2-bit wire formed from the 3rd and 2nd bits of “b1".
ASSIGN STATEMENTS If we want to specify a behavior equivalent to combinational logic, use Verilog’s
operators and continuous assignment statements:
// 2-to-1 multiplexer with dual-polarity outputs
module mux2(z, zbar, a,b,sel);
input a, b, sel;
output z, zbar;
// again order doesn’t matter (concurrent execution!)
// syntax is “assign LHS = RHS” where LHS is a wire/bus and RHS is an expression
assign z = sel ? b : a;
assign zbar = ~z;
endmodule
Conceptually assign’s are evaluated continuously, so whenever a value used in the RHS changes, the RHS is re-evaluated and the value of the wire/bus specified on the LHS is updated. This type of execution model is called “dataflow” since evaluations are triggered by data values flowing through the network of wires and operators. LHS must be of type wire
BOOLEAN OPERATORS Bitwise operators perform bit-oriented operations on vectors
• ~(4’b0101) = {~0,~1,~0,~1} = 4’b1010
• 4’b0101 & 4’b0011 = {0&0, 1&0, 0&1, 1&1} = 4’b0001 Reduction operators act on each bit of a single input vector
• &(4’b0101) = 0 & 1 & 0 & 1 = 1’b0
Logical operators return one-bit (true/false) results
• !(4’b0101) = 1’b0
BOOLEAN OPERATORS LIST
OTHER OPERATORS
NUMERIC CONSTANTS Constant values can be specified with a specific width and radix:
123 // default: decimal radix, 32-bit width ’d123 // ’d = decimal radix ’h7B // ’h = hex radix ’o173 // ’o = octal radix ’b111_1011 // ’b = binary radix, “_” are ignored ’hxx // can include X, Z or ? in non-decimal constants 16’d5 // 16-bit constant ‘b0000_0000_0000_0101 11’h1X? // 11-bit constant ‘b001_XXXX_ZZZZ
By default constants are unsigned and will be extended with 0’s on left if need be (if high-order bit is X or Z, the extended bits will be X or Z too). You can specify a signed constant as follows: 8’shFF // 8-bit twos-complement representation of -1
To be absolutely clear in your intent it’s usually best to explicitly specify the width and radix.
HARDWARE MODELS BEHAVIOURAL
highest level of abstraction
farthest from hardware
closest to ideas (thinking)
DATA FLOW
hardware described in boolean (logic)
combinational
STRUCTURAL
hardware described in terms of fundamental gates
STRUCTURAL DESIGN The lowest level of design is structural level design. In structural level design
you simply insert pre-defined building blocks into your design and wire them together to create the final circuit. To accommodate this, Verilog provides a set of built-in logic gates. Advantages and disadvantages of structural design include the following:
+ Easy to learn + Easy to debug + Design is simply a textual equivalent of a schematic - Does not take advantage of most of the HDL advantages An AND gate would be instanced structurally like this:
AND2(d, a, b); // where d is the output and a & b are the inputs The last point in the advantages/disadvantages list above is the major
disadvantage with this level of design. You must manually do the entire design including all optimization steps.
DATA FLOW DESIGN In dataflow level design, you write what amounts to Boolean equations for your logic
using a C-like syntax. The Verilog synthesizer then converts the equations to their gate-level equivalent while doing logic minimization and technology mapping. Advantages and disadvantages of dataflow design include the following:
+ No explicit gates are instanced and thus it is less verbose + Multi-bit wires can be operated on in one statement + If-then-else constructs exist which make MUX-like statements simple to write - Sequential logic cannot be specified using dataflow-only constructs
An AND gate would be described in dataflow terms like this: assign q = a & b;
While this simple example does not show the power of dataflow modelling, complex Boolean expressions can be created involving multi-bit wires in a single statement.
BEHAVIOURAL DESIGN Here, the term behavioral level design is used to
indicate design using always blocks. These are sequential blocks of code that describe how a computation should be performed. This level of design makes it possible to describe complete sequential circuits consisting of input forming logic, state registers, and output forming logic in a single construct. In addition, if-then-else, case, and loop statements make many kinds of combinational logic easy to write.
+ Highest level of abstraction
+ Least verbose and most powerful
Here is an example of an up-down counter design in Verilog, complete with a synchronous clear:
module counter( q, clk, clear, up_down);
input clk, clear, up_down;
output reg[7:0] q;
// the q is defined to be an 8-bit vector;
always @ (posedge clk)
// execute this code on the rising edge of the clock
begin
if (clear)
q = 8'b00000000;
else if (up_down)
q = q + 1;
else
q = q - 1;
end
endmodule
As can be seen, the code above represents logic consisting of an adder, a subtractor, control of the adding, subtracting, and clearing functions, and the state register for the counter.
EXAMPLE: 1-bit ADDER FOR ALL 3 CASES
STRUCTURAL DESIGN (ADDER)
module adder_s(sum, carry, in1, in2);
input in1, in2;
output sum, carry;
and g0(carry,in1,in2);
xor g1(sum,in1,in2);
endmodule
DATA FLOW DESIGN - ADDER module adder_d(sum, carry, in1, in2);
input in1, in2;
output sum, carry;
assign sum = in1 ^ in2;
assign carry = in1 & in2;
endmodule
Boolean logic - more fundamental construct than addition
BEHAVIOURAL DESIGN - ADDER module adder_b(sum, carry, in1, in2);
input in1, in2;
output sum, carry;
assign {carry, sum} = in1 + in2;
endmodule
(+) Addition is a high level construct Verilog compiler will generate the code for addition
DATA FLOW MODEL – 2X1 MUX module mux_2_1 (op, a, b, sel);
input a, b, sel;
output op;
assign op = sel?b:a;
endmodule
BEHAVIOURAL MODEL – 2X1 MUX module mux_2_1 (op, a,b, sel); input a, b, sel; output op; reg op; always @(sel or a or b) begin if(sel) op = b; else op = a; end endmodule
op will be implemented as wire only if
1) a and b both are in sensitivity list of always block
2) all possible cases are covered in if-else or switch
This is behavioral model of
2-1 MUX
DATA FLOW MODEL – 4x1 MUX module mux_4_1 (op, a, b, c, d, sel);
input a, b, c, d;
input [1:0] sel;
output op;
assign op = (sel[1]==1)?(sel[0]==1?d:c):(sel[0]==1?b:a);
endmodule
BEHAVIOURAL MODEL – 4x1 MUX module mux_4_1 (op, a, b, c, d, sel); input a, b, c, d; input [1:0] sel; output op; reg op; always @(sel or a or b or c or d) begin case(sel) 2'b00: op = a; 2'b01: op = b; 2'b10: op = c; 2'b11: op = d; end endmodule
HIERARCHICAL DESIGN Once a module has been created, it
can be used in higher-level designs. Thus, the following module makes use of the mux2 module a MUX that selects between two different 4-bit values.: module mux2_4(q, a, b, sel); input sel; input[3:0] a, b; output[3:0] q; mux2 M0(q[0], a[0], b[0], sel); mux2 M1(q[1], a[1], b[1], sel); mux2 M2(q[2], a[2], b[2], sel); mux2 M3(q[3], a[3], b[3], sel); endmodule
When instancing a user-define module, an instance name is required before the parentheses. In this case, the instance names are M0, M1, M2 and M3.
The module mux2 will be:
module mux2(z, a, b, sel); input a, b, sel; output z; assign z = sel ? b : a; endmodule