0% found this document useful (0 votes)
14 views16 pages

Verilog

The document provides various examples of Verilog HDL code for digital circuits, including Half Adders, Full Adders, Four-bit Adders, and multiplexers. It explains both structural and behavioral descriptions of circuits, highlighting the differences between wire and reg types. Additionally, it covers conditional assignments, loops, and the use of initial values in modules, demonstrating how to implement logical expressions and arithmetic operations in Verilog.

Uploaded by

kalesh167.uu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views16 pages

Verilog

The document provides various examples of Verilog HDL code for digital circuits, including Half Adders, Full Adders, Four-bit Adders, and multiplexers. It explains both structural and behavioral descriptions of circuits, highlighting the differences between wire and reg types. Additionally, it covers conditional assignments, loops, and the use of initial values in modules, demonstrating how to implement logical expressions and arithmetic operations in Verilog.

Uploaded by

kalesh167.uu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

Verilog HDL through Examples

Half Adder
// Code of a Half Adder circuit

module HalfAdder1 (input a, input b, output s, output co);


assign s = a&(~b) | (~a)&b;
assign co = a&b;
endmodule
Note the Operators:
AND OR NOT XOR ADD SUBTRACT MULTIPLY
& | ~ ^ + - *

// Another way to code a Half Adder circuit

module HalfAdder (input a, input b, output s, output co);


assign s = a ^ b;
assign co = a & b;
endmodule
// Another way to code a Half Adder circuit

module HalfAdder (input a, input b, output s, output co);


xor(s, a, b);
and(co, a, b);
endmodule

// A sophisticated way to code a Half Adder circuit

module HalfAdder4 (input a, input b, output s, output co);


assign {co, s} = a + b;
endmodule
Leave it to the computer to figure out the logical circuit
Full Adder
// Code of a Full Adder circuit using 2 Half Adder circuits

module FullAdder (input A, input B, input Ci, output S, output Co);


wire co1, co2, s1;
HalfAdder ha1 (.a(A), .b(B), .s(s1), .co(co1));
HalfAdder ha2 (.a(s1), .b(Ci), .s(S), .co(co2));
assign Co = co1 | co2;
endmodule

// Another way to code a Full Adder circuit

module FullAdder1(input A, input B, input Ci, output S, output Co);


assign S = A ^ B ^ Ci;
assign Co = (A & B) | (B & Ci) | (Ci & A);
endmodule
Four-bit Adder
// Code of a Four-bit Adder circuit using 4 Full Adder circuits

module FourbitAdder (input [3:0] X, input [3:0] Y, output [3:0] S, output Co);
wire co1, co2, co3;
FullAdder fa0 (.A(X[0]), .B(Y[0]), .Ci(0), .S(S[0]), .Co(co1));
FullAdder fa1 (.A(X[1]), .B(Y[1]), .Ci(co1), .S(S[1]), .Co(co2));
FullAdder fa2 (.A(X[2]), .B(Y[2]), .Ci(co2), .S(S[2]), .Co(co3));
FullAdder fa3 (.A(X[3]), .B(Y[3]), .Ci(co3), .S(S[3]), .Co(Co));
endmodule
// A sophisticated way to code a 4-bit Adder circuit

module FourbitAdder (input [3:0] X, input [3:0] Y, input Ci, output [3:0] S, output Co);
assign {Co, S} = X + Y + Ci;
endmodule
Leave it to the computer to figure out the logical circuit

Let’s start leaving things to the computer whenever we can.


// A 4-bit Adder/Subtractor circuit

module FourbitAdderSubtractor (input [3:0] X, input [3:0] Y, input C_B_in, input Control,
output [3:0] Sum_Diff, output C_B_out);

// If Control = 0, then the module adds the two numbers


// If Control =1, then the module subtracts Y from X
// C_B_in = Carry / Borrow in
// C_B_out = Carry / Borrow out
// Sum_Diff = Sum / Difference

