0% found this document useful (0 votes)
10 views18 pages

assignment 3

The document details the design and verification of various digital circuits including a 16-bit adder, a Pseudo Random Number Generator (PRNG), a ones counter, a First Come First Serve (FCFS) arbiter, and different types of adders (ripple carry, carry select, and carry save). Each design is accompanied by a test bench that generates random inputs and verifies the correctness of the outputs through assertions and coverage metrics. The document emphasizes the importance of testing and verification in digital design to ensure functionality and performance.

Uploaded by

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

assignment 3

The document details the design and verification of various digital circuits including a 16-bit adder, a Pseudo Random Number Generator (PRNG), a ones counter, a First Come First Serve (FCFS) arbiter, and different types of adders (ripple carry, carry select, and carry save). Each design is accompanied by a test bench that generates random inputs and verifies the correctness of the outputs through assertions and coverage metrics. The document emphasizes the importance of testing and verification in digital design to ensure functionality and performance.

Uploaded by

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

Assignment -3

Design a 16-bit adder and verify using linear test bench, linear random test bench.
Design:
module adder_16bit(
input logic [15:0] a, b, // 16-bit inputs
output logic [15:0] sum, // 16-bit sum output
output logic carry_out // 1-bit carry output
);
// Perform addition with carry
assign {carry_out, sum} = a + b;
endmodule

Linear test bench:


module tb_adder_16bit_random;
logic [15:0] a, b; // 16-bit inputs
logic [15:0] sum; // 16-bit sum output
logic carry_out; // Carry-out signal

// Instantiate the DUT (Device Under Test)


adder_16bit uut (
.a(a),
.b(b),
.sum(sum),
.carry_out(carry_out)
);

// Random stimulus generation and verification


initial begin
repeat (10) begin // Generate 10 random test cases
a = $urandom % 65536; // Random 16-bit value
b = $urandom % 65536; // Random 16-bit value
#10; // Wait for changes to propagate

// Assertion to verify correctness


assert ({carry_out, sum} == (a + b))
else $error("Mismatch: A = %0d, B = %0d, Sum = %0d, Carry_out = %0d", a, b, sum, carry_out);

// Display values for debugging


$display("A = %0d, B = %0d, Sum = %0d, Carry_out = %0d", a, b, sum, carry_out);
end
$stop; // End simulation
end
endmodule

Linear random test bench:


module tb_adder_16bit_random;
logic [15:0] a, b;
logic [15:0] sum;
logic carry_out;

// Instantiate the DUT (Device Under Test)


adder_16bit uut (
.a(a),
.b(b),
.sum(sum),
.carry_out(carry_out)
);

// Random stimulus generation and verification


initial begin
repeat (10) begin // Generate 10 random test cases
a = $urandom & 16'hFFFF; // Random 16-bit value
#10 b = $urandom & 16'hFFFF; // Apply delay and assign random 16-bit value
// Assertion to verify correctness
assert ({carry_out, sum} == (a + b)[16:0])
else $error("Mismatch: A = %0d, B = %0d, Sum = %0d, Carry_out = %0d", a, b, sum, carry_out);
$display("A = %0d, B = %0d, Sum = %0d, Carry_out = %0d", a, b, sum, carry_out);
end
$stop;
end
endmodule
Results:
Verification of low power Pseudo Random Number Generator (PRNG) to understand code coverage.

Design:
module prng #(parameter WIDTH = 8) (
input logic clk, // Clock signal
input logic reset, // Reset signal
output logic [WIDTH-1:0] prng_out // Output random number
);

logic [WIDTH-1:0] lfsr; // Linear Feedback Shift Register

// PRNG logic based on LFSR


always_ff @(posedge clk or posedge reset) begin
if (reset)
lfsr <= 'h1; // Initialize to a non-zero seed
else
lfsr <= {lfsr[WIDTH-2:0], lfsr[WIDTH-1] ^ lfsr[WIDTH-2]}; // Example tap points
end

assign prng_out = lfsr; // Output the value of lfsr

endmodule

test_bench:

module tb_prng;
// DUT Signals
logic clk, reset;
logic [7:0] prng_out;

// Instantiate the PRNG


prng #(8) uut (
.clk(clk),
.reset(reset),
.prng_out(prng_out)
);

// Clock generation
initial clk = 0;
always #5 clk = ~clk;

// Testbench stimulus
initial begin
reset = 1;
#10 reset = 0; // Apply reset and release it after 10ns

// Generate some random values


repeat (20) begin
@(posedge clk);
$display("PRNG Output: %b", prng_out);
end

