串行负载移位寄存器
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
.
之外引用它
在 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' 来初始化一些值。另外,我用移位运算符 <<
.
您只需弄清楚模型中不同信号之间的时序关系,然后根据需要调整代码。
这里有一个 示例 测试台,可以快速测试上述内容。
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
.