2012-07-26 15 views
5

Như tôi đã biết, D flipflop lấy mẫu giá trị đầu vào của nó ở mọi cạnh dương của đồng hồ.Tại sao chiếc Flip Flop của tôi lại không chờ đợi sự tích cực của đồng hồ?

Do đó, nó sẽ tạo ra độ trễ 1 chu kỳ. Đúng?

Nhưng tại sao nút lật D của tôi không tạo ra độ trễ 1 chu kỳ?

  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 

dff no delay

D chức năng flip flop của tôi giống như một mạch tổ hợp ở đây.

Trả lời

5

Các mô phỏng có lẽ làm một cái gì đó như thế này:

 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 

Kể từ khi sự kiện đồng hồ đang xảy ra cuối cùng trong mỗi bước thời gian từ của bạn testbench, có vẻ như flop đang được gán ngay lập tức. Bạn có thể muốn testbench của bạn được hoàn toàn slaved ra khỏi đồng hồ để gợi ý của Marty sử dụng @ (posedge ...) sẽ đạt được điều này. Bạn cũng có thể đơn giản trì hoãn bài tập của mình một lần ngay từ đầu:

 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 
+0

Đó là cách hay để giải thích vấn đề. – Marty

5

Bạn đã chạy lên chống lại sự tinh chỉnh lập lịch sự kiện mô phỏng Verilog! Việc thay đổi các bài tập dữ liệu để sử dụng các bài tập nonblocking có lẽ là cách sửa chữa dễ nhất.

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

Điều đang xảy ra trong phiên bản gốc là đồng hồ và dữ liệu đầu vào được lên lịch diễn ra cùng một lúc. Vì bộ mô phỏng chỉ có thể làm một việc tại một thời điểm, nó phải quyết định xem nó có thay đổi đồng hồ hay dữ liệu trước không. Nó đã thay đổi dữ liệu đầu tiên, do đó, khi cạnh đồng hồ xuất hiện, dữ liệu đầu vào đã được thay đổi thành giá trị tiếp theo để có vẻ như dữ liệu trượt qua FF.

Bài tập không được chặn (<=) được lên lịch để xảy ra sau khi tất cả các bài tập chặn (=) đã được thực hiện. Vì vậy, làm cho việc phân bổ dữ liệu nonblocking đảm bảo rằng chúng xảy ra sau các cạnh đồng hồ được chỉ định chặn.

Một cách khác để viết lại những thứ để làm việc sẽ là:

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

Marty, bạn có thể xem lại đề xuất cuối cùng của mình không? Nó nghĩ rằng nó phải là '@ (posedge clk) i_data <= 8'hFA;' (không chặn). Bằng cách này, sau khi đồng hồ được cập nhật, chúng tôi có 2 @ (cledge posedge). Cả hai đều sử dụng nhiệm vụ không chặn để kết quả sẽ giống nhau bất kể thứ tự thực hiện: flipflop sẽ đăng ký một giá trị cũ & 'i_data' sẽ được cập nhật với giá trị mới. Tuy nhiên, nếu chúng ta có một nhiệm vụ ngăn chặn để 'i_data' và nonblocking để' o_data' đầu ra sẽ phụ thuộc vào lịch trình mô phỏng. Thử nghiệm trên 'irun' của Cadence tôi nhận được kết quả sai lầm, giống với vấn đề ban đầu của OP. – RaZ

Các vấn đề liên quan