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

Quartus编译0门电路问题:TestLeds模块悬空引脚报错排查

Arduino MKR Vidor 4000 FPGA开发问题排查与解决

问题背景

使用Intel Quartus Prime Lite 23.1,基于Arduino MKR Vidor 4000模板项目(Cyclone 10 LP 10CL016YU256C8G芯片)开发,编写TestLeds模块意图将32位计数器最高有效位路由到LED引脚调试,编译后出现以下问题:

  • Quartus显示0门电路生成
  • 警告:Warning (12158): Entity "TestLeds" contains only dangling pins
  • 预期的wire连接未生效,LED无输出
  • 仿真时无法选择语言

原代码

module TestLeds(
    inout wire  [6:0]  bMKR_A,
    inout wire  [14:0] bMKR_D,
    inout wire  [7:0]  bByte
);

assign bByte = '{bMKR_A[5], bMKR_A[6], bMKR_D[0], bMKR_D[1], bMKR_D[2], bMKR_D[3], bMKR_D[4], bMKR_D[5]};

endmodule

module MKRVIDOR4000_top
(
  // system signals
  input         iCLK,

  // SAM D21 PINS
  inout  [6:0]  bMKR_A,
  inout  [14:0] bMKR_D
);

reg [5:0] rRESETCNT;
reg [31:0] hadcounter;

always @(posedge iCLK) begin
    if (!rRESETCNT[5]) begin
        rRESETCNT <= rRESETCNT+1;
        hadcounter <= 0;
    end else begin
        hadcounter <= hadcounter + 1;
    end
end

wire [7:0]bMKR_LED;

TestLeds leds(
    .bMKR_A(bMKR_A),
    .bMKR_D(bMKR_D),
    .bByte(bMKR_LED));

assign bMKR_LED[7:0] = hadcounter[31:31-7];

endmodule

问题成因

  1. 逻辑方向完全反向:TestLeds模块中assign bByte = {...}是将bMKR_A/D引脚的输入值赋值给bByte,但需求是将计数器值输出到bMKR_A/D引脚,逻辑完全颠倒,导致模块无实际输出作用。
  2. 多重驱动冲突:顶层模块中同时通过assign bMKR_LED = ...和TestLeds模块的.bByte(bMKR_LED)对bMKR_LED进行驱动,Verilog中线网不允许无意义的多重驱动,综合器直接优化掉TestLeds模块的无效逻辑。
  3. inout端口误用:将LED输出引脚定义为inout双向端口,但未添加三态控制逻辑,综合器无法识别有效输出方向,进一步导致模块被判定为无效。

解决方法

1. 修正模块逻辑方向与端口定义

将TestLeds模块改为从bByte接收计数器值,再分配到对应的LED输出引脚,同时将bMKR_A/D改为output端口(根据硬件引脚功能,LED为输出)。

2. 移除多重驱动

顶层仅负责将计数器值赋值给bMKR_LED,由TestLeds模块完成引脚分配。

3. 修正后代码

module TestLeds(
    output wire  [6:0]  bMKR_A,
    output wire  [14:0] bMKR_D,
    input wire   [7:0]  bByte
);

// 将bByte的位映射到对应LED引脚
assign bMKR_A[5] = bByte[0];
assign bMKR_A[6] = bByte[1];
assign bMKR_D[0] = bByte[2];
assign bMKR_D[1] = bByte[3];
assign bMKR_D[2] = bByte[4];
assign bMKR_D[3] = bByte[5];
assign bMKR_D[4] = bByte[6];
assign bMKR_D[5] = bByte[7];

// 未使用的引脚接地(根据硬件需求调整)
assign bMKR_A[0:4] = 5'b0;
assign bMKR_D[6:14] = 9'b0;

endmodule

module MKRVIDOR4000_top
(
  // system signals
  input         iCLK,

  // SAM D21 PINS
  output  [6:0]  bMKR_A,
  output  [14:0] bMKR_D
);

reg [5:0] rRESETCNT;
reg [31:0] hadcounter;

always @(posedge iCLK) begin
    if (!rRESETCNT[5]) begin
        rRESETCNT <= rRESETCNT+1;
        hadcounter <= 0;
    end else begin
        hadcounter <= hadcounter + 1;
    end
end

wire [7:0]bMKR_LED;

// 取计数器最高8位作为LED信号
assign bMKR_LED = hadcounter[31:24];

TestLeds leds(
    .bMKR_A(bMKR_A),
    .bMKR_D(bMKR_D),
    .bByte(bMKR_LED));

endmodule

4. 编译验证

重新编译项目,此时TestLeds模块会生成有效逻辑门,悬空引脚警告消失,计数器值可正常输出到LED引脚。

认知误区

  1. 连续赋值逻辑理解错误:Verilog中同一个线网不能被多个assign无意义驱动,这种冲突会被综合器判定为无效逻辑并优化。
  2. inout端口滥用:inout是双向引脚,需配合三态门控制方向,仅用于需要双向通信的场景(如I2C),单向输出引脚应使用output定义。
  3. 模块连接逻辑颠倒:混淆了输入输出的方向,错误地将引脚值读入模块而非将模块信号输出到引脚,导致模块功能完全不符合需求。

仿真操作说明

  1. 创建Testbench:新建Verilog Testbench文件,编写时钟激励与复位逻辑,示例:
module tb_top;
reg iCLK;

MKRVIDOR4000_top uut(
    .iCLK(iCLK)
);

initial begin
    iCLK = 0;
    forever #10 iCLK = ~iCLK; // 生成50MHz时钟
end

initial begin
    #100;
    $finish;
end
endmodule
  1. 配置仿真设置:
    • 打开Quartus,进入Assignments > Settings > Simulation
    • 选择仿真工具为ModelSim-Altera
    • 设置仿真语言为Verilog
    • 指定Testbench顶层模块为tb_top
  2. 运行仿真:点击Tools > Run Simulation Tool > RTL Simulation启动仿真。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:27:05