From 273b41df992939e496f2375373b34335a5e3558d Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 28 May 2024 17:55:43 -0500 Subject: [PATCH 1/7] Changed name of cache parameter NUMLINES to NUMSETS to better match book. --- src/cache/cache.sv | 10 +++++----- src/cache/cacheLRU.sv | 6 +++--- src/cache/cacheway.sv | 18 +++++++++--------- src/ifu/ifu.sv | 2 +- src/lsu/lsu.sv | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index e1a0f3556..a71065c3b 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -29,7 +29,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module cache import cvw::*; #(parameter cvw_t P, - parameter PA_BITS, XLEN, LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, READ_ONLY_CACHE) ( + parameter PA_BITS, XLEN, LINELEN, NUMSETS, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, READ_ONLY_CACHE) ( input logic clk, input logic reset, input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY @@ -63,12 +63,12 @@ module cache import cvw::*; #(parameter cvw_t P, // Cache parameters localparam LINEBYTELEN = LINELEN/8; // Line length in bytes localparam OFFSETLEN = $clog2(LINEBYTELEN); // Number of bits in offset field - localparam SETLEN = $clog2(NUMLINES); // Number of set bits + localparam SETLEN = $clog2(NUMSETS); // Number of set bits localparam SETTOP = SETLEN+OFFSETLEN; // Number of set plus offset bits localparam TAGLEN = PA_BITS - SETTOP; // Number of tag bits localparam CACHEWORDSPERLINE = LINELEN/WORDLEN;// Number of words in cache line localparam LOGCWPL = $clog2(CACHEWORDSPERLINE);// Log2 of ^ - localparam FLUSHADRTHRESHOLD = NUMLINES - 1; // Used to determine when flush is complete + localparam FLUSHADRTHRESHOLD = NUMSETS - 1; // Used to determine when flush is complete localparam LOGLLENBYTES = $clog2(WORDLEN/8); // Number of bits to address a word @@ -119,14 +119,14 @@ module cache import cvw::*; #(parameter cvw_t P, AdrSelMuxSelTag, CacheSetTag); // Array of cache ways, along with victim, hit, dirty, and read merging logic - cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0]( + cacheway #(P, PA_BITS, XLEN, NUMSETS, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0]( .clk, .reset, .CacheEn, .CacheSetData, .CacheSetTag, .PAdr, .LineWriteData, .LineByteMask, .SelVictim, .SetValid, .ClearValid, .SetDirty, .ClearDirty, .VictimWay, .FlushWay, .FlushCache, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .HitDirtyWay, .TagWay, .FlushStage, .InvalidateCache); // Select victim way for associative caches if(NUMWAYS > 1) begin:vict - cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU( + cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMSETS) cacheLRU( .clk, .reset, .FlushStage, .CacheEn, .HitWay, .ValidWay, .VictimWay, .CacheSetData, .CacheSetTag, .LRUWriteEn, .SetValid, .ClearValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache); end else diff --git a/src/cache/cacheLRU.sv b/src/cache/cacheLRU.sv index 48f5bb586..55f3ba37f 100644 --- a/src/cache/cacheLRU.sv +++ b/src/cache/cacheLRU.sv @@ -29,7 +29,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module cacheLRU - #(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128) ( + #(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMSETS = 128) ( input logic clk, input logic reset, input logic FlushStage, @@ -48,7 +48,7 @@ module cacheLRU localparam LOGNUMWAYS = $clog2(NUMWAYS); - logic [NUMWAYS-2:0] LRUMemory [NUMLINES-1:0]; + logic [NUMWAYS-2:0] LRUMemory [NUMSETS-1:0]; logic [NUMWAYS-2:0] CurrLRU; logic [NUMWAYS-2:0] NextLRU; logic [LOGNUMWAYS-1:0] HitWayEncoded, Way; @@ -146,7 +146,7 @@ module cacheLRU // Move to = to keep Verilator happy and simulator running fast always_ff @(posedge clk) begin if (reset | (InvalidateCache & ~FlushStage)) - for (int set = 0; set < NUMLINES; set++) LRUMemory[set] = '0; // exclusion-tag: initialize + for (int set = 0; set < NUMSETS; set++) LRUMemory[set] = '0; // exclusion-tag: initialize else if(CacheEn) begin // Because we are using blocking assignments, change to LRUMemory must occur after LRUMemory is used so we get the proper value if(LRUWriteEn & (PAdr == CacheSetTag)) CurrLRU = NextLRU; diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index eba64a173..41e620547 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -29,14 +29,14 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module cacheway import cvw::*; #(parameter cvw_t P, - parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN = 26, + parameter PA_BITS, XLEN, NUMSETS=512, LINELEN = 256, TAGLEN = 26, OFFSETLEN = 5, INDEXLEN = 9, READ_ONLY_CACHE = 0) ( input logic clk, input logic reset, input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations) input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant - input logic [$clog2(NUMLINES)-1:0] CacheSetData, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr - input logic [$clog2(NUMLINES)-1:0] CacheSetTag, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr + input logic [$clog2(NUMSETS)-1:0] CacheSetData, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr + input logic [$clog2(NUMSETS)-1:0] CacheSetTag, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr input logic [PA_BITS-1:0] PAdr, // Physical address input logic [LINELEN-1:0] LineWriteData, // Final data written to cache (D$ only) input logic SetValid, // Set the valid bit in the selected way and set @@ -63,8 +63,8 @@ module cacheway import cvw::*; #(parameter cvw_t P, localparam LOGXLENBYTES = $clog2(XLEN/8); localparam BYTESPERWORD = XLEN/8; - logic [NUMLINES-1:0] ValidBits; - logic [NUMLINES-1:0] DirtyBits; + logic [NUMSETS-1:0] ValidBits; + logic [NUMSETS-1:0] DirtyBits; logic [LINELEN-1:0] ReadDataLine; logic [TAGLEN-1:0] ReadTag; logic Dirty; @@ -112,7 +112,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, // Tag Array ///////////////////////////////////////////////////////////////////////////////////////////// - ram1p1rwe #(.USE_SRAM(P.USE_SRAM), .DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn), + ram1p1rwe #(.USE_SRAM(P.USE_SRAM), .DEPTH(NUMSETS), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn), .addr(CacheSetTag), .dout(ReadTag), .din(PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN)); @@ -136,12 +136,12 @@ module cacheway import cvw::*; #(parameter cvw_t P, for(words = 0; words < NUMSRAM; words++) begin: word if (READ_ONLY_CACHE) begin:wordram // no byte-enable needed for i$. - ram1p1rwe #(.USE_SRAM(P.USE_SRAM), .DEPTH(NUMLINES), .WIDTH(P.CACHE_SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSetData), + ram1p1rwe #(.USE_SRAM(P.USE_SRAM), .DEPTH(NUMSETS), .WIDTH(P.CACHE_SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSetData), .dout(ReadDataLine[P.CACHE_SRAMLEN*(words+1)-1:P.CACHE_SRAMLEN*words]), .din(LineWriteData[P.CACHE_SRAMLEN*(words+1)-1:P.CACHE_SRAMLEN*words]), .we(SelectedWriteWordEn)); end else begin:wordram // D$ needs byte enables - ram1p1rwbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(NUMLINES), .WIDTH(P.CACHE_SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSetData), + ram1p1rwbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(NUMSETS), .WIDTH(P.CACHE_SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSetData), .dout(ReadDataLine[P.CACHE_SRAMLEN*(words+1)-1:P.CACHE_SRAMLEN*words]), .din(LineWriteData[P.CACHE_SRAMLEN*(words+1)-1:P.CACHE_SRAMLEN*words]), .we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words])); @@ -173,7 +173,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, if (!READ_ONLY_CACHE) begin:dirty always_ff @(posedge clk) begin // reset is optional. Consider merging with TAG array in the future. - //if (reset) DirtyBits <= {NUMLINES{1'b0}}; + //if (reset) DirtyBits <= {NUMSETS{1'b0}}; if(CacheEn) begin Dirty <= DirtyBits[CacheSetTag]; if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CacheSetData] <= SetDirtyWay; // exclusion-tag: cache UpdateDirty diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index d8d2c0eb1..921d2dce5 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -239,7 +239,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0; // *** RT: PAdr and NextSet are replaced with mux between PCPF/IEUAdrM and PCSpillNextF/IEUAdrE. cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS), - .NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS), + .NUMSETS(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS), .NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1)) icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD), .FetchBuffer, .CacheBusAck(ICacheBusAck), diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 31441a095..a4062be7d 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -329,7 +329,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( assign CacheRWM = (CacheableM & ~SelDTIM) ? LSURWM : '0; assign FlushDCache = FlushDCacheM & ~(SelHPTW); - cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMLINES(P.DCACHE_WAYSIZEINBYTES*8/LINELEN), + cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMSETS(P.DCACHE_WAYSIZEINBYTES*8/LINELEN), .NUMWAYS(P.DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(CACHEWORDLEN), .MUXINTERVAL(P.LLEN), .READ_ONLY_CACHE(0)) dcache( .clk, .reset, .Stall(GatedStallW & ~SelSpillE), .SelBusBeat, .FlushStage(FlushW | IgnoreRequestTLB), .CacheRW(CacheRWM), From 84946919a4ae42cf6efb457a165c6c132736d22f Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 28 May 2024 18:00:39 -0500 Subject: [PATCH 2/7] Changed name CacheWriteData to WriteData. --- src/cache/cache.sv | 4 ++-- src/ifu/ifu.sv | 2 +- src/lsu/lsu.sv | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index a71065c3b..c5adcd076 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -42,7 +42,7 @@ module cache import cvw::*; #(parameter cvw_t P, input logic [11:0] NextSet, // Virtual address, but we only use the lower 12 bits. input logic [PA_BITS-1:0] PAdr, // Physical address input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only) - input logic [WORDLEN-1:0] CacheWriteData, // Data to write to cache (D$ only) + input logic [WORDLEN-1:0] WriteData, // Data to write to cache (D$ only) output logic CacheCommitted, // Cache has started bus operation that shouldn't be interrupted output logic CacheStall, // Cache stalls pipeline during multicycle operation output logic [WORDLEN-1:0] ReadDataWord, // Word read from cache (goes to CPU and bus) @@ -184,7 +184,7 @@ module cache import cvw::*; #(parameter cvw_t P, // Merge write data into fetched cache line for store miss for(index = 0; index < LINELEN/8; index++) begin - mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), + mux2 #(8) WriteDataMux(.d0(WriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), .d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index] & ~CMOpM[3]), .y(LineWriteData[8*index+7:8*index])); end assign LineByteMask = SetDirty ? DemuxedByteMask : '1; diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 921d2dce5..9bb54e1a0 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -249,7 +249,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( .SelHPTW('0), .CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess), .ByteMask('0), .BeatCount('0), .SelBusBeat('0), - .CacheWriteData('0), + .WriteData('0), .CacheRW(CacheRWF), .FlushCache('0), .NextSet(PCSpillNextF[11:0]), diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index a4062be7d..43176e04b 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -335,7 +335,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( .CacheRW(CacheRWM), .FlushCache(FlushDCache), .NextSet(IEUAdrExtE[11:0]), .PAdr(PAdrM), .ByteMask(ByteMaskSpillM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]), - .CacheWriteData(LSUWriteDataSpillM), .SelHPTW, + .WriteData(LSUWriteDataSpillM), .SelHPTW, .CacheStall, .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess), .CacheCommitted(DCacheCommittedM), .CacheBusAdr(DCacheBusAdr), .ReadDataWord(DCacheReadDataWordM), From f4626d5b06c369c56c5887c56338761af43cf740 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 29 May 2024 14:50:09 -0500 Subject: [PATCH 3/7] Fixed bug so that wsim can start logging after a given number of instructions. --- bin/wsim | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/bin/wsim b/bin/wsim index 487647514..5305f8aee 100755 --- a/bin/wsim +++ b/bin/wsim @@ -67,15 +67,19 @@ cd = "cd $WALLY/sim/" +args.sim # functional coverage and imply it. if (args.sim == "questa"): if (args.lockstep): - prefix = "IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic" # OTHERFLAGS=\"+IDV_TRACE2LOG=" + str(args.locksteplog) + " +IDV_TRACE2COV=" + str(args.covlog) + "\""; + prefix = "IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic" + if(int(args.locksteplog) >= 1): EnableLog = 1 + else: EnableLog = 0 + if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog) + else: ImperasPlusArgs = "" if(args.fcov): CovEnableStr = "1" if int(args.covlog) > 0 else "0"; - #ImperasPlusArgs = "+IDV_TRACE2LOG=" + str(args.locksteplog) + " +IDV_TRACE2COV=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; - ImperasPlusArgs = " +IDV_TRACE2COV=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; + if(args.covlog >= 1): EnableLog = 1 + else: EnableLog = 0 + ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; suffix = "" else: CovEnableStr = "" - ImperasPlusArgs = ""; suffix = "--lockstep" else: prefix = "" From a78093274c1e72a01c29a2c55b502f85e46f036f Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Sat, 1 Jun 2024 09:56:50 -0500 Subject: [PATCH 4/7] Simplified wsim so it automatically figures out if the second parameter is a testsuite or an elf file. --- bin/wsim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/wsim b/bin/wsim index 5305f8aee..68f759f35 100755 --- a/bin/wsim +++ b/bin/wsim @@ -18,7 +18,6 @@ import os parser = argparse.ArgumentParser() parser.add_argument("config", help="Configuration file") parser.add_argument("testsuite", help="Test suite or ELF file") -parser.add_argument("--elf", "-e", help="Elf file", action="store_true") parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "verilator", "vcs"], default="questa") parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testbench_fp"], default="testbench") parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true") @@ -33,7 +32,7 @@ args = parser.parse_args() print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim + " gui=" + str(args.gui) + " args='" + args.args + "'") ElfFile="" -if(args.elf): +if(os.path.isfile(args.testsuite)): ElfFile = "+ElfFile=" + args.testsuite args.testsuite = "none" From 224b8469ab7036270585f80ea9099b83fa1822fc Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Sat, 1 Jun 2024 09:58:10 -0500 Subject: [PATCH 5/7] Updated readme to reflect changes to wsim. --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c2e0f1d39..e225a44b4 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,6 @@ Parameters and options: -h, --help show this help message and exit --elf, -e Elf file - --sim {questa,verilator,vcs}, -s {questa,verilator,vcs} Simulator --tb {testbench,testbench_fp}, -t {testbench,testbench_fp} Testbench --gui, -g Simulate with GUI --coverage, -c Code & Functional Coverage @@ -175,8 +174,8 @@ Run Questa with gui Run lockstep against ImperasDV with a single elf file in the --gui. Lockstep requires single elf. - wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --elf --lockstep --gui + wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --lockstep --gui Run lockstep against ImperasDV with a single elf file. Compute coverage. - wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --elf --lockstep --coverage + wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --lockstep --coverage From 2382677f8f636f3962ff947ddee1029e04aa5c45 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Sat, 1 Jun 2024 10:56:37 -0500 Subject: [PATCH 6/7] Got the directory mode wsim working! --- bin/wsim | 138 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 59 deletions(-) diff --git a/bin/wsim b/bin/wsim index 68f759f35..9884992e4 100755 --- a/bin/wsim +++ b/bin/wsim @@ -14,6 +14,68 @@ import argparse import os +def LaunchSim(ElfFile): + # Launch selected simulator + cd = "cd $WALLY/sim/" +args.sim + # ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running + # functional coverage and imply it. + if (args.sim == "questa"): + if (args.lockstep): + prefix = "IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic" + if(int(args.locksteplog) >= 1): EnableLog = 1 + else: EnableLog = 0 + if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog) + else: ImperasPlusArgs = "" + if(args.fcov): + CovEnableStr = "1" if int(args.covlog) > 0 else "0"; + if(args.covlog >= 1): EnableLog = 1 + else: EnableLog = 0 + ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; + suffix = "" + else: + CovEnableStr = "" + suffix = "--lockstep" + else: + prefix = "" + ImperasPlusArgs = "" + suffix = "" + if (args.tb == "testbench_fp"): + args.args = " -GTEST=\"" + args.testsuite + "\" " + args.args + cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + " " + suffix + " " + ImperasPlusArgs + if (args.coverage): + cmd += " --coverage" + if (args.fcov): + cmd += " --fcov" + if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible + if(args.tb == "testbench"): + cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc -GDEBUG=1\"" + elif(args.tb == "testbench_fp"): + cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc\"" + else: # launch Questa in batch mode + cmd = cd + "; " + prefix + " vsim -c -do \"" + cmd + "\"" + print("Running Questa with command: " + cmd) + os.system(cmd) + elif (args.sim == "verilator"): + # PWD=${WALLY}/sim CONFIG=rv64gc TESTSUITE=arch64i + print(f"Running Verilator on {args.config} {args.testsuite}") + if (args.coverage): + print("Coverage option not available for Verilator") + exit(1) + if (args.gui): + print("GUI option not available for Verilator") + exit(1) + os.system(f"/usr/bin/make -C {regressionDir}/verilator WALLYCONF={args.config} TEST={args.testsuite} TESTBENCH={args.tb} EXTRA_ARGS='{args.args}'") + elif (args.sim == "vcs"): + print(f"Running VCS on " + args.config + " " + args.testsuite) + if (args.gui): + args.args += "gui" + elif (args.coverage): + args.args += "coverage" + cmd = cd + "; ./run_vcs " + args.config + " " + args.testsuite + " " + args.args + print(cmd) + os.system(cmd) + + # Parse arguments parser = argparse.ArgumentParser() parser.add_argument("config", help="Configuration file") @@ -28,13 +90,25 @@ parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_ parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true") parser.add_argument("--locksteplog", "-b", help="Retired instruction number to be begin logging.", default=0) parser.add_argument("--covlog", "-d", help="Log coverage after n instructions.", default=0) +parser.add_argument("--elfext", "-e", help="When searching for elf files only includes ones which end in this extension", default=".elf") args = parser.parse_args() print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim + " gui=" + str(args.gui) + " args='" + args.args + "'") ElfFile="" +DirectorMode = 0 +ElfList = [] if(os.path.isfile(args.testsuite)): ElfFile = "+ElfFile=" + args.testsuite args.testsuite = "none" + ElfList.append("+ElfFile=" + args.testsuite) +elif(os.path.isdir(args.testsuite)): + DirectorMode = 1 + for dirpath, dirnames, filenames in os.walk(args.testsuite): + for file in filenames: + if file.endswith(args.elfext): + ElfList.append("+ElfFile=" + os.path.join(dirpath, file)) + args.testsuite = "none" +print(ElfList) # Validate arguments if (args.gui): @@ -59,63 +133,9 @@ for d in ["logs", "wkdir", "cov"]: except: pass +if(DirectorMode): + for ElfFile in ElfList: + LaunchSim(ElfFile) -# Launch selected simulator -cd = "cd $WALLY/sim/" +args.sim -# ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running -# functional coverage and imply it. -if (args.sim == "questa"): - if (args.lockstep): - prefix = "IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic" - if(int(args.locksteplog) >= 1): EnableLog = 1 - else: EnableLog = 0 - if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog) - else: ImperasPlusArgs = "" - if(args.fcov): - CovEnableStr = "1" if int(args.covlog) > 0 else "0"; - if(args.covlog >= 1): EnableLog = 1 - else: EnableLog = 0 - ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; - suffix = "" - else: - CovEnableStr = "" - suffix = "--lockstep" - else: - prefix = "" - ImperasPlusArgs = "" - suffix = "" - if (args.tb == "testbench_fp"): - args.args = " -GTEST=\"" + args.testsuite + "\" " + args.args - cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + " " + suffix + " " + ImperasPlusArgs - if (args.coverage): - cmd += " --coverage" - if (args.fcov): - cmd += " --fcov" - if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible - if(args.tb == "testbench"): - cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc -GDEBUG=1\"" - elif(args.tb == "testbench_fp"): - cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc\"" - else: # launch Questa in batch mode - cmd = cd + "; " + prefix + " vsim -c -do \"" + cmd + "\"" - print("Running Questa with command: " + cmd) - os.system(cmd) -elif (args.sim == "verilator"): - # PWD=${WALLY}/sim CONFIG=rv64gc TESTSUITE=arch64i - print(f"Running Verilator on {args.config} {args.testsuite}") - if (args.coverage): - print("Coverage option not available for Verilator") - exit(1) - if (args.gui): - print("GUI option not available for Verilator") - exit(1) - os.system(f"/usr/bin/make -C {regressionDir}/verilator WALLYCONF={args.config} TEST={args.testsuite} TESTBENCH={args.tb} EXTRA_ARGS='{args.args}'") -elif (args.sim == "vcs"): - print(f"Running VCS on " + args.config + " " + args.testsuite) - if (args.gui): - args.args += "gui" - elif (args.coverage): - args.args += "coverage" - cmd = cd + "; ./run_vcs " + args.config + " " + args.testsuite + " " + args.args - print(cmd) - os.system(cmd) +else: + LaunchSim(ElfFile) From 3da62558ec7172c35688098a87afaa317c2eed83 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Sat, 1 Jun 2024 11:12:30 -0500 Subject: [PATCH 7/7] Updated readme. --- README.md | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e225a44b4..084741107 100644 --- a/README.md +++ b/README.md @@ -150,19 +150,22 @@ If you want to add a cronjob you can do the following: wsim runs one of multiple simulators, Questa, VCS, or Verilator using a specific configuration and either a suite of tests or a specific elf file. The general syntax is -wsim [--options] +wsim [--options] Parameters and options: - -h, --help show this help message and exit - --elf, -e Elf file - --tb {testbench,testbench_fp}, -t {testbench,testbench_fp} Testbench - --gui, -g Simulate with GUI - --coverage, -c Code & Functional Coverage - --args ARGS, -a ARGS Optional arguments passed to simulator via $value$plusargs - --vcd, -v Generate testbench.vcd - --lockstep, -l Run ImperasDV lock, step, and compare. - --locksteplog LOCKSTEPLOG, -b LOCKSTEPLOG Retired instruction number to be begin logging. + -h, --help show this help message and exit + --sim {questa,verilator,vcs}, -s {questa,verilator,vcs} Simulator + --tb {testbench,testbench_fp}, -t {testbench,testbench_fp} Testbench + --gui, -g Simulate with GUI + --coverage, -c Code & Functional Coverage + --fcov, -f Code & Functional Coverage + --args ARGS, -a ARGS Optional arguments passed to simulator via $value$plusargs + --vcd, -v Generate testbench.vcd + --lockstep, -l Run ImperasDV lock, step, and compare. + --locksteplog LOCKSTEPLOG, -b LOCKSTEPLOG Retired instruction number to be begin logging. + --covlog COVLOG, -d COVLOG Log coverage after n instructions. + --elfext ELFEXT, -e ELFEXT When searching for elf files only includes ones which end in this extension Run basic test with questa @@ -179,3 +182,11 @@ Run lockstep against ImperasDV with a single elf file in the --gui. Lockstep re Run lockstep against ImperasDV with a single elf file. Compute coverage. wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/ref/ref.elf --lockstep --coverage + +Run lockstep against ImperasDV with directory file. + + wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/ --lockstep + +Run lockstep against ImperasDV with directory file and specify specific extension. + + wsim rv64gc ../../tests/riscof/work/riscv-arch-test/rv64i_m/I/src/ --lockstep --elfext ref.elf