Resolved conflicts between different gpio files

This commit is contained in:
slmnemo 2022-07-05 18:38:52 -07:00
commit f8059e9e40
50 changed files with 900 additions and 2638 deletions

3
.gitignore vendored
View File

@ -76,7 +76,8 @@ synthDC/*.log
synthDC/*.svf
synthDC/runs/
synthDC/newRuns
synthDC/PPAruns
synthDC/ppa/PPAruns
synthDC/ppa/plots
synthDC/plots/
synthDC/runArchive
synthDC/hdl

View File

@ -157,7 +157,7 @@ void softfloatInit(void) {
// RM: softfloat_round_min
softfloat_roundingMode = softfloat_round_near_even;
softfloat_exceptionFlags = 0; // clear exceptions
softfloat_detectTininess = softfloat_tininess_beforeRounding; // RISC-V behavior for tininess
softfloat_detectTininess = softfloat_tininess_afterRounding; // RISC-V behavior for tininess
}
uint64_t parseNum(char *num) {

View File

@ -37,7 +37,7 @@ void softfloatInit(void) {
// RM: softfloat_round_min
softfloat_roundingMode = softfloat_round_near_even;
softfloat_exceptionFlags = 0; // clear exceptions
softfloat_detectTininess = softfloat_tininess_beforeRounding; // RISC-V behavior for tininess
softfloat_detectTininess = softfloat_tininess_afterRounding; // RISC-V behavior for tininess
}
int main()

View File

@ -32,7 +32,7 @@
`define DESIGN_COMPILER 0
// RV32 or RV64: XLEN = 32 or 64
`define XLEN 32
`define XLEN 64
// IEEE 754 compliance
`define IEEE754 0

View File

@ -36,7 +36,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -o testbenchopt
vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084
vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084 -fatal 7
run -all
run -all
@ -46,7 +46,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt
vsim -lib wkdir/work_${1}_${2} testbenchopt
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7
# Adding coverage increases runtime from 2:00 to 4:29. Can't run it all the time
#vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf
#vsim -coverage -lib work_$2 workopt_$2

View File

@ -35,7 +35,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -G NO_SPOOFING=0 -o testbenchopt
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829 -fatal 7
#-- Run the Simulation
run -all
@ -49,7 +49,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=0 -G INSTR_WAVEON=0 -G CHECKPOINT=0 -G NO_SPOOFING=1 -o testbenchopt
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829 -fatal 7
#-- Run the Simulation
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@ -69,7 +69,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063
vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt
vsim workopt +nowarn3829
vsim workopt +nowarn3829 -fatal 7
view wave
#-- display input and output signals as hexidecimal values
@ -78,12 +78,12 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
do wave.do
# power add generates the logging necessary for saif generation.
power add -r /dut/core/*
#power add -r /dut/core/*
#-- Run the Simulation
run -all
power off -r /dut/core/*
power report -all -bsaif power.saif
#power off -r /dut/core/*
#power report -all -bsaif power.saif
noview ../testbench/testbench.sv
view wave
}

View File

@ -168,9 +168,9 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGWPL, WORDLEN, MUXINTER
else
mux2 #(LINELEN) WriteDataMux(.d0({WORDSPERLINE{FinalWriteData}}),
.d1(CacheBusWriteData), .s(SetValid), .y(CacheWriteData));
mux3 #(`PA_BITS) CacheBusAdrMux(.d0({PAdr[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
.d1({VictimTag, PAdr[SETTOP-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
.d2({VictimTag, FlushAdr, {{OFFSETLEN}{1'b0}}}),
mux3 #(`PA_BITS) CacheBusAdrMux(.d0({PAdr[`PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
.d1({VictimTag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
.d2({VictimTag, FlushAdr, {OFFSETLEN{1'b0}}}),
.s({SelFlush, SelEvict}), .y(CacheBusAdr));
/////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -49,6 +49,8 @@ module ahblite (
input logic [2:0] IFUBurstType,
input logic [1:0] IFUTransType,
input logic IFUTransComplete,
input logic [(`XLEN-1)/8:0] ByteMaskM,
// Signals from Data Cache
input logic [`PA_BITS-1:0] LSUBusAdr,
input logic LSUBusRead,
@ -67,6 +69,7 @@ module ahblite (
(* mark_debug = "true" *) output logic HCLK, HRESETn,
(* mark_debug = "true" *) output logic [31:0] HADDR, // *** one day switch to a different bus that supports the full physical address
(* mark_debug = "true" *) output logic [`AHBW-1:0] HWDATA,
output logic [`XLEN/8-1:0] HWSTRB,
(* mark_debug = "true" *) output logic HWRITE,
(* mark_debug = "true" *) output logic [2:0] HSIZE,
(* mark_debug = "true" *) output logic [2:0] HBURST,
@ -131,8 +134,8 @@ module ahblite (
// bus outputs
assign #1 GrantData = (NextBusState == MEMREAD) | (NextBusState == MEMWRITE);
assign #1 AccessAddress = (GrantData) ? LSUBusAdr[31:0] : IFUBusAdr[31:0];
assign #1 HADDR = AccessAddress;
assign AccessAddress = (GrantData) ? LSUBusAdr[31:0] : IFUBusAdr[31:0];
assign HADDR = AccessAddress;
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway
assign HSIZE = (GrantData) ? {1'b0, LSUBusSize[1:0]} : ISize;
assign HBURST = (GrantData) ? LSUBurstType : IFUBurstType; // If doing memory accesses, use LSUburst, else use Instruction burst.
@ -154,6 +157,7 @@ module ahblite (
assign HTRANS = (GrantData) ? LSUTransType : IFUTransType; // SEQ if not first read or write, NONSEQ if first read or write, IDLE otherwise
assign HMASTLOCK = 0; // no locking supported
assign HWRITE = (NextBusState == MEMWRITE);
assign HWSTRB = ByteMaskM;
// delay write data by one cycle for
flopen #(`XLEN) wdreg(HCLK, (LSUBusAck | LSUBusInit), LSUBusHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN
// delay signals for subword writes
@ -163,13 +167,10 @@ module ahblite (
// Route signals to Instruction and Data Caches
// *** assumes AHBW = XLEN
assign IFUBusHRDATA = HRDATA;
assign LSUBusHRDATA = HRDATA;
assign IFUBusInit = (BusState != INSTRREAD) & (NextBusState == INSTRREAD);
assign LSUBusInit = (((BusState != MEMREAD) & (NextBusState == MEMREAD)) | (BusState != MEMWRITE) & (NextBusState == MEMWRITE));
assign IFUBusAck = HREADY & (BusState == INSTRREAD);
assign LSUBusAck = HREADY & ((BusState == MEMREAD) | (BusState == MEMWRITE));
endmodule

View File

@ -31,6 +31,7 @@ module cvtshiftcalc(
// | `NF-1 zeros | Mantissa | 0's if nessisary |
// - otherwise:
// | LzcInM | 0's if nessisary |
// change to int shift to the left one
assign CvtShiftIn = ToInt ? {{`XLEN{1'b0}}, XManM[`NF]&~CvtCalcExpM[`NE], XManM[`NF-1]|(CvtCalcExpM[`NE]&XManM[`NF]), XManM[`NF-2:0], {`CVTLEN-`XLEN{1'b0}}} :
CvtResDenormUfM ? {{`NF-1{1'b0}}, XManM, {`CVTLEN-`NF+1{1'b0}}} :
{CvtLzcInM, {`NF+1{1'b0}}};

View File

@ -11,7 +11,7 @@ module divshiftcalc(
output logic [`NE+1:0] DivDenormShift
);
logic [`NE+1:0] NormShift;
logic [`NE+1:0] Nf, NfPlus1;
logic [`NE+1:0] Nf;
// is the result denromalized
// if the exponent is 1 then the result needs to be normalized then the result is denormalizes
@ -19,51 +19,25 @@ module divshiftcalc(
// select the proper fraction lengnth
if (`FPSIZES == 1) begin
assign Nf = (`NE+2)'(`NF);
assign NfPlus1 = (`NE+2)'(`NF+1);
end else if (`FPSIZES == 2) begin
assign Nf = FmtM ? (`NE+2)'(`NF) : (`NE+2)'(`NF1);
assign NfPlus1 = FmtM ? (`NE+2)'(`NF+1) : (`NE+2)'(`NF1+1);
end else if (`FPSIZES == 3) begin
always_comb
case (FmtM)
`FMT: begin
Nf = (`NE+2)'(`NF);
NfPlus1 = (`NE+2)'(`NF+1);
end
`FMT1: begin
Nf = (`NE+2)'(`NF1);
NfPlus1 = (`NE+2)'(`NF1+1);
end
`FMT2: begin
Nf = (`NE+2)'(`NF2);
NfPlus1 = (`NE+2)'(`NF2+1);
end
default: begin
Nf = 1'bx;
NfPlus1 = 1'bx;
end
`FMT: Nf = (`NE+2)'(`NF);
`FMT1: Nf = (`NE+2)'(`NF1);
`FMT2: Nf = (`NE+2)'(`NF2);
default: Nf = 1'bx;
endcase
end else if (`FPSIZES == 4) begin
always_comb
case (FmtM)
2'h3: begin
Nf = (`NE+2)'(`Q_NF);
NfPlus1 = (`NE+2)'(`Q_NF+1);
end
2'h1: begin
Nf = (`NE+2)'(`D_NF);
NfPlus1 = (`NE+2)'(`D_NF+1);
end
2'h0: begin
Nf = (`NE+2)'(`S_NF);
NfPlus1 = (`NE+2)'(`S_NF+1);
end
2'h2: begin
Nf = (`NE+2)'(`H_NF);
NfPlus1 = (`NE+2)'(`H_NF+1);
end
2'h3: Nf = (`NE+2)'(`Q_NF);
2'h1: Nf = (`NE+2)'(`D_NF);
2'h0: Nf = (`NE+2)'(`S_NF);
2'h2: Nf = (`NE+2)'(`H_NF);
endcase
end
// if the result is denormalized

View File

@ -179,7 +179,7 @@ module fcvt (
// - shifted right by XLEN (XLEN)
// - shift left to normilize (-1-ZeroCnt)
// - newBias to make the biased exponent
//
// oldexp - biasold +newbias - (ZeroCnt+1)&(XDenormE|IntToFp)
assign CvtCalcExpE = {1'b0, OldExp} - (`NE+1)'(`BIAS) + {2'b0, NewBias} - {{`NE{1'b0}}, XDenormE|IntToFp} - {{`NE-`LOGCVTLEN+1{1'b0}}, (ZeroCnt&{`LOGCVTLEN{XDenormE|IntToFp}})};
// find if the result is dnormal or underflows
// - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0)

View File

@ -30,27 +30,27 @@
`include "wally-config.vh"
module fma(
input logic XSgnE, YSgnE, ZSgnE, // input's signs
input logic [`NE-1:0] XExpE, YExpE, ZExpE, // biased exponents in B(NE.0) format
input logic [`NF:0] XManE, YManE, ZManE, // fractions in U(0.NF) format
input logic Xs, Ys, Zs, // input's signs
input logic [`NE-1:0] Xe, Ye, Ze, // input's biased exponents in B(NE.0) format
input logic [`NF:0] Xm, Ym, Zm, // input's significands in U(0.NF) format
input logic XZeroE, YZeroE, ZZeroE, // is the input zero
input logic [2:0] FOpCtrlE, // 000 = fmadd (X*Y)+Z, 001 = fmsub (X*Y)-Z, 010 = fnmsub -(X*Y)+Z, 011 = fnmadd -(X*Y)-Z, 100 = fmul (X*Y)
input logic [`FMTBITS-1:0] FmtE, // precision 1 = double 0 = single
output logic [`NE+1:0] ProdExpE, // X exponent + Y exponent - bias in B(NE+2.0) format; adds 2 bits to allow for size of number and negative sign
output logic [`NE+1:0] Pe, // the product's exponent B(NE+2.0) format; adds 2 bits to allow for size of number and negative sign
output logic AddendStickyE, // sticky bit that is calculated during alignment
output logic KillProdE, // set the product to zero before addition if the product is too small to matter
output logic [3*`NF+5:0] SumE, // the positive sum
output logic [3*`NF+5:0] Sm, // the positive sum
output logic NegSumE, // was the sum negitive
output logic InvZE, // intert Z
output logic InvA, // intert Z
output logic ZSgnEffE, // the modified Z sign
output logic PSgnE, // the product's sign
output logic Ps, // the product's sign
output logic [$clog2(3*`NF+7)-1:0] FmaNormCntE // normalization shift cnt
);
logic [2*`NF+1:0] ProdManE; // 1.X frac * 1.Y frac in U(2.2Nf) format
logic [3*`NF+5:0] AlignedAddendE; // Z aligned for addition in U(NF+5.2NF+1)
logic [3*`NF+6:0] AlignedAddendInv; // aligned addend possibly inverted
logic [2*`NF+1:0] ProdManKilled; // the product's mantissa possibly killed
logic [2*`NF+1:0] Pm; // the product's significand in U(2.2Nf) format
logic [3*`NF+5:0] Am; // Z aligned for addition in U(NF+5.2NF+1)
logic [3*`NF+6:0] AmInv; // aligned addend possibly inverted
logic [2*`NF+1:0] PmKilled; // the product's mantissa possibly killed
logic [3*`NF+6:0] PreSum, NegPreSum; // positive and negitve versions of the sum
///////////////////////////////////////////////////////////////////////////////
// Calculate the product
@ -62,46 +62,40 @@ module fma(
// calculate the product's exponent
expadd expadd(.FmtE, .XExpE, .YExpE, .XZeroE, .YZeroE,
.ProdExpE);
expadd expadd(.FmtE, .Xe, .Ye, .XZeroE, .YZeroE, .Pe);
// multiplication of the mantissa's
mult mult(.XManE, .YManE, .ProdManE);
mult mult(.Xm, .Ym, .Pm);
///////////////////////////////////////////////////////////////////////////////
// Alignment shifter
///////////////////////////////////////////////////////////////////////////////
align align(.ZExpE, .ZManE, .XZeroE, .YZeroE, .ZZeroE, .ProdExpE, .XExpE, .YExpE,
.AlignedAddendE, .AddendStickyE, .KillProdE);
align align(.Ze, .Zm, .XZeroE, .YZeroE, .ZZeroE, .Xe, .Ye,
.Am, .AddendStickyE, .KillProdE);
// calculate the signs and take the opperation into account
sign sign(.FOpCtrlE, .XSgnE, .YSgnE, .ZSgnE, .PSgnE, .ZSgnEffE);
sign sign(.FOpCtrlE, .Xs, .Ys, .Zs, .Ps, .ZSgnEffE);
// ///////////////////////////////////////////////////////////////////////////////
// // Addition/LZA
// ///////////////////////////////////////////////////////////////////////////////
add add(.AlignedAddendE, .ProdManE, .PSgnE, .ZSgnEffE, .KillProdE, .AlignedAddendInv, .ProdManKilled, .NegSumE, .PreSum, .NegPreSum, .InvZE, .XZeroE, .YZeroE);
add add(.Am, .Pm, .Ps, .ZSgnEffE, .KillProdE, .AmInv, .PmKilled, .NegSumE, .PreSum, .NegPreSum, .InvA, .XZeroE, .YZeroE, .Sm);
loa loa(.A(AlignedAddendInv+{(3*`NF+6)'(0),InvZE}), .P(ProdManKilled), .FmaNormCntE);
// Choose the positive sum and accompanying LZA result.
assign SumE = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0];
loa loa(.A(AmInv+{(3*`NF+6)'(0),InvA}), .P(PmKilled), .FmaNormCntE);
endmodule
module expadd(
input logic [`FMTBITS-1:0] FmtE, // precision
input logic [`NE-1:0] XExpE, YExpE, // input exponents
input logic [`NE-1:0] Xe, Ye, // input exponents
input logic XZeroE, YZeroE, // are the inputs zero
output logic [`NE+1:0] ProdExpE // product's exponent B^(1023)NE+2
output logic [`NE+1:0] Pe // product's exponent B^(1023)NE+2
);
// kill the exponent if the product is zero - either X or Y is 0
assign ProdExpE = ({2'b0, XExpE} + {2'b0, YExpE} - {2'b0, (`NE)'(`BIAS)})&{`NE+2{~(XZeroE|YZeroE)}};
assign Pe = ({2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)})&{`NE+2{~(XZeroE|YZeroE)}};
endmodule
@ -110,10 +104,10 @@ endmodule
module mult(
input logic [`NF:0] XManE, YManE,
output logic [2*`NF+1:0] ProdManE
input logic [`NF:0] Xm, Ym,
output logic [2*`NF+1:0] Pm
);
assign ProdManE = XManE * YManE;
assign Pm = Xm * Ym;
endmodule
@ -125,8 +119,8 @@ endmodule
module sign(
input logic [2:0] FOpCtrlE, // precision
input logic XSgnE, YSgnE, ZSgnE, // are the inputs denormalized
output logic PSgnE, // the product's sign - takes opperation into account
input logic Xs, Ys, Zs, // are the inputs denormalized
output logic Ps, // the product's sign - takes opperation into account
output logic ZSgnEffE // Z sign used in fma - takes opperation into account
);
@ -134,9 +128,9 @@ module sign(
// Negate product's sign if FNMADD or FNMSUB
// flip is negation opperation
assign PSgnE = XSgnE ^ YSgnE ^ (FOpCtrlE[1]&~FOpCtrlE[2]);
assign Ps = Xs ^ Ys ^ (FOpCtrlE[1]&~FOpCtrlE[2]);
// flip if subtraction
assign ZSgnEffE = ZSgnE^FOpCtrlE[0];
assign ZSgnEffE = Zs^FOpCtrlE[0];
endmodule
@ -148,11 +142,10 @@ endmodule
module align(
input logic [`NE-1:0] XExpE, YExpE, ZExpE, // biased exponents in B(NE.0) format
input logic [`NF:0] ZManE, // fractions in U(0.NF) format]
input logic [`NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format
input logic [`NF:0] Zm, // fractions in U(0.NF) format]
input logic XZeroE, YZeroE, ZZeroE, // is the input zero
input logic [`NE+1:0] ProdExpE, // the product's exponent
output logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1)
output logic [3*`NF+5:0] Am, // Z aligned for addition in U(NF+5.2NF+1)
output logic AddendStickyE, // Sticky bit calculated from the aliged addend
output logic KillProdE // should the product be set to zero
);
@ -160,6 +153,7 @@ module align(
logic [`NE+1:0] AlignCnt; // how far to shift the addend to align with the product in Q(NE+2.0) format
logic [4*`NF+5:0] ZManShifted; // output of the alignment shifter including sticky bits U(NF+5.3NF+1)
logic [4*`NF+5:0] ZManPreShifted; // input to the alignment shifter U(NF+5.3NF+1)
logic KillZ;
///////////////////////////////////////////////////////////////////////////////
// Alignment shifter
@ -168,16 +162,19 @@ module align(
// determine the shift count for alignment
// - negitive means Z is larger, so shift Z left
// - positive means the product is larger, so shift Z right
// *** can we use ProdExpE instead of XExp/YExp to save an adder? DH 5/12/22
// KP- yes we used ProdExpE originally but we did this for timing
assign AlignCnt = XZeroE|YZeroE ? -(`NE+2)'($unsigned(1)) : {2'b0, XExpE} + {2'b0, YExpE} - {2'b0, (`NE)'(`BIAS)} + (`NE+2)'(`NF)+3 - {2'b0, ZExpE};
// This could have been done using Pe, but AlignCnt is on the critical path so we replicate logic for speed
assign AlignCnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)} + (`NE+2)'(`NF+3) - {2'b0, Ze};
// Defualt Addition without shifting
// | 54'b0 | 106'b(product) | 2'b0 |
// | addnend |
// the 1'b0 before the added is because the product's mantissa has two bits before the binary point (xx.xxxxxxxxxx...)
assign ZManPreShifted = {ZManE,(3*`NF+5)'(0)};
assign ZManPreShifted = {Zm,(3*`NF+5)'(0)};
assign KillProdE = AlignCnt[`NE+1]|XZeroE|YZeroE;
assign KillZ = $signed(AlignCnt)>$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(5));
always_comb
begin
@ -185,34 +182,31 @@ module align(
// | 54'b0 | 106'b(product) | 2'b0 |
// | addnend |
if ($signed(AlignCnt) < $signed((`NE+2)'(0))) begin
KillProdE = 1;
if (KillProdE) begin
ZManShifted = ZManPreShifted;
AddendStickyE = ~(XZeroE|YZeroE);
// If the Addend is shifted right
// | 54'b0 | 106'b(product) | 2'b0 |
// | addnend |
end else if ($signed(AlignCnt)<=$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(5))) begin
KillProdE = 0;
ZManShifted = ZManPreShifted >> AlignCnt;
AddendStickyE = |(ZManShifted[`NF-1:0]);
// If the addend is too small to effect the addition
// - The addend has to shift two past the end of the addend to be considered too small
// - The 2 extra bits are needed for rounding
// | 54'b0 | 106'b(product) | 2'b0 |
// | addnend |
end else begin
KillProdE = 0;
end else if (KillZ) begin
ZManShifted = 0;
AddendStickyE = ~ZZeroE;
// If the Addend is shifted right
// | 54'b0 | 106'b(product) | 2'b0 |
// | addnend |
end else begin
ZManShifted = ZManPreShifted >> AlignCnt;
AddendStickyE = |(ZManShifted[`NF-1:0]);
end
end
assign AlignedAddendE = ZManShifted[4*`NF+5:`NF];
assign Am = ZManShifted[4*`NF+5:`NF];
endmodule
@ -223,15 +217,16 @@ endmodule
module add(
input logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1)
input logic [2*`NF+1:0] ProdManE, // the product's mantissa
input logic PSgnE, ZSgnEffE,// the product and modified Z signs
input logic [3*`NF+5:0] Am, // Z aligned for addition in U(NF+5.2NF+1)
input logic [2*`NF+1:0] Pm, // the product's mantissa
input logic Ps, ZSgnEffE,// the product and modified Z signs
input logic KillProdE, // should the product be set to 0
input logic XZeroE, YZeroE, // is the input zero
output logic [3*`NF+6:0] AlignedAddendInv, // aligned addend possibly inverted
output logic [2*`NF+1:0] ProdManKilled, // the product's mantissa possibly killed
output logic [3*`NF+6:0] AmInv, // aligned addend possibly inverted
output logic [2*`NF+1:0] PmKilled, // the product's mantissa possibly killed
output logic NegSumE, // was the sum negitive
output logic InvZE, // do you invert Z
output logic InvA, // do you invert Z
output logic [3*`NF+5:0] Sm, // the positive sum
output logic [3*`NF+6:0] PreSum, NegPreSum// possibly negitive sum
);
@ -242,27 +237,29 @@ module add(
// Negate Z when doing one of the following opperations:
// -prod + Z
// prod - Z
assign InvZE = ZSgnEffE ^ PSgnE;
assign InvA = ZSgnEffE ^ Ps;
// Choose an inverted or non-inverted addend - the one has to be added now for the LZA
assign AlignedAddendInv = InvZE ? {1'b1, ~AlignedAddendE} : {1'b0, AlignedAddendE};
assign AmInv = InvA ? {1'b1, ~Am} : {1'b0, Am};
// Kill the product if the product is too small to effect the addition (determined in fma1.sv)
assign ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}};
assign PmKilled = Pm&{2*`NF+2{~KillProdE}};
// Do the addition
// - calculate a positive and negitive sum in parallel
assign PreSum = AlignedAddendInv + {{`NF+3{1'b0}}, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE};
assign NegPreSum = XZeroE|YZeroE|KillProdE ? {1'b0, AlignedAddendE} : {1'b0, AlignedAddendE} + {{`NF+3{1'b1}}, ~ProdManKilled, 2'b0} + {(3*`NF+7)'(4)};
assign PreSum = {{`NF+3{1'b0}}, PmKilled, 2'b0} + AmInv + {{3*`NF+6{1'b0}}, InvA};
assign NegPreSum = {1'b0, Am} + {{`NF+3{1'b1}}, ~PmKilled, 2'b0} + {(3*`NF+7)'(4)};
// Is the sum negitive
assign NegSumE = PreSum[3*`NF+6];
// Choose the positive sum and accompanying LZA result.
assign Sm = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0];
endmodule
module loa( //https://ieeexplore.ieee.org/abstract/document/930098
module loa( // [Schmookler & Nowka, Leading zero anticipation and detection, IEEE Sym. Computer Arithmetic, 2001]
input logic [3*`NF+6:0] A, // addend
input logic [2*`NF+1:0] P, // product
output logic [$clog2(3*`NF+7)-1:0] FmaNormCntE // normalization shift count for the positive result

View File

@ -27,7 +27,7 @@ module fmashiftcalc(
// calculate the sum's exponent
assign NormSumExp = KillProdM ? {2'b0, ZExpM[`NE-1:1], ZExpM[0]&~ZDenormM} : ProdExpM + -{{`NE+2-$unsigned($clog2(3*`NF+7)){1'b0}}, FmaNormCntM} - 1 + (`NE+2)'(`NF+4);
//convert the sum's exponent into the propper percision
//convert the sum's exponent into the proper percision
if (`FPSIZES == 1) begin
assign ConvNormSumExp = NormSumExp;
@ -105,7 +105,7 @@ module fmashiftcalc(
2'h1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero;
2'h0: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero;
2'h2: PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero;
endcase
endcase // *** remove checking to see if it's underflowed and only check for less than zero for denorm checking
end
end

View File

@ -110,7 +110,7 @@ module fpu (
logic [`NE+1:0] ProdExpE, ProdExpM;
logic AddendStickyE, AddendStickyM;
logic KillProdE, KillProdM;
logic InvZE, InvZM;
logic InvAE, InvAM;
logic NegSumE, NegSumM;
logic ZSgnEffE, ZSgnEffM;
logic PSgnE, PSgnM;
@ -249,10 +249,10 @@ module fpu (
.XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, .XExpMaxE);
// fma - does multiply, add, and multiply-add instructions
fma fma (.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE,
.XManE, .YManE, .ZManE, .XZeroE, .YZeroE, .ZZeroE,
.FOpCtrlE, .FmtE, .SumE, .NegSumE, .InvZE, .FmaNormCntE,
.ZSgnEffE, .PSgnE, .ProdExpE, .AddendStickyE, .KillProdE);
fma fma (.Xs(XSgnE), .Ys(YSgnE), .Zs(ZSgnE), .Xe(XExpE), .Ye(YExpE), .Ze(ZExpE),
.Xm(XManE), .Ym(YManE), .Zm(ZManE), .XZeroE, .YZeroE, .ZZeroE,
.FOpCtrlE, .FmtE, .Sm(SumE), .NegSumE, .InvA(InvAE), .FmaNormCntE,
.ZSgnEffE, .Ps(PSgnE), .Pe(ProdExpE), .AddendStickyE, .KillProdE);
// fpdivsqrt using Goldschmidt's iteration
if(`FLEN == 64) begin
@ -351,8 +351,8 @@ module fpu (
flopenrc #(3*`NF+6) EMRegFma2(clk, reset, FlushM, ~StallM, SumE, SumM);
flopenrc #(`NE+2) EMRegFma3(clk, reset, FlushM, ~StallM, ProdExpE, ProdExpM);
flopenrc #($clog2(3*`NF+7)+6) EMRegFma4(clk, reset, FlushM, ~StallM,
{AddendStickyE, KillProdE, InvZE, FmaNormCntE, NegSumE, ZSgnEffE, PSgnE},
{AddendStickyM, KillProdM, InvZM, FmaNormCntM, NegSumM, ZSgnEffM, PSgnM});
{AddendStickyE, KillProdE, InvAE, FmaNormCntE, NegSumE, ZSgnEffE, PSgnE},
{AddendStickyM, KillProdM, InvAM, FmaNormCntM, NegSumM, ZSgnEffM, PSgnM});
flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM,
{CvtCalcExpE, CvtShiftAmtE, CvtResDenormUfE, CvtResSgnE, IntZeroE, CvtLzcInE},
{CvtCalcExpM, CvtShiftAmtM, CvtResDenormUfM, CvtResSgnM, IntZeroM, CvtLzcInM});
@ -374,7 +374,7 @@ module fpu (
postprocess postprocess(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, .FrmM, .FmtM, .ProdExpM, .EarlyTermShiftDiv2M,
.AddendStickyM, .KillProdM, .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .Quot,
.ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .SumM, .DivCalcExpM,
.NegSumM, .InvZM, .ZDenormM, .ZSgnEffM, .PSgnM, .FOpCtrlM, .FmaNormCntM, .DivNegStickyM,
.NegSumM, .InvZM(InvAM), .ZDenormM, .ZSgnEffM, .PSgnM, .FOpCtrlM, .FmaNormCntM, .DivNegStickyM,
.CvtCalcExpM, .CvtResDenormUfM,.CvtShiftAmtM, .CvtResSgnM, .FWriteIntM, .DivStickyM,
.CvtLzcInM, .IntZeroM, .PostProcSelM, .PostProcResM, .PostProcFlgM, .FCvtIntResM);

View File

@ -0,0 +1,20 @@
`include "wally-config.vh"
module negateintres(
input logic XSgnM,
input logic [`NORMSHIFTSZ-1:0] Shifted,
input logic Signed,
input logic Int64,
input logic Plus1,
output logic [1:0] NegResMSBS,
output logic [`XLEN+1:0] NegRes
);
// round and negate the positive res if needed
assign NegRes = XSgnM ? -({2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}) : {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1};
assign NegResMSBS = Signed ? Int64 ? NegRes[`XLEN:`XLEN-1] : NegRes[32:31] :
Int64 ? NegRes[`XLEN+1:`XLEN] : NegRes[33:32];
endmodule

View File

@ -109,6 +109,7 @@ module postprocess(
// conversion signals
logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted
logic [1:0] NegResMSBS;
logic [`XLEN+1:0] NegRes;
logic CvtResUf;
// readability signals
logic Mult; // multiply opperation
@ -166,7 +167,7 @@ module postprocess(
ShiftAmt = {{$clog2(`NORMSHIFTSZ)-$clog2(`CVTLEN+1){1'b0}}, CvtShiftAmtM};
ShiftIn = {CvtShiftIn, {`NORMSHIFTSZ-`CVTLEN-`NF-1{1'b0}}};
end
2'b01: begin //div ***prob can take out
2'b01: begin //div
ShiftAmt = DivShiftAmt;
ShiftIn = DivShiftIn;
end
@ -201,9 +202,11 @@ module postprocess(
// Sign calculation
///////////////////////////////////////////////////////////////////////////////
resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .InvZM, .SumExp, .Round, .Sticky,
.FmaOp, .DivOp, .CvtOp, .ZInfM, .InfIn, .NegSumM, .SumZero, .Mult,
.XSgnM, .YSgnM, .CvtResSgnM, .RoundSgn, .ResSgn);
resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .SumExp, .Round, .Sticky,
.FmaOp, .ZInfM, .InfIn, .SumZero, .Mult, .RoundSgn, .ResSgn);
roundsign roundsign(.PSgnM, .ZSgnEffM, .InvZM, .FmaOp, .DivOp, .CvtOp, .NegSumM,
.XSgnM, .YSgnM, .CvtResSgnM, .RoundSgn);
///////////////////////////////////////////////////////////////////////////////
// Flags
@ -219,10 +222,11 @@ module postprocess(
// Select the result
///////////////////////////////////////////////////////////////////////////////
resultselect resultselect(.XSgnM, .ZExpM, .XManM, .YManM, .ZManM, .ZDenormM, .ZZeroM, .XZeroM, .IntInvalid,
.IntZeroM, .FrmM, .OutFmt, .AddendStickyM, .KillProdM, .XNaNM, .YNaNM, .ZNaNM, .RoundAdd, .CvtResUf,
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .NegResMSBS,
negateintres negateintres(.XSgnM, .Shifted, .Signed, .Int64, .Plus1, .NegResMSBS, .NegRes);
resultselect resultselect(.XSgnM, .XManM, .YManM, .ZManM, .XZeroM, .IntInvalid,
.IntZeroM, .FrmM, .OutFmt, .XNaNM, .YNaNM, .ZNaNM, .CvtResUf,
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .NegRes,
.XInfM, .YInfM, .DivOp,
.DivByZero, .FullResExp, .Shifted, .CvtCalcExpM, .ResSgn, .ResExp, .ResFrac, .PostProcResM, .FCvtIntResM);
.DivByZero, .FullResExp, .CvtCalcExpM, .ResSgn, .ResExp, .ResFrac, .PostProcResM, .FCvtIntResM);
endmodule

View File

@ -1,45 +1,38 @@
`include "wally-config.vh"
module resultselect(
input logic XSgnM, // input signs
input logic [`NE-1:0] ZExpM, // input exponents
input logic [`NF:0] XManM, YManM, ZManM, // input mantissas
input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
input logic [`FMTBITS-1:0] OutFmt, // output format
input logic InfIn,
input logic XInfM, YInfM,
input logic XZeroM, ZZeroM,
input logic IntZeroM,
input logic NaNIn,
input logic IntToFp,
input logic Int64,
input logic Signed,
input logic CvtOp,
input logic DivOp,
input logic FmaOp,
input logic [`NORMSHIFTSZ-1:0] Shifted, // is the sum zero
input logic Plus1,
input logic DivByZero,
input logic [`NE:0] CvtCalcExpM, // the calculated expoent
input logic AddendStickyM, // sticky bit that is calculated during alignment
input logic KillProdM, // set the product to zero before addition if the product is too small to matter
input logic ZDenormM, // is the original precision denormalized
input logic ResSgn, // the res's sign
input logic [`FLEN:0] RoundAdd, // how much to add to the res
input logic IntInvalid, Invalid, Overflow, // flags
input logic CvtResUf,
input logic [`NE-1:0] ResExp, // Res exponent
input logic [`NE+1:0] FullResExp, // Res exponent
input logic [`NF-1:0] ResFrac, // Res fraction
output logic [`FLEN-1:0] PostProcResM, // final res
output logic [1:0] NegResMSBS,
output logic [`XLEN-1:0] FCvtIntResM // final res
input logic XSgnM, // input signs
input logic [`NF:0] XManM, YManM, ZManM, // input mantissas
input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
input logic [`FMTBITS-1:0] OutFmt, // output format
input logic InfIn,
input logic XInfM, YInfM,
input logic XZeroM,
input logic IntZeroM,
input logic NaNIn,
input logic IntToFp,
input logic Int64,
input logic Signed,
input logic CvtOp,
input logic DivOp,
input logic FmaOp,
input logic Plus1,
input logic DivByZero,
input logic [`NE:0] CvtCalcExpM, // the calculated expoent
input logic ResSgn, // the res's sign
input logic IntInvalid, Invalid, Overflow, // flags
input logic CvtResUf,
input logic [`NE-1:0] ResExp, // Res exponent
input logic [`NE+1:0] FullResExp, // Res exponent
input logic [`NF-1:0] ResFrac, // Res fraction
input logic [`XLEN+1:0] NegRes, // the negation of the result
output logic [`FLEN-1:0] PostProcResM, // final res
output logic [`XLEN-1:0] FCvtIntResM // final res
);
logic [`FLEN-1:0] XNaNRes, YNaNRes, ZNaNRes, InvalidRes, OfRes, UfRes, NormRes; // possible results
logic OfResMax;
logic [`XLEN-1:0] OfIntRes; // the overflow result for integer output
logic [`XLEN+1:0] NegRes; // the negation of the result
logic KillRes;
logic SelOfRes;
@ -244,7 +237,7 @@ module resultselect(
// signed | -2^31 | -2^63 |
// unsigned | 0 | 0 |
//
// - positive infinity and out of range negitive input and NaNs
// - positive infinity and out of range positive input and NaNs
// | int | long |
// signed | 2^31-1 | 2^63-1 |
// unsigned | 2^32-1 | 2^64-1 |
@ -254,13 +247,7 @@ module resultselect(
Int64 ? {1'b0, {`XLEN-1{1'b1}}} : {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}} : // signed positive
XSgnM&~XNaNM ? {`XLEN{1'b0}} : // unsigned negitive
{`XLEN{1'b1}};// unsigned positive
// round and negate the positive res if needed
assign NegRes = XSgnM ? -({2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}) : {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1};
//*** false critical path probably
assign NegResMSBS = Signed ? Int64 ? NegRes[`XLEN:`XLEN-1] : NegRes[32:31] :
Int64 ? NegRes[`XLEN+1:`XLEN] : NegRes[33:32];
// select the integer output
// - if the input is invalid (out of bounds NaN or Inf) then output overflow res

View File

@ -3,31 +3,21 @@
module resultsign(
input logic [2:0] FrmM,
input logic PSgnM, ZSgnEffM,
input logic InvZM,
input logic XSgnM,
input logic YSgnM,
input logic ZInfM,
input logic InfIn,
input logic NegSumM,
input logic FmaOp,
input logic DivOp,
input logic CvtOp,
input logic [`NE+1:0] SumExp,
input logic SumZero,
input logic Mult,
input logic Round,
input logic Sticky,
input logic CvtResSgnM,
output logic RoundSgn,
input logic RoundSgn,
output logic ResSgn
);
logic ZeroSgn;
logic InfSgn;
logic FmaResSgn;
logic FmaResSgnTmp;
logic Underflow;
logic DivSgn;
// logic ResultSgnTmp;
// Determine the sign if the sum is zero
@ -42,14 +32,7 @@ module resultsign(
// if p - z is the Sum negitive
// if -p + z is the Sum positive
// if -p - z then the Sum is negitive
assign FmaResSgnTmp = InvZM&(ZSgnEffM)&NegSumM | InvZM&PSgnM&~NegSumM | (ZSgnEffM&PSgnM);
assign InfSgn = ZInfM ? ZSgnEffM : PSgnM;
assign FmaResSgn = InfIn ? InfSgn : SumZero ? ZeroSgn : FmaResSgnTmp;
assign DivSgn = XSgnM^YSgnM;
// Sign for rounding calulation
assign RoundSgn = (FmaResSgnTmp&FmaOp) | (CvtResSgnM&CvtOp) | (DivSgn&DivOp);
assign ResSgn = (FmaResSgn&FmaOp) | (CvtResSgnM&CvtOp) | (DivSgn&DivOp);
assign ResSgn = InfIn&FmaOp ? InfSgn : SumZero&FmaOp ? ZeroSgn : RoundSgn;
endmodule

View File

@ -0,0 +1,32 @@
`include "wally-config.vh"
module roundsign(
input logic PSgnM, ZSgnEffM,
input logic InvZM,
input logic XSgnM,
input logic YSgnM,
input logic NegSumM,
input logic FmaOp,
input logic DivOp,
input logic CvtOp,
input logic CvtResSgnM,
output logic RoundSgn
);
logic FmaResSgnTmp;
logic DivSgn;
// is the result negitive
// if p - z is the Sum negitive
// if -p + z is the Sum positive
// if -p - z then the Sum is negitive
assign FmaResSgnTmp = NegSumM^PSgnM; //*** move to execute stage
// assign FmaResSgnTmp = InvZM&(ZSgnEffM)&NegSumM | InvZM&PSgnM&~NegSumM | (ZSgnEffM&PSgnM);
assign DivSgn = XSgnM^YSgnM;
// Sign for rounding calulation
assign RoundSgn = (FmaResSgnTmp&FmaOp) | (CvtResSgnM&CvtOp) | (DivSgn&DivOp);
endmodule

View File

@ -4,12 +4,14 @@ module lzc #(parameter WIDTH = 1) (
output logic [$clog2(WIDTH+1)-1:0] ZeroCnt
);
/* verilator lint_off CMPCONST */
/* verilator lint_off WIDTH */
logic [$clog2(WIDTH+1)-1:0] i;
int i;
always_comb begin
i = 0;
while (~num[WIDTH-1-(32)'(i)] & $unsigned(i) <= $unsigned(($clog2(WIDTH+1))'(WIDTH-1))) i = i+1; // search for leading one
while (~num[WIDTH-1-i] & (i < WIDTH)) i = i+1; // search for leading one
ZeroCnt = i;
end
/* verilator lint_on WIDTH */
/* verilator lint_on CMPCONST */
endmodule

