Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 77

Verilog Reference Guide From

Digitronix Nepal
Verilog Reference Guide For Beginners
Table of Contents: Design and Simulation of
1. Gate
2. MUX, Encoder
3. DeMUX, Decoder
4. Half Adder
5. Full Adder
6. ALU Design (2–bit)
7. Latch , Flip-flops
8. Structural Design in Verilog: 8 bit ALU Design
9. Counter Design
10. Finite State Machine: Sequence Detector
11. File Handling in Verilog
12. Image Processing in Verilog
13. Complete flow for Implementing design in Spartan 3e FPGA

No. 1 – AND Gate


Introduction

Example
/* A simple AND gate File: and.v */

module andgate (a, b, y);

input a, b;

output y;
assign y = a & b;

endmodule

RTL Schematic

Simulation Text Fixture

/* testbench for AND gate File: and_tb.v */

module andgate_tb;

wire t_y;

reg t_a, t_b;

andgate my_gate( .a(t_a), .b(t_b), .y(t_y) );

initial

begin

$monitor(t_a, t_b, t_y);

t_a = 1'b0;

t_b = 1'b0;

#5

t_a = 1'b0;

t_b = 1'b1;

#5

t_a = 1'b1;

t_b = 1'b0;
#5

t_a = 1'b1;

t_b = 1'b1;

end endmodule

Simulation Output

Reference

 Electrosoft
 Verilog Codes

No. 2 – Procedural Blocks


Example:

module comb(a, b, c);

input c;

input b;

output a;

reg a;

always @( c or b)

begin

a = c & b;

end
endmodule

RTL:

1. Figure: Output of module comb

Simulation TestFixture:

module forkjoin(clk, a, b);

input clk;

output a;

output b;

reg a, b;

initial

begin

a = 0;

b = 0;

end
always @(posedge clk)

fork

#2 a = 1;

#1 b = 1;

join

endmodule

Output:

No. 3 – Decoder
Decoder selects 2n signals from n select signals.

Example:

module decoder_using_assign (

binary_in , // 4 bit binary input

decoder_out , // 16-bit out

enable // Enable for the decoder

);

input [3:0] binary_in ;

input enable ;

output [15:0] decoder_out ;

wire [15:0] decoder_out ;


assign decoder_out = (enable) ? (1 << binary_in) : 16'b0 ;

endmodule

No. 4 – MUX (2:1)

Module mux21a (

Input wire a,

Input wire b,

Input wire s,

Output wire y

);

assign y = ~s & a| s &strong;

endmodule

Simulation
No. 5 – 2:1 MUX with Gate level modelling
Example

//declare the Verilog module - The inputs and output signals.

module mux2to1(

Data_in_0,

Data_in_1,

sel,

Data_out

);

//what are the input ports.

input Data_in_0;

input Data_in_1;

input sel;

//What are the output ports.


output Data_out;

//Internal variables.

wire not_sel;

wire temp1,temp2;

wire Data_out_temp;

//NOT gate - first signal(not_sel) is output and others are inputs.

not n1(not_sel,sel);

//AND gate - first signal(temp1 and temp2) is output and others are
inputs.

and and_1(temp1,Data_in_0,not_sel);

and and_2(temp2,Data_in_1,sel);

//OR gate - first signal(Data_out_temp) is output and others are inputs.

or or_1(Data_out_temp,temp1,temp2);

//Assign the final value to the output port.

assign Data_out = Data_out_temp;

endmodule

Output
No. 6 – 2:1 MUX using if statements
Example

//declare the Verilog module - The inputs and output signals.

module mux2to1( Data_in_0, Data_in_1, sel, Data_out );

//what are the input ports.

input Data_in_0;

input Data_in_1;

input sel; //What are the output ports.

output Data_out; //Internal variables.

reg Data_out; //Always block - the statements inside this block are
executed when the given sensitivity list //is satidfied. for example in this
case the block is executed when any changes occur in the three
signals //named 'Data_in_0','Data_in_1' or
'sel'. always @(Data_in_0,Data_in_1,sel)

begin

if(sel == 0) Data_out = Data_in_0; //when select signal to the mux


is low

else Data_out = Data_in_1; //when select signal to the mux is


high

end

endmodule

Simulation Test Fixture

module tb_mux;
// Declaring Inputs

reg Data_in_0;

reg Data_in_1;

reg sel;

// Declaring Outputs

wire Data_out;

// Instantiate the Unit Under Test (UUT)

mux2to1 uut (

.Data_in_0(Data_in_0),

.Data_in_1(Data_in_1),

.sel(sel),

.Data_out(Data_out)

);

initial begin

// Apply Inputs

Data_in_0 = 0;

Data_in_1 = 0;

sel = 0;

// Wait 100 ns
#100;

//Similarly apply Inputs and wait for 100 ns

Data_in_0 = 0; Data_in_1 = 0; sel = 1; #100;

Data_in_0 = 0; Data_in_1 = 1; sel = 0; #100;

Data_in_0 = 0; Data_in_1 = 1; sel = 1; #100;

Data_in_0 = 1; Data_in_1 = 0; sel = 0; #100;

Data_in_0 = 1; Data_in_1 = 0; sel = 1; #100;

Data_in_0 = 1; Data_in_1 = 1; sel = 0; #100;

Data_in_0 = 1; Data_in_1 = 1; sel = 1; #100;

end

endmodule

Output

No. 7 – Structural Level Coding of MUX [4:1]


A multiplexer (or mux) is a device that selects one of several input signals
and forwards the selected input into a single output line. In previous posts,
there is Verilog code for 2:1 MUX's using Behavioral modelling and Gate
level modelling. It might have to use either of these codes in this example.
In the structural level coding using Verilog ,the 2:1 MUX's is used to create
a 4:1 MUX. A 4:1 MUX has 4 input bits, a 2 bit select signal and one single
output bit. It can be implemented using three 2:1 MUX's as shown below:

