1

Here is the first HDL code for my program counter.

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

The signal y is come from the output of the instance MUX, and it is not generated by the PC module itself. So I used wire to connect this signal to the top module PC, and D-type flipflop pc_addr will adopt that signal as the output signal of the module.

In this case, this code can be compiled perfectly fine, and I found the wire statement in this code is essential. I have tried to remove that statement, then the simulation result went wrong because the signal y from MUX did not connect to the PC module.

Here come the second code for my MIPS pipeline:

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

This code's situation is exactly the same as the first one. I want to connect the signal y from the instance MUX_5 (and all other instance output signal) to the top module by using the wire statement. However the simulator can not compile this time, the error is :

*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)].

I am not very sure my use of wire statement is correct or not, but if I delete this wire statement, then the simulation result is wrong.

Guys pls help me and tell me what is going on? That is so confused! Why two wire statement have different compile result???

Thank you very much!

Greg
  • 18,111
  • 5
  • 46
  • 68
Shuaiyu Jiang
  • 239
  • 1
  • 3
  • 15
  • Well, I find out the problem, which looks very interesting. If I move the wire statement in code 2, to the position that before I declare the instance, like what I did in code 1. The error disappeared... – Shuaiyu Jiang Feb 24 '15 at 13:41

1 Answers1

2

In module IDEX you have:

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

In Verilog and SystemVerilog variables, wire and regs should be declared before they are used.

If an unknown name is used it is often created as an implict 1 bit wire, leading to y effectively being declared twice. Once as an implicit 1 bit wire then explicitly as a 5 bit wire.

You are actually trying to do this:

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

Removing the explicit declaration (wire [4:0]y;) will remove the error but leave you with only 1 bit connected.

Solution

Declare the wire before you is use it.

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)
);
Morgan
  • 19,934
  • 8
  • 58
  • 84