diff --git a/MCLR5/Core/DPROM_8Kx128.v b/MCLR5/Core/DPROM_8Kx128.v new file mode 100644 index 0000000..ff2fdd9 --- /dev/null +++ b/MCLR5/Core/DPROM_8Kx128.v @@ -0,0 +1,80 @@ +// +// File Name : DPROM_8Kx128.v +// Used on : +// Author : Ted Fried, MicroCore Labs +// Creation : 8/57/2017 +// Code Type : Behavioral +// +// Description: +// ============ +// Xilinx ROM behavioral model. +// +// + +//------------------------------------------------------------------------ + + +`timescale 1ns/100ps + + + +module DPROM_8Kx128 + ( + input clka, + input[12:0] addra, + output reg[127:0] douta, + + input clkb, + input[12:0] addrb, + output reg[127:0] doutb + + ); + +//------------------------------------------------------------------------ + +integer file, k, l; +reg [127:0] ram_array[0:8191]; + + + +//------------------------------------------------------------------------ + + +initial + begin + + // Zero out the RAM so there are no X's + for (k = 0; k < 8192 ; k = k + 1) + begin + ram_array[k] = 'h0; + end + + + // Load the instructions into the array using ASCII byte file + $readmemh("D:/MCL/MCLR5/Quad_Issue/usercode_rom.hex", ram_array); + //$readmemb("C:/MCL/MCLR5/Quad_Issue/usercode_rom.hex", ram_array); + + end + + + +always @(posedge clka) + begin + + douta <= ram_array[addra]; + doutb <= ram_array[addrb]; + + end + + + + +//------------------------------------------------------------------------ + +endmodule + + +//------------------------------------------------------------------------ + + + diff --git a/MCLR5/Core/MCLR5.v b/MCLR5/Core/MCLR5.v new file mode 100644 index 0000000..25ca134 --- /dev/null +++ b/MCLR5/Core/MCLR5.v @@ -0,0 +1,491 @@ +// +// +// File Name : MCLR5.v +// Author : Ted Fried, MicroCore Labs +// Creation : 4/27/2018 +// Code Type : Synthesizable +// +//------------------------------------------------------------------------ +// +// Description: +// ============ +// +// Quad-issue Superscalar Risc V Processor +// +//------------------------------------------------------------------------ +// +// Copyright (C) 2018 by Ted Fried info@MicroCoreLabs.com +// +// Permission to use, copy, modify, and distribute this software and its +// documentation for any purpose and without fee is hereby granted, provided +// that the above copyright notice appear in all copies and that both that +// copyright notice and this permission notice appear in supporting documentation. +// This software is provided "as is" without express or implied warranty. +// +//------------------------------------------------------------------------ +// +// Modification History: +// ===================== +// +// Revision 1 4/27/18 +// Initial revision +// +// +//------------------------------------------------------------------------ + + +module MCLR5 + ( + input CORE_CLK, + input RST_n, + + output [31:0] LOAD_STORE_ADDRESS, + output [31:0] STORE_DATA, + input [31:0] LOAD_DATA, + output LOAD_REQ, + output STORE_REQ + + ); + +//------------------------------------------------------------------------ + +// Internal Signals + +reg new_pc_stall = 'h0; +reg alu0_load_req_d = 'h0; +reg alu1_load_req_d = 'h0; +reg alu2_load_req_d = 'h0; +reg alu3_load_req_d = 'h0; +reg [31:0] register_1 = 'h0; +reg [31:0] register_2 = 'h0; +reg [31:0] register_3 = 'h0; +reg [31:0] register_4 = 'h0; +reg [3:0] loadstore_stall = 'h0; +reg [31:0] new_pc = 'h0; +wire alu0_load_req; +wire alu1_load_req; +wire alu2_load_req; +wire alu3_load_req; +wire alu0_store_req; +wire alu1_store_req; +wire alu2_store_req; +wire alu3_store_req; +wire [31:0] i_immediate; +wire [255:0] program_rom_data; +wire [31:0] new_pc_plus1; +wire [32:0] alu0_rd; +wire [32:0] alu1_rd; +wire [32:0] alu2_rd; +wire [32:0] alu3_rd; +wire [32:0] alu0_newpc; +wire [32:0] alu1_newpc; +wire [32:0] alu2_newpc; +wire [32:0] alu3_newpc; +wire [31:0] alu0_opcode; +wire [31:0] alu1_opcode; +wire [31:0] alu2_opcode; +wire [31:0] alu3_opcode; +wire [31:0] alu0_pc; +wire [31:0] alu1_pc; +wire [31:0] alu2_pc; +wire [31:0] alu3_pc; +wire [31:0] alu0_rs1; +wire [31:0] alu1_rs1; +wire [31:0] alu2_rs1; +wire [31:0] alu3_rs1; +wire [31:0] alu0_rs2; +wire [31:0] alu1_rs2; +wire [31:0] alu2_rs2; +wire [31:0] alu3_rs2; +wire [31:0] alu0_load_store_address; +wire [31:0] alu0_store_data; +wire [31:0] alu0_load_data; +wire [4:0] alu0_opcode_rs1; +wire [4:0] alu1_opcode_rs1; +wire [4:0] alu2_opcode_rs1; +wire [4:0] alu3_opcode_rs1; +wire [4:0] alu0_opcode_rs2; +wire [4:0] alu1_opcode_rs2; +wire [4:0] alu2_opcode_rs2; +wire [4:0] alu3_opcode_rs2; +wire [4:0] alu0_opcode_rd; +wire [4:0] alu1_opcode_rd; +wire [4:0] alu2_opcode_rd; +wire [4:0] alu3_opcode_rd; + + + + + +/* +// For Xilinx FPGAs +DPROM_8Kx128 code_rom + ( + .clka (CORE_CLK), + .addra (new_pc[14:2]), + .douta (program_rom_data[127:0]), + + .clkb (CORE_CLK), + .addrb (new_pc_plus1[14:2]), + .doutb (program_rom_data[255:128]) + ); + + */ + + DPROM_8Kx128 code_rom ( + .address_a (new_pc[14:2]), // input, width = 13, ram_input.address_a + .address_b (new_pc_plus1[14:2]), // input, width = 13, .address_b + .clock (CORE_CLK), // input, width = 1, .clock + .q_a (program_rom_data[127:0]), // output, width = 128, ram_output.q_a + .q_b (program_rom_data[255:128]) // output, width = 128, .q_b + ); + + + + + + +assign new_pc_plus1 = new_pc + 3'h4; + + +assign alu0_pc = new_pc; +assign alu1_pc = new_pc + 1; +assign alu2_pc = new_pc + 2; +assign alu3_pc = new_pc + 3; + + + +assign alu0_opcode = (new_pc[1:0]==2'h0) ? program_rom_data[31:0] : + (new_pc[1:0]==2'h1) ? program_rom_data[63:32] : + (new_pc[1:0]==2'h2) ? program_rom_data[95:64] : + program_rom_data[127:96] ; + + +assign alu1_opcode = (new_pc[1:0]==2'h0) ? program_rom_data[63:32] : + (new_pc[1:0]==2'h1) ? program_rom_data[95:64] : + (new_pc[1:0]==2'h2) ? program_rom_data[127:96] : + program_rom_data[159:128] ; + +assign alu2_opcode = (new_pc[1:0]==2'h0) ? program_rom_data[95:64] : + (new_pc[1:0]==2'h1) ? program_rom_data[127:96] : + (new_pc[1:0]==2'h2) ? program_rom_data[159:128] : + program_rom_data[191:160] ; + +assign alu3_opcode = (new_pc[1:0]==2'h0) ? program_rom_data[127:96] : + (new_pc[1:0]==2'h1) ? program_rom_data[159:128] : + (new_pc[1:0]==2'h2) ? program_rom_data[191:160] : + program_rom_data[223:192] ; + + + +// Register decodes from the opcode +// +assign alu0_opcode_rs1 = alu0_opcode[19:15]; +assign alu0_opcode_rs2 = alu0_opcode[24:20]; +assign alu0_opcode_rd = alu0_opcode[11:7]; + +assign alu1_opcode_rs1 = alu1_opcode[19:15]; +assign alu1_opcode_rs2 = alu1_opcode[24:20]; +assign alu1_opcode_rd = alu1_opcode[11:7]; + +assign alu2_opcode_rs1 = alu2_opcode[19:15]; +assign alu2_opcode_rs2 = alu2_opcode[24:20]; +assign alu2_opcode_rd = alu2_opcode[11:7]; + +assign alu3_opcode_rs1 = alu3_opcode[19:15]; +assign alu3_opcode_rs2 = alu3_opcode[24:20]; +assign alu3_opcode_rd = alu3_opcode[11:7]; + + +assign LOAD_STORE_ADDRESS = alu0_load_store_address; +assign STORE_DATA = alu0_store_data; +assign alu0_load_data = LOAD_DATA; +assign LOAD_REQ = alu0_load_req; +assign STORE_REQ = alu0_store_req; + + + +// Register read-port routing +// If the previous alu has modified a register that this alu needs, then use this value, +// otherwise take the register from the main register-file. +// + +assign alu0_rs1 = (alu0_opcode_rs1 == 5'h00) ? 32'h0 : + (alu0_opcode_rs1 == 5'h01) ? register_1 : + (alu0_opcode_rs1 == 5'h02) ? register_2 : + (alu0_opcode_rs1 == 5'h03) ? register_3 : + register_4 ; + + + +assign alu0_rs2 = (alu0_opcode_rs2 == 5'h00) ? 32'h0 : + (alu0_opcode_rs2 == 5'h01) ? register_1 : + (alu0_opcode_rs2 == 5'h02) ? register_2 : + (alu0_opcode_rs2 == 5'h03) ? register_3 : + register_4 ; + + +//------------------------------------------------------------------------ + + +assign alu1_rs1 = ( alu0_rd[32]==1'b1 && (alu1_opcode_rs1==alu0_opcode_rd) ) ? alu0_rd[31:0] : + (alu1_opcode_rs1 == 5'h00) ? 32'h0 : + (alu1_opcode_rs1 == 5'h01) ? register_1 : + (alu1_opcode_rs1 == 5'h02) ? register_2 : + (alu1_opcode_rs1 == 5'h03) ? register_3 : + register_4 ; + + + +assign alu1_rs2 = ( alu0_rd[32]==1'b1 && (alu1_opcode_rs2==alu0_opcode_rd) ) ? alu0_rd[31:0] : + (alu1_opcode_rs2 == 5'h00) ? 32'h0 : + (alu1_opcode_rs2 == 5'h01) ? register_1 : + (alu1_opcode_rs2 == 5'h02) ? register_2 : + (alu1_opcode_rs2 == 5'h03) ? register_3 : + register_4 ; + +//------------------------------------------------------------------------ + + +assign alu2_rs1 = ( alu1_rd[32]==1'b1 && (alu2_opcode_rs1==alu1_opcode_rd) ) ? alu1_rd[31:0] : + ( alu0_rd[32]==1'b1 && (alu2_opcode_rs1==alu0_opcode_rd) ) ? alu0_rd[31:0] : + (alu2_opcode_rs1 == 5'h00) ? 32'h0 : + (alu2_opcode_rs1 == 5'h01) ? register_1 : + (alu2_opcode_rs1 == 5'h02) ? register_2 : + (alu2_opcode_rs1 == 5'h03) ? register_3 : + register_4 ; + + + + +assign alu2_rs2 = ( alu1_rd[32]==1'b1 && (alu2_opcode_rs2==alu1_opcode_rd) ) ? alu1_rd[31:0] : + ( alu0_rd[32]==1'b1 && (alu2_opcode_rs2==alu0_opcode_rd) ) ? alu0_rd[31:0] : + (alu2_opcode_rs2 == 5'h00) ? 32'h0 : + (alu2_opcode_rs2 == 5'h01) ? register_1 : + (alu2_opcode_rs2 == 5'h02) ? register_2 : + (alu2_opcode_rs2 == 5'h03) ? register_3 : + register_4 ; + +//------------------------------------------------------------------------ + + +assign alu3_rs1 = ( alu2_rd[32]==1'b1 && (alu3_opcode_rs1==alu2_opcode_rd) ) ? alu2_rd[31:0] : + ( alu1_rd[32]==1'b1 && (alu3_opcode_rs1==alu1_opcode_rd) ) ? alu1_rd[31:0] : + ( alu0_rd[32]==1'b1 && (alu3_opcode_rs1==alu0_opcode_rd) ) ? alu0_rd[31:0] : + (alu3_opcode_rs1 == 5'h00) ? 32'h0 : + (alu3_opcode_rs1 == 5'h01) ? register_1 : + (alu3_opcode_rs1 == 5'h02) ? register_2 : + (alu3_opcode_rs1 == 5'h03) ? register_3 : + register_4 ; + + + + +assign alu3_rs2 = ( alu2_rd[32]==1'b1 && (alu3_opcode_rs2==alu2_opcode_rd) ) ? alu2_rd[31:0] : + ( alu1_rd[32]==1'b1 && (alu3_opcode_rs2==alu1_opcode_rd) ) ? alu1_rd[31:0] : + ( alu0_rd[32]==1'b1 && (alu3_opcode_rs2==alu0_opcode_rd) ) ? alu0_rd[31:0] : + (alu3_opcode_rs2 == 5'h00) ? 32'h0 : + (alu3_opcode_rs2 == 5'h01) ? register_1 : + (alu3_opcode_rs2 == 5'h02) ? register_2 : + (alu3_opcode_rs2 == 5'h03) ? register_3 : + register_4 ; + + + + +//------------------------------------------------------------------------------------------ +// +// Register writebacks +// +//------------------------------------------------------------------------------------------ + +always @(posedge CORE_CLK or negedge RST_n) +begin : REGISTER_WRITEBACKS + + if (RST_n==1'b0) + begin + alu0_load_req_d <= 'h0; + new_pc <= 32'hFFFF_FFFC; + end + +else + begin + + if ( (loadstore_stall == 4'b0000 && (alu0_load_req==1'b1 || alu0_store_req==1'b1) ) || + (loadstore_stall == 4'b0000 && (alu1_load_req==1'b1 || alu1_store_req==1'b1) ) || + (loadstore_stall == 4'b0000 && (alu2_load_req==1'b1 || alu2_store_req==1'b1) ) || + (loadstore_stall == 4'b0000 && (alu3_load_req==1'b1 || alu3_store_req==1'b1) ) ) + begin + loadstore_stall <= 4'b1111; // new_pc_stall for three cycles + end + else + begin + loadstore_stall <= { 1'b0 , loadstore_stall[3:1] }; + end + + + + // Writeback register file + // Only write back registers that have been updated. + // Block register updates if a previous alu is taking a branch + // + if (new_pc_stall==1'b0 && ((loadstore_stall==4'b0001 || alu0_newpc[32]==1'b0) && alu1_newpc[32]==1'b0 && alu2_newpc[32]==1'b0) && alu3_rd[32]==1'b1) + begin + case (alu3_opcode_rd) + 5'h01 : register_1 <= alu3_rd[31:0]; + 5'h02 : register_2 <= alu3_rd[31:0]; + 5'h03 : register_3 <= alu3_rd[31:0]; + 5'h04 : register_4 <= alu3_rd[31:0]; + default: ; + endcase + end + + else if (new_pc_stall==1'b0 && ((loadstore_stall==4'b0001 || alu0_newpc[32]==1'b0) && alu1_newpc[32]==1'b0) && alu2_rd[32]==1'b1) + begin + case (alu2_opcode_rd) + 5'h01 : register_1 <= alu2_rd[31:0]; + 5'h02 : register_2 <= alu2_rd[31:0]; + 5'h03 : register_3 <= alu2_rd[31:0]; + 5'h04 : register_4 <= alu2_rd[31:0]; + default: ; + endcase + end + + else if (new_pc_stall==1'b0 && (loadstore_stall==4'b0001 || alu0_newpc[32]==1'b0) && alu1_rd[32]==1'b1) + begin + case (alu1_opcode_rd) + 5'h01 : register_1 <= alu1_rd[31:0]; + 5'h02 : register_2 <= alu1_rd[31:0]; + 5'h03 : register_3 <= alu1_rd[31:0]; + 5'h04 : register_4 <= alu1_rd[31:0]; + default: ; + endcase + end + + else if (new_pc_stall==1'b0 && alu0_rd[32]==1'b1) + begin + case (alu0_opcode_rd) + 5'h01 : register_1 <= alu0_rd[31:0]; + 5'h02 : register_2 <= alu0_rd[31:0]; + 5'h03 : register_3 <= alu0_rd[31:0]; + 5'h04 : register_4 <= alu0_rd[31:0]; + default: ; + endcase + end + + +//------------------------------------------------------------------------ +// +// Update the PC for branches/jumps +// Otherwise increment the PC by four +// +//------------------------------------------------------------------------ + + if ((new_pc_stall==1'b0 && alu0_newpc[32]==1'b1) && loadstore_stall!=4'b0001) + begin + new_pc_stall <= 1'b1; + new_pc <= alu0_newpc[31:0]; + end + + else if (new_pc_stall==1'b0 && alu1_newpc[32]==1'b1) + begin + new_pc_stall <= 1'b1; + new_pc <= alu1_newpc[31:0]; + end + + else if (new_pc_stall==1'b0 && alu2_newpc[32]==1'b1) + begin + new_pc_stall <= 1'b1; + new_pc <= alu2_newpc[31:0]; + end + + else if (new_pc_stall==1'b0 && alu3_newpc[32]==1'b1) + begin + new_pc_stall <= 1'b1; + new_pc <= alu3_newpc[31:0]; + end + + else + begin + new_pc <= new_pc + 32'h0000_0004; + new_pc_stall <= 1'b0; + end + + end +end // Register writebacks + + + +//------------------------------------------------------------------------ +// +// MCLR5 ALU cores +// +//------------------------------------------------------------------------ + +MCLR5_alu mclr5_alu0 + ( + .OPCODE (alu0_opcode), + .PC (alu0_pc), + .RS1 (alu0_rs1), + .RS2 (alu0_rs2), + .RD (alu0_rd), + .NEWPC (alu0_newpc), + .LOAD_DATA (alu0_load_data), + .STORE_DATA (alu0_store_data), + .LOAD_REQ (alu0_load_req), + .STORE_REQ (alu0_store_req), + .LOAD_STORE_ADDRESS (alu0_load_store_address) + ); + + +MCLR5_alu mclr5_alu1 + ( + .OPCODE (alu1_opcode), + .PC (alu1_pc), + .RS1 (alu1_rs1), + .RS2 (alu1_rs2), + .RD (alu1_rd), + .NEWPC (alu1_newpc), + .LOAD_DATA (), + .STORE_DATA (), + .LOAD_REQ (alu1_load_req), + .STORE_REQ (alu1_store_req), + .LOAD_STORE_ADDRESS () + ); + + +MCLR5_alu mclr5_alu2 + ( + .OPCODE (alu2_opcode), + .PC (alu2_pc), + .RS1 (alu2_rs1), + .RS2 (alu2_rs2), + .RD (alu2_rd), + .NEWPC (alu2_newpc), + .LOAD_DATA (), + .STORE_DATA (), + .LOAD_REQ (alu2_load_req), + .STORE_REQ (alu2_store_req), + .LOAD_STORE_ADDRESS () + ); + + + +MCLR5_alu mclr5_alu3 + ( + .OPCODE (alu3_opcode), + .PC (alu3_pc), + .RS1 (alu3_rs1), + .RS2 (alu3_rs2), + .RD (alu3_rd), + .NEWPC (alu3_newpc), + .LOAD_DATA (), + .STORE_DATA (), + .LOAD_REQ (alu3_load_req), + .STORE_REQ (alu3_store_req), + .LOAD_STORE_ADDRESS () + ); + + + +endmodule // MCLR5.v diff --git a/MCLR5/Core/MCLR5_alu.v b/MCLR5/Core/MCLR5_alu.v new file mode 100644 index 0000000..cbf8c1d --- /dev/null +++ b/MCLR5/Core/MCLR5_alu.v @@ -0,0 +1,206 @@ +// +// +// File Name : MCLR5_alu.v +// Author : Ted Fried, MicroCore Labs +// Creation : 4/21/2018 +// Code Type : Synthesizable +// +//------------------------------------------------------------------------ +// +// Description: +// ============ +// +// Quad-issue Superscalar Risc V Processor ALU core +// +//------------------------------------------------------------------------ +// +// Copyright (C) 2018 by Ted Fried info@MicroCoreLabs.com +// +// Permission to use, copy, modify, and distribute this software and its +// documentation for any purpose and without fee is hereby granted, provided +// that the above copyright notice appear in all copies and that both that +// copyright notice and this permission notice appear in supporting documentation. +// This software is provided "as is" without express or implied warranty. +// +//------------------------------------------------------------------------ +// +// Modification History: +// ===================== +// +// Revision 1 4/21/18 +// Initial revision +// +// +//------------------------------------------------------------------------ + + +module MCLR5_alu + ( + + input [31:0] OPCODE, + input [31:0] PC, + + input [31:0] RS1, + input [31:0] RS2, + output reg [32:0] RD, + output reg [32:0] NEWPC, + input [31:0] LOAD_DATA, + output [31:0] STORE_DATA, + output reg LOAD_REQ, + output reg STORE_REQ, + output reg [31:0] LOAD_STORE_ADDRESS + + ); + +//------------------------------------------------------------------------ + + +// Internal Signals + +wire beq_taken; +wire bne_taken; +wire blt_taken; +wire bge_taken; +wire bltu_taken; +wire bgeu_taken; +wire slti_true; +wire sltiu_true; +wire slt_true; +wire sltu_true; +wire [31:0] i_immediate; +wire [31:0] s_immediate; +wire [31:0] b_immediate; +wire [31:0] u_immediate; +wire [31:0] j_immediate; +wire [31:0] slli_result; +wire [31:0] srli_result; +wire [31:0] srai_result; +wire [31:0] sll_result; +wire [31:0] srl_result; +wire [31:0] sra_result; +wire [31:0] pc_adjusted; + + + +//------------------------------------------------------------------------ +// +// RISC V ALU +// +//------------------------------------------------------------------------ + +assign i_immediate = { {21{OPCODE[31]}} , OPCODE[30:25] , OPCODE[24:21] , OPCODE[20] } ; +assign s_immediate = { {21{OPCODE[31]}} , OPCODE[30:25] , OPCODE[11:8] , OPCODE[7] } ; +assign b_immediate = { {20{OPCODE[31]}} , OPCODE[7] , OPCODE[30:25] , OPCODE[11:8] , 1'b0 } ; +assign u_immediate = { OPCODE[31] , OPCODE[30:20] , OPCODE[19:12] , 12'b0 } ; +assign j_immediate = { {12{OPCODE[31]}} , OPCODE[19:12] , OPCODE[20] , OPCODE[30:25] , OPCODE[24:21] , 1'b0 } ; + + +assign slti_true = ($signed(RS1) < $signed(i_immediate)) ? 32'h0000_0001 : 32'h0000_0000; +assign sltiu_true = (RS1 < i_immediate) ? 32'h0000_0001 : 32'h0000_0000; +assign slt_true = ($signed(RS1) < $signed(RS2)) ? 32'h0000_0001 : 32'h0000_0000; +assign sltu_true = (RS1 < RS2) ? 32'h0000_0001 : 32'h0000_0000; + + +assign slli_result = 32'h0123_4567; +assign srli_result = 32'h0123_4567; +assign srai_result = 32'h0123_4567; +assign sll_result = 32'h0123_4567; +assign srl_result = 32'h0123_4567; +assign sra_result = 32'h0123_4567; + +assign beq_taken = (RS1 == RS1) ? 1'b1 : 1'b0; +assign bne_taken = (RS1 != RS1) ? 1'b1 : 1'b0; +assign blt_taken = ($signed(RS1) < $signed(RS2)) ? 1'b1 : 1'b0; +assign bge_taken = ($signed(RS1) >= $signed(RS2)) ? 1'b1 : 1'b0; +assign bltu_taken = (RS1 < RS2) ? 1'b1 : 1'b0; +assign bgeu_taken = (RS1 >= RS2) ? 1'b1 : 1'b0; + + +assign pc_adjusted = PC - 4'h4; // Subtracts pipelined PC to the true PC + +assign STORE_DATA = RS2; + + +always @* begin + casex (OPCODE) + + 32'b???????_?????_?????_???_?????_01101?? : RD = { 1'b1 , {u_immediate[31:12] , 12'b0 } } ; // LUI + 32'b???????_?????_?????_???_?????_00101?? : RD = { 1'b1 , PC + {u_immediate[31:12] , 12'b0 } } ; // AUIPC + 32'b???????_?????_?????_???_?????_11011?? : RD = { 1'b1 , PC + 3'h4 } ; // JAL + 32'b???????_?????_?????_???_?????_11001?? : RD = { 1'b1 , PC + 3'h4 } ; // JALR + 32'b???????_?????_?????_000_?????_00100?? : RD = { 1'b1 , RS1 + i_immediate } ; // ADDI + 32'b???????_?????_?????_010_?????_00100?? : RD = { 1'b1 , slti_true } ; // SLTI + 32'b???????_?????_?????_011_?????_00100?? : RD = { 1'b1 , sltiu_true } ; // SLTIU + 32'b???????_?????_?????_100_?????_00100?? : RD = { 1'b1 , RS1 ^ i_immediate } ; // XORI + 32'b???????_?????_?????_110_?????_00100?? : RD = { 1'b1 , RS1 | i_immediate } ; // ORI + 32'b???????_?????_?????_111_?????_00100?? : RD = { 1'b1 , RS1 & i_immediate } ; // ANDI + 32'b???????_?????_?????_001_?????_00100?? : RD = { 1'b1 , slli_result } ; // SLLI + 32'b?0?????_?????_?????_101_?????_00100?? : RD = { 1'b1 , srli_result } ; // SRLI + 32'b?1?????_?????_?????_101_?????_00100?? : RD = { 1'b1 , srai_result } ; // SRAI + 32'b?0?????_?????_?????_000_?????_01100?? : RD = { 1'b1 , RS1 + RS2 } ; // ADD + 32'b?1?????_?????_?????_000_?????_01100?? : RD = { 1'b1 , RS1 - RS2 } ; // SUB + 32'b???????_?????_?????_001_?????_01100?? : RD = { 1'b1 , sll_result } ; // SLL + 32'b???????_?????_?????_010_?????_01100?? : RD = { 1'b1 , slt_true } ; // SLT + 32'b???????_?????_?????_011_?????_01100?? : RD = { 1'b1 , sltu_true } ; // SLTU + 32'b???????_?????_?????_100_?????_01100?? : RD = { 1'b1 , RS1 ^ RS2 } ; // XOR + 32'b?0?????_?????_?????_101_?????_01100?? : RD = { 1'b1 , srl_result } ; // SRL + 32'b?1?????_?????_?????_101_?????_01100?? : RD = { 1'b1 , sra_result } ; // SRA + 32'b???????_?????_?????_110_?????_01100?? : RD = { 1'b1 , RS1 | RS2 } ; // OR + 32'b???????_?????_?????_111_?????_01100?? : RD = { 1'b1 , RS1 & RS2 } ; // AND + + 32'b???????_?????_?????_010_?????_00000?? : RD = { 1'b1 , LOAD_DATA } ; // LW + default : RD = { 1'b0 , 32'h0000_0000 } ; + + endcase + + + casex (OPCODE) + + 32'b???????_?????_?????_010_?????_00000?? : LOAD_STORE_ADDRESS = RS1 + i_immediate ; // Loads + 32'b???????_?????_?????_010_?????_01000?? : LOAD_STORE_ADDRESS = RS1 + s_immediate ; // Stores + default : ; + endcase + + + casex (OPCODE) + + 32'b???????_?????_?????_010_?????_00000?? : LOAD_REQ = 1'b1 ; + 32'b???????_?????_?????_010_?????_01000?? : STORE_REQ = 1'b1 ; + default : begin LOAD_REQ = 1'b0 ; STORE_REQ = 1'b0; end + + endcase + + + casex (OPCODE) + + 32'b???????_?????_?????_???_?????_11011?? : NEWPC = { 1'b1 , pc_adjusted + j_immediate } ; // JAL + 32'b???????_?????_?????_000_?????_11001?? : NEWPC = { 1'b1 , ( RS1 + i_immediate) & 32'hFFFF_FFFE } ; // JALR + + 32'b???????_?????_?????_010_?????_00000?? : NEWPC = { 1'b1 , pc_adjusted } ; // LW + 32'b???????_?????_?????_010_?????_01000?? : NEWPC = { 1'b1 , pc_adjusted } ; // SW + + //32'hBBBBBBBB : NEWPC = { 1'b1 , pc_adjusted + 4'h6 } ; // Temp jump code !!!! + + 32'b???????_?????_?????_000_?????_11000?? : if (beq_taken == 1'b1) NEWPC = { 1'b1 , pc_adjusted + b_immediate } ; // BEQ + 32'b???????_?????_?????_001_?????_11000?? : if (bne_taken == 1'b1) NEWPC = { 1'b1 , pc_adjusted + b_immediate } ; // BNE + 32'b???????_?????_?????_100_?????_11000?? : if (blt_taken == 1'b1) NEWPC = { 1'b1 , pc_adjusted + b_immediate } ; // BLT + 32'b???????_?????_?????_101_?????_11000?? : if (bge_taken == 1'b1) NEWPC = { 1'b1 , pc_adjusted + b_immediate } ; // BGE + 32'b???????_?????_?????_110_?????_11000?? : if (bltu_taken == 1'b1) NEWPC = { 1'b1 , pc_adjusted + b_immediate } ; // BLTU + 32'b???????_?????_?????_111_?????_11000?? : if (bgeu_taken == 1'b1) NEWPC = { 1'b1 , pc_adjusted + b_immediate } ; // BGEU + + + default : NEWPC = { 1'b0 , 32'h0000_0000 } ; // No Branch Taken + + endcase + + + + +end + + + + + + +endmodule // MCLR5_alu.v diff --git a/MCLR5/Movies_Pictures/Quadissue1.JPG b/MCLR5/Movies_Pictures/Quadissue1.JPG new file mode 100644 index 0000000..0edac90 Binary files /dev/null and b/MCLR5/Movies_Pictures/Quadissue1.JPG differ diff --git a/MCLR5/README.md b/MCLR5/README.md new file mode 100644 index 0000000..2c13e5d --- /dev/null +++ b/MCLR5/README.md @@ -0,0 +1,12 @@ +# Quad-issue Superscalar RISCV + + + - Up to four instructions can be simultaneously issued and retired. + - ALU cores are combinational. + - Core can handle branches which occur in any of the four pipelines. + - Can also handle register dependancies in the pipeline. + +** Very incomplete! Once it was able to issue multiple instructions and handle branches and register dependancies I got bored and moved on! :) + + +For questions email me at www.MicroCoreLabs.com