Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

This commit is contained in:
slmnemo 2022-06-21 02:16:26 -07:00
commit 80a57d0469
44 changed files with 2480 additions and 917 deletions

2
.gitignore vendored
View File

@ -32,7 +32,7 @@ testsBP/*/*/*.elf*
testsBP/*/OBJ/* testsBP/*/OBJ/*
testsBP/*/*.a testsBP/*/*.a
tests/wally-riscv-arch-test/riscv-test-suite/*/I/*/* tests/wally-riscv-arch-test/riscv-test-suite/*/I/*/*
tests/riscof/riscof_work*/* tests/riscof/riscof_work/
tests/riscof/config32.ini tests/riscof/config32.ini
tests/riscof/config64.ini tests/riscof/config64.ini
tests/linux-testgen/linux-testvectors/* tests/linux-testgen/linux-testvectors/*

@ -1 +1 @@
Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86 Subproject commit be67c99bd461742aa1c100bcc0732657faae2230

View File

@ -4,20 +4,29 @@
embench_dir = ../../addins/embench-iot embench_dir = ../../addins/embench-iot
all: sim size all: build sim size
allClean: clean all allClean: clean all
build: buildspeed buildsize build: buildspeed buildsize
buildspeed: build_speedopt_speed build_sizeopt_speed
buildsize: build_speedopt_size build_sizeopt_size
# uses the build_all.py python file to build the tests in addins/embench-iot/bd_speed/ optimized for speed # uses the build_all.py python file to build the tests in addins/embench-iot/bd_speed/ optimized for speed and size
buildspeed: build_speedopt_speed:
$(embench_dir)/build_all.py --builddir=bd_speed --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/crt0.S" --cflags="-O2 -nostartfiles" $(embench_dir)/build_all.py --builddir=bd_speedopt_speed --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/crt0.S" --cflags="-O2 -nostartfiles"
find $(embench_dir)/bd_speed/ -type f ! -name "*.*" | while read f; do cp "$$f" "$$f.elf"; done find $(embench_dir)/bd_speedopt_speed/ -type f ! -name "*.*" | while read f; do cp "$$f" "$$f.elf"; done
# uses the build_all.py python file to build the tests in addins/embench-iot/bd_speed/ optimized for size build_sizeopt_speed:
buildsize: $(embench_dir)/build_all.py --builddir=bd_sizeopt_speed --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/crt0.S" --cflags="-Os -nostartfiles"
$(embench_dir)/build_all.py --builddir=bd_size --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostdlib -nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/dummy.S" --cflags="-Os -msave-restore" --dummy-libs="libgcc libm libc crt0" find $(embench_dir)/bd_sizeopt_speed/ -type f ! -name "*.*" | while read f; do cp "$$f" "$$f.elf"; done
# uses the build_all.py python file to build the tests in addins/embench-iot/bd_speed/ optimized for speed and size
build_speedopt_size:
$(embench_dir)/build_all.py --builddir=bd_speedopt_size --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostdlib -nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/dummy.S" --cflags="-O2 -msave-restore" --dummy-libs="libgcc libm libc crt0"
build_sizeopt_size:
$(embench_dir)/build_all.py --builddir=bd_sizeopt_size --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostdlib -nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/dummy.S" --cflags="-Os -msave-restore" --dummy-libs="libgcc libm libc crt0"
# builds dependencies, then launches modelsim and finally runs python wrapper script to present results # builds dependencies, then launches modelsim and finally runs python wrapper script to present results
sim: modelsim_build_memfile modelsim_run speed sim: modelsim_build_memfile modelsim_run speed
@ -28,35 +37,37 @@ modelsim_run:
cd ../../benchmarks/embench/ cd ../../benchmarks/embench/
# builds the objdump based on the compiled c elf files # builds the objdump based on the compiled c elf files
objdump: buildspeed objdump:
find $(embench_dir)/bd_speed/ -type f -name "*.elf" | while read f; do riscv64-unknown-elf-objdump -S -D "$$f" > "$$f.objdump"; done find $(embench_dir)/bd_*_speed/ -type f -name "*.elf" | while read f; do riscv64-unknown-elf-objdump -S -D "$$f" > "$$f.objdump"; done
# build memfiles, objdump.lab and objdump.addr files # build memfiles, objdump.lab and objdump.addr files
modelsim_build_memfile: objdump modelsim_build_memfile: objdump
find $(embench_dir)/bd_speed/ -type f -name "*.elf" | while read f; do riscv64-unknown-elf-elf2hex --bit-width 32 --input "$$f" --output "$$f.memfile"; done find $(embench_dir)/bd_*_speed/ -type f -name "*.elf" | while read f; do riscv64-unknown-elf-elf2hex --bit-width 32 --input "$$f" --output "$$f.memfile"; done
find $(embench_dir)/bd_speed/ -type f -name "*.elf.objdump" | while read f; do extractFunctionRadix.sh $$f; done find $(embench_dir)/bd_*_speed/ -type f -name "*.elf.objdump" | while read f; do extractFunctionRadix.sh $$f; done
# builds the tests for speed, runs them on spike and then launches python script to present results # builds the tests for speed, runs them on spike and then launches python script to present results
# note that the speed python script benchmark_speed.py can get confused if there's both a .output file created from spike and modelsim # note that the speed python script benchmark_speed.py can get confused if there's both a .output file created from spike and modelsim
# you'll need to manually remove one of the two .output files, or run make clean # you'll need to manually remove one of the two .output files, or run make clean
spike: buildspeed objdump spike_run speed spike: buildspeed spike_run speed
# command to run spike on all of the benchmarks # command to run spike on all of the benchmarks
spike_run: spike_run:
find $(embench_dir)/bd_speed/ -type f -name "*.elf" | while read f; do spike --isa=rv32imac +signature=$$f.spike.output +signature-granularity=4 $$f; done find $(embench_dir)/bd_*opt_speed/ -type f -name "*.elf" | while read f; do spike --isa=rv32imac +signature=$$f.spike.output +signature-granularity=4 $$f; done
# python wrapper to present results of embench size benchmark # python wrapper to present results of embench size benchmark
size: buildsize size: buildsize
$(embench_dir)/benchmark_size.py --builddir=bd_size --json-output > wallySize.json $(embench_dir)/benchmark_size.py --builddir=bd_speedopt_size --json-output > wallySpeedOpt_size.json
$(embench_dir)/benchmark_size.py --builddir=bd_sizeopt_size --json-output > wallySizeOpt_size.json
# python wrapper to present results of embench speed benchmark # python wrapper to present results of embench speed benchmark
speed: speed:
$(embench_dir)/benchmark_speed.py --builddir=bd_speed --target-module run_wally --cpu-mhz=1 --json-output > wallySpeed.json $(embench_dir)/benchmark_speed.py --builddir=bd_sizeopt_speed --target-module run_wally --cpu-mhz=1 --json-output > wallySizeOpt_speed.json
$(embench_dir)/benchmark_speed.py --builddir=bd_speedopt_speed --target-module run_wally --cpu-mhz=1 --json-output > wallySpeedOpt_speed.json
# deletes all files # deletes all files
clean: clean:
rm -rf $(embench_dir)/bd_speed/ rm -rf $(embench_dir)/bd_*_speed/
rm -rf $(embench_dir)/bd_size/ rm -rf $(embench_dir)/bd_*_size/
allclean: clean allclean: clean
rm -rf $(embench_dir)/logs/ rm -rf $(embench_dir)/logs/

View File

@ -3,9 +3,8 @@ import subprocess
import sys import sys
import json import json
import plotly.graph_objects as go import plotly.graph_objects as go
from plotly.subplots import make_subplots
coremarkData = {}
embenchData = {}
debug = True debug = True
def loadCoremark(): def loadCoremark():
@ -21,61 +20,85 @@ def loadCoremark():
if (debug): print(coremarkData) if (debug): print(coremarkData)
return coremarkData return coremarkData
def loadEmbench(): def loadEmbench(embenchPath, embenchData):
"""loads the embench data dictionary""" """loads the embench data dictionary"""
embenchPath = "embench/wallySpeed.json"
f = open(embenchPath) f = open(embenchPath)
embenchData = json.load(f) embenchData = json.load(f)
if (debug): print(embenchData) if (debug): print(embenchData)
return embenchData return embenchData
def graphEmbench(embenchData): def graphEmbench(embenchSpeedOpt_SpeedData, embenchSizeOpt_SpeedData, embenchSpeedOpt_SizeData, embenchSizeOpt_SizeData):
ydata = list(embenchData["speed results"]["detailed speed results"].keys()) + ["speed geometric mean","speed geometric sd","speed geometric range"] fig = make_subplots(rows=2, cols=4,
xdata = list(embenchData["speed results"]["detailed speed results"].values()) + [embenchData["speed results"]["speed geometric mean"],embenchData["speed results"]["speed geometric sd"],embenchData["speed results"]["speed geometric range"]] # subplot_titles( "Wally's Embench Cycles and Instret (with -O2)","Wally's Embench Cycles Per Instruction (with -O2)"))
fig = go.Figure(go.Bar( subplot_titles=( "Wally's Embench Cycles and Instret (with -O2)","Wally's Embench Cycles Per Instruction (with -O2)","Wally's Embench Speed Score (with -O2)","Wally's Embench Size Score (with -O2)",
"Wally's Embench Cycles and Instret (with -Os)","Wally's Embench Cycles Per Instruction (with -Os)","Wally's Embench Speed Score (with -Os)","Wally's Embench Size Score (with -Os)"))
ydata = list(embenchSpeedOpt_SpeedData["speed results"]["detailed speed results"].keys()) + ["speed geometric mean","speed geometric sd","speed geometric range"]
xdata = list(embenchSpeedOpt_SpeedData["speed results"]["detailed speed results"].values()) + [embenchSpeedOpt_SpeedData["speed results"]["speed geometric mean"],embenchSpeedOpt_SpeedData["speed results"]["speed geometric sd"],embenchSpeedOpt_SpeedData["speed results"]["speed geometric range"]]
fig.add_trace( go.Bar(
y=ydata, y=ydata,
x=xdata, x=xdata,
orientation='h')) textposition='outside', text=xdata,
orientation='h'),
row=1,col=3)
fig.show() ydata = list(embenchSizeOpt_SpeedData["speed results"]["detailed speed results"].keys()) + ["speed geometric mean","speed geometric sd","speed geometric range"]
xdata = list(embenchSizeOpt_SpeedData["speed results"]["detailed speed results"].values()) + [embenchSizeOpt_SpeedData["speed results"]["speed geometric mean"],embenchSizeOpt_SpeedData["speed results"]["speed geometric sd"],embenchSizeOpt_SpeedData["speed results"]["speed geometric range"]]
fig.add_trace( go.Bar(
y=ydata,
x=xdata,
textposition='outside', text=xdata,
orientation='h'),
row=2,col=3)
ydata = list(embenchSpeedOpt_SizeData["size results"]["detailed size results"].keys()) + ["size geometric mean","size geometric sd","size geometric range"]
xdata = list(embenchSpeedOpt_SizeData["size results"]["detailed size results"].values()) + [embenchSpeedOpt_SizeData["size results"]["size geometric mean"],embenchSpeedOpt_SizeData["size results"]["size geometric sd"],embenchSpeedOpt_SizeData["size results"]["size geometric range"]]
fig.add_trace( go.Bar(
y=ydata,
x=xdata,
textposition='outside', text=xdata,
orientation='h'),
row=1,col=4)
ydata = list(embenchSizeOpt_SizeData["size results"]["detailed size results"].keys()) + ["size geometric mean","size geometric sd","size geometric range"]
xdata = list(embenchSizeOpt_SizeData["size results"]["detailed size results"].values()) + [embenchSizeOpt_SizeData["size results"]["size geometric mean"],embenchSizeOpt_SizeData["size results"]["size geometric sd"],embenchSizeOpt_SizeData["size results"]["size geometric range"]]
fig.add_trace( go.Bar(
y=ydata,
x=xdata,
textposition='outside', text=xdata,
orientation='h'),
row=2,col=4)
# facet_row="Score", facet_col="Optimization Flag",
# category_orders={"Score": ["Cycles & Instr", "CPI", "SpeedScore", "SizeScore"],
# "Optimization Flag": ["O2", "Os"]}),
# orientation='h')
fig.update_layout(height=1500,width=4000, title_text="Wally Embench Scores", showlegend=False)
fig.write_image("figure.png", engine="kaleido")
# fig.show()
def main(): def main():
coremarkData = loadCoremark() coremarkData = {}
embenchData = loadEmbench() embenchSizeOpt_SpeedData = {}
graphEmbench(embenchData) embenchSpeedOpt_SpeedData = {}
embenchSizeOpt_SizeData = {}
embenchSpeedOpt_SizeData = {}
# coremarkData = loadCoremark()
embenchSpeedOpt_SpeedData = loadEmbench("embench/wallySpeedOpt_speed.json", embenchSpeedOpt_SpeedData)
embenchSizeOpt_SpeedData = loadEmbench("embench/wallySizeOpt_speed.json", embenchSizeOpt_SpeedData)
embenchSpeedOpt_SizeData = loadEmbench("embench/wallySpeedOpt_size.json", embenchSpeedOpt_SizeData)
embenchSizeOpt_SizeData = loadEmbench("embench/wallySizeOpt_size.json", embenchSizeOpt_SizeData)
graphEmbench(embenchSpeedOpt_SpeedData, embenchSizeOpt_SpeedData, embenchSpeedOpt_SizeData, embenchSizeOpt_SizeData)
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())
# x = # "ls -Art ../addins/embench-iot/logs/*speed* | tail -n 1 " # gets most recent embench speed log
# y =
# df = px.data.tips()
# fig = px.bar(df, x="total_bill", y="day", orientation='h')
# fig.show()
# import plotly.express as px
# result = sp.run(['ls', '-l'], stdout=sp.PIPE)
# result.stdout
# fig = go.Figure( go.Bar(
# x=[],
# y=[],
# color="species",
# facet_col="species",
# title="Using update_traces() With Plotly Express Figures"),
# orientation='h')
# fig.show()
#
# "ls -Art ../addins/embench-iot/logs/*speed* | tail -n 1 " # gets most recent embench speed log
# "ls -Art ../addins/embench-iot/logs/*size* | tail -n 1 " # gets most recent embench speed log
## get coremark score
# cat coremarkPath | grep "CoreMark 1.0" | cut -d ':' -f 2 | cut -d " " -f 2
# cat coremarkPath | grep "MTIME" | cut -d ':' -f 2 | cut -d " " -f 2 | tail -1
# cat coremarkPath | grep "MINSTRET" | cut -d ':' -f 2 | cut -d " " -f 2 | tail -1

View File

@ -95,6 +95,7 @@
// largest length in IEU/FPU // largest length in IEU/FPU
`define LGLEN ((`NF<`XLEN) ? `XLEN : `NF) `define LGLEN ((`NF<`XLEN) ? `XLEN : `NF)
`define LLEN ((`FLEN<`XLEN) ? `XLEN : `FLEN)
`define LOGLGLEN $unsigned($clog2(`LGLEN+1)) `define LOGLGLEN $unsigned($clog2(`LGLEN+1))
`define NORMSHIFTSZ ((`LGLEN+`NF) > (3*`NF+8) ? (`LGLEN+`NF+1) : (3*`NF+9)) `define NORMSHIFTSZ ((`LGLEN+`NF) > (3*`NF+8) ? (`LGLEN+`NF+1) : (3*`NF+9))
`define CORRSHIFTSZ ((`LGLEN+`NF) > (3*`NF+8) ? (`LGLEN+`NF+1) : (3*`NF+6)) `define CORRSHIFTSZ ((`LGLEN+`NF) > (3*`NF+8) ? (`LGLEN+`NF+1) : (3*`NF+6))

View File

@ -3,7 +3,7 @@ make allclean:
make all make all
make clean: make clean:
make clean -C ../../addins/riscv-arch-test make clean -C ../../tests/riscof
make clean -C ../../tests/wally-riscv-arch-test make clean -C ../../tests/wally-riscv-arch-test
# make allclean -C ../../tests/imperas-riscv-tests # make allclean -C ../../tests/imperas-riscv-tests
@ -15,8 +15,8 @@ make all:
#make -C ../../tests/imperas-riscv-tests XLEN=64 --jobs #make -C ../../tests/imperas-riscv-tests XLEN=64 --jobs
# Build riscv-arch-test 64 and 32-bit versions # Build riscv-arch-test 64 and 32-bit versions
make -C ../../addins/riscv-arch-test --jobs make -C ../../tests/riscof/ --jobs
make -C ../../addins/riscv-arch-test XLEN=32 --jobs make -C ../../tests/riscof/ XLEN=32 --jobs
# Build wally-riscv-arch-test # Build wally-riscv-arch-test
make -C ../../tests/wally-riscv-arch-test/ --jobs make -C ../../tests/wally-riscv-arch-test/ --jobs

View File

@ -1,6 +1,6 @@
ROOT := ../.. ROOT := ../..
SUFFIX := work SUFFIX := work
ARCHDIR := $(ROOT)/addins/riscv-arch-test ARCHDIR := $(ROOT)/tests/riscof
WALLYDIR:= $(ROOT)/tests/wally-riscv-arch-test WALLYDIR:= $(ROOT)/tests/wally-riscv-arch-test
# IMPERASDIR := $(ROOT)/tests/imperas-riscv-tests # IMPERASDIR := $(ROOT)/tests/imperas-riscv-tests
# ALLDIRS := $(ARCHDIR)/$(SUFFIX) $(WALLYDIR)/$(SUFFIX) $(IMPERASDIR)/$(SUFFIX) # ALLDIRS := $(ARCHDIR)/$(SUFFIX) $(WALLYDIR)/$(SUFFIX) $(IMPERASDIR)/$(SUFFIX)

View File

@ -121,11 +121,11 @@ module fctrl (
assign FmtD = 0; assign FmtD = 0;
else if (`FPSIZES == 2)begin else if (`FPSIZES == 2)begin
logic [1:0] FmtTmp; logic [1:0] FmtTmp;
assign FmtTmp = (FResSelD == 2'b10)&~FWriteIntD ? {~Funct3D[1], ~(Funct3D[1]^Funct3D[0])} : ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : Funct7D[1:0]; assign FmtTmp = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : Funct7D[1:0];
assign FmtD = (`FMT == FmtTmp); assign FmtD = (`FMT == FmtTmp);
end end
else if (`FPSIZES == 3|`FPSIZES == 4) else if (`FPSIZES == 3|`FPSIZES == 4)
assign FmtD = (FResSelD == 2'b10)&~FWriteIntD ? {~Funct3D[1], ~(Funct3D[1]^Funct3D[0])} : ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : Funct7D[1:0]; assign FmtD = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : Funct7D[1:0];
// Final Res Sel: // Final Res Sel:
// fp int // fp int

View File

@ -34,13 +34,14 @@ module fpu (
input logic reset, input logic reset,
input logic [2:0] FRM_REGW, // Rounding mode from CSR input logic [2:0] FRM_REGW, // Rounding mode from CSR
input logic [31:0] InstrD, // instruction from IFU input logic [31:0] InstrD, // instruction from IFU
input logic [`XLEN-1:0] ReadDataW,// Read data from memory input logic [`FLEN-1:0] ReadDataW,// Read data from memory
input logic [`XLEN-1:0] ForwardedSrcAE, // Integer input being processed (from IEU) input logic [`XLEN-1:0] ForwardedSrcAE, // Integer input being processed (from IEU)
input logic StallE, StallM, StallW, // stall signals from HZU input logic StallE, StallM, StallW, // stall signals from HZU
input logic FlushE, FlushM, FlushW, // flush signals from HZU input logic FlushE, FlushM, FlushW, // flush signals from HZU
input logic [4:0] RdM, RdW, // which FP register to write to (from IEU) input logic [4:0] RdM, RdW, // which FP register to write to (from IEU)
input logic [1:0] STATUS_FS, // Is floating-point enabled? input logic [1:0] STATUS_FS, // Is floating-point enabled?
output logic FRegWriteM, // FP register write enable output logic FRegWriteM, // FP register write enable
output logic FpLoadM, // Fp load instruction?
output logic FStallD, // Stall the decode stage output logic FStallD, // Stall the decode stage
output logic FWriteIntE, // integer register write enables output logic FWriteIntE, // integer register write enables
output logic [`XLEN-1:0] FWriteDataE, // Data to be written to memory output logic [`XLEN-1:0] FWriteDataE, // Data to be written to memory
@ -348,6 +349,8 @@ module fpu (
// ||| ||| // ||| |||
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
assign FpLoadM = FResSelM[1];
postprocess postprocess(.XSgnM, .ZExpM, .XManM, .YManM, .ZManM, .FrmM, .FmtM, .ProdExpM, postprocess postprocess(.XSgnM, .ZExpM, .XManM, .YManM, .ZManM, .FrmM, .FmtM, .ProdExpM,
.AddendStickyM, .KillProdM, .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .AddendStickyM, .KillProdM, .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM,
.ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .SumM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .SumM,
@ -378,21 +381,7 @@ module fpu (
// ||| ||| // ||| |||
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// put ReadData into NaN-blocking format
// - if there are any unsused bits the most significant bits are filled with 1s
// - for load instruction
generate
if(`FPSIZES == 1) assign ReadResW = {{`FLEN-`XLEN{1'b1}}, ReadDataW};
else if(`FPSIZES == 2)
mux2 #(`FLEN) SrcAMux ({{`FLEN-`LEN1{1'b1}}, ReadDataW[`LEN1-1:0]}, {{`FLEN-`XLEN{1'b1}}, ReadDataW}, FmtW, ReadResW);
else if(`FPSIZES == 3 | `FPSIZES == 4)
mux4 #(`FLEN) SrcAMux ({{`FLEN-`S_LEN{1'b1}}, ReadDataW[`S_LEN-1:0]},
{{`FLEN-`D_LEN{1'b1}}, ReadDataW[`D_LEN-1:0]},
{{`FLEN-`H_LEN{1'b1}}, ReadDataW[`H_LEN-1:0]},
{{`FLEN-`XLEN{1'b1}}, ReadDataW}, FmtW, ReadResW); // NaN boxing zeroes
endgenerate
// select the result to be written to the FP register // select the result to be written to the FP register
mux2 #(`FLEN) FPUResultMux (FpResW, ReadResW, FResSelW[1], FPUResultW); mux2 #(`FLEN) FPUResultMux (FpResW, ReadDataW, FResSelW[1], FPUResultW);
endmodule // fpu endmodule // fpu

View File

@ -63,9 +63,9 @@ module datapath (
input logic [2:0] ResultSrcW, input logic [2:0] ResultSrcW,
input logic [`XLEN-1:0] FCvtIntResW, input logic [`XLEN-1:0] FCvtIntResW,
input logic [1:0] FResSelW, input logic [1:0] FResSelW,
output logic [`XLEN-1:0] ReadDataW, input logic [`XLEN-1:0] ReadDataW,
// input logic [`XLEN-1:0] PCLinkW, // input logic [`XLEN-1:0] PCLinkW,
input logic [`XLEN-1:0] CSRReadValW, ReadDataM, MDUResultW, input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
// Hazard Unit signals // Hazard Unit signals
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
output logic [4:0] RdE, RdM, RdW output logic [4:0] RdE, RdM, RdW
@ -121,7 +121,6 @@ module datapath (
// Writeback stage pipeline register and logic // Writeback stage pipeline register and logic
flopenrc #(`XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW); flopenrc #(`XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW);
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW); flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
flopen #(`XLEN) ReadDataWReg(clk, ~StallW, ReadDataM, ReadDataW);
// floating point interactions: fcvt, fp stores // floating point interactions: fcvt, fp stores
if (`F_SUPPORTED) begin:fpmux if (`F_SUPPORTED) begin:fpmux

View File

@ -60,11 +60,11 @@ module ieu (
output logic InvalidateICacheM, FlushDCacheM, output logic InvalidateICacheM, FlushDCacheM,
// Writeback stage // Writeback stage
input logic [`XLEN-1:0] CSRReadValW, ReadDataM, MDUResultW, input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
input logic [1:0] FResSelW, input logic [1:0] FResSelW,
input logic [`XLEN-1:0] FCvtIntResW, input logic [`XLEN-1:0] FCvtIntResW,
output logic [4:0] RdW, output logic [4:0] RdW,
output logic [`XLEN-1:0] ReadDataW, input logic [`XLEN-1:0] ReadDataW,
// input logic [`XLEN-1:0] PCLinkW, // input logic [`XLEN-1:0] PCLinkW,
output logic InstrValidM, output logic InstrValidM,
// hazards // hazards
@ -109,7 +109,7 @@ module ieu (
.FWriteDataE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .FWriteDataE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataE, .FResSelW, .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataE, .FResSelW,
.StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, .StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
.CSRReadValW, .ReadDataM, .MDUResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW); .CSRReadValW, .MDUResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
forward fw( forward fw(
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,

View File

@ -30,12 +30,32 @@
`include "wally-config.vh" `include "wally-config.vh"
module bigendianswap ( module bigendianswap #(parameter LEN=`XLEN) (
input logic BigEndianM, input logic BigEndianM,
input logic [`XLEN-1:0] a, input logic [LEN-1:0] a,
output logic [`XLEN-1:0] y); output logic [LEN-1:0] y);
if(`XLEN == 64) begin if(LEN == 128) begin
always_comb
if (BigEndianM) begin // swap endianness
y[127:120] = a[7:0];
y[119:112] = a[15:8];
y[111:104] = a[23:16];
y[103:96] = a[31:24];
y[95:88] = a[39:32];
y[87:80] = a[47:40];
y[79:72] = a[55:48];
y[71:64] = a[63:56];
y[63:56] = a[71:64];
y[55:48] = a[79:72];
y[47:40] = a[87:80];
y[39:32] = a[95:88];
y[31:24] = a[103:96];
y[23:16] = a[111:104];
y[15:8] = a[119:112];
y[7:0] = a[127:120];
end else y = a;
end else if(LEN == 64) begin
always_comb always_comb
if (BigEndianM) begin // swap endianness if (BigEndianM) begin // swap endianness
y[63:56] = a[7:0]; y[63:56] = a[7:0];

View File

@ -51,11 +51,13 @@ module lsu (
input logic [`XLEN-1:0] IEUAdrE, input logic [`XLEN-1:0] IEUAdrE,
(* mark_debug = "true" *)output logic [`XLEN-1:0] IEUAdrM, (* mark_debug = "true" *)output logic [`XLEN-1:0] IEUAdrM,
input logic [`XLEN-1:0] WriteDataE, input logic [`XLEN-1:0] WriteDataE,
output logic [`XLEN-1:0] ReadDataM, output logic [`LLEN-1:0] ReadDataW,
// cpu privilege // cpu privilege
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic BigEndianM, input logic BigEndianM,
input logic sfencevmaM, input logic sfencevmaM,
// fpu
input logic FpLoadM,
// faults // faults
output logic LoadPageFaultM, StoreAmoPageFaultM, output logic LoadPageFaultM, StoreAmoPageFaultM,
output logic LoadMisalignedFaultM, LoadAccessFaultM, output logic LoadMisalignedFaultM, LoadAccessFaultM,
@ -110,6 +112,7 @@ module lsu (
logic [`XLEN-1:0] LSUWriteDataM; logic [`XLEN-1:0] LSUWriteDataM;
logic [(`XLEN-1)/8:0] ByteMaskM; logic [(`XLEN-1)/8:0] ByteMaskM;
logic [`XLEN-1:0] WriteDataM; logic [`XLEN-1:0] WriteDataM;
logic [`LLEN-1:0] ReadDataM;
// *** TO DO: Burst mode // *** TO DO: Burst mode
@ -128,7 +131,7 @@ module lsu (
.DTLBMissM, .DTLBWriteM, .InstrDAPageFaultF, .DataDAPageFaultM, .DTLBMissM, .DTLBWriteM, .InstrDAPageFaultF, .DataDAPageFaultM,
.TrapM, .DCacheStallM, .SATP_REGW, .PCF, .TrapM, .DCacheStallM, .SATP_REGW, .PCF,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW,
.ReadDataM, .WriteDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M, .ReadDataM(ReadDataM[`XLEN-1:0]), .WriteDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M,
.IEUAdrExtM, .PTE, .LSUWriteDataM, .PageType, .PreLSURWM, .LSUAtomicM, .IEUAdrE, .IEUAdrExtM, .PTE, .LSUWriteDataM, .PageType, .PreLSURWM, .LSUAtomicM, .IEUAdrE,
.LSUAdrE, .PreLSUPAdrM, .CPUBusy, .InterlockStall, .SelHPTW, .LSUAdrE, .PreLSUPAdrM, .CPUBusy, .InterlockStall, .SelHPTW,
.IgnoreRequestTLB, .IgnoreRequestTrapM); .IgnoreRequestTLB, .IgnoreRequestTrapM);
@ -187,8 +190,8 @@ module lsu (
// Either Data Cache or Data Tightly Integrated Memory or just bus interface // Either Data Cache or Data Tightly Integrated Memory or just bus interface
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
logic [`XLEN-1:0] AMOWriteDataM, FinalWriteDataM, LittleEndianWriteDataM; logic [`XLEN-1:0] AMOWriteDataM, FinalWriteDataM, LittleEndianWriteDataM;
logic [`XLEN-1:0] ReadDataWordM, LittleEndianReadDataWordM; logic [`LLEN-1:0] ReadDataWordM, LittleEndianReadDataWordM;
logic [`XLEN-1:0] ReadDataWordMuxM; logic [`LLEN-1:0] ReadDataWordMuxM;
logic IgnoreRequest; logic IgnoreRequest;
logic SelUncachedAdr; logic SelUncachedAdr;
assign IgnoreRequest = IgnoreRequestTLB | IgnoreRequestTrapM; assign IgnoreRequest = IgnoreRequestTLB | IgnoreRequestTrapM;
@ -197,7 +200,7 @@ module lsu (
// *** directly instantiate RAM or ROM here. Instantiate SRAM1P1RW. // *** directly instantiate RAM or ROM here. Instantiate SRAM1P1RW.
// Merge SimpleRAM and SRAM1p1rw into one that is good for synthesis and RAM libraries and flops // Merge SimpleRAM and SRAM1p1rw into one that is good for synthesis and RAM libraries and flops
dtim dtim(.clk, .reset, .CPUBusy, .LSURWM, .IEUAdrM, .IEUAdrE, .TrapM, .FinalWriteDataM, dtim dtim(.clk, .reset, .CPUBusy, .LSURWM, .IEUAdrM, .IEUAdrE, .TrapM, .FinalWriteDataM,
.ReadDataWordM, .BusStall, .LSUBusWrite,.LSUBusRead, .BusCommittedM, .ReadDataWordM(ReadDataWordM[`XLEN-1:0]), .BusStall, .LSUBusWrite,.LSUBusRead, .BusCommittedM,
.DCacheStallM, .DCacheCommittedM, .ByteMaskM, .Cacheable(CacheableM), .DCacheStallM, .DCacheCommittedM, .ByteMaskM, .Cacheable(CacheableM),
.DCacheMiss, .DCacheAccess); .DCacheMiss, .DCacheAccess);
end end
@ -222,14 +225,14 @@ module lsu (
.SelUncachedAdr, .IgnoreRequest, .LSURWM, .CPUBusy, .CacheableM, .SelUncachedAdr, .IgnoreRequest, .LSURWM, .CPUBusy, .CacheableM,
.BusStall, .BusCommittedM); .BusStall, .BusCommittedM);
mux2 #(`XLEN) UnCachedDataMux(.d0(LittleEndianReadDataWordM), .d1(DCacheBusWriteData[`XLEN-1:0]), mux2 #(`LLEN) UnCachedDataMux(.d0(LittleEndianReadDataWordM), .d1({{`LLEN-`XLEN{1'b0}}, DCacheBusWriteData[`XLEN-1:0]}),
.s(SelUncachedAdr), .y(ReadDataWordMuxM)); .s(SelUncachedAdr), .y(ReadDataWordMuxM));
mux2 #(`XLEN) LsuBushwdataMux(.d0(ReadDataWordM), .d1(FinalWriteDataM), mux2 #(`XLEN) LsuBushwdataMux(.d0(ReadDataWordM[`XLEN-1:0]), .d1(FinalWriteDataM),
.s(SelUncachedAdr), .y(LSUBusHWDATA)); .s(SelUncachedAdr), .y(LSUBusHWDATA));
if(CACHE_ENABLED) begin : dcache if(CACHE_ENABLED) begin : dcache
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
.NUMWAYS(`DCACHE_NUMWAYS), .LOGWPL(LOGWPL), .WORDLEN(`XLEN), .MUXINTERVAL(`XLEN), .DCACHE(1)) dcache( .NUMWAYS(`DCACHE_NUMWAYS), .LOGWPL(LOGWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`XLEN), .DCACHE(1)) dcache(
.clk, .reset, .CPUBusy, .LSUBusWriteCrit, .RW(LSURWM), .Atomic(LSUAtomicM), .clk, .reset, .CPUBusy, .LSUBusWriteCrit, .RW(LSURWM), .Atomic(LSUAtomicM),
.FlushCache(FlushDCacheM), .NextAdr(LSUAdrE), .PAdr(LSUPAdrM), .FlushCache(FlushDCacheM), .NextAdr(LSUAdrE), .PAdr(LSUPAdrM),
.ByteMask(ByteMaskM), .WordCount, .ByteMask(ByteMaskM), .WordCount,
@ -253,7 +256,7 @@ module lsu (
// Atomic operations // Atomic operations
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
if (`A_SUPPORTED) begin:atomic if (`A_SUPPORTED) begin:atomic
atomic atomic(.clk, .reset, .StallW, .ReadDataM, .LSUWriteDataM, .LSUPAdrM, atomic atomic(.clk, .reset, .StallW, .ReadDataM(ReadDataM[`XLEN-1:0]), .LSUWriteDataM, .LSUPAdrM,
.LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest, .LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest,
.AMOWriteDataM, .SquashSCW, .LSURWM); .AMOWriteDataM, .SquashSCW, .LSURWM);
end else begin:lrsc end else begin:lrsc
@ -266,7 +269,13 @@ module lsu (
subwordwrite subwordwrite(.LSUPAdrM(LSUPAdrM[2:0]), subwordwrite subwordwrite(.LSUPAdrM(LSUPAdrM[2:0]),
.LSUFunct3M, .AMOWriteDataM, .LittleEndianWriteDataM, .ByteMaskM); .LSUFunct3M, .AMOWriteDataM, .LittleEndianWriteDataM, .ByteMaskM);
subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]), subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]),
.Funct3M(LSUFunct3M), .ReadDataM); .FpLoadM, .Funct3M(LSUFunct3M), .ReadDataM);
/////////////////////////////////////////////////////////////////////////////////////////////
// MW Pipeline Register
/////////////////////////////////////////////////////////////////////////////////////////////
flopen #(`LLEN) ReadDataMWReg(clk, ~StallW, ReadDataM, ReadDataW);
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Big Endian Byte Swapper // Big Endian Byte Swapper
@ -274,8 +283,8 @@ module lsu (
// swap the bytes when read from big-endian memory // swap the bytes when read from big-endian memory
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
if (`BIGENDIAN_SUPPORTED) begin:endian if (`BIGENDIAN_SUPPORTED) begin:endian
bigendianswap storeswap(.BigEndianM, .a(LittleEndianWriteDataM), .y(FinalWriteDataM)); bigendianswap #(`XLEN) storeswap(.BigEndianM, .a(LittleEndianWriteDataM), .y(FinalWriteDataM));
bigendianswap loadswap(.BigEndianM, .a(ReadDataWordM), .y(LittleEndianReadDataWordM)); bigendianswap #(`LLEN) loadswap(.BigEndianM, .a(ReadDataWordM), .y(LittleEndianReadDataWordM));
end else begin end else begin
assign FinalWriteDataM = LittleEndianWriteDataM; assign FinalWriteDataM = LittleEndianWriteDataM;
assign LittleEndianReadDataWordM = ReadDataWordM; assign LittleEndianReadDataWordM = ReadDataWordM;

View File

@ -32,10 +32,11 @@
module subwordread module subwordread
( (
input logic [`XLEN-1:0] ReadDataWordMuxM, input logic [`LLEN-1:0] ReadDataWordMuxM,
input logic [2:0] LSUPAdrM, input logic [2:0] LSUPAdrM,
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
output logic [`XLEN-1:0] ReadDataM input logic FpLoadM,
output logic [`LLEN-1:0] ReadDataM
); );
logic [7:0] ByteM; logic [7:0] ByteM;
@ -74,18 +75,31 @@ module subwordread
1'b1: WordM = ReadDataWordMuxM[63:32]; 1'b1: WordM = ReadDataWordMuxM[63:32];
endcase endcase
// sign extension logic [63:0] DblWordM;
assign DblWordM = ReadDataWordMuxM[63:0];
// sign extension/ NaN boxing
always_comb always_comb
case(Funct3M) case(Funct3M)
3'b000: ReadDataM = {{56{ByteM[7]}}, ByteM}; // lb 3'b000: ReadDataM = {{`LLEN-8{ByteM[7]}}, ByteM}; // lb
3'b001: ReadDataM = {{48{HalfwordM[15]}}, HalfwordM[15:0]}; // lh 3'b001: if(`ZFH_SUPPORTED)
3'b010: ReadDataM = {{32{WordM[31]}}, WordM[31:0]}; // lw ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadM}}, HalfwordM[15:0]}; // lh/flh
3'b011: ReadDataM = ReadDataWordMuxM; // ld else ReadDataM = {{`LLEN-16{HalfwordM[15]}}, HalfwordM[15:0]}; // lh
3'b100: ReadDataM = {56'b0, ByteM[7:0]}; // lbu 3'b010: if(`F_SUPPORTED)
3'b101: ReadDataM = {48'b0, HalfwordM[15:0]}; // lhu ReadDataM = {{`LLEN-32{WordM[31]|FpLoadM}}, WordM[31:0]}; // lw/flw
3'b110: ReadDataM = {32'b0, WordM[31:0]}; // lwu else ReadDataM = {{`LLEN-32{WordM[31]}}, WordM[31:0]}; // lw
3'b011: if(`D_SUPPORTED)
ReadDataM = {{`LLEN-64{DblWordM[63]|FpLoadM}}, DblWordM[63:0]}; // ld/fld
else ReadDataM = {{`LLEN-64{DblWordM[63]}}, DblWordM[63:0]}; // ld/fld
3'b100: if(`Q_SUPPORTED)
ReadDataM = FpLoadM ? ReadDataWordMuxM : {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq
else
ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
3'b110: ReadDataM = {{`LLEN-32{1'b0}}, WordM[31:0]}; // lwu
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
endcase endcase
end else begin:swrmux // 32-bit end else begin:swrmux // 32-bit
// byte mux // byte mux
always_comb always_comb
@ -105,13 +119,18 @@ module subwordread
// sign extension // sign extension
always_comb always_comb
case(Funct3M) case(Funct3M)
3'b000: ReadDataM = {{24{ByteM[7]}}, ByteM}; // lb 3'b000: ReadDataM = {{`LLEN-8{ByteM[7]}}, ByteM}; // lb
3'b001: ReadDataM = {{16{HalfwordM[15]}}, HalfwordM[15:0]}; // lh 3'b001: if(`ZFH_SUPPORTED)
3'b010: ReadDataM = ReadDataWordMuxM; // lw ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadM}}, HalfwordM[15:0]}; // lh/flh
3'b100: ReadDataM = {24'b0, ByteM[7:0]}; // lbu else ReadDataM = {{`LLEN-16{HalfwordM[15]}}, HalfwordM[15:0]}; // lh
3'b101: ReadDataM = {16'b0, HalfwordM[15:0]}; // lhu 3'b010: if(`F_SUPPORTED)
default: ReadDataM = ReadDataWordMuxM; ReadDataM = {{`LLEN-32{ReadDataWordMuxM[31]|FpLoadM}}, ReadDataWordMuxM[31:0]}; // lw/flw
else ReadDataM = {{`LLEN-32{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:0]}; // lw
3'b011: ReadDataM = ReadDataWordMuxM; // fld
3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
endcase endcase
end end
endmodule endmodule

View File

@ -98,6 +98,7 @@ module wallypipelinedcore (
logic IllegalFPUInstrD, IllegalFPUInstrE; logic IllegalFPUInstrD, IllegalFPUInstrE;
logic FRegWriteM; logic FRegWriteM;
logic FPUStallD; logic FPUStallD;
logic FpLoadM;
logic [1:0] FResSelW; logic [1:0] FResSelW;
logic [4:0] SetFflagsM; logic [4:0] SetFflagsM;
@ -128,8 +129,7 @@ module wallypipelinedcore (
logic [`XLEN-1:0] IEUAdrE; logic [`XLEN-1:0] IEUAdrE;
(* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataE; (* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataE;
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM; (* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
(* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM; logic [`LLEN-1:0] ReadDataW;
logic [`XLEN-1:0] ReadDataW;
logic CommittedM; logic CommittedM;
// AHB ifu interface // AHB ifu interface
@ -229,8 +229,8 @@ module wallypipelinedcore (
.RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM, .RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM,
// Writeback stage // Writeback stage
.CSRReadValW, .ReadDataM, .MDUResultW, .CSRReadValW, .MDUResultW,
.RdW, .ReadDataW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]),
.InstrValidM, .InstrValidM,
.FCvtIntResW, .FCvtIntResW,
.FResSelW, .FResSelW,
@ -253,9 +253,10 @@ module wallypipelinedcore (
.AtomicM, .TrapM, .AtomicM, .TrapM,
.CommittedM, .DCacheMiss, .DCacheAccess, .CommittedM, .DCacheMiss, .DCacheAccess,
.SquashSCW, .SquashSCW,
.FpLoadM,
//.DataMisalignedM(DataMisalignedM), //.DataMisalignedM(DataMisalignedM),
.IEUAdrE, .IEUAdrM, .WriteDataE, .IEUAdrE, .IEUAdrM, .WriteDataE,
.ReadDataM, .FlushDCacheM, .ReadDataW, .FlushDCacheM,
// connected to ahb (all stay the same) // connected to ahb (all stay the same)
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck, .LSUBusInit, .LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck, .LSUBusInit,
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize, .LSUBurstType, .LSUTransType, .LSUTransComplete, .LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize, .LSUBurstType, .LSUTransType, .LSUTransComplete,
@ -383,13 +384,14 @@ module wallypipelinedcore (
.clk, .reset, .clk, .reset,
.FRM_REGW, // Rounding mode from CSR .FRM_REGW, // Rounding mode from CSR
.InstrD, // instruction from IFU .InstrD, // instruction from IFU
.ReadDataW,// Read data from memory .ReadDataW(ReadDataW[`FLEN-1:0]),// Read data from memory
.ForwardedSrcAE, // Integer input being processed (from IEU) .ForwardedSrcAE, // Integer input being processed (from IEU)
.StallE, .StallM, .StallW, // stall signals from HZU .StallE, .StallM, .StallW, // stall signals from HZU
.FlushE, .FlushM, .FlushW, // flush signals from HZU .FlushE, .FlushM, .FlushW, // flush signals from HZU
.RdM, .RdW, // which FP register to write to (from IEU) .RdM, .RdW, // which FP register to write to (from IEU)
.STATUS_FS, // is floating-point enabled? .STATUS_FS, // is floating-point enabled?
.FRegWriteM, // FP register write enable .FRegWriteM, // FP register write enable
.FpLoadM,
.FStallD, // Stall the decode stage .FStallD, // Stall the decode stage
.FWriteIntE, // integer register write enable .FWriteIntE, // integer register write enable
.FWriteDataE, // Data to be written to memory .FWriteDataE, // Data to be written to memory

View File

@ -1 +1,2 @@
verilator --lint-only --top-module srt srt.sv -I../config/rv64gc -I../config/shared ../src/generic/*.sv ../src/generic/flop/*.sv verilator --lint-only --top-module srt srt.sv -I../config/rv64gc -I../config/shared ../src/generic/*.sv ../src/generic/flop/*.sv
verilator --lint-only --top-module srtradix4 srt-radix4.sv qsel4.sv -I../config/rv64gc -I../config/shared ../src/generic/*.sv ../src/generic/flop/*.sv

1048
pipelined/srt/qsel4.sv Normal file

File diff suppressed because it is too large Load Diff

2
pipelined/srt/sim-srt4 Executable file
View File

@ -0,0 +1,2 @@
vsim -do "do srt-radix4.do"

1
pipelined/srt/sim-srt4-batch Executable file
View File

@ -0,0 +1 @@
vsim -c -do "do srt-radix4.do"

View File

@ -0,0 +1,31 @@
# srt.do
#
# David_Harris@hmc.edu 19 October 2021
# Use this wally-pipelined.do file to run this example.
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
# do wally-pipelined.do
# or, to run from a shell, type the following at the shell prompt:
# vsim -do wally-pipelined.do -c
# (omit the "-c" to see the GUI while running from the shell)
onbreak {resume}
# create library
if [file exists work] {
vdel -all
}
vlib work
vlog +incdir+../config/rv64gc +incdir+../config/shared srt-radix4.sv testbench-radix4.sv qsel4.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv ../src/generic/lzc.sv
vopt +acc work.testbenchradix4 -o workopt
vsim workopt
-- display input and output signals as hexidecimal values
add wave /testbenchradix4/*
add wave /testbenchradix4/srtradix4/*
add wave /testbenchradix4/srtradix4/qsel4/*
add wave /testbenchradix4/srtradix4/otfc4/*
-- Run the Simulation
run -all

323
pipelined/srt/srt-radix4.sv Normal file
View File

@ -0,0 +1,323 @@
///////////////////////////////////////////
// srt.sv
//
// Written: David_Harris@hmc.edu 13 January 2022
// Modified:
//
// Purpose: Combined Divide and Square Root Floating Point and Integer Unit
//
// 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"
`define DIVLEN ((`NF<(`XLEN)) ? (`XLEN) : `NF)
module srtradix4 (
input logic clk,
input logic Start,
input logic Stall, // *** multiple pipe stages
input logic Flush, // *** multiple pipe stages
// Floating Point Inputs
// later add exponents, signs, special cases
input logic XSign, YSign,
input logic [`NE-1:0] XExp, YExp,
input logic [`NF-1:0] XFrac, YFrac,
input logic [`XLEN-1:0] SrcA, SrcB,
input logic [1:0] Fmt, // Floats: 00 = 16 bit, 01 = 32 bit, 10 = 64 bit, 11 = 128 bit
input logic W64, // 32-bit ints on XLEN=64
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, // *** later handle integers
output logic [`NE-1:0] rExp,
output logic [3:0] Flags
);
// logic qp, qz, qm; // quotient is +1, 0, or -1
logic [3:0] q;
logic [`NE-1:0] calcExp;
logic calcSign;
logic [`DIVLEN-1:0] X, Dpreproc;
logic [`DIVLEN+3:0] WS, WSA, WSN;
logic [`DIVLEN+3:0] WC, WCA, WCN;
logic [`DIVLEN+3:0] D, DBar, D2, DBar2, Dsel;
logic [$clog2(`XLEN+1)-1:0] intExp;
logic intSign;
srtpreproc preproc(SrcA, SrcB, XFrac, YFrac, Fmt, W64, Signed, Int, Sqrt, X, Dpreproc, intExp, intSign);
// Top Muxes and Registers
// When start is asserted, the inputs are loaded into the divider.
// Otherwise, the divisor is retained and the partial remainder
// is fed back for the next iteration.
// - assumed one is added here since all numbers are normlaized
// *** wait what about zero? is that specal case? can the divider handle it?
// - when the start signal is asserted X and 0 are loaded into WS and WC
// - otherwise load WSA into the flipflop
// *** what does N and A stand for?
// *** change shift amount for radix4
mux2 #(`DIVLEN+4) wsmux({WSA[`DIVLEN+1:0], 2'b0}, {4'b0001, X}, Start, WSN);
flop #(`DIVLEN+4) wsflop(clk, WSN, WS);
mux2 #(`DIVLEN+4) wcmux({WCA[`DIVLEN+1:0], 2'b0}, {`DIVLEN+4{1'b0}}, Start, WCN);
flop #(`DIVLEN+4) wcflop(clk, WCN, WC);
flopen #(`DIVLEN+4) dflop(clk, Start, {4'b0001, Dpreproc}, D);
// Quotient Selection logic
// Given partial remainder, select quotient of +1, 0, or -1 (qp, qz, pm)
// *** change this for radix 4 - generate w/ stine code
// q encoding:
// 1000 = +2
// 0100 = +1
// 0000 = 0
// 0010 = -1
// 0001 = -2
qsel4 qsel4(.D, .WS, .WC, .q);
// Store the expoenent and sign until division is done
flopen #(`NE) expflop(clk, Start, calcExp, rExp);
flopen #(1) signflop(clk, Start, calcSign, rsign);
// Divisor Selection logic
// *** radix 4 change to choose -2 to 2
// - choose the negitive version of what's being selected
assign DBar = ~D;
assign DBar2 = {~D[`DIVLEN+2:0], 1'b1};
assign D2 = {D[`DIVLEN+2:0], 1'b0};
always_comb
case (q)
4'b1000: Dsel = DBar2;
4'b0100: Dsel = DBar;
4'b0000: Dsel = {(`DIVLEN+4){1'b0}};
4'b0010: Dsel = D;
4'b0001: Dsel = D2;
default: Dsel = {`DIVLEN+4{1'bx}};
endcase
// Partial Product Generation
// WSA, WCA = WS + WC - qD
csa #(`DIVLEN+4) csa(WS, WC, Dsel, |q[3:2], WSA, WCA);
//*** change for radix 4
otfc4 #(`DIVLEN) otfc4(clk, Start, q, Quot);
expcalc expcalc(.XExp, .YExp, .calcExp);
signcalc signcalc(.XSign, .YSign, .calcSign);
endmodule
////////////////
// Submodules //
////////////////
///////////////////
// Preprocessing //
///////////////////
module srtpreproc (
input logic [`XLEN-1:0] SrcA, SrcB,
input logic [`NF-1:0] XFrac, YFrac,
input logic [1:0] Fmt, // Floats: 00 = 16 bit, 01 = 32 bit, 10 = 64 bit, 11 = 128 bit
input logic W64, // 32-bit ints on XLEN=64
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 [`DIVLEN-1:0] X, D,
output logic [$clog2(`XLEN+1)-1:0] intExp, // Quotient integer exponent
output logic intSign // Quotient integer sign
);
logic [$clog2(`XLEN+1)-1:0] zeroCntA, zeroCntB;
logic [`XLEN-1:0] PosA, PosB;
logic [`DIVLEN-1:0] ExtraA, ExtraB, PreprocA, PreprocB, PreprocX, PreprocY;
assign PosA = (Signed & SrcA[`XLEN - 1]) ? -SrcA : SrcA;
assign PosB = (Signed & SrcB[`XLEN - 1]) ? -SrcB : SrcB;
lzc #(`XLEN) lzcA (PosA, zeroCntA);
lzc #(`XLEN) lzcB (PosB, zeroCntB);
assign ExtraA = {PosA, {`DIVLEN-`XLEN{1'b0}}};
assign ExtraB = {PosB, {`DIVLEN-`XLEN{1'b0}}};
assign PreprocA = ExtraA << zeroCntA;
assign PreprocB = ExtraB << (zeroCntB + 1);
assign PreprocX = {XFrac, {`DIVLEN-`NF{1'b0}}};
assign PreprocY = {YFrac, {`DIVLEN-`NF{1'b0}}};
assign X = Int ? PreprocA : PreprocX;
assign D = Int ? PreprocB : PreprocY;
assign intExp = zeroCntB - zeroCntA + 1;
assign intSign = Signed & (SrcA[`XLEN - 1] ^ SrcB[`XLEN - 1]);
endmodule
/////////////////////////////////
// Quotient Selection, Radix 2 //
/////////////////////////////////
module qsel2 ( // *** eventually just change to 4 bits
input logic [`DIVLEN+3:`DIVLEN] ps, pc,
output logic qp, qz, qm
);
logic [`DIVLEN+3:`DIVLEN] p, g;
logic magnitude, sign, cout;
// The quotient selection logic is presented for simplicity, not
// for efficiency. You can probably optimize your logic to
// select the proper divisor with less delay.
// Quotient equations from EE371 lecture notes 13-20
assign p = ps ^ pc;
assign g = ps & pc;
assign #1 magnitude = ~(&p[`DIVLEN+2:`DIVLEN]);
assign #1 cout = g[`DIVLEN+2] | (p[`DIVLEN+2] & (g[`DIVLEN+1] | p[`DIVLEN+1] & g[`DIVLEN]));
assign #1 sign = p[`DIVLEN+3] ^ cout;
/* assign #1 magnitude = ~((ps[54]^pc[54]) & (ps[53]^pc[53]) &
(ps[52]^pc[52]));
assign #1 sign = (ps[55]^pc[55])^
(ps[54] & pc[54] | ((ps[54]^pc[54]) &
(ps[53]&pc[53] | ((ps[53]^pc[53]) &
(ps[52]&pc[52]))))); */
// Produce quotient = +1, 0, or -1
assign #1 qp = magnitude & ~sign;
assign #1 qz = ~magnitude;
assign #1 qm = magnitude & sign;
endmodule
///////////////////////////////////
// On-The-Fly Converter, Radix 2 //
///////////////////////////////////
module otfc4 #(parameter N=65) (
input logic clk,
input logic Start,
input logic [3:0] q,
output logic [N-1:0] r
);
// The on-the-fly converter transfers the quotient
// bits to the quotient as they come.
//
// This code follows the psuedocode presented in the
// floating point chapter of the book. Right now,
// it is written for Radix-2 division.
//
// QM is Q-1. It allows us to write negative bits
// without using a costly CPA.
logic [N+2:0] Q, QM, QNext, QMNext, QMux, QMMux;
// QR and QMR are the shifted versions of Q and QM.
// They are treated as [N-1:r] size signals, and
// discard the r most significant bits of Q and QM.
logic [N:0] QR, QMR;
// if starting a new divison set Q to 0 and QM to -1
mux2 #(N+3) Qmux(QNext, {N+3{1'b0}}, Start, QMux);
mux2 #(N+3) QMmux(QMNext, {N+3{1'b1}}, Start, QMMux);
flop #(N+3) Qreg(clk, QMux, Q);
flop #(N+3) QMreg(clk, QMMux, QM);
// shift Q (quotent) and QM (quotent-1)
// if q = 2 Q = {Q, 10} QM = {Q, 01}
// else if q = 1 Q = {Q, 01} QM = {Q, 00}
// else if q = 0 Q = {Q, 00} QM = {QM, 11}
// else if q = -1 Q = {QM, 11} QM = {QM, 10}
// else if q = -2 Q = {QM, 10} QM = {QM, 01}
// *** how does the 0 concatination numbers work?
always_comb begin
QR = Q[N:0];
QMR = QM[N:0]; // Shift Q and QM
if (q[3]) begin // +2
QNext = {QR, 2'b10};
QMNext = {QR, 2'b01};
end else if (q[2]) begin // +1
QNext = {QR, 2'b01};
QMNext = {QR, 2'b00};
end else if (q[1]) begin // -1
QNext = {QMR, 2'b11};
QMNext = {QMR, 2'b10};
end else if (q[0]) begin // -2
QNext = {QMR, 2'b10};
QMNext = {QMR, 2'b01};
end else begin // 0
QNext = {QR, 2'b00};
QMNext = {QMR, 2'b11};
end
end
assign r = Q[N+2] ? Q[N+1:2] : Q[N:1];
endmodule
/////////
// csa //
/////////
module csa #(parameter N=69) (
input logic [N-1:0] in1, in2, in3,
input logic cin,
output logic [N-1:0] out1, out2
);
// This block adds in1, in2, in3, and cin to produce
// a result out1 / out2 in carry-save redundant form.
// cin is just added to the least significant bit and
// is required to handle adding a negative divisor.
// Fortunately, the carry (out2) is shifted left by one
// bit, leaving room in the least significant bit to
// insert cin.
assign #1 out1 = in1 ^ in2 ^ in3;
assign #1 out2 = {in1[N-2:0] & (in2[N-2:0] | in3[N-2:0]) |
(in2[N-2:0] & in3[N-2:0]), cin};
endmodule
//////////////
// expcalc //
//////////////
module expcalc(
input logic [`NE-1:0] XExp, YExp,
output logic [`NE-1:0] calcExp
);
assign calcExp = XExp - YExp + (`NE)'(`BIAS);
endmodule
//////////////
// signcalc //
//////////////
module signcalc(
input logic XSign, YSign,
output logic calcSign
);
assign calcSign = XSign ^ YSign;
endmodule

View File

@ -1 +1,3 @@
add wave -noupdate /testbench/clk add wave -noupdate /testbench/*
add wave -noupdate /testbench/srt/*
add wave -noupdate /testbench/srt/otfc2/*

13
pipelined/srt/stine/notes Normal file
View File

@ -0,0 +1,13 @@
Dividend x --(0.10101111), divisord --(0.11000101)(i -- 16(0.1100)2- 12)
X = 175 (xAF)
D = 197 (xC5)
X = 175/256 = 0.68359375
D = 197/256 = 0.76953125
Note: Add lg(r) extra iterations due to shifting of computed q
q_{computed} = q / radix
./srt4div 0.68359375 0.76953125 4 10

Binary file not shown.

View File

@ -1,83 +1,45 @@
#include "disp.h" #include "disp.h"
#include <math.h> #include <math.h>
// QSLC is for division by recuerrence for
// r=4 using a CPA - See Table 5.9 EL
int qslc (double prem, double d) { int qslc (double prem, double d) {
int q; int q;
// For Debugging
printf("d --> %lg\n", d); printf("d --> %lg\n", d);
printf("rw --> %lg\n", prem); printf("rw --> %lg\n", prem);
if ((d>=0.0)&&(d<1.0)) {
if (prem>=1.0) if ((d>=8.0)&&(d<9.0)) {
q = 2; if (prem>=6.0)
else if (prem>=0.25)
q = 1;
else if (prem>=-0.25)
q = 0;
else if (prem >= -1)
q = -1;
else
q = -2;
return q;
}
if ((d>=1.0)&&(d<2.0)) {
if (prem>=2.0)
q = 2;
else if (prem>=0.66667)
q = 1;
else if (prem>=-0.6667)
q = 0;
else if (prem >= -2)
q = -1;
else
q = -2;
return q;
}
if ((d>=2.0)&&(d<3.0)) {
if (prem>=4.0)
q = 2;
else if (prem>=1.25)
q = 1;
else if (prem>=-1.25)
q = 0;
else if (prem >= -4)
q = -1;
else
q = -2;
return q;
}
if ((d>=3.0)&&(d<4.0)) {
if (prem>=5.0)
q = 2; q = 2;
else if (prem>=2.0) else if (prem>=2.0)
q = 1; q = 1;
else if (prem>=-2.0) else if (prem>=-2.0)
q = 0; q = 0;
else if (prem >= -5) else if (prem >= -6)
q = -1; q = -1;
else else
q = -2; q = -2;
return q; return q;
} }
if ((d>=4.0)&&(d<5.0)) { if ((d>=9.0)&&(d<10.0)) {
if (prem>=6.66667) if (prem>=7)
q = 2; q = 2;
else if (prem>=2.0) else if (prem>=2.0)
q = 1; q = 1;
else if (prem>=-2.0) else if (prem>=-2.0)
q = 0; q = 0;
else if (prem >= -6.66667) else if (prem >= 7.0)
q = -1; q = -1;
else else
q = -2; q = -2;
return q; return q;
} }
if ((d>=5.0)&&(d<6.0)) { if ((d>=10.0)&&(d<11.0)) {
if (prem>=8.0) if (prem>=8.0)
q = 2; q = 2;
else if (prem>=2.0) else if (prem>=2.0)
@ -91,7 +53,21 @@ int qslc (double prem, double d) {
return q; return q;
} }
if ((d>=6.0)&&(d<7.0)) { if ((d>=11.0)&&(d<12.0)) {
if (prem>=8.0)
q = 2;
else if (prem>=2.0)
q = 1;
else if (prem>=-2.0)
q = 0;
else if (prem >= -8.0)
q = -1;
else
q = -2;
return q;
}
if ((d>=12.0)&&(d<13.0)) {
if (prem>=10.0) if (prem>=10.0)
q = 2; q = 2;
else if (prem>=4.0) else if (prem>=4.0)
@ -105,21 +81,35 @@ int qslc (double prem, double d) {
return q; return q;
} }
if ((d>=7.0)&&(d<8.0)) { if ((d>=13.0)&&(d<14.0)) {
if (prem>=11.0) if (prem>=10.0)
q = 2; q = 2;
else if (prem>=4.0) else if (prem>=4.0)
q = 1; q = 1;
else if (prem>=-4.0) else if (prem>=-4.0)
q = 0; q = 0;
else if (prem >= -11.0) else if (prem >= -10.0)
q = -1; q = -1;
else else
q = -2; q = -2;
return q; return q;
} }
if ((d>=8.0)&&(d<9.0)) { if ((d>=14.0)&&(d<15.0)) {
if (prem>=10.0)
q = 2;
else if (prem>=4.0)
q = 1;
else if (prem>=-4.0)
q = 0;
else if (prem >= -10.0)
q = -1;
else
q = -2;
return q;
}
if ((d>=15.0)&&(d<16.0)) {
if (prem>=12.0) if (prem>=12.0)
q = 2; q = 2;
else if (prem>=4.0) else if (prem>=4.0)
@ -133,106 +123,9 @@ int qslc (double prem, double d) {
return q; return q;
} }
if ((d>=9.0)&&(d<10.0)) {
if (prem>=15.0)
q = 2;
else if (prem>=4.0)
q = 1;
else if (prem>=-4.0)
q = 0;
else if (prem >= -15.0)
q = -1;
else
q = -2;
return q;
}
if ((d>=10.0)&&(d<11.0)) {
if (prem>=15.0)
q = 2;
else if (prem>=4.0)
q = 1;
else if (prem>=-4.0)
q = 0;
else if (prem >= -15.0)
q = -1;
else
q = -2;
return q;
}
if ((d>=11.0)&&(d<12.0)) {
if (prem>=16.0)
q = 2;
else if (prem>=4.0)
q = 1;
else if (prem>=-4.0)
q = 0;
else if (prem >= -16.0)
q = -1;
else
q = -2;
return q;
}
if ((d>=12.0)&&(d<13.0)) {
if (prem>=20.0)
q = 2;
else if (prem>=8.0)
q = 1;
else if (prem>=-8.0)
q = 0;
else if (prem >= -20.0)
q = -1;
else
q = -2;
return q;
}
if ((d>=13.0)&&(d<14.0)) {
if (prem>=20.0)
q = 2;
else if (prem>=8.0)
q = 1;
else if (prem>=-8.0)
q = 0;
else if (prem >= -20.0)
q = -1;
else
q = -2;
return q;
}
if ((d>=14.0)&&(d<15.0)) {
if (prem>=20.0)
q = 2;
else if (prem>=8.0)
q = 1;
else if (prem>=-8.0)
q = 0;
else if (prem >= -20.0)
q = -1;
else
q = -2;
return q;
}
if ((d>=15.0)&&(d<16.0)) {
if (prem>=24.0)
q = 2;
else if (prem>=8.0)
q = 1;
else if (prem>=-8.0)
q = 0;
else if (prem >= -24.0)
q = -1;
else
q = -2;
return q;
}
} }
/* /*
This routine performs a radix-4 SRT division This routine performs a radix-4 SRT division
algorithm. The user inputs the numerator, the denominator, algorithm. The user inputs the numerator, the denominator,
@ -246,6 +139,8 @@ int main(int argc, char* argv[]) {
int q; int q;
int num_iter, i; int num_iter, i;
int prec; int prec;
int radix = 4;
if (argc < 5) { if (argc < 5) {
fprintf(stderr, fprintf(stderr,
"Usage: %s numerator denominator num_iterations prec\n", "Usage: %s numerator denominator num_iterations prec\n",
@ -267,27 +162,29 @@ int main(int argc, char* argv[]) {
printf("\n"); printf("\n");
Q = 0; Q = 0;
P = N*0.25; P = N * pow(2.0, -log2(radix));
printf("N = %lg, D = %lg, N/D = %lg, num_iter = %d \n\n", printf("N = %lg, D = %lg, N/D = %lg, num_iter = %d \n\n",
N, D, N/D, num_iter); N, D, N/D, num_iter);
for (scale = 1, i = 0; i < num_iter; i++) { for (scale = 1, i = 0; i < num_iter; i++) {
// Shift by r // Shift by r
scale = scale*0.25; scale = scale * pow(2.0, -log2(radix));
q = qslc(flr((4*P)*16,3), D*16); // (4*P)*8 because of footnote in Table 5.9, page 296 EL
//q = -q; // i.e., real value = shown value / 8
// D*16 since we use 4 bits of D (1 bit known)
q = qslc(flr((radix * P) * 8, 3), D*16);
printf("4*W[n] = "); printf("4*W[n] = ");
disp_bin(4*P,3,prec,stdout); disp_bin(radix*P, 3, prec, stdout);
printf("\n"); printf("\n");
printf("q*D = "); printf("q*D = ");
disp_bin(q*D,3,prec,stdout); disp_bin(q*D, 3, prec, stdout);
printf("\n"); printf("\n");
printf("W[n+1] = "); printf("W[n+1] = ");
disp_bin(P ,3,prec,stdout); disp_bin(P ,3, prec, stdout);
printf("\n"); printf("\n");
// Recurrence // Recurrence
P = 4*P - q*D; P = radix * P - q * D;
// OTFC // OTFC
Q = Q + q*scale; Q = Q + q * scale;
printf("i = %d, q = %d, Q = %1.18lf, W = %1.18lf\n", i, q, Q, P); printf("i = %d, q = %d, Q = %1.18lf, W = %1.18lf\n", i, q, Q, P);
printf("i = %d, q = %d", i, q); printf("i = %d, q = %d", i, q);
printf(", Q = "); printf(", Q = ");
@ -296,8 +193,9 @@ int main(int argc, char* argv[]) {
disp_bin(P, 3, prec, stdout); disp_bin(P, 3, prec, stdout);
printf("\n\n"); printf("\n\n");
} }
// Is shifted partial remainder negative?
if (P < 0) { if (P < 0) {
Q = Q - scale; Q = Q - pow(2.0, -prec);
P = P + D; P = P + D;
printf("\nCorrecting Negative Remainder\n"); printf("\nCorrecting Negative Remainder\n");
printf("Q = %1.18lf, W = %1.18lf\n", Q, P); printf("Q = %1.18lf, W = %1.18lf\n", Q, P);
@ -306,9 +204,12 @@ int main(int argc, char* argv[]) {
printf(", W = "); printf(", W = ");
disp_bin(P, 3, prec, stdout); disp_bin(P, 3, prec, stdout);
printf("\n"); printf("\n");
} }
RQ = flr(N/D, (double) prec);
RD = Q*4; // Output Results
RQ = N/D;
// Since q_{computed} = q / radix, multiply by radix
RD = Q * radix;
printf("true = %1.18lf, computed = %1.18lf, \n", RQ, RD); printf("true = %1.18lf, computed = %1.18lf, \n", RQ, RD);
printf("true = "); printf("true = ");
disp_bin(RQ, 3, prec, stdout); disp_bin(RQ, 3, prec, stdout);

View File

@ -0,0 +1,148 @@
`include "wally-config.vh"
`define DIVLEN ((`NF<`XLEN) ? `XLEN : `NF)
/////////////
// counter //
/////////////
module counter(input logic clk,
input logic req,
output logic done);
logic [5: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.
always @(posedge clk)
begin
if (count == `DIVLEN/2+1) done <= #1 1;
else if (done | req) done <= #1 0;
if (req) count <= #1 0;
else count <= #1 count+1;
end
endmodule
///////////
// clock //
///////////
module clock(clk);
output clk;
// Internal clk signal
logic clk;
endmodule
//////////
// testbench //
//////////
module testbenchradix4;
logic clk;
logic req;
logic done;
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
// Test parameters
parameter MEM_SIZE = 40000;
parameter MEM_WIDTH = 64+64+64;
`define memr 63:0
`define memb 127:64
`define mema 191:128
// Test logicisters
logic [MEM_WIDTH-1:0] Tests [0:MEM_SIZE]; // Space for input file
logic [MEM_WIDTH-1:0] Vec; // Verilog doesn't allow direct access to a
// bit field of an array
logic [63:0] correctr, nextr, diffn, diffp;
logic [10:0] rExp;
logic rsign;
integer testnum, errors;
// Divider
srtradix4 srtradix4(.clk, .Start(req),
.Stall(1'b0), .Flush(1'b0),
.XExp(aExp), .YExp(bExp), .rExp,
.XSign(asign), .YSign(bsign), .rsign,
.XFrac(afrac), .YFrac(bfrac),
.SrcA('0), .SrcB('0), .Fmt(2'b00),
.W64(1'b0), .Signed(1'b0), .Int(1'b0), .Sqrt(1'b0),
.Quot, .Rem(), .Flags());
// Counter
counter counter(clk, req, done);
initial
forever
begin
clk = 1; #17;
clk = 0; #17;
end
// Read test vectors from disk
initial
begin
testnum = 0;
errors = 0;
$readmemh ("testvectors", Tests);
Vec = Tests[testnum];
a = Vec[`mema];
{asign, aExp, afrac} = a;
b = Vec[`memb];
{bsign, bExp, bfrac} = b;
nextr = Vec[`memr];
r = Quot[`DIVLEN-1:`DIVLEN - 52];
req <= 1;
end
// Apply directed test vectors read from file.
always @(posedge clk)
begin
r = Quot[`DIVLEN-1:`DIVLEN - 52];
if (done) begin
req <= 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
if (req)
begin
req <= 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

@ -7,7 +7,7 @@ module counter(input logic clk,
input logic req, input logic req,
output logic done); output logic done);
logic [5:0] count; logic [7:0] count;
// This block of control logic sequences the divider // This block of control logic sequences the divider
// through its iterations. You may modify it if you // through its iterations. You may modify it if you
@ -17,7 +17,7 @@ module counter(input logic clk,
always @(posedge clk) always @(posedge clk)
begin begin
if (count == 54) done <= #1 1; if (count == `DIVLEN+1) done <= #1 1;
else if (done | req) done <= #1 0; else if (done | req) done <= #1 0;
if (req) count <= #1 0; if (req) count <= #1 0;
else count <= #1 count+1; else count <= #1 count+1;
@ -110,12 +110,14 @@ module testbench;
always @(posedge clk) always @(posedge clk)
begin begin
r = Quot[`DIVLEN:`DIVLEN - 52];
rOTFC = QuotOTFC[`DIVLEN:`DIVLEN - 52];
if (done) if (done)
begin begin
req <= #5 1; req <= #5 1;
diffp = correctr[51:0] - r; diffp = correctr[51:0] - r;
diffn = r - correctr[51:0]; diffn = r - correctr[51:0];
if ((rsign !== correctr[63]) | (rExp !== correctr[62:52]) | ($signed(diffn) > 1) | ($signed(diffp) > 1)) // check if accurate to 1 ulp 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 begin
errors = errors+1; errors = errors+1;
$display("result was %h_%h, should be %h %h %h\n", rExp, r, correctr, diffn, diffp); $display("result was %h_%h, should be %h %h %h\n", rExp, r, correctr, diffn, diffp);

View File

@ -559,11 +559,11 @@ module testbench;
if ((dut.core.lsu.LSUPAdrM == 'h10000002) | (dut.core.lsu.LSUPAdrM == 'h10000005) | (dut.core.lsu.LSUPAdrM == 'h10000006)) begin \ if ((dut.core.lsu.LSUPAdrM == 'h10000002) | (dut.core.lsu.LSUPAdrM == 'h10000005) | (dut.core.lsu.LSUPAdrM == 'h10000006)) begin \
if(!NO_SPOOFING) begin \ if(!NO_SPOOFING) begin \
$display("%tns, %d instrs: Overwrite UART's Register in memory stage.", $time, AttemptedInstructionCount); \ $display("%tns, %d instrs: Overwrite UART's Register in memory stage.", $time, AttemptedInstructionCount); \
force dut.core.ieu.dp.ReadDataM = ExpectedMemReadDataM; \ force dut.core.lsu.ReadDataM = ExpectedMemReadDataM; \
end \ end \
end else \ end else \
if(!NO_SPOOFING) \ if(!NO_SPOOFING) \
release dut.core.ieu.dp.ReadDataM; \ release dut.core.lsu.ReadDataM; \
if(textM.substr(0,5) == "rdtime") begin \ if(textM.substr(0,5) == "rdtime") begin \
//$display("%tns, %d instrs: Overwrite MTIME_CLINT on read of MTIME in memory stage.", $time, InstrCountW-1); \ //$display("%tns, %d instrs: Overwrite MTIME_CLINT on read of MTIME in memory stage.", $time, InstrCountW-1); \
if(!NO_SPOOFING) \ if(!NO_SPOOFING) \

View File

@ -51,7 +51,6 @@ module testbench;
string tests[]; string tests[];
logic [3:0] dummy; logic [3:0] dummy;
string ProgramAddrMapFile, ProgramLabelMapFile;
logic [`AHBW-1:0] HRDATAEXT; logic [`AHBW-1:0] HRDATAEXT;
logic HREADYEXT, HRESPEXT; logic HREADYEXT, HRESPEXT;
logic [31:0] HADDR; logic [31:0] HADDR;
@ -65,6 +64,9 @@ logic [3:0] dummy;
logic HCLK, HRESETn; logic HCLK, HRESETn;
logic [`XLEN-1:0] PCW; logic [`XLEN-1:0] PCW;
string ProgramAddrMapFile, ProgramLabelMapFile;
integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 };
logic DCacheFlushDone, DCacheFlushStart; logic DCacheFlushDone, DCacheFlushStart;
flopenr #(`XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); flopenr #(`XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW);
@ -128,7 +130,7 @@ logic [3:0] dummy;
end end
string signame, memfilename, pathname, objdumpfilename, adrstr, outputfile; string signame, memfilename, pathname, objdumpfilename, adrstr, outputfile;
integer outputFilePointer, ProgramLabelMap, ProgramAddrMap; integer outputFilePointer;
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
logic UARTSin, UARTSout; logic UARTSin, UARTSout;
@ -194,6 +196,9 @@ logic [3:0] dummy;
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
// declare memory labels that interest us, the updateProgramAddrLabelArray task will find the addr of each label and fill the array
// to expand, add more elements to this array and initialize them to zero (also initilaize them to zero at the start of the next test)
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
$display("Read memfile %s", memfilename); $display("Read memfile %s", memfilename);
reset_ext = 1; # 42; reset_ext = 0; reset_ext = 1; # 42; reset_ext = 0;
end end
@ -218,30 +223,12 @@ logic [3:0] dummy;
end end
// Termination condition (i.e. we finished running current test) // Termination condition (i.e. we finished running current test)
if (DCacheFlushDone) begin if (DCacheFlushDone) begin
// Gets the memory location of begin_signature integer begin_signature_addr;
adrstr = "0"; begin_signature_addr = ProgramAddrLabelArray["begin_signature"];
ProgramLabelMap = $fopen(ProgramLabelMapFile, "r"); if (!begin_signature_addr)
ProgramAddrMap = $fopen(ProgramAddrMapFile, "r");
if (ProgramLabelMap & ProgramAddrMap) begin // check we found both files
while (!$feof(ProgramLabelMap)) begin
string label;
integer returncode;
returncode = $fgets(label, ProgramLabelMap);
returncode = $fgets(adrstr, ProgramAddrMap);
if (label == "begin_signature\n") begin
if (DEBUG) $display("%s begin_signature adrstr: %s", TEST, adrstr);
break;
end
end
end
if (adrstr == "0") begin
$display("begin_signature addr not found in %s", ProgramLabelMapFile); $display("begin_signature addr not found in %s", ProgramLabelMapFile);
end testadr = ($unsigned(begin_signature_addr))/(`XLEN/8);
$fclose(ProgramLabelMap); testadrNoBase = (begin_signature_addr - `RAM_BASE)/(`XLEN/8);
$fclose(ProgramAddrMap);
testadr = ($unsigned(adrstr.atohex()))/(`XLEN/8);
testadrNoBase = (adrstr.atohex() - `RAM_BASE)/(`XLEN/8);
#600; // give time for instructions in pipeline to finish #600; // give time for instructions in pipeline to finish
if (TEST == "embench") begin if (TEST == "embench") begin
// Writes contents of begin_signature to .sim.output file // Writes contents of begin_signature to .sim.output file
@ -263,8 +250,10 @@ logic [3:0] dummy;
for(i=0; i<SIGNATURESIZE; i=i+1) begin for(i=0; i<SIGNATURESIZE; i=i+1) begin
sig32[i] = 'bx; sig32[i] = 'bx;
end end
// riscof tests have a different signature, tests[0] == "1" refers to RISCVARCHTESTs
if (tests[0] == "1") signame = {pathname, tests[test], "erence-sail_c_simulator.signature"};
else signame = {pathname, tests[test], ".signature.output"};
// read signature, reformat in 64 bits if necessary // read signature, reformat in 64 bits if necessary
signame = {pathname, tests[test], ".signature.output"};
$readmemh(signame, sig32); $readmemh(signame, sig32);
i = 0; i = 0;
while (i < SIGNATURESIZE) begin while (i < SIGNATURESIZE) begin
@ -319,7 +308,6 @@ logic [3:0] dummy;
end end
end end
// move onto the next test, check to see if we're done // move onto the next test, check to see if we're done
// test = test + 2;
test = test + 1; test = test + 1;
if (test == tests.size()) begin if (test == tests.size()) begin
if (totalerrors == 0) $display("SUCCESS! All tests ran without failures."); if (totalerrors == 0) $display("SUCCESS! All tests ran without failures.");
@ -337,6 +325,8 @@ logic [3:0] dummy;
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
ProgramAddrLabelArray = '{ "begin_signature" : 0, "tohost" : 0 };
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
$display("Read memfile %s", memfilename); $display("Read memfile %s", memfilename);
reset_ext = 1; # 47; reset_ext = 0; reset_ext = 1; # 47; reset_ext = 0;
end end
@ -364,7 +354,8 @@ logic [3:0] dummy;
(dut.core.ieu.dp.regf.we3 & (dut.core.ieu.dp.regf.we3 &
dut.core.ieu.dp.regf.a3 == 3 & dut.core.ieu.dp.regf.a3 == 3 &
dut.core.ieu.dp.regf.wd3 == 1)) | dut.core.ieu.dp.regf.wd3 == 1)) |
(dut.core.ifu.InstrM == 32'h6f | dut.core.ifu.InstrM == 32'hfc32a423 | dut.core.ifu.InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM; ((dut.core.ifu.InstrM == 32'h6f | dut.core.ifu.InstrM == 32'hfc32a423 | dut.core.ifu.InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) |
((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" );
DCacheFlushFSM DCacheFlushFSM(.clk(clk), DCacheFlushFSM DCacheFlushFSM(.clk(clk),
.reset(reset), .reset(reset),
@ -396,7 +387,7 @@ module riscvassertions;
assert (`DIV_BITSPERCYCLE == 1 | `DIV_BITSPERCYCLE==2 | `DIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: DIV_BITSPERCYCLE must be 1, 2, or 4"); assert (`DIV_BITSPERCYCLE == 1 | `DIV_BITSPERCYCLE==2 | `DIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: DIV_BITSPERCYCLE must be 1, 2, or 4");
assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double (D) without supporting float (F)"); assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double (D) without supporting float (F)");
assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported"); assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported");
assert (`XLEN == 64 | ~`D_SUPPORTED) else $error("Wally does not yet support D extensions on RV32"); // assert (`XLEN == 64 | ~`D_SUPPORTED) else $error("Wally does not yet support D extensions on RV32");
assert (`FLEN<=`XLEN | `DMEM == `MEM_CACHE) else $error("Wally does not support FLEN > XLEN unleses data cache is supported"); assert (`FLEN<=`XLEN | `DMEM == `MEM_CACHE) else $error("Wally does not support FLEN > XLEN unleses data cache is supported");
assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (`DMEM != `MEM_CACHE) | `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (`DMEM != `MEM_CACHE) | `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 | (`DMEM != `MEM_CACHE)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled"); assert (`DCACHE_LINELENINBITS >= 128 | (`DMEM != `MEM_CACHE)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
@ -524,5 +515,26 @@ module copyShadow
end end
end end
endmodule endmodule
task automatic updateProgramAddrLabelArray;
input string ProgramAddrMapFile, ProgramLabelMapFile;
inout integer ProgramAddrLabelArray [string];
// Gets the memory location of begin_signature
integer ProgramLabelMapFP, ProgramAddrMapFP;
ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r");
ProgramAddrMapFP = $fopen(ProgramAddrMapFile, "r");
if (ProgramLabelMapFP & ProgramAddrMapFP) begin // check we found both files
while (!$feof(ProgramLabelMapFP)) begin
string label, adrstr;
integer returncode;
returncode = $fscanf(ProgramLabelMapFP, "%s\n", label);
returncode = $fscanf(ProgramAddrMapFP, "%s\n", adrstr);
if (ProgramAddrLabelArray.exists(label))
ProgramAddrLabelArray[label] = adrstr.atohex();
end
end
$fclose(ProgramLabelMapFP);
$fclose(ProgramAddrMapFP);
endtask

File diff suppressed because it is too large Load Diff

1
synthDC/secondtest/test2 Normal file
View File

@ -0,0 +1 @@
test 123

View File

@ -1,31 +1,17 @@
arch_dir = ../../addins/riscv-arch-test arch_dir = ../../addins/riscv-arch-test
work_dir = "./riscof_work" work_dir = ./riscof_work
current_dir = $(shell pwd) current_dir = $(shell pwd)
XLEN ?= 64
all: clone memfile all: build
clone: build:
mkdir -p $(work_dir) mkdir -p $(work_dir)
mkdir -p work mkdir -p work
sed 's,{0},$(current_dir),g;s,{1},32imc,g' config.ini > config32.ini sed 's,{0},$(current_dir),g;s,{1},$(XLEN)$(if $(findstring 64,$(XLEN)),gc,imc),g' config.ini > config$(XLEN).ini
sed 's,{0},$(current_dir),g;s,{1},64gc,g' config.ini > config64.ini riscof run --work-dir=$(work_dir) --config=config$(XLEN).ini --suite=$(arch_dir)/riscv-test-suite/ --env=$(arch_dir)/riscv-test-suite/env --no-browser
riscof run --work-dir=$(work_dir) --config=config64.ini --suite=$(arch_dir)/riscv-test-suite/ --env=$(arch_dir)/riscv-test-suite/env rm -rf work/rv$(XLEN)i_m
cp -r $(work_dir)/rv64i_m work/ mv -f $(work_dir)/rv$(XLEN)i_m work/
riscof run --work-dir=$(work_dir) --config=config32.ini --suite=$(arch_dir)/riscv-test-suite/ --env=$(arch_dir)/riscv-test-suite/env
cp -r $(work_dir)/rv32i_m work/
# sed >> config64.ini
# (cd $(arch_dir) && riscof validateyaml --config=config.ini)
# (cd $(arch_dir) && riscof --verbose info arch-test --clone)
# (cd $(arch_dir) && riscof testlist --config=config.ini --suite=riscv-arch-test/riscv-test-suite/ --env=riscv-arch-test/riscv-test-suite/env)
# sed -i 's/riscv{.}-unknown-/riscv64-unknown-/g' $(arch_dir)/spike/riscof_spike.py
# sed -i 's/riscv{.}-unknown-/riscv64-unknown-/g' $(arch_dir)/sail_cSim/riscof_sail_cSim.py
memfile:
sleep 1
find work/rv*/*/ -type f -name "*ref.elf" | while read f; do riscv64-unknown-elf-objdump -S -D "$$f" > "$$f.objdump"; done
find work/rv32*/*/ -type f -name "*ref.elf" | while read f; do riscv64-unknown-elf-elf2hex --bit-width 32 --input "$$f" --output "$$f.memfile"; done
find work/rv64*/*/ -type f -name "*ref.elf" | while read f; do riscv64-unknown-elf-elf2hex --bit-width 64 --input "$$f" --output "$$f.memfile"; done
find work/rv*/*/ -type f -name "*.objdump" | while read f; do extractFunctionRadix.sh $$f; done
clean: clean:
rm -f config64.ini rm -f config64.ini

View File

@ -90,7 +90,7 @@ class sail_cSim(pluginTemplate):
test_dir = testentry['work_dir'] test_dir = testentry['work_dir']
test_name = test.rsplit('/',1)[1][:-2] test_name = test.rsplit('/',1)[1][:-2]
elf = 'ref.elf' elf = 'Ref.elf'
execute = "@cd "+testentry['work_dir']+";" execute = "@cd "+testentry['work_dir']+";"
@ -98,7 +98,7 @@ class sail_cSim(pluginTemplate):
compile_cmd = cmd + ' -D' + " -D".join(testentry['macros']) compile_cmd = cmd + ' -D' + " -D".join(testentry['macros'])
execute+=compile_cmd+";" execute+=compile_cmd+";"
execute += self.objdump_cmd.format(elf, self.xlen, 'ref.disass') execute += self.objdump_cmd.format(elf, self.xlen, 'Ref.elf.objdump')
sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") sig_file = os.path.join(test_dir, self.name[:-1] + ".signature")
execute += self.sail_exe[self.xlen] + ' --test-signature={0} {1} > {2}.log 2>&1;'.format(sig_file, elf, test_name) execute += self.sail_exe[self.xlen] + ' --test-signature={0} {1} > {2}.log 2>&1;'.format(sig_file, elf, test_name)

View File

@ -1,11 +1,11 @@
hart_ids: [0] hart_ids: [0]
hart0: hart0:
ISA: RV32IMCZicsr_Zifencei ISA: RV32IMFCZicsr_Zifencei
physical_addr_sz: 32 physical_addr_sz: 32
User_Spec_Version: '2.3' User_Spec_Version: '2.3'
supported_xlen: [32] supported_xlen: [32]
misa: misa:
reset-val: 0x40001104 reset-val: 0x40001124
rv32: rv32:
accessible: true accessible: true
mxl: mxl:
@ -23,7 +23,7 @@ hart0:
warl: warl:
dependency_fields: [] dependency_fields: []
legal: legal:
- extensions[25:0] bitmask [0x0001104, 0x0000000] - extensions[25:0] bitmask [0x0001124, 0x0000000]
wr_illegal: wr_illegal:
- Unchanged - Unchanged

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-ADD.S // ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-ADD.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.392776// // Created 2022-06-17 22:58:09.906970//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-SLT.S // ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-SLT.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.393471// // Created 2022-06-17 22:58:09.909889//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-SLTU.S // ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-SLTU.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.393741// // Created 2022-06-17 22:58:09.911056//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-SUB.S // ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-SUB.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.393180// // Created 2022-06-17 22:58:09.908718//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-XOR.S // ../wally-riscv-arch-test/riscv-test-suite/rv32i_m/I/src/WALLY-XOR.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.394013// // Created 2022-06-17 22:58:09.913218//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-ADD.S // ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-ADD.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.394307// // Created 2022-06-17 22:58:09.914370//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-SLT.S // ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-SLT.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.394785// // Created 2022-06-17 22:58:09.916813//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-SLTU.S // ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-SLTU.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.395005// // Created 2022-06-17 22:58:09.917963//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-SUB.S // ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-SUB.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.394545// // Created 2022-06-17 22:58:09.915580//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-XOR.S // ../wally-riscv-arch-test/riscv-test-suite/rv64i_m/I/src/WALLY-XOR.S
// David_Harris@hmc.edu & Katherine Parry // David_Harris@hmc.edu & Katherine Parry
// Created 2022-01-27 08:08:42.395231// // Created 2022-06-17 22:58:09.919138//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation