繁体   English   中英

有人可以解释为什么这会导致组合反馈循环吗? (Vivado Verilog)

Can someone please explain why this causes a combinational feedback loop? (Vivado Verilog)

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

一些基本背景:我有一个显示驱动程序,需要处理一些输入并将结果显示在分段显示器上。 通过在“ statusDisplay”中设置数值来更新分段显示。 我已将此代码简化为仅显示驱动程序,并试图显示一个简单的计数器。

使用分段显示很令人兴奋,但是可以。 但是,一旦我尝试在statusDisplay寄存器中输入一个值,Vivado就会说存在一个组合反馈循环。 对于我的一生,我不知道为什么或如何解决它。

我什至创建了一些测试代码,它们基本上完成了相同的操作,并且不会导致任何问题。

奇怪的是,还编译器报告线路上的问题“ticker1 <= ticker1 + 1”,但仅除去“线valueToDisplay <= bigCounter”解决问题。

谢谢!!!

timescale 1ns / 1ps

module circuit1_top(
    input clk,
    output [15:0] LED,      // Create two outputs
    output [7:0] SSEG_CA,
    output [7:0] SSEG_AN
    );

    reg [31:0] counter = 32'h0; 
    reg [0:0] divclk = 1'b0;
    reg [0:0] showclk= 1'b0;

    reg [15:0] caseCounter = 15'b0;
    reg [15:0] LedReg=0;
    reg [7:0] SegReg;
    reg [7:0] DigReg;
    reg [31:0] Hex = 0;

    reg [0:0] segclk = 1'b0, scroll = 1'b0;
    reg [31:0] displayNumber;
    reg [2:0] segNumber = 3'b0;

    reg [31:0] statusDisplay;
    reg [31:0] display1, display2, display3, display4, display5, display6, display7, display8, display9, display10;

    reg [31:0] ticker1=0;

    initial 
    begin
        scroll = 0;
        displayNumber = 32'hDEADBEEF;
        statusDisplay = 32'h80085;
        display1=1;
        display2=2;
        display3=3;
        display4=4;
        display5=5;
        display6=6;
        display7=7;
        display8=8;
        display9=9;
        display10=10;
    end

    // Testing simpler similar code - this does not create a loop problem
    reg [31:0] bigCounter=0;
    reg [31:0] valueToDisplay=0;
    reg [31:0] displayRegister=0;

    always @(clk)
    begin
        bigCounter <= bigCounter + 1;
        if( (bigCounter & 32'h7FFF) == 32'h7FFF )
            valueToDisplay <= bigCounter;
    end

    always @(clk)
    begin
        displayRegister <= valueToDisplay;
    end
    // End Test Code


    always @(clk)
    begin
        ticker1 <= ticker1 + 1;     //. <<—- This line is reported as causing the problem
        if( (ticker1 & 32'h7FFF) == 32'h7FFF )
            statusDisplay <= ticker1 + 1;   // <<—- Removing this line actually solves the problem
    end

        // Display driver starts here...

        // Retrieve display segments based on number to display
    task automatic getSegments;
        input [7:0] number;
        output [7:0] segment_ca;

        begin
           case (number)
              4'h0 :segment_ca <= 8'b11000000;       // 0                     
              4'h1 :segment_ca <= 8'b11111001;       // 1                       
              4'h2 :segment_ca <= 8'b10100100;       // 2                       
              4'h3 :segment_ca <= 8'b10110000;       // 3                       
              4'h4 :segment_ca <= 8'b10011001;       // 4                       
              4'h5 :segment_ca <= 8'b10010010;       // 5                       
              4'h6 :segment_ca <= 8'b10000010;       // 6                       
              4'h7 :segment_ca <= 8'b11111000;       // 7                       
               4'h8 :segment_ca <= 8'b10000000;       // 8                        
               4'h9 :segment_ca <= 8'b10010000;       // 9                        
               4'hA :segment_ca <= 8'b10001000;       // A                        
               4'hB :segment_ca <= 8'b10000011;       // b                        
               4'hC :segment_ca <= 8'b11000110;       // C                        
               4'hD :segment_ca <= 8'b10100001;       // d                        
               4'hE :segment_ca <= 8'b10000110;       // E
               4'hF :segment_ca <= 8'b10001110;       // F
              default: begin end
           endcase
          end
    endtask



assign SSEG_AN = DigReg;
assign SSEG_CA = SegReg;


always @(posedge segclk)
    segNumber <= segNumber + 1;


always @(posedge segclk)      
    begin
    case( segNumber )
         4'h0: begin  DigReg <= ~(32'h1);             getSegments( displayNumber & 4'b1111, SegReg ); end
         4'h1: begin  DigReg <= ~(((displayNumber < 32'h10 ? 1'b0 : 1'b1) & 32'h1) << 1);        getSegments( (displayNumber>>4) & 4'b1111, SegReg ); end
         4'h2: begin  DigReg <= ~(((displayNumber < 32'h100 ? 1'b0 : 1'b1) & 32'h1) << 2);        getSegments( (displayNumber>>8) & 4'b1111, SegReg ); end
         4'h3: begin  DigReg <= ~(((displayNumber < 32'h1000 ? 1'b0 : 1'b1) & 32'h1) << 3);        getSegments( (displayNumber>>12) & 4'b1111, SegReg ); end
         4'h4: begin  DigReg <= ~(((displayNumber < 32'h10000 ? 1'h0 : 1'h1) & 32'h1) << 4);        getSegments( (displayNumber>>16) & 4'b1111, SegReg ); end
         4'h5: begin  DigReg <= ~(((displayNumber < 32'h100000 ? 1'h0 : 1'h1) & 32'h1) << 5);        getSegments( (displayNumber>>20) & 4'b1111, SegReg ); end
         4'h6: begin  DigReg <= ~(((displayNumber < 32'h1000000 ? 1'h0 : 1'h1) & 32'h1) << 6);        getSegments( (displayNumber>>24) & 4'b1111, SegReg ); end
         4'h7: begin  DigReg <= ~(((displayNumber < 32'h10000000 ? 1'h0 : 1'h1) & 32'h1) << 7);        getSegments( (displayNumber>>28) & 4'b1111, SegReg ); end
          default: begin end

    endcase

    end




