我正在尝试实现一个迷你CPU,但是当我尝试为寄存器2分配值时遇到了麻烦。这里是代码
module miniCPU(
input [11:0] In,
input Clock,
output [7:0] Out,
output Overflow,
output [7:0] Re1,
output [7:0] Re2,
output cl,
output ee1,
output ee2,
output ee3,
reg [7:0] tempY,
input clk,
input clr
);
wire [7:0] r1;
wire [7:0] r2;
wire [7:0] y1;
wire [3:0] y2;
wire [7:0] Rout;
wire CLR;
wire EN1;
wire EN2;
wire EN3;
wire S0;
wire [2:0] Sel;
BusSplit B(.i(In[11:0]),.y_1(y1[7:0]),.y_2(y2[3:0]));
InstructionDecoder I(.Y2(y2[3:0]),.C(CLR),.E1(EN1),.E2(EN2),.E3(EN3),.S(S0),.sel(Sel[2:0]));
assign cl=CLR;
assign ee1=EN1;
assign ee2=EN2;
assign ee3=EN3;
assign clk=Clock;
assign clr=CLR;
Reg8bit R1(.r(r1[7:0]),.y(y1[7:0]),.CLK(Clock),.clr(CLR),.en(EN1));
always@(S0)
if (S0 == 1'b1)
assign tempY=y1;
else
assign tempY=Out;
Reg8bit R2(.r(r2[7:0]),.y(tempY[7:0]),.CLK(Clock),.clr(CLR),.en(EN2));
endmodule
module BusSplit (i,y_1,y_2);
input [11:0] i;
output [7:0] y_1;
output [3:0] y_2;
assign y_1 = i[7:0];
assign y_2 = i[11:8];
endmodule
module InstructionDecoder (Y2,C,E1,E2,E3,S,sel);
input [3:0] Y2;
output C;
output E1,E2,E3,S;
output [2:0] sel;
reg clr,e1,e2,e3,s;
reg[2:0] se;
always@(Y2)
if (Y2 == 4'b0000)
begin
clr=1'b1;
e1=1'b1;
e2=1'b1;
e3=1'b1;
end
else if (Y2 == 4'b0001)
begin
clr=1'b0;
e1=1'b1;
e2=1'b0;
e3=1'b0;
end
else if (Y2 == 4'b0010)
begin
clr=1'b0;
e1=1'b0;
e2=1'b1;
e3=1'b0;
s=1'b0;
end
else if (Y2 == 4'b0011)
begin
clr=1'b0;
e1=1'b0;
e2=1'b1;
e3=1'b0;
s=1'b1;
end
else if (Y2 == 4'b0100)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b000;
end
else if (Y2 == 4'b0101)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b001;
end
else if (Y2 == 4'b0110)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b010;
end
else if (Y2 == 4'b0111)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b011;
end
else if (Y2 == 4'b1000)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b100;
end
else if (Y2 == 4'b1001)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b101;
end
else
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b0;
end
assign C=clr;
assign E1=e1;
assign E2=e2;
assign E3=e3;
assign S=s;
assign sel=se;
endmodule
module Reg8bit (r,y,CLK,clr,en);
input [7:0] y;
input CLK;
input clr;
input en;
output [7:0] r;
reg[7:0] tempQ;
always @(posedge CLK)
begin
if (en)
begin
if (clr)
tempQ = 8'b00000000;
else
tempQ = y;
end
end
assign r=tempQ;
endmodule
另一个模块看起来工作正常,当我第一次调用模块Reg8bit时,我将值赋给r1,它可以工作。但是当我第二次调用模块Reg8bit时,r2的值变为xxxxxxxx。它是如此有线,因为模块是相同的,我没有改变任何东西,有人可以帮助我,非常感谢你
答案 0 :(得分:1)
我修改了你的代码,我认为这应该可以帮助你使代码工作,请参阅代码中的注释:
module miniCPU(
input [11:0]In,
input Clock,
output [7:0] Out,
output Overflow,
output [7:0] Re1,
output [7:0] Re2,
output cl,
output ee1,
output ee2,
output ee3,
//reg [7:0] tempY, //Without direction(in/output). Should not be in the interface or directed.
//As it seems to be a temporary value, I will consider that it is an internal signal.
input clk,
input clr
);
wire [7:0] r1;
wire [7:0] r2;
wire [7:0] y1;
wire [3:0] y2;
wire [7:0] Rout;
wire CLR;
wire EN1;
wire EN2;
wire EN3;
wire S0;
wire [2:0] Sel;
reg [7:0] tempY; //temporary Y declared here
//You are not coding software, declaration of the modules have no importance as long as all signals are declared.
//In my opinion though, it is easier to read a code where all modules declarations are grouped.
BusSplit B(.i(In[11:0]), .y_1(y1[7:0]), .y_2(y2[3:0]));
InstructionDecoder I(.Y2(y2[3:0]), .C(CLR), .E1(EN1), .E2(EN2), .E3(EN3), .S(S0), .sel(Sel[2:0]));
Reg8bit R1(.r(r1[7:0]), .y(y1[7:0]), .CLK(Clock), .clr(CLR), .en(EN1));
Reg8bit R2(.r(r2[7:0]), .y(tempY[7:0]), .CLK(Clock), .clr(CLR), .en(EN2));
assign cl=CLR;
//Also a personal consideration, but I would put first processes, then output assignements.
always@(S0 or y1 or Out)//Piece of advice, use always@(*) for combinatorial processes. It will avoid a lot of problem caused by sensitivity lists
if (S0 == 1'b1)
//assign tempY=y1;//You cannot 'assign' in process
tempY = y1;
else
//assign tempY=Out;//Same as the previous assignement
//I am not quite sure of what you want to do here, 'Out' is never assigned --> X in tempY.
tempY = Out//?
assign ee1=EN1;
assign ee2=EN2;
assign ee3=EN3;
assign clk=Clock;
assign clr=CLR;
assign Out = 8'hXX//Can't guess what you want to do
endmodule
module BusSplit (i,y_1,y_2);
input [11:0] i;
output [7:0] y_1;
output [3:0] y_2;
assign y_1 = i[7:0];
assign y_2 = i[11:8];
endmodule
module InstructionDecoder (Y2,C,E1,E2,E3,S,sel);
input [3:0] Y2;
output C;
output E1,E2,E3,S;
output [2:0] sel;
reg clr,e1,e2,e3,s;
reg[2:0] se;
always@(Y2)//Same remark about always@* as earlier
//Be careful if you want to synthesize you design, there are some signals that are not assigned in some cases, it will generate latches !
// A way to avoid that is to assign all values with a default value before the case. The case will modify the relevant signals regarding your selection signal :
begin//more that one line now, need 'begin-end'
clr = 1'b0;
e1 = 1'b0;
e2 = 1'b0;
e3 = 1'b0;
s = 1'b0;
se = 3'b000;
if (Y2 == 4'b0000)
begin
clr=1'b1;
e1=1'b1;
e2=1'b1;
e3=1'b1;
end
else if (Y2 == 4'b0001)
begin
clr=1'b0;
e1=1'b1;
e2=1'b0;
e3=1'b0;
end
else if (Y2 == 4'b0010)
begin
clr=1'b0;
e1=1'b0;
e2=1'b1;
e3=1'b0;
s=1'b0;
end
else if (Y2 == 4'b0011)
begin
clr=1'b0;
e1=1'b0;
e2=1'b1;
e3=1'b0;
s=1'b1;
end
else if (Y2 == 4'b0100)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b000;
end
else if (Y2 == 4'b0101)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b001;
end
else if (Y2 == 4'b0110)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b010;
end
else if (Y2 == 4'b0111)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b011;
end
else if (Y2 == 4'b1000)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b100;
end
else if (Y2 == 4'b1001)
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b1;
se=3'b101;
end
else
begin
clr=1'b0;
e1=1'b0;
e2=1'b0;
e3=1'b0;
end
end//end for the always@(Y2)
assign C=clr;
assign E1=e1;
assign E2=e2;
assign E3=e3;
assign S=s;
assign sel=se;
endmodule
module Reg8bit (r,y,CLK,clr,en);
input [7:0] y;
input CLK;
input clr;
input en;
output [7:0] r;
reg[7:0] tempQ;
always @(posedge CLK)
begin
if (en)
begin
if (clr)
tempQ <= 8'b00000000; //Flops should use non-blocking (<=) assignments, not blocking (=)
else
tempQ <= y; //Same as previous flop assignment
end
end
assign r=tempQ;
endmodule