这是我的程序计数器的第一个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语句有不同的编译结果???
非常感谢!
答案 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)
);