我正在设计一个 LC-3(小型计算机)CPU。我在模块中设计了 PC 单元、控制单元(作为有限状态机)、指令存储器、ALU 单元和数据存储器。还有一个寄存器文件单元作为主单元,模块调用在这个单元中完成。
我希望程序在 PCread 为 1 时工作,从变量中获取要分配给out
的in
变量,当 PCwrite 为 1 时,只需递增out
变量。out
是发送到指令存储器的地址。
问题是当我模拟时,指令永远不会加载到指令内存中。因为 PCwrite 不适用于控制单元的第一个状态,因为我在第一个状态下重置了 PCread 和 PCread 变量。我这样做是因为我不希望在一条指令完成它工作之前加载指令。我找不到处理这个问题的方法。
我知道如果解决了这个问题,处理器就会工作,因为当我尝试一条具有初始化值的指令时,它就可以工作。
module reg_fileandMain();
parameter B=16, W=3;
reg Clk;
wire wr_en;
wire [W-1:0] w_addr, r_addr1, r_addr2;
wire [B-1:0] inData;
wire [B-1:0] r_data1;
wire [B-1:0] r_data2;
wire [B-1:0] address;
wire Dataout;
wire InsMemRead;
reg [15:0] extended, mux1out, mux2out, mux3out, mux4out, mux5out;
wire ALUout, incrementer;
wire [15:0] instruction;
reg [B-1:0] array_reg[2**W-1:0];
wire mux1,mux3,mux4,mux5;
wire [1:0] mux2;
initial begin
mux5out=16'hFFFF;
end
wire MemRead,PCwrite,ALUcontrol,MemWrite,PCread;
always@(posedge Clk)
begin
if(wr_en)begin
array_reg[w_addr]<=inData;
end
end
assign r_data1=array_reg[r_addr1];
assign r_data2=array_reg[r_addr2];
controlUnit controlUnit0(Clk,instruction,mux1,mux2,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,wr_en,ALUcontrol,MemWrite,PCread,r_addr1,r_addr2,w_addr);
PCunit PCunit0(Clk,PCwrite,PCread,mux5out,address);
DataMem DataMem0(Clk,mux2out,r_data1,MemRead,MemWrite,Dataout);
ALU ALU0(mux1out,r_data2,ALUout,ALUcontrol);
InstructionMemory InstructionMemory0(Clk,address,InsMemRead,instruction);
always @* begin
if(mux1)begin
extended = { {11{instruction[4]}}, instruction[4:0] };
mux1out=extended;
end
else begin
mux1out=r_data1;
end
if(mux2==2'b00)begin
mux2out=ALUout;
end
else if(mux2==2'b01)begin
extended = instruction[8:0];
mux2out=extended;
end
else if(mux2==2'b11)begin
extended = instruction[8:0];
mux2out=extended;
end
if(mux3)begin
mux3out<=mux2out;
end
else begin
mux3out<=Dataout;
end
if(mux4)begin
mux4out<=address;
end
else begin
mux4out<=mux3out;
end
if(mux5)begin
mux5out<=address;
end
else begin
mux5out<=mux3out;
end
end
assign inData=mux4out;
always begin
#20 Clk<=0;
#20 Clk<=1;
end
endmodule
module controlUnit(Clk,in,mux1,mux2,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread,rd1,rd2,wr);
input Clk;
input [15:0] in;
output reg mux1,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread;
output reg [1:0] mux2;
reg [3:0] state,stateNext;
reg counter;
output wire [2:0] rd1,rd2,wr;
initial begin
state=4'b0000;
stateNext=4'b0001;
MemRead=0;
PCwrite=1;
end
assign rd1=in[2:0];
assign rd2=in[8:6];
assign wr=in[11:9];
always @* begin
if (state==4'b0000)begin
stateNext=4'b0001;
PCwrite=0;
PCread=0;
end
if(state==4'b0001)
begin
InsMemRead<=1;
if(in[15:12]==4'b0100)begin
stateNext=4'b0100;
InsMemRead=1'b1;
end
else if( in[15:12]==4'b1000)begin
stateNext=4'b0100;
InsMemRead=1;
end
else if(in[15:12]==4'b0010)begin
stateNext=4'b0010;
InsMemRead=1;
end
else if(in[15:12]==4'b1100)begin
stateNext=4'b1100;
InsMemRead=1;
end
else if(in[15:12]==1010)begin
stateNext=4'b1010;
InsMemRead=1;
end
end
else if(state==4'b0100)begin
stateNext=4'b0101;
end
else if(state==4'b0101)begin
stateNext=4'b0000;
mux3=0;
mux4=0;
WE=1;
mux2=2'b01;
MemRead=1;
mux5=1;
PCwrite=1;
end
else if(state==4'b1000)begin
stateNext=4'b0000;
mux1=in[5];
ALUcontrol=0;
mux3=1;
mux4=0;
WE=1;
PCwrite=1;
end
else if(state==4'b0010)begin
stateNext=4'b0000;
mux1=in[5];
ALUcontrol=1;
mux3=1;
mux4=0;
WE=1;
PCwrite=1;
end
else if(state==4'b1100)begin
stateNext=4'b0000;
mux2=2'b01;
MemWrite=1;
PCwrite=1;
end
else if(state==4'b1010)begin
stateNext=4'b0000;
mux2=2'b11;
mux3=1;
mux5=0;
PCread=1;
end
end
always @(posedge Clk) begin
state = stateNext;
end
endmodule
module PCunit(Clk,PCwrite,PCread,in,out);
input Clk,PCread,PCwrite;
input wire [15:0] in;
output reg [15:0] out;
always @(posedge Clk) begin
if(PCwrite)
begin
out<=out+1;
end
else
begin
if(PCread)
begin
out<=in;
end
end
end
endmodule
module ALU(in1,in2,ALUout,ALUcontrol);
input ALUcontrol;
input wire [15:0] in1, in2;
output reg [15:0] ALUout;
always @* begin
if(ALUcontrol)
ALUout = in1 + in2;
else
ALUout = in1 & in2;
end
endmodule
module DataMem(Clk,AddrReg,in,MemRead,MemWrite,out);
input Clk, MemRead, MemWrite;
input [15:0] AddrReg, in;
output reg [15:0] out;
reg[15:0] Mem[2**9:0];
always @(posedge Clk) begin
if(MemWrite)begin
Mem[AddrReg]=in;
end
end
always @* begin
if(MemRead) begin
out=Mem[AddrReg];
end
end
endmodule
module InstructionMemory(Clk,address,InsMemRead,instruction);
input Clk;
input [15:0] address;
input InsMemRead;
output reg [15:0] instruction;
reg [15:0] InstructionMemory [15:0];
initial begin
$readmemh("AssemblerOutput.hex", InstructionMemory);
end
always@(posedge Clk)begin
if(InsMemRead)
instruction=InstructionMemory[address];
end
endmodule