0% found this document useful (0 votes)
0 views

Verilog Assignment

Uploaded by

sushilkhandare91
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views

Verilog Assignment

Uploaded by

sushilkhandare91
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Vivado Practice Assignment

Question 1.

Write a verilog module to implement an adder - it should have the module interfac

module adder (sum, a, b);

where a, b, sum are 8 bit values.

Solution

module adder ( sum, a, b ) ;

input [7:0] a, b;

output [7:0] sum;

/*** WRITE YOUR CODE HERE ***/

endmodule // adder

Q2. Sequential Multiplier

This basically refers to the "long form" multiplication as we learn in school. For each digit of
the multiplier, we shift the multiplicand to the appropriate place value, and then add all the
partial products. An example of the partial products in binary for a simple 4-bit multiplication
are shown below. As expected, multiplying two 4-bit numbers can result in an output that is
up to 8 bits in length.

0110 # Decimal 6 - Multiplicand


x 0011 # Decimal 3 - Multiplier
--------
0110 # Partial product 0 (PP0)
0110 # PP1
0000 # PP2
0000 # PP3
--------
00010010 # Decimal 18
--------

Number Representation

The numbers themselves are represented in 2's complement notation. Therefore, if the
multiplicand is negative, the PP values should be "sign-extended" to get the correct result. An
example for negative multiplicand is shown below - negative multiplier requires similar
careful handling, and is left as an exercise.

1010 # Decimal -6
x 0011 # Decimal 3
--------
11111010 # Partial product 0 (PP0) - sign extended
1111010 # PP1
000000 # PP2
00000 # PP3
--------
(1)11101110 # Decimal -18 (discard the overflow 1)
--------

Hardware Implementation

The above multiplication process can be directly implemented as combinational logic, where
each partial product vector is created using a set of AND gates, and the results are put
through a chain of adders.

The other alternative is to have a reduced hardware with a single register to hold the final
product. This accumulates the final product by iterating over several clock cycles (how
many?). A diagram indicating the architecture is shown here.
Solution Design: - Expected behaviour:

A sequential multiplier does multiplication of two numbers by using a "shift-and-add" approach. It


examines each bit of one of the values (called the "multiplier") and if the value is 1, then it adds the
"multiplicand" to the partial product that has been accumulated up to this point. Obviously this
means it takes multiple clock cycles to complete the multiplication.

In the present template, we assume that there is also a "start" signal that indicates when the inputs
are valid, and that any time the start signal is 1, the multiplier should initialize internal variables to a
known state. You can assume that the start signal is only high for 1 cycle, and that the multiplication
itself should start only when the start signal is removed (made 0). Finally, after performing the
multiplication, the module should make the "done" signal high and keep it that way till the next start
signal is received.

`define width 8

`define ctrwidth 4

module seq_mult (

// Outputs

p, done,

// Inputs

clk, start, a, b

);

input clk, start;


input [`width-1:0] a, b;

// *** Output declaration for 'p'

// *** Register declarations for p, multiplier, multiplicand

always @(posedge clk)

if (start) begin

done <= 0;

p <= 0;

ctr <= 0;

multiplier <= // remember to sign-extend

multiplicand <=

end else begin

if ( /* *** How many times should the loop run? */ )

begin

// *** Code for multiplication

end else begin

done <= 1; // Assert 'done' signal to indicate end of multiplication

end

end

endmodule // seqmult
Q2 – Testbech code – for verification of your code in vivado

`timescale 1ns/1ns
`define width 8
`define TIMEOUT 100

module seq_mult_tb () ;
reg signed [`width-1:0] a, b;
reg clk, start;
integer tot, err;
integer timer;
reg timedout;

wire signed [2*`width-1:0] p, expected_p;


wire done;

//Calculation of expected output.


assign expected_p = a * b;

seq_mult dut( .clk(clk),


.start(start),
.a(a),
.b(b),
.p(p),
.done(done));

// Generate a 10ns clock


always #5 clk = !clk;

task start_and_crank_dut;
begin
tot += 1;
timer = 0;
// start the DUT for one clock cycle
start = 1;
@(posedge clk);
// Remove start
#1 start = 0;

// Loop until the DUT indicates 'done'


while ((done == 0) && (timer < `TIMEOUT)) begin
@(posedge clk); // Wait for one clock cycle
timer += 1;
end
if (timer == `TIMEOUT) begin
$display("Timed out");
timedout = 1;
end else if (p !== expected_p) begin
err += 1;
$display($time, " a = %d, b = %d, p = %d, expected p = %d", a,
b, p, expected_p);
end
end
endtask // start_and_crank_dut

initial begin
// Initialize the clock
clk = 1;
tot = 0;
err = 0;
timedout = 0;

// Sequences of values pumped through DUT

// It is not necessary to place a #1 before the $display,


// because the start_and_crank_dut task will only exit after the
// value is correctly computed.
a = 10;
b = 1;
start_and_crank_dut;

a = 10;
b = 2;
start_and_crank_dut;

// Product will not fit in 8 bits.


a = 20;
b = 20;
start_and_crank_dut;

// One operand negative


a = -10;
b = 2;
start_and_crank_dut;

// One operand negative


a = 10;
b = -2;
start_and_crank_dut;

// One input 0
a = 0;
b = 10;
start_and_crank_dut;

// Other input 0
a = 10;
b = 0;
start_and_crank_dut;

// Large values
a = 127;
b = 127;
start_and_crank_dut;

// Add more test cases:


// - other input negative
// - each input 0
// - max/min values etc.
// - random numbers if necessary?

if (err > 0) begin


$display("FAILED %d out of %d", err, tot);
end else if (timedout === 'b1) begin
$display("FAILED due to TIMEOUT");
end else begin
$display("PASS");
end

$finish;
end

endmodule // seq_mult_tb

&&&&&

You might also like