Verilog RTL 文件中的始终模块不起作用,但一旦包含在测试台中就可以工作

always module in Verilog RTL file not working, but working once included in testbench

这似乎是一个非常幼稚的问题,但我刚刚开始使用 Verilog(我使用 Xilinx ISE,如果有帮助的话)。

我正在尝试实现一个移位寄存器,将输入 PI 移位 shft 端口中指定的值。当我在 RTL 文件中包含移位逻辑时,移位不起作用,但是当我将与移位相对应的 always 块移动到测试平台时,它起作用了。请帮我解决这个问题!

module shift (PI, shft, clk, PO);
input  [7:0] PI;
input clk;
input [7:0] shft; 
output reg [13:0] PO;
reg [7:0] shft_reg;
always @(posedge clk) begin
  if  (shft_reg[0]||shft_reg[1]||shft_reg[2]||shft_reg[3]||shft_reg[4]||shft_reg[5]||shft_reg[6]||shft_reg[7]) begin 
      PO <= {PO, 0};
      shft_reg <= shft_reg-1;
  end 
end
endmodule

请注意,|| 是逻辑或,理想情况下应与 (shft_reg[0] == 1'b1 ) || ( shft_reg[1] == 1'b1) 等逻辑语句一起使用。

您的 if 语句实际上是对所有位进行按位或运算,即

shft_reg[0] | shft_reg[1] | shft_reg[2] | ...

您可以使用 OR 归约运算符:

|shft_reg

您提供的代码中有错误的 PI for PO。

always @(posedge clk) begin
  if  (|shft_reg) begin 
      PO       <= {PI, 0}; //PI input 
      shft_reg <= shft_reg-1;
  end 
end
module shift (
    input wire clk;
    input wire load;  // load shift register from input
    input wire [7:0] PI;
    input wire [7:0] shft; // this might need less bits
    output wire [13:0] PO;
    );

    reg [7:0] shft_reg;
    reg [13:0] value;
    assign PO = value; // PO follows value 
    always @(posedge clk) begin
      if (load) begin  // initialize shift register and counter
        shft_reg <= shft;
        value <= {6'b0,PI};
      end
      else if (shft_reg) begin // if counter not reached end...
        shft_reg <= shft_reg - 1;  // decrement, and
        value <= {value[13:1],1'b0};  // shift left value 1 bit
      end
  end 
end
endmodule

回想一下,Verilog 支持 >><< 运算符。对于非常数多位操作数,这可能是对多路复用器的浪费,但是:

module shiftcomb (
    input wire [7:0] PI;   // this value is left shifted
    input wire [2:0] shft; // 0 to 7 bits positions
    output wire [14:0] PO; // and is outputted to PO
    );

    assign PO = PI<<shft; // this will generate 15 mutlplexers:
                          // each one with 8 inputs, 3 bit select,
                          // and 1 output.
endmodule