I need to create Verilog code for a 4-bit ALU but I am confused about how to imp
ID: 2085794 • Letter: I
Question
I need to create Verilog code for a 4-bit ALU but I am confused about how to implement the ALU portion.
It needs to be able to complete the following Opcodes:
0000 - add
alut_out = alut_in_a + alu_in_b
0001 - add with Cin
alu_out = alu_in_a + alu_in_b + Cin
0010 - sub tract b from a
alu_out = alu_in_a - alu_in_b
0011 - logical shift right
alu_out = alu_in_a shift right by alu_in_b
0100 - arithmetic shift right
alu_out = alu_in_a arith shift right by alu_in_b
0101 - Logical shift left
alu_out = alu_in_a shift left by alu_in_b
0110 - aright shift left
alu_out = alu_in_a arith shift left by alu_in_b
0111 - bit wise inversion
alu_out = NOT alu_in_a
Cout is the carry out
OF = Over flow
I have created a 1 bit half adder, 1 bit full adder, ripple adder, and have coding for 2 Complement. I need to create an ALU that incorporate the above, but I'm not really sure how to go about that. I know that :
always @ (*) begin
Bin = 4'b0000; Sum = 4'b0000; Cout = 'b0;
case (OPCODE)
// add A + B
4'b0000 : begin
//some code here
end
Here is the informaiton for my 2s complement:
// 2s Complement
module com2s (input [3:0] B, output [3:0] Bn);
wire [3:0] Bn1;
wire OF;
assign Bn1 = ~B;
FA4 fa1 (Bn1, 4'b0000, 1'b1, Bn, Cout, OF);
endmodule
I just need help putting it all together. Thanks.
Explanation / Answer
module HA (a,b,sum,carry);
input a,b;
output sum,carry;
assign sum=a^b;
assign carrry=a&b;
endmodule
module FA(a,b,cin,sum,carry);
input a,b,cin;
output sum,carry;
assign sum=a^b^cin;
assign carry=a&b | b&cin | a&cin;
endmodule
module ripple_add (a,b,cin,sum,carry);
input [3:0] a,b;
input cin;
output [3:0] sum;
output carry;
wire w1,w2,w3;
FA a1 (a[0],b[0],cin,sum[0],w1);
FA a2 (a[1],b[1],w1,sum[1],w2);
FA a3 (a[2],b[2],w2,sum[2],w3);
FA a4 (a[3],b[3],w3,sum[3],carry);
endmodule
module com2s (input [3:0] B,output [3:0] Bn);
wire [3:0] Bn1;
wire OF;
assign Bn1=~B;
ripple_add fa1 (Bn1,4'b0000,1'b1,Bn,OF);
endmodule
module alu (alu_in_a,alu_in_b,cin,opcode,clk,rst,alu_out,carry);
input rst,clk,cin;
input [2:0] opcode;
input [3:0] alu_in_a,alu_in_b;
output reg [3:0] alu_out;
output reg carry;
wire [4:0] out1,out2,out3;
wire [3:0] bn;
ripple_add alu1 (alu_in_a,alu_in_b,1'b0,out1[3:0],out1[4]);
ripple_add alu2 (alu_in_a,alu_in_b,cin,out2[3:0],out2[4]);
com2s alu3 (alu_in_b,bn);
ripple_add alu4 (alu_in_a,bn,1'b0,out3[3:0],out3[4]);
always @(posedge clk or negedge rst)
begin
if(!rst)
{alu_out,carry}<=5'b0;
else
case(opcode)
3'd0:begin
alu_out<=out1[3:0];
carry<=out1[4];
end
3'd1:begin
alu_out<=out2[3:0];
carry<=out2[4];
end
3'd2:begin
alu_out<=out3[3:0];
carry<=out3[4];
end
3'd3:begin
alu_out<=alu_in_a >> alu_in_b;
carry<=0;
end
3'd4:begin
alu_out<=alu_in_a >>> alu_in_b;
carry<=0;
end
3'd5:begin
alu_out<=alu_in_a << alu_in_b;
carry<=0;
end
3'd6:begin
alu_out<=alu_in_a <<< alu_in_b;
carry<=0;
end
3'd7:begin
alu_out<=~alu_in_a;
carry<=0;
end
endcase
end
endmodule
module alu_tst;
reg [3:0] a,b;
reg [2:0] opcode;
reg cin;
reg clk,rst;
wire [3:0] out;
wire cout;
alu a1 (.alu_in_a(a),.alu_in_b(b),.cin(cin),.opcode(opcode),.clk(clk),.rst(rst),.alu_out(out),.carry(cout));
always #5 clk=!clk;
initial
begin
clk=0;
$monitor("alu_in_a=%b alu_in_b=%b cin=%b opcode=%b rst=%b alu_out=%b carry=%b",a,b,cin,opcode,rst,out,cout);
rst=1;
#10;
@(negedge clk)
rst<=0;
@(negedge clk)
rst<=1;
repeat(10)
begin
@(negedge clk)
begin
a=$random%10;
b=$random%10;
cin=$random;
opcode=$random;
end
end
$finish;
end
endmodule
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.