Verilog设计烧入FPGA正常运行 但Verilator仿真编译失败该如何解决?
问题原因
- FPGA综合工具Yosys的语法检查规则宽松,会自动把在过程块中赋值的
o_led输出信号推断为寄存器类型,所以你写的非标准语法可以正常综合、上板运行。 - Verilator仿真工具严格遵循IEEE Verilog标准,标准明确规定:
wire类型属于线网,仅能通过连续赋值语句赋值,不能在always这类过程块中做过程赋值,因此直接报PROCASSWIRE错误。
修复方法
共有两种符合Verilog标准的修改方案,两种方案都可同时兼容上板运行和仿真:
方案1:显式声明输出为reg类型
直接修改端口定义,把输出端口声明为reg类型,同时补充初始值避免仿真出现不定态:
`default_nettype none module pps(i_clk, o_led); parameter CLOCK_RATE_HZ = 12_000_000; input wire i_clk; output reg o_led; // 原output wire o_led修改为output reg o_led reg [23:0] counter; initial begin counter = 0; o_led = 0; // 新增输出寄存器初始值 end always @(posedge i_clk) if (counter < CLOCK_RATE_HZ/2 - 1) begin counter <= counter + 1'b1; end else begin counter <= 0; o_led <= !o_led; end endmodule
方案2:中间寄存器+连续赋值
如果不想把输出端口直接声明为reg,可以新增内部寄存器存储LED状态,再用连续赋值语句把状态赋值给输出线网:
`default_nettype none module pps(i_clk, o_led); parameter CLOCK_RATE_HZ = 12_000_000; input wire i_clk; output wire o_led; reg [23:0] counter; reg led_state; // 新增内部状态寄存器 initial begin counter = 0; led_state = 0; end always @(posedge i_clk) if (counter < CLOCK_RATE_HZ/2 - 1) begin counter <= counter + 1'b1; end else begin counter <= 0; led_state <= !led_state; // 改为给内部寄存器赋值 end assign o_led = led_state; // 新增连续赋值语句,把内部状态输出到端口 endmodule
修改完成后重新运行make simulate即可正常完成仿真编译、执行波形查看流程。
内容的提问来源于stack exchange,提问作者71GA
相关产品推荐
相关产品推荐

