为什么systemverilog中正好有两条"wire"语句,一个可以编译,一个不能编译?

Why two exactly "wire" statement in systemverilog, one can be compiled and the other on can not?

这是我的程序计数器的第一个 HDL 代码。

timeunit 1ns; timeprecision 10ps;

module PC(
output logic [31:0] pc_addr,
output logic [31:0] Next_addr,
input logic [31:0] Branch_addr,
input logic PCSrc,
input logic clock, reset
);

wire [31:0] y;

MUX MUX (
     .y (y),
     .a (Branch_addr),
     .b (Next_addr),
     .sel (PCSrc)
);


adder_1 adder_1(
     .y(Next_addr),
     .a(pc_addr),
     .b(3'b100)
);

always_ff @ (posedge clock)
begin

   if(reset)

          pc_addr <= 0;  //PC address start at 0x0000_0000

   else

          pc_addr <= y;

end
endmodule

信号y来自实例MUX的输出,不是PC模块自己产生的。所以我用线把这个信号接到最上面的模块PC上,D型触发器pc_addr会采用这个信号作为模块的输出信号

在这种情况下,这段代码可以完美编译,我发现这段代码中的 wire 语句是必不可少的。我试过去掉那个语句,结果仿真结果出错,因为MUX的信号y没有连接到PC模块。

这是我的 MIPS 流水线的第二个代码:

module IDEX(
output logic IDEX_RegDst, IDEX_ALUSrc, IDEX_MemtoReg, IDEX_RegWrite, IDEX_MemRead, 
IDEX_MemWrite, IDEX_Branch, IDEX_ALUOp1, IDEX_ALUOp0,
output logic [31:0]IDEX_Next_addr,
output logic [31:0] IDEX_Read_data_1, IDEX_Read_data_2,
output logic [4:0] IDEX_Write_register,
output logic [31:0] IDEX_Extended,
input logic [31:0] IFID_Next_addr,
input logic [31:0] IFID_Instruction,
input logic [31:0] Write_data,
input logic [4:0] Write_register,
input logic RegWrite,
input logic clock, reset
);

register register (
         .Read_data_1(Read_data_1),
     .Read_data_2(Read_data_2),
     .Read_register_1(IFID_Instruction[25:21]),
     .Read_register_2(IFID_Instruction[20:16]),
     .Write_register(Write_register),
     .Write_data(Write_data),
     .RegWrite(RegWrite),
     .clock(clock),
     .reset(reset)
);

sign_extender sign_extender (
         .extended(extended),
     .unextended(IFID_Instruction[15:0])
);

control control (
         .RegDst(RegDst),
     .ALUSrc(ALUSrc),
     .MemtoReg(MemtoReg),
     .RegWrite(RegWrite_0),     //this RegWrite signal does not connect with the Register.sv
     .MemRead(MemRead),
     .MemWrite(MemWrite),
     .Branch(Branch),
     .ALUOp1(ALUOp1),
     .ALUOp0(ALUOp0),
     .Operand(IFID_Instruction[31:26])
);

MUX_5 MUX_5 (
         .y (y),
     .a (IFID_Instruction[15:11]),
     .b (IFID_Instruction[20:16]),
     .sel (RegDst)
);

wire RegDst;
wire [4:0]y;
wire [31:0]Read_data_1, Read_data_2, extended;


always_ff @ (posedge clock)
begin

     if(reset)
      {IDEX_RegDst, IDEX_ALUSrc, IDEX_MemtoReg, IDEX_RegWrite, IDEX_MemRead, 
IDEX_MemWrite, IDEX_Branch, IDEX_ALUOp1, IDEX_ALUOp0, IDEX_Next_addr, IDEX_Read_data_1, 
IDEX_Read_data_2, IDEX_Write_register, IDEX_Extended} <= 0;


     else
       begin

      {IDEX_RegDst, IDEX_ALUSrc, IDEX_MemtoReg, IDEX_RegWrite, IDEX_MemRead, 
IDEX_MemWrite, IDEX_Branch, IDEX_ALUOp1, IDEX_ALUOp0} <= {RegDst, 
ALUSrc, MemtoReg, RegWrite_0, MemRead, MemWrite, Branch, ALUOp1, ALUOp0};

          IDEX_Next_addr <= IFID_Next_addr;
      IDEX_Read_data_1 <= Read_data_1;
      IDEX_Read_data_2 <= Read_data_2;
      IDEX_Write_register <= y;
      IDEX_Extended <= extended;
    end

end
endmodule

这段代码的情况和第一个一模一样。我想使用 wire 语句将来自实例 MUX_5 的信号 y(以及所有其他实例输出信号)连接到顶层模块。但是这次模拟器无法编译,错误是:

*ncvlog: *E,DUPIMP (IDEX.sv,65|13): Identifier 'y', implicitly declared here, first as a wire, is subsequently redeclared.
wire [4:0]y;
          |
ncvlog: *E,DUPIDN (IDEX.sv,72|10): identifier 'y' previously declared [12.5(IEEE)].

我不太确定我使用的wire语句是否正确,但是如果我删除这个wire语句,那么模拟结果是错误的。

请各位帮帮我,告诉我这是怎么回事?太迷茫了!为什么两条线语句有不同的编译结果???

非常感谢!

在 IDEX 模块中你有:

MUX_5 MUX_5 (
     .y (y),                       //<-- y used
     .a (IFID_Instruction[15:11]),
     .b (IFID_Instruction[20:16]),
     .sel (RegDst)
);

wire RegDst;
wire [4:0]y;                      //<-- y declared

在 Verilog 和 SystemVerilog 变量中,wire 和 regs 应该在使用前声明。

如果使用未知名称,它通常被创建为隐含的 1 位连线,导致 y 被有效声明两次。一次作为隐式 1 位线,然后显式地作为 5 位线。

您实际上是在尝试这样做:

wire y;                      //<-- y declared
MUX_5 MUX_5 (
     .y (y),                 //<-- y used
);
wire [4:0]y;                 //<-- y re-declared

删除显式声明 (wire [4:0]y;) 将消除错误,但只留下 1 位连接。

解决方案

在使用之前声明电线。

wire RegDst;
wire [4:0]y;                       //<-- y declared
MUX_5 MUX_5 (
     .y (y),                       //<-- y used
     .a (IFID_Instruction[15:11]),
     .b (IFID_Instruction[20:16]),
     .sel (RegDst)
);