【问题标题】:Verilog Synchronous 4 bit Counter stay on max value until given signalVerilog 同步 4 位计数器保持最大值直到给定信号
【发布时间】:2018-03-04 04:49:24
【问题描述】:

所以我的计数器是 4 位的 verilog,我希望它保持最大值 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

感谢您的帮助:)

【问题讨论】:

    标签: verilog counter synchronous test-bench


    【解决方案1】:

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

    为了解决你的问题,你很接近。像这样的代码的诀窍是使用“编程”语言进行定义。然后代码从中流出。
    我想要一个计数器,当信号出现时,它从 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
    

    更多评论:
    你的重置条件在我看来有缺陷,但你必须解决这个问题。
    给计数器启用信号起一个像样的名字:'count_enable' 而不是 'signal'。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      相关资源
      最近更新 更多