You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vivado生成比特流时出现组合环错误的技术求助

组合环(Combinatorial Loop)错误排查与分析

问题概述

生成比特流时触发约100个组合环错误,涉及信号addr_121f、addr_store_1_f和addr_store_2_f。其中addr_store_2_f与addr_122f逻辑完全一致,但addr_122f未出现错误。

关键代码片段

// 简化后的赋值逻辑
// assign jump_1= (some signals)?(addr_121s == addr_store_1_f + some value)
// assign jump_2= (some signals)?(addr_122s == addr_store_2_f + some value)
assign input_last_addr_1 = addr_store_1_f + addr_temp_cal_2;
assign input_last_addr_2 = addr_store_2_f + addr_temp_cal_2;
assign last_addr_1 = (ram_cs == READ_FROM_S) ? addr_store_1_s + addr_temp_cal_1 : (ram_cs == READ_FROM_F) ? addr_store_1_f + addr_temp_cal_1 : input_last_addr_1;
assign last_addr_2 = (ram_cs == READ_FROM_S) ? addr_store_2_s + addr_temp_cal_1 : (ram_cs == READ_FROM_F) ? addr_store_2_f + addr_temp_cal_1 : input_last_addr_2;
assign jump_1= (conv_start) ? (ram_1_w_sd)? (ram_cs == READ_FROM_S) ? (addr_121s == last_addr_1):(addr_121f == last_addr_1) : 0 : 0;
assign jump_2= (conv_start) ? (ram_2_w_sd)? (ram_cs == READ_FROM_S) ? (addr_122s == last_addr_2):(addr_122f == last_addr_2) : 0 : 0;
assign addr_f_r_stop =  !(cs==FIRST_ROW_SD && ram_1_w_sd && ram_cs == READ_FROM_SD);

/////////////////////////////////////////////////////////////////////////
always@(posedge clk)begin//conv_b reading input from ram1
    if( ram_cs==CLEAR_STATE || ram_cs==SD_TO_F || ram_cs==F_TO_F || ram_cs==F_TO_S || ram_cs == TO_OUT)begin//change 1 is one clk before READ_FROM_F 
        addr_1f_r <= 1;
        addr_2f_r <= 0;
        addr_store_1_f <= 0;
        addr_store_2_f <= 0;
    end
    else if(ram_cs!= READ_FROM_S  )begin //input valid high indicates that the conv_cell will take value and the input is valid to store
        if( addr_f_r_stop && conv_start && input_valid)begin
                    if(ram_1_jump)
                    addr_2f_r <= addr_2f_r + 1;
                    if(ram_2_jump)
                    addr_1f_r <= addr_1f_r + 1;
        end
        if(jump_1)begin
            addr_store_1_f <= addr_121f +1;
        end
        if(jump_2)begin
            addr_store_2_f <= addr_122f +1;
        end
    end
end
////////////////////////////////////////////////
assign addr_121f = (conv_start) ? ( wen_121f ) ? addr_121f_w : (input_valid) ?  addr_1f_r : addr_121f : 0;
////////////////////////////////////////////////////

错误示例

ERROR: [DRC LUTLP-1] 组合环告警:1个LUT单元形成组合环,这会引发竞争条件,时序分析结果可能不准确。推荐的解决方式是修改设计移除组合逻辑环。如果确认该环路是预期且可接受的,可以通过对环路中的任意网表添加以下XDC约束来绕过DRC检查:set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets <myHier/myNet>]。环路中的一个网表为:design_1_i/e_top_0/inst/conv_top_1/addr_store_2_f[28]_i_9_n_0。请评估你的设计。环路中的单元为:design_1_i/e_top_0/inst/conv_top_1/addr_store_2_f[28]_i_9。

错误原因分析

  1. addr_121f的自赋值组合环:
    最后一行addr_121f的连续赋值中,当conv_start为真、wen_121f为假且input_valid为假时,addr_121f直接赋值为自身,这是典型的组合逻辑环路——信号输出直接反馈到输入,综合工具会生成LUT形成闭环。

  2. addr_store_1_f与jump_1的循环依赖:
    信号依赖链:addr_121f → jump_1 → addr_store_1_f → last_addr_1 → jump_1。整个链路完全由组合逻辑构成,没有时序寄存器打断,形成了更大的组合环路。

  3. addr_122f无错误的原因:
    推测addr_122f的赋值逻辑没有自引用,也没有形成类似的组合依赖链,因此未触发错误。

解决方案

1. 修复addr_121f的自赋值问题

把addr_121f的组合逻辑改成时序逻辑,用寄存器寄存,避免自反馈:

reg addr_121f;
always@(posedge clk)begin
    if(!conv_start) begin
        addr_121f <= 0;
    end else begin
        if(wen_121f) begin
            addr_121f <= addr_121f_w;
        end else if(input_valid) begin
            addr_121f <= addr_1f_r;
        end
        // 去掉原有的自赋值分支,寄存器会保持原值
    end
end

2. 打破jump_1与addr_store_1_f的组合环路

给jump_1或者addr_store_1_f增加一拍寄存,消除组合依赖:
比如把jump_1寄存后再驱动addr_store_1_f:

reg jump_1_reg;
always@(posedge clk)begin
    jump_1_reg <= jump_1;
end

// 在always块中使用寄存后的信号
if(jump_1_reg)begin
    addr_store_1_f <= addr_121f +1;
end

3. 临时规避(不推荐)

如果确认组合环是设计预期且无功能风险,可以添加XDC约束绕过DRC检查:

set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets design_1_i/e_top_0/inst/conv_top_1/addr_store_2_f[28]_i_9_n_0]

但这种方法会导致时序分析不准确,存在竞争风险,仅建议临时验证使用。

内容的提问来源于stack exchange,提问作者ENing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:34:51