From af3a888cdee792515d5d7fb1a6b537da249908ca Mon Sep 17 00:00:00 2001 From: Teo Ene Date: Fri, 12 Feb 2021 16:08:34 -0600 Subject: [PATCH 01/16] Removed riscv-o3 module --- .gitmodules | 3 --- riscv-o3 | 1 - 2 files changed, 4 deletions(-) delete mode 160000 riscv-o3 diff --git a/.gitmodules b/.gitmodules index e406bcfa5..22f34ffd0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "riscv-o3"] - path = riscv-o3 - url = git@github.com:stineje/riscv-o3.git [submodule "sky130/sky130_osu_sc_t12"] path = sky130/sky130_osu_sc_t12 url = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12/ diff --git a/riscv-o3 b/riscv-o3 deleted file mode 160000 index afb27bd55..000000000 --- a/riscv-o3 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit afb27bd558a9b6fabb6b768ae81ef122b4db9eea From eab780afb99e919586bfb65309a3745125480dea Mon Sep 17 00:00:00 2001 From: Teo Ene Date: Fri, 12 Feb 2021 21:49:42 -0600 Subject: [PATCH 04/16] - Cleaned up unnecessary files - Pulled updates for std cells - Fixed typo that prevented easy switching between standard cell variants - Fixed asynchronous reset paths from not being flagged as false --- sky130/sky130_osu_sc_t12 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sky130/sky130_osu_sc_t12 b/sky130/sky130_osu_sc_t12 index 87ca77795..f60f2d039 160000 --- a/sky130/sky130_osu_sc_t12 +++ b/sky130/sky130_osu_sc_t12 @@ -1 +1 @@ -Subproject commit 87ca77795004bea5525b25badd7ec36cbc8222e1 +Subproject commit f60f2d0395053c4df362a97d7e2099721b6face6 From bd99a5613a84e534cda959ebca122225b8a32903 Mon Sep 17 00:00:00 2001 From: Teo Ene Date: Sun, 14 Feb 2021 09:05:41 -0600 Subject: [PATCH 09/16] sky130 18T and 15T cell libraries removed Upon noticing their size, concerns were raised about available drive space. As 12T is the main implementation focus, the decision was made to remove 15T and 18T. Apologies if any were interested in implementing the processor across multiple standard cell libraries for comparison. --- .gitmodules | 6 ------ sky130/sky130_osu_sc_t15 | 1 - sky130/sky130_osu_sc_t18 | 1 - 3 files changed, 8 deletions(-) delete mode 160000 sky130/sky130_osu_sc_t15 delete mode 160000 sky130/sky130_osu_sc_t18 diff --git a/.gitmodules b/.gitmodules index 22f34ffd0..65e1e71c9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,3 @@ [submodule "sky130/sky130_osu_sc_t12"] path = sky130/sky130_osu_sc_t12 url = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12/ -[submodule "sky130/sky130_osu_sc_t15"] - path = sky130/sky130_osu_sc_t15 - url = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t15/ -[submodule "sky130/sky130_osu_sc_t18"] - path = sky130/sky130_osu_sc_t18 - url = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t18/ diff --git a/sky130/sky130_osu_sc_t15 b/sky130/sky130_osu_sc_t15 deleted file mode 160000 index dae3c2282..000000000 --- a/sky130/sky130_osu_sc_t15 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dae3c2282e10d72f57af61d1dd73a1b0aead63f9 diff --git a/sky130/sky130_osu_sc_t18 b/sky130/sky130_osu_sc_t18 deleted file mode 160000 index 6c20402bf..000000000 --- a/sky130/sky130_osu_sc_t18 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6c20402bf853e6bf3985fce49fe88ca25502cc63 From 8491deb1a98422f46b918351fb78b2e72119707f Mon Sep 17 00:00:00 2001 From: Teo Ene Date: Thu, 25 Feb 2021 09:58:54 -0600 Subject: [PATCH 12/16] Changed .do file back to run all --- wally-pipelined/regression/wally-coremark.do | 2 +- wally-pipelined/regression/wally-pipelined.do | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wally-pipelined/regression/wally-coremark.do b/wally-pipelined/regression/wally-coremark.do index 44667d53d..d56122384 100644 --- a/wally-pipelined/regression/wally-coremark.do +++ b/wally-pipelined/regression/wally-coremark.do @@ -42,7 +42,7 @@ view wave add wave /testbench/clk add wave /testbench/reset add wave -divider -add wave /testbench/dut/hart/ebu/IReadF +#add wave /testbench/dut/hart/ebu/IReadF add wave /testbench/dut/hart/DataStall add wave /testbench/dut/hart/InstrStall add wave /testbench/dut/hart/StallF diff --git a/wally-pipelined/regression/wally-pipelined.do b/wally-pipelined/regression/wally-pipelined.do index 227ea3770..b8e72968b 100644 --- a/wally-pipelined/regression/wally-pipelined.do +++ b/wally-pipelined/regression/wally-pipelined.do @@ -105,6 +105,6 @@ configure wave -childrowmargin 2 set DefaultRadix hexadecimal -- Run the Simulation -run 2000 -#run -all +#run 2000 +run -all #quit From b9701293a0b7f0ebd9ccb946cada7a16b6ac6742 Mon Sep 17 00:00:00 2001 From: Teo Ene Date: Thu, 25 Feb 2021 11:03:41 -0600 Subject: [PATCH 13/16] Changed TIMBASE in coremark config file --- wally-pipelined/config/coremark/wally-config.vh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wally-pipelined/config/coremark/wally-config.vh b/wally-pipelined/config/coremark/wally-config.vh index 11058a47f..906373f90 100644 --- a/wally-pipelined/config/coremark/wally-config.vh +++ b/wally-pipelined/config/coremark/wally-config.vh @@ -66,7 +66,7 @@ // Peripheral memory space extends from BASE to BASE+RANGE // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits -`define TIMBASE 32'h80000000 +`define TIMBASE 32'h00000000 `define TIMRANGE 32'h0007FFFF `define CLINTBASE 32'h02000000 `define CLINTRANGE 32'h0000FFFF From 5fee65231e13f7b7fe3561980c32542b835bf0ac Mon Sep 17 00:00:00 2001 From: Teo Ene Date: Thu, 25 Feb 2021 11:23:01 -0600 Subject: [PATCH 14/16] Edited imem to account for TIMBASE==0; still hard-coded and needs to be improved, but works with coremark config now. --- wally-pipelined/src/uncore/imem.sv | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wally-pipelined/src/uncore/imem.sv b/wally-pipelined/src/uncore/imem.sv index 09a6c2ce8..1d8146cd3 100644 --- a/wally-pipelined/src/uncore/imem.sv +++ b/wally-pipelined/src/uncore/imem.sv @@ -57,7 +57,11 @@ module imem ( end else begin assign InstrF = AdrF[2] ? (AdrF[1] ? {rd2[15:0], rd[63:48]} : rd[63:32]) : (AdrF[1] ? rd[47:16] : rd[31:0]); - assign InstrAccessFaultF = (|AdrF[`XLEN-1:32]) | ~AdrF[31] | (|AdrF[30:16]); // memory mapped to 0x80000000-0x8000FFFF] + if(`TIMBASE==0) begin + assign InstrAccessFaultF = 0; + end else begin + assign InstrAccessFaultF = (|AdrF[`XLEN-1:32]) | ~AdrF[31] | (|AdrF[30:16]); // memory mapped to 0x80000000-0x8000FFFF] + end end endgenerate endmodule From a35fdac75b56cbe4cfcb3ed7b96eeb640628daef Mon Sep 17 00:00:00 2001 From: Teo Ene Date: Thu, 25 Feb 2021 11:24:44 -0600 Subject: [PATCH 15/16] Fixed previous commit --- wally-pipelined/src/uncore/imem.sv | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wally-pipelined/src/uncore/imem.sv b/wally-pipelined/src/uncore/imem.sv index 1d8146cd3..86d235564 100644 --- a/wally-pipelined/src/uncore/imem.sv +++ b/wally-pipelined/src/uncore/imem.sv @@ -53,7 +53,11 @@ module imem ( generate if (`XLEN==32) begin assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd; - assign InstrAccessFaultF = ~AdrF[31] | (|AdrF[30:16]); // memory mapped to 0x80000000-0x8000FFFF + if(`TIMBASE==0) begin + assign InstrAccessFaultF = 0; + end else begin + assign InstrAccessFaultF = ~AdrF[31] | (|AdrF[30:16]); // memory mapped to 0x80000000-0x8000FFFF + end end else begin assign InstrF = AdrF[2] ? (AdrF[1] ? {rd2[15:0], rd[63:48]} : rd[63:32]) : (AdrF[1] ? rd[47:16] : rd[31:0]); From b0a5052bcfb146d8dc9fccab005b122f66d3228b Mon Sep 17 00:00:00 2001 From: Brett Mathis Date: Thu, 25 Feb 2021 14:32:36 -0600 Subject: [PATCH 16/16] FPU Assembly tests --- wally-pipelined/src/fpu/fcsr.sv | 29 ++ wally-pipelined/src/fpu/fctrl.sv | 143 +++++++++ wally-pipelined/src/fpu/fputop.sv | 59 ++++ wally-pipelined/src/fpu/freg.sv | 513 ++++++++++++++++++++++++++++++ 4 files changed, 744 insertions(+) create mode 100644 wally-pipelined/src/fpu/fcsr.sv create mode 100644 wally-pipelined/src/fpu/fctrl.sv create mode 100644 wally-pipelined/src/fpu/fputop.sv create mode 100644 wally-pipelined/src/fpu/freg.sv diff --git a/wally-pipelined/src/fpu/fcsr.sv b/wally-pipelined/src/fpu/fcsr.sv new file mode 100644 index 000000000..64f3f7b92 --- /dev/null +++ b/wally-pipelined/src/fpu/fcsr.sv @@ -0,0 +1,29 @@ +`include "../../config/rv64icfd/wally-config.vh" + +module fcsr( + input logic [2:0] frm, + input logic reset, + input logic clear, + input logic clk, + input logic write, + input logic [4:0] flags, + output logic [31:0] readData); + + //register I/O assignment + logic [31:0] regInput; + logic [31:0] regOutput; + + //no L instruction support + //only last 8 bits used for FCSR + + //latching input to write signal + //AND clk and write and remove latch + //for clk-based write + assign regInput = (write) ? {24'h0,frm,flags} : regInput; + + floprc #(32) (.clk(clk), .reset(reset), .clear(clear), .d(regInput), .q(regOutput)); + + assign readData = regOutput; + + +endmodule diff --git a/wally-pipelined/src/fpu/fctrl.sv b/wally-pipelined/src/fpu/fctrl.sv new file mode 100644 index 000000000..13451165d --- /dev/null +++ b/wally-pipelined/src/fpu/fctrl.sv @@ -0,0 +1,143 @@ +`include "../../config/rv64icfd/wally-config.vh" + +module fctrl ( + input logic [6:0] Funct7D, + input logic [6:0] OpD, + input logic [4:0] Rs2D, + input logic [4:0] Rs1D, + input logic [2:0] FrmW, + output logic WriteEnD, + output logic DivSqrtStartD, + output logic [2:0] regSelD, + output logic [2:0] writeSelD, + output logic [3:0] OpCtrlD, + output logic FmtD, + output logic WriteIntD); + + + + //precision is taken directly from instruction + assign FmtD = Funct7D[0]; + + //all subsequent logic is based on the table present + //in Section 5 of Wally Architecture Specification + + //write is enabled for all fp instruciton op codes + //sans fp load + logic isFP, isFPLD; + always_comb begin + //case statement is easier to modify + //in case of errors + case(OpD) + //fp instructions sans load + 7'b1010011 : begin isFP = 1'b1; isFPLD = 1'b0; end + 7'b1000011 : begin isFP = 1'b1; isFPLD = 1'b0; end + 7'b1000111 : begin isFP = 1'b1; isFPLD = 1'b0; end + 7'b1001011 : begin isFP = 1'b1; isFPLD = 1'b0; end + 7'b1001111 : begin isFP = 1'b1; isFPLD = 1'b0; end + 7'b0100111 : begin isFP = 1'b1; isFPLD = 1'b0; end + //fp load + 7'b1010011 : begin isFP = 1'b1; isFPLD = 1'b1; end + default : begin isFP = 1'b0; isFPLD = 1'b0; end + endcase + end + + assign WriteEnD = isFP & ~isFPLD; + + //useful intermediary signals + // + //(mult only not supported in current datapath) + //set third FMA operand to zero in this case + //(or equivalent) + logic isAddSub, isFMA, isMult, isDivSqrt, isCvt, isCmp, isFPSTR; + + always_comb begin + //checks all but FMA/store/load + if(OpD == 7'b1010011) begin + case(Funct7D) + //compare + 7'b10100?? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b1; isFPSTR = 1'b0; end + //div/sqrt + 7'b0?011?? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b1; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end + //add/sub + 7'b0000??? : begin isAddSub = 1'b1; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end + //mult + 7'b00010?? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b1; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end + //convert (not precision) + 7'b110?0?? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b1; isCmp = 1'b0; isFPSTR = 1'b0; end + //convert (precision) + 7'b010000? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b1; isCmp = 1'b0; isFPSTR = 1'b0; end + endcase + end + //FMA/store/load + else begin + case(OpD) + //4 FMA instructions + 7'b1000011 : begin isAddSub = 1'b0; isFMA = 1'b1; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end + 7'b1000111 : begin isAddSub = 1'b0; isFMA = 1'b1; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end + 7'b1001011 : begin isAddSub = 1'b0; isFMA = 1'b1; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end + 7'b1001111 : begin isAddSub = 1'b0; isFMA = 1'b1; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end + //store (load already found) + 7'b0100111 : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b1; end + endcase + end + end + + //register is chosen based on operation performed + //---- + //write selection is chosen in the same way as + //register selection + // + + // reg/write sel logic and assignment + // + // 3'b000 = add/sub/cvt + // 3'b001 = sign + // 3'b010 = fma + // 3'b011 = cmp + // 3'b100 = div/sqrt + // + //reg select + + //this value is used enough to be shorthand + logic isSign; + assign isSign = ~Funct7D[6] & ~Funct7D[5] & Funct7D[4] & ~Funct7D[3] & ~Funct7D[2]; + + + assign regSelD[2] = isDivSqrt & ~isFMA; + assign regSelD[1] = isFMA | isCmp; + //AND of Funct7 for sign + assign regSelD[0] = isCmp | isSign; + + //write select + assign writeSelD[2] = isDivSqrt & ~isFMA; + assign writeSelD[1] = isFMA | isCmp; + //AND of Funct7 for sign + assign writeSelD[0] = isCmp | isSign; + + //if op is div/sqrt - start div/sqrt + assign DivSqrtStartD = isDivSqrt & ~isFMA; + + //operation control for each fp operation + //has to be expanded over standard to account for + //integrated fpadd/cvt + // + //will integrate FMA opcodes into design later + // + //conversion instructions will + //also need to be added later as I find the opcode + //version I used for this repo + + assign OpCtrlD[3] = 1'b0; + //if is positive sign injection OR is precision convert + assign OpCtrlD[2] = (isSign & ~FrmW[0]) | (~Funct7D[6] & Funct7D[5] & ~Funct7D[4] & ~Funct7D[3] & ~Funct7D[2] & ~Funct7D[1]); + //if is precision convert OR is sign xor + assign OpCtrlD[1] = (isSign & FrmW[1]) | (~Funct7D[6] & Funct7D[5] & ~Funct7D[4] & ~Funct7D[3] & ~Funct7D[2] & ~Funct7D[1]); + //if is sqrt OR is sub OR is single-precision cmp OR negation + assign OpCtrlD[0] = (isDivSqrt & ~isFMA & Funct7D[6]) | (isAddSub & ~isFMA & Funct7D[2]) | (isCmp & ~isFMA & Funct7D[0]) | (isSign & FrmW[0]); + + //write to integer source if conv to int occurs + //AND of Funct7 for int results + assign WriteIntD = isCvt & (Funct7D[6] & Funct7D[5] & ~Funct7D[4] & ~Funct7D[3] & ~Funct7D[2] & ~Funct7D[1]); + +endmodule diff --git a/wally-pipelined/src/fpu/fputop.sv b/wally-pipelined/src/fpu/fputop.sv new file mode 100644 index 000000000..3267ac9fa --- /dev/null +++ b/wally-pipelined/src/fpu/fputop.sv @@ -0,0 +1,59 @@ +`include "../../config/rv64icfd/wally-config.vh" + +module fputop ( + input logic [2:0] FrmW, + input logic reset, + input logic clear, + input logic clk, + input logic [31:0] InstrD, + input logic [`XLEN-1:0] SrcAE, + input logic [`XLEN-1:0] SrcAW, + output logic [31:0] FSROutW, + output logic DivSqrtDoneE, + output logic FInvalInstrD, + output logic [`XLEN-1:0] FPUResultW); + + /*fctrl (); + + //regfile instantiation and decode stage + //freg1adr (); + + //freg2adr (); + + //freg2adr (); + + //freg2adr (); + + freg3adr (); + + //can easily be merged into privledged core + //if necessary + //fcsr (); + + //E pipe and execution stage + + fpdivsqrt (); + + fma1 (); + + fpaddcvt1 (); + + fpcmp1 (); + + fpsign (); + + //M pipe and memory stage + + fma2 (); + + fpaddcvt2 (); + + fpcmp2 (); + + //W pipe and writeback stage + + //flag signal mux + + //result mux +*/ +endmodule diff --git a/wally-pipelined/src/fpu/freg.sv b/wally-pipelined/src/fpu/freg.sv new file mode 100644 index 000000000..6da116d5f --- /dev/null +++ b/wally-pipelined/src/fpu/freg.sv @@ -0,0 +1,513 @@ +`include "../../config/rv64icfd/wally-config.vh" + +module freg1adr ( + input logic [2:0] frm, + input logic reset, + input logic clear, + input logic clk, + input logic [4:0] rd, + input logic write, + input logic [4:0] adr1, + input logic [`XLEN-1:0] writeData, + output logic [`XLEN-1:0] readData); + + //note - not word aligning based on precision of + //operation (frm) + + //reg number should remain static, but it doesn't hurt + //to parameterize + parameter numRegs = 32; + + //intermediary signals - useful for debugging + //and easy instatiation of generated modules + logic [`XLEN-1:0] [numRegs-1:0] regInput; + logic [`XLEN-1:0] [numRegs-1:0] regOutput; + + //generate fp registers themselves + genvar i; + generate + for (i = 0; i < numRegs; i = i + 1) begin:register + + floprc #(`XLEN) (.clk(clk), .reset(reset), .clear(clear), .d(regInput[i][`XLEN-1:0]), .q(regOutput[i][`XLEN-1:0])); + end + + endgenerate + + //this could be done with: + // + //assign readData = regOutput[adr1]; + // + //but always_comb allows for finer control + + + //address decoder + //only 1 for this fp register set + //used with fpsign + //defaults to outputting zeroes + always_comb begin + case(adr1) + 5'b00000 : readData = regOutput[0]; + 5'b00001 : readData = regOutput[1]; + 5'b00010 : readData = regOutput[2]; + 5'b00011 : readData = regOutput[3]; + 5'b00100 : readData = regOutput[4]; + 5'b00101 : readData = regOutput[5]; + 5'b00110 : readData = regOutput[6]; + 5'b00111 : readData = regOutput[7]; + 5'b01000 : readData = regOutput[8]; + 5'b01001 : readData = regOutput[9]; + 5'b01010 : readData = regOutput[10]; + 5'b01011 : readData = regOutput[11]; + 5'b01100 : readData = regOutput[12]; + 5'b01101 : readData = regOutput[13]; + 5'b01110 : readData = regOutput[14]; + 5'b01111 : readData = regOutput[15]; + 5'b10000 : readData = regOutput[16]; + 5'b10001 : readData = regOutput[17]; + 5'b10010 : readData = regOutput[18]; + 5'b10011 : readData = regOutput[19]; + 5'b10100 : readData = regOutput[20]; + 5'b10101 : readData = regOutput[21]; + 5'b10110 : readData = regOutput[22]; + 5'b10111 : readData = regOutput[23]; + 5'b11000 : readData = regOutput[24]; + 5'b11001 : readData = regOutput[25]; + 5'b11010 : readData = regOutput[26]; + 5'b11011 : readData = regOutput[27]; + 5'b11100 : readData = regOutput[28]; + 5'b11101 : readData = regOutput[29]; + 5'b11110 : readData = regOutput[30]; + 5'b11111 : readData = regOutput[31]; + default : readData = `XLEN'h0; + endcase + end + + //destination register decoder + //only change input values on write + //defaults to undefined with invalid address + // + //note - this is an intermediary signal, so + //this is not asynch assignment. FF in flopr + //will not update data until clk pulse + always_comb begin + if(write) begin + case(rd) + 5'b00000 : regInput[0] = writeData; + 5'b00001 : regInput[1] = writeData; + 5'b00010 : regInput[2] = writeData; + 5'b00011 : regInput[3] = writeData; + 5'b00100 : regInput[4] = writeData; + 5'b00101 : regInput[5] = writeData; + 5'b00110 : regInput[6] = writeData; + 5'b00111 : regInput[7] = writeData; + 5'b01000 : regInput[8] = writeData; + 5'b01000 : regInput[9] = writeData; + 5'b01001 : regInput[10] = writeData; + 5'b01010 : regInput[11] = writeData; + 5'b01111 : regInput[12] = writeData; + 5'b01101 : regInput[13] = writeData; + 5'b01110 : regInput[14] = writeData; + 5'b01111 : regInput[15] = writeData; + 5'b10000 : regInput[16] = writeData; + 5'b10001 : regInput[17] = writeData; + 5'b10010 : regInput[18] = writeData; + 5'b10011 : regInput[19] = writeData; + 5'b10100 : regInput[20] = writeData; + 5'b10101 : regInput[21] = writeData; + 5'b10110 : regInput[22] = writeData; + 5'b10111 : regInput[23] = writeData; + 5'b11000 : regInput[24] = writeData; + 5'b11000 : regInput[25] = writeData; + 5'b11001 : regInput[26] = writeData; + 5'b11010 : regInput[27] = writeData; + 5'b11111 : regInput[28] = writeData; + 5'b11101 : regInput[29] = writeData; + 5'b11110 : regInput[30] = writeData; + 5'b11111 : regInput[31] = writeData; + default : regInput[0] = `XLEN'hx; + endcase + end + end + +endmodule + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//******** +//formatting separation +//******** +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +module freg2adr ( + input logic [2:0] frm, + input logic reset, + input logic clear, + input logic clk, + input logic [4:0] rd, + input logic write, + input logic [4:0] adr1, + input logic [4:0] adr2, + input logic [`XLEN-1:0] writeData, + output logic [`XLEN-1:0] readData1, + output logic [`XLEN-1:0] readData2); + + //note - not word aligning based on precision of + //operation (frm) + + //reg number should remain static, but it doesn't hurt + //to parameterize + parameter numRegs = 32; + + //intermediary signals - useful for debugging + //and easy instatiation of generated modules + logic [`XLEN-1:0] [numRegs-1:0] regInput; + logic [`XLEN-1:0] [numRegs-1:0] regOutput; + + //generate fp registers themselves + genvar i; + generate + for (i = 0; i < numRegs; i = i + 1) begin:register + + floprc #(`XLEN) (.clk(clk), .reset(reset), .clear(clear), .d(regInput[i][`XLEN-1:0]), .q(regOutput[i][`XLEN-1:0])); + end + + endgenerate + + //address decoder + //2 are used for this fp register set + //used with fpadd/cvt, fpdiv/sqrt, and fpcmp + //defaults to outputting zeroes + always_comb begin + + //adderss 1 decoder + case(adr1) + 5'b00000 : readData1 = regOutput[0]; + 5'b00001 : readData1 = regOutput[1]; + 5'b00010 : readData1 = regOutput[2]; + 5'b00011 : readData1 = regOutput[3]; + 5'b00100 : readData1 = regOutput[4]; + 5'b00101 : readData1 = regOutput[5]; + 5'b00110 : readData1 = regOutput[6]; + 5'b00111 : readData1 = regOutput[7]; + 5'b01000 : readData1 = regOutput[8]; + 5'b01001 : readData1 = regOutput[9]; + 5'b01010 : readData1 = regOutput[10]; + 5'b01011 : readData1 = regOutput[11]; + 5'b01100 : readData1 = regOutput[12]; + 5'b01101 : readData1 = regOutput[13]; + 5'b01110 : readData1 = regOutput[14]; + 5'b01111 : readData1 = regOutput[15]; + 5'b10000 : readData1 = regOutput[16]; + 5'b10001 : readData1 = regOutput[17]; + 5'b10010 : readData1 = regOutput[18]; + 5'b10011 : readData1 = regOutput[19]; + 5'b10100 : readData1 = regOutput[20]; + 5'b10101 : readData1 = regOutput[21]; + 5'b10110 : readData1 = regOutput[22]; + 5'b10111 : readData1 = regOutput[23]; + 5'b11000 : readData1 = regOutput[24]; + 5'b11001 : readData1 = regOutput[25]; + 5'b11010 : readData1 = regOutput[26]; + 5'b11011 : readData1 = regOutput[27]; + 5'b11100 : readData1 = regOutput[28]; + 5'b11101 : readData1 = regOutput[29]; + 5'b11110 : readData1 = regOutput[30]; + 5'b11111 : readData1 = regOutput[31]; + default : readData1 = `XLEN'h0; + endcase + + //address 2 decoder + case(adr2) + 5'b00000 : readData2 = regOutput[0]; + 5'b00001 : readData2 = regOutput[1]; + 5'b00010 : readData2 = regOutput[2]; + 5'b00011 : readData2 = regOutput[3]; + 5'b00100 : readData2 = regOutput[4]; + 5'b00101 : readData2 = regOutput[5]; + 5'b00110 : readData2 = regOutput[6]; + 5'b00111 : readData2 = regOutput[7]; + 5'b01000 : readData2 = regOutput[8]; + 5'b01001 : readData2 = regOutput[9]; + 5'b01010 : readData2 = regOutput[10]; + 5'b01011 : readData2 = regOutput[11]; + 5'b01100 : readData2 = regOutput[12]; + 5'b01101 : readData2 = regOutput[13]; + 5'b01110 : readData2 = regOutput[14]; + 5'b01111 : readData2 = regOutput[15]; + 5'b10000 : readData2 = regOutput[16]; + 5'b10001 : readData2 = regOutput[17]; + 5'b10010 : readData2 = regOutput[18]; + 5'b10011 : readData2 = regOutput[19]; + 5'b10100 : readData2 = regOutput[20]; + 5'b10101 : readData2 = regOutput[21]; + 5'b10110 : readData2 = regOutput[22]; + 5'b10111 : readData2 = regOutput[23]; + 5'b11000 : readData2 = regOutput[24]; + 5'b11001 : readData2 = regOutput[25]; + 5'b11010 : readData2 = regOutput[26]; + 5'b11011 : readData2 = regOutput[27]; + 5'b11100 : readData2 = regOutput[28]; + 5'b11101 : readData2 = regOutput[29]; + 5'b11110 : readData2 = regOutput[30]; + 5'b11111 : readData2 = regOutput[31]; + default : readData2 = `XLEN'h0; + endcase + end + + //destination register decoder + //only change input values on write + //defaults to undefined with invalid address + // + //note - this is an intermediary signal, so + //this is not asynch assignment. FF in flopr + //will not update data until clk pulse + always_comb begin + if(write) begin + case(rd) + 5'b00000 : regInput[0] = writeData; + 5'b00001 : regInput[1] = writeData; + 5'b00010 : regInput[2] = writeData; + 5'b00011 : regInput[3] = writeData; + 5'b00100 : regInput[4] = writeData; + 5'b00101 : regInput[5] = writeData; + 5'b00110 : regInput[6] = writeData; + 5'b00111 : regInput[7] = writeData; + 5'b01000 : regInput[8] = writeData; + 5'b01000 : regInput[9] = writeData; + 5'b01001 : regInput[10] = writeData; + 5'b01010 : regInput[11] = writeData; + 5'b01111 : regInput[12] = writeData; + 5'b01101 : regInput[13] = writeData; + 5'b01110 : regInput[14] = writeData; + 5'b01111 : regInput[15] = writeData; + 5'b10000 : regInput[16] = writeData; + 5'b10001 : regInput[17] = writeData; + 5'b10010 : regInput[18] = writeData; + 5'b10011 : regInput[19] = writeData; + 5'b10100 : regInput[20] = writeData; + 5'b10101 : regInput[21] = writeData; + 5'b10110 : regInput[22] = writeData; + 5'b10111 : regInput[23] = writeData; + 5'b11000 : regInput[24] = writeData; + 5'b11000 : regInput[25] = writeData; + 5'b11001 : regInput[26] = writeData; + 5'b11010 : regInput[27] = writeData; + 5'b11111 : regInput[28] = writeData; + 5'b11101 : regInput[29] = writeData; + 5'b11110 : regInput[30] = writeData; + 5'b11111 : regInput[31] = writeData; + default : regInput[0] = `XLEN'hx; + endcase + end + end + +endmodule + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//******** +//formatting separation +//******** +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +module freg3adr ( + input logic [2:0] frm, + input logic reset, + input logic clear, + input logic clk, + input logic [4:0] rd, + input logic write, + input logic [4:0] adr1, + input logic [4:0] adr2, + input logic [4:0] adr3, + input logic [`XLEN-1:0] writeData, + output logic [`XLEN-1:0] readData1, + output logic [`XLEN-1:0] readData2, + output logic [`XLEN-1:0] readData3); + + //note - not word aligning based on precision of + //operation (frm) + + //reg number should remain static, but it doesn't hurt + //to parameterize + parameter numRegs = 32; + + //intermediary signals - useful for debugging + //and easy instatiation of generated modules + logic [`XLEN-1:0] [numRegs-1:0] regInput; + logic [`XLEN-1:0] [numRegs-1:0] regOutput; + + //generate fp registers themselves + genvar i; + generate + for (i = 0; i < numRegs; i = i + 1) begin:register + + floprc #(`XLEN) (.clk(clk), .reset(reset), .clear(clear), .d(regInput[i][`XLEN-1:0]), .q(regOutput[i][`XLEN-1:0])); + end + + endgenerate + + //address decoder + //3 are used for this fp register set + //used exclusively for fma + //defaults to outputting zeroes + always_comb begin + + //adderss 1 decoder + case(adr1) + 5'b00000 : readData1 = regOutput[0]; + 5'b00001 : readData1 = regOutput[1]; + 5'b00010 : readData1 = regOutput[2]; + 5'b00011 : readData1 = regOutput[3]; + 5'b00100 : readData1 = regOutput[4]; + 5'b00101 : readData1 = regOutput[5]; + 5'b00110 : readData1 = regOutput[6]; + 5'b00111 : readData1 = regOutput[7]; + 5'b01000 : readData1 = regOutput[8]; + 5'b01001 : readData1 = regOutput[9]; + 5'b01010 : readData1 = regOutput[10]; + 5'b01011 : readData1 = regOutput[11]; + 5'b01100 : readData1 = regOutput[12]; + 5'b01101 : readData1 = regOutput[13]; + 5'b01110 : readData1 = regOutput[14]; + 5'b01111 : readData1 = regOutput[15]; + 5'b10000 : readData1 = regOutput[16]; + 5'b10001 : readData1 = regOutput[17]; + 5'b10010 : readData1 = regOutput[18]; + 5'b10011 : readData1 = regOutput[19]; + 5'b10100 : readData1 = regOutput[20]; + 5'b10101 : readData1 = regOutput[21]; + 5'b10110 : readData1 = regOutput[22]; + 5'b10111 : readData1 = regOutput[23]; + 5'b11000 : readData1 = regOutput[24]; + 5'b11001 : readData1 = regOutput[25]; + 5'b11010 : readData1 = regOutput[26]; + 5'b11011 : readData1 = regOutput[27]; + 5'b11100 : readData1 = regOutput[28]; + 5'b11101 : readData1 = regOutput[29]; + 5'b11110 : readData1 = regOutput[30]; + 5'b11111 : readData1 = regOutput[31]; + default : readData1 = `XLEN'h0; + endcase + + //address 2 decoder + case(adr2) + 5'b00000 : readData2 = regOutput[0]; + 5'b00001 : readData2 = regOutput[1]; + 5'b00010 : readData2 = regOutput[2]; + 5'b00011 : readData2 = regOutput[3]; + 5'b00100 : readData2 = regOutput[4]; + 5'b00101 : readData2 = regOutput[5]; + 5'b00110 : readData2 = regOutput[6]; + 5'b00111 : readData2 = regOutput[7]; + 5'b01000 : readData2 = regOutput[8]; + 5'b01001 : readData2 = regOutput[9]; + 5'b01010 : readData2 = regOutput[10]; + 5'b01011 : readData2 = regOutput[11]; + 5'b01100 : readData2 = regOutput[12]; + 5'b01101 : readData2 = regOutput[13]; + 5'b01110 : readData2 = regOutput[14]; + 5'b01111 : readData2 = regOutput[15]; + 5'b10000 : readData2 = regOutput[16]; + 5'b10001 : readData2 = regOutput[17]; + 5'b10010 : readData2 = regOutput[18]; + 5'b10011 : readData2 = regOutput[19]; + 5'b10100 : readData2 = regOutput[20]; + 5'b10101 : readData2 = regOutput[21]; + 5'b10110 : readData2 = regOutput[22]; + 5'b10111 : readData2 = regOutput[23]; + 5'b11000 : readData2 = regOutput[24]; + 5'b11001 : readData2 = regOutput[25]; + 5'b11010 : readData2 = regOutput[26]; + 5'b11011 : readData2 = regOutput[27]; + 5'b11100 : readData2 = regOutput[28]; + 5'b11101 : readData2 = regOutput[29]; + 5'b11110 : readData2 = regOutput[30]; + 5'b11111 : readData2 = regOutput[31]; + default : readData2 = `XLEN'h0; + endcase + + //address 3 decoder + case(adr3) + 5'b00000 : readData3 = regOutput[0]; + 5'b00001 : readData3 = regOutput[1]; + 5'b00010 : readData3 = regOutput[2]; + 5'b00011 : readData3 = regOutput[3]; + 5'b00100 : readData3 = regOutput[4]; + 5'b00101 : readData3 = regOutput[5]; + 5'b00110 : readData3 = regOutput[6]; + 5'b00111 : readData3 = regOutput[7]; + 5'b01000 : readData3 = regOutput[8]; + 5'b01001 : readData3 = regOutput[9]; + 5'b01010 : readData3 = regOutput[10]; + 5'b01011 : readData3 = regOutput[11]; + 5'b01100 : readData3 = regOutput[12]; + 5'b01101 : readData3 = regOutput[13]; + 5'b01110 : readData3 = regOutput[14]; + 5'b01111 : readData3 = regOutput[15]; + 5'b10000 : readData3 = regOutput[16]; + 5'b10001 : readData3 = regOutput[17]; + 5'b10010 : readData3 = regOutput[18]; + 5'b10011 : readData3 = regOutput[19]; + 5'b10100 : readData3 = regOutput[20]; + 5'b10101 : readData3 = regOutput[21]; + 5'b10110 : readData3 = regOutput[22]; + 5'b10111 : readData3 = regOutput[23]; + 5'b11000 : readData3 = regOutput[24]; + 5'b11001 : readData3 = regOutput[25]; + 5'b11010 : readData3 = regOutput[26]; + 5'b11011 : readData3 = regOutput[27]; + 5'b11100 : readData3 = regOutput[28]; + 5'b11101 : readData3 = regOutput[29]; + 5'b11110 : readData3 = regOutput[30]; + 5'b11111 : readData3 = regOutput[31]; + default : readData3 = `XLEN'h0; + endcase + end + + //destination register decoder + //only change input values on write + //defaults to undefined with invalid address + // + //note - this is an intermediary signal, so + //this is not asynch assignment. FF in flopr + //will not update data until clk pulse + always_comb begin + if(write) begin + case(rd) + 5'b00000 : regInput[0] = writeData; + 5'b00001 : regInput[1] = writeData; + 5'b00010 : regInput[2] = writeData; + 5'b00011 : regInput[3] = writeData; + 5'b00100 : regInput[4] = writeData; + 5'b00101 : regInput[5] = writeData; + 5'b00110 : regInput[6] = writeData; + 5'b00111 : regInput[7] = writeData; + 5'b01000 : regInput[8] = writeData; + 5'b01000 : regInput[9] = writeData; + 5'b01001 : regInput[10] = writeData; + 5'b01010 : regInput[11] = writeData; + 5'b01111 : regInput[12] = writeData; + 5'b01101 : regInput[13] = writeData; + 5'b01110 : regInput[14] = writeData; + 5'b01111 : regInput[15] = writeData; + 5'b10000 : regInput[16] = writeData; + 5'b10001 : regInput[17] = writeData; + 5'b10010 : regInput[18] = writeData; + 5'b10011 : regInput[19] = writeData; + 5'b10100 : regInput[20] = writeData; + 5'b10101 : regInput[21] = writeData; + 5'b10110 : regInput[22] = writeData; + 5'b10111 : regInput[23] = writeData; + 5'b11000 : regInput[24] = writeData; + 5'b11000 : regInput[25] = writeData; + 5'b11001 : regInput[26] = writeData; + 5'b11010 : regInput[27] = writeData; + 5'b11111 : regInput[28] = writeData; + 5'b11101 : regInput[29] = writeData; + 5'b11110 : regInput[30] = writeData; + 5'b11111 : regInput[31] = writeData; + default : regInput[0] = `XLEN'hx; + endcase + end + end + +endmodule