为什么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)
);
这是我的程序计数器的第一个 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)
);