ELEC50010-IAC-CW/rtl/mips_cpu_harvard.v

136 lines
5.3 KiB
Coq
Raw Normal View History

2020-11-24 05:20:29 +00:00
module mips_cpu_harvard(
/* Standard signals */
input logic clk,
input logic reset,
output logic active,
output logic [31:0] register_v0,
/* New clock enable. See below. */
input logic clk_enable,
2020-11-24 05:20:29 +00:00
/* Combinatorial read access to instructions */
output logic[31:0] instr_address,//Port from PC out to instruction memory address input.
input logic[31:0] instr_readdata,//port from instruction memory out, going to various inputs.
2020-11-24 05:20:29 +00:00
/* Combinatorial read and single-cycle write access to instructions */
output logic[31:0] data_address,//Port from ALURes going into Data Memory 'Address' port
output logic data_write,//Control line from 'control' CtrlMemWrite enabling/disabling write access for Data Memory.
output logic data_read,//Control line from 'control' CtrlMemRead enabling/disabling read access for Data Memory.
output logic[31:0] data_writedata,//Data from Register file 'Read data 2' port, aka rt's data, going to 'Write data' port on Data Memory.
input logic[31:0] data_readdata//port from data memory out, going to the 'Write Register' port in regfile.
);
always_comb begin
instr_address = out_pc_out;
data_address = out_ALURes;
data_write = out_MemWrite;
data_read = out_MemRead;
data_writedata = out_readdata2;
end
logic[31:0] in_pc_in;
logic[4:0] in_readreg1;
logic[4:0] in_readreg2;
logic[4:0] in_writereg;
logic[31:0] in_writedata;
logic[5:0] in_opcode;
logic[31:0] in_B;
always_comb begin
in_readreg1 = instr_readdata[25:21];
in_readreg2 = instr_readdata[20:16];
in_opcode = instr_readdata[31:26];
//Picking what register should be written to.
case(out_RegDst)
2'd0:begin
in_writereg = instr_readdata[20:16];//GPR rt
end
2'd1:begin
in_writereg = instr_readdata[15:11];//GPR rd
end
2'd2:begin
in_writereg = 5'd31;//Link Register 31.
end
endcase
//Picking which output should be written to regfile.
case(out_MemtoReg)
2'd0:begin
in_writedata = out_ALURes;//Output from ALU Result.
end
2'd1:begin
in_writedata = data_readdata;//Output from Data Memory.
end
2'd2:begin
in_writedata = (out_pc_out + 32'd8);//Output from PC +8.
end
endcase
//Picking which output should be taken as the second operand for ALU.
case(out_ALUSrc)
1'b1:begin
in_B = {{16{instr_readdata[15]}},instr_readdata[15:0]};//Output from the 16-bit immediate values sign extened to 32bits.
end
1'b0:begin
in_B = out_readdata2;//Output from 'Read data 2' port of regfile.
end
endcase
end
mips_cpu_pc pc(
//PC inputs
.clk(clk),//clk taken from the Standard signals
.rst(reset),//clk taken from the Standard signals
.Instr(instr_readdata),//what the pc will output on the next clock cycle taken from either: PC itself + 4(Normal/Default Operation); or 16-bit signed valued taken from Instr[15-0] sign extend to 32bit then shifted by 2 then added to PC + 4(Branch Operation); or 26-bit instruction address taken from J-type instr[25-0] shifted left by 2 then concatanated to form Jump Address (PC-region branch); or from the GPR rs.
.JumpReg(out_readdata1),
.pc_ctrl(out_PC),
//PC outputs
.pc_out(out_pc_out)//What the pc outputs at every clock edge that goes into the 'Read address' port of Instruction Memory.
);
mips_cpu_control control( //instance of the 'mips_cpu_control' module called 'control' in top level 'harvard'
//Inputs to control
.Instr(instr_readdata), //Full instruction taken from the Instruction Memory.
.ALUCond(out_ALUCond), //Active high condition check from ALU
//Outputs from control
.CtrlRegDst(out_RegDst),
.CtrlPC(out_PC),
.CtrlMemRead(out_MemRead),
.CtrlMemtoReg(out_MemtoReg),
.CtrlALUOp(out_ALUOp),
.Ctrlshamt(out_shamt),
.CtrlMemWrite(out_MemWrite),
.CtrlALUSrc(out_ALUSrc),
.CtrlRegWrite(out_RegWrite)
);
mips_cpu_regfile regfile(
//Inputs to refile
.clk(clk), //clock input for triggering write port
.readreg1(in_readreg1), //read port 1 selector
.readreg2(in_readreg2), //read port 2 selector
.writereg(in_writereg), //write port selector
.writedata(in_writedata), //write port input data
.regwrite(out_RegWrite), //enable line for write port
.opcode(in_opcode), //opcode input for controlling partial load weirdness
//Outputs from regfile
.readdata1(out_readdata1), //read port 1 output
.readdata2(out_readdata2), //read port 2 output
.regv0(register_v0) //debug output of $v0 or $2 (first register for returning function results
);
mips_cpu_alu alu(
//Inputs to ALU
.A(out_readdata1), //operand 1 taken from 'Read data 1' aka the data stored in GPR rs.
.B(in_B), //operand 2 taken either from: 'Read data 2' aka the data stored in rt; or 16-bit immediate sign extended to 32 bits.
.ALUOp(out_ALUOp), //Operation selection for ALU decided, and output by control.
.shamt(out_shamt), //Shift amount required for shift instruction taken from control.
//Outputs from ALU
.ALUCond(out_ALUCond), //condition used by control to decide on branch instructions.
.ALURes(out_ALURes) //output/result of operation that goes to either: 'Address' port of Data Memory; or 'Write Data' port of the register file.
);
endmodule