MIPS_Processor/sources_1/imports/single-cycle/CPU.v

155 lines
4.1 KiB
Verilog

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
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 ;
Control control1(
.OpCode (Instruction[31:26] ),
.Funct (Instruction[5 : 0] ),
.PCSrc (PCSrc ),
.Branch (Branch ),
.RegWrite (RegWrite ),
.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;
wire [5 -1:0] Write_register;
assign Write_register = (RegDst == 2'b00)? Instruction[20:16]: (RegDst == 2'b01)? Instruction[15:11]: 5'b11111;
RegisterFile register_file1(
.reset (reset ),
.clk (clk ),
.RegWrite (RegWrite ),
.Read_register1 (Instruction[25:21] ),
.Read_register2 (Instruction[20:16] ),
.Write_register (Write_register ),
.Write_data (Databus3 ),
.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 ),
.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