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
问题成因
- 逻辑方向完全反向:TestLeds模块中
assign bByte = {...}是将bMKR_A/D引脚的输入值赋值给bByte,但需求是将计数器值输出到bMKR_A/D引脚,逻辑完全颠倒,导致模块无实际输出作用。 - 多重驱动冲突:顶层模块中同时通过
assign bMKR_LED = ...和TestLeds模块的.bByte(bMKR_LED)对bMKR_LED进行驱动,Verilog中线网不允许无意义的多重驱动,综合器直接优化掉TestLeds模块的无效逻辑。 - 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引脚。
认知误区
- 连续赋值逻辑理解错误:Verilog中同一个线网不能被多个assign无意义驱动,这种冲突会被综合器判定为无效逻辑并优化。
- inout端口滥用:inout是双向引脚,需配合三态门控制方向,仅用于需要双向通信的场景(如I2C),单向输出引脚应使用output定义。
- 模块连接逻辑颠倒:混淆了输入输出的方向,错误地将引脚值读入模块而非将模块信号输出到引脚,导致模块功能完全不符合需求。
仿真操作说明
- 创建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
- 配置仿真设置:
- 打开Quartus,进入
Assignments > Settings > Simulation - 选择仿真工具为
ModelSim-Altera - 设置仿真语言为
Verilog - 指定Testbench顶层模块为
tb_top
- 打开Quartus,进入
- 运行仿真:点击
Tools > Run Simulation Tool > RTL Simulation启动仿真。
内容的提问来源于stack exchange,提问作者Tobiky
相关产品推荐
相关产品推荐

