Line 93... |
Line 93... |
reg[63:0] ex_mem_aluout; // ALU result
|
reg[63:0] ex_mem_aluout; // ALU result
|
reg ex_mem_carry; // ALU carry
|
reg ex_mem_carry; // ALU carry
|
reg ex_mem_branch, ex_mem_jump, ex_mem_jr, ex_mem_linked;
|
reg ex_mem_branch, ex_mem_jump, ex_mem_jr, ex_mem_linked;
|
reg ex_mem_mult, ex_mem_div;
|
reg ex_mem_mult, ex_mem_div;
|
reg ex_mem_load,ex_mem_store;
|
reg ex_mem_load,ex_mem_store;
|
|
reg[2:0] ex_mem_size;
|
reg[31:0] ex_mem_store_value;
|
reg[31:0] ex_mem_store_value;
|
reg[3:0] ex_mem_store_sel; // Byte Selector on Stores
|
reg[3:0] ex_mem_store_sel; // Byte Selector on Stores
|
reg[4:0] ex_mem_destreg;
|
reg[4:0] ex_mem_destreg;
|
reg ex_mem_desthi, ex_mem_destlo;
|
reg ex_mem_desthi, ex_mem_destlo;
|
reg[4:0] ex_mem_destsyscon;
|
reg[4:0] ex_mem_destsyscon;
|
Line 1758... |
Line 1759... |
ex_mem_linked <= id_ex_linked;
|
ex_mem_linked <= id_ex_linked;
|
ex_mem_mult <= id_ex_mult;
|
ex_mem_mult <= id_ex_mult;
|
ex_mem_div <= id_ex_div;
|
ex_mem_div <= id_ex_div;
|
ex_mem_load <= id_ex_load;
|
ex_mem_load <= id_ex_load;
|
ex_mem_store <= id_ex_store;
|
ex_mem_store <= id_ex_store;
|
|
ex_mem_size <= id_ex_size;
|
ex_mem_destreg <= id_ex_destreg;
|
ex_mem_destreg <= id_ex_destreg;
|
ex_mem_desthi <= id_ex_desthi;
|
ex_mem_desthi <= id_ex_desthi;
|
ex_mem_destlo <= id_ex_destlo;
|
ex_mem_destlo <= id_ex_destlo;
|
|
|
// Choose the output from ALU, Multiplier or Divider
|
// Choose the output from ALU, Multiplier or Divider
|
if(id_ex_mult) begin
|
if(id_ex_mult) begin
|
ex_mem_aluout <= mul_product_i;
|
ex_mem_aluout <= mul_product_i;
|
ex_mem_carry <= 1b'0;
|
ex_mem_carry <= 1'b0;
|
end else if(id_ex_div) begin
|
end else if(id_ex_div) begin
|
ex_mem_aluout <= { div_remainder_i, div_quotient_i };
|
ex_mem_aluout <= { div_remainder_i, div_quotient_i };
|
ex_mem_carry <= 1b'0;
|
ex_mem_carry <= 1'b0;
|
end else begin
|
end else begin
|
ex_mem_aluout <= {32'b0, alu_result_i[31:0]};
|
ex_mem_aluout <= {32'b0, alu_result_i[31:0]};
|
ex_mem_carry <= alu_result_i[32];
|
ex_mem_carry <= alu_result_i[32];
|
end
|
end
|
|
|
if(id_ex_store) begin
|
|
|
|
// Handle all supported store sizes
|
// Handle all supported store sizes
|
|
if(id_ex_store) begin
|
$display("INFO: CPU(%m)-EX: Execution of Store instruction @ADDR=%X w/OPCODE=%X started to STORE_ADDR=%X w/STORE_DATA=%X", id_ex_addr, id_ex_opcode, alu_result_i, id_ex_store_value);
|
$display("INFO: CPU(%m)-EX: Execution of Store instruction @ADDR=%X w/OPCODE=%X started to STORE_ADDR=%X w/STORE_DATA=%X", id_ex_addr, id_ex_opcode, alu_result_i, id_ex_store_value);
|
case(id_ex_size)
|
case(id_ex_size)
|
`SIZE_WORD: begin
|
`SIZE_WORD: begin
|
ex_mem_store_value <= id_ex_store_value;
|
ex_mem_store_value <= id_ex_store_value;
|
ex_mem_store_sel <= 4'b1111;
|
ex_mem_store_sel <= 4'b1111;
|
Line 1814... |
Line 1815... |
end
|
end
|
endcase
|
endcase
|
end
|
end
|
endcase
|
endcase
|
|
|
end else begin
|
|
|
|
// Not a store
|
// Not a store
|
|
end else begin
|
$display("INFO: CPU(%m)-EX: Execution of instruction @ADDR=%X w/OPCODE=%X gave ALU result %X", id_ex_addr, id_ex_opcode, alu_result_i);
|
$display("INFO: CPU(%m)-EX: Execution of instruction @ADDR=%X w/OPCODE=%X gave ALU result %X", id_ex_addr, id_ex_opcode, alu_result_i);
|
|
|
end
|
end
|
|
|
end
|
end
|
|
|
/*
|
/*
|
Line 1849... |
Line 1848... |
mem_wb_addrnext <= ex_mem_addrnext;
|
mem_wb_addrnext <= ex_mem_addrnext;
|
mem_wb_destreg <= ex_mem_destreg;
|
mem_wb_destreg <= ex_mem_destreg;
|
mem_wb_desthi <= ex_mem_desthi;
|
mem_wb_desthi <= ex_mem_desthi;
|
mem_wb_destlo <= ex_mem_destlo;
|
mem_wb_destlo <= ex_mem_destlo;
|
|
|
|
// Handle all supported load sizes
|
if(ex_mem_load) begin
|
if(ex_mem_load) begin
|
|
|
$display("INFO: CPU(%m)-MEM: Loading value %X", dmem_data_i);
|
$display("INFO: CPU(%m)-MEM: Loading value %X", dmem_data_i);
|
mem_wb_value[63:32] <= 32'b0;
|
mem_wb_value[63:32] <= 32'b0;
|
|
case(ex_mem_size)
|
|
`SIZE_WORD: begin
|
mem_wb_value[31:0] <= dmem_data_i;
|
mem_wb_value[31:0] <= dmem_data_i;
|
|
end
|
|
`SIZE_HALF: begin
|
|
if(ex_mem_aluout[1]==0) mem_wb_value[31:0] <= {{16{dmem_data_i[15]}}, dmem_data_i[15:0]};
|
|
else mem_wb_value[31:0] <= {{16{dmem_data_i[31]}}, dmem_data_i[31:16]};
|
|
end
|
|
`SIZE_BYTE: begin
|
|
case(ex_mem_aluout[1:0])
|
|
2'b00: mem_wb_value[31:0] <= {{24{dmem_data_i[7]}}, dmem_data_i[7:0]};
|
|
2'b01: mem_wb_value[31:0] <= {{24{dmem_data_i[15]}}, dmem_data_i[15:8]};
|
|
2'b10: mem_wb_value[31:0] <= {{24{dmem_data_i[23]}}, dmem_data_i[23:16]};
|
|
2'b11: mem_wb_value[31:0] <= {{24{dmem_data_i[31]}}, dmem_data_i[31:24]};
|
|
endcase
|
|
end
|
|
endcase
|
|
|
|
// For multiplications and divisions the result is 64-bit wide
|
end else if (ex_mem_desthi && ex_mem_destlo) begin
|
end else if (ex_mem_desthi && ex_mem_destlo) begin
|
|
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
mem_wb_value[31:0] <= ex_mem_aluout[31:0];
|
|
mem_wb_value[63:32] <= ex_mem_aluout[63:32];
|
mem_wb_value[63:32] <= ex_mem_aluout[63:32];
|
|
mem_wb_value[31:0] <= ex_mem_aluout[31:0];
|
|
|
|
// For MTHI instruction we must move the value to the correct side of the bus
|
end else if (ex_mem_desthi) begin
|
end else if (ex_mem_desthi) begin
|
|
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
mem_wb_value[63:32] <= ex_mem_aluout[31:0];
|
mem_wb_value[63:32] <= ex_mem_aluout[31:0];
|
mem_wb_value[31:0] <= 32'b0;
|
mem_wb_value[31:0] <= 32'b0;
|
|
|
|
// The default is working with 32-bit values
|
end else begin
|
end else begin
|
|
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
$display("INFO: CPU(%m)-MEM: Propagating value %X", ex_mem_aluout);
|
mem_wb_value[31:0] <= ex_mem_aluout[31:0];
|
|
mem_wb_value[63:32] <= 32'b0;
|
mem_wb_value[63:32] <= 32'b0;
|
|
mem_wb_value[31:0] <= ex_mem_aluout[31:0];
|
|
|
end
|
end
|
|
|
end
|
end
|
|
|