Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
6 views14 pages

Nhat Lab5

This document is a lab guide for designing a 32-bit Arithmetic Logic Unit (ALU) in Verilog, including steps for creating the ALU, developing test vectors, and implementing a testbench. It outlines the requirements for both dataflow and behavioral styles of the ALU, as well as instructions for testing and simulating the design using Vivado. The document also specifies what needs to be submitted for evaluation, including the Verilog code and testbench.

Uploaded by

Nhat Le Quang
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)
6 views14 pages

Nhat Lab5

This document is a lab guide for designing a 32-bit Arithmetic Logic Unit (ALU) in Verilog, including steps for creating the ALU, developing test vectors, and implementing a testbench. It outlines the requirements for both dataflow and behavioral styles of the ALU, as well as instructions for testing and simulating the design using Vivado. The document also specifies what needs to be submitted for evaluation, including the Verilog code and testbench.

Uploaded by

Nhat Le Quang
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/ 14

ELEC 3010 Lab 05 Guide

Lab 05: 32-bit ALU and Testbench


Introduction
In this lab, you will design the 32-bit Arithmetic Logic Unit (ALU) that is described in Section 5.2.4
of the text. Your ALU will become an important part of the MIPS microprocessor that you will build
in later labs. In this lab you will design an ALU in Verilog. You will also write a Verilog testbench
and testvector file to test the ALU.
Step 01: Creating the ALU (30 points)
Create a 32-bit ALU in Verilog. Name the file alu.v. It should have the following module
declaration:

The output zero should be TRUE if y is equal to zero.


Try to use no more than ONE adder in your design, as the adder is a relatively expensive piece of
hardware.
After your design, you can use the ELABORATE DESIGN function in Vivado to quickly see how
many adders you will get.
Complete TWO version of your ALU.
• The first version should follow the dataflow style (using only assign statement)
• The second version should follow the behavioral verilog style (using always).

Step 02: Develop The Test Vectors (10 points)


Develop an appropriate set of test vectors to convince a reasonable person that your design is
probably correct. Complete Table 1 to verify that all 5 ALU operations work as they are supposed
to. Note that the values are expressed in hexadecimal to reduce the amount of writing.
Test F[2:0] A B Y Zero

ADD 0+0 2 00000000 00000000 00000000 1


ADD 0+(-1) 2 00000000 FFFFFFFF FFFFFFFF 0
ADD 1+(-1) 2 00000001 FFFFFFFF 00000000 1
ADD FF+1 2 000000FF 00000001
SUB 0-0 6 00000000 00000000 00000000 1
SUB 0-(-1) 00000000 FFFFFFFF 00000001 0
SUB 1-1 00000001
SUB 100-1 00000100
SLT 0,0 7 00000000 00000000 00000000 1
SLT 0,1 00000000 00000001 0
SLT 0,-1 00000000

1
ELEC 3010 Lab 05 Guide

SLT 1,0 00000001


SLT -1,0 FFFFFFFF
AND FFFFFFFF, FFFFFFFF FFFFFFFF
AND FFFFFFFF, 12345678 FFFFFFFF 12345678 12345678 0
AND 12345678, 87654321 12345678
AND 00000000, FFFFFFFF 00000000
OR FFFFFFFF, FFFFFFFF FFFFFFFF
OR 12345678, 87654321 12345678
OR 00000000, FFFFFFFF 00000000
OR 00000000, 00000000 00000000

(Step 03 and 04 should apply to both versions of your design)


