mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-02 17:55:19 +00:00
merge upstream synth changes
This commit is contained in:
commit
9c3aa55349
3
.gitignore
vendored
3
.gitignore
vendored
@ -101,3 +101,6 @@ sim/branch.log
|
||||
/fpga/generator/sim/syn-funcsim.v
|
||||
external
|
||||
sim/results
|
||||
tests/wally-riscv-arch-test/riscv-test-suite/rv*i_m/I/src/*.S
|
||||
tests/wally-riscv-arch-test/riscv-test-suite/rv*i_m/I/Makefrag
|
||||
|
||||
|
@ -209,6 +209,12 @@ It is most convenient if the sysadmin installs riscof into the server’s Python
|
||||
|
||||
However, riscof can also be installed and run locally by individual users.
|
||||
|
||||
### Other Python libraries
|
||||
|
||||
While a sysadmin is installing Python libraries, it's worth doing some more that will be needed by visualization scripts.
|
||||
|
||||
$ sudo pip3 install matplotlib scipy sklearn adjustText lief
|
||||
|
||||
### Install Verilator
|
||||
|
||||
Verilator is a free Verilog simulator with a good Lint tool used to catch errors in the SystemVerilog code. It is needed to run regression.
|
||||
|
@ -40,8 +40,9 @@
|
||||
`define ZICSR_SUPPORTED 1
|
||||
`define ZIFENCEI_SUPPORTED 1
|
||||
`define ZICOUNTERS_SUPPORTED 1
|
||||
`define ZFH_SUPPORTED 0
|
||||
`define COUNTERS 32
|
||||
`define ZFH_SUPPORTED 0
|
||||
`define SSTC_SUPPORTED 1
|
||||
|
||||
// LSU microarchitectural Features
|
||||
`define BUS_SUPPORTED 1
|
||||
|
@ -43,6 +43,7 @@
|
||||
`define ZICOUNTERS_SUPPORTED 1
|
||||
`define ZFH_SUPPORTED 0
|
||||
`define COUNTERS 32
|
||||
`define SSTC_SUPPORTED 1
|
||||
|
||||
// LSU microarchitectural Features
|
||||
`define BUS_SUPPORTED 1
|
||||
|
@ -44,6 +44,7 @@
|
||||
`define COUNTERS 0
|
||||
`define ZICOUNTERS_SUPPORTED 0
|
||||
`define ZFH_SUPPORTED 0
|
||||
`define SSTC_SUPPORTED 0
|
||||
|
||||
// LSU microarchitectural Features
|
||||
`define BUS_SUPPORTED 1
|
||||
|
@ -43,6 +43,7 @@
|
||||
`define COUNTERS 32
|
||||
`define ZICOUNTERS_SUPPORTED 1
|
||||
`define ZFH_SUPPORTED 0
|
||||
`define SSTC_SUPPORTED 0
|
||||
|
||||
// LSU microarchitectural Features
|
||||
`define BUS_SUPPORTED 1
|
||||
|
@ -44,6 +44,7 @@
|
||||
`define COUNTERS 32
|
||||
`define ZICOUNTERS_SUPPORTED 0
|
||||
`define ZFH_SUPPORTED 0
|
||||
`define SSTC_SUPPORTED 0
|
||||
|
||||
// LSU microarchitectural Features
|
||||
`define BUS_SUPPORTED 0
|
||||
|
@ -43,6 +43,7 @@
|
||||
`define COUNTERS 32
|
||||
`define ZICOUNTERS_SUPPORTED 1
|
||||
`define ZFH_SUPPORTED 0
|
||||
`define SSTC_SUPPORTED 0
|
||||
|
||||
// LSU microarchitectural Features
|
||||
`define BUS_SUPPORTED 1
|
||||
|
@ -44,6 +44,7 @@
|
||||
`define COUNTERS 32
|
||||
`define ZICOUNTERS_SUPPORTED 1
|
||||
`define ZFH_SUPPORTED 1
|
||||
`define SSTC_SUPPORTED 0
|
||||
|
||||
// LSU microarchitectural Features
|
||||
`define BUS_SUPPORTED 1
|
||||
|
@ -44,6 +44,7 @@
|
||||
`define COUNTERS 32
|
||||
`define ZICOUNTERS_SUPPORTED 1
|
||||
`define ZFH_SUPPORTED 0
|
||||
`define SSTC_SUPPORTED 0
|
||||
|
||||
// LSU microarchitectural Features
|
||||
`define BUS_SUPPORTED 1
|
||||
|
@ -44,6 +44,7 @@
|
||||
`define COUNTERS 32
|
||||
`define ZICOUNTERS_SUPPORTED 0
|
||||
`define ZFH_SUPPORTED 0
|
||||
`define SSTC_SUPPORTED 0
|
||||
|
||||
// LSU microarchitectural Features
|
||||
`define BUS_SUPPORTED 0
|
||||
|
@ -49,7 +49,7 @@ module fdivsqrtpostproc(
|
||||
logic [`DIVb+3:0] W, Sum, DM;
|
||||
logic [`DIVb:0] PreQmM;
|
||||
logic NegStickyM;
|
||||
logic weq0E, weq0M, WZeroM;
|
||||
logic weq0E, WZeroM;
|
||||
logic [`XLEN-1:0] IntDivResultM;
|
||||
|
||||
//////////////////////////
|
||||
@ -81,7 +81,6 @@ module fdivsqrtpostproc(
|
||||
//////////////////////////
|
||||
|
||||
flopenr #(1) WZeroMReg(clk, reset, ~StallM, WZeroE, WZeroM);
|
||||
flopenr #(1) WeqZeroMReg(clk, reset, ~StallM, weq0E, weq0M);
|
||||
|
||||
//////////////////////////
|
||||
// Memory Stage: Postprocessing
|
||||
|
@ -110,6 +110,7 @@ module fpu (
|
||||
logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage
|
||||
logic XInfM, YInfM, ZInfM; // is the input infinity - memory stage
|
||||
logic XExpMaxE; // is the exponent all ones (max value)
|
||||
logic [`FLEN-1:0] XPostBoxE; // X after fixing bad NaN box. Needed for 1-input operations
|
||||
|
||||
// Fma Signals
|
||||
logic FmaAddSubE; // Multiply by 1.0 when adding or subtracting
|
||||
@ -200,23 +201,20 @@ module fpu (
|
||||
mux3 #(`FLEN) fzemux (FRD3E, FResultW, PreFpResM, ForwardZE, PreZE);
|
||||
|
||||
// Select NAN-boxed value of Y = 1.0 in proper format for fma to add/subtract X*Y+Z
|
||||
generate
|
||||
if(`FPSIZES == 1) assign BoxedOneE = {2'b0, {`NE-1{1'b1}}, (`NF)'(0)};
|
||||
else if(`FPSIZES == 2)
|
||||
mux2 #(`FLEN) fonemux ({{`FLEN-`LEN1{1'b1}}, 2'b0, {`NE1-1{1'b1}}, (`NF1)'(0)}, {2'b0, {`NE-1{1'b1}}, (`NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes
|
||||
else if(`FPSIZES == 3 | `FPSIZES == 4)
|
||||
mux4 #(`FLEN) fonemux ({{`FLEN-`S_LEN{1'b1}}, 2'b0, {`S_NE-1{1'b1}}, (`S_NF)'(0)},
|
||||
{{`FLEN-`D_LEN{1'b1}}, 2'b0, {`D_NE-1{1'b1}}, (`D_NF)'(0)},
|
||||
{{`FLEN-`H_LEN{1'b1}}, 2'b0, {`H_NE-1{1'b1}}, (`H_NF)'(0)},
|
||||
{2'b0, {`NE-1{1'b1}}, (`NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes
|
||||
endgenerate
|
||||
if(`FPSIZES == 1) assign BoxedOneE = {2'b0, {`NE-1{1'b1}}, (`NF)'(0)};
|
||||
else if(`FPSIZES == 2)
|
||||
mux2 #(`FLEN) fonemux ({{`FLEN-`LEN1{1'b1}}, 2'b0, {`NE1-1{1'b1}}, (`NF1)'(0)}, {2'b0, {`NE-1{1'b1}}, (`NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes
|
||||
else if(`FPSIZES == 3 | `FPSIZES == 4)
|
||||
mux4 #(`FLEN) fonemux ({{`FLEN-`S_LEN{1'b1}}, 2'b0, {`S_NE-1{1'b1}}, (`S_NF)'(0)},
|
||||
{{`FLEN-`D_LEN{1'b1}}, 2'b0, {`D_NE-1{1'b1}}, (`D_NF)'(0)},
|
||||
{{`FLEN-`H_LEN{1'b1}}, 2'b0, {`H_NE-1{1'b1}}, (`H_NF)'(0)},
|
||||
{2'b0, {`NE-1{1'b1}}, (`NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes
|
||||
assign FmaAddSubE = OpCtrlE[2]&OpCtrlE[1]&(FResSelE==2'b01)&(PostProcSelE==2'b10);
|
||||
mux2 #(`FLEN) fyaddmux (PreYE, BoxedOneE, FmaAddSubE, YE); // Force Y to be 1 for add/subtract
|
||||
|
||||
// Select NAN-boxed value of Z = 0.0 in proper format for FMA for multiply X*Y+Z
|
||||
// For add and subtract, Z comes from second source operand
|
||||
generate
|
||||
if(`FPSIZES == 1) assign BoxedZeroE = 0;
|
||||
if(`FPSIZES == 1) assign BoxedZeroE = 0;
|
||||
else if(`FPSIZES == 2)
|
||||
mux2 #(`FLEN) fmulzeromux ({{`FLEN-`LEN1{1'b1}}, {`LEN1{1'b0}}}, (`FLEN)'(0), FmtE, BoxedZeroE); // NaN boxing zeroes
|
||||
else if(`FPSIZES == 3 | `FPSIZES == 4)
|
||||
@ -224,7 +222,6 @@ module fpu (
|
||||
{{`FLEN-`D_LEN{1'b1}}, {`D_LEN{1'b0}}},
|
||||
{{`FLEN-`H_LEN{1'b1}}, {`H_LEN{1'b0}}},
|
||||
(`FLEN)'(0), FmtE, BoxedZeroE); // NaN boxing zeroes
|
||||
endgenerate
|
||||
assign FmaZSelE = {OpCtrlE[2]&OpCtrlE[1], OpCtrlE[2]&~OpCtrlE[1]};
|
||||
mux3 #(`FLEN) fzmulmux (PreZE, BoxedZeroE, PreYE, FmaZSelE, ZE);
|
||||
|
||||
@ -234,7 +231,7 @@ module fpu (
|
||||
.XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XEn(XEnE),
|
||||
.YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XSubnorm(XSubnormE),
|
||||
.XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE),
|
||||
.ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE));
|
||||
.ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE), .XPostBox(XPostBoxE));
|
||||
|
||||
// fused multiply add: fadd/sub, fmul, fmadd/fnmadd/fmsub/fnmsub
|
||||
fma fma (.Xs(XsE), .Ys(YsE), .Zs(ZsE), .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE),
|
||||
@ -255,7 +252,7 @@ module fpu (
|
||||
.CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE));
|
||||
|
||||
// sign injection: fsgnj/fsgnjx/fsgnjn
|
||||
fsgninj fsgninj(.OpCtrl(OpCtrlE[1:0]), .Xs(XsE), .Ys(YsE), .X(XE), .Fmt(FmtE), .SgnRes(SgnResE));
|
||||
fsgninj fsgninj(.OpCtrl(OpCtrlE[1:0]), .Xs(XsE), .Ys(YsE), .X(XPostBoxE), .Fmt(FmtE), .SgnRes(SgnResE));
|
||||
|
||||
// classify: fclass
|
||||
fclassify fclassify (.Xs(XsE), .XSubnorm(XSubnormE), .XZero(XZeroE), .XNaN(XNaNE),
|
||||
@ -268,7 +265,6 @@ module fpu (
|
||||
|
||||
|
||||
// NaN Box SrcA to convert integer to requested FP size
|
||||
generate
|
||||
if(`FPSIZES == 1) assign AlignedSrcAE = {{`FLEN-`XLEN{1'b1}}, ForwardedSrcAE};
|
||||
else if(`FPSIZES == 2)
|
||||
mux2 #(`FLEN) SrcAMux ({{`FLEN-`LEN1{1'b1}}, ForwardedSrcAE[`LEN1-1:0]}, {{`FLEN-`XLEN{1'b1}}, ForwardedSrcAE}, FmtE, AlignedSrcAE);
|
||||
@ -277,14 +273,12 @@ module fpu (
|
||||
{{`FLEN-`D_LEN{1'b1}}, ForwardedSrcAE[`D_LEN-1:0]},
|
||||
{{`FLEN-`H_LEN{1'b1}}, ForwardedSrcAE[`H_LEN-1:0]},
|
||||
{{`FLEN-`XLEN{1'b1}}, ForwardedSrcAE}, FmtE, AlignedSrcAE); // NaN boxing zeroes
|
||||
endgenerate
|
||||
|
||||
// select a result that may be written to the FP register
|
||||
mux3 #(`FLEN) FResMux(SgnResE, AlignedSrcAE, CmpFpResE, {OpCtrlE[2], &OpCtrlE[1:0]}, PreFpResE);
|
||||
assign PreNVE = CmpNVE&(OpCtrlE[2]|FWriteIntE);
|
||||
|
||||
// select the result that may be written to the integer register - to IEU
|
||||
generate
|
||||
if(`FPSIZES == 1)
|
||||
assign SgnExtXE = XE;
|
||||
else if(`FPSIZES == 2)
|
||||
@ -294,7 +288,7 @@ module fpu (
|
||||
{{`FLEN-`S_LEN{XsE}}, XE[`S_LEN-1:0]},
|
||||
{{`FLEN-`D_LEN{XsE}}, XE[`D_LEN-1:0]},
|
||||
XE, FmtE, SgnExtXE);
|
||||
endgenerate
|
||||
|
||||
if (`FLEN>`XLEN)
|
||||
assign IntSrcXE = SgnExtXE[`XLEN-1:0];
|
||||
else
|
||||
|
@ -39,7 +39,8 @@ module unpack (
|
||||
output logic XSubnorm, // is X subnormal
|
||||
output logic XZero, YZero, ZZero, // is XYZ zero
|
||||
output logic XInf, YInf, ZInf, // is XYZ infinity
|
||||
output logic XExpMax // does X have the maximum exponent (NaN or Inf)
|
||||
output logic XExpMax, // does X have the maximum exponent (NaN or Inf)
|
||||
output logic [`FLEN-1:0] XPostBox // X after being properly NaN-boxed
|
||||
);
|
||||
|
||||
logic XExpNonZero, YExpNonZero, ZExpNonZero; // is the exponent of XYZ non-zero
|
||||
@ -48,14 +49,17 @@ module unpack (
|
||||
|
||||
unpackinput unpackinputX (.In(X), .Fmt, .Sgn(Xs), .Exp(Xe), .Man(Xm), .En(XEn),
|
||||
.NaN(XNaN), .SNaN(XSNaN), .ExpNonZero(XExpNonZero),
|
||||
.Zero(XZero), .Inf(XInf), .ExpMax(XExpMax), .FracZero(XFracZero), .Subnorm(XSubnorm));
|
||||
.Zero(XZero), .Inf(XInf), .ExpMax(XExpMax), .FracZero(XFracZero),
|
||||
.Subnorm(XSubnorm), .PostBox(XPostBox));
|
||||
|
||||
unpackinput unpackinputY (.In(Y), .Fmt, .Sgn(Ys), .Exp(Ye), .Man(Ym), .En(YEn),
|
||||
.NaN(YNaN), .SNaN(YSNaN), .ExpNonZero(YExpNonZero),
|
||||
.Zero(YZero), .Inf(YInf), .ExpMax(YExpMax), .FracZero(YFracZero), .Subnorm());
|
||||
.Zero(YZero), .Inf(YInf), .ExpMax(YExpMax), .FracZero(YFracZero),
|
||||
.Subnorm(), .PostBox());
|
||||
|
||||
unpackinput unpackinputZ (.In(Z), .Fmt, .Sgn(Zs), .Exp(Ze), .Man(Zm), .En(ZEn),
|
||||
.NaN(ZNaN), .SNaN(ZSNaN), .ExpNonZero(ZExpNonZero),
|
||||
.Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero), .Subnorm());
|
||||
.Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero),
|
||||
.Subnorm(), .PostBox());
|
||||
|
||||
endmodule
|
@ -40,13 +40,14 @@ module unpackinput (
|
||||
output logic Inf, // is the number infinity
|
||||
output logic ExpNonZero, // is the exponent not zero
|
||||
output logic FracZero, // is the fraction zero
|
||||
output logic ExpMax, // does In have the maximum exponent (NaN or Inf)
|
||||
output logic Subnorm // is the number subnormal
|
||||
output logic ExpMax, // does In have the maximum exponent (NaN or Inf)
|
||||
output logic Subnorm, // is the number subnormal
|
||||
output logic [`FLEN-1:0] PostBox // Number reboxed correctly as a NaN
|
||||
);
|
||||
|
||||
logic [`NF-1:0] Frac; // Fraction of XYZ
|
||||
logic BadNaNBox; // is the NaN boxing bad
|
||||
|
||||
logic BadNaNBox; // incorrectly NaN Boxed
|
||||
|
||||
if (`FPSIZES == 1) begin // if there is only one floating point format supported
|
||||
assign BadNaNBox = 0;
|
||||
assign Sgn = In[`FLEN-1]; // sign bit
|
||||
@ -54,6 +55,7 @@ module unpackinput (
|
||||
assign ExpNonZero = |In[`FLEN-2:`NF]; // is the exponent non-zero
|
||||
assign Exp = {In[`FLEN-2:`NF+1], In[`NF]|~ExpNonZero}; // exponent. subnormal numbers have effective biased exponent of 1
|
||||
assign ExpMax = &In[`FLEN-2:`NF]; // is the exponent all 1's
|
||||
assign PostBox = In;
|
||||
|
||||
end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported
|
||||
// largest format | smaller format
|
||||
@ -75,9 +77,15 @@ module unpackinput (
|
||||
// double and half
|
||||
|
||||
assign BadNaNBox = ~(Fmt|(&In[`FLEN-1:`LEN1])); // Check NaN boxing
|
||||
always_comb
|
||||
if (BadNaNBox) begin
|
||||
// PostBox = {{(`FLEN-`LEN1){1'b1}}, 1'b1, {(`NE1+1){1'b1}}, In[`LEN1-`NE1-3:0]};
|
||||
PostBox = {{(`FLEN-`LEN1){1'b1}}, 1'b1, {(`NE1+1){1'b1}}, {(`LEN1-`NE1-2){1'b0}}};
|
||||
end else
|
||||
PostBox = In;
|
||||
|
||||
// choose sign bit depending on format - 1=larger precsion 0=smaller precision
|
||||
assign Sgn = Fmt ? In[`FLEN-1] : In[`LEN1-1];
|
||||
assign Sgn = Fmt ? In[`FLEN-1] : (BadNaNBox ? 0 : In[`LEN1-1]); // improperly boxed NaNs are treated as positive
|
||||
|
||||
// extract the fraction, add trailing zeroes to the mantissa if nessisary
|
||||
assign Frac = Fmt ? In[`NF-1:0] : {In[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||
@ -128,8 +136,23 @@ module unpackinput (
|
||||
default: BadNaNBox = 1'bx;
|
||||
endcase
|
||||
|
||||
always_comb
|
||||
if (BadNaNBox) begin
|
||||
case (Fmt)
|
||||
`FMT: PostBox = In;
|
||||
// `FMT1: PostBox = {{(`FLEN-`LEN1){1'b1}}, 1'b1, {(`NE1+1){1'b1}}, In[`LEN1-`NE1-3:0]};
|
||||
// `FMT2: PostBox = {{(`FLEN-`LEN2){1'b1}}, 1'b1, {(`NE2+1){1'b1}}, In[`LEN2-`NE2-3:0]};
|
||||
`FMT1: PostBox = {{(`FLEN-`LEN1){1'b1}}, 1'b1, {(`NE1+1){1'b1}}, {(`LEN1-`NE1-2){1'b0}}};
|
||||
`FMT2: PostBox = {{(`FLEN-`LEN2){1'b1}}, 1'b1, {(`NE2+1){1'b1}}, {(`LEN2-`NE2-2){1'b0}}};
|
||||
default: PostBox = 'x;
|
||||
endcase
|
||||
end else
|
||||
PostBox = In;
|
||||
|
||||
// extract the sign bit
|
||||
always_comb
|
||||
if (BadNaNBox) Sgn = 0; // improperly boxed NaNs are treated as positive
|
||||
else
|
||||
case (Fmt)
|
||||
`FMT: Sgn = In[`FLEN-1];
|
||||
`FMT1: Sgn = In[`LEN1-1];
|
||||
@ -137,7 +160,7 @@ module unpackinput (
|
||||
default: Sgn = 1'bx;
|
||||
endcase
|
||||
|
||||
// extract the fraction
|
||||
// extract the fraction
|
||||
always_comb
|
||||
case (Fmt)
|
||||
`FMT: Frac = In[`NF-1:0];
|
||||
@ -200,8 +223,24 @@ module unpackinput (
|
||||
2'b10: BadNaNBox = ~&In[`Q_LEN-1:`H_LEN];
|
||||
endcase
|
||||
|
||||
always_comb
|
||||
if (BadNaNBox) begin
|
||||
case (Fmt)
|
||||
2'b11: PostBox = In;
|
||||
// 2'b01: PostBox = {{(`Q_LEN-`D_LEN){1'b1}}, 1'b1, {(`D_NE+1){1'b1}}, In[`D_LEN-`D_NE-3:0]};
|
||||
// 2'b00: PostBox = {{(`Q_LEN-`S_LEN){1'b1}}, 1'b1, {(`S_NE+1){1'b1}}, In[`S_LEN-`S_NE-3:0]};
|
||||
// 2'b10: PostBox = {{(`Q_LEN-`H_LEN){1'b1}}, 1'b1, {(`H_NE+1){1'b1}}, In[`H_LEN-`H_NE-3:0]};
|
||||
2'b01: PostBox = {{(`Q_LEN-`D_LEN){1'b1}}, 1'b1, {(`D_NE+1){1'b1}}, {(`D_LEN-`D_NE-2){1'b0}}};
|
||||
2'b00: PostBox = {{(`Q_LEN-`S_LEN){1'b1}}, 1'b1, {(`S_NE+1){1'b1}}, {(`S_LEN-`S_NE-2){1'b0}}};
|
||||
2'b10: PostBox = {{(`Q_LEN-`H_LEN){1'b1}}, 1'b1, {(`H_NE+1){1'b1}}, {(`H_LEN-`H_NE-2){1'b0}}};
|
||||
endcase
|
||||
end else
|
||||
PostBox = In;
|
||||
|
||||
// extract sign bit
|
||||
always_comb
|
||||
if (BadNaNBox) Sgn = 0; // improperly boxed NaNs are treated as positive
|
||||
else
|
||||
case (Fmt)
|
||||
2'b11: Sgn = In[`Q_LEN-1];
|
||||
2'b01: Sgn = In[`D_LEN-1];
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module ram1p1rwbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) (
|
||||
input logic clk,
|
||||
input logic ce,
|
||||
input logic [$clog2(DEPTH)-1:0] addr,
|
||||
@ -49,7 +49,7 @@ module ram1p1rwbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
// ***************************************************************************
|
||||
// TRUE SRAM macro
|
||||
// ***************************************************************************
|
||||
if (`USE_SRAM == 1 && WIDTH == 128 && DEPTH == 64) begin
|
||||
if ((`USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray
|
||||
genvar index;
|
||||
// 64 x 128-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
@ -58,8 +58,8 @@ module ram1p1rwbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
TS1N28HPCPSVTB64X128M4SW sram1A (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
|
||||
end else if (`USE_SRAM == 1 && WIDTH == 44 && DEPTH == 64) begin
|
||||
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag
|
||||
genvar index;
|
||||
// 64 x 44-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
@ -69,17 +69,7 @@ module ram1p1rwbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
|
||||
end if (`USE_SRAM == 1 && WIDTH == 128 && DEPTH == 32) begin
|
||||
genvar index;
|
||||
// 64 x 128-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
for (index=0; index < WIDTH; index++)
|
||||
assign BitWriteMask[index] = bwe[index/8];
|
||||
TS1N28HPCPSVTB64X128M4SW sram1A (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||
.A(addr), .D(din),
|
||||
.BWEB(~BitWriteMask), .Q(dout));
|
||||
|
||||
end else if (`USE_SRAM == 1 && WIDTH == 22 && DEPTH == 32) begin
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag
|
||||
genvar index;
|
||||
// 64 x 22-bit SRAM
|
||||
logic [WIDTH-1:0] BitWriteMask;
|
||||
@ -96,9 +86,15 @@ module ram1p1rwbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
integer i;
|
||||
|
||||
// Read
|
||||
always_ff @(posedge clk)
|
||||
if(ce) dout <= #1 RAM[addr];
|
||||
|
||||
logic [$clog2(DEPTH)-1:0] addrd;
|
||||
flopen #($clog2(DEPTH)) adrreg(clk, ce, addr, addrd);
|
||||
assign dout = RAM[addrd];
|
||||
|
||||
/* // Read
|
||||
always_ff @(posedge clk)
|
||||
if(ce) dout <= #1 mem[addr]; */
|
||||
|
||||
|
||||
// Write divided into part for bytes and part for extra msbs
|
||||
// Questa sim version 2022.3_2 does not allow multiple drivers for RAM when using always_ff.
|
||||
// Therefore these always blocks use the older always @(posedge clk)
|
||||
|
@ -35,6 +35,7 @@ module ram1p1rwbe_64x128(
|
||||
);
|
||||
|
||||
// replace "generic64x128RAM" with "TS1N..64X128.." module from your memory vendor
|
||||
generic64x128RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q);
|
||||
//generic64x128RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q);
|
||||
TS1N28HPCPSVTB64X128M4SW sramIP(.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q);
|
||||
|
||||
endmodule
|
||||
|
@ -29,12 +29,14 @@ module ram1p1rwbe_64x22(
|
||||
input logic CEB,
|
||||
input logic WEB,
|
||||
input logic [5:0] A,
|
||||
input logic [127:0] D,
|
||||
input logic [127:0] BWEB,
|
||||
output logic [127:0] Q
|
||||
input logic [21:0] D,
|
||||
input logic [21:0] BWEB,
|
||||
output logic [21:0] Q
|
||||
);
|
||||
|
||||
// replace "generic64x22RAM" with "TS1N..64X22.." module from your memory vendor
|
||||
generic64x22RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q);
|
||||
// use part of a larger RAM to avoid generating more flavors of RAM
|
||||
TS1N28HPCPSVTB64X44M4SW sramIP(.CLK, .CEB, .WEB, .A, .D(D[21:0]), .BWEB(BWEB[21:0]), .Q(Q[21:0]));
|
||||
// genericRAM #(64, 22) sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q);
|
||||
|
||||
endmodule
|
||||
|
@ -29,12 +29,13 @@ module ram1p1rwbe_64x44(
|
||||
input logic CEB,
|
||||
input logic WEB,
|
||||
input logic [5:0] A,
|
||||
input logic [127:0] D,
|
||||
input logic [127:0] BWEB,
|
||||
output logic [127:0] Q
|
||||
input logic [43:0] D,
|
||||
input logic [43:0] BWEB,
|
||||
output logic [43:0] Q
|
||||
);
|
||||
|
||||
// replace "generic64x44RAM" with "TS1N..64X44.." module from your memory vendor
|
||||
generic64x44RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q);
|
||||
// generic64x44RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q);
|
||||
TS1N28HPCPSVTB64X44M4SW sramIP(.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q);
|
||||
|
||||
endmodule
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module ram2p1r1wbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) (
|
||||
input logic clk,
|
||||
input logic ce1, ce2,
|
||||
input logic [$clog2(DEPTH)-1:0] ra1,
|
||||
@ -52,7 +52,7 @@ module ram2p1r1wbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
// TRUE Smem macro
|
||||
// ***************************************************************************
|
||||
|
||||
if (`USE_SRAM == 1 && WIDTH == 68 && DEPTH == 1024) begin
|
||||
if ((`USE_SRAM == 1) & (WIDTH == 68) & (DEPTH == 1024)) begin
|
||||
|
||||
ram2p1r1wbe_1024x68 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
@ -64,7 +64,7 @@ module ram2p1r1wbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
|
||||
end if (`USE_SRAM == 1 && WIDTH == 36 && DEPTH == 1024) begin
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 36) & (DEPTH == 1024)) begin
|
||||
|
||||
ram2p1r1wbe_1024x36 memory1(.CLKA(clk), .CLKB(clk),
|
||||
.CEBA(~ce1), .CEBB(~ce2),
|
||||
@ -76,7 +76,7 @@ module ram2p1r1wbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
.QA(rd1),
|
||||
.QB());
|
||||
|
||||
end else if (`USE_SRAM == 1 && WIDTH == 2 && DEPTH == 1024) begin
|
||||
end else if ((`USE_SRAM == 1) & (WIDTH == 2) & (DEPTH == 1024)) begin
|
||||
|
||||
logic [SRAMWIDTH-1:0] SRAMReadData;
|
||||
logic [SRAMWIDTH-1:0] SRAMWriteData;
|
||||
@ -113,9 +113,14 @@ module ram2p1r1wbe #(parameter DEPTH=128, WIDTH=256) (
|
||||
// ***************************************************************************
|
||||
integer i;
|
||||
|
||||
// Read
|
||||
// Read
|
||||
logic [$clog2(DEPTH)-1:0] ra1d;
|
||||
flopen #($clog2(DEPTH)) adrreg(clk, ce1, ra1, ra1d);
|
||||
assign rd1 = mem[ra1d];
|
||||
|
||||
/* // Read
|
||||
always_ff @(posedge clk)
|
||||
if(ce1) rd1 <= #1 mem[ra1];
|
||||
if(ce1) rd1 <= #1 mem[ra1]; */
|
||||
|
||||
// Write divided into part for bytes and part for extra msbs
|
||||
if(WIDTH >= 8)
|
||||
|
@ -42,7 +42,11 @@ module ram2p1r1wbe_1024x36(
|
||||
);
|
||||
|
||||
// replace "generic1024x36RAM" with "TSDN..1024X36.." module from your memory vendor
|
||||
generic1024x36RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
//generic1024x36RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
// use part of a larger RAM to avoid generating more flavors of RAM
|
||||
TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA(DA[35:0]), .DB(DB[35:0]),
|
||||
.BWEBA(BWEBA[35:0]), .BWEBB(BWEBB[35:0]), .QA(QA[35:0]), .QB(QB[35:0]));
|
||||
|
||||
endmodule
|
||||
|
@ -42,7 +42,9 @@ module ram2p1r1wbe_1024x68(
|
||||
);
|
||||
|
||||
// replace "generic1024x68RAM" with "TSDN..1024X68.." module from your memory vendor
|
||||
generic1024x68RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
//generic1024x68RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
|
||||
endmodule
|
||||
|
@ -42,7 +42,8 @@ module ram2p1r1wbe_64x32(
|
||||
);
|
||||
|
||||
// replace "generic64x32RAM" with "TSDN..64X32.." module from your memory vendor
|
||||
generic64x32RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
//generic64x32RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
TSDN28HPCPA64X32M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
|
||||
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
|
||||
|
||||
endmodule
|
||||
|
@ -38,10 +38,10 @@ module rom1p1r #(parameter ADDR_WIDTH = 8,
|
||||
|
||||
// Core Memory
|
||||
logic [DATA_WIDTH-1:0] ROM [(2**ADDR_WIDTH)-1:0];
|
||||
if (`USE_SRAM == 1 && DATA_WIDTH == 64) begin
|
||||
if ((`USE_SRAM == 1) & (DATA_WIDTH == 64)) begin
|
||||
rom1p1r_128x64 rom1 (.CLK(clk), .CEB(~ce), .A(addr[6:0]), .Q(dout));
|
||||
|
||||
end if (`USE_SRAM == 1 && DATA_WIDTH == 32) begin
|
||||
end if ((`USE_SRAM == 1) & (DATA_WIDTH == 32)) begin
|
||||
rom1p1r_128x32 rom1 (.CLK(clk), .CEB(~ce), .A(addr[6:0]), .Q(dout));
|
||||
|
||||
end else begin
|
||||
|
@ -208,7 +208,7 @@ module bpred (
|
||||
// pipeline the class
|
||||
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD);
|
||||
flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE);
|
||||
|
||||
|
||||
// Check the prediction
|
||||
// if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address.
|
||||
// if the class prediction is wrong a regular instruction may have been predicted as a taken branch
|
||||
|
@ -113,6 +113,7 @@ module csr #(parameter
|
||||
logic SelMtvecM;
|
||||
logic [`XLEN-1:0] TVecAlignedM;
|
||||
logic InstrValidNotFlushedM;
|
||||
logic STimerInt;
|
||||
|
||||
// only valid unflushed instructions can access CSRs
|
||||
assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW;
|
||||
@ -201,7 +202,7 @@ module csr #(parameter
|
||||
|
||||
csri csri(.clk, .reset, .InstrValidNotFlushedM,
|
||||
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
|
||||
.MExtInt, .SExtInt, .MTimerInt, .MSwInt,
|
||||
.MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt,
|
||||
.MIP_REGW, .MIE_REGW, .MIP_REGW_writeable);
|
||||
|
||||
csrsr csrsr(.clk, .reset, .StallW,
|
||||
@ -227,11 +228,12 @@ module csr #(parameter
|
||||
csrs csrs(.clk, .reset, .InstrValidNotFlushedM,
|
||||
.CSRSWriteM, .STrapM, .CSRAdrM,
|
||||
.NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW,
|
||||
.STATUS_TVM, .CSRWriteValM, .PrivilegeModeW,
|
||||
.STATUS_TVM, .MCOUNTEREN_TM(MCOUNTEREN_REGW[1]),
|
||||
.CSRWriteValM, .PrivilegeModeW,
|
||||
.CSRSReadValM, .STVEC_REGW, .SEPC_REGW,
|
||||
.SCOUNTEREN_REGW,
|
||||
.SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
|
||||
.WriteSSTATUSM, .IllegalCSRSAccessM);
|
||||
.SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT,
|
||||
.WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt);
|
||||
end else begin
|
||||
assign WriteSSTATUSM = 0;
|
||||
assign CSRSReadValM = 0;
|
||||
|
@ -39,13 +39,14 @@ module csri #(parameter
|
||||
input logic CSRMWriteM, CSRSWriteM,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic MExtInt, SExtInt, MTimerInt, MSwInt,
|
||||
input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt,
|
||||
output logic [11:0] MIP_REGW, MIE_REGW,
|
||||
output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
|
||||
output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
|
||||
);
|
||||
|
||||
logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK;
|
||||
logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;
|
||||
logic STIP;
|
||||
|
||||
// Interrupt Write Enables
|
||||
assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM;
|
||||
@ -58,7 +59,13 @@ module csri #(parameter
|
||||
// SEIP, STIP, SSIP is writable in MIP if S mode exists
|
||||
// SSIP is writable in SIP if S mode exists
|
||||
if (`S_SUPPORTED) begin:mask
|
||||
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9)
|
||||
if (`SSTC_SUPPORTED) begin
|
||||
assign MIP_WRITE_MASK = 12'h202; // SEIP and SSIP are writable, but STIP is not writable when STIMECMP is implemented (see SSTC spec)
|
||||
assign STIP = STimerInt;
|
||||
end else begin
|
||||
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9)
|
||||
assign STIP = MIP_REGW_writeable[5];
|
||||
end
|
||||
assign SIP_WRITE_MASK = 12'h002; // SSIP is writeable in SIP (privileged 20210108-draft 4.1.3)
|
||||
assign MIE_WRITE_MASK = 12'hAAA;
|
||||
end else begin:mask
|
||||
@ -75,5 +82,8 @@ module csri #(parameter
|
||||
else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
|
||||
else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (MIE_REGW & 12'h888); // only S fields
|
||||
|
||||
assign MIP_REGW = {MExtInt,1'b0,SExtInt|MIP_REGW_writeable[9],1'b0,MTimerInt,1'b0,MIP_REGW_writeable[5],1'b0,MSwInt,1'b0,MIP_REGW_writeable[1],1'b0};
|
||||
|
||||
assign MIP_REGW = {MExtInt, 1'b0, SExtInt|MIP_REGW_writeable[9], 1'b0,
|
||||
MTimerInt, 1'b0, STIP, 1'b0,
|
||||
MSwInt, 1'b0, MIP_REGW_writeable[1], 1'b0};
|
||||
endmodule
|
||||
|
@ -41,22 +41,27 @@ module csrs #(parameter
|
||||
SCAUSE = 12'h142,
|
||||
STVAL = 12'h143,
|
||||
SIP= 12'h144,
|
||||
STIMECMP = 12'h14D,
|
||||
STIMECMPH = 12'h15D,
|
||||
SATP = 12'h180) (
|
||||
input logic clk, reset,
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRSWriteM, STrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
|
||||
input logic STATUS_TVM,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic clk, reset,
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRSWriteM, STrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
|
||||
input logic STATUS_TVM,
|
||||
input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
|
||||
output logic [`XLEN-1:0] SEPC_REGW,
|
||||
output logic [31:0] SCOUNTEREN_REGW,
|
||||
output logic [`XLEN-1:0] SATP_REGW,
|
||||
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
|
||||
output logic WriteSSTATUSM,
|
||||
output logic IllegalCSRSAccessM
|
||||
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
output logic WriteSSTATUSM,
|
||||
output logic IllegalCSRSAccessM,
|
||||
output logic STimerInt
|
||||
);
|
||||
|
||||
// Constants
|
||||
@ -66,10 +71,13 @@ module csrs #(parameter
|
||||
logic WriteSTVECM;
|
||||
logic WriteSSCRATCHM, WriteSEPCM;
|
||||
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
|
||||
logic WriteSTIMECMPM, WriteSTIMECMPHM;
|
||||
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
|
||||
logic [`XLEN-1:0] SCAUSE_REGW;
|
||||
logic [63:0] STIMECMP_REGW;
|
||||
|
||||
// write enables
|
||||
// *** can InstrValidNotFlushed be factored out of all these writes into CSRWriteM?
|
||||
assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS) & InstrValidNotFlushedM;
|
||||
assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC) & InstrValidNotFlushedM;
|
||||
assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH) & InstrValidNotFlushedM;
|
||||
@ -78,6 +86,8 @@ module csrs #(parameter
|
||||
assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)) & InstrValidNotFlushedM;
|
||||
assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == `M_MODE | ~STATUS_TVM) & InstrValidNotFlushedM;
|
||||
assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN) & InstrValidNotFlushedM;
|
||||
assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & MCOUNTEREN_TM & InstrValidNotFlushedM;
|
||||
assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & MCOUNTEREN_TM & (`XLEN == 32) & InstrValidNotFlushedM;
|
||||
|
||||
// CSRs
|
||||
flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW);
|
||||
@ -90,7 +100,20 @@ module csrs #(parameter
|
||||
else
|
||||
assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
|
||||
flopens #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW);
|
||||
if (`XLEN == 64)
|
||||
flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW);
|
||||
else begin
|
||||
flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW[31:0]);
|
||||
flopenr #(`XLEN) STIMECMPHreg(clk, reset, WriteSTIMECMPHM, CSRWriteValM, STIMECMP_REGW[63:32]);
|
||||
end
|
||||
|
||||
// Supervisor timer interrupt logic
|
||||
// Spec is a bit peculiar - Machine timer interrupts are produced in CLINT, while Supervisor timer interrupts are in CSRs
|
||||
if (`SSTC_SUPPORTED)
|
||||
assign STimerInt = ({1'b0, MTIME_CLINT} >= {1'b0, STIMECMP_REGW}); // unsigned comparison
|
||||
else
|
||||
assign STimerInt = 0;
|
||||
|
||||
// CSR Reads
|
||||
always_comb begin:csrr
|
||||
IllegalCSRSAccessM = 0;
|
||||
@ -109,10 +132,20 @@ module csrs #(parameter
|
||||
if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1;
|
||||
end
|
||||
SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW};
|
||||
STIMECMP: if (MCOUNTEREN_TM) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0];
|
||||
else begin
|
||||
CSRSReadValM = 0;
|
||||
IllegalCSRSAccessM = 1;
|
||||
end
|
||||
STIMECMPH: if (MCOUNTEREN_TM & (`XLEN == 32)) CSRSReadValM[31:0] = STIMECMP_REGW[63:32];
|
||||
else begin // not supported for RV64
|
||||
CSRSReadValM = 0;
|
||||
IllegalCSRSAccessM = 1;
|
||||
end
|
||||
default: begin
|
||||
CSRSReadValM = 0;
|
||||
IllegalCSRSAccessM = 1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
@ -68,7 +68,7 @@ module csrsr (
|
||||
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
|
||||
STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE,
|
||||
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
|
||||
assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be.
|
||||
assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be.
|
||||
end else begin: csrsr32 // RV32
|
||||
assign MSTATUS_REGW = {STATUS_SD, 8'b0,
|
||||
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
|
@ -20,6 +20,20 @@ if {$tech == "sky130"} {
|
||||
} elseif {$tech == "tsmc28"} {
|
||||
set s10lib /proj/models/tsmc28/libraries/28nmtsmc/tcbn28hpcplusbwp30p140_190a/TSMCHOME/digital/Front_End/timing_power_noise/NLDM/tcbn28hpcplusbwp30p140_180a
|
||||
lappend search_path $s10lib
|
||||
} elseif {$tech == "tsmc28psyn"} {
|
||||
set TLU /home/jstine/TLU+
|
||||
set pdk /proj/models/tsmc28/libraries/28nmtsmc/tcbn28hpcplusbwp30p140_190a/
|
||||
set s10lib $pdk/TSMCHOME/digital/Front_End/timing_power_noise/NLDM/tcbn28hpcplusbwp30p140_180a
|
||||
lappend search_path $s10lib
|
||||
set TLUPLUS true
|
||||
set mw_logic1_net VDD
|
||||
set mw_logic0_net VSS
|
||||
set CAPTABLE $TLU/1p8m/
|
||||
set MW_REFERENCE_LIBRARY /home/jstine/MW
|
||||
set MW_TECH_FILE tcbn28hpcplusbwp30p140
|
||||
set MIN_TLU_FILE $CAPTABLE/crn28hpc+_1p08m+ut-alrdl_5x1z1u_rcbest.tluplus
|
||||
set MAX_TLU_FILE $CAPTABLE/crn28hpc+_1p08m+ut-alrdl_5x1z1u_rcworst.tluplus
|
||||
set PRS_MAP_FILE $MW_REFERENCE_LIBRARY/astro_layername.map
|
||||
}
|
||||
|
||||
# Synthetic libraries
|
||||
@ -48,11 +62,13 @@ set cache_read $cache_write
|
||||
lappend search_path ./scripts
|
||||
lappend search_path ./hdl
|
||||
lappend search_path ./mapped
|
||||
if {$tech == "tsmc28"} {
|
||||
if {$tech == "tsmc28" || $tech == "tsmc28psyn"} {
|
||||
set memory /home/jstine/WallyMem/rv64gc/
|
||||
lappend target_library $memory/ts3n28hpcpa128x64m8m_130a/NLDM/ts3n28hpcpa128x64m8m_tt0p9v25c.db
|
||||
lappend target_library $memory/ts1n28hpcpsvtb64x128m4sw_180a/NLDM/ts1n28hpcpsvtb64x128m4sw_tt0p9v25c.db
|
||||
lappend target_library $memory/ts1n28hpcpsvtb64x44m4sw_180a/NLDM/ts1n28hpcpsvtb64x44m4sw_tt0p9v25c.db
|
||||
lappend target_library $memory/tsdn28hpcpa1024x68m4mw_130a/NLDM/tsdn28hpcpa1024x68m4mw_tt0p9v25c.db
|
||||
lappend target_library $memory/tsdn28hpcpa64x32m4mw_130a/NLDM/tsdn28hpcpa64x32m4mw_tt0p9v25c.db
|
||||
}
|
||||
|
||||
# Set up User Information
|
||||
|
@ -20,7 +20,8 @@ export MAXCORES ?= 1
|
||||
# The output netlist is hard to interpret, but significantly better PPA
|
||||
export MAXOPT ?= 0
|
||||
export DRIVE ?= FLOP
|
||||
export USESRAM ?= 1
|
||||
export USESRAM ?= 0
|
||||
export USETOPO ?= 0
|
||||
|
||||
time := $(shell date +%F-%H-%M)
|
||||
hash := $(shell git rev-parse --short HEAD)
|
||||
@ -84,6 +85,14 @@ endif
|
||||
endif
|
||||
|
||||
# adjust config if synthesizing with any modifications
|
||||
# This code is subtle with ifneq. It successively turns off a larger
|
||||
# set of features in order of cycle time limiting.
|
||||
# When mod = orig, all features are ON
|
||||
# When mod = PMP0, the number of PMP entries is set to 0
|
||||
# when mod = noPriv, the privileged unit and PMP are disabled
|
||||
# when mod = noFPU, the FPU, privileged unit, and PMP are disabled
|
||||
# when mod = noMulDiv, the MDU, FPU, privileged unit, and PMP are disabled.
|
||||
|
||||
ifneq ($(MOD), orig)
|
||||
# PMP 0
|
||||
sed -i 's/PMP_ENTRIES \(64\|16\|0\)/PMP_ENTRIES 0/' $(CONFIGDIR)/wally-config.vh
|
||||
|
@ -85,7 +85,7 @@ def freqPlot(tech, width, config):
|
||||
freqsL, delaysL, areasL = ([[], []] for i in range(3))
|
||||
for oneSynth in allSynths:
|
||||
if (width == oneSynth.width) & (config == oneSynth.config) & (tech == oneSynth.tech) & ('orig' == oneSynth.mod):
|
||||
ind = (1000/oneSynth.delay < oneSynth.freq) # when delay is within target clock period
|
||||
ind = (1000/oneSynth.delay < (0.95*oneSynth.freq)) # when delay is within target clock period
|
||||
freqsL[ind] += [oneSynth.freq]
|
||||
delaysL[ind] += [oneSynth.delay]
|
||||
areasL[ind] += [oneSynth.area]
|
||||
@ -103,7 +103,7 @@ def freqPlot(tech, width, config):
|
||||
freqs = freqsL[ind]
|
||||
freqs, delays, areas = noOutliers(median, freqs, delays, areas)
|
||||
|
||||
c = 'blue' if ind else 'green'
|
||||
c = 'blue' if ind else 'gray'
|
||||
targs = [1000/f for f in freqs]
|
||||
|
||||
ax1.scatter(targs, delays, color=c)
|
||||
@ -113,7 +113,7 @@ def freqPlot(tech, width, config):
|
||||
delays = list(flatten(delaysL))
|
||||
areas = list(flatten(areasL))
|
||||
|
||||
legend_elements = [lines.Line2D([0], [0], color='green', ls='', marker='o', label='timing achieved'),
|
||||
legend_elements = [lines.Line2D([0], [0], color='gray', ls='', marker='o', label='timing achieved'),
|
||||
lines.Line2D([0], [0], color='blue', ls='', marker='o', label='slack violated')]
|
||||
|
||||
ax1.legend(handles=legend_elements)
|
||||
@ -246,8 +246,8 @@ if __name__ == '__main__':
|
||||
|
||||
TechSpec = namedtuple("TechSpec", "color shape targfreq fo4 add32area add32lpower add32denergy")
|
||||
techdict = {}
|
||||
techdict['sky90'] = TechSpec('green', 'o', args.skyfreq, 43.2e-3, 1440.600027, 714.057, 0.658023)
|
||||
techdict['tsmc28'] = TechSpec('blue', 's', args.tsmcfreq, 12.2e-3, 209.286002, 1060.0, .081533)
|
||||
techdict['sky90'] = TechSpec('gray', 'o', args.skyfreq, 43.2e-3, 1440.600027, 714.057, 0.658023)
|
||||
techdict['tsmc28psyn'] = TechSpec('blue', 's', args.tsmcfreq, 12.2e-3, 209.286002, 1060.0, .081533)
|
||||
|
||||
current_directory = os.getcwd()
|
||||
final_directory = os.path.join(current_directory, 'wallyplots')
|
||||
@ -256,10 +256,10 @@ if __name__ == '__main__':
|
||||
|
||||
synthsintocsv()
|
||||
synthsfromcsv('Summary.csv')
|
||||
freqPlot('tsmc28', 'rv32', 'e')
|
||||
freqPlot('tsmc28psyn', 'rv32', 'e')
|
||||
freqPlot('sky90', 'rv32', 'e')
|
||||
plotFeatures('sky90', 'rv64', 'gc')
|
||||
plotFeatures('tsmc28', 'rv64', 'gc')
|
||||
plotFeatures('tsmc28psyn', 'rv64', 'gc')
|
||||
plotConfigs('sky90', mod='orig')
|
||||
plotConfigs('tsmc28', mod='orig')
|
||||
plotConfigs('tsmc28psyn', mod='orig')
|
||||
normAreaDelay(mod='orig')
|
||||
|
@ -49,6 +49,24 @@ set report_default_significant_digits 6
|
||||
set verilogout_show_unconnected_pins "true"
|
||||
set vhdlout_show_unconnected_pins "true"
|
||||
|
||||
# Set up MW List
|
||||
set MY_LIB_NAME $my_toplevel
|
||||
# Create MW
|
||||
if { [shell_is_in_topographical_mode] } {
|
||||
echo "In Topographical Mode...processing\n"
|
||||
create_mw_lib -technology $MW_REFERENCE_LIBRARY/$MW_TECH_FILE.tf \
|
||||
-mw_reference_library $mw_reference_library $outputDir/$MY_LIB_NAME
|
||||
# Open MW
|
||||
open_mw_lib $outputDir/$MY_LIB_NAME
|
||||
|
||||
# TLU+
|
||||
set_tlu_plus_files -max_tluplus $MAX_TLU_FILE -min_tluplus $MIN_TLU_FILE \
|
||||
-tech2itf_map $PRS_MAP_FILE
|
||||
|
||||
} else {
|
||||
echo "In normal DC mode...processing\n"
|
||||
}
|
||||
|
||||
# Due to parameterized Verilog must use analyze/elaborate and not
|
||||
# read_verilog/vhdl (change to pull in Verilog and/or VHDL)
|
||||
#
|
||||
@ -122,7 +140,7 @@ if {$tech == "sky130"} {
|
||||
} elseif {$drive == "FLOP"} {
|
||||
set_driving_cell -lib_cell scc9gena_dfxbp_1 -pin Q $all_in_ex_clk
|
||||
}
|
||||
} elseif {$tech == "tsmc28"} {
|
||||
} elseif {$tech == "tsmc28" || $tech=="tsmc28psyn"} {
|
||||
if {$drive == "INV"} {
|
||||
set_driving_cell -lib_cell INVD1BWP30P140 -pin ZN $all_in_ex_clk
|
||||
} elseif {$drive == "FLOP"} {
|
||||
@ -148,7 +166,7 @@ if {$tech == "sky130"} {
|
||||
} elseif {$drive == "FLOP"} {
|
||||
set_load [expr [load_of scc9gena_tt_1.2v_25C/scc9gena_dfxbp_1/D] * 1] [all_outputs]
|
||||
}
|
||||
} elseif {$tech == "tsmc28"} {
|
||||
} elseif {$tech == "tsmc28" || $tech == "tsmc28psyn"} {
|
||||
if {$drive == "INV"} {
|
||||
set_load [expr [load_of tcbn28hpcplusbwp30p140tt0p9v25c/INVD4BWP30P140/I] * 1] [all_outputs]
|
||||
} elseif {$drive == "FLOP"} {
|
||||
@ -156,8 +174,10 @@ if {$tech == "sky130"} {
|
||||
}
|
||||
}
|
||||
|
||||
# Set the wire load model
|
||||
set_wire_load_mode "top"
|
||||
if {$tech != "tsmc28psyn"} {
|
||||
# Set the wire load model
|
||||
set_wire_load_mode "top"
|
||||
}
|
||||
|
||||
# Set switching activities
|
||||
# default activity factors are 1 for clocks, 0.1 for others
|
||||
|
@ -19,6 +19,7 @@ if __name__ == '__main__':
|
||||
techs = ['sky90', 'tsmc28']
|
||||
allConfigs = ['rv32gc', 'rv32imc', 'rv64gc', 'rv64imc', 'rv32e', 'rv32i', 'rv64i']
|
||||
freqVaryPct = [-20, -12, -8, -6, -4, -2, 0, 2, 4, 6, 8, 12, 20]
|
||||
# freqVaryPct = [-20, -10, 0, 10, 20]
|
||||
|
||||
pool = Pool()
|
||||
|
||||
@ -45,13 +46,13 @@ if __name__ == '__main__':
|
||||
sc = args.freqsweep
|
||||
config = args.version if args.version else 'rv32e'
|
||||
for freq in [round(sc+sc*x/100) for x in freqVaryPct]: # rv32e freq sweep
|
||||
runSynth(config, mod, tech, freq, maxopt, usesram)
|
||||
if args.configsweep:
|
||||
runSynth(config, mod, tech, freq, maxopt, usesram, usetopo)
|
||||
elif args.configsweep:
|
||||
defaultfreq = 1500 if tech == 'sky90' else 5000
|
||||
freq = args.targetfreq if args.targetfreq else defaultfreq
|
||||
for config in ['rv32i', 'rv64gc', 'rv64i', 'rv32gc', 'rv32imc', 'rv32e']: #configs
|
||||
runSynth(config, mod, tech, freq, maxopt, usesram)
|
||||
if args.featuresweep:
|
||||
runSynth(config, mod, tech, freq, maxopt, usesram, usetopo)
|
||||
elif args.featuresweep:
|
||||
defaultfreq = 500 if tech == 'sky90' else 1500
|
||||
freq = args.targetfreq if args.targetfreq else defaultfreq
|
||||
config = args.version if args.version else 'rv64gc'
|
||||
|
@ -1,33 +1,24 @@
|
||||
///////////////////////////////////////////
|
||||
// datapath.sv
|
||||
// functionName.sv
|
||||
//
|
||||
// Written: Ross Thompson
|
||||
// email: ross1728@gmail.com
|
||||
// Created: November 9, 2019
|
||||
// Modified: March 04, 2021
|
||||
//
|
||||
// Purpose: Finds the current function or global assembly label based on PCE.
|
||||
// Purpose: decode name of function
|
||||
//
|
||||
// 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:
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// 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.
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
@ -1,3 +1,26 @@
|
||||
///////////////////////////////////////////
|
||||
// instrNameDecTB.sv
|
||||
//
|
||||
// Purpose: decode name of function
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// decode the instruction name, to help the test bench
|
||||
module instrNameDecTB(
|
||||
input logic [31:0] instr,
|
||||
|
@ -1,3 +1,24 @@
|
||||
///////////////////////////////////////////
|
||||
// instrTrackerTB.sv
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module instrTrackerTB(
|
||||
input logic clk, reset, FlushE,
|
||||
input logic [31:0] InstrF, InstrD,
|
||||
|
64
testbench/common/riscvassertions.sv
Normal file
64
testbench/common/riscvassertions.sv
Normal file
@ -0,0 +1,64 @@
|
||||
///////////////////////////////////////////
|
||||
// riscvassertions.sv
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module riscvassertions;
|
||||
initial begin
|
||||
assert (`PMP_ENTRIES == 0 | `PMP_ENTRIES==16 | `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
|
||||
assert (`S_SUPPORTED | `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support");
|
||||
assert (`IDIV_BITSPERCYCLE == 1 | `IDIV_BITSPERCYCLE==2 | `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");
|
||||
assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)");
|
||||
assert (`D_SUPPORTED | ~`Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)");
|
||||
assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)");
|
||||
assert (`DCACHE_SUPPORTED | ~`F_SUPPORTED | `FLEN <= `XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN");
|
||||
assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported");
|
||||
assert (`FLEN<=`XLEN | `DCACHE_SUPPORTED | `DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported");
|
||||
assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (!`DCACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (`DCACHE_LINELENINBITS >= 128 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
|
||||
assert (`DCACHE_LINELENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (`ICACHE_WAYSIZEINBYTES <= 4096 | (!`ICACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (`ICACHE_LINELENINBITS >= 32 | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled");
|
||||
assert (`ICACHE_LINELENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (2**$clog2(`DCACHE_LINELENINBITS) == `DCACHE_LINELENINBITS | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES | (!`DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(`ICACHE_LINELENINBITS) == `ICACHE_LINELENINBITS | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES | (!`ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2");
|
||||
assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2");
|
||||
assert (`UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'h07FFFFFF");
|
||||
assert (`ZICSR_SUPPORTED == 1 | (`PMP_ENTRIES == 0 & `VIRTMEM_SUPPORTED == 0)) else $error("PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported.");
|
||||
assert (`ZICSR_SUPPORTED == 1 | (`S_SUPPORTED == 0 & `U_SUPPORTED == 0)) else $error("S and U modes not supported if ZICSR not supported");
|
||||
assert (`U_SUPPORTED | (`S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported");
|
||||
assert (`VIRTMEM_SUPPORTED == 0 | (`DTIM_SUPPORTED == 0 & `IROM_SUPPORTED == 0)) else $error("Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses");
|
||||
assert (`DCACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache");
|
||||
assert (`ICACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache");
|
||||
assert ((`DCACHE_SUPPORTED == 0 & `ICACHE_SUPPORTED == 0) | `BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS_SUPPORTED.");
|
||||
assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1");
|
||||
assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words");
|
||||
assert (`DCACHE_SUPPORTED | `A_SUPPORTED == 0) else $error("Atomic extension (A) requires cache on Wally.");
|
||||
assert (`IDIV_ON_FPU == 0 | `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED");
|
||||
assert (`SSTC_SUPPORTED == 0 | (`S_SUPPORTED)) else $error("SSTC requires S_SUPPORTED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -1,3 +1,24 @@
|
||||
///////////////////////////////////////////
|
||||
// wallyTracer.sv
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
`define NUM_REGS 32
|
||||
@ -14,7 +35,10 @@ module wallyTracer(rvviTrace rvvi);
|
||||
|
||||
// wally specific signals
|
||||
logic reset;
|
||||
|
||||
logic clk;
|
||||
logic InstrValidD, InstrValidE;
|
||||
logic StallF, StallD;
|
||||
logic STATUS_SXL, STATUS_UXL;
|
||||
logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW;
|
||||
logic [`XLEN-1:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW;
|
||||
logic InstrValidM, InstrValidW;
|
||||
|
@ -282,7 +282,7 @@ logic [3:0] dummy;
|
||||
// once the test inidicates it's done we need to immediately hold reset for a number of cycles.
|
||||
if(ResetCount < ResetThreshold) ResetCount = ResetCount + 1;
|
||||
else begin // hit reset threshold so we remove reset.
|
||||
InReset = 0;
|
||||
InReset = 0;
|
||||
ResetCount = 0;
|
||||
end
|
||||
end else begin
|
||||
@ -520,47 +520,6 @@ logic [3:0] dummy;
|
||||
|
||||
endmodule
|
||||
|
||||
module riscvassertions;
|
||||
initial begin
|
||||
assert (`PMP_ENTRIES == 0 | `PMP_ENTRIES==16 | `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
|
||||
assert (`S_SUPPORTED | `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support");
|
||||
assert (`IDIV_BITSPERCYCLE == 1 | `IDIV_BITSPERCYCLE==2 | `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");
|
||||
assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)");
|
||||
assert (`D_SUPPORTED | ~`Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)");
|
||||
assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)");
|
||||
assert (`DCACHE_SUPPORTED | ~`F_SUPPORTED | `FLEN <= `XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN");
|
||||
assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported");
|
||||
assert (`FLEN<=`XLEN | `DCACHE_SUPPORTED | `DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported");
|
||||
assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (!`DCACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (`DCACHE_LINELENINBITS >= 128 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
|
||||
assert (`DCACHE_LINELENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (`ICACHE_WAYSIZEINBYTES <= 4096 | (!`ICACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (`ICACHE_LINELENINBITS >= 32 | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled");
|
||||
assert (`ICACHE_LINELENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (2**$clog2(`DCACHE_LINELENINBITS) == `DCACHE_LINELENINBITS | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES | (!`DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(`ICACHE_LINELENINBITS) == `ICACHE_LINELENINBITS | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES | (!`ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2");
|
||||
assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2");
|
||||
assert (`UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'h07FFFFFF");
|
||||
assert (`ZICSR_SUPPORTED == 1 | (`PMP_ENTRIES == 0 & `VIRTMEM_SUPPORTED == 0)) else $error("PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported.");
|
||||
assert (`ZICSR_SUPPORTED == 1 | (`S_SUPPORTED == 0 & `U_SUPPORTED == 0)) else $error("S and U modes not supported if ZICSR not supported");
|
||||
assert (`U_SUPPORTED | (`S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported");
|
||||
assert (`VIRTMEM_SUPPORTED == 0 | (`DTIM_SUPPORTED == 0 & `IROM_SUPPORTED == 0)) else $error("Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses");
|
||||
assert (`DCACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache");
|
||||
assert (`ICACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache");
|
||||
assert ((`DCACHE_SUPPORTED == 0 & `ICACHE_SUPPORTED == 0) | `BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS_SUPPORTED.");
|
||||
assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1");
|
||||
assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words");
|
||||
assert (`DCACHE_SUPPORTED | `A_SUPPORTED == 0) else $error("Atomic extension (A) requires cache on Wally.");
|
||||
assert (`IDIV_ON_FPU == 0 | `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED");
|
||||
end
|
||||
|
||||
// *** DH 8/23/
|
||||
endmodule
|
||||
|
||||
|
||||
/* verilator lint_on STMTDLY */
|
||||
/* verilator lint_on WIDTH */
|
||||
|
||||
|
@ -321,46 +321,6 @@ module testbench;
|
||||
|
||||
endmodule
|
||||
|
||||
module riscvassertions;
|
||||
initial begin
|
||||
assert (`PMP_ENTRIES == 0 | `PMP_ENTRIES==16 | `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
|
||||
assert (`S_SUPPORTED | `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support");
|
||||
assert (`IDIV_BITSPERCYCLE == 1 | `IDIV_BITSPERCYCLE==2 | `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");
|
||||
assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)");
|
||||
assert (`D_SUPPORTED | ~`Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)");
|
||||
assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)");
|
||||
assert (`DCACHE_SUPPORTED | ~`F_SUPPORTED | `FLEN <= `XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN");
|
||||
assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported");
|
||||
assert (`FLEN<=`XLEN | `DCACHE_SUPPORTED | `DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported");
|
||||
assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (!`DCACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (`DCACHE_LINELENINBITS >= 128 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
|
||||
assert (`DCACHE_LINELENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (`ICACHE_WAYSIZEINBYTES <= 4096 | (!`ICACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (`ICACHE_LINELENINBITS >= 32 | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled");
|
||||
assert (`ICACHE_LINELENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (2**$clog2(`DCACHE_LINELENINBITS) == `DCACHE_LINELENINBITS | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES | (!`DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(`ICACHE_LINELENINBITS) == `ICACHE_LINELENINBITS | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES | (!`ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2");
|
||||
assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2");
|
||||
assert (`UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'h07FFFFFF");
|
||||
assert (`ZICSR_SUPPORTED == 1 | (`PMP_ENTRIES == 0 & `VIRTMEM_SUPPORTED == 0)) else $error("PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported.");
|
||||
assert (`ZICSR_SUPPORTED == 1 | (`S_SUPPORTED == 0 & `U_SUPPORTED == 0)) else $error("S and U modes not supported if ZISR not supported");
|
||||
assert (`U_SUPPORTED | (`S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported");
|
||||
assert (`VIRTMEM_SUPPORTED == 0 | (`DTIM_SUPPORTED == 0 & `IROM_SUPPORTED == 0)) else $error("Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses");
|
||||
assert (`DCACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache");
|
||||
assert (`ICACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache");
|
||||
assert ((`DCACHE_SUPPORTED == 0 & `ICACHE_SUPPORTED == 0) | `BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS.");
|
||||
assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1");
|
||||
assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words");
|
||||
assert (`DCACHE_SUPPORTED | `A_SUPPORTED == 0) else $error("Atomic extension (A) requires cache on Wally.");
|
||||
assert (`IDIV_ON_FPU == 0 | `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED");
|
||||
end
|
||||
|
||||
// *** DH 8/23/
|
||||
endmodule
|
||||
|
||||
|
||||
/* verilator lint_on STMTDLY */
|
||||
/* verilator lint_on WIDTH */
|
||||
|
@ -5,23 +5,38 @@
|
||||
|
||||
.global rvtest_entry_point
|
||||
rvtest_entry_point:
|
||||
lui t0, 0x1e # turn on Floating point and XS
|
||||
lui t0, 0x02 # turn on Floating point and XS
|
||||
csrs mstatus, t0
|
||||
|
||||
# openhwgroup/cvw Issue #55
|
||||
la a6, begin_signature
|
||||
la a7, rvtest_data
|
||||
fadd.d ft0, ft1, ft2
|
||||
|
||||
# openhwgroup/cvw Issue #55
|
||||
fld f4, 0(a7)
|
||||
fld f9, 8(a7)
|
||||
# li x1, 0x7ff0000000000001
|
||||
# sd x1, 0(a6)
|
||||
# fmv.w.x f4, x1
|
||||
# li x1, 0x7ff8000000000000
|
||||
# fmv.w.x f9, x1
|
||||
fsgnjx.s f12,f9,f4 # expected f 0xffffffff7fc00000
|
||||
fsgnjx.s f12,f9,f4 # expected f 0xffffffff7fc00000, hdl has been giving fff8000000000000
|
||||
fsd f12, 0(a6)
|
||||
|
||||
# openhwgroup/cvw Issue #56
|
||||
fld f4, 16(a7)
|
||||
fld f14, 24(a7)
|
||||
fsgnjx.s f10,f4,f14 # expected f 0xffffffff7fc00000, hdl has been giving 0xcfa695b1047553b1
|
||||
fsd f19, 8(a6)
|
||||
|
||||
# openhwgroup/cvw Issue #57
|
||||
fld f0, 32(a7)
|
||||
fld f15, 40(a7)
|
||||
fsgnjx.s f30,f0,f15 # expected f 0xfffffffffb3754ef, hdl has been giving 0xffffffff7b3754ef
|
||||
fsd f30, 16(a6)
|
||||
|
||||
# openhwgroup/cvw Issue #58
|
||||
fld f14, 48(a7)
|
||||
fclass.s x2, f14 # expected 0x0000000000000200, hdl had been giving 0x0000000000000220
|
||||
sd x2, 24(a6)
|
||||
|
||||
# fsgnjx.s, fclass.s, fsgnjn.s, fsgnj.s, fneg.s, fabs.s, fmv.s all treat inputs as dp rather than sp
|
||||
|
||||
|
||||
#########################
|
||||
# HTIF and signature
|
||||
#########################
|
||||
@ -47,10 +62,14 @@ fromhost:
|
||||
rvtest_data:
|
||||
.dword 0x7ff0000000000001
|
||||
.dword 0x7ff8000000000000
|
||||
.dword 0xcfa695b1047553b1
|
||||
.dword 0xffffffff7fc00000
|
||||
.dword 0xfffffffffb3754ef
|
||||
.dword 0x7fefffffffffffff
|
||||
|
||||
.EQU XLEN,64
|
||||
begin_signature:
|
||||
.fill 2*(XLEN/32),4,0xdeadbeef #
|
||||
.fill 8*(XLEN/32),4,0xdeadbeef #
|
||||
end_signature:
|
||||
|
||||
# Initialize stack with room for 512 bytes
|
||||
|
Loading…
Reference in New Issue
Block a user