Cleaned up the cacheLRU.
This commit is contained in:
Rose Thompson 2024-03-05 11:08:40 -06:00
commit c093f53c9c
15 changed files with 60 additions and 93 deletions

View File

@ -69,9 +69,6 @@ fi
cd $RISCV cd $RISCV
git clone https://github.com/riscv/riscv-gnu-toolchain git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain cd riscv-gnu-toolchain
# Temporarily use the following commands until gcc-13 is part of riscv-gnu-toolchain (issue #1249)
#git clone https://github.com/gcc-mirror/gcc -b releases/gcc-13 gcc-13
#./configure --prefix=/opt/riscv --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;" --with-gcc-src=`pwd`/gcc-13
./configure --prefix=${RISCV} --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;" ./configure --prefix=${RISCV} --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
make -j ${NUM_THREADS} make -j ${NUM_THREADS}
@ -111,14 +108,15 @@ cd riscv-isa-sim/build
make -j ${NUM_THREADS} make -j ${NUM_THREADS}
make install make install
cd ../arch_test_target/spike/device cd ../arch_test_target/spike/device
sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include # dh 2/5/24: these should be obsolete
sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include #sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include
#sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include
# Wally needs Verilator 5.021 or later. # Wally needs Verilator 5.021 or later.
# Verilator needs to be built from scratch to get the latest version # Verilator needs to be built from scratch to get the latest version
# apt-get install verilator installs version 4.028 as of 6/8/23 # apt-get install verilator installs version 4.028 as of 6/8/23
sudo apt-get install -y perl g++ ccache help2man libgoogle-perftools-dev numactl perl-doc zlib1g sudo apt-get install -y perl g++ ccache help2man libgoogle-perftools-dev numactl perl-doc zlib1g
sudo apt-get install -y libfl2 libfl-dev # Ubuntu only (ignore if gives error) sudo apt-get install -y perl g++ ccache help2man libgoogle-perftools-dev numactl perl-doc zlib1g
cd $RISCV cd $RISCV
git clone https://github.com/verilator/verilator # Only first time git clone https://github.com/verilator/verilator # Only first time
# unsetenv VERILATOR_ROOT # For csh; ignore error if on bash # unsetenv VERILATOR_ROOT # For csh; ignore error if on bash
@ -173,6 +171,8 @@ sudo make install
cd $RISCV cd $RISCV
opam init -y --disable-sandboxing opam init -y --disable-sandboxing
opam update
opam upgrade
opam switch create 5.1.0 opam switch create 5.1.0
opam install sail -y opam install sail -y

View File

@ -94,7 +94,7 @@ localparam LOGR = $clog2(RADIX); // r = log(R
localparam RK = LOGR*DIVCOPIES; // r*k bits per cycle generated localparam RK = LOGR*DIVCOPIES; // r*k bits per cycle generated
// intermediate division parameters not directly used in fdivsqrt hardware // intermediate division parameters not directly used in fdivsqrt hardware
localparam FPDIVMINb = NF + 3; // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit to allow sqrt being shifted right localparam FPDIVMINb = NF + 2; // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit to allow sqrt being shifted right
//localparam FPDIVMINb = NF + 2 + (RADIX == 2); // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit for preshifting radix2 square root right, if radix4 doesn't use a right shift. This version saves one cycle on double-precision with R=4,k=4. However, it doesn't work yet because C is too short, so k is incorrectly calculated as a 1 in the lsb after the last step. //localparam FPDIVMINb = NF + 2 + (RADIX == 2); // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit for preshifting radix2 square root right, if radix4 doesn't use a right shift. This version saves one cycle on double-precision with R=4,k=4. However, it doesn't work yet because C is too short, so k is incorrectly calculated as a 1 in the lsb after the last step.
localparam DIVMINb = ((FPDIVMINb<XLEN) & IDIV_ON_FPU) ? XLEN : FPDIVMINb; // minimum fractional bits b = max(XLEN, FPDIVMINb) localparam DIVMINb = ((FPDIVMINb<XLEN) & IDIV_ON_FPU) ? XLEN : FPDIVMINb; // minimum fractional bits b = max(XLEN, FPDIVMINb)
localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r integer + b fractional localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r integer + b fractional

View File

