为什么我的d触发器不等待时钟的上升沿?(Why is my D Flip Flop not wait

2019-09-20 06:45发布

正如我所已知的,d触发器样品其输入值在时钟的每个上升沿。

因此,将产生1个周期的延迟。 对?

但为什么我的d触发器不会产生1个周期的延迟?

         module flipflop(
             input clk,
             input rstn,
             input [7:0] i_data,
             output reg [7:0] o_data
         );

             always @(posedge clk) begin
                     if (~rstn) begin
                             o_data <= 0;
                     end
                     else begin
                             o_data <= i_data;
                     end
             end
         endmodule

       module test;
           reg clk;
           reg [7:0] i_data;
           reg rstn;
           wire [7:0] o_data;

           initial begin
                   clk = 0;
                   rstn = 1;
                   i_data = 0;
                   #20;
                   rstn = 0;

                   #30;
                   rstn = 1;
                   #20;
                   i_data = 8'hFA;
                   #20;
                   i_data = 8'hF0;
                   #20
                   i_data = 8'hF1;
                   #20
                   #10 $finish;
           end

           always #10 clk = !clk;

           flipflop flipflop(
                   .clk (clk),
                   .rstn(rstn),
                   .i_data(i_data),
                   .o_data(o_data)
           );

           initial begin
                   $dumpfile("flipflop.vcd");
                   $dumpvars();
           end
       endmodule

我的d触发器的功能,如在这里组合电路。

Answer 1:

该模拟器可能做这样的事情:

       initial begin
               clk = 0;
               rstn = 1;
               i_data = 0;
               #10;
               clk = !clk;
               #10;
               rstn = 0;
               clk = !clk;

               #10;
               clk = !clk;
               #10;
               clk = !clk;
               #10;
               rstn = 1;
               clk = !clk;
               #10;
               clk = !clk;
               #10
               i_data = 8'hFA; //Input updated
               clk = !clk;     //Clock event
                               //o_data assigned here
               #10;
               clk = !clk;
               #10;
               i_data = 8'hF0;
               clk = !clk;
               #20
               i_data = 8'hF1;
               #20
               #10 $finish;
       end

由于时钟事件在您的测试平台,每次最后一步出现,它看起来像翻牌被立即分配。 你可能希望你的测试平台是完全从属于关闭时钟所以使用@马蒂的建议(posedge ...)将实现这一目标。 你也可以简单地在开始的时候耽误你的任务一次:

       initial begin
               clk = 0;
               #1;
               rstn = 1;
               i_data = 0;
               #20;
               rstn = 0;

               #30;
               rstn = 1;
               #20;
               i_data = 8'hFA;
               #20;
               i_data = 8'hF0;
               #20
               i_data = 8'hF1;
               #20
               #10 $finish;
       end


Answer 2:

你对Verilog仿真事件调度微妙之处跑起来! 更改数据的分配使用非阻塞赋值可能是最简单的解决。

#20;
i_data <= 8'hFA;
#20;
i_data <= 8'hF0;
#20
i_data <= 8'hF1;
#20

发生了什么事在你原来的版本是,时钟和输入数据被安排在同一时间发生。 由于模拟器只能做一件事的时候,它必须决定是否将首先改变时钟或数据。 它首先改变的数据,所以当时钟边沿出现时,输入的数据已经改变为下一个值,所以它看起来像数据通过FF打滑。

非阻塞赋值( <=所有预定的阻塞赋值(发生后, = )已经完成。 所以使数据分配非阻塞确保它们的联锁分配时钟边沿后发生。

另一种方式重写的东西的工作将是:

initial begin
   @(posedge clk) i_data = 8'hFA;
   @(posedge clk) i_data = 8'hF0;
   @(posedge clk) i_data = 8'hF1;
end


文章来源: Why is my D Flip Flop not waiting for the positive edge of the clock?
标签: verilog