assign {C_B_out, Sum_Diff} = (Control==0)? (X+Y+C_B_in) : (X-Y-C_B_in);


endmodule
Note:
Note the syntax of the conditional assignment (Control==0)?
Negative numbers are represented in 2's complement form

Example:
Design a circuit to implement the logical expression x y+ y (x+ z )
module myModule(input x, input y, input z, output out);
assign out = (~x)&(~y) | y&(x|z);
endmodule
Example:
Consider a circuit that accepts a 3-bit binary number X and outputs a 2-bit binary number
Y that is equal to the number of 1’s that appear in X.
For example,
(a) X=000 contains no 1’s and Y=00,
(b) X=110 contains two 1’s and Y=10,
(c) X=111 contains three 1’s and Y=11, etc
Design this circuit using Verilog.
module countOnes (input [2:0] X, output [1:0] Y);
assign Y = X[0] + X[1] + X[2];
endmodule
Note how the individual bits are referred

Example:
Design a three-input circuit that yields an output 1 when exactly one of its inputs is 1
module isSingleOne(input [2:0] X, output Z);
wire [1:0] Y;
assign Y = X[0] + X[1] + X[2];
assign Z = (Y==1)? 1:0;
endmodule

// A 16:1 Multiplexer

module Multiplexer (input [3:0] Select, input [15:0] DataIn, output DataOut);
assign DataOut = DataIn[Select];
endmodule
// A 4:16 Decoder

module Decoder (input [3:0] A, output [15:0] DataOut);


assign DataOut = (16'b0000_0000_0000_0001 << A);
endmodule
Note:
Number formats:
4’b1010 4-bit binary number 1010, i.e. ten
4’hA 4-bit hexadecimal number A, i.e. ten
4’d10 4-bit decimal number 10, i.e. ten
16'b0000_0000_0000_0001 16-bit binary 0000 0000 0000 0001, i.e. one.
(underscores enhance readability)
If the format is not specified, then by default numbers are treated as 32-bit decimals.

<< Left shift operator


4’b0001 << 2 shifts the number towards the left by two bits resulting in 4’b0100

// An ugly way to generate a 4:16 Decoder

module Decoder (input [3:0] A, output [15:0] DataOut);


assign DataOut[0] = (A==0)? 1:0;
assign DataOut[1] = (A==1)? 1:0;
assign DataOut[2] = (A==2)? 1:0;
assign DataOut[3] = (A==3)? 1:0;
assign DataOut[4] = (A==4)? 1:0;
assign DataOut[5] = (A==5)? 1:0;
assign DataOut[6] = (A==6)? 1:0;
assign DataOut[7] = (A==7)? 1:0;
assign DataOut[8] = (A==8)? 1:0;
assign DataOut[9] = (A==9)? 1:0;
assign DataOut[10] = (A==10)? 1:0;
assign DataOut[11] = (A==11)? 1:0;
assign DataOut[12] = (A==12)? 1:0;
assign DataOut[13] = (A==13)? 1:0;
assign DataOut[14] = (A==14)? 1:0;
assign DataOut[15] = (A==15)? 1:0;
endmodule
Here each line generates a logical circuit to control one DataOut output
// A loopy way to generate a 4:16 Decoder

module Decoder (input [3:0] A, output [15:0] DataOut);


genvar i;
generate
for (i=0; i<16; i=i+1)begin
assign DataOut[i] = (A==i)? 1:0;
end
endgenerate
endmodule
It is not that inside the for loop sixteen DataOut values will be computed sequentially one
after the other.
Rather the code would generate sixteen logical circuits to control sixteen DataOut lines
parallelly.

// A loopy way to code a 8-bit Adder circuit

module NbitAdder #(parameter N = 8) (input [N-1:0] X, input [N-1:0] Y,


output [N-1:0] S, output Co);
wire [N:0] co;
assign co[0] = 0;
genvar i;
generate
for(i=0; i<N; i=i+1) begin
FullAdder fa (.A(X[i]), .B(Y[i]), .Ci(co[i]), .S(S[i]), .Co(co[i+1]));
end
endgenerate
assign co[N] = Co;
endmodule

