From cc077da2bbe535b52b6ef18861ba343c426ab521 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 e406bcfa..22f34ffd 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 afb27bd5..00000000 --- a/riscv-o3 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit afb27bd558a9b6fabb6b768ae81ef122b4db9eea From ca7ee1d670f5a31ebd29a49a4ae6889d550ae7d2 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 87ca7779..f60f2d03 160000 --- a/sky130/sky130_osu_sc_t12 +++ b/sky130/sky130_osu_sc_t12 @@ -1 +1 @@ -Subproject commit 87ca77795004bea5525b25badd7ec36cbc8222e1 +Subproject commit f60f2d0395053c4df362a97d7e2099721b6face6 From 72dd97d9b63bb47ef90ef1cc957a8929f6d7b0c1 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 22f34ffd..65e1e71c 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 dae3c228..00000000 --- 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 6c20402b..00000000 --- a/sky130/sky130_osu_sc_t18 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6c20402bf853e6bf3985fce49fe88ca25502cc63 From c47872c2af09ec00e42e5f2001c0e19678f51003 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 44667d53..d5612238 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 227ea377..b8e72968 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 61b872a3e8de47c7fadb9ac06c72891200256ee3 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 11058a47..906373f9 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 31c07b2adcdeaac25c8f5bd3f472b2f589ba41c7 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 09a6c2ce..1d8146cd 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 6be5bb1f845c600f11ab0fe1cf307b6451849b98 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 1d8146cd..86d23556 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 ec82453ba1683873f18f7c4b847be8a764643169 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 00000000..64f3f7b9 --- /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 00000000..13451165 --- /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 00000000..3267ac9f --- /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 00000000..6da116d5 --- /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