为什么 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}}