ELEC50010-IAC-CW/rtl/mips_cpu_harvard.v

113 lines
3.8 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,
/* Combinatorial read access to instructions */
output logic[31:0] instr_address,
input logic[31:0] instr_readdata,
/* Combinatorial read and single-cycle write access to instructions */
output logic[31:0] data_address,
output logic data_write,
output logic data_read,
output logic[31:0] data_writedata,
input logic[31:0] data_readdata
);
//Control Flags
logic Jump, Branch, ALUSrc, ALUZero, RegWrite;
logic[5:0] ALUOp = instr_readdata[31:26];
logic[30:0] ALUFlags; //Not sure if this is needed anymore
logic[1:0] RegDst, MemtoReg;
//PC wires
logic[31:0] pc_curr;
logic[31:0] pc_curr_next = pc_curr + 3'd4; //Added due to compilation error
logic[31:0] pc_delay; //Added due to compilation error
logic[31:0] Jump_addr = {pc_curr_next[31:28], instr_readdata[25:0], 2'b00};
logic[31:0] pc_next = Jump ? Jump_addr : PCSrc ? {pc_curr_next + {{14{instr_readdata[15]}}, instr_readdata[15:0], 2'b00}} : pc_curr_next;
logic PCSrc = Branch && ALUZero;
//Instruction MEM
assign instr_address = pc_delay;
//deconstruction of instruction :)
logic[5:0] opcode = instr_readdata[31:26];
logic[4:0] rs = instr_readdata[25:21];
logic[4:0] rt = instr_readdata[20:16];
logic[4:0] rd = RegDst==2'b10 ? 5'b11111 : RegDst==2'b01 ? instr_readdata[15:11] : instr_readdata[20:16];
2020-11-30 14:15:36 +00:00
logic[15:0] immediate = instr_readdata[15:0];
2020-12-02 13:27:37 +00:00
logic[4:0] shamt = instr_readdata[10:6]; // Shamt needed for the sll instruction
//ALU Data
logic[31:0] alu_in1 = read_data1;
logic[31:0] alu_in2 = ALUSrc ? {{16{immediate[15]}},immediate} : read_data2;
logic[31:0] ALUOut;
//Data MEM
assign data_address = ALUOut; //address to be written to comes from ALU
assign data_writedata = read_data2; //data to be written comes from reg read bus 2
//Writeback logic
logic[31:0] writeback = MemtoReg==2'b10 ? {pc_curr_next} : MemtoReg==2'b01 ? data_readdata : ALUOut;
always_ff @(posedge clk) begin
pc_delay <= pc_curr;
end
pc pc(
.clk(clk),
.rst(reset),
.pc_in(pc_next),
.pc_out(pc_curr)
);
mips_cpu_control control( //control flags block
.Instr(opcode), //opcode to be decoded
.Jump(Jump), //jump flag: 0 - increment or branch, 1 - J-type jump
.Branch(Branch), //branch flag: 0 - increment, 1 - branch if ALU.Zero == 1
.Memread(data_read), //tells data memory to read out data at dMEM[ALUout]
.Memtoreg(MemtoReg), //0: writeback = ALUout, 1: writeback = data_readdata
.Memwrite(data_write), //tells data memory to store data_writedata at data_writeaddress
.Alusrc(ALUSrc), //0: ALUin2 = read_data2, 1: ALUin2 = signextended(instr_readdata[15:0])
.Regwrite(RegWrite), //tells register file to write writeback to rd
.Regdst(RegDst) //select Rt, Rd or $ra to store to
);
regfile regfile(
.clk(clk), //clock input for triggering write port
.readreg1(rs), //read port 1 selector
.readreg2(rt), //read port 2 selector
.writereg(rd), //write port selector
.writedata(writeback), //write port input data
.regwrite(RegWrite), //enable line for write port
.opcode(opcode), //opcode input for controlling partial load weirdness
.readdata1(read_data1), //read port 1 output
.readdata2(read_data2), //read port 2 output
.regv0(register_v0) //debug output of $v0 or $2 (first register for returning function results
);
/*
alucontrol alucontrol(
.ALUOp(ALUOp), //opcode of instruction
.funct(immediate[5:0]), //funct of instruction
.aluflags(ALUFlags) //ALU Control flags
);
*/
mips_cpu_alu alu(
//.ALUFlags(ALUFlags), //selects the operation carried out by the ALU
2020-12-02 13:27:37 +00:00
.A(alu_in1), //operand 1
.B(alu_in2), //operand 2
.ALUCond(ALUZero), //is the result zero, used for checks
.ALURes(ALUOut), //output/result of operation
.shamt(shamt),
.ALUOp(ALUOp)
);
endmodule : mips_cpu_harvard