@ -142,7 +142,8 @@ module cacheLRU
// This is a two port memory. // This is a two port memory.
// Every cycle must read from CacheSetData and each load/store must write the new LRU. // Every cycle must read from CacheSetData and each load/store must write the new LRU.
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; // exclusion-tag: initialize if (reset | (InvalidateCache & ~FlushStage))
for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; // exclusion-tag: initialize
if(CacheEn) begin if(CacheEn) begin
if(LRUWriteEn) if(LRUWriteEn)
LRUMemory[PAdr] <= NextLRU; LRUMemory[PAdr] <= NextLRU;

View File

@ -71,8 +71,7 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
// The datapath produces rk bits per cycle, so Cycles = ceil (ResultBitsE / rk) // The datapath produces rk bits per cycle, so Cycles = ceil (ResultBitsE / rk)
always_comb begin always_comb begin
if (SqrtE) FPResultBitsE = Nf + 2 + 0; // Nf + two fractional bits for round/guard; integer bit implicit because starting at n=1 FPResultBitsE = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard; integer bit implicit because starting at n=1
else FPResultBitsE = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard + integer bits
if (P.IDIV_ON_FPU) ResultBitsE = IntDivE ? IntResultBitsE : FPResultBitsE; if (P.IDIV_ON_FPU) ResultBitsE = IntDivE ? IntResultBitsE : FPResultBitsE;
else ResultBitsE = FPResultBitsE; else ResultBitsE = FPResultBitsE;

View File

@ -44,7 +44,7 @@ module fdivsqrtiter import cvw::*; #(parameter cvw_t P) (
logic [P.DIVb+3:0] WCNext[P.DIVCOPIES-1:0]; // Q4.DIVb logic [P.DIVb+3:0] WCNext[P.DIVCOPIES-1:0]; // Q4.DIVb
logic [P.DIVb+3:0] WS[P.DIVCOPIES:0]; // Q4.DIVb logic [P.DIVb+3:0] WS[P.DIVCOPIES:0]; // Q4.DIVb
logic [P.DIVb+3:0] WC[P.DIVCOPIES:0]; // Q4.DIVb logic [P.DIVb+3:0] WC[P.DIVCOPIES:0]; // Q4.DIVb
logic [P.DIVb:0] U[P.DIVCOPIES:0]; // U1.DIVb logic [P.DIVb:0] U[P.DIVCOPIES:0]; // U1.DIVb // *** probably Q not U. See Table 16.26 notes
logic [P.DIVb:0] UM[P.DIVCOPIES:0]; // U1.DIVb logic [P.DIVb:0] UM[P.DIVCOPIES:0]; // U1.DIVb
logic [P.DIVb:0] UNext[P.DIVCOPIES-1:0]; // U1.DIVb logic [P.DIVb:0] UNext[P.DIVCOPIES-1:0]; // U1.DIVb
logic [P.DIVb:0] UMNext[P.DIVCOPIES-1:0]; // U1.DIVb logic [P.DIVb:0] UMNext[P.DIVCOPIES-1:0]; // U1.DIVb
@ -71,24 +71,18 @@ module fdivsqrtiter import cvw::*; #(parameter cvw_t P) (
flopen #(P.DIVb+4) wcreg(clk, FDivBusyE, WCN, WC[0]); flopen #(P.DIVb+4) wcreg(clk, FDivBusyE, WCN, WC[0]);
// UOTFC Result U and UM registers/initialization mux // UOTFC Result U and UM registers/initialization mux
// Initialize U to 1.0 and UM to 0 for square root; U to 0 and UM to -1 otherwise // Initialize U to 0 = 0.0000... and UM to -1 = 1.00000... (in Q1.Divb)
assign initU = {SqrtE, {(P.DIVb){1'b0}}}; assign initU ={(P.DIVb+1){1'b0}};
assign initUM = {~SqrtE, {(P.DIVb){1'b0}}}; assign initUM = {{1'b1}, {(P.DIVb){1'b0}}};
mux2 #(P.DIVb+1) Umux(UNext[P.DIVCOPIES-1], initU, IFDivStartE, UMux); mux2 #(P.DIVb+1) Umux(UNext[P.DIVCOPIES-1], initU, IFDivStartE, UMux);
mux2 #(P.DIVb+1) UMmux(UMNext[P.DIVCOPIES-1], initUM, IFDivStartE, UMMux); mux2 #(P.DIVb+1) UMmux(UMNext[P.DIVCOPIES-1], initUM, IFDivStartE, UMMux);
flopen #(P.DIVb+1) UReg(clk, FDivBusyE, UMux, U[0]); flopen #(P.DIVb+1) UReg(clk, FDivBusyE, UMux, U[0]);
flopen #(P.DIVb+1) UMReg(clk, FDivBusyE, UMMux, UM[0]); flopen #(P.DIVb+1) UMReg(clk, FDivBusyE, UMMux, UM[0]);
// C register/initialization mux // C register/initialization mux: C = -R:
// Initialize C to -1 for sqrt and -R for division // C = -4 = 00.000000... (in Q2.DIVb) for radix 4, C = -2 = 10.000000... for radix2
logic [1:0] initCUpper; if(P.RADIX == 4) assign initC = '0;
if(P.RADIX == 4) begin else assign initC = {2'b10, {{P.DIVb{1'b0}}}};
mux2 #(2) cuppermux4(2'b00, 2'b11, SqrtE, initCUpper);
end else begin
mux2 #(2) cuppermux2(2'b10, 2'b11, SqrtE, initCUpper);
end
assign initC = {initCUpper, {P.DIVb{1'b0}}};
mux2 #(P.DIVb+2) cmux(C[P.DIVCOPIES], initC, IFDivStartE, NextC); mux2 #(P.DIVb+2) cmux(C[P.DIVCOPIES], initC, IFDivStartE, NextC);
flopen #(P.DIVb+2) creg(clk, FDivBusyE, NextC, C[0]); flopen #(P.DIVb+2) creg(clk, FDivBusyE, NextC, C[0]);
@ -108,9 +102,7 @@ module fdivsqrtiter import cvw::*; #(parameter cvw_t P) (
.WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]), .WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]),
.C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i])); .C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i]));
end else begin: stage end else begin: stage
logic j1; fdivsqrtstage4 #(P) fdivsqrtstage(.D, .DBar, .D2, .DBar2, .SqrtE,
assign j1 = (i == 0 & ~C[0][P.DIVb-1]);
fdivsqrtstage4 #(P) fdivsqrtstage(.D, .DBar, .D2, .DBar2, .SqrtE, .j1,
.WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]), .WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]),
.C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i])); .C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i]));
end end

