时钟门控 verilog 代码无法正常工作
clock gating verilog code not working correctly
我正在尝试编写一个时钟门控逻辑,允许数据仅在 posedge write_clk_en 处通过。代码在 EDA playground 中编译正确,但根据代码
,输出不是 intended.So
@ (posedge write_clk_en)begin
data_in[3] <= 1'b1;
end
在这种情况下 write_clk_en 被禁用,因此 data_in[3] NBA 应该停止并等待下一个有效姿势(这是 write_clk_en 的下一个姿势) ), data_in[3] 应该写成。但这并没有发生,而是门控时钟周期也被考虑在内,即使 write_clk_en 被门控为第 4 pulse.What 可能是问题,NBA 分配也在发生?。波形显示在这里。
sv代码:
module tb;
logic [4:0] data_in;
logic write_clk;
logic write_clk_en;
logic write_clk_mod;
logic [5:0] write_clk_init;
always//write_clk 500M
begin
write_clk =0;
#10 write_clk = 1;
#10 write_clk = 0;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
#10000 $finish;
end
initial begin
data_in=5'b00000;
write_clk_init = 6'b000000;
write_clk_mod=0;
end
initial begin
write_clk_init =6'b110111;
end
initial begin
repeat (3) begin
@(posedge write_clk)begin
if(write_clk_init[0]==1 || write_clk_init[0]==0)
write_clk_mod<=write_clk_init[0];
end
@(posedge write_clk)begin
if(write_clk_init[1]==1 || write_clk_init[1]==0)
write_clk_mod<=write_clk_init[1];
end
@(posedge write_clk)begin
if(write_clk_init[2]==1 || write_clk_init[2]==0)
write_clk_mod<=write_clk_init[2];
end
@(posedge write_clk)begin
if(write_clk_init[3]==1 || write_clk_init[3]==0)
write_clk_mod<=write_clk_init[3];
end
@(posedge write_clk)begin
if(write_clk_init[4]==1 || write_clk_init[4]==0)
write_clk_mod<=write_clk_init[4];
end
@(posedge write_clk)begin
if(write_clk_init[5]==1 || write_clk_init[5]==0)
write_clk_mod<=write_clk_init[5];
end
end
end
always @ (*) begin
write_clk_en = write_clk & write_clk_mod;
end
initial begin
@ (posedge write_clk_en)begin
data_in[0] <= 1'b1;
end
@ (posedge write_clk_en)begin
data_in[1] <= 1'b1;
end
@ (posedge write_clk_en)begin
data_in[2] <= 1'b1;
end
@ (posedge write_clk_en)begin
data_in[3] <= 1'b1;
end
@ (posedge write_clk_en)begin
data_in[4] <= 1'b1;
end
end
endmodule
在初始块中,将您的 NBA 更改为 BA。 NBA 只能在 always @(posedge clocksignal) block
内使用
还要考虑到在模拟中,@(posedge clocksignal)
块(没有保留字 always
)被视为延迟(等到上升沿 clk 事件发生,然后继续模拟)。顺便说一句,您在最初的陈述中写了这些块,我不确定您是否知道它们的真实行为。我重写了那些 @(posedge)
块以使模拟流程更清晰。
我也将你的一些初始块合并为一个。您拥有的每个初始块同时启动(模拟时间 0)。特别是,write_clk_init
被分配到两个不同的初始块中。
此编辑后的代码按预期工作。它也可以在 https://www.edaplayground.com/x/3VYk
module tb;
reg [4:0] data_in;
reg write_clk;
reg write_clk_en;
reg write_clk_mod;
reg [5:0] write_clk_init;
initial begin
$dumpfile("dump.vcd");
$dumpvars;
#10000 $finish;
end
initial begin
data_in = 5'b00000;
write_clk_init = 6'b110111;
write_clk_mod = 0;
write_clk = 0;
repeat (3) begin
@(posedge write_clk);
if(write_clk_init[0]==1 || write_clk_init[0]==0)
write_clk_mod = write_clk_init[0];
@(posedge write_clk);
if(write_clk_init[1]==1 || write_clk_init[1]==0)
write_clk_mod = write_clk_init[1];
@(posedge write_clk);
if(write_clk_init[2]==1 || write_clk_init[2]==0)
write_clk_mod = write_clk_init[2];
@(posedge write_clk);
if(write_clk_init[3]==1 || write_clk_init[3]==0)
write_clk_mod = write_clk_init[3];
@(posedge write_clk);
if(write_clk_init[4]==1 || write_clk_init[4]==0)
write_clk_mod = write_clk_init[4];
@(posedge write_clk);
if(write_clk_init[5]==1 || write_clk_init[5]==0)
write_clk_mod = write_clk_init[5];
end
end
always @* begin
write_clk_en = write_clk & write_clk_mod;
end
initial begin
@(posedge write_clk_en);
data_in[0] = 1'b1;
@(posedge write_clk_en);
data_in[1] = 1'b1;
@(posedge write_clk_en);
data_in[2] = 1'b1;
@(posedge write_clk_en);
data_in[3] = 1'b1;
@(posedge write_clk_en);
data_in[4] = 1'b1;
end
always begin
write_clk = #10 ~write_clk;
end
endmodule
我正在尝试编写一个时钟门控逻辑,允许数据仅在 posedge write_clk_en 处通过。代码在 EDA playground 中编译正确,但根据代码
,输出不是 intended.So@ (posedge write_clk_en)begin
data_in[3] <= 1'b1;
end
在这种情况下 write_clk_en 被禁用,因此 data_in[3] NBA 应该停止并等待下一个有效姿势(这是 write_clk_en 的下一个姿势) ), data_in[3] 应该写成。但这并没有发生,而是门控时钟周期也被考虑在内,即使 write_clk_en 被门控为第 4 pulse.What 可能是问题,NBA 分配也在发生?。波形显示在这里。
sv代码:
module tb;
logic [4:0] data_in;
logic write_clk;
logic write_clk_en;
logic write_clk_mod;
logic [5:0] write_clk_init;
always//write_clk 500M
begin
write_clk =0;
#10 write_clk = 1;
#10 write_clk = 0;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
#10000 $finish;
end
initial begin
data_in=5'b00000;
write_clk_init = 6'b000000;
write_clk_mod=0;
end
initial begin
write_clk_init =6'b110111;
end
initial begin
repeat (3) begin
@(posedge write_clk)begin
if(write_clk_init[0]==1 || write_clk_init[0]==0)
write_clk_mod<=write_clk_init[0];
end
@(posedge write_clk)begin
if(write_clk_init[1]==1 || write_clk_init[1]==0)
write_clk_mod<=write_clk_init[1];
end
@(posedge write_clk)begin
if(write_clk_init[2]==1 || write_clk_init[2]==0)
write_clk_mod<=write_clk_init[2];
end
@(posedge write_clk)begin
if(write_clk_init[3]==1 || write_clk_init[3]==0)
write_clk_mod<=write_clk_init[3];
end
@(posedge write_clk)begin
if(write_clk_init[4]==1 || write_clk_init[4]==0)
write_clk_mod<=write_clk_init[4];
end
@(posedge write_clk)begin
if(write_clk_init[5]==1 || write_clk_init[5]==0)
write_clk_mod<=write_clk_init[5];
end
end
end
always @ (*) begin
write_clk_en = write_clk & write_clk_mod;
end
initial begin
@ (posedge write_clk_en)begin
data_in[0] <= 1'b1;
end
@ (posedge write_clk_en)begin
data_in[1] <= 1'b1;
end
@ (posedge write_clk_en)begin
data_in[2] <= 1'b1;
end
@ (posedge write_clk_en)begin
data_in[3] <= 1'b1;
end
@ (posedge write_clk_en)begin
data_in[4] <= 1'b1;
end
end
endmodule
在初始块中,将您的 NBA 更改为 BA。 NBA 只能在 always @(posedge clocksignal) block
还要考虑到在模拟中,@(posedge clocksignal)
块(没有保留字 always
)被视为延迟(等到上升沿 clk 事件发生,然后继续模拟)。顺便说一句,您在最初的陈述中写了这些块,我不确定您是否知道它们的真实行为。我重写了那些 @(posedge)
块以使模拟流程更清晰。
我也将你的一些初始块合并为一个。您拥有的每个初始块同时启动(模拟时间 0)。特别是,write_clk_init
被分配到两个不同的初始块中。
此编辑后的代码按预期工作。它也可以在 https://www.edaplayground.com/x/3VYk
module tb;
reg [4:0] data_in;
reg write_clk;
reg write_clk_en;
reg write_clk_mod;
reg [5:0] write_clk_init;
initial begin
$dumpfile("dump.vcd");
$dumpvars;
#10000 $finish;
end
initial begin
data_in = 5'b00000;
write_clk_init = 6'b110111;
write_clk_mod = 0;
write_clk = 0;
repeat (3) begin
@(posedge write_clk);
if(write_clk_init[0]==1 || write_clk_init[0]==0)
write_clk_mod = write_clk_init[0];
@(posedge write_clk);
if(write_clk_init[1]==1 || write_clk_init[1]==0)
write_clk_mod = write_clk_init[1];
@(posedge write_clk);
if(write_clk_init[2]==1 || write_clk_init[2]==0)
write_clk_mod = write_clk_init[2];
@(posedge write_clk);
if(write_clk_init[3]==1 || write_clk_init[3]==0)
write_clk_mod = write_clk_init[3];
@(posedge write_clk);
if(write_clk_init[4]==1 || write_clk_init[4]==0)
write_clk_mod = write_clk_init[4];
@(posedge write_clk);
if(write_clk_init[5]==1 || write_clk_init[5]==0)
write_clk_mod = write_clk_init[5];
end
end
always @* begin
write_clk_en = write_clk & write_clk_mod;
end
initial begin
@(posedge write_clk_en);
data_in[0] = 1'b1;
@(posedge write_clk_en);
data_in[1] = 1'b1;
@(posedge write_clk_en);
data_in[2] = 1'b1;
@(posedge write_clk_en);
data_in[3] = 1'b1;
@(posedge write_clk_en);
data_in[4] = 1'b1;
end
always begin
write_clk = #10 ~write_clk;
end
endmodule