串行负载移位寄存器

Serial-Load-Shift-Register

serial load shift register 中,我如何确保在至少加载五个数据之前未禁用班次

module serial_load_shift_register(
  input logic clk         ,
  input logic shift_enable,
  input logic d_in        ,
  output logic q
);
  logic [0:4] register;
  always @(posedge clk) begin
    register[0] <= shift_enable ? d_in        : register[0];
    register[1] <= shift_enable ? register[0] : register[1];
    register[2] <= shift_enable ? register[1] : register[2];
    register[3] <= shift_enable ? register[2] : register[3];
    register[4] <= shift_enable ? register[3] : register[4];
  end
  assign q = register[4];
endmodule: serial_load_shift_register

有几种方法可以做到这一点。通常,您需要一种计数器,用于使您的启用在多个周期内保持活动状态。例如,您可以使用另一个寄存器将启用信号的值移位 5 个周期左右。这是一个例子。

module serial_load_shift_register(
  input logic clk         ,
  input logic reset,
  input logic shift_enable,
  input logic d_in        ,
  output logic q
);
  logic [4:0] register;
  logic [4:0] enable_validator;
  
  always @(posedge clk) begin
    if (reset) begin
      enable_valida <= 0;
      register <= 0;
    end
    else begin
       enable_valid <= (enable_valid << 1) | shift_enable;
    
       if (|enable_valid)  begin
          register <= (register << 1) | d_in;
       end
    end
  end
  assign q = register[4];
endmodule: serial_load_shift_register

上面例子中的enable_valid就是这样一个寄存器。它使 enable 标志在其任何位为 non-zero 时保持活动状态,从而允许 register 保持移位,即使 enable_shift信号消失

我对您的代码进行了几次更新。首先,我添加了一个 'reset' 来初始化一些值。另外,我用移位运算符 <<.

替换了你的 bit-by-bit 移位

您只需弄清楚模型中不同信号之间的时序关系,然后根据需要调整代码。

这里有一个 示例 测试台,可以快速测试上述内容。

module tb;
  logic clk, reset, shift_enable, d_in, q;
 
  serial_load_shift_register shifter(.clk(clk), .reset(reset), .shift_enable(shift_enable), .d_in(d_in), .q(q));
  
  initial begin 
    clk = 0;
    forever #2 clk = !clk;
  end
  
  initial begin
    reset = 0;
    d_in = 0;
    shift_enable = 0;
    
    #4 reset = 1;
    #4 reset = 0;
    #4 d_in = 1;
    #4 shift_enable = 1;
    #8 shift_enable = 0;
       d_in = 0;
    #30 $finish;
  end
  
  always @* begin
    $display("%0t> clk %b, shift_enable = %b, d_in = %b, q ==> %b (%b %b)", $time, clk, shift_enable, d_in, q,
            shifter.enable_validator, shifter.register);
  end
endmodule

您可以做的是将 shift_enable 信号也放入移位寄存器,从而为您提供该信号的 历史记录 。如果该寄存器是 non-zero,则使用该条件来控制数据的移位。

module serial_load_shift_register(
  input logic clk         ,
  input logic shift_enable,
  input logic d_in        ,
  output logic q
);
  logic [0:3] register;
  always @(posedge clk) begin
    logic [0:4] enable;
    enable = {enable,shift_enable};
    if (enable != 0) register <= {register, d_in};
  end
  assign q = register[0];
 
endmodule: serial_load_shift_register

请注意,对 enable 的分配并未使用 NBA。这意味着在赋值后引用 enable 的语句使用当前值,而不是前一个循环的值。竞争条件没有问题,因为我在 always 块中声明了 enable 本地,所以没有人可以在 always.

之外引用它