使用SystemVerilog接口与iverilog编译报错问题求助
问题:使用Interface封装PISO寄存器测试平台时Icarus Verilog编译错误
我在为简单PISO寄存器设计测试平台,用interface封装所有与设计交互的信号,通过modport区分TB(测试平台)和DUT(被测设计)。但用Icarus Verilog编译时出现以下错误:
iverilog -g2012 piso_tb.sv ./piso.sv:25: syntax error ./piso.sv:1: Errors in port declarations. piso_tb.sv:9: syntax error piso_tb.sv:9: error: Invalid module instantiation
尝试将编译标志改为-g2005-sv后,错误依旧。以下是我的设计文件和测试平台文件代码:
piso.sv(设计 + 接口)
interface my_piso; logic [7:0] din; logic resetn; logic dout; logic din_en; modport TB ( output din, output resetn, input dout, output din_en ); modport DUT ( input din, input resetn, input din_en, output dout ); endinterface module model (input clk, my_piso piso_if); reg [7:0] temp; always @(posedge clk) begin if(!piso_if.resetn) begin temp <= 0; end else begin if(piso_if.din_en) begin temp <= piso_if.din; end else begin temp <= temp >> 1; end end end assign piso_if.dout = temp & 1'b1; endmodule
piso_tb.sv(测试平台)
`include "piso.sv" module model_tb; reg clk; always #5 clk = ~clk; my_piso piso_if; model dut( .clk(clk), .piso_if(piso_if.DUT) ); initial begin $dumpfile("model.vcd"); $dumpvars; end initial begin $display("time\tclk\tresetn\tdin_en\tdin\tdout"); $monitor("%d\t%b\t%b\t%b\t%b\t%b", $time, clk, piso_if.resetn, piso_if.din_en, piso_if.din, piso_if.dout); end initial begin clk <= 0; piso_if.resetn <= 0; piso_if.din_en <= 0; piso_if.din <= 0; @(posedge clk); piso_if.resetn <= 1; piso_if.din_en <= 1; piso_if.din <= $random; @(posedge clk); repeat(10) begin piso_if.din_en <= 0; @(posedge clk); end $finish; end endmodule
问题原因与修复方案
错误1:模块端口未指定Interface的Modport
在Verilog 2012标准中,模块引用interface时必须明确指定对应的modport,否则编译器无法识别信号的方向约束。原代码中model模块的端口声明缺少modport指定,需要修改:
// 原错误代码 module model (input clk, my_piso piso_if); // 修改后 module model (input clk, my_piso.DUT piso_if);
错误2:模块实例化时错误传递Modport
模块端口已经指定了DUT modport,实例化时直接传递interface实例即可,不需要额外加.DUT后缀,否则会导致语法错误:
// 原错误代码 model dut( .clk(clk), .piso_if(piso_if.DUT) ); // 修改后 model dut( .clk(clk), .piso_if(piso_if) );
修复后的完整代码
修复后的piso.sv
interface my_piso; logic [7:0] din; logic resetn; logic dout; logic din_en; modport TB ( output din, output resetn, input dout, output din_en ); modport DUT ( input din, input resetn, input din_en, output dout ); endinterface module model (input clk, my_piso.DUT piso_if); reg [7:0] temp; always @(posedge clk) begin if(!piso_if.resetn) begin temp <= 0; end else begin if(piso_if.din_en) begin temp <= piso_if.din; end else begin temp <= temp >> 1; end end end assign piso_if.dout = temp & 1'b1; endmodule
修复后的piso_tb.sv
`include "piso.sv" module model_tb; reg clk; always #5 clk = ~clk; my_piso piso_if; model dut( .clk(clk), .piso_if(piso_if) ); initial begin $dumpfile("model.vcd"); $dumpvars; end initial begin $display("time\tclk\tresetn\tdin_en\tdin\tdout"); $monitor("%d\t%b\t%b\t%b\t%b\t%b", $time, clk, piso_if.resetn, piso_if.din_en, piso_if.din, piso_if.dout); end initial begin clk <= 0; piso_if.resetn <= 0; piso_if.din_en <= 0; piso_if.din <= 0; @(posedge clk); piso_if.resetn <= 1; piso_if.din_en <= 1; piso_if.din <= $random; @(posedge clk); repeat(10) begin piso_if.din_en <= 0; @(posedge clk); end $finish; end endmodule
修改完成后,使用iverilog -g2012 piso_tb.sv即可正常编译。
内容的提问来源于stack exchange,提问作者Tyler Durden
相关产品推荐
相关产品推荐

