Verilog代码,结构相同,风格相同。为什么一个有效但另一个有效?我哪里做错了?

问题描述 投票:0回答:2

我会直言不讳。我有一个简单的计数器,试图模仿时钟的工作原理。我有一个名为counter60sec的模块和另一个名为counter12hr的模块

counter12hr

    module counter12hr(reset, hourInc, overflowOut, hrCounter);
        input reset;
        input hourInc;
        output overflowOut;
        output [3:0] hrCounter;
        reg overflowOut;
        reg [3:0] hrCounter; //0'b1101 == 13 hours

        //Initialize counter
        initial begin
            overflowOut = 1'b0;
            hrCounter = 4'b0; //once hour reaches 12:59:59, it is supposed to go back to zero
            end
        //Everytime hrInc is one, increment hrCounter
        always@(negedge reset or posedge hourInc) begin
            overflowOut = 1'b0;
            if(reset == 1'b0) begin
                overflowOut = 1'b0;
                hrCounter = 4'b0;
            end
            else begin
                if (hourInc == 1'b1) begin
                    hrCounter = hrCounter + 1'b1;
                end 
            end
        end

        always@(negedge hrCounter) begin
            if (hrCounter == 4'b1100) begin
                overflowOut = 1'b1;
                hrCounter = 4'b0;
            end
        end
    endmodule

counter60sec

    module counter60sec(reset, secInc, minOut, secCounter);
        input reset;
        input secInc;
        output minOut;
        output [5:0] secCounter;
        reg [5:0] secCounter; //0'b111100 == 60 seconds. 
        reg minOut;

        //Initialize counter
        initial begin
            minOut = 1'b0;
            secCounter = 6'b0;
            end
        //Everytime secInc is one, increment secCounter
        always@(posedge secInc or negedge reset) begin
            minOut = 1'b0;
            if(reset == 1'b0) begin
                minOut = 1'b0;
                secCounter = 6'b0;
            end
            else begin
                if (secInc == 1'b1) begin
                    secCounter = secCounter + 1'b1;
                end
            end
        end

        //output minOut to 1 to signal minute increase when secCounter hits 111100 in binary
        always@(negedge secCounter) begin
            if(secCounter == 6'b111100) begin
                minOut = 1'b1;
                secCounter = 6'b0;
            end
        end
    endmodule

我为两者设置了测试台。 counter60sec一个正常工作(当secCounter值为60时,minOut变为1)。 counter12hr遵循相同的概念,但overflowOut的值永远不会变为1。

对于我在counter12hr.v中的hrCounter条件语句,我尝试了4'b1101和4'b1100,但两者都没有奏效。 (当hrCounter命中13时,试图让overflowOut成为一个)

我已经花了好几个小时,休息放松我的眼睛等等。我仍然看不到我错在哪里。任何帮助,将不胜感激

verilog counter
2个回答
1
投票

你有一些问题。主要的一点是,在这两种情况下你都有一个多驱动寄存器:

    always@(negedge reset or posedge hourInc) begin
        overflowOut = 1'b0;
        ...

    always@(negedge hrCounter) begin
        if (hrCounter == 4'b1100) begin
            overflowOut = 1'b1;

overflowOut由2个不同的alsways块驱动。与minOut在第二个柜台相同。这些语句的执行顺序是未定义的,结果值将取决于顺序。

您需要重新构建程序,使寄存器仅在单个always块中分配。

其次,我认为,你有一个逻辑错误,在第一个块的第一个语句中将溢出分配给'0'(与第二个块中的相同)。

第三,您应该在寄存器的最终赋值中使用非阻塞赋值“<=”。

类似下面的东西应该工作。

  always@(negedge reset or posedge hourInc) begin
        if(reset == 1'b0) begin
            hrCounter <= 4'b0;
            overflowOut <= 1'b0;
        end
        else begin
          if (hrCounter == 4'b1100) begin 
            overflowOut <= 1'b1;
            hrCounter <= 4'b0;
          end
          else 
            hrCounter <= hrCounter + 1'b1;
            overflowOut <= 1'b0;
          end 
       end
   end

0
投票

你的代码在很多方面都是错误的...... 最有可能它不起作用,因为:

@(negedge hrCounter)

你正在使用向量,但@ ...使用位。所以它只会查看LS位。 至于你的代码:首先和大多数人开始使用时钟。不要使用信号的posedge和negedge来驱动其他信号。 你用:

always@(posedge secInc ...
   ...
   if (secInc == 1'b1)

删除'if'。你的永远陈述中已经有了这个条件。 (但信号不应该是'总是',它应该是你的时钟) 删除“初始”部分您有一个定义开始条件的重置。 如果您有一个活动的低重置反映在名称中。将它称为reset_n或n_reset除了'reset'之外的任何东西,按照惯例,它是一个正复位信号。 如果您的驱动器从边缘开始,无论是来自时钟还是来自其他信号,请使用非阻塞分配“<=” 不要使用生成的信号边缘来生成其他信号。如上所述,为时钟部分中的所有内容使用时钟使用if。也不要从不同的'always'驱动信号。你永远不知道他们执行的顺序,然后你就有竞争条件。因此,清除和增量总是在一个块中:

if (secCounter == 6'b111100) begin
   minOut <= 1'b1;
   secCounter <= 6'b0;
end
else
   secCounter <= secCounter  + 6'b000001;

由于时序方面,你现在必须转到59而不是60.这是你应该期望的,因为数字钟表从00到59,而不是00到60.你可以使用十进制数字,这将再次使代码更具可读性:6'd59,4'd11

© www.soinside.com 2019 - 2024. All rights reserved.