为什么 shift 命令不能在 Verilog 中串联使用?
Why is shift command not working in concatenation in Verilog?
我在这里发布所有代码。
我在 always 块中收到串联警告,但我没有收到:
与未调整大小的文字连接;将解释为 32 位
module DECSTAGE(
input [31:0] Instr, ALU_out,MEM_out,
input RF_WrEn,RF_WrData_sel,RF_B_sel,
input Clk,
output reg [31:0]Immed,
output [31:0] RF_A,RF_B
);
wire [5:0]Opcode,func;
wire [4:0]rs,rd,rt;
wire [15:0]Immediate ;
/*
Decoding instruction in:
- Opcode
- rs,rd,rt
- func
- Immediate
*/
assign Opcode[5:0] = Instr[31:26];
assign rs[4:0] = Instr[25:21];
assign rd[4:0] = Instr[20:16];
assign rt[4:0] = Instr[15:11];
assign func[5:0] = Instr[5:0];
assign Immediate[15:0] = Instr[15:0];
// Needed variables for always block
reg [4:0]adr2;
reg [31:0]din;
// Creating the Register File with 32 registers
Register_File_RF rgf_RF (.Adr1(rs),.Adr2(adr2),.Awr(rd),.Dout1(RF_A),.Dout2(RF_B),.Din(din),.WrEn(RF_WrEn),.Clk(Clk));
always @(posedge Clk)begin
// MUX for rd/rt
if (RF_B_sel)begin
adr2 = rd;
end else begin
adr2 = rt;
end
// MUX for ALU_out/MEM_out
if (RF_WrData_sel)begin
din = ALU_out;
end else begin
din = MEM_out;
end
// Selecting the Operation for the Immediate
// SignExtend(Immediate)
if (Opcode == 6'b111000 || Opcode == 6'b110000 || Opcode ==6'b000111 || 6'b001111 || 6'b011111)begin
Immed = {{16{Immediate[15]}}, Immediate[15:0]};
// Immediate << 16 (zeroFill)
end else if (Opcode == 6'b111001)begin
Immed = {{Immediate[15:0]},{16{0}}};
// ZeroFill(Immediate)
end else if (Opcode == 6'b110010 || Opcode == 6'b110011)begin
Immed = {{16{0}},Immediate[15:0]};
// SignExtend(Immediate)<<2
end else if (Opcode ==6'b111111 || Opcode == 6'b000000 || Opcode == 6'b000001)begin
Immed = {{16{Immediate[15]}},Immediate[15:0]}<<2;
// ZeroFill(Immediate) (7 downto 0)
end else if (Opcode == 6'b000011)begin
Immed = {{16'b000000000000000000000000},Immediate[7:0]};
end
end
endmodule
根据我的模拟,Immed是一个32位的,在所有16位中取Immediate[15]的符号,取其余位立即[15:0],但它从不执行移位命令。
这是我的模拟:
initial begin
// Initialize Inputs
Instr = 0;
ALU_out = 0;
MEM_out = 0;
RF_WrEn = 0;
RF_WrData_sel = 0;
RF_B_sel = 0;
Clk = 0;
#20;
Instr = 32'b11111100000000000000000000000011;
RF_B_sel = 1;
// Add stimulus here
end
您永远不会执行带有 shift 的行,因为 if
条件始终为真。以下行始终为真,因为您在最后 2 次比较中错误地省略了 Opcode ==
:
if (Opcode == 6'b111000 || Opcode == 6'b110000 || Opcode ==6'b000111 || 6'b001111 || 6'b011111)begin
将行更改为:
if (Opcode == 6'b111000 || Opcode == 6'b110000 || Opcode ==6'b000111 || Opcode ==6'b001111 || Opcode ==6'b011111)begin
您收到警告,因为复制的串联语法是非法的。您需要使用大小文字而不是 0
。您需要更改:
{16{0}}
至:
{16{1'b0}}
我在 always 块中收到串联警告,但我没有收到:
与未调整大小的文字连接;将解释为 32 位
module DECSTAGE(
input [31:0] Instr, ALU_out,MEM_out,
input RF_WrEn,RF_WrData_sel,RF_B_sel,
input Clk,
output reg [31:0]Immed,
output [31:0] RF_A,RF_B
);
wire [5:0]Opcode,func;
wire [4:0]rs,rd,rt;
wire [15:0]Immediate ;
/*
Decoding instruction in:
- Opcode
- rs,rd,rt
- func
- Immediate
*/
assign Opcode[5:0] = Instr[31:26];
assign rs[4:0] = Instr[25:21];
assign rd[4:0] = Instr[20:16];
assign rt[4:0] = Instr[15:11];
assign func[5:0] = Instr[5:0];
assign Immediate[15:0] = Instr[15:0];
// Needed variables for always block
reg [4:0]adr2;
reg [31:0]din;
// Creating the Register File with 32 registers
Register_File_RF rgf_RF (.Adr1(rs),.Adr2(adr2),.Awr(rd),.Dout1(RF_A),.Dout2(RF_B),.Din(din),.WrEn(RF_WrEn),.Clk(Clk));
always @(posedge Clk)begin
// MUX for rd/rt
if (RF_B_sel)begin
adr2 = rd;
end else begin
adr2 = rt;
end
// MUX for ALU_out/MEM_out
if (RF_WrData_sel)begin
din = ALU_out;
end else begin
din = MEM_out;
end
// Selecting the Operation for the Immediate
// SignExtend(Immediate)
if (Opcode == 6'b111000 || Opcode == 6'b110000 || Opcode ==6'b000111 || 6'b001111 || 6'b011111)begin
Immed = {{16{Immediate[15]}}, Immediate[15:0]};
// Immediate << 16 (zeroFill)
end else if (Opcode == 6'b111001)begin
Immed = {{Immediate[15:0]},{16{0}}};
// ZeroFill(Immediate)
end else if (Opcode == 6'b110010 || Opcode == 6'b110011)begin
Immed = {{16{0}},Immediate[15:0]};
// SignExtend(Immediate)<<2
end else if (Opcode ==6'b111111 || Opcode == 6'b000000 || Opcode == 6'b000001)begin
Immed = {{16{Immediate[15]}},Immediate[15:0]}<<2;
// ZeroFill(Immediate) (7 downto 0)
end else if (Opcode == 6'b000011)begin
Immed = {{16'b000000000000000000000000},Immediate[7:0]};
end
end
endmodule
根据我的模拟,Immed是一个32位的,在所有16位中取Immediate[15]的符号,取其余位立即[15:0],但它从不执行移位命令。
这是我的模拟:
initial begin
// Initialize Inputs
Instr = 0;
ALU_out = 0;
MEM_out = 0;
RF_WrEn = 0;
RF_WrData_sel = 0;
RF_B_sel = 0;
Clk = 0;
#20;
Instr = 32'b11111100000000000000000000000011;
RF_B_sel = 1;
// Add stimulus here
end
您永远不会执行带有 shift 的行,因为 if
条件始终为真。以下行始终为真,因为您在最后 2 次比较中错误地省略了 Opcode ==
:
if (Opcode == 6'b111000 || Opcode == 6'b110000 || Opcode ==6'b000111 || 6'b001111 || 6'b011111)begin
将行更改为:
if (Opcode == 6'b111000 || Opcode == 6'b110000 || Opcode ==6'b000111 || Opcode ==6'b001111 || Opcode ==6'b011111)begin
您收到警告,因为复制的串联语法是非法的。您需要使用大小文字而不是 0
。您需要更改:
{16{0}}
至:
{16{1'b0}}