Anda di halaman 1dari 3

Bahcesehir University

CMPE2007 DIGITAL DESIGN LAB– LAB ASSIGNMENT 6

TITLE: Arithmetic Logic Unit design using Behavioral Verilog

DESCRIPTION:

In this lab you are going design a simplistic version of a digital circuit in your CPUs called Arithmetic
Logic Unit. This unit is responsible from, as the name suggests, doing arithmetic and logic operations
in CPU. You will implement this by using Behavioral Verilog, which strongly resembles imperative
programming languages like C, Java, etc. ALU simply decodes the operation code, and calculates the
result of decoded operation. The operations that our ALU will support will initially be addition,
multiplication, bitwise-and, bitwise-xor. Then we will see more operation that Verilog offers in detail,
like comparison/equality, concatenation, replication, left/right shift, unary binary operations by
extending our ALU.

1) Create a Xilinx Project and create a new Verilog source file and name it “alu.v”.

2) Your design should take two 4-bit inputs as operands that ALU will do operation on, one 2-bit
input as the operation code of the operation that ALU will do, and give an 8-bit output since
multiplying two 4-bit numbers may require 8-bit space. Structure of ALU module will look like
following figure.

3) Type following code into the file you have created. It defines the module shown above in
Behavioral Verilog. The list within the parenthesis after always keyword is called sensitivity list.
Whenever any value in that list changes, the code inside always block is executed. Since the
output depends all of the inputs sensitivity list will include all of them. Note that the output is
defined as reg, because it is assigned to within the always block.

module alu(in1, in2, op_code, out);

input [3:0] in1, in2;


input [1:0] op_c;
output reg [7:0] out;

always @(in1 or in2 or op_c) begin


//code to calculate out based on
end
endmodule

4) Now we need to define how out_val is calculated. It has to check the op_code, and based on its
value, it should decide which operation’s result should be stored in out_val. Operations are
addition (op_code = 2’b00), multiplication (op_code = 2’b01), bitwise-and (op_code = 2’b10) and
bitwise-xor (op_code = 2’b11). To do this we can use control flow structure named case, similar
to the switch statement you already seen in C.

case (op_code)
2’b00 : out_val = in1_val + in2_val;
2’b01 : out_val = in1_val * in2_val;
2’b10 : out_val = in1_val & in2_val;
default : out_val = in1_val ^ in2_val;
endcase

5) Create a new Verilog module file and call it t_alu.v. Run the simulation with the following
testbench codes which will automatically assign all the possible combinations for operations
given the n_bit_code:

module t_alu;
parameter n_bit_code = 2;

reg [3:0] in1, in2;


reg [(n_bit_code-1):0] code;
wire [7:0] out;
initial begin
$monitor($time,,"%b %b %b -->> %b", in1, in2, code, out);
in1 = 13;
in2 = 7;
code = 0;
repeat (1 << (n_bit_code-1)) begin
#10 code = code + 1;
end
end

initial #((1 << n_bit_code) * 10) $finish;


alu design_under_test(in1, in2, code, out);
endmodule
6) Now you can test your ALU design using your FPGA boards.

7) Let’s now extend our design to support more operations. We will add 4 more operations, so we
need 1 more bit in op_code. Change the 4th line of your code so that op_code is now 3-bits:

input [2:0] op_code;

8) Here are some other operators that you can use in Verilog.

a) Multi-bit unary bitwise operators : & w, ^ w, | w. These operators do the operation among
the bits of a multi-bit value. For example ^ 5’b10110 will give you 1’b1.

b) Concatenation and replication operators :

i) {n{w}} : Replicates bitstring w for n times. For example {5{2’b01}} will give you
10’b0101010101. NOTE that writing bitstrings without a size will make it have 32-bit size,
which will make your design to be subject to errors for replication and concatenation
operations, especially. So {5{1}} will give 000000….001, but {5{1’b1}} will give 11111 as
expected.

ii) {w, t, …} : Concatenates two or more bitstrings w, t etc. and obtains a single bitstring. For
example {3’b101, 2’11} will give you 5’b10111.

c) Single and slice indexing operator :

i) w[i] : retreives a single bit of a bitstring w at index i. For example if w is defined like reg w
[4:0]; and w = 5’10111, then w[3] will give us 0.

ii) w[i:j] : retrieves i – j +1 (or j – i + 1, depending on the order in the declaretion) bits from
the bitstring between indexes i and j, included. For example w[3:1] = 011. NOTE that if w
is defined so that the MSB is at the leftmost place (which we had most commonly), then i
>= j, otherwise your code will not pass Check Syntax.

If you would like to see all available operators along with examples of them, you may checkout
following links:

http://www.asic-world.com/verilog/operators1.html
http://www.asic-world.com/verilog/operators2.html

9) Now we will add four more operations to the case statement and then try on FPGA.

3’b100 : out_val = { in1[0], in1[1], in1[2], in1[3], in2[0], in2[1], in2[2], in2[3] }; // bits reversed
3’b101 : out_val = | { in1, in2 }; // do operands have any 1’s in them?
3’b110 : out_val = { in2[1:0], in1, in2[3:2] }; // 2-bits rotated right
3’b111 : out_val = { in1[1:0], in2, in1[3:2] }; // 2-bits rotated left

Anda mungkin juga menyukai