Example

//Declare the ports of the module

module mux4to1(

Data_in_0,

Data_in_1,

Data_in_2,

Data_in_3,

sel,

Data_out );

//list the inputs and their sizes


input

Data_in_0;

input Data_in_1;

input Data_in_2;

input Data_in_3;

input [1:0] sel;

//list the outputs and their sizes

output Data_out;

//Instantiate the mux for selecting between input 0 or 1.

mux2to1 low_mux (

.Data_in_0(Data_in_0),

.Data_in_1(Data_in_1),

.sel(sel[0]),

//LSB of sel is connected here

.Data_out(Data_temp1)

); //Instantiate the mux for selecting between input 2 or 3.

mux2to1 high_mux (

.Data_in_0(Data_in_2),

.Data_in_1(Data_in_3),

.sel(sel[0]),

//LSB of sel is connected here

.Data_out(Data_temp2)
); //Instantiate the mux for selecting between low or high mux
output

mux2to1 last_mux (

.Data_in_0(Data_temp1),

.Data_in_1(Data_temp2),

.sel(sel[1]),

//MSB of sel is connected here

.Data_out(Data_out)

//The output of module is connected here.

);

endmodule

Testbench for 4:1 MUX

module tb_tm; // Inputs

reg Data_in_0;

reg Data_in_1;

reg Data_in_2;

reg Data_in_3;

reg [1:0] sel; // Outputs

wire Data_out; // Instantiate the Unit Under Test (UUT)

mux4to1 uut (

.Data_in_0(Data_in_0),

.Data_in_1(Data_in_1),

.Data_in_2(Data_in_2),
.Data_in_3(Data_in_3),

.sel(sel),

.Data_out(Data_out)

);

initial begin // Initialize Inputs

Data_in_0 = 0;

Data_in_1 = 0;

Data_in_2 = 0;

Data_in_3 = 0; sel = 0; #100;

Data_in_0 = 1; #100; Data_in_0 = 0; Data_in_1 = 1; #100;

sel = 1; #100;

Data_in_1 = 0; Data_in_2 = 1; #100;

sel = 2; #100;

Data_in_2 = 0; Data_in_3 = 1; #100; sel = 3; #100;

end

endmodule

Output
No. 8 – MUX (4:1)
Example
module mux4( select, d, q );

input[1:0] select;

input[3:0] d;

output q;

reg q;

wire[1:0] select;

wire[3:0] d;

always @( select or d )

begin

case( select )

0 : q = d[0];

1 : q = d[1];

2 : q = d[2];

3 : q = d[3];

endcase

end

endmodule
No. 9– 1 to 4 De-multiplexer

Example

module demux (s2,s1,I,en,y0,y1,y2,y3)

input s2,s1,I,en;

output y0,y1,y2,y3;

assign y0=(~s2)&(~s1)& I& en;

assign y1=(~s2)& s1& I& en;


assign y2=s2&(~s1)& I & en;

assign y3=s2& s1 & I & en;

end module

No. 10 – 1:4 Demux using Case statements


Example
Demultiplexer(Also known as Demux) is a data distributer, which is
basically the exact opposite of a multiplexer. A Demux can have one single
bit data input and a N-bit select line. The number of output lines will be
2^N.Here is the Verilog code for a 1:4 Demux. The code is designed using
behavioral modelling and implemented using Case statements.

//Verilog module for 1:4 DEMUX

module demux1to4(

Data_in, sel, Data_out_0, Data_out_1, Data_out_2, Data_out


_3

); //list the inputs and their sizes

input Data_in; input [1:0] sel;

//list the outputs and their sizes

output Data_out_0; output Data_out_1; output Data_out_2; output


Data_out_3;

//Internal variables

reg Data_out_0; reg Data_out_1; reg Data_out_2; reg Data_out_3;

//always block with Data_in and sel in its sensitivity list

always @(Data_in or sel)


begin

case (sel)

//case statement with "sel"

//multiple statements can be written inside each case.

//you just have to use 'begin' and 'end' keywords as shown below.

2'b00 : begin Data_out_0 = Data_in; Data_ou


t_1 = 0; Data_out_2 = 0; Data_out_3 = 0;

end

2'b01 : begin Data_out_0 = 0; Data_out_1 =


Data_in; Data_out_2 = 0; Data_out_3 = 0;

end

2'b10 : begin Data_out_0 = 0; Data_out_1 =


0; Data_out_2 = Data_in; Data_out_3 = 0;

end

2'b11 : begin Data_out_0 = 0; Data_out_1 =


0;

Data_out_2 = 0;

Data_out_3 = Data_in;

end

endcase

end

endmodule

Simulation Test Fixture


module tb_demux;

// Inputs

reg Data_in;

reg [1:0] sel;

// Outputs

wire Data_out_0;

wire Data_out_1;

wire Data_out_2;

wire Data_out_3;

// Instantiate the Unit Under Test (UUT)

demux1to4 uut (

.Data_in(Data_in),

.sel(sel),

.Data_out_0(Data_out_0),

.Data_out_1(Data_out_1),

.Data_out_2(Data_out_2),

.Data_out_3(Data_out_3)

);

initial begin

//Apply Inputs

Data_in = 1; sel = 0; #100; sel = 1; #100;

sel = 2; #100; sel = 3; #100; Data_in = 0;

end
endmodule

Output

Figure: The simulated waveform is generate Xilinx ISE 13.1

No. 11 – Half Adder (HA)

Example

module halfadder(

input wire a,

input wire b,

output wire c,

output wire s

);

assign s = b^ a;

assign c= b & a;
endmodule

No. 12 – Full Adder: Structural Design using Half Adder


and OR Gate.