Step 03: Testbench with Verilog and Simulation with Vivado (30 points)
Now you need to add a Verilog testbench to the design.
You may use the self-checking template from Lab 03 as a starting point. Use the test vectors you
created in step 02.
Compile your alu and testbench in Vivado and simulate the design. Run for a long enough time to
check all of the vectors. If you encounter any errors, correct your design and rerun.
Take the screenshot of the simulation waveform.
Step 04: Hardware Implementation (30 points)
Go through the synthesis flow as described in Lab 01 (Under Synthesis/Run synthesis)
Read the report utilization and capture the utilization summary (Under Synthesis/Open
Synthesized
Design/Report Utilization)
Report the maximum frequency your ALU can run at.
Discuss the difference between the two vesions. Which one do you prefer?
What to Turn In
You must submit an electronic copy of the lab reports via Canvas in a single file. The followings
should be included:
1. Verilog code of the design and the test bench
1.1 Structural Style
1.1.1 Verilog Design
`timescale 1ns / 1ps

module nhatstructure (

2
ELEC 3010 Lab 05 Guide

input wire [31:0] a, b, // 32-bit input operands


input wire [2:0] f, // 3-bit function selector
output wire [31:0] y, // 32-bit result output
output wire zero // Output is TRUE if y == 0
);

// Signed versions of inputs for SLT operation


wire signed [31:0] signed_a = a;
wire signed [31:0] signed_b = b;

// Operation results
wire [31:0] add_res = a + b;
wire [31:0] sub_res = a - b;
wire [31:0] and_res = a & b;
wire [31:0] or_res = a | b;
wire [31:0] xor_res = a ^ b;
wire [31:0] not_res = ~a;
wire [31:0] shift_res = (f == 3'b110) ? (a << b[4:0]) : (a >> b[4:0]);
wire [31:0] slt_res = (signed_a < signed_b) ? 32'd1 : 32'd0;

// Function selector
assign y = (f == 3'b000) ? add_res :
(f == 3'b001) ? sub_res :
(f == 3'b010) ? and_res :
(f == 3'b011) ? or_res :
(f == 3'b100) ? xor_res :
(f == 3'b101) ? not_res :
(f == 3'b111) ? slt_res :
shift_res;

// Zero flag
assign zero = (y == 32'b0);

endmodule
1.1.2 Test Bench
`timescale 1ns / 1ps

3
ELEC 3010 Lab 05 Guide

module structural_simulation;

// Inputs and outputs


reg [31:0] a, b;
reg [2:0] f;
wire [31:0] y;
wire zero;

// Error counter
integer errors = 0;

// Function codes
localparam ADD = 3'b000;
localparam SUB = 3'b001;
localparam AND_ = 3'b010;
localparam OR_ = 3'b011;
localparam SLT = 3'b111;

// Instantiate the ALU (Device Under Test)


nhatstructure dut (
.a(a),
.b(b),
.f(f),
.y(y),
.zero(zero)
);

// Test task
task run_test;
input [31:0] test_a, test_b;
input [2:0] test_f;
input [31:0] expected_y;
input expected_zero;
input [127:0] label;

4
ELEC 3010 Lab 05 Guide

begin
a = test_a;
b = test_b;
f = test_f;
#5; // Allow time for propagation

if (y !== expected_y || zero !== expected_zero) begin


$display("FAIL: %-25s | a=%h b=%h f=%b | y=%h (exp %h), zero=%b (exp %b)",
label, a, b, f, y, expected_y, zero, expected_zero);
errors = errors + 1;
end else begin
$display("PASS: %-25s | a=%h b=%h f=%b | y=%h, zero=%b",
label, a, b, f, y, zero);
end
end
endtask

// Main test sequence


initial begin
$display("Starting ALU testbench...\n");