View File

@ -39,9 +39,11 @@ module priorityonehot #(parameter N = 8) (
input logic [N-1:0] a,
output logic [N-1:0] y
);
logic [N-1:0] nolower;
// create thermometer code mask
prioritythermometer #(N) maskgen(.a({a[N-2:0], 1'b0}), .y(nolower));
assign y = a & nolower;
genvar i;
assign y[0] = a[0];
for (i=1; i<N; i++) begin:poh
assign y[i] = a[i] & ~|a[i-1:0];
end
endmodule

View File

@ -77,6 +77,8 @@ module lsu (
(* mark_debug = "true" *) output logic [2:0] LSUBurstType,
(* mark_debug = "true" *) output logic [1:0] LSUTransType,
(* mark_debug = "true" *) output logic LSUTransComplete,
output logic [(`XLEN-1)/8:0] ByteMaskM,
// page table walker
input logic [`XLEN-1:0] SATP_REGW, // from csr
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
@ -112,7 +114,6 @@ module lsu (
logic LSUBusWriteCrit;
logic DataDAPageFaultM;
logic [`XLEN-1:0] LSUWriteDataM;
logic [(`XLEN-1)/8:0] ByteMaskM;
logic [`XLEN-1:0] WriteDataM;
logic [`LLEN-1:0] ReadDataM;
@ -268,10 +269,10 @@ module lsu (
/////////////////////////////////////////////////////////////////////////////////////////////
// Subword Accesses
/////////////////////////////////////////////////////////////////////////////////////////////
subwordwrite subwordwrite(.LSUPAdrM(LSUPAdrM[2:0]),
.LSUFunct3M, .AMOWriteDataM, .LittleEndianWriteDataM, .ByteMaskM);
subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]),
.FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM);
subwordwrite subwordwrite(.LSUPAdrM(LSUPAdrM[2:0]),
.LSUFunct3M, .AMOWriteDataM, .LittleEndianWriteDataM, .ByteMaskM);
/////////////////////////////////////////////////////////////////////////////////////////////
// MW Pipeline Register