Example
No. 13 – Ripple Carry Adder using Structural Level
Ripple carry adder(RCA) is the most basic form of digital adder for adding
multi bit numbers. The adder is implemented by concatenating N full-
adders to form a N-bit adder. For a 4 bit RCA, the block diagram can be
drawn like

this:

The full adder and half adder modules written in a previous post to
implement RCA. The coding is done in structural modelling.
The code size can be much smaller and compact looking, while using
behavioral modelling.

Example
//Verilog module for Ripple Carry Adder

module RC_adder( A, B, C_in, Sum_out, C_out);

//What are the Inputs?

input [3:0] A; input [3:0] B; input C_in;

//What are the Outputs?

output [3:0] Sum_out; output C_out;

//Internal variables.

wire [3:0] Sum; wire [3:0] Carry; wire [3:0] Sum_out; wire C_out;

//Instantiate Full Adder 1

full_adder fa1(

.Data_in_A (A[0]), .Data_in_B (B[0]), .Data_in_C (C_in), .Data


_out_Sum (Sum[0]), .Data_out_Carry (Carry[0])

);

//Instantiate Full Adder 2

full_adder
fa2( .Data_in_A (A[1]), .Data_in_B (B[1]), .Data_in_C (Carry[0]),
.Data_out_Sum (Sum[1]), .Data_out_Carry (Carry[1])

);

//Instantiate Full Adder 3

full_adder
fa3( .Data_in_A (A[2]), .Data_in_B (B[2]), .Data_in_C (Carry[1]),
.Data_out_Sum (Sum[2]), .Data_out_Carry (Carry[2])

);
//Instantiate Full Adder 4

full_adder
fa4( .Data_in_A (A[3]), .Data_in_B (B[3]), .Data_in_C (Carry[2]),
.Data_out_Sum (Sum[3]), .Data_out_Carry (Carry[3])

);

//Assign the final outputs.

assign Sum_out = Sum;

assign C_out = Carry[3];

endmodule

Simulation Test Fixture


module tb_RCA; // Inputs

reg [3:0] A; reg [3:0] B; reg C_in;

// Outputs

wire [3:0] Sum_out; wire C_out;

// Instantiate the Unit Under Test (UUT)

RC_adder uut (

.A(A), .B(B), .C_in(C_in), .Sum_out(Sum_out), .C_o


ut(C_out)

);

initial begin //Apply Inputs

A = 3; B = 6; C_in = 0; #100;

A = 5; B = 7; C_in = 1; #100;

A = 6; B = 4; C_in = 0; #100;

A = 8; B = 9; C_in = 1; #100;
A = 11; B = 10; C_in = 0; #100;

A = 13; B = 11; C_in = 1; #100;

A = 15; B = 3; C_in = 0; #100;

A = 0; B = 0; C_in = 1; #100;

end

endmodule

Output: Waveform

No. 14 – Encoder (if - else)


Example
module encoder_using_if(

binary_out , // 4 bit binary output

encoder_in , // 16-bit input

enable // Enable for the encoder

);

//-----------Output Ports---------------

output [3:0] binary_out ;

//-----------Input Ports---------------

input enable ;

input [15:0] encoder_in ;

//------------Internal Variables--------

reg [3:0] binary_out ;


//-------------Code Start-----------------

always @ (enable or encoder_in)

begin

binary_out = 0;

if (enable) begin

