Verilog同步4位计数器保持最大值,直到给定信号

时间:2018-03-04 04:49:25

标签: verilog counter synchronous test-bench

所以我的verilog中的计数器是4位,我希望它保持最大值1111,直到我给它一个信号从0000再次开始计数。

这是我迄今为止能够提出的:

module contadorAscMax
(
    input iClk,
    input iRst,
    output oQ,
    input iCE,
    input iSignal,
    output [3:0] orCnt
);

reg[3:0] rvCnt_d;
reg[3:0] rvCnt_q;

assign orCnt = rvCnt_q;

always @(posedge iClk or posedge iRst)
begin
    if(iRst)
    begin
        rvCnt_q<=4'b0;
    end
    else
    begin
        if(iCE)
        begin
            rvCnt_q<=rvCnt_d;
        end
        else
        begin
            rvCnt_q<=rvCnt_q;
        end
    end
end
always @*
begin
    rvCnt_d=rvCnt_q+4'b1;
    if(rvCnt_d == 4'b1111)
    begin
        rvCnt_d = rvCnt_d;
    end
    else if(rvCnt_d == 4'b1111 & iSignal)
    begin
        rvCnt_d = 4'b0;
    end
end


endmodule

但它只是等不及等待信号。我对verilog很陌生,所以我的代码很可能对硬件人员没有多大意义,因为我是一名软件工程师,如果这里有一些新手的错误,那就很抱歉。

至于测试平台,这就是我所拥有的:

`timescale 1ns / 1ps

module vtfContMax;

    // Inputs
    reg iClk;
    reg iRst;
    reg iCE;
    reg iSignal;

    // Outputs
    wire oQ;
    wire [3:0] orCnt;

    // Instantiate the Unit Under Test (UUT)
    contadorAscMax uut (
        .iClk(iClk), 
        .iRst(iRst), 
        .oQ(oQ), 
        .iCE(iCE), 
        .iSignal(iSignal), 
        .orCnt(orCnt)
    );

    initial begin
        // Initialize Inputs
        iClk = 1;
        iRst = 1;
        iCE = 1;
        iSignal = 0;

        // Wait 100 ns for global reset to finish
        #10;
        iRst = 0;


        repeat(10)
        begin
            repeat(10)
            begin
                wait(iClk);
                wait(!iClk);
            end
        end
        $stop();

        // Add stimulus here

    end

    always
    begin
        #5;
        iClk = ~iClk;
        #10
        iSignal = ~iSignal;
    end

endmodule

感谢您的帮助:)

1 个答案:

答案 0 :(得分:1)

您已将代码拆分为寄存器和组合部分。虽然这对于复杂逻辑来说是一个好主意,但对于一个简单的4位计数器来说,它有点过头了。

为了解决你的问题,你很接近。像这样的代码的技巧是使用&#39;编程&#39;来制定定义。语言。然后代码从那里流出。
我希望有一个计数器,当信号出现时从1111到0000,其他我想让它计数。
然后导致:

always @(clk or posedge reset)
begin
   if (reset)
      count <= 4'b1111;
   else
   begin
       if (count==4'b1111 && start_signal)
          count <= 4'b0000;
       else
          count <= count + 4'b0001
   end
end

你没有提到,但我从你的代码中看到你还有一个启用(iCE)和一个未使用的输出oQ。然后总数变为:

module contadorAscMax
(
    input iClk,
    input iRst,
//    output oQ,
    input iCE,
    input iSignal,
   output reg [3:0] orCnt
);
always @(iClk or posedge iRst)
begin
   if (iRst)
      orCnt <= 4'b0000; // or should that be 4'b1111
      // Is this really what you want? 
      // It will start counting after a reset!
   else
   begin
       if (iCE)
       begin
          if (orCnt==4'b1111 && iSignal)
             orCnt <= 4'b0000;
          else
             orCnt <= orCnt+ 4'b0001;
       end
   end
end
endmodule

更多评论:
你的重置条件对我来说是有缺陷的,但你必须解决这个问题 给计数器启用信号一个合适的名称:&#39; count_enable&#39;不是&#39;信号&#39;。

最后:我不会使用所有的&#39;和&#39; o。 &#39; o&#39;来自一个模块的信号将是&#39; i&#39;另一个因此,您必须在某处更改信号名称。最好在系统中定义一个信号。如果只是这样你可以在合成后的时序报告或门中找到。