为什么两个在systemverilog中完全是“wire”语句,一个可以编译而另一个不可以?

时间:2015-02-24 12:33:43

标签: system-verilog

这是我的程序计数器的第一个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):标识符'y',在此隐式声明,首先作​​为电线,随后重新声明。
  电线[4:0] y;
  |
  ncvlog:* E,DUPIDN(IDEX.sv,72 | 10):先前声明的标识符'y'[12.5(IEEE)]。

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

伙计们帮帮我,告诉我发生了什么事?那太混乱了!为什么两个wire语句有不同的编译结果???

非常感谢!

1 个答案:

答案 0 :(得分:1)

在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)
);