0

所以我的计数器是 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

谢谢你的帮助 :)

4

1 回答 1

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”。因此,您必须在某处更改信号名称。最好在您的系统中有一个定义好的信号。如果只有这样,您可以在综合后的时序报告或门中找到。

于 2018-03-04T10:07:40.297 回答