View File

@ -39,7 +39,6 @@ module pmpadrdec (
input logic [7:0] PMPCfg,
input logic [`XLEN-1:0] PMPAdr,
input logic PAgePMPAdrIn,
input logic FirstMatch,
output logic PAgePMPAdrOut,
output logic Match, Active,
output logic L, X, W, R
@ -83,10 +82,10 @@ module pmpadrdec (
(AdrMode == NA4 | AdrMode == NAPOT) ? NAMatch :
0;
assign L = PMPCfg[7] & FirstMatch;
assign X = PMPCfg[2] & FirstMatch;
assign W = PMPCfg[1] & FirstMatch;
assign R = PMPCfg[0] & FirstMatch;
assign L = PMPCfg[7];
assign X = PMPCfg[2];
assign W = PMPCfg[1];
assign R = PMPCfg[0];
assign Active = |PMPCfg[4:3];
endmodule

View File

@ -67,16 +67,16 @@ module pmpchecker (
.PMPAdr(PMPADDR_ARRAY_REGW),
.PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
.PAgePMPAdrOut(PAgePMPAdr),
.FirstMatch, .Match, .Active, .L, .X, .W, .R);
.Match, .Active, .L, .X, .W, .R);
priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
// Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L : |Active;
assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active;
assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|X;
assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|W;
assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~|R;
assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;
assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ;
assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~|(R & FirstMatch) ;
end else begin: pmpchecker // no checker
assign PMPInstrAccessFaultF = 0;
assign PMPLoadAccessFaultM = 0;

View File

@ -34,9 +34,11 @@ module ahbapbbridge #(PERIPHS = 2) (
input logic [PERIPHS-1:0] HSEL,
input logic [31:0] HADDR,
input logic [`XLEN-1:0] HWDATA,
input logic [`XLEN/8-1:0] HWSTRB,
input logic HWRITE,
input logic [1:0] HTRANS,
input logic HREADY,
// input logic [3:0] HPROT, // not used
output logic [`XLEN-1:0] HRDATA,
output logic HRESP, HREADYOUT,
output logic PCLK, PRESETn,
@ -45,30 +47,37 @@ module ahbapbbridge #(PERIPHS = 2) (
output logic PENABLE,
output logic [31:0] PADDR,
output logic [`XLEN-1:0] PWDATA,
// output logic [2:0] PPROT, // not used
output logic [`XLEN/8-1:0] PSTRB,
// output logic PWAKEUP // not used
input logic [PERIPHS-1:0] PREADY,
input var [`XLEN-1:0][PERIPHS-1:0] PRDATA
input var [PERIPHS-1:0][`XLEN-1:0] PRDATA
);
logic activeTrans;
logic initTrans, initTransSel, initTransSelD;
logic nextPENABLE;
logic PREADYOUT;
// convert AHB to APB signals
assign PCLK = HCLK;
assign PRESETn = HRESETn;
// identify start of a transaction
assign activeTrans = (HTRANS == 2'b10); // only accept nonsequential transactions
assign initTrans = activeTrans & HREADY; // start a transaction when the bus is ready and an active transaction is requested
assign initTrans = HTRANS[1] & HREADY; // start a transaction when the bus is ready and an active transaction is requested
assign initTransSel = initTrans & |HSEL; // capture data and address if any of the peripherals are selected
// delay AHB Address phase signals to align with AHB Data phase because APB expects them at the same time
flopenr #(32) addrreg(HCLK, ~HRESETn, initTransSel, HADDR, PADDR);
flopenr #(1) writereg(HCLK, ~HRESETn, initTransSel, HWRITE, PWRITE);
// enable selreg with iniTrans rather than initTransSel so PSEL can turn off
flopenr #(PERIPHS) selreg(HCLK, ~HRESETn, initTrans, HSEL & {PERIPHS{activeTrans}}, PSEL);
// AHB Data phase signal doesn't need delay. Note that HWDATA is guaranteed to remain stable until READY is asserted
flopen #(32) addrreg(HCLK, HREADY, HADDR, PADDR);
flopenr #(1) writereg(HCLK, ~HRESETn, HREADY, HWRITE, PWRITE);
flopenr #(PERIPHS) selreg(HCLK, ~HRESETn, HREADY, HSEL & {PERIPHS{initTrans}}, PSEL);
// PPROT[2:0] = {Data/InstrB, Secure, Privileged};
// assign PPROT = {~HPROT[0], 1'b0, HPROT[1]}; // protection not presently used
// assign PWAKEUP = 1'b1; // not used
// AHB Data phase signal doesn't need delay. Note that they are guaranteed to remain stable until READY is asserted
assign PWDATA = HWDATA;
assign PSTRB = HWSTRB;
// enable logic: goes high a cycle after initTrans, then back low on cycle after desired PREADY is asserted
// cycle1: AHB puts HADDR, HWRITE, HSEL on bus. initTrans is 1, and these are captured
@ -81,16 +90,19 @@ module ahbapbbridge #(PERIPHS = 2) (
// result and ready multiplexer
int i;
always_comb
always_comb begin
// default: no peripheral selected: read 0, indicate ready during access phase so bus doesn't hang
// *** also could assert ready right away
HRDATA = 0;
PREADYOUT = 1'b1;
for (i=0; i<PERIPHS; i++) begin
// no peripheral selected: read 0, indicate ready
HRDATA = 0;
HREADYOUT = 1;
if (PSEL[i]) begin // highest numbered peripheral has priority, but multiple PSEL should never be asserted
HRDATA = PRDATA[i];
HREADYOUT = PREADY[i];
PREADYOUT = PREADY[i];
end
end
end
assign HREADYOUT = PREADYOUT & ~initTransSelD; // don't raise HREADYOUT before access phase
// resp logic
assign HRESP = 0; // bridge never indicates errors

View File

@ -28,7 +28,7 @@
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////
/*
`include "wally-config.vh"
module clint (
@ -258,3 +258,4 @@ module graytobinary #(parameter N = `XLEN) (
assign b[i] = g[i] ^ b[i+1];
end
endmodule
*/

View File

@ -0,0 +1,252 @@
///////////////////////////////////////////
// clint_apb.sv
//
// Written: David_Harris@hmc.edu 14 January 2021
// Modified:
//
// Purpose: Core-Local Interruptor
// See FE310-G002-Manual-v19p05 for specifications
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// MIT LICENSE
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module clint_apb (
input logic PCLK, PRESETn,
input logic PSEL,
input logic [15:0] PADDR,
input logic [`XLEN-1:0] PWDATA,
input logic [`XLEN/8-1:0] PSTRB,
input logic PWRITE,
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic PREADY,
(* mark_debug = "true" *) output logic [63:0] MTIME,
output logic MTimerInt, MSwInt);
logic MSIP;
logic [15:0] entry;
logic memwrite;
(* mark_debug = "true" *) logic [63:0] MTIMECMP;
integer i, j;
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign PREADY = 1'b1; // GPIO never takes >1 cycle to respond
// word aligned reads
if (`XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000};
else assign #2 entry = {PADDR[15:2], 2'b00};
//swbytemask swbytemask(.Size(HSIZED[1:0]), .Adr(entry[2:0]), .ByteMask(PSTRB));
// DH 2/20/21: Eventually allow MTIME to run off a separate clock
// This will require synchronizing MTIME to the system clock
// before it is read or compared to MTIMECMP.
// It will also require synchronizing the write to MTIMECMP.
// Use req and ack signals synchronized across the clock domains.
// register access
if (`XLEN==64) begin:clint // 64-bit
always @(posedge PCLK) begin
case(entry)
16'h0000: PRDATA <= {63'b0, MSIP};
16'h4000: PRDATA <= MTIMECMP;
16'hBFF8: PRDATA <= MTIME;
default: PRDATA <= 0;
endcase
end
always_ff @(posedge PCLK or negedge PRESETn)
if (~PRESETn) begin
MSIP <= 0;
MTIMECMP <= 64'hFFFFFFFFFFFFFFFF; // Spec says MTIMECMP is not reset, but we reset to maximum value to prevent spurious timer interrupts
end else if (memwrite) begin
if (entry == 16'h0000) MSIP <= PWDATA[0];
if (entry == 16'h4000) begin
for(i=0;i<`XLEN/8;i++)
if(PSTRB[i])
MTIMECMP[i*8 +: 8] <= PWDATA[i*8 +: 8]; // ***dh: this notation isn't in book yet - maybe from Ross
end
end
// eventually replace MTIME logic below with timereg
// timereg tr(PCLK, PRESETn, TIMECLK, memwrite & (entry==16'hBFF8), 1'b0, PWDATA, MTIME, done);
always_ff @(posedge PCLK or negedge PRESETn)
if (~PRESETn) begin
MTIME <= 0;
end else if (memwrite & entry == 16'hBFF8) begin
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
for(j=0;j<`XLEN/8;j++)
if(PSTRB[j])
MTIME[j*8 +: 8] <= PWDATA[j*8 +: 8];
end else MTIME <= MTIME + 1;
end else begin:clint // 32-bit
always @(posedge PCLK) begin
case(entry)
16'h0000: PRDATA <= {31'b0, MSIP};
16'h4000: PRDATA <= MTIMECMP[31:0];
16'h4004: PRDATA <= MTIMECMP[63:32];
16'hBFF8: PRDATA <= MTIME[31:0];
16'hBFFC: PRDATA <= MTIME[63:32];
default: PRDATA <= 0;
endcase
end
always_ff @(posedge PCLK or negedge PRESETn)
if (~PRESETn) begin
MSIP <= 0;
MTIMECMP <= 0;
// MTIMECMP is not reset ***?
end else if (memwrite) begin
if (entry == 16'h0000) MSIP <= PWDATA[0];
if (entry == 16'h4000)
for(j=0;j<`XLEN/8;j++)
if(PSTRB[j])
MTIMECMP[j*8 +: 8] <= PWDATA[j*8 +: 8];
if (entry == 16'h4004)
for(j=0;j<`XLEN/8;j++)
if(PSTRB[j])
MTIMECMP[32 + j*8 +: 8] <= PWDATA[j*8 +: 8];
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
end
// eventually replace MTIME logic below with timereg
// timereg tr(PCLK, PRESETn, TIMECLK, memwrite & (entry==16'hBFF8), memwrite & (entry == 16'hBFFC), PWDATA, MTIME, done);
always_ff @(posedge PCLK or negedge PRESETn)
if (~PRESETn) begin
MTIME <= 0;
// MTIMECMP is not reset
end else if (memwrite & (entry == 16'hBFF8)) begin
for(i=0;i<`XLEN/8;i++)
if(PSTRB[i])
MTIME[i*8 +: 8] <= PWDATA[i*8 +: 8];
end else if (memwrite & (entry == 16'hBFFC)) begin
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
for(i=0;i<`XLEN/8;i++)
if(PSTRB[i])
MTIME[32 + i*8 +: 8]<= PWDATA[i*8 +: 8];
end else MTIME <= MTIME + 1;
end
// Software interrupt when MSIP is set
assign MSwInt = MSIP;
// Timer interrupt when MTIME >= MTIMECMP
assign MTimerInt = ({1'b0, MTIME} >= {1'b0, MTIMECMP}); // unsigned comparison
endmodule
module timeregsync(
input logic clk, resetn,
input logic we0, we1,
input logic [`XLEN-1:0] wd,
output logic [63:0] q);
if (`XLEN==64)
always_ff @(posedge clk or negedge resetn)
if (~resetn) q <= 0;
else if (we0) q <= wd;
else q <= q + 1;
else
always_ff @(posedge clk or negedge resetn)
if (~resetn) q <= 0;
else if (we0) q[31:0] <= wd;
else if (we1) q[63:32] <= wd;
else q <= q + 1;
endmodule
module timereg(
input logic PCLK, PRESETn, TIMECLK,
input logic we0, we1,
input logic [`XLEN-1:0] PWDATA,
output logic [63:0] MTIME,
output logic done);
// if (`TIMEBASE_SYNC) begin:timereg // use PCLK for MTIME
if (1) begin:timereg // use PCLK for MTIME
timregsync timeregsync(.clk(PCLK), .resetn(PRESETn), .we0, .we1, .wd(PWDATA), .q(MTIME));
assign done = 1; // immediately completes
end else begin // use asynchronous TIMECLK
// TIME counter runs on TIMECLK but bus interface runs on PCLK
// Need to synchronize reads and writes
// This is subtle because synchronizing a binary counter on a per-bit basis could give a mix of old and new bits
// Instead, we use a Gray coded counter that only changes one bit per cycle
// Synchronizing this for a read is safe because we are guaranteed to get either the old or the new value.
// Writing to the counter requires a request/acknowledge handshake to ensure the write value is held long enough.
// The handshake signals are synchronized in each direction across the interface
// There is no back pressure on instructions, so if multiple counter writes occur ***
logic req, req_sync, ack, we0_stored, we1_stored, ack_stored, resetn_sync;
logic [`XLEN-1:0] wd_stored;
logic [63:0] time_int, time_int_gc, time_gc, MTIME_GC;
// When a write enable is asserted for a cycle, sample the enables and data and raise a request until it is acknowledged
// When the acknowledge falls, the transaction is done and the system is ready for another write.
// ***look at redoing this assuming write enable and data are held rather than pulsed.
always_ff @(posedge PCLK or negedge PRESETn)
if (~PRESETn)
req <= 0; // don't bother resetting wd
else begin
req <= we0 | we1 | req & ~ack;
we0_stored <= we0;
we1_stored <= we1;
wd_stored <= PWDATA;
ack_stored <= ack;
done <= ack_stored & ~ack;
end
// synchronize the reset and reqest into the TIMECLK domain
sync resetsync(TIMECLK, PRESETn, resetn_sync);
sync rsync(TIMECLK, req, req_sync);
// synchronize the acknowledge back to the PCLK domain to indicate the request was handled and can be lowered
sync async(PCLK, req_sync, ack);
timeregsync timeregsync(.clk(TIMECLK), .resetn(resetn_sync), .we0(we0_stored), .we1(we1_stored), .wd(wd_stored), .q(time_int));
binarytogray b2g(time_int, time_int_gc);
flop gcreg(TIMECLK, time_int_gc, time_gc);
sync timesync[63:0](PCLK, time_gc, MTIME_GC);
graytobinary g2b(MTIME_GC, MTIME);
end
endmodule
module binarytogray #(parameter N = `XLEN) (
input logic [N-1:0] b,
output logic [N-1:0] g);
// G[N-1] = B[N-1]; G[i] = B[i] ^ B[i+1] for 0 <= i < N-1
// requires single layer of N-1 XOR gates
assign g = b ^ {1'b0, b[N-1:1]};
endmodule
module graytobinary #(parameter N = `XLEN) (
input logic [N-1:0] g,
output logic [N-1:0] b);
// B[N-1] = G[N-1]; B[i] = G[i] ^ B[i+1] for 0 <= i < N-1
// requires rippling through N-1 XOR gates
genvar i;
assign b[N-1] = g[N-1];
for (i=N-2; i >= 0; i--) begin:g2b
assign b[i] = g[i] ^ b[i+1];
end
endmodule

View File

@ -37,10 +37,12 @@ module gpio_apb (
input logic PSEL,
input logic [7:0] PADDR,
input logic [`XLEN-1:0] PWDATA,
input logic [`XLEN/8-1:0] PSTRB,
input logic PWRITE,
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic PREADY,
input logic [31:0] iof0, iof1,
input logic [31:0] GPIOPinsIn,
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
output logic GPIOIntr);
@ -48,6 +50,7 @@ module gpio_apb (
logic [31:0] input0d, input1d, input2d, input3d;
logic [31:0] input_val, input_en, output_en, output_val;
logic [31:0] rise_ie, rise_ip, fall_ie, fall_ip, high_ie, high_ip, low_ie, low_ip;
logic [31:0] out_xor, iof_en, iof_sel, iof_out, gpio_out;
logic [7:0] entry;
logic [31:0] Din, Dout;
@ -55,8 +58,8 @@ module gpio_apb (
// APB I/O
assign entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses
assign memwrite = PWRITE & PENABLE; // only write in access phase
assign PREADY = PENABLE; // GPIO never takes >1 cycle to respond
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign PREADY = 1'b1; // GPIO never takes >1 cycle to respond
// account for subword read/write circuitry
// -- Note GPIO registers are 32 bits no matter what; access them with LW SW.
@ -84,6 +87,9 @@ module gpio_apb (
high_ip <= #1 0;
low_ie <= #1 0;
low_ip <= #1 0;
iof_en <= #1 0;
iof_sel <= #1 0;
out_xor <= #1 0;
end else begin // writes
// According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit.
/* verilator lint_off CASEINCOMPLETE */
@ -96,7 +102,9 @@ module gpio_apb (
8'h20: fall_ie <= #1 Din;
8'h28: high_ie <= #1 Din;
8'h30: low_ie <= #1 Din;
8'h40: output_val <= #1 output_val ^ Din; // OUT_XOR
8'h38: iof_en <= #1 Din;
8'h3C: iof_sel <= #1 Din;
8'h40: out_xor <= #1 Din;
endcase
/* verilator lint_on CASEINCOMPLETE */
@ -123,7 +131,9 @@ module gpio_apb (
8'h2C: Dout <= #1 high_ip;
8'h30: Dout <= #1 low_ie;
8'h34: Dout <= #1 low_ip;
8'h40: Dout <= #1 0; // OUT_XOR reads as 0
8'h38: Dout <= #1 iof_en;
8'h3C: Dout <= #1 iof_sel;
8'h40: Dout <= #1 out_xor;
default: Dout <= #1 0;
endcase
end
@ -138,7 +148,9 @@ module gpio_apb (
flop #(32) sync2(PCLK,input1d,input2d);
flop #(32) sync3(PCLK,input2d,input3d);
assign input_val = input3d;
assign GPIOPinsOut = output_val;
assign iof_out = iof_sel & iof1 | ~iof_sel & iof0; // per-bit mux between iof1 and iof0
assign gpio_out = iof_en & iof_out | ~iof_en & output_val; // per-bit mux between IOF and output_val
assign GPIOPinsOut = gpio_out ^ out_xor; // per-bit flip output polarity
assign GPIOPinsEn = output_en;
assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)};

View File

@ -176,8 +176,8 @@ module plic (
end
// pending interrupt requests
//assign nextIntPending = (intPending | requests) & ~intInProgress;
assign nextIntPending = requests;
//assign nextIntPending = (intPending | requests) & ~intInProgress; //
assign nextIntPending = requests; // DH: RT made this change May 2022, but it seems to be a bug to not consider intInProgress; see May 23, 2022 slack discussion
flopr #(`N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
// context-dependent signals

View File

@ -39,6 +39,7 @@ module uncore (
input logic TIMECLK,
input logic [31:0] HADDR,
input logic [`AHBW-1:0] HWDATA,
input logic [`XLEN/8-1:0] HWSTRB,
input logic HWRITE,
input logic [2:0] HSIZE,
input logic [2:0] HBURST,
@ -81,6 +82,22 @@ module uncore (
logic UARTIntr,GPIOIntr;
logic SDCIntM;
logic PCLK, PRESETn, PWRITE, PENABLE;
// logic PSEL, PREADY;
logic [1:0] PSEL, PREADY;
logic [31:0] PADDR;
logic [`XLEN-1:0] PWDATA;
logic [`XLEN/8-1:0] PSTRB;
logic [1:0][`XLEN-1:0] PRDATA;
// logic [`XLEN-1:0][8:0] PRDATA;
logic [`XLEN-1:0] HREADBRIDGE;
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
// *** to do:
// hook up HWSTRB and remove subword write decoders
// add other peripherals on AHB
// HTRANS encoding
// Determine which region of physical memory (if any) is being accessed
// Use a trimmed down portion of the PMA checker - only the address decoders
// Set access types to all 1 as don't cares because the MMU has already done access checking
@ -89,130 +106,149 @@ module uncore (
// unswizzle HSEL signals
assign {HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[7:0];
// generate
// on-chip RAM
if (`RAM_SUPPORTED) begin : ram
ram #(
.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram (
.HCLK, .HRESETn,
.HSELRam, .HADDR,
.HWRITE, .HREADY, .HSIZED,
.HTRANS, .HWDATA, .HREADRam,
.HRESPRam, .HREADYRam);
end
// AHB -> APB bridge
ahbapbbridge #(2) ahbapbbridge
(.HCLK, .HRESETn, .HSEL({HSELCLINT, HSELGPIO}), .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HTRANS, .HREADY,
.HRDATA(HREADBRIDGE), .HRESP(HRESPBRIDGE), .HREADYOUT(HREADYBRIDGE),
.PCLK, .PRESETn, .PSEL, .PWRITE, .PENABLE, .PADDR, .PWDATA, .PSTRB, .PREADY, .PRDATA);
assign HSELBRIDGE = HSELGPIO | HSELCLINT; // if any of the bridge signals are selected
// on-chip RAM
if (`RAM_SUPPORTED) begin : ram
ram #(
.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram (
.HCLK, .HRESETn,
.HSELRam, .HADDR,
.HWRITE, .HREADY, .HSIZED,
.HTRANS, .HWDATA, .HREADRam,
.HRESPRam, .HREADYRam);
end
if (`BOOTROM_SUPPORTED) begin : bootrom
ram_orig #(.BASE(`BOOTROM_BASE), .RANGE(`BOOTROM_RANGE))
bootrom(
.HCLK, .HRESETn,
.HSELRam(HSELBootRom), .HADDR,
.HWRITE, .HREADY, .HTRANS, .HSIZED,
.HWDATA,
.HREADRam(HREADBootRom), .HRESPRam(HRESPBootRom), .HREADYRam(HREADYBootRom));
end
if (`BOOTROM_SUPPORTED) begin : bootrom
ram_orig #(.BASE(`BOOTROM_BASE), .RANGE(`BOOTROM_RANGE))
bootrom(
.HCLK, .HRESETn,
.HSELRam(HSELBootRom), .HADDR,
.HWRITE, .HREADY, .HTRANS, .HSIZED,
.HWDATA,
.HREADRam(HREADBootRom), .HRESPRam(HRESPBootRom), .HREADYRam(HREADYBootRom));
end
// memory-mapped I/O peripherals
if (`CLINT_SUPPORTED == 1) begin : clint
clint clint(
.HCLK, .HRESETn, .TIMECLK,
.HSELCLINT, .HADDR(HADDR[15:0]), .HWRITE,
.HWDATA, .HREADY, .HTRANS, .HSIZED,
.HREADCLINT,
.HRESPCLINT, .HREADYCLINT,
.MTIME(MTIME_CLINT),
.MTimerInt, .MSwInt);
// memory-mapped I/O peripherals
if (`CLINT_SUPPORTED == 1) begin : clint
/* clint clint(
.HCLK, .HRESETn, .TIMECLK,
.HSELCLINT, .HADDR(HADDR[15:0]), .HWRITE,
.HWDATA, .HREADY, .HTRANS, .HSIZED,
.HREADCLINT,
.HRESPCLINT, .HREADYCLINT,
.MTIME(MTIME_CLINT),
.MTimerInt, .MSwInt);*/
clint_apb clint(
.PCLK, .PRESETn, .PSEL(PSEL[1]), .PADDR(PADDR[15:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
.PRDATA(PRDATA[1]), .PREADY(PREADY[1]),
.MTIME(MTIME_CLINT),
.MTimerInt, .MSwInt);
end else begin : clint
assign MTIME_CLINT = 0;
assign MTimerInt = 0; assign MSwInt = 0;
end
if (`PLIC_SUPPORTED == 1) begin : plic
plic plic(
.HCLK, .HRESETn,
.HSELPLIC, .HADDR(HADDR[27:0]),
.HWRITE, .HREADY, .HTRANS, .HWDATA,
.UARTIntr, .GPIOIntr,
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
.MExtInt, .SExtInt);
end else begin : plic
assign MExtInt = 0;
assign SExtInt = 0;
end
if (`GPIO_SUPPORTED == 1) begin : gpio
gpio gpio(
.HCLK, .HRESETn, .HSELGPIO,
.HADDR(HADDR[7:0]),
.HWDATA,
.HWRITE, .HREADY,
.HTRANS,
.HREADGPIO,
.HRESPGPIO, .HREADYGPIO,
.GPIOPinsIn,
.GPIOPinsOut, .GPIOPinsEn,
.GPIOIntr);
end else begin : gpio
assign GPIOPinsOut = 0; assign GPIOPinsEn = 0; assign GPIOIntr = 0;
end
if (`UART_SUPPORTED == 1) begin : uart
uart uart(
.HCLK, .HRESETn,
.HSELUART,
.HADDR(HADDR[2:0]),
.HWRITE, .HWDATA,
.HREADUART, .HRESPUART, .HREADYUART,
.SIN(UARTSin), .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1), // from E1A driver from RS232 interface
.SOUT(UARTSout), .RTSb(), .DTRb(), // to E1A driver to RS232 interface
.OUT1b(), .OUT2b(), .INTR(UARTIntr), .TXRDYb(), .RXRDYb()); // to CPU
end else begin : uart
assign UARTSout = 0; assign UARTIntr = 0;
end
if (`SDC_SUPPORTED == 1) begin : sdc
SDC SDC(.HCLK, .HRESETn, .HSELSDC, .HADDR(HADDR[4:0]), .HWRITE, .HREADY, .HTRANS,
.HWDATA, .HREADSDC, .HRESPSDC, .HREADYSDC,
// sdc interface
.SDCCmdOut, .SDCCmdIn, .SDCCmdOE, .SDCDatIn, .SDCCLK,
// interrupt to PLIC
.SDCIntM
);
end else begin : sdc
assign SDCCLK = 0;
assign SDCCmdOut = 0;
assign SDCCmdOE = 0;
end
// endgenerate
end else begin : clint
assign MTIME_CLINT = 0;
assign MTimerInt = 0; assign MSwInt = 0;
end
if (`PLIC_SUPPORTED == 1) begin : plic
plic plic(
.HCLK, .HRESETn,
.HSELPLIC, .HADDR(HADDR[27:0]),
.HWRITE, .HREADY, .HTRANS, .HWDATA,
.UARTIntr, .GPIOIntr,
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
.MExtInt, .SExtInt);
end else begin : plic
assign MExtInt = 0;
assign SExtInt = 0;
end
if (`GPIO_SUPPORTED == 1) begin : gpio
/* gpio gpio(
.HCLK, .HRESETn, .HSELGPIO,
.HADDR(HADDR[7:0]),
.HWDATA,
.HWRITE, .HREADY,
.HTRANS,
.HREADGPIO,
.HRESPGPIO, .HREADYGPIO,
.GPIOPinsIn,
.GPIOPinsOut, .GPIOPinsEn,
.GPIOIntr); */
gpio_apb gpio(
.PCLK, .PRESETn, .PSEL(PSEL[0]), .PADDR(PADDR[7:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
.PRDATA(PRDATA[0]), .PREADY(PREADY[0]),
.iof0(), .iof1(), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .GPIOIntr);
end else begin : gpio
assign GPIOPinsOut = 0; assign GPIOPinsEn = 0; assign GPIOIntr = 0;
end
if (`UART_SUPPORTED == 1) begin : uart
uart uart(
.HCLK, .HRESETn,
.HSELUART,
.HADDR(HADDR[2:0]),
.HWRITE, .HWDATA,
.HREADUART, .HRESPUART, .HREADYUART,
.SIN(UARTSin), .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1), // from E1A driver from RS232 interface
.SOUT(UARTSout), .RTSb(), .DTRb(), // to E1A driver to RS232 interface
.OUT1b(), .OUT2b(), .INTR(UARTIntr), .TXRDYb(), .RXRDYb()); // to CPU
end else begin : uart
assign UARTSout = 0; assign UARTIntr = 0;
end
if (`SDC_SUPPORTED == 1) begin : sdc
SDC SDC(.HCLK, .HRESETn, .HSELSDC, .HADDR(HADDR[4:0]), .HWRITE, .HREADY, .HTRANS,
.HWDATA, .HREADSDC, .HRESPSDC, .HREADYSDC,
// sdc interface
.SDCCmdOut, .SDCCmdIn, .SDCCmdOE, .SDCDatIn, .SDCCLK,
// interrupt to PLIC
.SDCIntM
);
end else begin : sdc
assign SDCCLK = 0;
assign SDCCmdOut = 0;
assign SDCCmdOE = 0;
end
// mux could also include external memory
// AHB Read Multiplexer
assign HRDATA = ({`XLEN{HSELRamD}} & HREADRam) |
({`XLEN{HSELEXTD}} & HRDATAEXT) |
({`XLEN{HSELCLINTD}} & HREADCLINT) |
// ({`XLEN{HSELCLINTD}} & HREADCLINT) |
({`XLEN{HSELPLICD}} & HREADPLIC) |
({`XLEN{HSELGPIOD}} & HREADGPIO) |
// ({`XLEN{HSELGPIOD}} & HREADGPIO) |
({`XLEN{HSELBRIDGED}} & HREADBRIDGE) |
({`XLEN{HSELBootRomD}} & HREADBootRom) |
({`XLEN{HSELUARTD}} & HREADUART) |
({`XLEN{HSELSDCD}} & HREADSDC);
assign HRESP = HSELRamD & HRESPRam |
HSELEXTD & HRESPEXT |
HSELCLINTD & HRESPCLINT |
// HSELCLINTD & HRESPCLINT |
HSELPLICD & HRESPPLIC |
HSELGPIOD & HRESPGPIO |
// HSELGPIOD & HRESPGPIO |
HSELBRIDGE & HRESPBRIDGE |
HSELBootRomD & HRESPBootRom |
HSELUARTD & HRESPUART |
HSELSDC & HRESPSDC;
assign HREADY = HSELRamD & HREADYRam |
HSELEXTD & HREADYEXT |
HSELCLINTD & HREADYCLINT |
// HSELCLINTD & HREADYCLINT |
HSELPLICD & HREADYPLIC |
HSELGPIOD & HREADYGPIO |
// HSELGPIOD & HREADYGPIO |
HSELBRIDGED & HREADYBRIDGE |
HSELBootRomD & HREADYBootRom |
HSELUARTD & HREADYUART |
HSELSDCD & HREADYSDC |
HSELNoneD; // don't lock up the bus if no region is being accessed
// *** remove HREADYGPIO, others
// Address Decoder Delay (figure 4-2 in spec)
flopr #(9) hseldelayreg(HCLK, ~HRESETn, HSELRegions, {HSELNoneD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD});
flopr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HSELBRIDGE, HSELBRIDGED);
endmodule

View File

@ -42,6 +42,7 @@ module wallypipelinedcore (
output logic HCLK, HRESETn,
output logic [31:0] HADDR,
output logic [`AHBW-1:0] HWDATA,
output logic [`XLEN/8-1:0] HWSTRB,
output logic HWRITE,
output logic [2:0] HSIZE,
output logic [2:0] HBURST,
@ -115,6 +116,8 @@ module wallypipelinedcore (
logic [1:0] PageType;
logic sfencevmaM, wfiM, IntPendingM;
logic SelHPTW;
logic [`XLEN/8-1:0] ByteMaskM;
// PMA checker signals
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
@ -263,6 +266,7 @@ module wallypipelinedcore (
// connected to ahb (all stay the same)
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck, .LSUBusInit,
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize, .LSUBurstType, .LSUTransType, .LSUTransComplete,
.ByteMaskM,
// connect to csr or privilege and stay the same.
.PrivilegeModeW, .BigEndianM, // connects to csr
@ -309,9 +313,10 @@ module wallypipelinedcore (
.LSUTransComplete,
.LSUBusAck,
.LSUBusInit,
.ByteMaskM,
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn,
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST,
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST,
.HPROT, .HTRANS, .HMASTLOCK, .HADDRD, .HSIZED,
.HWRITED);

View File

@ -48,6 +48,7 @@ module wallypipelinedsoc (
output logic HCLK, HRESETn,
output logic [31:0] HADDR,
output logic [`AHBW-1:0] HWDATA,
output logic [`XLEN/8-1:0] HWSTRB,
output logic HWRITE,
output logic [2:0] HSIZE,
output logic [2:0] HBURST,
@ -79,6 +80,7 @@ module wallypipelinedsoc (
logic [3:0] HSIZED;
logic HWRITED;
// synchronize reset to SOC clock domain
synchronizer resetsync(.clk, .d(reset_ext), .q(reset));
@ -86,13 +88,13 @@ module wallypipelinedsoc (
wallypipelinedcore core(.clk, .reset,
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
.MTIME_CLINT,
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA,
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB,
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
.HADDRD, .HSIZED, .HWRITED
);
uncore uncore(.HCLK, .HRESETn, .TIMECLK,
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED,
.MTimerInt, .MSwInt, .MExtInt, .SExtInt, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
.HSELEXT,

BIN
pipelined/srt/inttestgen Executable file

Binary file not shown.

View File

@ -0,0 +1,83 @@
/* testgen.c */
/* Written 10/31/96 by David Harris
This program creates test vectors for mantissa component
of an IEEE floating point divider.
*/
/* #includes */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* Constants */
#define ENTRIES 10
#define RANDOM_VECS 500
/* Prototypes */
void output(FILE *fptr, long a, long b, long r, long rem);
void printhex(FILE *fptr, long x);
double random_input(void);
/* Main */
void main(void)
{
FILE *fptr;
long a, b, r, rem;
long list[ENTRIES] = {1, 3, 5, 18, 25, 33, 42, 65, 103, 255};
int i, j;
if ((fptr = fopen("inttestvectors","w")) == NULL) {
fprintf(stderr, "Couldn't write testvectors file\n");
exit(1);
}
for (i=0; i<ENTRIES; i++) {
b = list[i];
for (j=0; j<ENTRIES; j++) {
a = list[j];
r = a/b;
rem = a%b;
output(fptr, a, b, r, rem);
}
}
// for (i = 0; i< RANDOM_VECS; i++) {
// a = random_input();
// b = random_input();
// r = a/b;
// output(fptr, a, b, r);
// }
fclose(fptr);
}
/* Functions */
void output(FILE *fptr, long a, long b, long r, long rem)
{
printhex(fptr, a);
fprintf(fptr, "_");
printhex(fptr, b);
fprintf(fptr, "_");
printhex(fptr, r);
fprintf(fptr, "_");
printhex(fptr, rem);
fprintf(fptr, "\n");
}
void printhex(FILE *fptr, long m)
{
fprintf(fptr, "%016llx", m);
}
double random_input(void)
{
return 1.0 + rand()/32767.0;
}

View File

@ -1,3 +1,5 @@
add wave -noupdate /testbench/*
add wave -noupdate /testbench/srt/*
add wave -noupdate /testbench/srt/otfc2/*
add wave -noupdate /testbench/srt/preproc/*
add wave -noupdate /testbench/srt/divcounter/*

View File

@ -48,8 +48,8 @@ module srt (
input logic Signed, // Interpret integers as signed 2's complement
input logic Int, // Choose integer inputs
input logic Sqrt, // perform square root, not divide
output logic rsign,
output logic [`DIVLEN-1:0] Quot, Rem, QuotOTFC, // *** later handle integers
output logic rsign, done,
output logic [`DIVLEN-1:0] Rem, Quot, // *** later handle integers
output logic [`NE-1:0] rExp,
output logic [3:0] Flags
);
@ -59,11 +59,10 @@ module srt (
logic calcSign;
logic [`DIVLEN-1:0] X, Dpreproc;
logic [`DIVLEN+3:0] WS, WSA, WSN, WC, WCA, WCN, D, Db, Dsel;
logic [`DIVLEN+2:0] rp, rm;
logic [$clog2(`XLEN+1)-1:0] intExp;
logic [$clog2(`XLEN+1)-1:0] intExp, dur, calcDur;
logic intSign;
srtpreproc preproc(SrcA, SrcB, SrcXFrac, SrcYFrac, Fmt, W64, Signed, Int, Sqrt, X, Dpreproc, intExp, intSign);
srtpreproc preproc(SrcA, SrcB, SrcXFrac, SrcYFrac, Fmt, W64, Signed, Int, Sqrt, X, Dpreproc, intExp, calcDur, intSign);
// Top Muxes and Registers
// When start is asserted, the inputs are loaded into the divider.
@ -78,25 +77,25 @@ module srt (
// Quotient Selection logic
// Given partial remainder, select quotient of +1, 0, or -1 (qp, qz, pm)
qsel2 qsel2(WS[`DIVLEN+3:`DIVLEN], WC[`DIVLEN+3:`DIVLEN], qp, qz, qm);
// Accumulate quotient digits in a shift register (now done in OTFC)
qacc #(`DIVLEN+3) qacc(clk, Start, qp, qz, qm, rp, rm);
flopen #(`NE) expflop(clk, Start, calcExp, rExp);
flopen #(1) signflop(clk, Start, calcSign, rsign);
flopen #(7) durflop(clk, Start, calcDur, dur);
counter divcounter(clk, Start, dur, done);
// Divisor Selection logic
inv dinv(D, Db);
assign Db = ~D;
mux3onehot #(`DIVLEN) divisorsel(Db, {(`DIVLEN+4){1'b0}}, D, qp, qz, qm, Dsel);
// Partial Product Generation
csa #(`DIVLEN+4) csa(WS, WC, Dsel, qp, WSA, WCA);
otfc2 #(`DIVLEN) otfc2(clk, Start, qp, qz, qm, QuotOTFC);
otfc2 #(`DIVLEN) otfc2(clk, Start, qp, qz, qm, Quot);
expcalc expcalc(.XExp, .YExp, .calcExp);
signcalc signcalc(.XSign, .YSign, .calcSign);
srtpostproc postproc(rp, rm, Quot);
endmodule
////////////////
@ -115,7 +114,7 @@ module srtpreproc (
input logic Int, // Choose integer inputs
input logic Sqrt, // perform square root, not divide
output logic [`DIVLEN-1:0] X, D,
output logic [$clog2(`XLEN+1)-1:0] intExp, // Quotient integer exponent
output logic [$clog2(`XLEN+1)-1:0] intExp, dur, // Quotient integer exponent
output logic intSign // Quotient integer sign
);
@ -132,8 +131,8 @@ module srtpreproc (
assign ExtraA = {PosA, {`EXTRAINTBITS{1'b0}}};
assign ExtraB = {PosB, {`EXTRAINTBITS{1'b0}}};
assign PreprocA = ExtraA << zeroCntA;
assign PreprocB = ExtraB << zeroCntB;
assign PreprocA = ExtraA << (zeroCntA + 1);
assign PreprocB = ExtraB << (zeroCntB + 1);
assign PreprocX = {SrcXFrac, {`EXTRAFRACBITS{1'b0}}};
assign PreprocY = {SrcYFrac, {`EXTRAFRACBITS{1'b0}}};
@ -142,6 +141,8 @@ module srtpreproc (
assign D = Int ? PreprocB : PreprocY;
assign intExp = zeroCntB - zeroCntA + 1;
assign intSign = Signed & (SrcA[`XLEN - 1] ^ SrcB[`XLEN - 1]);
assign dur = Int ? (intExp & {7{~intExp[6]}}) : (`DIVLEN + 2);
endmodule
/////////////////////////////////
@ -179,38 +180,10 @@ module qsel2 ( // *** eventually just change to 4 bits
assign #1 qm = magnitude & sign;
endmodule
//////////
// qacc //
//////////
// To be replaced by OTFC
module qacc #(parameter N=68) (
input logic clk,
input logic req,
input logic qp, qz, qm,
output logic [N-1:0] rp, rm
);
flopr #(N) rmreg(clk, req, {rm[N-2:0], qm}, rm);
flopr #(N) rpreg(clk, req, {rp[N-2:0], qp}, rp);
/* always @(posedge clk)
begin
if (req)
begin
rp <= #1 0;
rm <= #1 0;
end
else
begin
rm <= #1 {rm[54:0], qm};
rp <= #1 {rp[54:0], qp};
end
end */
endmodule
///////////////////////////////////
// On-The-Fly Converter, Radix 2 //
///////////////////////////////////
module otfc2 #(parameter N=65) (
module otfc2 #(parameter N=64) (
input logic clk,
input logic Start,
input logic qp, qz, qm,
@ -254,13 +227,29 @@ module otfc2 #(parameter N=65) (
endmodule
/////////
// inv //
/////////
module inv(input logic [`DIVLEN+3:0] in,
output logic [`DIVLEN+3:0] out);
/////////////
// counter //
/////////////
module counter(input logic clk,
input logic req,
input logic [$clog2(`XLEN+1)-1:0] dur,
output logic done);
logic [$clog2(`XLEN+1)-1:0] count;
assign #1 out = ~in;
// This block of control logic sequences the divider
// through its iterations. You may modify it if you
// build a divider which completes in fewer iterations.
// You are not responsible for the (trivial) circuit
// design of the block.
always @(posedge clk)
begin
if (count == dur) done <= #1 1;
else if (done | req) done <= #1 0;
if (req) count <= #1 0;
else count <= #1 count+1;
end
endmodule
//////////
@ -323,43 +312,4 @@ module signcalc(
assign calcSign = XSign ^ YSign;
endmodule
////////////////////
// Postprocessing //
////////////////////
module srtpostproc (
input [`DIVLEN+2:0] rp, rm,
output [`DIVLEN-1:0] Quot
);
//assign Quot = rp - rm;
finaladd #(`DIVLEN+3) finaladd(rp, rm, Quot);
endmodule
//////////////
// finaladd //
//////////////
module finaladd #(parameter N=68) (
input logic [N-1:0] rp, rm,
output logic [N-4:0] r
);
logic [N-1:0] diff;
// this magic block performs the final addition for you
// to convert the positive and negative quotient digits
// into a normalized mantissa. It returns the 52 bit
// mantissa after shifting to guarantee a leading 1.
// You can assume this block operates in one cycle
// and do not need to budget it in your area and power
// calculations.
// Since no rounding is performed, the result may be too
// small by one unit in the least significant place (ulp).
// The checker ignores such an error.
assign #1 diff = rp - rm;
assign #1 r = diff[N-1] ? diff[N-2:2] : diff[N-3:1];
endmodule
endmodule

View File

@ -3,26 +3,26 @@
/////////////
// counter //
/////////////
module counter(input logic clk,
input logic req,
output logic done);
// module counter(input logic clk,
// input logic req,
// output logic done);
logic [7:0] count;
// logic [7:0] count;
// This block of control logic sequences the divider
// through its iterations. You may modify it if you
// build a divider which completes in fewer iterations.
// You are not responsible for the (trivial) circuit
// design of the block.
// // This block of control logic sequences the divider
// // through its iterations. You may modify it if you
// // build a divider which completes in fewer iterations.
// // You are not responsible for the (trivial) circuit
// // design of the block.
always @(posedge clk)
begin
if (count == `DIVLEN + 2) done <= #1 1;
else if (done | req) done <= #1 0;
if (req) count <= #1 0;
else count <= #1 count+1;
end
endmodule
// always @(posedge clk)
// begin
// if (count == `DIVLEN + 2) done <= #1 1;
// else if (done | req) done <= #1 0;
// if (req) count <= #1 0;
// else count <= #1 count+1;
// end
// endmodule
///////////
// clock //
@ -42,21 +42,23 @@ module testbench;
logic clk;
logic req;
logic done;
logic Int;
logic [63:0] a, b;
logic [51:0] afrac, bfrac;
logic [10:0] aExp, bExp;
logic asign, bsign;
logic [51:0] r, rOTFC;
logic [`DIVLEN-1:0] Quot, QuotOTFC;
logic [54:0] rp, rm; // positive quotient digits
logic [51:0] r;
logic [63:0] rInt;
logic [`DIVLEN-1:0] Quot;
// Test parameters
parameter MEM_SIZE = 40000;
parameter MEM_WIDTH = 64+64+64;
parameter MEM_WIDTH = 64+64+64+64;
`define memr 63:0
`define memb 127:64
`define mema 191:128
`define memrem 63:0
`define memr 127:64
`define memb 191:128
`define mema 255:192
// Test logicisters
logic [MEM_WIDTH-1:0] Tests [0:MEM_SIZE]; // Space for input file
@ -67,18 +69,20 @@ module testbench;
logic rsign;
integer testnum, errors;
assign Int = 1'b1;
// Divider
srt srt(.clk, .Start(req),
.Stall(1'b0), .Flush(1'b0),
.XExp(aExp), .YExp(bExp), .rExp,
.XSign(asign), .YSign(bsign), .rsign,
.SrcXFrac(afrac), .SrcYFrac(bfrac),
.SrcA('0), .SrcB('0), .Fmt(2'b00),
.W64(1'b0), .Signed(1'b0), .Int(1'b0), .Sqrt(1'b0),
.Quot, .QuotOTFC, .Rem(), .Flags());
.SrcA(a), .SrcB(b), .Fmt(2'b00),
.W64(1'b1), .Signed(1'b0), .Int, .Sqrt(1'b0),
.Quot, .Rem(), .Flags(), .done);
// Counter
counter counter(clk, req, done);
// counter counter(clk, req, done);
initial
@ -94,7 +98,7 @@ module testbench;
begin
testnum = 0;
errors = 0;
$readmemh ("testvectors", Tests);
$readmemh ("inttestvectors", Tests);
Vec = Tests[testnum];
a = Vec[`mema];
{asign, aExp, afrac} = a;
@ -102,7 +106,7 @@ module testbench;
{bsign, bExp, bfrac} = b;
nextr = Vec[`memr];
r = Quot[(`DIVLEN - 1):(`DIVLEN - 52)];
rOTFC = QuotOTFC[(`DIVLEN - 1):(`DIVLEN - 52)];
rInt = Quot;
req <= #5 1;
end
@ -111,45 +115,54 @@ module testbench;
always @(posedge clk)
begin
r = Quot[(`DIVLEN - 1):(`DIVLEN - 52)];
rOTFC = QuotOTFC[(`DIVLEN - 1):(`DIVLEN - 52)];
if (done)
begin
req <= #5 1;
diffp = correctr[51:0] - r;
diffn = r - correctr[51:0];
if ((rsign !== correctr[63]) | (rExp !== correctr[62:52]) | ($signed(diffn) > 1) | ($signed(diffp) > 1) | (diffn === 64'bx) | (diffp === 64'bx)) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("result was %h_%h, should be %h %h %h\n", rExp, r, correctr, diffn, diffp);
$display("failed\n");
$stop;
end
if (r !== rOTFC) // Check if OTFC works
begin
errors = errors+1;
$display("OTFC is %h, should be %h\n", rOTFC, r);
$display("failed\n");
// $stop;
rInt = Quot;
if (done) begin
if (~Int) begin
req <= #5 1;
diffp = correctr[51:0] - r;
diffn = r - correctr[51:0];
if ((rsign !== correctr[63]) | (rExp !== correctr[62:52]) | ($signed(diffn) > 1) | ($signed(diffp) > 1) | (diffn === 64'bx) | (diffp === 64'bx)) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("result was %h_%h, should be %h %h %h\n", rExp, r, correctr, diffn, diffp);
$display("failed\n");
$stop;
end
if (afrac === 52'hxxxxxxxxxxxxx)
begin
$display("%d Tests completed successfully", testnum);
$stop;
end
end else begin
req <= #5 1;
diffp = correctr[63:0] - rInt;
diffn = rInt - correctr[63:0];
if (($signed(diffn) > 1) | ($signed(diffp) > 1) | (diffn === 64'bx) | (diffp === 64'bx)) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("result was %h, should be %h %h %h\n", rInt, correctr, diffn, diffp);
$display("failed\n");
$stop;
end
if (afrac === 52'hxxxxxxxxxxxxx)
begin
$display("%d Tests completed successfully", testnum);
$stop;
end
end
end
if (afrac === 52'hxxxxxxxxxxxxx)
begin
$display("%d Tests completed successfully", testnum);
$stop;
end
end
if (req)
begin
req <= #5 0;
correctr = nextr;
testnum = testnum+1;
Vec = Tests[testnum];
$display("a = %h b = %h",a,b);
a = Vec[`mema];
{asign, aExp, afrac} = a;
b = Vec[`memb];
{bsign, bExp, bfrac} = b;
nextr = Vec[`memr];
end
if (req) begin
req <= #5 0;
correctr = nextr;
testnum = testnum+1;
Vec = Tests[testnum];
$display("a = %h b = %h",a,b);
a = Vec[`mema];
{asign, aExp, afrac} = a;
b = Vec[`memb];
{bsign, bExp, bfrac} = b;
nextr = Vec[`memr];
end
end
endmodule

View File

@ -61,15 +61,15 @@ module testbenchfp;
// in-between FMA signals
logic Mult;
logic [`NE+1:0] ProdExpE;
logic [`NE+1:0] Pe;
logic AddendStickyE;
logic KillProdE;
logic [$clog2(3*`NF+7)-1:0] FmaNormCntE;
logic [3*`NF+5:0] SumE;
logic [3*`NF+5:0] Sm;
logic InvZE;
logic NegSumE;
logic ZSgnEffE;
logic PSgnE;
logic Ps;
logic DivSticky;
logic DivNegSticky;
logic [`NE+1:0] DivCalcExp;
@ -637,12 +637,12 @@ module testbenchfp;
///////////////////////////////////////////////////////////////////////////////////////////////
// instantiate devices under test
fma fma(.XSgnE(XSgn), .YSgnE(YSgn), .ZSgnE(ZSgn),
.XExpE(XExp), .YExpE(YExp), .ZExpE(ZExp),
.XManE(XMan), .YManE(YMan), .ZManE(ZMan),
fma fma(.Xs(XSgn), .Ys(YSgn), .Zs(ZSgn),
.Xe(XExp), .Ye(YExp), .Ze(ZExp),
.Xm(XMan), .Ym(YMan), .Zm(ZMan),
.XZeroE(XZero), .YZeroE(YZero), .ZZeroE(ZZero),
.FOpCtrlE(OpCtrlVal), .FmtE(ModFmt), .SumE, .NegSumE, .InvZE, .FmaNormCntE, .ZSgnEffE, .PSgnE,
.ProdExpE, .AddendStickyE, .KillProdE);
.FOpCtrlE(OpCtrlVal), .FmtE(ModFmt), .Sm, .NegSumE, .InvA(InvZE), .FmaNormCntE, .ZSgnEffE, .Ps,
.Pe, .AddendStickyE, .KillProdE);
postprocess postprocess(.XSgnM(XSgn), .YSgnM(YSgn), .PostProcSelM(UnitVal[1:0]),
.ZExpM(ZExp), .ZDenormM(ZDenorm), .FOpCtrlM(OpCtrlVal), .Quot, .DivCalcExpM(DivCalcExp),
@ -651,8 +651,8 @@ module testbenchfp;
.XZeroM(XZero), .YZeroM(YZero), .ZZeroM(ZZero), .CvtShiftAmtM(CvtShiftAmtE),
.XInfM(XInf), .YInfM(YInf), .ZInfM(ZInf), .CvtResSgnM(CvtResSgnE), .FWriteIntM(WriteIntVal),
.XSNaNM(XSNaN), .YSNaNM(YSNaN), .ZSNaNM(ZSNaN), .CvtLzcInM(CvtLzcInE), .IntZeroM(IntZeroE),
.KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(ProdExpE),
.SumM(SumE), .NegSumM(NegSumE), .InvZM(InvZE), .FmaNormCntM(FmaNormCntE), .EarlyTermShiftDiv2M(EarlyTermShiftDiv2), .ZSgnEffM(ZSgnEffE), .PSgnM(PSgnE), .FmtM(ModFmt), .FrmM(FrmVal),
.KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(Pe),
.SumM(Sm), .NegSumM(NegSumE), .InvZM(InvZE), .FmaNormCntM(FmaNormCntE), .EarlyTermShiftDiv2M(EarlyTermShiftDiv2), .ZSgnEffM(ZSgnEffE), .PSgnM(Ps), .FmtM(ModFmt), .FrmM(FrmVal),
.PostProcFlgM(Flg), .PostProcResM(FpRes), .FCvtIntResM(IntRes));
fcvt fcvt (.XSgnE(XSgn), .XExpE(XExp), .XManE(XMan), .ForwardedSrcAE(SrcA), .FWriteIntE(WriteIntVal),
@ -818,7 +818,15 @@ end
// check if result is correct
// - wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage)
if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlg === AnsFlg | AnsFlg === 5'bx))&((~DivStart&DivDone)^~(UnitVal == `DIVUNIT))&(UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT)) begin
if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlg === AnsFlg | AnsFlg === 5'bx))&((UnitVal !== `DIVUNIT))&(UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT)) begin
errors += 1;
$display("There is an error in %s", Tests[TestNum]);
$display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg);
$stop;
end
// division
else if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlg === AnsFlg | AnsFlg === 5'bx))&(~DivStart&DivDone)&(UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT)) begin
errors += 1;
$display("There is an error in %s", Tests[TestNum]);
$display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg);

View File

@ -290,7 +290,6 @@ logic [3:0] dummy;
// if (signature[i+4] !== 'bx | (signature[i] !== 32'hFFFFFFFF & signature[i] !== 32'h00000000)) begin
// report errors unless they are garbage at the end of the sim
// kind of hacky test for garbage right now
$display("sig4 = %h ne %b", signature[i+4], signature[i+4] !== 'bx);
errors = errors+1;
$display(" Error on test %s result %d: adr = %h sim (D$) %h sim (DMEM) = %h, signature = %h",
tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]);

View File

@ -5,8 +5,8 @@ NAME := synth
# defaults
export DESIGN ?= wallypipelinedcore
export FREQ ?= 3402
export CONFIG ?= rv32e
export FREQ ?= 3000
export CONFIG ?= rv32gc
# sky130 and sky90 presently supported
export TECH ?= tsmc28
# MAXCORES allows parallel compilation, which is faster but less CPU-efficient
@ -14,7 +14,7 @@ export TECH ?= tsmc28
export MAXCORES ?= 4
# MAXOPT turns on flattening, boundary optimization, and retiming
# The output netlist is hard to interpret, but significantly better PPA
export MAXOPT ?= 0
export MAXOPT ?= 1
export DRIVE ?= FLOP
time := $(shell date +%F-%H-%M)

View File

@ -1,113 +0,0 @@
Module,Tech,Width,Target Freq,Delay,Area,L Power (nW),D energy (fJ)
priorityencoder,sky90,8,7994,0.12495882036527395,60.760001,44.346,13.42057730723042
priorityencoder,sky90,16,5761,0.16976997552508244,136.220003,77.243,21.28915493084534
priorityencoder,sky90,32,4776,0.20887023450586265,379.260006,246.78,50.06619521105528
priorityencoder,sky90,64,4096,0.244021625,794.780014,364.853,72.71844425000002
priorityencoder,sky90,128,3409,0.2933331557641537,1602.300031,610.009,126.1332569785861
add,sky90,8,3652,0.2733695629791895,245.000005,139.276,101.6934774282585
add,sky90,16,2931,0.33991248447628797,623.280012,352.919,268.5308627362675
add,sky90,32,2420,0.4132191404958678,1330.840024,582.809,520.6561170247934
add,sky90,64,2139,0.4674681813931744,2781.240054,1050.0,939.1435764188874
add,sky90,128,1885,0.5304949787798409,6186.740118,2230.0,2147.9741690795754
csa,sky90,8,5740,0.16671402787456446,290.080006,207.654,143.04063591637635
csa,sky90,16,5984,0.16522529946524064,588.000011,322.135,321.19798216042784
csa,sky90,32,5740,0.16671402787456446,1160.320023,826.559,570.4954033867597
csa,sky90,64,5984,0.16522529946524064,2469.600048,1440.0,1354.3517797165773
csa,sky90,128,5984,0.16522529946524064,4897.060095,2990.0,2649.0572263262034
shiftleft,sky90,8,4321,0.23108991020597083,250.880004,181.951,70.25133270261513
shiftleft,sky90,16,3355,0.29803959314456036,666.400006,558.433,195.51397310283156
shiftleft,sky90,32,2500,0.39945200000000003,1400.420023,738.137,368.29474400000004
shiftleft,sky90,64,2203,0.45385946391284615,3914.120062,2680.0,1144.633567988198
shiftleft,sky90,128,1907,0.5242938489774515,9192.400136,6080.0,2900.3935725432616
comparator,sky90,8,4829,0.2066692116380203,198.940004,136.459,48.56726473493477
comparator,sky90,16,4014,0.24886605181863478,355.740006,188.666,62.714245058295965
comparator,sky90,32,3596,0.27763876307007784,697.760013,316.793,109.38967264961067
comparator,sky90,64,3129,0.31954192361776923,1372.980026,508.393,204.82637303899006
comparator,sky90,128,2682,0.37267507755406415,2836.120055,772.571,463.6077964772558
flop,sky90,8,10,0.1143419999999935,133.279999,64.8145,0.22163481569998741
flop,sky90,16,10,0.1143419999999935,266.5599975,129.629,0.4426750529999749
flop,sky90,32,10,0.1143419999999935,533.119995,259.258,0.88306326599995
flop,sky90,64,10,0.1143419999999935,1066.23999,520.0,1.7717864609998994
flop,sky90,128,10,0.1143419999999935,2132.4799805,1035.0,3.537741479999799
mux2,sky90,1,11806,0.08300869354565475,13.72,12.3,3.8183999031001186
mux2,sky90,8,5280,0.1887229393939394,63.700001,23.506,19.476207345454547
mux2,sky90,16,4815,0.20207331983385254,119.560002,32.354,37.76750347694705
mux2,sky90,32,5000,0.19989700000000002,374.360008,259.372,136.72954800000002
mux2,sky90,64,4060,0.24566741871921183,514.50001,165.954,163.6145008669951
mux2,sky90,128,4004,0.24974824975024976,1302.420025,767.078,466.52973053346653
mux4,sky90,1,7687,0.12838276193573567,28.420001,22.994,6.3164318872381955
mux4,sky90,8,4655,0.21455177121374866,159.740002,86.462,42.03069198077337
mux4,sky90,16,4452,0.22313914914645103,392.0,398.313,103.09028690566036
mux4,sky90,32,3802,0.2622634634402946,465.500009,150.568,139.26189908679646
mux4,sky90,64,3699,0.2695173360367667,877.100017,304.149,274.9076827575021
mux4,sky90,128,3166,0.3157249696778269,1984.500039,725.267,569.5678452987997
mux8,sky90,1,5763,0.17009673572791947,70.560001,49.874,12.31500366670137
mux8,sky90,8,3577,0.2789168803466592,287.140006,116.648,60.83177160360637
mux8,sky90,16,3419,0.2915101822170225,588.000006,280.193,150.71076420620065
mux8,sky90,32,3155,0.3146512107765452,1237.740008,639.983,323.14679346751194
mux8,sky90,64,3020,0.33032882781456957,2207.940042,730.503,445.61358872185434
mux8,sky90,128,2666,0.37501377344336084,3761.240072,1460.0,854.281375903976
mult,sky90,8,1310,0.7631557786259543,2194.220041,1440.0,1420.996059801527
mult,sky90,16,997,1.0029260270812437,7519.540137,4940.0,6375.600754155466
mult,sky90,32,763,1.3106129895150722,25200.700446,14900.0,24931.79089954522
mult,sky90,64,632,1.5822664810126583,86011.661365,42600.0,88845.84517534176
mult,sky90,128,524,1.9083759465648855,296198.144128,114000.0,273311.87793918326
mux2d,sky90,1,13217,0.07565913467503972,19.6,18.562,6.03759894706817
mux4d,sky90,1,9701,0.10307715647871353,51.940001,49.18,13.626800086485927
mux8d,sky90,1,7099,0.1341249105507818,85.260001,40.078,14.405015393153965
priorityencoder,tsmc28,8,31306,0.03191275857663067,8.316,34.836,1.713715135565067
priorityencoder,tsmc28,16,21202,0.04705136175832468,21.294,73.912,3.815865438600132
priorityencoder,tsmc28,32,16453,0.060740189205615996,62.118,205.801,9.439025402552724
priorityencoder,tsmc28,64,13786,0.07244435673872045,137.088001,428.365,18.328422254896275
priorityencoder,tsmc28,128,11439,0.0874122290410001,315.252,980.365,40.908923191188045
add,tsmc28,8,13787,0.07226709545223761,33.012,176.194,12.328766484151734
add,tsmc28,16,11520,0.08680155555555555,90.972001,475.452,33.67900355555555
add,tsmc28,32,9810,0.1019177991845056,209.286002,1060.0,81.43232154841998
add,tsmc28,64,8203,0.12186861952944045,392.616003,1800.0,142.34254761038645
add,tsmc28,128,7210,0.13869425520110956,868.140006,4090.0,331.3405756754508
csa,tsmc28,8,23865,0.04077636748376283,49.392,473.393,20.91827651917033
csa,tsmc28,16,23865,0.04077636748376283,98.783999,946.879,41.75500030337314
csa,tsmc28,32,23865,0.04077636748376283,197.567999,1890.0,83.30611876932745
csa,tsmc28,64,23865,0.04077636748376283,395.135998,3790.0,166.5306848036874
csa,tsmc28,128,23865,0.04077636748376283,790.271996,7570.0,333.1021459748586
shiftleft,tsmc28,8,15183,0.06578013640255549,48.384,333.876,15.51753417736284
shiftleft,tsmc28,16,11800,0.0847177627118644,130.788,613.549,33.71766955932203
shiftleft,tsmc28,32,9587,0.10430391697089808,384.803997,1940.0,101.80062296359652
shiftleft,tsmc28,64,8269,0.12088260744951022,967.427998,4980.0,272.83204501354453
shiftleft,tsmc28,128,7023,0.14238329232521713,1836.953994,8670.0,566.543120162039
comparator,tsmc28,8,17054,0.05854826984871585,32.256,160.477,8.752966342383019
comparator,tsmc28,16,13709,0.07280278080093369,48.132,204.944,11.852292714392004
comparator,tsmc28,32,12136,0.08238147264337507,146.16,623.674,35.50641470929466
comparator,tsmc28,64,10862,0.09205807659731172,291.312,1240.0,69.41178975437303
comparator,tsmc28,128,9371,0.10671119720414043,558.432,2400.0,127.9467254477644
flop,tsmc28,8,10,0.048889000000002625,15.12,78.6345,0.013320296940000717
flop,tsmc28,16,10,0.048889000000002625,30.24,157.29,0.026541838100001425
flop,tsmc28,32,10,0.048889000000002625,60.4799995,314.5805,0.05332812120000287
flop,tsmc28,64,10,0.048889000000002625,120.959999,630.0,0.10640935295000573
flop,tsmc28,128,10,0.048889000000002625,241.919998,1260.0,0.21305826200001143
mux2,tsmc28,1,50000,0.019658000000000002,2.142,15.112,0.5917058000000001
mux2,tsmc28,8,29041,0.033768075961571574,16.884,113.726,5.335356001928308
mux2,tsmc28,16,19059,0.05221864998163597,15.75,88.448,5.133093293194816
mux2,tsmc28,32,17903,0.05585556035301346,32.130001,171.146,9.897605294553983
mux2,tsmc28,64,18546,0.05385698274560552,90.846,517.414,27.359347234767604
mux2,tsmc28,128,16594,0.0601057455706882,184.968,1150.0,58.603101931421
mux4,tsmc28,1,26255,0.03808798324128737,5.292,41.928,1.7101504475338032
mux4,tsmc28,8,18130,0.05509219801434087,27.971999,133.963,8.021424030888031
mux4,tsmc28,16,16440,0.06065625060827251,39.438,185.149,12.373875124087593
mux4,tsmc28,32,15168,0.0658052700421941,69.174,324.969,23.229260324894515
mux4,tsmc28,64,13915,0.07180589399928135,137.465999,648.086,45.59674268954365
mux4,tsmc28,128,13089,0.07639603056001222,296.603997,1440.0,94.50188980273512
mux8,tsmc28,1,16320,0.05991150980392156,7.182,38.342,1.8428780415686272
mux8,tsmc28,8,12885,0.07750962359332557,44.856,215.13,11.90547818393481
mux8,tsmc28,16,12256,0.08154268929503918,121.841998,521.624,25.93057519582246
mux8,tsmc28,32,11695,0.08537362676357418,168.21,815.694,46.35787933262078
mux8,tsmc28,64,11000,0.0907930909090909,304.037999,1490.0,81.89536799999999
mux8,tsmc28,128,10464,0.09547474923547401,664.775992,2850.0,153.04602302446486
mult,tsmc28,8,5000,0.19998100000000002,444.150001,3260.0,306.970835
mult,tsmc28,16,3819,0.26184265147944485,1634.472002,11800.0,1455.3214569227544
mult,tsmc28,32,2973,0.3363555785401951,5141.430011,36900.0,5416.333881232761
mult,tsmc28,64,2390,0.4184090418410042,16045.092071,109000.0,18545.980779602512
mult,tsmc28,128,1868,0.5353279057815846,44272.49428,262000.0,50011.4036139272
mux2d,tsmc28,1,51887,0.018931650182126544,3.276,26.574,0.9106123737602868
mux4d,tsmc28,1,32558,0.03008041734750292,4.158,30.464,1.2543534033908719
mux8d,tsmc28,1,21936,0.045586162654996355,20.664,171.151,6.614552201239972
1 Module Tech Width Target Freq Delay Area L Power (nW) D energy (fJ)
2 priorityencoder sky90 8 7994 0.12495882036527395 60.760001 44.346 13.42057730723042
3 priorityencoder sky90 16 5761 0.16976997552508244 136.220003 77.243 21.28915493084534
4 priorityencoder sky90 32 4776 0.20887023450586265 379.260006 246.78 50.06619521105528
5 priorityencoder sky90 64 4096 0.244021625 794.780014 364.853 72.71844425000002
6 priorityencoder sky90 128 3409 0.2933331557641537 1602.300031 610.009 126.1332569785861
7 add sky90 8 3652 0.2733695629791895 245.000005 139.276 101.6934774282585
8 add sky90 16 2931 0.33991248447628797 623.280012 352.919 268.5308627362675
9 add sky90 32 2420 0.4132191404958678 1330.840024 582.809 520.6561170247934
10 add sky90 64 2139 0.4674681813931744 2781.240054 1050.0 939.1435764188874
11 add sky90 128 1885 0.5304949787798409 6186.740118 2230.0 2147.9741690795754
12 csa sky90 8 5740 0.16671402787456446 290.080006 207.654 143.04063591637635
13 csa sky90 16 5984 0.16522529946524064 588.000011 322.135 321.19798216042784
14 csa sky90 32 5740 0.16671402787456446 1160.320023 826.559 570.4954033867597
15 csa sky90 64 5984 0.16522529946524064 2469.600048 1440.0 1354.3517797165773
16 csa sky90 128 5984 0.16522529946524064 4897.060095 2990.0 2649.0572263262034
17 shiftleft sky90 8 4321 0.23108991020597083 250.880004 181.951 70.25133270261513
18 shiftleft sky90 16 3355 0.29803959314456036 666.400006 558.433 195.51397310283156
19 shiftleft sky90 32 2500 0.39945200000000003 1400.420023 738.137 368.29474400000004
20 shiftleft sky90 64 2203 0.45385946391284615 3914.120062 2680.0 1144.633567988198
21 shiftleft sky90 128 1907 0.5242938489774515 9192.400136 6080.0 2900.3935725432616
22 comparator sky90 8 4829 0.2066692116380203 198.940004 136.459 48.56726473493477
23 comparator sky90 16 4014 0.24886605181863478 355.740006 188.666 62.714245058295965
24 comparator sky90 32 3596 0.27763876307007784 697.760013 316.793 109.38967264961067
25 comparator sky90 64 3129 0.31954192361776923 1372.980026 508.393 204.82637303899006
26 comparator sky90 128 2682 0.37267507755406415 2836.120055 772.571 463.6077964772558
27 flop sky90 8 10 0.1143419999999935 133.279999 64.8145 0.22163481569998741
28 flop sky90 16 10 0.1143419999999935 266.5599975 129.629 0.4426750529999749
29 flop sky90 32 10 0.1143419999999935 533.119995 259.258 0.88306326599995
30 flop sky90 64 10 0.1143419999999935 1066.23999 520.0 1.7717864609998994
31 flop sky90 128 10 0.1143419999999935 2132.4799805 1035.0 3.537741479999799
32 mux2 sky90 1 11806 0.08300869354565475 13.72 12.3 3.8183999031001186
33 mux2 sky90 8 5280 0.1887229393939394 63.700001 23.506 19.476207345454547
34 mux2 sky90 16 4815 0.20207331983385254 119.560002 32.354 37.76750347694705
35 mux2 sky90 32 5000 0.19989700000000002 374.360008 259.372 136.72954800000002
36 mux2 sky90 64 4060 0.24566741871921183 514.50001 165.954 163.6145008669951
37 mux2 sky90 128 4004 0.24974824975024976 1302.420025 767.078 466.52973053346653
38 mux4 sky90 1 7687 0.12838276193573567 28.420001 22.994 6.3164318872381955
39 mux4 sky90 8 4655 0.21455177121374866 159.740002 86.462 42.03069198077337
40 mux4 sky90 16 4452 0.22313914914645103 392.0 398.313 103.09028690566036
41 mux4 sky90 32 3802 0.2622634634402946 465.500009 150.568 139.26189908679646
42 mux4 sky90 64 3699 0.2695173360367667 877.100017 304.149 274.9076827575021
43 mux4 sky90 128 3166 0.3157249696778269 1984.500039 725.267 569.5678452987997
44 mux8 sky90 1 5763 0.17009673572791947 70.560001 49.874 12.31500366670137
45 mux8 sky90 8 3577 0.2789168803466592 287.140006 116.648 60.83177160360637
46 mux8 sky90 16 3419 0.2915101822170225 588.000006 280.193 150.71076420620065
47 mux8 sky90 32 3155 0.3146512107765452 1237.740008 639.983 323.14679346751194
48 mux8 sky90 64 3020 0.33032882781456957 2207.940042 730.503 445.61358872185434
49 mux8 sky90 128 2666 0.37501377344336084 3761.240072 1460.0 854.281375903976
50 mult sky90 8 1310 0.7631557786259543 2194.220041 1440.0 1420.996059801527
51 mult sky90 16 997 1.0029260270812437 7519.540137 4940.0 6375.600754155466
52 mult sky90 32 763 1.3106129895150722 25200.700446 14900.0 24931.79089954522
53 mult sky90 64 632 1.5822664810126583 86011.661365 42600.0 88845.84517534176
54 mult sky90 128 524 1.9083759465648855 296198.144128 114000.0 273311.87793918326
55 mux2d sky90 1 13217 0.07565913467503972 19.6 18.562 6.03759894706817
56 mux4d sky90 1 9701 0.10307715647871353 51.940001 49.18 13.626800086485927
57 mux8d sky90 1 7099 0.1341249105507818 85.260001 40.078 14.405015393153965
58 priorityencoder tsmc28 8 31306 0.03191275857663067 8.316 34.836 1.713715135565067
59 priorityencoder tsmc28 16 21202 0.04705136175832468 21.294 73.912 3.815865438600132
60 priorityencoder tsmc28 32 16453 0.060740189205615996 62.118 205.801 9.439025402552724
61 priorityencoder tsmc28 64 13786 0.07244435673872045 137.088001 428.365 18.328422254896275
62 priorityencoder tsmc28 128 11439 0.0874122290410001 315.252 980.365 40.908923191188045
63 add tsmc28 8 13787 0.07226709545223761 33.012 176.194 12.328766484151734
64 add tsmc28 16 11520 0.08680155555555555 90.972001 475.452 33.67900355555555
65 add tsmc28 32 9810 0.1019177991845056 209.286002 1060.0 81.43232154841998
66 add tsmc28 64 8203 0.12186861952944045 392.616003 1800.0 142.34254761038645
67 add tsmc28 128 7210 0.13869425520110956 868.140006 4090.0 331.3405756754508
68 csa tsmc28 8 23865 0.04077636748376283 49.392 473.393 20.91827651917033
69 csa tsmc28 16 23865 0.04077636748376283 98.783999 946.879 41.75500030337314
70 csa tsmc28 32 23865 0.04077636748376283 197.567999 1890.0 83.30611876932745
71 csa tsmc28 64 23865 0.04077636748376283 395.135998 3790.0 166.5306848036874
72 csa tsmc28 128 23865 0.04077636748376283 790.271996 7570.0 333.1021459748586
73 shiftleft tsmc28 8 15183 0.06578013640255549 48.384 333.876 15.51753417736284
74 shiftleft tsmc28 16 11800 0.0847177627118644 130.788 613.549 33.71766955932203
75 shiftleft tsmc28 32 9587 0.10430391697089808 384.803997 1940.0 101.80062296359652
76 shiftleft tsmc28 64 8269 0.12088260744951022 967.427998 4980.0 272.83204501354453
77 shiftleft tsmc28 128 7023 0.14238329232521713 1836.953994 8670.0 566.543120162039
78 comparator tsmc28 8 17054 0.05854826984871585 32.256 160.477 8.752966342383019
79 comparator tsmc28 16 13709 0.07280278080093369 48.132 204.944 11.852292714392004
80 comparator tsmc28 32 12136 0.08238147264337507 146.16 623.674 35.50641470929466
81 comparator tsmc28 64 10862 0.09205807659731172 291.312 1240.0 69.41178975437303
82 comparator tsmc28 128 9371 0.10671119720414043 558.432 2400.0 127.9467254477644
83 flop tsmc28 8 10 0.048889000000002625 15.12 78.6345 0.013320296940000717
84 flop tsmc28 16 10 0.048889000000002625 30.24 157.29 0.026541838100001425
85 flop tsmc28 32 10 0.048889000000002625 60.4799995 314.5805 0.05332812120000287
86 flop tsmc28 64 10 0.048889000000002625 120.959999 630.0 0.10640935295000573
87 flop tsmc28 128 10 0.048889000000002625 241.919998 1260.0 0.21305826200001143
88 mux2 tsmc28 1 50000 0.019658000000000002 2.142 15.112 0.5917058000000001
89 mux2 tsmc28 8 29041 0.033768075961571574 16.884 113.726 5.335356001928308
90 mux2 tsmc28 16 19059 0.05221864998163597 15.75 88.448 5.133093293194816
91 mux2 tsmc28 32 17903 0.05585556035301346 32.130001 171.146 9.897605294553983
92 mux2 tsmc28 64 18546 0.05385698274560552 90.846 517.414 27.359347234767604
93 mux2 tsmc28 128 16594 0.0601057455706882 184.968 1150.0 58.603101931421
94 mux4 tsmc28 1 26255 0.03808798324128737 5.292 41.928 1.7101504475338032
95 mux4 tsmc28 8 18130 0.05509219801434087 27.971999 133.963 8.021424030888031
96 mux4 tsmc28 16 16440 0.06065625060827251 39.438 185.149 12.373875124087593
97 mux4 tsmc28 32 15168 0.0658052700421941 69.174 324.969 23.229260324894515
98 mux4 tsmc28 64 13915 0.07180589399928135 137.465999 648.086 45.59674268954365
99 mux4 tsmc28 128 13089 0.07639603056001222 296.603997 1440.0 94.50188980273512
100 mux8 tsmc28 1 16320 0.05991150980392156 7.182 38.342 1.8428780415686272
101 mux8 tsmc28 8 12885 0.07750962359332557 44.856 215.13 11.90547818393481
102 mux8 tsmc28 16 12256 0.08154268929503918 121.841998 521.624 25.93057519582246
103 mux8 tsmc28 32 11695 0.08537362676357418 168.21 815.694 46.35787933262078
104 mux8 tsmc28 64 11000 0.0907930909090909 304.037999 1490.0 81.89536799999999
105 mux8 tsmc28 128 10464 0.09547474923547401 664.775992 2850.0 153.04602302446486
106 mult tsmc28 8 5000 0.19998100000000002 444.150001 3260.0 306.970835
107 mult tsmc28 16 3819 0.26184265147944485 1634.472002 11800.0 1455.3214569227544
108 mult tsmc28 32 2973 0.3363555785401951 5141.430011 36900.0 5416.333881232761
109 mult tsmc28 64 2390 0.4184090418410042 16045.092071 109000.0 18545.980779602512
110 mult tsmc28 128 1868 0.5353279057815846 44272.49428 262000.0 50011.4036139272
111 mux2d tsmc28 1 51887 0.018931650182126544 3.276 26.574 0.9106123737602868
112 mux4d tsmc28 1 32558 0.03008041734750292 4.158 30.464 1.2543534033908719
113 mux8d tsmc28 1 21936 0.045586162654996355 20.664 171.151 6.614552201239972

File diff suppressed because it is too large Load Diff

View File

@ -245,7 +245,7 @@ def oneMetricPlot(module, var, freq=None, ax=None, fits='clsgn', norm=True, colo
ax.add_artist(ax.legend(handles=fullLeg, loc=legLoc))
titleStr = " (target " + str(freq)+ "MHz)" if freq != None else " (best achievable delay)"
ax.set_title(module + titleStr)
plt.savefig('./plots/PPA/'+ module + '_' + var + '.png')
plt.savefig('.plots/'+ module + '_' + var + '.png')
# plt.show()
return r2
@ -550,7 +550,7 @@ def plotPPA(mod, freq=None, norm=True, aleOpt=False):
if freq != 10:
n = 'normalized' if norm else 'unnormalized'
saveStr = './plots/PPA/'+ n + '/' + mod + '.png'
saveStr = './plots/'+ n + '/' + mod + '.png'
plt.savefig(saveStr)
# plt.show()
@ -563,7 +563,7 @@ def makeLineLegend():
fullLeg += [lines.Line2D([0], [0], color='green', label='sky90', marker='o')]
fullLeg += [lines.Line2D([0], [0], color='red', label='combined', marker='_')]
fig.legend(handles=fullLeg, ncol=5, handlelength=1.4, loc='center')
saveStr = './plots/PPA/legend.png'
saveStr = './plots/legend.png'
plt.savefig(saveStr)
def muxPlot(fits='clsgn', norm=True):
@ -616,7 +616,7 @@ def muxPlot(fits='clsgn', norm=True):
ax.set_title('mux timing')
ax.legend(handles = fullLeg)
plt.savefig('./plots/PPA/mux.png')
plt.savefig('./plots/mux.png')
def stdDevError():
for var in ['delay', 'area', 'lpower', 'denergy']:

View File

@ -102,7 +102,8 @@ set_critical_range [expr $my_period*0.05] $current_design
# Partitioning - flatten or hierarchically synthesize
if { $maxopt == 1 } {
ungroup -all -flatten -simple_names
ungroup -all -simple_names
# -flatten
}
# Set input pins except clock

View File

@ -857,6 +857,7 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a
addi a6, a6, 8
.endm
// Place this macro in peripheral tests to setup all the PLIC registers to generate external interrupts
.macro SETUP_PLIC
# Setup PLIC with a series of register writes