// A Magnitude Comparator

module Decoder (input [7:0] A, input [7:0] B,


output is_Equal, output is_A_gt_B, output is_B_gt_A);
assign is_Equal = (A==B)? 1:0;
assign is_A_gt_B = (A>B)? 1:0;
assign is_B_gt_A = (B>A)? 1:0;
endmodule
Verilog is a Hardware Description Language.
Through this language we describe the functionality/behaviour of the hardware/circuit we
want. It is the task of the computer to give us the design of that circuit which will provide us
the desired functionality.
We know that programming languages need a compiler to translate our programs in
computer executable codes. Similarly, HDLs need a ‘synthesizer’ which generates
(synthesizes) hardware designs according to our description.
We can describe the desired hardware in different ways:
Structural Description: In our first example of the half adder, we described it how it is made
up of basic AND, OR, NOT gates. There we provide the computer with the exact gate level
structure of the desired circuit. We shall call it a Structural Description.
Behavioural Description: Here we will not provide the computer with the gate level
structure of the desired circuit. We will provide a much higher (abstract) level description of
the function of the circuit. It is the task of the synthesizer to find out the required structure
of the circuit. Such descriptions are called Behavioural Descriptions. Please note that the
behavioural description is not the same as the underlying structure of the circuit.
We shall see the Behavioural style of describing circuits more and more.
We shall write the HalfAdder description in a new manner.

// Half Adder

module HalfAdder (input wire a, input wire b, output reg s, output reg co);
always @(a, b)
begin
s = a ^ b;
co = a & b;
end
endmodule
begin Explanation:
s = a ^ b; begin end: this acts as a pair of brackets. It is like:
co = a & b; {
end s = a ^ b;
co = a & b;
}

In C, C++, etc. we use {} to group multiple statements.


Similarly, in Verilog we use ‘begin end’ to group multiple statements.
always @(a, b) Explanation:
begin always @(a, b): It means always monitor the variables a, b.
s = a ^ b; Whenever a, b change, perform the updates described subsequently
co = a & b; between begin and end.
end That means, whenever a or b change; s and co are updated using the
new values of a and b.
Note that as long as a or b remains unchanged, s and co should retain their values
unchanged.
input wire a, Explanation:
input wire b, We see two types of variables: wire and reg.
output reg s, Behavioural differences between the two types are below:
output reg co wire Reg
A wire cannot store/remember a A reg can store/remember a value
value
A wire is always connected to The value of a reg changes only
“something else” that governs the under certain event/conditions.
value of the wire Until that particular event occurs,
the reg should retain/remember
its previous value
The value of a wire is continuously A reg is not ‘continuously driven’
driven by “something else”. by anything else
Whenever, the value of that
“something else” changes, the
value of the wire also changes.
If the type of a variable is not written explicitly, then it is assumed to be
a wire by default.
A wire can be connected to the output of a reg. In that case, the reg
drives the wire. Whenever the value of the reg changes, the value of the
wire also changes.
// We can provide reg variables with initial values as shown below

module HalfAdder (input wire a, input wire b, output reg s = 0, output reg co = 0);
always @(a, b)
begin
s = a ^ b;
co = a & b;
end
endmodule
// Full Adder

module FullAdder1(input A, input B, input Ci, output reg S = 0, output reg Co = 0);
always @(A, B, Ci)
begin
S = A ^ B ^ Ci;
Co = (A & B) | (B & Ci) | (Ci & A);
end
endmodule

// Four-bit Adder

module FourbitAdder (input [3:0] X, input [3:0] Y, input Ci,


output reg [3:0] S = 0, output reg Co = 0);
always @(X, Y, Ci)
begin
{Co, S} = X + Y + Ci;
end
endmodule

If else statement (similar to C language)