// End simulation
$stop;
end

endmodule

Results:
Ones Counter is a Counter which counts the number of one's coming in serial stream. The Minimum
value of the count is "0" and count starts by incriminating one till "15". After "15" the counter rolls
back to "0". Reset is also provided to reset the counter value to "0". Reset signal is active negedge.
Input is 1 bit port for which the serial stream enters. Out bit is 4 bit port from where the count
values can be taken. Reset and clock pins also provided.
Design:
module ones_counter (
input logic clk,
input logic reset_n,
input logic serial_in,
output logic [3:0] count
);
// Internal count logic for ones_counter
always_ff @(posedge clk or negedge reset_n) begin
if (!reset_n)
count <= 4'b0; // Reset the count to 0
else
count <= count + serial_in; // Increment count on serial input
end
endmodule

test_bench:
module tb_ones_counter;
logic clk;
logic reset_n;
logic serial_in;
logic [3:0] count;

// Instantiate the DUT (Device Under Test)


ones_counter uut (
.clk(clk),
.reset_n(reset_n),
.serial_in(serial_in),
.count(count)
);

// Clock generation
initial begin
clk = 0;
forever #5 clk = ~clk; // 10ns clock period
end

initial begin
reset_n = 0; // Hold reset active
serial_in = 0;
#10; // Wait for 10ns
reset_n = 1; // Release reset
#10; // Wait for 10ns

// Simulate serial input with some 1's and 0's


repeat (20) begin
serial_in = $urandom_range(0, 1); // Random input
#10; // Wait for one clock cycle
$display("Time: %0t | Serial In: %b | Count: %0d", $time, serial_in, count);
end
// Apply reset
reset_n = 0;
#10;
// Verify reset
$display("After Reset | Count: %0d", count);
// End simulation
$stop;
end
endmodule
Results:
Verification of First Come First Serve Arbiter using constrained randomized Layered Test Bench.
Design:
module fcfs_arbiter #(
parameter NUM_REQ = 4 // Number of request lines
)(
input logic clk, // Clock signal
input logic reset, // Reset signal
input logic [NUM_REQ-1:0] req, // Request signals
output logic [NUM_REQ-1:0] grant // Grant signals
);

// Internal variable for looping


integer i;
// Always block for FCFS arbiter logic
always_ff @(posedge clk or posedge reset) begin
if (reset) begin
grant <= '0; // Reset all grant signals to 0
end else begin
grant <= '0; // Default to no grants
// Loop through the request signals
for (i = 0; i < NUM_REQ; i = i + 1) begin
if (req[i] && (grant == '0)) begin
grant[i] <= 1'b1; // Grant the first request
break; // Only one request is granted
end
end
end
end
endmodule

test_bench:
module tb_fcfs_arbiter;
// Testbench signals
parameter NUM_REQ = 4;
logic clk, reset;
logic [NUM_REQ-1:0] req, grant;

// Instantiate the DUT


fcfs_arbiter #(NUM_REQ) dut (
.clk(clk),
.reset(reset),
.req(req),
.grant(grant)
);

// Clock generation
initial clk = 0;
always #5 clk = ~clk; // 10ns clock period

// Reset logic
initial begin
reset = 1;
#10 reset = 0;
end

// Driver: Generates constrained random requests


initial begin
req = 0;
#20;
repeat (10) begin
req = $urandom_range(1, 2**NUM_REQ - 1); // Randomize request pattern
#10;
end
$stop;
end

// Monitor: Observes outputs and logs results


initial begin
forever @(posedge clk) begin
$display("Time: %0t | Req: %b | Grant: %b", $time, req, grant);
end
end

// Scoreboard: Checks correctness of grant logic


always @(posedge clk) begin
if (grant != 0) begin
integer i;
for (i = 0; i < NUM_REQ; i = i + 1) begin
if (grant[i]) begin
assert (req[i]) else $fatal("Grant issued without request at index %0d", i);
assert (grant == (1 << i)) else $fatal("Invalid grant: %b", grant);
break;
end
end
end
end

// Coverage: Ensures all request patterns are tested


covergroup arbiter_coverage @(posedge clk);
coverpoint req {
bins all_requests[] = {[0:2**NUM_REQ - 1]}; // Cover all possible requests
}
coverpoint grant {
bins all_grants[] = {[0:2**NUM_REQ - 1]}; // Cover all possible grants
}
endgroup
arbiter_coverage cov = new();

// Sample coverage
always @(posedge clk) cov.sample();

endmodule

Results:
Verification of Ripple carry adder, Carry select Adder and carry save adder using coverage.

Design:
module ripple_carry_adder #(parameter WIDTH = 4) (
input logic [WIDTH-1:0] a, b,
input logic cin,
output logic [WIDTH-1:0] sum,
output logic cout
);
logic [WIDTH:0] carry;
assign carry[0] = cin;
generate
genvar i;
for (i = 0; i < WIDTH; i++) begin
assign {carry[i+1], sum[i]} = a[i] + b[i] + carry[i];
end
endgenerate
assign cout = carry[WIDTH];
endmodule