// ADD tests
run_test(32'h00000000, 32'h00000000, ADD, 32'h00000000, 1, "ADD 0 + 0");
run_test(32'h00000000, 32'hFFFFFFFF, ADD, 32'hFFFFFFFF, 0, "ADD 0 + (-1)");
run_test(32'h00000001, 32'hFFFFFFFF, ADD, 32'h00000000, 1, "ADD 1 + (-1)");
run_test(32'h000000FF, 32'h00000001, ADD, 32'h00000100, 0, "ADD FF + 1");

// SUB tests
run_test(32'h00000000, 32'h00000000, SUB, 32'h00000000, 1, "SUB 0 - 0");
run_test(32'h00000000, 32'hFFFFFFFF, SUB, 32'h00000001, 0, "SUB 0 - (-1)");
run_test(32'h00000001, 32'h00000001, SUB, 32'h00000000, 1, "SUB 1 - 1");
run_test(32'h00000100, 32'h00000001, SUB, 32'h000000FF, 0, "SUB 100 - 1");

// SLT tests
run_test(32'h00000000, 32'h00000000, SLT, 32'h00000000, 1, "SLT 0, 0");
run_test(32'h00000000, 32'h00000001, SLT, 32'h00000001, 0, "SLT 0, 1");

5
ELEC 3010 Lab 05 Guide

run_test(32'h00000000, 32'hFFFFFFFF, SLT, 32'h00000000, 1, "SLT 0, -1");


run_test(32'h00000001, 32'h00000000, SLT, 32'h00000000, 1, "SLT 1, 0");
run_test(32'hFFFFFFFF, 32'h00000000, SLT, 32'h00000001, 0, "SLT -1, 0");

// AND tests
run_test(32'hFFFFFFFF, 32'hFFFFFFFF, AND_, 32'hFFFFFFFF, 0, "AND all 1s");
run_test(32'hFFFFFFFF, 32'h12345678, AND_, 32'h12345678, 0, "AND FFFFFFFF &
12345678");
run_test(32'h12345678, 32'h87654321, AND_, 32'h02244220, 0, "AND 12345678 &
87654321");
run_test(32'h00000000, 32'hFFFFFFFF, AND_, 32'h00000000, 1, "AND 0 & all 1s");

// OR tests
run_test(32'hFFFFFFEF, 32'hFFFFFFFF, OR_, 32'hFFFFFFFF, 0, "OR FFFFFFEF |
FFFFFFFF");
run_test(32'h12345678, 32'h87654321, OR_, 32'h97755779, 0, "OR 12345678 | 87654321");
run_test(32'h00000000, 32'hFFFFFFFF, OR_, 32'hFFFFFFFF, 0, "OR 0 | all 1s");
run_test(32'h00000000, 32'h00000000, OR_, 32'h00000000, 1, "OR 0 | 0");

// Final report
if (errors == 0)
$display("\nAll tests passed!");
else
$display("\n%d test(s) failed.", errors);

$finish;
end

endmodule
1.2 Behavioral Style
1.2.1 Verilog Design
`timescale 1ns / 1ps
module nhatlab5behave (
input [31:0] a, b,
input [2:0] f,
output reg [31:0] y,

6
ELEC 3010 Lab 05 Guide

output reg zero


);

// Internal signed versions of inputs for SLT operation


reg signed [31:0] sa, sb;

always @(*) begin


// Assign signed values
sa = a;
sb = b;

// Default outputs
y = 32'b0;
zero = 1'b0;

case (f)
3'b000: y = a + b; // ADD
3'b001: y = a - b; // SUB
3'b010: y = a & b; // AND
3'b011: y = a | b; // OR
3'b100: y = a ^ b; // XOR
3'b101: y = ~a; // NOT
3'b110: y = a << b[4:0]; // SLL (logical left shift)
3'b111: y = (sa < sb) ? 32'd1 : 32'd0; // SLT (signed less than)
default: y = 32'b0;
endcase

// Set zero flag if result is zero


zero = (y == 32'b0);
end

endmodule
1.2.2 Test Bench
`timescale 1ns / 1ps

module behavesimu;

7
ELEC 3010 Lab 05 Guide

// Inputs and outputs


reg [31:0] a, b;
reg [2:0] f;
wire [31:0] y;
wire zero;

integer errors = 0;

// Function codes
localparam ADD = 3'b000;
localparam SUB = 3'b001;
localparam AND_ = 3'b010;
localparam OR_ = 3'b011;
localparam SLT = 3'b111;

// Instantiate the behavioral ALU


nhatlab5behave uut (
.a(a),
.b(b),
.f(f),
.y(y),
.zero(zero)
);

// Test task
task run_test;
input [31:0] test_a, test_b;
input [2:0] test_f;
input [31:0] expected_y;
input expected_zero;
input [127:0] label;

begin
a = test_a;
b = test_b;

8
ELEC 3010 Lab 05 Guide

f = test_f;
#5; // Wait for output to settle

if (y !== expected_y || zero !== expected_zero) begin


$display("FAIL: %-25s | a=%h b=%h f=%b | y=%h (exp %h), zero=%b (exp %b)",
label, a, b, f, y, expected_y, zero, expected_zero);
errors = errors + 1;
end else begin
$display("PASS: %-25s | a=%h b=%h f=%b | y=%h, zero=%b",
label, a, b, f, y, zero);
end
end
endtask

// Main simulation
initial begin
$display("Starting behavioral ALU testbench...\n");

// ADD tests
run_test(32'h00000000, 32'h00000000, ADD, 32'h00000000, 1, "ADD 0 + 0");
run_test(32'h00000000, 32'hFFFFFFFF, ADD, 32'hFFFFFFFF, 0, "ADD 0 + (-1)");
run_test(32'h00000001, 32'hFFFFFFFF, ADD, 32'h00000000, 1, "ADD 1 + (-1)");
run_test(32'h000000FF, 32'h00000001, ADD, 32'h00000100, 0, "ADD FF + 1");

// SUB tests
run_test(32'h00000000, 32'h00000000, SUB, 32'h00000000, 1, "SUB 0 - 0");
run_test(32'h00000000, 32'hFFFFFFFF, SUB, 32'h00000001, 0, "SUB 0 - (-1)");
run_test(32'h00000001, 32'h00000001, SUB, 32'h00000000, 1, "SUB 1 - 1");
run_test(32'h00000100, 32'h00000001, SUB, 32'h000000FF, 0, "SUB 100 - 1");

// SLT tests
run_test(32'h00000000, 32'h00000000, SLT, 32'h00000000, 1, "SLT 0, 0");
run_test(32'h00000000, 32'h00000001, SLT, 32'h00000001, 0, "SLT 0, 1");
run_test(32'h00000000, 32'hFFFFFFFF, SLT, 32'h00000000, 1, "SLT 0, -1");
run_test(32'h00000001, 32'h00000000, SLT, 32'h00000000, 1, "SLT 1, 0");
run_test(32'hFFFFFFFF, 32'h00000000, SLT, 32'h00000001, 0, "SLT -1, 0");

9
ELEC 3010 Lab 05 Guide

// AND tests
run_test(32'hFFFFFFFF, 32'hFFFFFFFF, AND_, 32'hFFFFFFFF, 0, "AND all 1s");
run_test(32'hFFFFFFFF, 32'h12345678, AND_, 32'h12345678, 0, "AND FFFFFFFF &
12345678");
run_test(32'h12345678, 32'h87654321, AND_, 32'h02244220, 0, "AND 12345678 &
87654321");
run_test(32'h00000000, 32'hFFFFFFFF, AND_, 32'h00000000, 1, "AND 0 & all 1s");

// OR tests
run_test(32'hFFFFFFEF, 32'hFFFFFFFF, OR_, 32'hFFFFFFFF, 0, "OR FFFFFFEF |
FFFFFFFF");
run_test(32'h12345678, 32'h87654321, OR_, 32'h97755779, 0, "OR 12345678 | 87654321");
run_test(32'h00000000, 32'hFFFFFFFF, OR_, 32'hFFFFFFFF, 0, "OR 0 | all 1s");
run_test(32'h00000000, 32'h00000000, OR_, 32'h00000000, 1, "OR 0 | 0");

// Final result
if (errors == 0)
$display("\nAll tests passed!");
else
$display("\n%d test(s) failed.", errors);

$finish;
end

endmodule
2. Your table of test vectors

10
ELEC 3010 Lab 05 Guide

Test F[2:0] A B Y Zero


ADD 0+0 010 00000000 00000000 00000000 1
ADD 0+(-1) 010 00000000 FFFFFFFF FFFFFFFF 0
ADD 1+(-1) 010 00000001 FFFFFFFF 00000000 1
ADD FF+1 010 000000FF 00000001 00000100 0
SUB 0-0 110 00000000 00000000 00000000 1
SUB 0-(-1) 110 00000000 FFFFFFFF 00000001 0
SUB 1-1 110 00000001 00000001 00000000 1
SUB 100-1 110 00000100 00000001 00000003 0
SLT 0,0 111 00000000 00000000 00000000 1
SLT 0,1 111 00000000 00000001 00000001 0
SLT 0,-1 111 00000000 FFFFFFFF 00000001 0
SLT 1,0 111 00000001 00000000 00000000 1
SLT -1,0 111 FFFFFFFF 00000000 00000001 0
AND FFFFFFFF, 000 FFFFFFFF FFFFFFFF FFFFFFFF 0
FFFFFFFF
AND FFFFFFFF, 000 FFFFFFFF 12345678 12345678 0
12345678
AND 12345678, 87654321 000 12345678 87654321 02244220 0
AND 00000000, 000 00000000 FFFFFFFF 00000000 1
FFFFFFFF
OR FFFFFFFF, 001 FFFFFFFF FFFFFFFF FFFFFFFF 0
FFFFFFFF
OR 12345678, 87654321 001 12345678 87654321 97755779 0
OR 00000000, FFFFFFFF 001 00000000 FFFFFFFF FFFFFFFF 0
OR 00000000, 00000000 001 00000000 00000000 00000000 1

3. An image of your simulation waveforms showing the correct operations for the ALU with
all the test vectors. Make sure these are readable and that they’re printed in hexadecimal.
Your test waveforms should include only the following signals in the following order,
from top to bottom: f, a, b, y, zero.

11
ELEC 3010 Lab 05 Guide

Structural

Behavorial

4. The utilization & timing summary.


Structural

12
ELEC 3010 Lab 05 Guide

Utilization Summary

Timing Constraints

Behavioral
Utilization Summary

Timing Constraints

13
ELEC 3010 Lab 05 Guide

Comparison of Behavioral and Structural Verilog Design Approaches


Verilog offers two primary design methodologies: Behavioral and Structural, each suited to
different development needs.
Behavioral Verilog emphasizes describing what a system should do, rather than how it achieves it.
This abstraction allows developers to write cleaner, more concise code, accelerating the
development process. It's particularly advantageous when working with complex control logic or
when quick prototyping is essential. Additionally, its higher-level nature makes modifications and
extensions easier. However, this approach offers limited visibility and control over the underlying
hardware implementation.
In contrast, Structural Verilog involves a detailed specification of the system’s hardware
components and their interconnections. This low-level approach grants designers full control over
the circuit's physical structure, allowing for fine-tuned optimization in terms of timing and
resource usage. The trade-off is that it results in more verbose code, which can be challenging to
maintain and scale in larger systems.
Despite these differences, both styles produce identical functional results for the same inputs, as
verified by simulation test cases. Notably, Structural Verilog requires manual handling of signed
comparisons, while Behavioral Verilog simplifies this using built-in Verilog signed types for
clarity.
From a synthesis perspective, Behavioral Verilog often benefits from more efficient hardware
implementation, thanks to modern tools that optimize high-level descriptions. In contrast,
Structural Verilog provides clearer insight into how the hardware is built, though it might result in
higher resource consumption.
Conclusion:
Behavioral Verilog is best suited for fast development, scalability, and ease of maintenance in
large or complex projects. Structural Verilog, meanwhile, is preferred when precision, control, and
optimization of the hardware architecture are critical.

14

You might also like