////clock divider////    
         always @(posedge clk)
         begin
            if( (counter & 16'h7FFF) == 16'h7FFF ) begin
                segclk <= ~segclk;      // Switch to the next segment in the display

            end

            if(counter == 32'h17D7840) begin    // 1/4 second, so change every 1/2 second...
                counter <= 32'h0;               // This only really matters if we are scrolling             divclk <= ~divclk;
            end
            else begin
                counter <= counter + 1'b1;
            end
        end

        always @(posedge divclk) 
               begin

                if(caseCounter == 9) begin    // Over it!!
                    caseCounter <= 0;
                end
                else begin
                    caseCounter <= caseCounter + 1'b1;
                end


               end

        always @(posedge divclk)  
        begin

            if( scroll )    // Scroll through ten potential outputs display
            begin
                case( caseCounter )
                0: displayNumber <= display1;
                1: displayNumber <= display2;
                2: displayNumber <= display3;
                3: displayNumber <= display4;
                4: displayNumber <= display5;
                5: displayNumber <= display6;
                6: displayNumber <= display7;
                7: displayNumber <= display8;
                8: displayNumber <= display9;
                9: displayNumber <= display10;
                default ;
                endcase
                LedReg <= 1 << caseCounter;
            end
            else
                displayNumber <= statusDisplay; // This is the only access to statusDisplay
             end

        assign LED = LedReg;

endmodule
1 个回复

我猜您跳过了模拟,直接进入了综合。 always @(clk)应该always @(posedge clk)

与模拟器不同,合成器并不严格遵循灵敏度列表。 合成器寻找关键字posedgenegedge来确定逻辑是否应该是同步的(然后其他步骤确定它是否是异步控制)。 否则,它假定是异步的。

ticker1 <= ticker1+1 ,合成器将忽略选择性列表,然后将ticker1 <= ticker1+1视为反馈循环。 删除statusDisplay <= ticker1 + 1 sudo可解决此问题,因为在其他任何地方都未引用ticker1 ,因此已对其进行了优化。

always @(posedge clk)
begin
    ticker1 <= ticker1 + 1;
    if( (ticker1 & 32'h7FFF) == 32'h7FFF )
        statusDisplay <= ticker1 + 1;
end
4 有人可以解释为什么要加上()吗? [重复]

这个问题已经在这里有了答案: 在JavaScript中声明函数后,空括号()有什么作用? [重复] 4个答案 我正在从freecodecamp学习JavaScript,并且有一个函数我不明白extra()的含义,我将附加代码,对不起,如果以前已经问过了 我知 ...

6 有人可以解释为什么这个功能是这样吗?

我正在查看来自GNU C库glibc-2.18的函数,这是我为strncmp.c找到的代码。 看着它,我不明白为什么这样写。 这个循环展开了吗? 为什么不使用5或10而不是4? 他们为什么这样写而不是使用更简单的方法? 有人可以解释代码背后的逻辑吗? 谢谢。 ...

8 有人可以解释为什么我的for循环在错误的地方停止

抱歉,这是一个愚蠢的错误,我只是一个初学者。 我在回答C编程现代方法一书中的一个问题。 这要求打印介于1和给定数字之间的所有偶数平方。 这是我的原始代码: 问题是它只会在达到一万时停止,因此我在for循环内划分了“ n”: 谁能解释为什么会这样 ...

2015-07-18 03:20:45 2 61   c
10 有人可以解释为什么此for循环正常工作吗? [重复]

这个问题已经在这里有了答案: 如何在迭代时从列表中删除项目? 27个答案 我创建了一个for循环,用于计算列表的总和,但整数13及其后面的整数除外。 我的循环有效,但我不知道为什么,有人可以帮助解释吗? 我尝试打印循环的各个部分以了解其功能。 它成功地从 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM