0
votes

(Verilog) The following is a 32-bit Arithmetic Logic Unit (ALU) [see slides]. It has two 2-1 and one 3-1 MUX, a 32-bit Adder, a 32-bit subtractor, and a 16-bit multiplier. The function table shows different functions this ALU performs for different values of F (a 3-bit control signal). Notice the interconnect among different modules inside the ALU. Please describe this ALU using Verilog. Your implementation should start with the smaller blocks showing in the ALU, and then using those smaller blocks to build the whole ALU. In other words, your implementation should promote reusability of smaller modules (i.e., modular). Optimize your implementation if possible.

function table in the image

module adding(r,a,b);

input[31:0] a;
input[31:0] b;
output[31:0] r;

assign r=a+b;

endmodule



module ALU(F,A,B,R);

input[2:0] F;
input[31:0] A;
input[31:0] B;
output[31:0] R;
reg R;

always @(F)
begin
if ( F == 3'b000 ) adding ad(R,A,B);
else if ( F == 3'b001 ) R = A+1;
else if ( F == 3'b010 ) R = A-B;
else if ( F == 3'b011 ) R = A-1;
else if ( F == 3'b10x ) R = A*B;
end

endmodule

this what I did so far but I got errors!! I will continue with the other statement as I know how to make the first small module

2
What are the errors?Paul Floyd

2 Answers

0
votes

Notice some basic verilog syntax issues.

  1. bit width mismatch in declaration of R.
  2. sensitivity list not complete for the always block.
  3. module instantiation is not allowed under a structural if.
  4. I don't know if the undefined branches for F is intended, it is leading to behavior perhaps your don't want.

Since you are mainly working on module partition, it's related to the point 3. You will need to instantiate the basic (reusable) modules separately, and then select the outputs via F.

wire [31:0] adder_b;
wire [31:0] adder_result;

assign adder_b = F[0] ? 32'h1 : B; // select input outside 'adding'

adding ad (adder_result, A, ader_b);

always@(*)begin
  if(F2:1] == 2'b00) R = adder_result;
  ...
end
0
votes

There are many ways to write simple code in verilog.it depends on requirement some time here I presented different ways to write this code.

first by assign keyword and the second by case statements.

assign result = (opcode==3'b000) ? A+B :
                ((opcode==3'b001)? A+1 :
                ((opcode==3'b010)? A-B :
                ((opcode==3'b011)? A-1 : A*B)));

always @(*) begin
casex(opcode) 
3'b000: result=A+B;
3'b001: result=A+1;
3'b010: result=A-B;
3'b011: result=A-1;
3'b1xx: result=A*B;
 endcase
end