xilinx vivado的Combinatorial Loop Alert

本文介绍了一种在处理inout信号过程中遇到的组合逻辑循环报警问题,并提供了通过在xdc文件中添加特定约束来解决该问题的方法。同时给出了具体的verilog代码实现。

问题:在对inout信号进行处理的工程中,生成bit文件的过程中遇到的组合逻辑循环报警的错误,这里需要的xdc中添加必要的约束才能解决,具体软件报错如下:

[DRC 23-20] Rule violation (LUTLP-1) Combinatorial Loop Alert - 3 LUT cells form a combinatorial loop. This can create a race condition. Timing analysis may not be accurate. The preferred resolution is to modify the design to remove combinatorial logic loops. If the loop is known and understood, this DRC can be bypassed by acknowledging the condition and setting the following XDC constraint on any net in the loop: 'set_property ALLOW_COMBINATORIAL_LOOPS TRUE [net_nets <myHier/myNet>'. The cells in the loop are: design_1_i/k115_GPIO_0/inst/k115_pin[0]_INST_0, design_1_i/k115_GPIO_0/inst/zynq_pin[0]_INST_0, design_1_i/k115_GPIO_0/inst/zynq_pin[0]_INST_0_i_1.

解决:

再xdc中添加如下的约束:

set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets -of_objects [get_cells design_1_i/k115_GPIO_0/inst/k115_pin[*]_INST_0]]
set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets -of_objects [get_cells design_1_i/k115_GPIO_0/inst/zynq_pin[*]_INST_0]]
set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets -of_objects [get_cells design_1_i/k115_GPIO_0/inst/zynq_pin[*]_INST_0_i_1]]

set_property SEVERITY {Warning}  [get_drc_checks LUTLP-1]

set_property SEVERITY {Warning} [get_drc_checks NSTD-1]

 

问题参考链接:

https://forums.xilinx.com/xlnx/board/crawl_message?board.id=IMPBD&message.id=18353

 

verilog代码:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: hypersilicon   
// Engineer: ryanyan
//
// Create Date: 2018/07/16 12:29:15
// Design Name: k115_gpio
// Module Name: k115_GPIO
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////


module k115_GPIO(
inout  [9:0]  zynq_pin,
inout  [9:0]  k115_pin,

input         sys_clk,//50~100Mhz
///////////bram port/////////////
input              bram_en,
input       [3:0]  bram_we,
input       [16:0] bram_adder,
input              bram_clk,
input              bram_rst,  
input       [31:0] bram_wr_data,
output  reg [31:0]  bram_rd_data
);

/************************register**************************88*/
reg  [31:0]  reg_ctl;// adder=0;2n bits define in/out,2n+1 bits define k115/zynq
                     //in=0,out=1
                     //k115=0,zynq=1
reg  [31:0]  reg_wr; // adder=1;defines the value which is written to the register in zynq,when the pin is out
reg  [31:0]  reg_rd; // adder=2;the value of the input value ,when the pin is in and the fpga is zynq
reg  [31:0]  reg_msk; //adder=3;
                      //bit[n]=1:mask is enable;
                      //bit[n]=0:normal operation
wire    [9:0]  net_in;
wire    [9:0]  net_out;

 


//    wire  [9:0]       zynq_pin;
//    wire  [9:0]       k115_pin;
    wire   [9:0]       zynq_pin_reg;
    wire   [9:0]       k115_pin_reg;
    wire   [9:0]       zynq_pin_oe;//oe=1,output
    wire   [9:0]       k115_pin_oe;
    
    assign zynq_pin=zynq_pin_oe?zynq_pin_reg:10'bz;
    assign k115_pin=k115_pin_oe?k115_pin_reg:10'bz;
    
    
