首页 > 解决方案 > Verilog - 故障定时信号到模块

问题描述

我在理解为什么使用下面的注册模块得到不同的结果时遇到了一些麻烦。

module register (clk, rst, ld, din, dout);
   input clk;
   input rst;
   input ld;
   input [3:0] din;
   output reg [3:0] dout;

   always @(posedge clk or posedge rst) begin
      if(rst) dout  = 4'b0;
      else if(ld) dout <= din;
      else dout <= dout;
   end

endmodule // rgister

module controller(clk, rst, ldI);
   input  clk;
   input  rst;
   output ldI;

   reg [2:0]   ps, ns;

   always @(posedge clk or posedge rst) begin
      if(rst) ps <= 3'b0;
      else ps <= ns;
   end

   always @(ps) begin
      case(ps)
    3'b000 : ns <= 3'b001;
    3'b001 : ns <= 3'b010;
    3'b010 : ns <= 3'b011;
    3'b011 : ns <= 3'b100;
    3'b100 : ns <= 3'b101;
    3'b101 : ns <= 3'b110;
    3'b110 : ns <= 3'b111;
    3'b111 : ns <= 3'b000;
      endcase // case (ps)
   end // always @ (ps)

   assign ldI = (ps == 3'b001) ? 1'b1 : 1'b0;

endmodule // reg_controller

module datapath (clk, rst, ldI, din);
   input clk;
   input rst;
   input ldI;
   input [3:0] din;

   register Ireg (clk, rst, ldI, din);

endmodule

module top (clk, rst, din);
   input clk;
   input rst;
   input [3:0] din;

   wire        ldI;

   datapath   dp (clk, rst, ldI, din);
   controller cp (clk, rst, ldI);

endmodule // top

module tb;
   reg clk, rst;
   reg [3:0] din;
   reg       ld;

   initial begin
      rst = 1'b1;
      clk = 1'b0;
      din = 4'b0;
      ld  = 1'b0;
   end

   top      uut (clk, rst, din);
   register r   (clk, rst, ld, din);

   always #5 clk = ~clk;

   initial begin
      #21 rst = 1'b0;
      din = 4'h1;
      @(posedge clk);
      din = 4'h2;
      ld = 1'b1;
      @(posedge clk);
      ld = 1'b0;
      din = 4'h3;
      @(posedge clk);
      din = 4'h4;
      @(posedge clk);
      din = 4'h5;

      #50;

      $finish;
   end // initial begin


endmodule

这是波形输出: 在此处输入图像描述

在上面的波形中,蓝色是 tb 中的“r”,绿色是数据路径中的 Ireg。我已经剥离了数据路径和控制器中的大部分内容,以缩小我遇到的这个时序问题。

我想让 Ireg 包含值 2。我可以做哪些调整来获得这个值?我尝试在寄存器模块中使用时钟的 negedge 并且它可以工作,但我认为这不是正确的解决方案。

谢谢

标签: verilog

解决方案


问题是你的tb模块。您对您的输入进行了阻塞分配,这些分配@(posedge clk)会在您的寄存器中产生比赛。在您的 tesbench 中也使用非阻塞分配,或者更改为negedge


推荐阅读