Digital System Design Lab
NAME : Sheshadri D B
USN : 24TMPLEL05
1) Write Verilog code for the design of 8-bit Carry Ripple Adder
module ripple_carry_adder(
input [7:0] a, b,
input cin,
output [7:0] sum,
output cout
);
wire [7:0] c;
full_adder fa0 (a[0], b[0], cin, sum[0], c[0]);
full_adder fa1 (a[1], b[1], c[0], sum[1], c[1]);
full_adder fa2 (a[2], b[2], c[1], sum[2], c[2]);
full_adder fa3 (a[3], b[3], c[2], sum[3], c[3]);
full_adder fa4 (a[4], b[4], c[3], sum[4], c[4]);
full_adder fa5 (a[5], b[5], c[4], sum[5], c[5]);
full_adder fa6 (a[6], b[6], c[5], sum[6], c[6]);
full_adder fa7 (a[7], b[7], c[6], sum[7], cout);
endmodule
//Test Bench Code
module full_adder(
input a, b, cin,
output sum, cout
);
assign sum = a ^ b ^ cin;
assign cout = (a & b) | (b & cin) | (a & cin);
endmodule
`timescale 1ns / 1ps
module ripple_carry_adder_tb;
reg [7:0] a, b;
reg cin;
wire [7:0] sum;
wire cout;
ripple_carry_adder uut (
.a(a), .b(b), .cin(cin),
.sum(sum), .cout(cout)
);
initial begin
$dumpfile("ripple_carry_adder.vcd");
$dumpvars(0, ripple_carry_adder_tb);
$monitor("Time = %0t | A = %b | B = %b | Cin = %b | Sum = %b | Cout = %b",
$time, a, b, cin, sum, cout);
a = 8'b00000000; b = 8'b00000000; cin = 0; #10;
a = 8'b00110011; b = 8'b01000101; cin = 0; #10;
a = 8'b01111000; b = 8'b10001110; cin = 0; #10;
a = 8'b11111111; b = 8'b00000001; cin = 0; #10;
a = 8'b11111111; b = 8'b11111111; cin = 1; #10;
$finish;
end
endmodule
Waveform :
2) Write a Verilog code for the design of 8 bit Booth’s Multiplier
module booth_multi(p, a, b, clk);
input clk;
input signed [7:0] a, b;
output reg signed [15:0] p;
reg signed [15:0] ans;
integer i;
integer operate;
always @(posedge clk)
begin
p = 16'b0;
for (i = 0; i <= 7; i = i + 2)
begin
if (i == 0)
operate = {b[1], b[0], 1'b0};
else
operate = {b[i+1], b[i], b[i-1]};
case (operate)
3'b001, 3'b010: begin
ans = a;
ans = ans << i;
p = p + ans;
end
3'b011: begin
ans = a << 1;
ans = ans << i;
p = p + ans;
end
3'b100: begin
ans = -(a << 1);
ans = ans << i;
p = p + ans;
end
3'b101, 3'b110: begin
ans = -a;
ans = ans << i;
p = p + ans;
end
endcase
end
end
endmodule
// Testbench for Booth Multiplier with Multiple Test Cases
module bitbooth_tb;
reg signed [7:0] a;
reg signed [7:0] b;
reg clk;
wire signed [15:0] p;
booth_multi uut(.p(p), .a(a), .b(b), .clk(clk));
initial begin
clk = 0;
// Test cases with expected outputs for verification
#10 a = -8'sd13; b = -8'sd17; // -13 * -17 = 221
#10 $display("Test: %d * %d = %d (Expected: 221)", a, b, p);
#10 a = 8'sd15; b = -8'sd7; // 15 * -7 = -105
#10 $display("Test: %d * %d = %d (Expected: -105)", a, b, p);
#10 a = -8'sd6; b = -8'sd9; // -6 * -9 = 54
#10 $display("Test: %d * %d = %d (Expected: 54)", a, b, p);
#10 a = 8'sd25; b = 8'sd4; // 25 * 4 = 100
#10 $display("Test: %d * %d = %d (Expected: 100)", a, b, p);
#10 a = -8'sd8; b = -8'sd12; // -8 * -12 = 96
#10 $display("Test: %d * %d = %d (Expected: 96)", a, b, p);
end
always begin
#10 clk = ~clk;
end
initial begin
#100 $stop;
end
endmodule
Waveform
3) Write Verilog code for the design of 8-bit Carry look ahead Adder
module carry_lookahead_adder(
input [7:0] A, B,
input Cin,
output [7:0] Sum,
output Cout
);
wire [7:0] G, P, C;
assign G = A & B;
assign P = A ^ B;
assign C[0] = Cin;
assign C[1] = G[0] | (P[0] & C[0]);
assign C[2] = G[1] | (P[1] & G[0]) | (P[1] & P[0] & C[0]);
assign C[3] = G[2] | (P[2] & G[1]) | (P[2] & P[1] & G[0]) | (P[2] & P[1] & P[0] & C[0]);
assign C[4] = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0])
| (P[3] & P[2] & P[1] & P[0] & C[0]);
assign C[5] = G[4] | (P[4] & G[3]) | (P[3] & P[4] & G[2]) | (P[3] & P[2] & P[4] & G[1])
| (P[3] & P[2] & P[1] & P[4] & G[0]) | (P[4] & P[3] & P[2] & P[1] & P[0] & C[0]);
assign C[6] = G[5] | (P[5] & G[4]) | (P[4] & P[5] & G[3]) | (P[5] & P[3] & P[2] & P[4] &
G[1])
| (P[3] & P[2] & P[1] & P[4] & P[5] & G[0]) | (P[5] & P[4] & P[3] & P[2] & P[1] &
P[0] & C[0]);
assign C[7] = G[6] | (P[6] & G[5]) | (P[6] & P[5] & G[4]) | (P[4] & P[5] & P[6] & G[3])
| (P[3] & P[4] & P[6] & G[5]) | (P[6] & P[5] & P[4] & P[3] & P[2] & G[1])
| (P[6] & P[5] & P[4] & P[3] & P[2] & P[1] & G[0])
| (P[6] & P[5] & P[4] & P[3] & P[2] & P[1] & P[0] & C[0]);
assign Cout = G[7] | (P[7] & G[6]) | (P[6] & P[7] & G[5]) | (P[7] & P[5] & P[6] & G[4])
| (P[4] & P[5] & P[6] & P[7] & G[3]) | (P[7] & P[6] & P[4] & P[3] & G[5])
| (P[7] & P[6] & P[5] & P[4] & P[3] & P[2] & G[1])
| (P[7] & P[6] & P[5] & P[4] & P[3] & P[2] & P[1] & G[0])
| (P[7] & P[6] & P[5] & P[4] & P[3] & P[2] & P[1] & P[0] & G[0]);
assign Sum = P ^ C;
endmodule
//Testbench code
module carry_lookahead_adder_tb;
reg [7:0] A, B;
reg Cin;
wire [7:0] Sum;
wire Cout;
carry_lookahead uut (
.A(A), .B(B), .Cin(Cin),
.Sum(Sum), .Cout(Cout)
);
initial begin
A = 8'b00000000; B = 8'b00000000; Cin = 1'b0;
#100 A = 8'b11110001; B = 8'b11110001; Cin = 1'b0;
#100 A = 8'b10101110; B = 8'b11000101; Cin = 1'b0;
#100 A = 8'b11011101; B = 8'b01011010; Cin = 1'b1;
#100 A = 8'b00001110; B = 8'b01011001; Cin = 1'b1;
#100 A = 8'b00001111; B = 8'b11111010; Cin = 1'b0;
end
initial begin
$monitor("Time = %0t | A = %b | B = %b | Cin = %b | Sum = %b | Cout = %b",
$time, A, B, Cin, Sum, Cout);
end
endmodule
Waveform
4) Write Verilog code to design a 8 bit Magnitude comparator
module compar_8bit (A, B, clk, a_eq_b, a_less_b, a_grt_b);
parameter N = 8;
input clk;
input [N-1:0] A;
input [N-1:0] B;
output reg a_eq_b;
output reg a_less_b;
output reg a_grt_b;
always @(posedge clk) begin
if (A == B) begin
a_eq_b = 1;
a_less_b = 0;
a_grt_b = 0;
end else if (A > B) begin
a_grt_b = 1;
a_eq_b = 0;
a_less_b = 0;
end else begin // A < B
a_grt_b = 0;
a_eq_b = 0;
a_less_b = 1;
end
end
endmodule
//Testbench code
module compr_tb;
// Inputs
reg [7:0] A;
reg [7:0] B;
reg clk;
// Outputs
wire a_eq_b;
wire a_less_b;
wire a_grt_b;
// Instantiate the Unit Under Test (UUT)
compar_8bit uut (
.A(A),
.B(B),
.clk(clk),
.a_eq_b(a_eq_b),
.a_less_b(a_less_b),
.a_grt_b(a_grt_b)
);
initial begin
clk = 0;
// Test cases covering A < B, A > B, and A == B
#10 A = 8'd50; B = 8'd100; // A < B (50 < 100)
#10 $display("A=%d, B=%d => a_eq_b=%b, a_less_b=%b, a_grt_b=%b (Expected:
0,1,0)", A, B, a_eq_b, a_less_b, a_grt_b);
#10 A = 8'd200; B = 8'd150; // A > B (200 > 150)
#10 $display("A=%d, B=%d => a_eq_b=%b, a_less_b=%b, a_grt_b=%b (Expected:
0,0,1)", A, B, a_eq_b, a_less_b, a_grt_b);
#10 A = 8'd127; B = 8'd127; // A == B (127 == 127)
#10 $display("A=%d, B=%d => a_eq_b=%b, a_less_b=%b, a_grt_b=%b (Expected:
1,0,0)", A, B, a_eq_b, a_less_b, a_grt_b);
#10 A = 8'd90; B = 8'd25; // A > B (90 > 25)
#10 $display("A=%d, B=%d => a_eq_b=%b, a_less_b=%b, a_grt_b=%b (Expected:
0,0,1)", A, B, a_eq_b, a_less_b, a_grt_b);
#10 A = 8'd18; B = 8'd250; // A < B (18 < 250)
#10 $display("A=%d, B=%d => a_eq_b=%b, a_less_b=%b, a_grt_b=%b (Expected:
0,1,0)", A, B, a_eq_b, a_less_b, a_grt_b);
end
always begin
#5 clk = ~clk; // Generate clock signal
end
initial begin
#100 $stop; // Stop simulation after all test cases
end
endmodule
Waveform
5) Write a Verilog code to design a 4bit Universal shift register
module universal_shift_reg(
input clk, rst_n,
input [1:0] select, // select operation
input [3:0] p_din, // parallel data in
input s_left_din, // serial left data in
input s_right_din, // serial right data in
output reg [3:0] p_dout, //parallel data out
output s_left_dout, // serial left data out
output s_right_dout // serial right data out
);
always@(posedge clk) begin
if(!rst_n) p_dout <= 0;
else begin
case(select)
2'h1: p_dout <= {s_right_din,p_dout[3:1]}; // Right Shift
2'h2: p_dout <= {p_dout[2:0],s_left_din}; // Left Shift
2'h3: p_dout <= p_din; // Parallel in - Parallel out
default: p_dout <= p_dout; // Do nothing
endcase
end
end
assign s_left_dout = p_dout[0];
assign s_right_dout = p_dout[3];
endmodule
//Testbench code
module TB;
reg clk, rst_n;
reg [1:0] select;
reg [3:0] p_din;
reg s_left_din, s_right_din;
wire [3:0] p_dout; //parallel data out
wire s_left_dout, s_right_dout;
universal_shift_reg usr(clk, rst_n, select, p_din, s_left_din, s_right_din, p_dout, s_left_dout,
s_right_dout);
always #2 clk = ~clk;
initial begin
$monitor("select=%b, p_din=%b, s_left_din=%b, s_right_din=%b --> p_dout = %b,
s_left_dout = %b, s_right_dout = %b",select, p_din, s_left_din, s_right_din, p_dout,
s_left_dout, s_right_dout);
clk = 0; rst_n = 0;
#3 rst_n = 1;
p_din = 4'b1101;
s_left_din = 1'b1;
s_right_din = 1'b0;
select = 2'h3; #10;
select = 2'h1; #20;
p_din = 4'b1101;
select = 2'h3; #10;
select = 2'h2; #20;
select = 2'h0; #20;
$finish;
end
// To enable waveform
initial begin
$dumpfile("dump.vcd"); $dumpvars;
end
endmodule
Waveform
6) Write a Verilog code to design a 8bit parity generator
module parity_gen_8bit(
input [7:0] parity_in,
output parity_even,
output parity_odd
);
// XOR all bits to generate even parity
assign parity_even = parity_in[7] ^ parity_in[6] ^ parity_in[5] ^ parity_in[4] ^
parity_in[3] ^ parity_in[2] ^ parity_in[1] ^ parity_in[0];
// Odd parity is the complement of even parity
assign parity_odd = ~parity_even;
endmodule
//Testbench code
module parity_gen_8bit_tb;
// Inputs
reg [7:0] parity_in;
// Outputs
wire parity_even;
wire parity_odd;
// Instantiate the Unit Under Test (UUT)
parity_gen_8bit uut (
.parity_in(parity_in),
.parity_even(parity_even),
.parity_odd(parity_odd)
);
initial begin
// Display the values
$monitor("Time=%0t | Input=%b | Even Parity=%b | Odd Parity=%b",
$time, parity_in, parity_even, parity_odd);
// Initialize Inputs
parity_in = 8'b00000000; #100;
parity_in = 8'b01100001; #100;
parity_in = 8'b01100011; #100;
parity_in = 8'b10110101; #100;
parity_in = 8'b00000001; #100;
parity_in = 8'b01111111; #100;
parity_in = 8'b11111111; #100;
// Finish simulation
$finish;
end
endmodule
Waveform
7) Design and develop a Verilog model for an accumulator that calculates
the sum of a sequence of fixed-point numbers. Each input number is signed
with 6 pre-binary-point and 12 post-binary-point bits. The accumulated sum
has 8 pre-binary-point and 12 post-binary-point bits. A new number arrives
at the input during a clock cycle when data_en control input is ‘1’. The
accumulated sum is cleared to ‘0’ when the rest counter 1 input is ‘1’. Both
control inputs are synchronous.
8) Design and develop a Verilog code for a dual port, 4k x 32-bit flow through
SSRAM (Synchronous Static Random-Access Memory), and one port allows
data to be written & read, while the other port allows only data to be read.