Sunteți pe pagina 1din 20

BASIC BUILDING BLOCK - MODULES

// single-line comments /* multi-line comments Dont 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 mostsignificant (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 Verilogs 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 doesnt 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 assigns 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 ~(4b0101) = {~0,~1,~0,~1} = 4b1010 4b0101 & 4b0011 = {0&0, 1&0, 0&1, 1&1} = 4b0001 Reduction operators act on each bit of a single input vector &(4b0101) = 0 & 1 & 0 & 1 = 1b0 Logical operators return one-bit (true/false) results !(4b0101) = 1b0

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 16d5 // 16-bit constant b0000_0000_0000_0101 11h1X? // 11-bit constant b001_XXXX_ZZZZ By default constants are unsigned and will be extended with 0s 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: 8shFF // 8-bit twos-complement representation of -1

To be absolutely clear in your intent its 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 gatelevel 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 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.

Here is an example of an up-down counter design in Verilog, complete with a synchronous clear:

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

S-ar putea să vă placă și