我的大学有一项 Verilog 学校作业,需要为 RISC-V 处理器创建 ALU。在ALU中,我需要执行AND、OR、XOR、sub、add、按位左移和右移、小于和算术右移运算。对于 sub、add 和 less 操作,教授告诉我们,我们需要先对它们进行签名,然后再进行操作,特别是对于 less,我需要再次对它们进行无签名。我已经为 ALU 创建了这段代码:
module alu
(output reg zero,
output reg [31:0] result,
input wire [31:0] op1, op2,
input wire [3:0] alu_op);
// extra
wire [31:0] signed_op1, signed_op2, unsigned_op1;
wire [4:0] shiftamount;
wire [31:0] shiftedresult;
// creating the signed number of op1, op2.
assign signed_op1 = {{32{op1[31]}},op1};
assign signed_op2 = {{32{op2[31]}},op2};
// making them unsigned again, only for >>>> operation.
assign unsigned_op1 = signed_op1[31:0];
always @ (alu_op or op1 or op2) // this block changes whenever alu_op, op1, or op2 changes
begin
case(alu_op)
4'b0000: result <= op1 & op2; // AND
4'b0001: result <= op1 | op2; // OR
4'b0010: result <= signed_op1 + signed_op2; // +
4'b0110: result = signed_op1 - signed_op2; // -
4'b0111: result = (signed_op1 < signed_op2); // smaller than
4'b1000: result = op1 >> shiftamount; // bitwise shift right
4'b1001: result = op1 << shiftamount; // bitwise shift left
4'b1010: shiftedresult = signed_op1 >>> shiftamount; // arithmetic shift right
assign result = shiftedresult; //making in unsigned
4'b1101: result = op1 ^ op2; // XOR
default : result = 0;
endcase
end
always @(result)
begin
if (result == 0)
begin
Zero <= 1;
end else
begin
Zero <= 0;
end
end
endmodule
assign signed_op1 = {{32{op1[31]}},op1};
行我从聊天gpt中看到它用于将未签名的输入转换为签名的,但我不确定它是否正确。聊天gpt写的对还是错。我现在子尚未完成,因为我需要先以二进制补码完成它,除此之外我还需要更改代码中的某些内容吗?然后,我们需要将结果恢复为无符号
只需声明
signed
变量
wire signed [31:0] signed_op1, signed_op2;
此外,请确保您知道所需的数字范围。
4 位无符号数的范围:0 到 15
4 位有符号数的范围:-8 到 7
此外,还可以在
signed
和 unsigned
数字之间进行转换。使用 $signed
和 $unsigned
。示例:
wire signed [3:0] a_sign;
wire [3:0] b_unsign;
assign a_sign = $signed(b_unsign);
assign b_unsign = $unsigned(a_sign);