Verilog Primer Slides
Verilog Primer Slides
x full_adder s
y
cin cout
Verilog Module I/O Ports
top_level_module
I The wires above are scalar (represent 1 bit). They can also be
vectors:
wire [7:0] d; // 8-bit wire declaration
wire [31:0] e; // 32-bit wire declaration
Multi-bit Nets
I We can declare signals that are more than 1 bit wide in Verilog
I Use the syntax [MSB bit index : LSB bit index]
before a signal name to declare its bit-width
I When connecting multi-bit inputs or outputs to another
module, the bit-widths of the signals need to match!
module two_bit_adder (input [1:0] x, input [1:0] y, output [2:0] sum);
wire [1:0] partial_sum;
wire carry_out;
endmodule
Structural Verilog with Gate Primitives
Gate-Level Circuit Construction
wire xor_a_b;
wire cin_and;
wire and_a_b;
xor(xor_a_b, a, b);
and(cin_and, cin, xor_a_b);
and(and_a_b, a, b);
or(cout, and_a_b, cin_and);
endmodule
Behavioral Verilog
Letting the tools translate RTL to gates
Reduction operators also exist for AND, OR, and XOR that have
the same symbol as the bitwise operators.
Verilog Operators Cont.
Shifts, Concatenation, Replication, Indexing multi-bit wires
wire [7:0] d;
wire [31:0] e;
wire [31:0] f;
assign f = {d, e[23:0]}; // Concatenation + Slicing
assign f = { 32{d[5]} }; // Replication + Indexing
Designing the Full Adder
Using Behavioral Verilog
Inside constants.vh:
`ifndef CONSTANTS // guard prevents header file from being included more
,→ than once
`define CONSTANTS
`define ADDR_BITS 16
`define NUM_WORDS 32
`define LOG2(x) \
(x <= 2) ? 1 : \
(x <= 4) ? 2 : \
(x <= 8) ? 3 : \
(x <= 16) ? 4 : \
(x <= 32) ? 5 : \
(x <= 64) ? 6 : \
-1
`endif
Verilog Macros
Example Cont.
Inside design.v:
`include "constants.vh"
module memory (input [`ADDR_BITS - 1:0] address,
,→ output [`LOG2(`NUM_WORDS) - 1:0] data);
// implementation
endmodule
Reg Nets
Verilog has two types of net: wire and reg. Reg nets are required
whenever a net must preserve state (i.e. in an always block).
Wires are used for structural verilog (to connect inputs to outputs)
and for continuous assignment.
reg x;
Combinational Logic Blocks using always@(*)
This code has a default value and will not generate a latch:
input [1:0] x;
reg [1:0] y;
always @(*) begin
y = 2'b00;
if(x == 2'b10) begin
y = 2'd3;
end else if(x == 2'b11) begin
y = 2'd2;
end
end
Synchronous Logic Blocks
always@(*) begin
x = coeff*y;
end
Wire vs. Reg
What is a real register and what is just a wire?
module top();
localparam adder1width = 64;
localparam adder2width = 32;
reg [adder1width-1:0] a,b;
reg [adder2width-1:0] c,d;
wire [adder1width:0] out1;
wire [adder2width:0] out2;
adder #(.width(adder1width)) adder64 (.a(a), .b(b), .s(out1));
adder #(.width(adder2width)) adder32 (.a(c), .b(d), .s(out2));
endmodule
Multidimensional Nets in Verilog
module memory #(
parameter BITS_PER_WORD = 32,
parameter NUM_WORDS = 128)(
input clk,
input [`LOG2(NUM_WORDS) - 1 : 0] write_address,
input [BITS_PER_WORD - 1 : 0] write_data,
input [`LOG2(NUM_WORDS) - 1 : 0] read_address,
input write_enable,
output [BITS_PER_WORD - 1 : 0] read_data
);
// RTL Code
endmodule
Memory Module Design Example
RTL Code
initial begin
clk = 1'b0;
a = 32'h01234567;
b = 32'h00000000;
#1 a = 32'h10101010; // wait 1 time unit
#1 b = 32'h01010101;
#1 a = 32'h00000000;
b = 32'h11111111; // a and b change together
@(posedge clk); // jump to next rising edge
@(posedge clk); // jump to next rising edge
a = 32'hFEDCBA98;
#10;
// observe some output here.
end
Initial Blocks and Test Benches