if (encoder_in == 16'h0002) begin

binary_out = 1;

end if (encoder_in == 16'h0004) begin

binary_out = 2;

end if (encoder_in == 16'h0008) begin

binary_out = 3;

end if (encoder_in == 16'h0010) begin

binary_out = 4;

end if (encoder_in == 16'h0020) begin

binary_out = 5;

end if (encoder_in == 16'h0040) begin

binary_out = 6;

end if (encoder_in == 16'h0080) begin

binary_out = 7;

end if (encoder_in == 16'h0100) begin

binary_out = 8;

end if (encoder_in == 16'h0200) begin

binary_out = 9;
end if (encoder_in == 16'h0400) begin

binary_out = 10;

end if (encoder_in == 16'h0800) begin

binary_out = 11;

end if (encoder_in == 16'h1000) begin

binary_out = 12;

end if (encoder_in == 16'h2000) begin

binary_out = 13;

end if (encoder_in == 16'h4000) begin

binary_out = 14;

end if (encoder_in == 16'h8000) begin

binary_out = 15;

end

end

end

endmodule

No. 10 – Encoder (Using Case)


Example
module encoder_using_case(

binary_out , // 4 bit binary Output

encoder_in , // 16-bit Input


enable // Enable for the encoder

);

output [3:0] binary_out ;

input enable ;

input [15:0] encoder_in ;

reg [3:0] binary_out ;

always @ (enable or encoder_in)

begin

binary_out = 0;

if (enable) begin

case (encoder_in)

16'h0002 : binary_out = 1;

16'h0004 : binary_out = 2;

16'h0008 : binary_out = 3;

16'h0010 : binary_out = 4;

16'h0020 : binary_out = 5;

16'h0040 : binary_out = 6;

16'h0080 : binary_out = 7;

16'h0100 : binary_out = 8;

16'h0200 : binary_out = 9;

16'h0400 : binary_out = 10;


16'h0800 : binary_out = 11;

16'h1000 : binary_out = 12;

16'h2000 : binary_out = 13;

16'h4000 : binary_out = 14;

16'h8000 : binary_out = 15;

endcase

end

end

endmodule

No. 10 – Decoder (Case Statement)


Example
module decoder_using_case (

binary_in , // 4 bit binary input

decoder_out , // 16-bit out

enable // Enable for the decoder

);

input [3:0] binary_in ;

input enable ;

output [15:0] decoder_out ;

reg [15:0] decoder_out ;

always @ (enable or binary_in)

begin

decoder_out = 0;
if (enable) begin

case (binary_in)

4'h0 : decoder_out = 16'h0001;

4'h1 : decoder_out = 16'h0002;

4'h2 : decoder_out = 16'h0004;

4'h3 : decoder_out = 16'h0008;

4'h4 : decoder_out = 16'h0010;

4'h5 : decoder_out = 16'h0020;

4'h6 : decoder_out = 16'h0040;

4'h7 : decoder_out = 16'h0080;

4'h8 : decoder_out = 16'h0100;

4'h9 : decoder_out = 16'h0200;

4'hA : decoder_out = 16'h0400;

4'hB : decoder_out = 16'h0800;

4'hC : decoder_out = 16'h1000;

4'hD : decoder_out = 16'h2000;

4'hE : decoder_out = 16'h4000;

4'hF : decoder_out = 16'h8000;

endcase

end

end

endmodule
No. 12 – MUX (4:1)
Example
<Illustrative short example using the syntax goes here> <make code font –
courier new>

module mux4( select, d, q );

input[1:0] select;

input[3:0] d;

output q;

reg q;

wire[1:0] select;

wire[3:0] d;

always @( select or d )

begin

case( select )

0 : q = d[0];

1 : q = d[1];

2 : q = d[2];

3 : q = d[3];

endcase

end
endmodule

No. 1 – 4 bit comparator


A simple comparator with two 4 bit inputs and three output bits which says,
whether one of the input is less, greater or equal to the second input.

Example
//declare the Verilog module - The inputs and output signals.

module comparator(

Data_in_A, //input A

Data_in_B, //input B

less, //high when A is less than B

equal, //high when A is equal to B

greater //high when A is greater than B

);

//what are the input ports.

input [3:0] Data_in_A;

input [3:0] Data_in_B;

//What are the output ports.

output less;

output equal;

output greater;

//Internal variables
reg less;

reg equal;

reg greater;

//When the inputs and A or B are changed execute this block

always @(Data_in_A or Data_in_B)

begin

if(Data_in_A > Data_in_B) begin //check if A is bigger than B.

less = 0;

equal = 0;

greater = 1; end

else if(Data_in_A == Data_in_B) begin //Check if A is equal to B

less = 0;

equal = 1;

greater = 0; end

else begin //Otherwise - check for A less than B.

less = 1;

equal = 0;

greater =0;

end

end

endmodule
Testbench for Comparator:

module tb_tm;

// Inputs

reg [3:0] Data_in_A;

reg [3:0] Data_in_B;

// Outputs

wire less;

wire equal;

wire greater;

// Instantiate the Unit Under Test (UUT)

comparator uut (

.Data_in_A(Data_in_A),

.Data_in_B(Data_in_B),

.less(less),

.equal(equal),

.greater(greater)

);

initial begin
//Apply inputs

Data_in_A = 10;

Data_in_B = 12;

#100;

Data_in_A = 15;

Data_in_B = 11;

#100;

Data_in_A = 10;

Data_in_B = 10;

#100;

end

endmodule

Output

No. 8 – ALU
ALU(Arithmetic Logic Unit) is a digital circuit which does arithmetic and
logical operations. Its a basic block in any processor. Note that this is one
of the simplest architecture of an ALU. Most of the ALU's used in practical
designs are far more complicated and requires good design experience.
The block diagram of the ALU is given below.It receives two input operands
'A' and 'B' which are 8 bits long. The result is denoted by 'R' which is also 8
bit long. The input signal 'Op' is a 3 bit value which tells the ALU what
operation has to be performed by the ALU. Since 'Op' is 3 bits long we can
have a maximum of 2^3=8 operations.

Our ALU is capable of doing the following operations:

These functions are implemented using a case statement. The ALU


calculates the outputs, whenever there is a change in the input operands A
or B or in the operation to be performed Op . As soon as the outputs are
calculated it is available at the port signal 'R'.

Example
//Verilog module for an ALU

module ALU(

A, B, Op, R

); //inputs,outputs and internal variables declared here

input [7:0] A,B;

input [2:0] Op;

output [7:0] R;

wire [7:0] Reg1,Reg2;

reg [7:0] Reg3;

//Assign A and B to internal variables for doing operations

assign Reg1 = A;

assign Reg2 = B; //Assign the output

assign R = Reg3;

//Always block with inputs in the sensitivity list.

always @(Op or Reg1 or Reg2)

begin

case (Op)

0 : Reg3 = Reg1 + Reg2; //addition

1 : Reg3 = Reg1 - Reg2; //subtraction


2 : Reg3 = ~Reg1; //NOT gate

3 : Reg3 = ~(Reg1 & Reg2); //NAND gate

4 : Reg3 = ~(Reg1 | Reg2); //NOR gate

5 : Reg3 = Reg1 & Reg2; //AND gate

6 : Reg3 = Reg1 | Reg2; //OR gate

7 : Reg3 = Reg1 ^ Reg2; //XOR gate

endcase

end

endmodule

Simulation test Fixture


module tb_alu; // Inputs

reg [7:0] A;

reg [7:0] B;

reg [2:0] Op;

// Outputs

wire [7:0] R;

// Instantiate the Unit Under Test (UUT)

ALU uut (

.A(A), .B(B), .Op(Op), .R(R)

);

initial begin // Apply inputs.

A = 8'b01101010;

B = 8'b00111011;
Op = 0; #100;

Op = 1; #100;

Op = 2; #100;

Op = 3; #100;

Op = 4; #100;

Op = 5; #100;

Op = 6; #100;

Op = 7; #100;

end

endmodule

Output

No. 9 – Syntax Name


Example
<Illustrative short example using the syntax goes here> <make code font –
courier new>

Output
<Output of the above example goes here>

Remarks
<Add comments on the implementation of the above syntax if any>

Reference
No. 11 – Flip Flops

Example

module dflipflop(

input clk,

input d,

output req q

);

always @ (posedge clk)

Q<= d;

endmodule

Simulation
Reference
ECE UMD EDU

ece-research unm edu /jimp

No. 14 – T Flip Flops (Asynchronous reset)


Example
module tff_async_reset (

data , // Data Input

clk , // Clock Input

reset , // Reset input

q // Q output

);

//-----------Input Ports---------------
input data, clk, reset ;

//-----------Output Ports---------------

output q;

//------------Internal Variables--------

reg q;

//-------------Code Starts Here---------

###p

if (~reset) begin

q <= 1'b0;

end else if (data) begin

q <= !q;

end

endmodule //End Of Module tff_async_reset

No. 13 – T Flip Flops (Synchronous reset)


Example
module tff_sync_reset (

data , // Data Input

clk , // Clock Input

reset , // Reset input

q // Q output

);
//-----------Input Ports---------------

input data, clk, reset ;

//-----------Output Ports---------------

output q;

//------------Internal Variables--------

reg q;

//-------------Code Starts Here---------

always @ ( posedge clk)

if (~reset) begin

q <= 1'b0;

end else if (data) begin

q <= !q;

end

endmodule //End Of Module tff_async_reset

No. 14 – JK Flip-flops
In here the Verilog code for a JK flip flop with synchronous reset,set and
clock enable. The particular flip flop is designed at Xilinx ISE DS and is
called by the name, FJKRSE.
From the truth table, we can see that reset(R) has the highest priority and
set(S) the next priority, then the clock enable (CE) and then the J or K
inputs.

Example
//JK flip flop module

module FJKRSE(J,K,Clk,R,S,CE,Qout);

input J,K; //inputs

input Clk; //Clock

input R; //synchronous reset (R)

input S; //synchronous set (S)

input CE; //clock enable (CE)

output Qout; //data output (Q)

//Internal variable

reg Qout;

always@ (posedge(Clk)) //Everything is synchronous to positive edge of


clock

begin

if(R == 1) //reset has highest priority.

Qout = 0;

else

if(S == 1) //set has next priority

Qout = 1;

else

if(CE == 1) //J,K values are considered only when CE is ON.


if(J == 0 && K == 0)

Qout = Qout; //no change

else

if(J == 0 && K == 1)

Qout = 0; //reset

else

if(J == 1 && K == 0)

Qout = 1; //set

else

Qout = ~Qout; //toggle

else

Qout = Qout; //no change

end

endmodule

Simulation Test fixture


module tb_jkff; // Inputs

reg J;

reg K;

reg Clk;

reg R;

reg S;

reg CE; // Outputs

wire Qout; // Instantiate the Unit Under Test (UUT)


FJKRSE uut (

.J(J), .K(K), .Clk(Clk), .R(R), .S(S), .CE(CE),


.Qout(Qout)

); //Create 50 Mhz clock(20 ns clock period).

initial Clk = 0;

always

#10 Clk = ~Clk;

initial begin

// Initialize Inputs

J = 0;

K = 0;

R = 0;

S = 0;

CE = 0;

#30;

//Apply inputs

R = 1; #50;

R = 0;

S = 1; #50;

S = 0;

J = 1; K = 1; #50;

CE = 1; #50;

J = 0; K = 0; #50;
J = 0; K = 1; #50;

J = 1; K = 0; #50;

J = 1; K = 1; #50;

CE = 0;

end

endmodule

Output: Simulation Waveform


The codes were simulated in Xilinx ISE 13.1 and we got the following
waveform.

Note how the outputs are changed only at the positive edge of the clock.
Also note how the priority of reset,set and clock enable works,

No. 15 – Digital Clock


The module has two inputs - A Clock at 1 Hz frequency and an active high
reset. There are three outputs to tell the time - seconds,minutes and hours.
The time units are incremented in an always block using Behavioral
modelling. At every clock cycle we increment 'seconds'.Whenever seconds
reaches the value '60' we increment 'minutes' by 1.Similarly whenever
minutes reach '60' we increment 'hours' by 1.Once hours reaches the value
'23' we reset the digital clock.

Example
module Digital_Clock(
Clk_1sec, //Clock with 1 Hz frequency

reset, //active high reset

seconds, minutes, hours

); //What are the Inputs?

input Clk_1sec; input reset;

//What are the Outputs?

output [5:0] seconds; output [5:0] minutes; output [4:0] hours;

//Internal variables.

reg [5:0] seconds; reg [5:0] minutes; reg [4:0] hours;

//Execute the always blocks when the Clock or reset inputs are

//changing from 0 to 1(positive edge of the


signal) always @(posedge(Clk_1sec) or posedge(reset))

begin

if(reset == 1'b1)

begin //check for active high reset.

//reset the time.

seconds = 0; minutes = 0; hours = 0;

end

else if(Clk_1sec == 1'b1)

begin //at the beginning of each second

seconds = seconds + 1;

//increment sec

if(seconds == 60)
begin //check for max value of sec

seconds = 0; //reset seconds

minutes = minutes + 1;

//increment minutes

if(minutes == 60)

begin //check for max value of min

minutes = 0; //reset minutes

hours = hours + 1; //increment hours

if(hours == 24) begin //check for max value of hours

hours = 0; //reset hours

end

end

end

end

end

endmodule

Simulation Test fixture


module tb_clock; // Inputs

reg Clk_1sec;

reg reset; // Outputs

wire [5:0] seconds;

wire [5:0] minutes;

wire [4:0] hours; // Instantiate the Unit Under Test (UUT)


Digital_Clock uut (

.Clk_1sec(Clk_1sec), .reset(reset), .seconds(seconds), .m


inutes(minutes), .hours(hours)

);

//Generating the Clock with `1 Hz frequency

initial Clk_1sec = 0;

always

#50000000

Clk_1sec = ~Clk_1sec;

//Every 0.5 sec toggle the clock.

initial begin

reset = 1;

// Wait 100 ns for global reset to finish

#100;

reset = 0;

end

endmodule

Output
Reference
 Verilog Codes

No. 16– 4-Bit Binary Counter


Counter includes reset and enable, it counts from the binary "0000" to
"1111" i.e from decimal 0 to 15. Binary Coded Decimal (BCD) counter
counts from 0000 to 1111.

Example
module upcount(Resetn, Clock, E, Q);

input Resetn, Clock, E;

output [3:0] Q;

reg [3:0] Q;

always @(negedge Resetn or posedge Clock)

if (!Resetn)

Q <= 0; // asynchronous reset overrides enable

else if (E)

Q <= Q + 1; // synthesizes adder circuit

endmodule
Simulation

No. 17 – 8-Bit Simple Up Counter


Example
module up_counter (

out , // Output of the counter

enable , // enable for counter

clk , // clock Input

reset // reset Input

);

//----------Output Ports--------------

output [7:0] out;

//------------Input Ports--------------

input enable, clk, reset;

//------------Internal Variables--------

reg [7:0] out;

//-------------Code Starts Here-------

always @(posedge clk)


if (reset) begin

out <= 8'b0 ;

end else if (enable) begin

out <= out + 1;

end

endmodule

Output
No. 18 – 8-Bit Up-Down Counter
Example
module up_down_counter (

out , // Output of the counter

up_down , // up_down control for counter

clk , // clock input

reset // reset input

);

//----------Output Ports--------------

output [7:0] out;

//------------Input Ports--------------

input [7:0] data;

input up_down, clk, reset;

//------------Internal Variables--------
reg [7:0] out;

//-------------Code Starts Here-------

always @(posedge clk)

if (reset) begin // active high reset

out <= 8'b0 ;

end else if (up_down) begin

out <= out + 1;

end else begin

out <= out - 1;

end

endmodule

Output

No. 19– Shift Register


• 4-bit with Parallel Load

• Shift left and shift right

Example

module shift_reg (

input clk,

input load,

input left_right_n,
input [3:0] d,

output [3:0] q

);

always @ (posedge clk) //all operations synchronous

if(load)

q<=d; //sync load

else if (left_right_n)

q<= { q[2:0], 1’b0}; //shift left

else

q<=q>>1; //shift right

endmodule

Simulation

No. 20 – Single Port RAM Synchronous Read/Write


Example
module ram_sp_sr_sw (

clk , // Clock Input

address , // Address Input


data , // Data bi-directional

cs , // Chip Select

we , // Write Enable/Read Enable

oe // Output Enable

);

parameter DATA_WIDTH = 8 ;

parameter ADDR_WIDTH = 8 ;

parameter RAM_DEPTH = 1 << ADDR_WIDTH;

//--------------Input Ports-----------------------

input clk ;

input [ADDR_WIDTH-1:0] address ;

input cs ;

input we ;

input oe ;

//--------------Inout Ports-----------------------

inout [DATA_WIDTH-1:0] data ;

//--------------Internal variables----------------

reg [DATA_WIDTH-1:0] data_out ;

reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];


reg oe_r;

//--------------Code Starts Here------------------

// Tri-State Buffer control

// output : When we = 0, oe = 1, cs = 1

assign data = (cs && oe && !we) ? data_out : 8'bz;

// Memory Write Block

// Write Operation : When we = 1, cs = 1

always @ (posedge clk)

begin : MEM_WRITE

if ( cs && we ) begin

mem[address] = data;

end

end

// Memory Read Block

// Read Operation : When we = 0, oe = 1, cs = 1

always @ (posedge clk)

begin : MEM_READ

if (cs && !we && oe) begin

data_out = mem[address];
oe_r = 1;

end else begin

oe_r = 0;

end

end

endmodule // End of Module ram_sp_sr_sw

Output
Reference
Verilog Guru, Verilog Codes, FPGA4student

No. 21 – Synchronous FIFO


Example
module syn_fifo (

clk , // Clock input

rst , // Active high reset

wr_cs , // Write chip select

rd_cs , // Read chipe select

data_in , // Data input

rd_en , // Read enable

wr_en , // Write Enable

data_out , // Data Output

empty , // FIFO empty

full // FIFO full


);

// FIFO constants

parameter DATA_WIDTH = 8;

parameter ADDR_WIDTH = 8;

parameter RAM_DEPTH = (1 << ADDR_WIDTH);

// Port Declarations

input clk ;

input rst ;

input wr_cs ;

input rd_cs ;

input rd_en ;

input wr_en ;

input [DATA_WIDTH-1:0] data_in ;

output full ;

output empty ;

output [DATA_WIDTH-1:0] data_out ;

//-----------Internal variables-------------------

reg [ADDR_WIDTH-1:0] wr_pointer;

reg [ADDR_WIDTH-1:0] rd_pointer;

reg [ADDR_WIDTH :0] status_cnt;

reg [DATA_WIDTH-1:0] data_out ;


wire [DATA_WIDTH-1:0] data_ram ;

//-----------Variable assignments---------------

assign full = (status_cnt == (RAM_DEPTH-1));

assign empty = (status_cnt == 0);

//-----------Code Start---------------------------

always @ (posedge clk or posedge rst)

begin : WRITE_POINTER

if (rst) begin

wr_pointer <= 0;

end else if (wr_cs && wr_en ) begin

wr_pointer <= wr_pointer + 1;

end

end

always @ (posedge clk or posedge rst)

begin : READ_POINTER

if (rst) begin

rd_pointer <= 0;

end else if (rd_cs && rd_en ) begin

rd_pointer <= rd_pointer + 1;

end
end

always @ (posedge clk or posedge rst)

begin : READ_DATA

if (rst) begin

data_out <= 0;

end else if (rd_cs && rd_en ) begin

data_out <= data_ram;

end

end

always @ (posedge clk or posedge rst)

begin : STATUS_COUNTER

if (rst) begin

status_cnt <= 0;

// Read but no write.

end else if ((rd_cs && rd_en) && !(wr_cs && wr_en)

&& (status_cnt != 0)) begin

status_cnt <= status_cnt - 1;

// Write but no read.

end else if ((wr_cs && wr_en) && !(rd_cs && rd_en)

&& (status_cnt != RAM_DEPTH)) begin

status_cnt <= status_cnt + 1;


end

end

ram_dp_ar_aw #(DATA_WIDTH,ADDR_WIDTH)DP_RAM (

.address_0 (wr_pointer) , // address_0 input

.data_0 (data_in) , // data_0 bi-directional

.cs_0 (wr_cs) , // chip select

.we_0 (wr_en) , // write enable

.oe_0 (1'b0) , // output enable

.address_1 (rd_pointer) , // address_q input

.data_1 (data_ram) , // data_1 bi-directional

.cs_1 (rd_cs) , // chip select

.we_1 (1'b0) , // Read enable

.oe_1 (rd_en) // output enable

);

endmodule

Output

No. 22 – Content Addressable Memory (CAM)


Example
module cam (
clk , // Cam clock

cam_enable , // Cam enable

cam_data_in , // Cam data to match

cam_hit_out , // Cam match has happened

cam_addr_out // Cam output address

);

parameter ADDR_WIDTH = 8;

parameter DEPTH = 1 << ADDR_WIDTH;

//------------Input Ports--------------

input clk;

input cam_enable;

input [DEPTH-1:0] cam_data_in;

//----------Output Ports--------------

output cam_hit_out;

output [ADDR_WIDTH-1:0] cam_addr_out;

//------------Internal Variables--------

reg [ADDR_WIDTH-1:0] cam_addr_out;

reg cam_hit_out;

reg [ADDR_WIDTH-1:0] cam_addr_combo;

reg cam_hit_combo;

reg found_match;

integer i;
//-------------Code Starts Here-------

always @(cam_data_in) begin

cam_addr_combo = {ADDR_WIDTH{1'b0}};

found_match = 1'b0;

cam_hit_combo = 1'b0;

for (i=0; i<DEPTH; i=i+1) begin

if (cam_data_in[i] && !found_match) begin

found_match = 1'b1;

cam_hit_combo = 1'b1;

cam_addr_combo = i;

end else begin

found_match = found_match;

cam_hit_combo = cam_hit_combo;

cam_addr_combo = cam_addr_combo;

end

end

end

// Register the outputs

always @(posedge clk) begin

if (cam_enable) begin

cam_hit_out <= cam_hit_combo;

cam_addr_out <= cam_addr_combo;


end else begin

cam_hit_out <= 1'b0;

cam_addr_out <= {ADDR_WIDTH{1'b0}};

end

end

endmodule

Output

No. 23 – Finite State Machine (FSM) Design


Example
<Illustrative short example using the syntax goes here> <make code font –
courier new>

module jk_counter(count, clock);

input clock;

output [2:0] count;

reg [2:0] count;

parameter [2:0] A = 3'b000, B = 3'b100, C = 3'b111,

D = 3'b010, E = 3'b011;

###p

case(count)

A: count <= B;

B: count <= C;
C: count <= D;

D: count <= E;

E: count <= A;

default: count <= A;

endcase

endmodule

Output
<Output of the above example goes here>

Simulation

No. 24 – Modeling With Switch Primitives (Not Gate using


switch)
Example
module not_switch (out, in);

output out;

input in;

supply1 power;

supply0 ground;
pmos (out, power, in);

nmos (out, ground, in);

endmodule

No. 25 – User Defined Primitives (Two Input OR using


UDP)
Example
primitive or2_input (c,a,b);

output c;

input a,b;

table

//a b : c

1 ? : 1;

? 1 : 1;

0 0 : 0;

0 x : x;

x 0 : x;

endtable

endprimitive

Looping Structures in Verilog


No. 26 – Synthesisable Verilog code for Division of two
binary numbers
For doing division, Verilog has an operator, '/' defined. But this operator has
some limitation when it comes to certain synthesis tools such as Xilinx
XST. The '/' operator is synthesisable only when the second operand is a
power of 2.

For division of generic numbers Xilinx returns the following error message
during synthesis:

Can not simplify operator DIV

The design was based on Restoring Division algorithm.

Example
The size of operands to the division module are defined through a
parameter named WIDTH. This way you can use the same code for
implementing 8 or 16 or 32 or any sized division. Note that, both the input
operands and output have the same size.

module division(A,B,Res);

//the size of input and output ports of the division module is generic.

parameter WIDTH = 8;

//input and output ports.

input [WIDTH-1:0] A;

input [WIDTH-1:0] B; output [WIDTH-1:0] Res;

//internal variables

reg [WIDTH-1:0] Res = 0; reg [WIDTH-


1:0] a1,b1; reg [WIDTH:0] p1; integer i; always@ (A or B)

begin

//initialize the variables.


a1 = A; b1 = B; p1= 0;

for(i=0;i < WIDTH;i=i+1)

begin //start the for loop

p1 = {p1[WIDTH-2:0],a1[WIDTH-1]};

a1[WIDTH-1:1] = a1[WIDTH-2:0];

p1 = p1-b1;

if(p1[WIDTH-1] == 1)

begin

a1[0] = 0;

p1 = p1 + b1;

end

else

a1[0] = 1;

end

Res = a1;

end

endmodule

Testbench
module tb_division;

parameter WIDTH = 8;

// Inputs

reg [WIDTH-1:0] A;

reg [WIDTH-1:0] B;
// Outputs

wire [WIDTH-1:0] Res;

// Instantiate the division module (UUT)

division #(WIDTH)

uut (

.A(A), .B(B), .Res(Res)

);

initial begin

// Initialize Inputs and wait for 100 ns

A = 0; B = 0; #100;

//Undefined inputs

//Apply each set of inputs and wait for 100 ns.

A = 100; B = 10; #100;

A = 200; B = 40; #100;

A = 90; B = 9; #100;

A = 70; B = 10; #100;

A = 16; B = 3; #100;

A = 255; B = 5; #100;

end

endmodule

Output
Remarks
The design was synthesised for Virtex 4 fpga and a maximum
combinational path delay of 20 ns was obtained for 8 bit division.

No. 27 – Verilog code for 4 bit Wallace tree multiplier


A Wallace tree multiplier is much faster than the normal multiplier designs.
The design uses half adder and full adder Verilog designs . These modules
will be instantiated for the implementation 4 bit Wallace multiplier.

Example
module wallace(A,B,prod);

//inputs and outputs

input [3:0] A,B; output [7:0] prod;

//internal variables.

wire s11,s12,s13,s14,s15,s22,s23,s24,s25,s26,s32,s33,s34,s35,s36,s37;
wire c11,c12,c13,c14,c15,c22,c23,c24,c25,c26,c32,c33,c34,c35,c36,c37;
wire [6:0] p0,p1,p2,p3;

//initialize the p's.

assign p0 = A & {4{B[0]}}; assign p1 = A & {4{B[1]}}; assign p2 = A


& {4{B[2]}};

assign p3 = A & {4{B[3]}};

//final product assignments

assign prod[0] = p0[0]; assign prod[1] = s11; assign prod[2] = s22;


assign prod[3] = s32; assign prod[4] = s34; assign prod[5] = s35;
assign prod[6] = s36; assign prod[7] = s37; //first stage

half_adder ha11 (p0[1],p1[0],s11,c11);


full_adder fa12(p0[2],p1[1],p2[0],s12,c12);

full_adder fa13(p0[3],p1[2],p2[1],s13,c13);

full_adder fa14(p1[3],p2[2],p3[1],s14,c14);

half_adder ha15(p2[3],p3[2],s15,c15);

//second stage

half_adder ha22 (c11,s12,s22,c22);

full_adder fa23 (p3[0],c12,s13,s23,c23);

full_adder fa24 (c13,c32,s14,s24,c24);

full_adder fa25 (c14,c24,s15,s25,c25);

full_adder fa26 (c15,c25,p3[3],s26,c26);

//third stage

half_adder ha32(c22,s23,s32,c32);

half_adder ha34(c23,s24,s34,c34);

half_adder ha35(c34,s25,s35,c35);

half_adder ha36(c35,s26,s36,c36);

half_adder ha37(c36,c26,s37,c37);

endmodule

Simulation Testbench
module tb;

// Inputs

reg [3:0] A; reg [3:0] B;

// Outputs

wire [7:0] prod;


integer i,j,error;

// Instantiate the Unit Under Test (UUT)

wallace uut (

.A(A), .B(B), .prod(prod)

);

initial begin

// Apply inputs for the whole range of A and B.

// 16*16 = 256 inputs.

error = 0;

for(i=0;i <=15;i = i+1)

for(j=0;j <=15;j = j+1)

begin

A <= i;

B <= j;

#1;

if(prod != A*B)

//if the result isnt correct increment "error".

error = error + 1;

end

end

endmodule

Output
No. 28 – simple Sine Wave Generator
The design uses look up table(LUT) method for generating the sine wave.
The sine wave is sampled at a pre-fixed sample rate and the values are
stored in a ROM. These values are read one by one and output to a
DAC(digital to analog converter) which is not included the DAC interface
code here.

In this particular design the sampled and stored 30 values of a sine wave.
Fort a much more smoother sine wave, sample and store more values in
the ROM at the cost of extra fpga resources.

To get the sample values following commands can be used in Matlab.

t=0 : pi/10 : 2*pi ; % for 20 values. t=0 : pi/50 : 2*pi ; % for 100 values etc..
(then type one of the following comment - to convert 't' into integer
format) int32(sin(t)*10000/128) %128 for 8 bit
output. int32(sin(t)*10000/512) %512 for 6 bit output etc...

The design can be modified for efficient use of memory. In that way, only
the first (pi/2) values need to be stored in the ROM. That means the
memory usage is reduced by a factor of 4.

If the frequency of your sine wave is very less, then it is better you increase
the number of sample values. Otherwise there will be lot of high frequency
components in your output wave.

Example
module sine_wave_gen(Clk,data_out);

//declare input and output

input Clk; output [7:0] data_out;

//declare the sine ROM - 30 registers each 8 bit wide.

reg [7:0] sine [0:29];


//Internal signals

integer i; reg [7:0] data_out;

//Initialize the sine rom with samples.

initial begin i = 0; sine[0] = 0; sine[1] = 16; sine[2] = 31


; sine[3] = 45; sine[4] = 58; sine[5] = 67; sine[6] = 74;
sine[7] = 77; sine[8] = 77; sine[9] = 74; sine[10] = 67;
sine[11] = 58; sine[12] = 45; sine[13] = 31; sine[14] = 16;
sine[15] = 0; sine[16] = -16; sine[17] = -31; sine[18] = -
45; sine[19] = -58; sine[20] = -67; sine[21] = -
74; sine[22] = -77; sine[23] = -77; sine[24] = -
74; sine[25] = -67; sine[26] = -58; sine[27] = -
45; sine[28] = -31; sine[29] = -16;

end

//At every positive edge of the clock, output a sine wave sample.

always@ (posedge(Clk))

begin

data_out = sine[i];

i = i+ 1;

if(i == 29)

i = 0;

end endmodule

Testbench Code:
module tb;

// Inputs

reg Clk;

// Outputs

wire [7:0] data_out;


// Instantiate the Unit Under Test (UUT)

sine_wave_gen uut (

.Clk(Clk), .data_out(data_out)

);

//Generate a clock with 10 ns clock period.

initial Clk = 0;

always

#5

Clk = ~Clk;

endmodule

Output

You might also like