////////////////////reg_msk///////////////////////
always @(posedge bram_clk or posedge bram_rst)
begin
 if(bram_rst==1'b1)
   reg_msk<=32'hFFFFF;
 else if((bram_en==1'b1)&&(bram_we==4'b1111)&&(bram_adder==17'h3))
   reg_msk<=bram_wr_data;
 else if((bram_en==1'b1)&&(bram_we==4'b1111)&&(bram_adder!=17'h3))
   reg_msk<=32'hFFFFF;
 else
   reg_msk<=reg_msk;
end
////////////////////reg_ctrl///////////////////////
genvar i;
generate
 for (i=0;i<=19;i=i+1) begin :operation_ctrl
    always @(posedge bram_clk or posedge bram_rst)
        begin
          if(bram_rst==1'b1)
             reg_ctl[i]<=1'b0;
          else if((bram_en==1'b1) && (bram_we==4'b1111) && (bram_adder==17'h0) && (reg_msk[i]==1'b0))
             reg_ctl[i]<=bram_wr_data[i];
          else
             reg_ctl[i]<=reg_ctl[i];
        end
        end
endgenerate
////////////////////reg_wr///////////////////////
genvar h;
generate
 for (h=0;h<=19;h=h+1) begin :operation_write
    always @(posedge bram_clk or posedge bram_rst)
        begin
          if(bram_rst==1'b1)
             reg_wr[h]<=1'b0;
          else if((bram_en==1'b1) && (bram_we==4'b1111) && (bram_adder==17'h1) && (reg_msk[h]==1'b0))
             reg_wr[h]<=bram_wr_data[h];
          else
             reg_wr[h]<=reg_wr[h];
        end
        end
endgenerate

////////////////////reg_rd///////////////////////
always @(posedge bram_clk or posedge bram_rst)
begin
 if(bram_rst==1'b1)
   bram_rd_data<=32'b0;
 else if((bram_en==1'b1)&&(bram_we==4'b0000)&&(bram_adder==17'h2))
   bram_rd_data<=reg_rd;
 else
   bram_rd_data<=bram_rd_data;
end

 


/*******************net operation*********************/
//net_in=(in1 or out0) ? zynq_pin : 1'bz;            
//pin_k115=(K115_1 or zynq_0) ? net_in : 1'bz                
//reg_zynq_read=(K115_1 or zynq_0) ? 1'bz :  net_in

//    zynq_pin=(in0 or out1)1'bz :net_out            
//  net_out=(K115_0 or zynq_1) ? Pin_k115 : reg_zynq_write;                    
wire [9:0]     net_in_1;        
genvar j;
generate
for(j=0;j<=9;j=j+1) begin:net_op
     //////////in///////////
   assign net_in[j]=reg_ctl[2*j]?1'bz:zynq_pin[j];
   assign k115_pin_reg[j]=reg_ctl[2*j+1]?1'bz:net_in[j];
   //assign net_in_1[j]=reg_ctl[2*j+1]?net_in[j]:1'bz;
   always @(posedge sys_clk or posedge bram_rst)
      begin
         if(bram_rst==1'b1)
          reg_rd[2*j+1:2*j]<=2'b0;
         else if(reg_ctl[2*j+1:2*j]==2'b10)
          reg_rd[2*j+1:2*j]<={1'b1,net_in[j]};
         else
          reg_rd[2*j+1:2*j]<={1'b0,1'bz};
      end
     //////////////out///////////////
   assign zynq_pin_reg[j]=reg_ctl[2*j]?net_out[j]:1'bz;
   assign net_out[j]=reg_ctl[2*j+1]? reg_wr[2*j]:k115_pin[j];
   
   assign zynq_pin_oe[j]=reg_ctl[2*j];
   assign k115_pin_oe[j]=~reg_ctl[2*j];
   end
endgenerate

endmodule

<think>我们正在处理一个关于FPGA设计中组合逻辑路警告的问题。用户引用了多个来源,这些来源讨论了Xilinx Vivado中的DRC LUTLP-1警告。这个警告表示在设计中存在组合逻辑路,可能导致竞争条件,并且时序分析可能不准确。根据引用,组合逻辑路是由查找表(LUT)形成的路。这通常是由于设计中的组合逻辑反馈引起的,即组合逻辑的输出不经过任何寄存器而直接反馈到输入,形成路。 解决方案有两种: 1.修改设计以消除组合逻辑路(推荐方法)。 2.如果理解并确认该路不会引起问题,可以通过添加XDC约束来绕过DRC检查:`set_property ALLOW_COMBINATORIAL_LOOPSTRUE [get_nets <net_name>]`,其中`<net_name>`是路中的任意一个网络。用户的问题是如何理解和解决这个警告。因此,我们需要分步骤解释原因和解决方案。步骤:1.理解组合逻辑路警告的原因。2.如何定位路?3.如何修改设计消除路? 4.如何添加约束绕过检查(不推荐,但有时必要)?另外,根据引用[3]和[4],具体的错误信息会指出形成路的LUT单元,因此我们可以利用这些信息来定位问题。 注意:用户可能是在设计状态机(如三段式状态机)或其他组合逻辑时遇到此问题。 因此,我们的回答应该包括:-解释警告的含义和潜在风险。-提供定位问题的方法(使用Vivado提供的路中的LUT或网络名称)。 -详细说明如何修改设计(例如,插入寄存器打破路,检查代码中的组合逻辑反馈)。 -说明如何添加约束(作为备选方案)。 同时,生成相关问题以帮助用户深入理解。</think>### 理解并解决 Vivado 中的组合逻辑路警告 (DRC LUTLP-1) #### 警告原因与风险 当 Vivado 检测到查找表(LUT)形成闭反馈路径时,会触发 **DRC LUTLP-1** 警告。例如: > `[DRC LUTLP-1] Combinatorial Loop Alert: 3 LUT cells form a combinatorial loop. This can create a race condition. Timing analysis may not be accurate.` **关键风险**: 1. **竞争条件**:信号在路中无限振荡,导致输出不稳定 2. **时序分析失效**:静态时序分析(STA)无法处理组合逻辑 3. **硬件行为不可预测**:实际硬件行为可能与时序仿真不一致 #### 解决方案(优先级排序) ##### ✅ 方案1:修改设计消除路(推荐) ```verilog // 错误示例:组合逻辑 always @(*) begin out = in & ~out; // 输出直接反馈到输入 end // 修复方案:插入寄存器打破路 always @(posedge clk) begin out_reg <= in & ~out_reg; // 通过寄存器隔离反馈 end assign out = out_reg; ``` **设计要点**: - 检查所有组合逻辑(`always @(*)`/`assign`)是否存在输出到输入的**直接反馈** - 特别关注:状态机译码逻辑、多路复用器控制信号、算术运算路径 - 在反馈路径中插入寄存器(至少1个时钟周期延迟) ##### ⚠️ 方案2:添加约束绕过检查(临时措施) 在XDC约束文件中添加: ```tcl set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets wr_cnt[3]_i_5_n_0] ``` **使用条件**: 1. 已确认路不会导致功能异常(如:逻辑冗余但无危害) 2. 明确知晓路位置(Vivado报告会提示具体网络名,如`wr_cnt[3]_i_5_n_0`[^3]) 3. **仅作为临时方案**,长期仍需优化设计 #### 调试定位技巧 1. **查看详细报告**: ```tcl report_drc -file drc_report.txt // 生成完整DRC报告 ``` 2. **追踪路路径**: - 在Vivado中选中警告提示的LUT单元(如`wr_cnt[3]_i_5`[^3]) - 使用`Schematic Viewer`可视化信号路径 3. **检查常见场景**: - 未寄存的状态机输出反馈到输入[^2] - 组合逻辑实现的计数器/分频器 - 组合路跨模块传播(检查接口信号) > 组合逻辑路会破坏时序收敛性,必须通过插入寄存器或重构逻辑消除闭路径[^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值