module carry_select_adder #(parameter WIDTH = 4) (


input logic [WIDTH-1:0] a, b,
input logic cin,
output logic [WIDTH-1:0] sum,
output logic cout
);
// Internal signals for carry select adder
logic [WIDTH-1:0] sum0, sum1;
logic cout0, cout1;

// Generate sum and carry for two cases (cin = 0 or cin = 1)


always_comb begin
sum0 = a + b;
cout0 = sum0[WIDTH];

sum1 = a + b + 1;
cout1 = sum1[WIDTH];
end

// Select the appropriate sum and carry based on cin


assign sum = (cin) ? sum1 : sum0;
assign cout = (cin) ? cout1 : cout0;
endmodule

module carry_save_adder #(parameter WIDTH = 4) (


input logic [WIDTH-1:0] a, b, c,
output logic [WIDTH-1:0] sum,
output logic carry
);
// Perform the carry-save addition
always_comb begin
{carry, sum} = a + b + c;
end
endmodule

test_bench:
`timescale 1ns / 1ps
module adder_tb;
parameter WIDTH = 4;
// Declare clock and reset signals
logic clk;
logic reset;
// Shared input signals
logic [WIDTH-1:0] a, b, c;
logic cin;
// RCA outputs
logic [WIDTH-1:0] rca_sum;
logic rca_cout;
// CSLA outputs
logic [WIDTH-1:0] csla_sum;
logic csla_cout;
// CSA outputs
logic [WIDTH-1:0] csa_sum;
logic csa_carry;
// Instantiate Ripple Carry Adder (RCA)
ripple_carry_adder #(WIDTH) rca (
.a(a), .b(b), .cin(cin), .sum(rca_sum), .cout(rca_cout)
);
// Instantiate Carry Select Adder (CSLA)
carry_select_adder #(WIDTH) csla (
.a(a), .b(b), .cin(cin), .sum(csla_sum), .cout(csla_cout)
);
// Instantiate Carry Save Adder (CSA)
carry_save_adder #(WIDTH) csa (
.a(a), .b(b), .c(c), .sum(csa_sum), .carry(csa_carry)
);
// Coverage Definitions
covergroup rca_coverage @(posedge clk);
coverpoint rca_sum {
bins sum_bins[] = {[0:15]}; // Cover all possible RCA sums
}
coverpoint rca_cout {
bins cout_bins[] = {0, 1}; // Cover RCA carry out
}
endgroup
covergroup csla_coverage @(posedge clk);
coverpoint csla_sum {
bins sum_bins[] = {[0:15]}; // Cover all possible CSLA sums
}
coverpoint csla_cout {
bins cout_bins[] = {0, 1}; // Cover CSLA carry out
}
endgroup
covergroup csa_coverage @(posedge clk);
coverpoint csa_sum {
bins sum_bins[] = {[0:15]}; // Cover all possible CSA sums
}
coverpoint csa_carry {
bins carry_bins[] = {0, 1}; // Cover CSA carry
}
endgroup
// Instantiate the coverage groups
rca_coverage rca_cov = new();
csla_coverage csla_cov = new();
csa_coverage csa_cov = new();
// Clock generation
initial begin
clk = 0;
end
always #5 clk = ~clk; // 10 ns period
// Test stimulus
initial begin
reset = 1; // Initialize reset signal
a = 0; b = 0; c = 0; cin = 0;
#10 reset = 0; // Deassert reset after 10ns
// Apply test cases
repeat (100) begin
a = $random;
b = $random;
c = $random;
cin = $random;
#10;
// Display outputs
$display("Inputs: a=%0d b=%0d c=%0d cin=%0d", a, b, c, cin);
$display("RCA: sum=%0d cout=%0d", rca_sum, rca_cout);
$display("CSLA: sum=%0d cout=%0d", csla_sum, csla_cout);
$display("CSA: sum=%0d carry=%0d", csa_sum, csa_carry);
end
$finish;
end
endmodule

Results:

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