2024-06-29 06:20:54 +00:00
|
|
|
module CPU(
|
|
|
|
input reset ,
|
|
|
|
input clk ,
|
|
|
|
output MemRead ,
|
|
|
|
output MemWrite ,
|
|
|
|
output [32 -1:0] MemBus_Address ,
|
|
|
|
output [32 -1:0] MemBus_Write_Data ,
|
|
|
|
input [32 -1:0] Device_Read_Data
|
|
|
|
);
|
|
|
|
|
|
|
|
// PC register
|
|
|
|
reg [31 :0] PC;
|
|
|
|
wire [31 :0] PC_next;
|
|
|
|
wire [31 :0] PC_plus_4;
|
|
|
|
|
|
|
|
always @(posedge reset or posedge clk)
|
|
|
|
if (reset)
|
|
|
|
PC <= 32'h00000000;
|
|
|
|
else
|
|
|
|
PC <= PC_next;
|
|
|
|
|
|
|
|
assign PC_plus_4 = PC + 32'd4;
|
|
|
|
|
|
|
|
// Instruction Memory
|
|
|
|
wire [31 :0] Instruction;
|
|
|
|
InstructionMemory instruction_memory1(
|
|
|
|
.Address (PC ),
|
|
|
|
.Instruction (Instruction )
|
|
|
|
);
|
|
|
|
|
|
|
|
// Control
|
2024-06-30 15:01:11 +00:00
|
|
|
wire ReadFrom ;
|
2024-06-29 06:20:54 +00:00
|
|
|
wire [2 -1:0] RegDst ;
|
|
|
|
wire [2 -1:0] PCSrc ;
|
|
|
|
wire Branch ;
|
|
|
|
wire MemRead ;
|
|
|
|
wire MemWrite ;
|
|
|
|
wire [2 -1:0] MemtoReg ;
|
|
|
|
wire ALUSrc1 ;
|
|
|
|
wire ALUSrc2 ;
|
|
|
|
wire [4 -1:0] ALUOp ;
|
|
|
|
wire ExtOp ;
|
|
|
|
wire LuOp ;
|
|
|
|
wire RegWrite ;
|
2024-06-30 15:01:11 +00:00
|
|
|
wire RegWrite2 ;
|
2024-06-29 06:20:54 +00:00
|
|
|
|
|
|
|
Control control1(
|
|
|
|
.OpCode (Instruction[31:26] ),
|
|
|
|
.Funct (Instruction[5 : 0] ),
|
|
|
|
.PCSrc (PCSrc ),
|
|
|
|
.Branch (Branch ),
|
|
|
|
.RegWrite (RegWrite ),
|
2024-06-30 15:01:11 +00:00
|
|
|
.RegWrite2 (RegWrite2 ),
|
|
|
|
.ReadFrom (ReadFrom ),
|
2024-06-29 06:20:54 +00:00
|
|
|
.RegDst (RegDst ),
|
|
|
|
.MemRead (MemRead ),
|
|
|
|
.MemWrite (MemWrite ),
|
|
|
|
.MemtoReg (MemtoReg ),
|
|
|
|
.ALUSrc1 (ALUSrc1 ),
|
|
|
|
.ALUSrc2 (ALUSrc2 ),
|
|
|
|
.ExtOp (ExtOp ),
|
|
|
|
.LuOp (LuOp ),
|
|
|
|
.ALUOp (ALUOp )
|
|
|
|
);
|
|
|
|
|
|
|
|
// Register File
|
|
|
|
wire [32 -1:0] Databus1;
|
|
|
|
wire [32 -1:0] Databus2;
|
|
|
|
wire [32 -1:0] Databus3;
|
2024-06-30 15:01:11 +00:00
|
|
|
wire [32 -1:0] Databus4;
|
2024-06-29 06:20:54 +00:00
|
|
|
wire [5 -1:0] Write_register;
|
2024-06-30 16:24:09 +00:00
|
|
|
wire [5 -1:0] Write_register2;
|
|
|
|
wire [5 -1:0] Read_register1;
|
2024-06-30 15:01:11 +00:00
|
|
|
wire [5 -1:0] Read_register2;
|
2024-06-29 06:20:54 +00:00
|
|
|
|
2024-06-30 16:24:09 +00:00
|
|
|
assign Write_register = (RegDst == 2'b00)? Instruction[20:16]:
|
|
|
|
(RegDst == 2'b01)? Instruction[15:11]:
|
|
|
|
(RegDst == 2'b11)? Instruction[25:21]:
|
|
|
|
5'b11111;
|
|
|
|
assign Write_register2 = Instruction[15:11];
|
|
|
|
assign Read_register1 = Instruction[25:21];
|
|
|
|
assign Read_register2 = (ReadFrom == 1'b1)? Instruction[15:11]: Instruction[20:16];
|
2024-06-29 06:20:54 +00:00
|
|
|
|
|
|
|
RegisterFile register_file1(
|
|
|
|
.reset (reset ),
|
|
|
|
.clk (clk ),
|
2024-06-30 15:01:11 +00:00
|
|
|
.RegWrite (RegWrite ),
|
|
|
|
.Regwrite2 (RegWrite2 ),
|
2024-06-30 16:24:09 +00:00
|
|
|
.Read_register1 (Read_register1 ),
|
2024-06-30 15:01:11 +00:00
|
|
|
.Read_register2 (Read_register2 ),
|
2024-06-29 06:20:54 +00:00
|
|
|
.Write_register (Write_register ),
|
2024-06-30 16:24:09 +00:00
|
|
|
.Write_register2(Write_register2 ),
|
2024-06-29 06:20:54 +00:00
|
|
|
.Write_data (Databus3 ),
|
2024-06-30 15:01:11 +00:00
|
|
|
.Write_data2 (Databus4 ),
|
2024-06-29 06:20:54 +00:00
|
|
|
.Read_data1 (Databus1 ),
|
|
|
|
.Read_data2 (Databus2 )
|
|
|
|
);
|
|
|
|
|
|
|
|
// Extend
|
|
|
|
wire [32 -1:0] Ext_out;
|
|
|
|
assign Ext_out = { ExtOp? {16{Instruction[15]}}: 16'h0000, Instruction[15:0]};
|
|
|
|
|
|
|
|
wire [32 -1:0] LU_out;
|
|
|
|
assign LU_out = LuOp? {Instruction[15:0], 16'h0000}: Ext_out;
|
|
|
|
|
|
|
|
// ALU Control
|
|
|
|
wire [5 -1:0] ALUCtl;
|
|
|
|
wire Sign ;
|
|
|
|
|
|
|
|
ALUControl alu_control1(
|
|
|
|
.ALUOp (ALUOp ),
|
|
|
|
.Funct (Instruction[5:0] ),
|
|
|
|
.ALUCtl (ALUCtl ),
|
|
|
|
.Sign (Sign )
|
|
|
|
);
|
|
|
|
|
|
|
|
// ALU
|
|
|
|
wire [32 -1:0] ALU_in1;
|
|
|
|
wire [32 -1:0] ALU_in2;
|
|
|
|
wire [32 -1:0] ALU_out;
|
|
|
|
wire Zero ;
|
|
|
|
|
|
|
|
assign ALU_in1 = ALUSrc1? {27'h00000, Instruction[10:6]}: Databus1;
|
|
|
|
assign ALU_in2 = ALUSrc2? LU_out: Databus2;
|
|
|
|
|
|
|
|
ALU alu1(
|
|
|
|
.in1 (ALU_in1 ),
|
|
|
|
.in2 (ALU_in2 ),
|
|
|
|
.ALUCtl (ALUCtl ),
|
|
|
|
.Sign (Sign ),
|
|
|
|
.out (ALU_out ),
|
2024-06-30 15:01:11 +00:00
|
|
|
.out2 (Databus4 ),
|
2024-06-29 06:20:54 +00:00
|
|
|
.zero (Zero )
|
|
|
|
);
|
|
|
|
|
|
|
|
// Data Memory
|
|
|
|
wire [32 -1:0] Memory_Read_Data ;
|
|
|
|
wire Memory_Read ;
|
|
|
|
wire Memory_Write ;
|
|
|
|
wire [32 -1:0] MemBus_Read_Data ;
|
|
|
|
|
|
|
|
DataMemory data_memory1(
|
|
|
|
.reset (reset ),
|
|
|
|
.clk (clk ),
|
|
|
|
.Address (MemBus_Address ),
|
|
|
|
.Write_data (MemBus_Write_Data ),
|
|
|
|
.Read_data (Memory_Read_Data ),
|
|
|
|
.MemRead (Memory_Read ),
|
|
|
|
.MemWrite (Memory_Write )
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
assign Memory_Read = MemRead ;
|
|
|
|
assign Memory_Write = MemWrite;
|
|
|
|
assign MemBus_Address = ALU_out ;
|
|
|
|
assign MemBus_Write_Data = Databus2;
|
|
|
|
assign MemBus_Read_Data = Memory_Read_Data;
|
|
|
|
|
|
|
|
|
|
|
|
// write back
|
|
|
|
assign Databus3 = (MemtoReg == 2'b00)? ALU_out: (MemtoReg == 2'b01)? MemBus_Read_Data: PC_plus_4;
|
|
|
|
|
|
|
|
// PC jump and branch
|
|
|
|
wire [32 -1:0] Jump_target;
|
|
|
|
assign Jump_target = {PC_plus_4[31:28], Instruction[25:0], 2'b00};
|
|
|
|
|
|
|
|
wire [32 -1:0] Branch_target;
|
|
|
|
assign Branch_target = (Branch & Zero)? PC_plus_4 + {LU_out[29:0], 2'b00}: PC_plus_4;
|
|
|
|
|
|
|
|
assign PC_next = (PCSrc == 2'b00)? Branch_target: (PCSrc == 2'b01)? Jump_target: Databus1;
|
|
|
|
|
|
|
|
endmodule
|