// Four-bit Adder/subtractor

module FourbitAdderSubtractor (input [3:0] X, input [3:0] Y, input C_B_in, input Control,
output reg [3:0] Sum_Diff = 0, output reg C_B_out = 0);

// If Control = 0, then the module adds the two numbers


// If Control =1, then the module subtracts Y from X
// C_B_in = Carry / Borrow in
// C_B_out = Carry / Borrow out
// Sum_Diff = Sum / Difference

always @(X, Y, C_B_in, Control) begin


if (Control==0)
begin
{C_B_out, Sum_Diff} = (X+Y+C_B_in);
end
else
begin
{C_B_out, Sum_Diff} = (X-Y-C_B_in);
end
end
endmodule
// Priority Encoder

module PriorityEncoder(input [7:0] D, output reg [3:0] A = 0, output reg DataValid = 0);
always @(D) begin
if(D[7]) begin
A = 7;
DataValid = 1;
end
else if(D[6]) begin
A = 6;
DataValid = 1;
end
else if(D[5]) begin
A = 5;
DataValid = 1;
end
else if(D[4]) begin
A = 4;
DataValid = 1;
end
else if(D[3]) begin
A = 3;
DataValid = 1;
end
else if(D[2]) begin
A = 2;
DataValid = 1;
end
else if(D[1]) begin
A = 1;
DataValid = 1;
end
else if(D[0]) begin
A = 0;
DataValid = 1;
end
else begin
DataValid = 0;
end
end
endmodule
for loop (similar to C language)
// Priority Encoder

module PriorityEncoder(input [7:0] D, output reg [3:0] A = 0, output reg DataValid = 0);
integer i;
always @(D) begin
A = 0;
DataValid = 0;
for(i=0; i<=8; i=i+1) begin
if(D[i]) begin
A = i;
DataValid = 1;
end
end
end
endmodule

Note the produced circuit is composed of a set of MUX.


Here in the circuit the result is not computed sequentially in a loop.
The circuit works all at once (not sequentially).
However, the result would be same to that if one had evaluated it in a sequential for loop.

while loop (similar to C language)


// Priority Encoder

module PriorityEncoder(input [7:0] D, output reg [3:0] A = 0, output reg DataValid = 0);
integer i;
always @(D) begin
DataValid = 0;
i=7;
while((i>=0) && (DataValid == 0)) begin
if(D[i]) begin
A = i;
DataValid = 1;
end
i = i-1;
end
end
endmodule
// BCD to Seven Segment Display Decoder

module BCDto7Segment(input [3:0] X, output reg [6:0] Y = 0);


always @(X) begin
if(X==0) begin
Y = 7'b1111110;
end
else if(X==1) begin
Y = 7'b0110000;
end
else if(X==2) begin
Y = 7'b1101101;
end
else if(X==3) begin
Y = 7'b1111001;
end
else if(X==4) begin
Y = 7'b0110111;
end
else if(X==5) begin
Y = 7'b1011011;
end
else if(X==6) begin
Y = 7'b1011111;
end
else if(X==7) begin
Y = 7'b1110000;
end
else if(X==8) begin
Y = 7'b1111111;
end
else if(X==9) begin
Y = 7'b1111011;
end
else begin
Y = 0;
end
end
endmodule
case statement (similar to C language)
// BCD to Seven Segment Display Decoder

module BCDto7Segment(input [3:0] X, output reg [6:0] Y = 0);


always @(X) begin
case(X)
0: begin Y = 7'b1111110; end
4'd1: Y = 7'b0110000;
4'b10: Y = 7'b1101101;
4'h3: Y = 7'b1111001;
4: Y = 7'b0110111;
5: Y = 7'b1011011;
6: Y = 7'b1011111;
7: Y = 7'b1110000;
8: Y = 7'b1111111;
9: Y = 7'b1111011;
default: Y = 0;
endcase
end
endmodule

Encoder, TestBench, initial, <=, signed

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy