Merge branch 'main' of https://github.com/supleed2/AM04_CPU into main

This commit is contained in:
yhp19 2020-12-19 19:04:39 +08:00
commit 3836be459f
3 changed files with 21 additions and 9 deletions

View file

@ -1 +1 @@
3 2

View file

@ -30,12 +30,13 @@ logic[31:0] out_pc_out, out_ALURes, out_readdata1, out_readdata2, in_B, in_write
logic[4:0] in_readreg1, in_readreg2, in_writereg, out_shamt, out_ALUOp; logic[4:0] in_readreg1, in_readreg2, in_writereg, out_shamt, out_ALUOp;
logic[5:0] in_opcode; logic[5:0] in_opcode;
logic out_ALUCond, out_RegWrite, out_MemWrite, out_MemRead, out_SpcRegWriteEn; logic out_ALUCond, out_RegWrite, out_MemWrite, out_MemRead, out_SpcRegWriteEn;
logic[1:0] out_RegDst, out_PC, out_ALUSrc; logic[1:0] out_RegDst, out_PC, out_ALUSrc, ALURes_offset;
logic[2:0] out_MemtoReg; logic[2:0] out_MemtoReg;
assign in_readreg1 = instr_readdata[25:21]; assign in_readreg1 = instr_readdata[25:21];
assign in_readreg2 = instr_readdata[20:16]; assign in_readreg2 = instr_readdata[20:16];
assign in_opcode = instr_readdata[31:26]; assign in_opcode = instr_readdata[31:26];
assign ALURes_offset = out_ALURes[1:0];
always @(*) begin always @(*) begin
//Picking what register should be written to. //Picking what register should be written to.
@ -116,6 +117,7 @@ mips_cpu_control control( //instance of the 'mips_cpu_control' module called 'co
mips_cpu_regfile regfile( mips_cpu_regfile regfile(
//Inputs to refile //Inputs to refile
.clk(clk), //clock input for triggering write port .clk(clk), //clock input for triggering write port
.rst(reset),
.readreg1(in_readreg1), //read port 1 selector .readreg1(in_readreg1), //read port 1 selector
.readreg2(in_readreg2), //read port 2 selector .readreg2(in_readreg2), //read port 2 selector
.writereg(in_writereg), //write port selector .writereg(in_writereg), //write port selector
@ -125,6 +127,7 @@ mips_cpu_regfile regfile(
//Outputs from regfile //Outputs from regfile
.readdata1(out_readdata1), //read port 1 output .readdata1(out_readdata1), //read port 1 output
.readdata2(out_readdata2), //read port 2 output .readdata2(out_readdata2), //read port 2 output
.vaddr(ALURes_offset), //base+offset[1:0]
.regv0(register_v0) //debug output of $v0 or $2 (first register for returning function results .regv0(register_v0) //debug output of $v0 or $2 (first register for returning function results
); );

View file

@ -1,5 +1,6 @@
module mips_cpu_regfile( module mips_cpu_regfile(
input logic clk, //clock input for triggering write port input logic clk, //clock input for triggering write port
input logic rst,
input logic[4:0] readreg1, //read port 1 register selector input logic[4:0] readreg1, //read port 1 register selector
input logic[4:0] readreg2, //read port 2 register selector input logic[4:0] readreg2, //read port 2 register selector
input logic[4:0] writereg, //write port register selector input logic[4:0] writereg, //write port register selector
@ -8,6 +9,7 @@ input logic regwrite, //enable line for write port
input[5:0] opcode, //opcode input for controlling partial load weirdness input[5:0] opcode, //opcode input for controlling partial load weirdness
output logic[31:0] readdata1, //read port 1 output output logic[31:0] readdata1, //read port 1 output
output logic[31:0] readdata2, //read port 2 output output logic[31:0] readdata2, //read port 2 output
input logic[1:0] vaddr, //partial read offset from ALUout
output logic[31:0] regv0 //debug output of $v0 or $2 (third register in file/ first register for returning function results) output logic[31:0] regv0 //debug output of $v0 or $2 (third register in file/ first register for returning function results)
); );
@ -25,13 +27,20 @@ assign regv0 = memory[2]; //assigning debug $v0 line to $2 of memory
assign readdata1 = memory[readreg1]; //combinatorially output register value based on read port 1 selector assign readdata1 = memory[readreg1]; //combinatorially output register value based on read port 1 selector
assign readdata2 = memory[readreg2]; //combinatorially output register value based on read port 2 selector assign readdata2 = memory[readreg2]; //combinatorially output register value based on read port 2 selector
always_ff @(posedge rst) begin
integer i; //Initialise to zero when reset
for (i = 0; i < 32; i++) begin
memory[i] = 0;
end
end
always_ff @(negedge clk) begin always_ff @(negedge clk) begin
if (writereg == 5'b00000) begin if (writereg == 5'b00000) begin
// skip writing if rd is $0 // skip writing if rd is $0
end else if (regwrite) begin end else if (regwrite) begin
case (opcode) case (opcode)
6'b100000: begin //lb, load byte 6'b100000: begin //lb, load byte
case (readdata1[1:0]) case (vaddr)
2'b00: memory[writereg] <= {{24{writedata[7]}}, writedata[7:0]}; 2'b00: memory[writereg] <= {{24{writedata[7]}}, writedata[7:0]};
2'b01: memory[writereg] <= {{24{writedata[15]}}, writedata[15:8]}; 2'b01: memory[writereg] <= {{24{writedata[15]}}, writedata[15:8]};
2'b10: memory[writereg] <= {{24{writedata[23]}}, writedata[23:16]}; 2'b10: memory[writereg] <= {{24{writedata[23]}}, writedata[23:16]};
@ -39,7 +48,7 @@ always_ff @(negedge clk) begin
endcase // readdata1[1:0] endcase // readdata1[1:0]
end end
6'b100100: begin //lbu, load byte unsigned 6'b100100: begin //lbu, load byte unsigned
case (readdata1[1:0]) case (vaddr)
2'b00: memory[writereg] <= {{24{1'b0}}, writedata[7:0]}; 2'b00: memory[writereg] <= {{24{1'b0}}, writedata[7:0]};
2'b01: memory[writereg] <= {{24{1'b0}}, writedata[15:8]}; 2'b01: memory[writereg] <= {{24{1'b0}}, writedata[15:8]};
2'b10: memory[writereg] <= {{24{1'b0}}, writedata[23:16]}; 2'b10: memory[writereg] <= {{24{1'b0}}, writedata[23:16]};
@ -47,19 +56,19 @@ always_ff @(negedge clk) begin
endcase // readdata1[1:0] endcase // readdata1[1:0]
end end
6'b100001: begin //lh, load half-word 6'b100001: begin //lh, load half-word
case (readdata1[1:0]) // must be half-word aligned, readdata1[0] = 0 case (vaddr) // must be half-word aligned, readdata1[0] = 0
2'b00: memory[writereg] <= {{16{writedata[15]}}, writedata[15:0]}; 2'b00: memory[writereg] <= {{16{writedata[15]}}, writedata[15:0]};
2'b10: memory[writereg] <= {{16{writedata[31]}}, writedata[31:16]}; 2'b10: memory[writereg] <= {{16{writedata[31]}}, writedata[31:16]};
endcase // readdata1[1:0] endcase // readdata1[1:0]
end end
6'b100101: begin //lhu, load half-word unsigned 6'b100101: begin //lhu, load half-word unsigned
case (readdata1[1:0]) // must be half-word aligned, readdata1[0] = 0 case (vaddr) // must be half-word aligned, readdata1[0] = 0
2'b00: memory[writereg] <= {{16{1'b0}}, writedata[15:0]}; 2'b00: memory[writereg] <= {{16{1'b0}}, writedata[15:0]};
2'b10: memory[writereg] <= {{16{1'b0}}, writedata[31:16]}; 2'b10: memory[writereg] <= {{16{1'b0}}, writedata[31:16]};
endcase // readdata1[1:0] endcase // readdata1[1:0]
end end
6'b100010: begin //lwl, load word left 6'b100010: begin //lwl, load word left
case (readdata1[1:0]) case (vaddr)
2'b00: memory[writereg][31:24] <= writedata[7:0]; 2'b00: memory[writereg][31:24] <= writedata[7:0];
2'b01: memory[writereg][31:16] <= writedata[15:0]; 2'b01: memory[writereg][31:16] <= writedata[15:0];
2'b10: memory[writereg][31:8] <= writedata[23:0]; 2'b10: memory[writereg][31:8] <= writedata[23:0];
@ -67,7 +76,7 @@ always_ff @(negedge clk) begin
endcase // readdata1[1:0] endcase // readdata1[1:0]
end end
6'b100110: begin //lwr, load word right 6'b100110: begin //lwr, load word right
case (readdata1[1:0]) case (vaddr)
2'b00: memory[writereg][31:0] <= writedata[31:0]; 2'b00: memory[writereg][31:0] <= writedata[31:0];
2'b01: memory[writereg][23:0] <= writedata[31:8]; 2'b01: memory[writereg][23:0] <= writedata[31:8];
2'b10: memory[writereg][15:0] <= writedata[31:16]; 2'b10: memory[writereg][15:0] <= writedata[31:16];
@ -81,4 +90,4 @@ always_ff @(negedge clk) begin
end end
end end
endmodule endmodule