forked from Github_Repos/cvw
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
commit
c060e427f0
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,9 +1,3 @@
|
|||||||
[submodule "sky130/sky130_osu_sc_t12"]
|
[submodule "sky130/sky130_osu_sc_t12"]
|
||||||
path = 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/
|
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/
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 87ca77795004bea5525b25badd7ec36cbc8222e1
|
Subproject commit f60f2d0395053c4df362a97d7e2099721b6face6
|
@ -1 +0,0 @@
|
|||||||
Subproject commit dae3c2282e10d72f57af61d1dd73a1b0aead63f9
|
|
@ -1 +0,0 @@
|
|||||||
Subproject commit 6c20402bf853e6bf3985fce49fe88ca25502cc63
|
|
@ -66,7 +66,7 @@
|
|||||||
// Peripheral memory space extends from BASE to BASE+RANGE
|
// 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
|
// 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 TIMRANGE 32'h0007FFFF
|
||||||
`define CLINTBASE 32'h02000000
|
`define CLINTBASE 32'h02000000
|
||||||
`define CLINTRANGE 32'h0000FFFF
|
`define CLINTRANGE 32'h0000FFFF
|
||||||
|
@ -42,7 +42,7 @@ view wave
|
|||||||
add wave /testbench/clk
|
add wave /testbench/clk
|
||||||
add wave /testbench/reset
|
add wave /testbench/reset
|
||||||
add wave -divider
|
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/DataStall
|
||||||
add wave /testbench/dut/hart/InstrStall
|
add wave /testbench/dut/hart/InstrStall
|
||||||
add wave /testbench/dut/hart/StallF
|
add wave /testbench/dut/hart/StallF
|
||||||
|
@ -105,6 +105,6 @@ configure wave -childrowmargin 2
|
|||||||
set DefaultRadix hexadecimal
|
set DefaultRadix hexadecimal
|
||||||
|
|
||||||
-- Run the Simulation
|
-- Run the Simulation
|
||||||
run 2000
|
#run 2000
|
||||||
#run -all
|
run -all
|
||||||
#quit
|
#quit
|
||||||
|
29
wally-pipelined/src/fpu/fcsr.sv
Normal file
29
wally-pipelined/src/fpu/fcsr.sv
Normal file
@ -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
|
143
wally-pipelined/src/fpu/fctrl.sv
Normal file
143
wally-pipelined/src/fpu/fctrl.sv
Normal file
@ -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
|
59
wally-pipelined/src/fpu/fputop.sv
Normal file
59
wally-pipelined/src/fpu/fputop.sv
Normal file
@ -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
|
513
wally-pipelined/src/fpu/freg.sv
Normal file
513
wally-pipelined/src/fpu/freg.sv
Normal file
@ -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
|
@ -53,11 +53,19 @@ module imem (
|
|||||||
generate
|
generate
|
||||||
if (`XLEN==32) begin
|
if (`XLEN==32) begin
|
||||||
assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd;
|
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
|
end else begin
|
||||||
assign InstrF = AdrF[2] ? (AdrF[1] ? {rd2[15:0], rd[63:48]} : rd[63:32])
|
assign InstrF = AdrF[2] ? (AdrF[1] ? {rd2[15:0], rd[63:48]} : rd[63:32])
|
||||||
: (AdrF[1] ? rd[47:16] : rd[31:0]);
|
: (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
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user