Verilog 1
Verilog 1
Overview
• Logic Design review
– Basic Building Blocks
– Design Examples: Incrementer, Fifo
• Verilog: Coding Basic blocks
– Use of Modules
– Gates, Mux/Demux, Registers
– Data Values
– Counter Example
Logic Design Review
Inputs Outputs
Input[N:0]
Clock
Reset
Output[N:0]
Clock
Input[N:0] 3 4 5 6
Output[N:0] x 3 4 5
Input[N:0]
Clock
Output[N:0] Enable
Clock
Input[N:0] 3 4 5 6
Output[N:0] x 5
Enable
Select Lines / Address
Inputs Output
Address[N:0]
Data Out[K:0]
Write
Data In[K:0]
Registers File
Address[N:0]
Data Out[K:0]
Write
Data In[K:0]
Registers
MEMORYFile
Input1[N:0]
Output[N+1:0]
Input2[N:0] Adder/
Subtracter
Cin
Add/Sub
Saturate
Input1[N:0]
Output[2N:0]
Input2[N:0] Multiplier
Signed/Unsigned
Saturate
Making new Modules, Using
Existing Modules
Design Examples
• Example 1:
– A simple decrementer capable of
counting number of clock cycles
down to zero.
• Example 2:
– A four deep FIFO
Decrementer
Initial
Value[N:0]
Decrement
--
Load Count
Enable
Clock
Reset
Four deep FIFO
Data in[N:0]
Push
Data out[N:0]
FIFO Full
==4
Increment
Pop counter
Decrement ==0 FIFO Empty
++ --
Increment
Decrement
Count
Increment
counter
Decrement
FIFO
Data in[N:0]
Push
Data out[N:0]
FIFO Full
==4
Increment
Pop counter
Decrement ==0 FIFO Empty
FIFO DMA
PROCESSOR A MEMORY
SDRAM
PROCESSOR B MEMORY
Other components
Some way to configure
Filter Taps
Introduction to Modules
Verilog
Module: A reasonable size
replicate-able block e.g. FIFO,
counter and decrementer that we
covered are good candidates.
FIFO DMA
PROCESSOR A MEMORY
SDRAM
PROCESSOR B MEMORY
fifo.v
module fifo(
data_in
input [15:0] data_in,
input push,
push
input pop,
data_out
output [15:0] data_out,
output fifo_full,
output fifo_empty
);
fifo_full
endmodule
fifo.v
counter.v
endmodule
module counter(
input increment,
input decrement,
output[3:0] count
);
module fifo(
input [15:0] data_in, Code for modeling Counter
input push,
input pop, endmodule
output [15:0] data_out,
output fifo_full,
output fifo_empty
);
endmodule
module counter(
input increment,
input decrement,
output[3:0] count
);
wire push;
wire pop;
Code for modeling Counter
wire [3:0] count;
counter
Summary
• A block level hierarchy can be
modeled as modules.
• Module is the basic building
block.
• A module can be instantiated
inside another module.
• Module can be replicated with a
different instance name.
Verilog
Verilog
always @(*)
begin
a = b & c & d;
end
a = b | c | d;
a = b ^ c ^ d;
a = ~b;
Modeling Muxes/Demuxes
always @(*)
begin addr
case(addr)
2’d0: out = a;
2’d1: out = b;
2’d2: out = c;
2’d3: out = d;
endcase
end
MUX
Data Values
8’hXA
8’bXXXX_1010
8’hA
8’d10
8’b0000_1010
Width
Modeling Muxes/Demuxes
always @(*)
begin addr
case(addr)
2’d0: out = a;
2’d1: out = b;
2’d2: out = c;
2’d3: out = d;
endcase
end
DEMUX
MUX
Modeling Muxes/Demuxes
addr
always @(*)
begin
case(addr)
2’d0: {a,b,c,d} = {in,3’d0};
2’d1: {a,b,c,d} = {1’d0,in,2’d0};
2’d2: {a,b,c,d} = {2’d0,in,1’d0};
2’d3: {a,b,c,d} = {3’d0,in};
endcase
end
DEMUX
concatenation
c
a [3:0] b [2:0] 0 0 0 0
data_in = { a,b,4’d0,{3{c}} };
data_in [13:0]
MEMORY
Modeling Muxes/Demuxes
addr
always @(*)
begin
case(addr)
2’d0: {a,b,c,d} = {in,3’d0};
2’d1: {a,b,c,d} = {1’d0,in,2’d0}; 0
2’d2: {a,b,c,d} = {2’d0,in,1’d0}; 0
2’d3: {a,b,c,d} = {3’d0,in}; 0
endcase
end
Modeling Registers
always@( posedge clk )
begin
if(reset) reg_out <= #1 0;
else reg_out <= #1 reg_in;
end
reg_in[N:0]
clk
reset
reg_out[N:0]
Arithmetic Operations
a[N:0]
c[N+1:0]
b[N:0] Adder/
Subtracter
always@(*) cin
add/sub
begin saturate
c = a + b;
end a[N:0]
c[2N:0]
b[N:0] Multiplier
c = a - b;
c = a * b; signed/unsigned
saturate
Declarations
always@(*) assign c = a + b;
c = a + b;
a[15:0]
What about a & b?
Should they be b[15:0] c[16:0]
Adder
wire or reg?
always@(posedge clk)
c <= #1 a + b;
Verilog Coding
• Make a Design Diagram
• Code all the building blocks
– Name the wires in the design
diagram
– Declare the module port list
– Start coding the logic elements
one by one
– Declare Variables
module counter(
input clk,
input reset,
input increment,
input decrement,
output reg [3:0] count
);
reg enable;
Example 1: counter.v
reg [3:0] mux_out;
always@(*)
enable = increment | decrement;
always@(*)
begin dec_out
case(increment)
1’b0: mux_out = count-1; inc_out
1’b1: mux_out = count+1;
++ --
endcase mux_out
end increment
else if(enable)
count <= #1 mux_out;
endmodule