VVP编译异常求助:Verilog多路复用器跨平台运行问题
代码编译运行问题:跨平台Verilog仿真异常(Windows正常,Linux无响应)
该Verilog多路复用器ALU模块在Windows环境下可正常编译运行,但在Linux环境中使用vvp执行仿真时,终端提示生成VCD文件后无响应,且生成的alu.vcd无法被GTKWave识别为有效文件。
ALU模块代码
module alu(i_a, i_b , i_oper, o_y, o_status, i_rsn, i_clk); parameter BITS = 4; parameter OPER = 3; input logic signed [BITS - 1:0] i_a, i_b; input logic [OPER-2:0] i_oper; input logic i_clk; input logic i_rsn; output logic signed [BITS - 1:0] o_y; output logic [3:0] o_status; logic [BITS - 1:0] o_y_mux; logic [BITS - 1:0] o_y_1; logic [BITS - 1:0] o_y_2; logic [BITS - 1:0] o_y_3; logic [BITS - 1:0] o_y_4; logic [3:0] o_status_mux; logic [3:0] o_status_1; logic [3:0] o_status_2; logic [3:0] o_status_3; logic [3:0] o_status_4; ashift_example1 #(.BITS(BITS)) case1 (.i_a(i_a), .i_b(i_b), .o_arith_left(o_y_1), .o_error(o_status_1)); U2_to_ZM #(.BITS(BITS)) case2 (.i_a(i_a), .o_zm(o_y_2), .o_status(o_status_2)); porownanie #(.BITS(BITS)) case3 (.i_a(i_a), .i_b(i_b), .o_smaller(o_y_3), .o_error(o_status_3)); replace #(.BITS(BITS)) case4 (.i_a(i_a), .i_b(i_b), .o_replaced(o_y_4), .o_error(o_status_4)); always_comb begin {o_y_mux, o_status_mux} = '0; case (i_oper) 2'b00 : o_y_mux = o_y_1; 2'b01 : o_y_mux = o_y_2; 2'b10 : o_y_mux = o_y_3; 2'b11 : o_y_mux = o_y_4; default : o_y_mux = '0; endcase case (i_oper) 2'b00 : o_status_mux = o_status_1; 2'b01 : o_status_mux = o_status_2; 2'b10 : o_status_mux = o_status_3; 2'b11 : o_status_mux = o_status_4; default : o_status_mux = '0; endcase end always_ff @(posedge i_clk) begin if(i_rsn == 1) begin o_y <= o_y_mux; o_status <= o_status_mux; end else begin o_y <= '0; o_status <= '0; end end endmodule
测试平台代码
`timescale 1ns/1ps module test_alu; parameter BITS = 4; parameter OPER = 3; logic signed [BITS - 1:0] i_a, i_b; logic [OPER-2:0] i_oper; logic i_rsn; logic i_clk; logic signed [BITS - 1:0] o_y; logic signed [BITS - 1:0] o_y_rtl; logic [3:0] o_status; logic [3:0] o_status_rtl; alu #(.BITS(BITS), .OPER(OPER)) alu (.i_a(i_a), .i_b(i_b), .i_oper(i_oper), .o_y(o_y), .o_status(o_status), .i_rsn(i_rsn), .i_clk(i_clk)); //exe_unit_38_rtl alu_rtl (.i_a(i_a), .i_b(i_b), .i_oper(i_oper), .o_y(o_y_rtl), .o_status(o_status_rtl), .i_rsn(i_rsn), .i_clk(i_clk)); initial begin $dumpfile("alu.vcd"); $dumpvars(0,test_alu); i_rsn = 1; i_clk = 0; i_oper = 2; i_a = '0; i_b = '0; #1 i_clk = 1; i_oper = 1; i_a[3] = 1; #1 i_clk = 0; i_oper = 3; i_b[3] = 0; i_a[3] = 0; i_a[2] = 1; i_a[0] = 0; #1 i_clk = 1; i_oper = 0; i_a[0] = 0; i_b[1] = 1; i_a[3] = 1; #1 $finish; end endmodule
依赖子模块代码
module ashift_example1(i_a, i_b, o_arith_left, o_error); parameter BITS = 4; input logic signed [BITS-1:0] i_a, i_b; output logic signed [BITS-1:0] o_arith_left; output logic [3:0] o_error; integer x; always_comb begin x = 0; o_arith_left = '0; o_error = '0; if(i_b >= 0) begin o_arith_left = i_a <<< i_b; if(i_a < 0) begin o_arith_left[BITS-1] = 'd1; end else begin o_arith_left[BITS-1] = 'd0; end end else begin o_error[0] = 1; o_arith_left = 'x; end for (int i = 0; i<BITS;i++) begin if(o_arith_left == 1) begin x = x+1; end end if (x % 2 == 0 && o_arith_left != '0) begin o_error[1] = 1; end if(o_arith_left == '1) begin o_error[2] = 1; end end endmodule module U2_to_ZM (i_a , o_zm, o_status); parameter BITS = 4; input logic signed [BITS-1:0] i_a; output logic signed [BITS-1:0] o_zm; output logic [3:0] o_status; logic signed [BITS-1:0] one; integer x; always_comb begin x = 0; one = i_a; o_status = '0; if(i_a < 0) begin for (int i = 0; i<BITS-1; i++) begin one = ~i_a; end if(one == '1) begin o_status[3] = 1; o_status[0] = 1; o_zm = 'x; end else begin o_zm = one + 1; end end else begin o_zm = one; end for (int i = 0; i<BITS;i++) begin if(o_zm == 1) begin x = x + 1; end end if (x % 2 == 0 && o_zm != '0) begin o_status[1] = 1; end if (o_zm == '1) begin o_status[2] = 1; end end endmodule module porownanie(i_a, i_b, o_smaller, o_error); parameter BITS = 4; input logic signed [BITS-1:0] i_a, i_b; output logic signed [BITS-1:0] o_smaller; output logic [3:0] o_error; always_comb begin o_error = '0; o_smaller = '0; if(i_a<=i_b) begin o_smaller = 'd1; end else begin o_smaller = '0; end if(o_smaller == '1) begin o_error[2] = 1; end end endmodule module replace(i_a, i_b, o_replaced, o_error); parameter BITS = 4; input logic signed [BITS-1:0] i_a, i_b; output logic signed [BITS-1:0] o_replaced; output logic [3:0] o_error; integer x; integer i; always_comb begin x = 0; i = 0; o_replaced = '0; o_error = '0; if(i_b < 0 || i_b > BITS) begin o_error[0] = 1; o_replaced = 'x; end else begin i = i_b; o_replaced = i_a; o_replaced = 1; end for (int i = 0; i<BITS;i++) begin if(o_replaced == 1) begin x = x+1; end end if (x % 2 == 0 && o_replaced != '0) begin o_error[1] = 1; end if (o_replaced == '1) begin o_error[2] = 1; end end endmodule
问题排查与解决建议
仿真器版本差异:Windows和Linux使用的iverilog/vvp版本可能不一致,部分旧版本Linux下的iverilog对Verilog语法兼容性处理不同。建议升级到最新稳定版:
sudo apt update && sudo apt install --upgrade iverilog gtkwaveVCD文件未正常闭合:仿真进程无响应可能是代码存在无限循环或阻塞逻辑,导致
$finish未执行,VCD文件未完成写入。检查:U2_to_ZM模块中的for (int i = 0; i<BITS-1; i++)循环无意义(每次迭代都重复赋值one = ~i_a;),可直接替换为单次取反操作。- 子模块中
'x未知值赋值,在Linux仿真器中可能触发异常处理逻辑,导致仿真停滞。
语法兼容性优化:
- 将
'0、'1等聚合赋值替换为明确位宽的赋值,比如{BITS{1'b0}}代替'0,提升跨平台兼容性。 - 确保测试平台中
$dumpfile路径正确,当前目录有写入权限。
- 将
规范仿真执行流程:使用完整编译命令确保所有模块被正确加载:
iverilog -o alu_tb alu.v test_alu.v ashift_example1.v U2_to_ZM.v porownanie.v replace.v vvp alu_tb
内容的提问来源于stack exchange,提问作者user331990
相关产品推荐
相关产品推荐