View File

@ -174,9 +174,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
logic [P.DIVb:0] PreSqrtX; logic [P.DIVb:0] PreSqrtX;
assign EvenExp = Xe[0] ^ ell[0]; // effective unbiased exponent after normalization is even assign EvenExp = Xe[0] ^ ell[0]; // effective unbiased exponent after normalization is even
mux2 #(P.DIVb+1) sqrtxmux(Xnorm, {1'b0, Xnorm[P.DIVb:1]}, EvenExp, PreSqrtX); // X if exponent odd, X/2 if exponent even mux2 #(P.DIVb+4) sqrtxmux({4'b0,Xnorm[P.DIVb:1]}, {5'b00, Xnorm[P.DIVb:2]}, EvenExp, SqrtX); // X/2 if exponent odd, X/4 if exponent even
if (P.RADIX == 2) assign SqrtX = {3'b111, PreSqrtX}; // PreSqrtX - 2 = 2(PreSqrtX/2 - 1)
else assign SqrtX = {2'b11, PreSqrtX, 1'b0}; // 2PreSqrtX - 4 = 4(PreSqrtX/2 - 1)
/* /*
// Attempt to optimize radix 4 to use a left shift by 1 or zero initially, followed by no more left shift // Attempt to optimize radix 4 to use a left shift by 1 or zero initially, followed by no more left shift

View File

@ -32,7 +32,7 @@ module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) (
input logic [P.DIVb:0] U,UM, // U1.DIVb input logic [P.DIVb:0] U,UM, // U1.DIVb
input logic [P.DIVb+3:0] WS, WC, // Q4.DIVb input logic [P.DIVb+3:0] WS, WC, // Q4.DIVb
input logic [P.DIVb+1:0] C, // Q2.DIVb input logic [P.DIVb+1:0] C, // Q2.DIVb
input logic SqrtE, j1, input logic SqrtE,
output logic [P.DIVb+1:0] CNext, // Q2.DIVb output logic [P.DIVb+1:0] CNext, // Q2.DIVb
output logic un, output logic un,
output logic [P.DIVb:0] UNext, UMNext, // U1.DIVb output logic [P.DIVb:0] UNext, UMNext, // U1.DIVb
@ -48,13 +48,16 @@ module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) (
logic [7:0] WCmsbs, WSmsbs; // U4.4 logic [7:0] WCmsbs, WSmsbs; // U4.4
logic CarryIn; logic CarryIn;
logic [P.DIVb+3:0] WSA, WCA; // Q4.DIVb logic [P.DIVb+3:0] WSA, WCA; // Q4.DIVb
logic j0, j1; // step j = 0 or step j = 1
// Digit Selection logic // Digit Selection logic
assign j0 = ~C[P.DIVb+1]; // first step of R digit selection: C = 00...0
assign j1 = C[P.DIVb] & ~C[P.DIVb-1]; // second step of R digit selection: C = 1100...0; *** could simplify to ~C[P.DIVb-1] because j=0 case takes priority
assign Smsbs = U[P.DIVb:P.DIVb-4]; // U1.4 most significant bits of square root assign Smsbs = U[P.DIVb:P.DIVb-4]; // U1.4 most significant bits of square root
assign Dmsbs = D[P.DIVb-1:P.DIVb-3]; // U0.3 most significant fractional bits of divisor after leading 1 assign Dmsbs = D[P.DIVb-1:P.DIVb-3]; // U0.3 most significant fractional bits of divisor after leading 1
assign WCmsbs = WC[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual assign WCmsbs = WC[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual
assign WSmsbs = WS[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual assign WSmsbs = WS[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual
fdivsqrtuslc4cmp uslc4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j1, .udigit); fdivsqrtuslc4cmp uslc4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j0, .j1, .udigit);
assign un = 1'b0; // unused for radix 4 assign un = 1'b0; // unused for radix 4
// F generation logic // F generation logic

View File

@ -31,7 +31,7 @@ module fdivsqrtuslc4 (
input logic [2:0] Dmsbs, // U0.3 fractional bits after implicit leading 1 input logic [2:0] Dmsbs, // U0.3 fractional bits after implicit leading 1
input logic [4:0] Smsbs, // U1.4 leading bits of square root approximation input logic [4:0] Smsbs, // U1.4 leading bits of square root approximation
input logic [7:0] WSmsbs, WCmsbs, // Q4.4 redundant residual most significant bits input logic [7:0] WSmsbs, WCmsbs, // Q4.4 redundant residual most significant bits
input logic Sqrt, j1, input logic Sqrt, j0, j1,
output logic [3:0] udigit // {2, 1, -1, -2} digit is 0 if none are hot output logic [3:0] udigit // {2, 1, -1, -2} digit is 0 if none are hot
); );
logic [7:0] PreWmsbs; // Q4.4 nonredundant residual msbs logic [7:0] PreWmsbs; // Q4.4 nonredundant residual msbs
@ -102,11 +102,12 @@ module fdivsqrtuslc4 (
// Select A // Select A
always_comb always_comb
if (Sqrt) begin if (Sqrt) begin
if (j1) A = 3'b101; // on first sqrt iteration A = .101 if (j1) A = 3'b101; // on first sqrt iteration A = .101
else if (Smsbs == 5'b10000) A = 3'b111; // if S = 1.0, use A = .111 else if (Smsbs[4] == 1) A = 3'b111; // if S = 1.0000, use A = .111
else A = Smsbs[2:0]; // otherwise use A = 2S (in U0.3 format) else A = Smsbs[2:0]; // otherwise use A = 2S (in U0.3 format)
end else A = Dmsbs; // division Unless A = D (IN U0.3 format, dropping leading 1) end else A = Dmsbs; // division A = D (IN U0.3 format, dropping leading 1)
// Select quotient digit from lookup table based on A and W // Select quotient digit from lookup table based on A and W
assign udigit = USel4[{A,Wmsbs}]; // On step j = 0 for square root, always select u_0 = 1
assign udigit = (Sqrt & j0) ? 4'b0100 : USel4[{A,Wmsbs}];
endmodule endmodule

View File

@ -31,7 +31,8 @@ module fdivsqrtuslc4cmp (
input logic [2:0] Dmsbs, // U0.3 fractional bits after implicit leading 1 input logic [2:0] Dmsbs, // U0.3 fractional bits after implicit leading 1
input logic [4:0] Smsbs, // U1.4 leading bits of square root approximation input logic [4:0] Smsbs, // U1.4 leading bits of square root approximation
input logic [7:0] WSmsbs, WCmsbs, // Q4.4 residual most significant bits input logic [7:0] WSmsbs, WCmsbs, // Q4.4 residual most significant bits
input logic SqrtE, j1, input logic SqrtE,
input logic j0, j1, // are we on first (j0) or second step (j1) of digit selection
output logic [3:0] udigit // {2, 1, -1, -2} digit is 0 if none are hot output logic [3:0] udigit // {2, 1, -1, -2} digit is 0 if none are hot
); );
logic [6:0] Wmsbs; logic [6:0] Wmsbs;
@ -46,7 +47,9 @@ module fdivsqrtuslc4cmp (
// Wmsbs = | | // Wmsbs = | |
logic [6:0] mk2, mk1, mk0, mkm1; logic [6:0] mk2, mk1, mk0, mkm1;
logic [6:0] mkj2, mkj1, mkj0, mkjm1;
logic [6:0] mks2[7:0], mks1[7:0]; logic [6:0] mks2[7:0], mks1[7:0];
logic sqrtspecial;
// Prepopulate table of mks0 // Prepopulate table of mks0
assign mks2[0] = 12; assign mks2[0] = 12;
@ -65,20 +68,25 @@ module fdivsqrtuslc4cmp (
assign mks1[5] = 8; // is the logic any cheaper if this is a 6? assign mks1[5] = 8; // is the logic any cheaper if this is a 6?
assign mks1[6] = 8; assign mks1[6] = 8;
assign mks1[7] = 8; assign mks1[7] = 8;
// handles special case when j = 0 or j = 1 for sqrt
assign mkj2 = 20; // when j = 1 use mk2[101] when j = 0 use anything bigger than 7.
assign mkj1 = j0 ? 0 : 8; // when j = 1 use mk1[101] = 8 and when j = 0 use 0 so we choose u_0 = 1
assign sqrtspecial = SqrtE & (j1 | j0);
// Choose A for current operation // Choose A for current operation
always_comb always_comb
if (SqrtE) begin if (SqrtE) begin
if (j1) A = 3'b101; if (Smsbs[4]) A = 3'b111; // for S = 1.0000 *** can we optimize away this case?
else if (Smsbs == 5'b10000) A = 3'b111;
else A = Smsbs[2:0]; else A = Smsbs[2:0];
end else A = Dmsbs; end else A = Dmsbs;
// Choose selection constants based on a // Choose selection constants based on a
assign mk2 = mks2[A];
assign mk1 = mks1[A]; assign mk2 = sqrtspecial ? mkj2 : mks2[A];
assign mk0 = -mks1[A]; assign mk1 = sqrtspecial ? mkj1 : mks1[A];
assign mkm1 = (A == 3'b000) ? -13 : -mks2[A]; // asymmetry in table assign mk0 = -mk1;
assign mkm1 = (A == 3'b000) ? -13 : -mk2; // asymmetry in table *** can we hide from critical path
// Compare residual W to selection constants to choose digit // Compare residual W to selection constants to choose digit
always_comb always_comb

View File

@ -1,38 +0,0 @@
///////////////////////////////////////////
// floprc.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Modified:
//
// Purpose: D flip-flop with synchronous reset and clear
//
// A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
module floprc #(parameter WIDTH = 8) (
input logic clk,
input logic reset,
input logic clear,
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset | clear ) q <= #1 0;
else q <= #1 d;
endmodule

View File

@ -43,7 +43,7 @@ module ram1p1rwbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44, PRE
output logic [WIDTH-1:0] dout output logic [WIDTH-1:0] dout
); );
logic [WIDTH-1:0] RAM[DEPTH-1:0]; bit [WIDTH-1:0] RAM[DEPTH-1:0];
// *************************************************************************** // ***************************************************************************
// TRUE SRAM macro // TRUE SRAM macro

View File

@ -40,7 +40,7 @@ module ram1p1rwe import cvw::* ; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44) (
output logic [WIDTH-1:0] dout output logic [WIDTH-1:0] dout
); );
logic [WIDTH-1:0] RAM[DEPTH-1:0]; bit [WIDTH-1:0] RAM[DEPTH-1:0];
// *************************************************************************** // ***************************************************************************
// TRUE SRAM macro // TRUE SRAM macro

View File

@ -148,6 +148,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB) flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
assign PRegEn = HPTWRW[1] & ~DCacheBusStallM | UpdatePTE; assign PRegEn = HPTWRW[1] & ~DCacheBusStallM | UpdatePTE;
flopenr #(P.XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache flopenr #(P.XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
assert property(@(posedge clk) ~PRegEn | reset | NextPTE[0] !== 1'bx); // report writing an x PTE from an uninitialized page table
// Assign PTE descriptors common across all XLEN values // Assign PTE descriptors common across all XLEN values
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table // For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
@ -173,7 +174,8 @@ module hptw import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] AccessedPTE; logic [P.XLEN-1:0] AccessedPTE;
assign AccessedPTE = {PTE[P.XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit assign AccessedPTE = {PTE[P.XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit
assign ReadDataNoXM = (ReadDataM[0] === 'x) ? '0 : ReadDataM; // If the PTE.V bit is x because it was read from uninitialized memory set to 0 to avoid x propagation and hanging the simulation. //assign ReadDataNoXM = (ReadDataM[0] === 'x) ? '0 : ReadDataM; // If the PTE.V bit is x because it was read from uninitialized memory set to 0 to avoid x propagation and hanging the simulation.
assign ReadDataNoXM = ReadDataM; // *** temporary fix for synthesis; === and x in line above are not synthesizable.
mux2 #(P.XLEN) NextPTEMux(ReadDataNoXM, AccessedPTE, UpdatePTE, NextPTE); // NextPTE = ReadDataNoXM when ADUE = 0 because UpdatePTE = 0 mux2 #(P.XLEN) NextPTEMux(ReadDataNoXM, AccessedPTE, UpdatePTE, NextPTE); // NextPTE = ReadDataNoXM when ADUE = 0 because UpdatePTE = 0
flopenr #(P.PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr); flopenr #(P.PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);

View File

@ -80,8 +80,8 @@ module privdec import cvw::*; #(parameter cvw_t P) (
if (P.U_SUPPORTED) begin:wfi if (P.U_SUPPORTED) begin:wfi
logic [P.WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1; logic [P.WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1;
assign WFICountPlus1 = WFICount + 1; assign WFICountPlus1 = wfiM ? WFICount + 1 : '0; // restart counting on WFI
floprc #(P.WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, ~wfiM, WFICountPlus1, WFICount); // count while in WFI flopr #(P.WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, WFICountPlus1, WFICount); // count while in WFI
// coverage off -item e 1 -fecexprrow 1 // coverage off -item e 1 -fecexprrow 1
// WFI Timout trap will not occur when STATUS_TW is low while in supervisor mode, so the system gets stuck waiting for an interrupt and triggers a watchdog timeout. // WFI Timout trap will not occur when STATUS_TW is low while in supervisor mode, so the system gets stuck waiting for an interrupt and triggers a watchdog timeout.
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != P.M_MODE) | (P.S_SUPPORTED & PrivilegeModeW == P.U_MODE)) & WFICount[P.WFI_TIMEOUT_BIT]; assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != P.M_MODE) | (P.S_SUPPORTED & PrivilegeModeW == P.U_MODE)) & WFICount[P.WFI_TIMEOUT_BIT];

View File

@ -51,7 +51,8 @@ configs: $(CONFIG)
$(CONFIG): $(CONFIG):
@echo $(CONFIG) @echo $(CONFIG)
cp -r $(OLDCONFIGDIR)/shared/*.vh $(CONFIGDIR) cp -r $(OLDCONFIGDIR)/shared/*.vh $(CONFIGDIR)
cp -r $(OLDCONFIGDIR)/$(CONFIG)/* $(CONFIGDIR) # cp -r $(OLDCONFIGDIR)/$(CONFIG)/* $(CONFIGDIR)
cp -r $(OLDCONFIGDIR)/deriv/$(CONFIG)/* $(CONFIGDIR)
# adjust DTIM and IROM to reasonable values depending on config # adjust DTIM and IROM to reasonable values depending on config
ifneq ($(filter $(CONFIG), $(DIRS32)),) ifneq ($(filter $(CONFIG), $(DIRS32)),)
@ -61,8 +62,8 @@ else ifneq ($(filter $(CONFIG), $(DIRS64)),)
sed -i "s/DTIM_RANGE.*/DTIM_RANGE = 56\'h01FF;/g" $(CONFIGDIR)/config.vh sed -i "s/DTIM_RANGE.*/DTIM_RANGE = 56\'h01FF;/g" $(CONFIGDIR)/config.vh
sed -i "s/IROM_RANGE.*/IROM_RANGE = 56\'h01FF;/g" $(CONFIGDIR)/config.vh sed -i "s/IROM_RANGE.*/IROM_RANGE = 56\'h01FF;/g" $(CONFIGDIR)/config.vh
else else
$(info $(CONFIG) does not exist in $(DIRS32) or $(DIRS64)) $(info $(CONFIG) does not exist in $(DIRS32) or $(DIRS64))
@echo "Config not in list, RAM_RANGE will be unmodified" @echo "Config not in list, RAM_RANGE will be unmodified"
endif endif
# if USESRAM = 1, set that in the config file, otherwise reduce sizes # if USESRAM = 1, set that in the config file, otherwise reduce sizes