From 37d2f3220e47f7b1d55d159bfee9bb06fba4a407 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Tue, 29 Oct 2024 10:30:08 -0500 Subject: [PATCH 01/15] Added a new spi controller design. Designed as a proof of concept to see if timing issues can be fixed. I intend to work it into existing SPI peripheral. --- src/uncore/spi_controller.sv | 317 +++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 src/uncore/spi_controller.sv diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv new file mode 100644 index 000000000..983a9d83e --- /dev/null +++ b/src/uncore/spi_controller.sv @@ -0,0 +1,317 @@ +module spi_controller ( + input logic PCLK, + input logic PRESETn, + input logic TransmitStart, + input logic [11:0] SckDiv, + input logic [1:0] SckMode, + input logic [1:0] CSMode, + input logic [15:0] Delay0, + input logic [15:0] Delay1, + input logic [7:0] txFIFORead, + input logic txFIFOReadEmpty, + output logic SPICLK, + output logic SPIOUT, + output logic CS +); + + // CSMode Stuff + localparam HOLDMODE = 2'b10; + localparam AUTOMODE = 2'b00; + localparam OFFMODE = 2'b11; + + typedef enum logic [2:0] {INACTIVE, CSSCK, TRANSMIT, SCKCS, HOLD, INTERCS, INTERXFR} statetype; + statetype CurrState, NextState; + + // SCLKenable stuff + logic [11:0] DivCounter; + logic SCLKenable; + logic SCLKenableEarly; + logic SCLKenableLate; + logic EdgeTiming; + logic ZeroDiv; + logic Clock0; + logic Clock1; + logic SCK; // SUPER IMPORTANT, THIS CAN'T BE THE SAME AS SPICLK! + + + // Shift and Sample Edges + logic PreShiftEdge; + logic PreSampleEdge; + logic ShiftEdge; + logic SampleEdge; + + // Frame stuff + logic [2:0] BitNum; + logic LastBit; + logic EndOfFrame; + logic EndOfFrameDelay; + logic PhaseOneOffset; + + // Transmit Stuff + logic ContinueTransmit; + + // SPIOUT Stuff + logic TransmitLoad; + logic [7:0] TransmitReg; + logic Transmitting; + logic EndTransmission; + + logic HoldMode; + + // Delay Stuff + logic [7:0] cssck; + logic [7:0] sckcs; + logic [7:0] intercs; + logic [7:0] interxfr; + + logic HasCSSCK; + logic HasSCKCS; + logic HasINTERCS; + logic HasINTERXFR; + + logic EndOfCSSCK; + logic EndOfSCKCS; + logic EndOfINTERCS; + logic EndOfINTERXFR; + + logic [7:0] CSSCKCounter; + logic [7:0] SCKCSCounter; + logic [7:0] INTERCSCounter; + logic [7:0] INTERXFRCounter; + + logic DelayIsNext; + + // Convenient Delay Reg Names + assign cssck = Delay0[7:0]; + assign sckcs = Delay0[15:8]; + assign intercs = Delay1[7:0]; + assign interxfr = Delay1[15:8]; + + // Do we have delay for anything? + assign HasCSSCK = cssck > 8'b0; + assign HasSCKCS = sckcs > 8'b0; + assign HasINTERCS = intercs > 8'b0; + assign HasINTERXFR = interxfr > 8'b0; + + // Have we hit full delay for any of the delays? + assign EndOfCSSCK = CSSCKCounter == cssck; + assign EndOfSCKCS = SCKCSCounter == sckcs; + assign EndOfINTERCS = INTERCSCounter == intercs; + assign EndOfINTERXFR = INTERXFRCounter == interxfr; + + // Clock Signal Stuff ----------------------------------------------- + // I'm going to handle all clock stuff here, including ShiftEdge and + // SampleEdge. This makes sure that SPICLK is an output of a register + // and it properly synchronizes signals. + + assign SCLKenableLate = DivCounter > SckDiv; + assign SCLKenable = DivCounter == SckDiv; + assign SCLKenableEarly = (DivCounter + 1'b1) == SckDiv; + assign LastBit = BitNum == 3'd7; + assign EdgeTiming = SckDiv > 12'b0 ? SCLKenableEarly : SCLKenable; + + //assign SPICLK = Clock0; + + assign ContinueTransmit = ~txFIFOReadEmpty & EndOfFrame; + assign EndTransmission = txFIFOReadEmpty & EndOfFrameDelay; + + always_ff @(posedge PCLK) begin + if (~PRESETn) begin + DivCounter <= 12'b0; + SPICLK <= SckMode[1]; + SCK <= 0; + BitNum <= 3'h0; + PreShiftEdge <= 0; + PreSampleEdge <= 0; + EndOfFrame <= 0; + end else begin + // TODO: Consolidate into one delay counter since none of the + // delays happen at the same time? + if (TransmitStart) begin + SCK <= 0; + end else if (SCLKenable) begin + SCK <= ~SCK; + end + + if ((CurrState == CSSCK) & SCK) begin + CSSCKCounter <= CSSCKCounter + 8'd1; + end else begin + CSSCKCounter <= 8'd0; + end + + if ((CurrState == SCKCS) & SCK) begin + SCKCSCounter <= SCKCSCounter + 8'd1; + end else begin + SCKCSCounter <= 8'd0; + end + + if ((CurrState == INTERCS) & SCK) begin + INTERCSCounter <= INTERCSCounter + 8'd1; + end else begin + INTERCSCounter <= 8'd0; + end + + if ((CurrState == INTERXFR) & SCK) begin + INTERXFRCounter <= INTERXFRCounter + 8'd1; + end else begin + INTERXFRCounter <= 8'd0; + end + + // SPICLK Logic + if (TransmitStart) begin + SPICLK <= SckMode[1]; + end else if (SCLKenable & Transmitting) begin + SPICLK <= (~EndTransmission & ~DelayIsNext) ? ~SPICLK : SckMode[1]; + end + + // Reset divider + if (SCLKenable | TransmitStart) begin + DivCounter <= 12'b0; + end else begin + DivCounter = DivCounter + 12'd1; + end + + // EndOfFrame controller + // if (SckDiv > 0 ? SCLKenableEarly & LastBit & SPICLK : LastBit & ~SPICLK) begin + // EndOfFrame <= 1'b1; + // end else begin + // EndOfFrame <= 1'b0; + // end + + if (~TransmitStart) begin + EndOfFrame <= (SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & LastBit & Transmitting; + end + + // Increment BitNum + if (ShiftEdge & Transmitting) begin + BitNum <= BitNum + 3'd1; + end else if (EndOfFrameDelay) begin + BitNum <= 3'b0; + end + end + end + + // Delay ShiftEdge and SampleEdge by a half PCLK period + // Aligned EXACTLY ON THE MIDDLE of the leading and trailing edges. + // Sweeeeeeeeeet... + always_ff @(posedge ~PCLK) begin + if (~PRESETn | TransmitStart) begin + ShiftEdge <= 0; + PhaseOneOffset <= 0; + SampleEdge <= 0; + EndOfFrameDelay <= 0; + end else begin + ShiftEdge <= ((SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & ~LastBit & Transmitting) & PhaseOneOffset; + PhaseOneOffset <= PhaseOneOffset == 0 ? Transmitting & SCLKenable : PhaseOneOffset; + SampleEdge <= (SckMode[1] ^ SckMode[0] ^ ~SPICLK) & SCLKenable & Transmitting; + EndOfFrameDelay <= (SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & LastBit & Transmitting; + end + end + + // typedef enum logic [2:0] {INACTIVE, CSSCK, TRANSMIT, SCKCS, HOLD, INTERCS, INTERXFR} statetype; + // statetype CurrState, NextState; + + assign HoldMode = CSMode == 2'b10; + assign TransmitLoad = TransmitStart | (EndOfFrameDelay & ~txFIFOReadEmpty); + + always_ff @(posedge PCLK) begin + if (~PRESETn) begin + CurrState <= INACTIVE; + end else if (SCLKenable) begin + CurrState <= NextState; + end + end + + always_comb begin + case (CurrState) + INACTIVE: begin // INACTIVE case -------------------------------- + if (TransmitStart) begin + if (~HasCSSCK) begin + NextState = TRANSMIT; + end else begin + NextState = CSSCK; + end + end else begin + NextState = INACTIVE; + end + end + CSSCK: begin // DELAY0 case ------------------------------------- + if (EndOfCSSCK) begin + NextState = TRANSMIT; + end + end + TRANSMIT: begin // TRANSMIT case -------------------------------- + case(CSMode) + AUTOMODE: begin + if (EndTransmission) begin + NextState = INACTIVE; + end else if (ContinueTransmit) begin + NextState = SCKCS; + end + end + HOLDMODE: begin + if (EndTransmission) begin + NextState = HOLD; + end else if (ContinueTransmit) begin + if (HasINTERXFR) NextState = INTERXFR; + end + end + OFFMODE: begin + + end + + endcase + end + SCKCS: begin // SCKCS case -------------------------------------- + if (EndOfSCKCS) begin + if (EndTransmission) begin + if (CSMode == AUTOMODE) NextState = INACTIVE; + else if (CSMode == HOLDMODE) NextState = HOLD; + end else if (ContinueTransmit) begin + if (HasINTERCS) NextState = INTERCS; + else NextState = TRANSMIT; + end + end + end + HOLD: begin // HOLD mode case ----------------------------------- + if (CSMode == AUTOMODE) begin + NextState = INACTIVE; + end else if (TransmitStart) begin // If FIFO is written to, start again. + NextState = TRANSMIT; + end + end + INTERCS: begin // INTERCS case ---------------------------------- + if (EndOfINTERCS) begin + if (HasCSSCK) NextState = CSSCK; + else NextState = TRANSMIT; + end + end + INTERXFR: begin // INTERXFR case -------------------------------- + if (EndOfINTERXFR) begin + NextState = TRANSMIT; + end + end + default: begin + NextState = INACTIVE; + end + endcase + end + + assign Transmitting = CurrState == TRANSMIT; + assign DelayIsNext = (NextState == CSSCK | NextState == SCKCS | NextState == INTERCS | NextState == INTERXFR); + + // + always_ff @(posedge PCLK) begin + if (~PRESETn) begin + TransmitReg <= 8'b0; + end else if (TransmitLoad) begin + TransmitReg <= txFIFORead; + end else if (ShiftEdge) begin + TransmitReg <= {TransmitReg[6:0], TransmitReg[0]}; + end + end + + assign SPIOUT = TransmitReg[7]; + assign CS = CurrState == INACTIVE | CurrState == INTERCS; + +endmodule From 784630b94582434b34ea99ae62a3d8f1989903f1 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Tue, 29 Oct 2024 10:53:33 -0500 Subject: [PATCH 02/15] Added wally header to spi_controller. --- src/uncore/spi_controller.sv | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index 983a9d83e..c4305047e 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -1,3 +1,34 @@ +/////////////////////////////////////////// +// spi_controller.sv +// +// Written: jacobpease@protonmail.com +// Created: October 28th, 2024 +// Modified: +// +// Purpose: Controller logic for SPI +// +// Documentation: RISC-V System on Chip Design +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + + module spi_controller ( input logic PCLK, input logic PRESETn, From b8c09f96498ea9940259a2dd0d1c470a65a66942 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Tue, 29 Oct 2024 12:04:20 -0700 Subject: [PATCH 03/15] Set MTI_VCO_MODE for all Questa runs --- bin/wsim | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/wsim b/bin/wsim index 3f6cbaaae..6df11e6b5 100755 --- a/bin/wsim +++ b/bin/wsim @@ -59,12 +59,12 @@ if(args.testsuite.endswith('.elf') and args.elf == ""): # No --elf argument; che args.testsuite = fields[1] + "_" + fields[3] else: args.testsuite = fields[2] + "_" + fields[3] - elif ('/' in args.testsuite): + elif ('/' in args.testsuite): args.testsuite=args.testsuite.rsplit('/', 1)[1] # strip off path if present else: print("ELF file not found: " + args.testsuite) exit(1) - + if(args.lockstep and not args.testsuite.endswith('.elf')): print(f"Invalid Options. Cannot run a testsuite, {args.testsuite} with lockstep. Must run a single elf.") exit(1) @@ -89,13 +89,13 @@ if(int(args.locksteplog) >= 1): EnableLog = 1 else: EnableLog = 0 prefix = "" if (args.lockstep or args.lockstepverbose or args.fcov or args.fcovimp): - if (args.sim == "questa" or args.sim == "vcs"): + if (args.sim == "questa" or args.sim == "vcs"): prefix = "IMPERAS_TOOLS=" + WALLY + "/config/"+args.config+"/imperas.ic" - if (args.sim == "questa"): - prefix = "MTI_VCO_MODE=64 " + prefix +if (args.sim == "questa"): + prefix = "MTI_VCO_MODE=64 " + prefix if (args.lockstep or args.lockstepverbose): - if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog) + if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog) else: ImperasPlusArgs = "" if(args.fcovimp): CovEnableStr = "1" if int(args.covlog) > 0 else "0" From 7993a877335111e17287f8e68a83e8675df1c7a4 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Tue, 29 Oct 2024 12:08:48 -0700 Subject: [PATCH 04/15] Add comment for MTI_VCO_MODE --- bin/wsim | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/wsim b/bin/wsim index 6df11e6b5..ca44e22a6 100755 --- a/bin/wsim +++ b/bin/wsim @@ -91,6 +91,7 @@ prefix = "" if (args.lockstep or args.lockstepverbose or args.fcov or args.fcovimp): if (args.sim == "questa" or args.sim == "vcs"): prefix = "IMPERAS_TOOLS=" + WALLY + "/config/"+args.config+"/imperas.ic" +# Force Questa to use 64-bit mode, sometimes it defaults to 32-bit even on 64-bit machines if (args.sim == "questa"): prefix = "MTI_VCO_MODE=64 " + prefix From 40783c1a5469892fcc6e5dd463d071481a347540 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Tue, 29 Oct 2024 18:01:47 -0700 Subject: [PATCH 05/15] Update README for design compiler support in red hat 9 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c2bc0d0a..40dc08d51 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ The Synopsys Installer automatically installs all downloaded product files into ``` > [!Note] -> Although most parts of Wally, including the Questa simulator, will work on most modern Linux platforms, as of 2022, the Synopsys CAD tools for SoC design are only supported on RedHat Enterprise Linux 7.4 or 8 or SUSE Linux Enterprise Server (SLES) 12 or 15. Moreover, the RISC-V formal specification (sail-riscv) does not build gracefully on RHEL7. +> Although most parts of Wally, including the Questa simulator, will work on most modern Linux platforms, as of 2024, the Synopsys CAD tools for SoC design are only supported on Red Hat Enterprise Linux (or AlmaLinux/Rocky) 8.4+ or 9.1+ or SUSE Linux Enterprise Server (SLES) 15. The Verilog simulation has been tested with Siemens Questa/ModelSim. This package is available to universities worldwide as part of the Design Verification Bundle through the Siemens Academic Partner Program members for $990/year. From b9317e7cd38c01a37c0e562afa7a963cde343662 Mon Sep 17 00:00:00 2001 From: Corey Hickson Date: Wed, 30 Oct 2024 03:28:58 -0700 Subject: [PATCH 06/15] Fixed fround bug --- src/fpu/fround.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fpu/fround.sv b/src/fpu/fround.sv index 3265ec626..fadd963d0 100644 --- a/src/fpu/fround.sv +++ b/src/fpu/fround.sv @@ -76,7 +76,8 @@ module fround import cvw::*; #(parameter cvw_t P) ( assign Eeqm1 = ($signed(E) == -1); // Logic for nonnegative mask and rounding bits - assign IMask = {1'b1, {P.NF{1'b0}}} >>> E; /// if E > Nf, this produces all 0s instead of all 1s. Hence exact handling is needed below. + // assign IMask = {1'b1, {P.NF{1'b0}}} >>> E; /// if E > Nf, this produces all 0s instead of all 1s. Hence exact handling is needed below. + assign IMask = $signed({1'b1, {P.NF{1'b0}}}) >>> E; assign Tmasknonneg = ~IMask >>> 1'b1; assign HotE = IMask & ~(IMask << 1'b1); assign HotEP1 = HotE >> 1'b1; From b1f340ba5c1b0c3bb3a252dbc2f230294c76fe6d Mon Sep 17 00:00:00 2001 From: Corey Hickson Date: Wed, 30 Oct 2024 03:39:55 -0700 Subject: [PATCH 07/15] formatting --- src/fpu/fround.sv | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fpu/fround.sv b/src/fpu/fround.sv index fadd963d0..6c37d2973 100644 --- a/src/fpu/fround.sv +++ b/src/fpu/fround.sv @@ -76,8 +76,7 @@ module fround import cvw::*; #(parameter cvw_t P) ( assign Eeqm1 = ($signed(E) == -1); // Logic for nonnegative mask and rounding bits - // assign IMask = {1'b1, {P.NF{1'b0}}} >>> E; /// if E > Nf, this produces all 0s instead of all 1s. Hence exact handling is needed below. - assign IMask = $signed({1'b1, {P.NF{1'b0}}}) >>> E; + assign IMask = $signed({1'b1, {P.NF{1'b0}}}) >>> E; /// if E > Nf, this produces all 0s instead of all 1s. Hence exact handling is needed below. assign Tmasknonneg = ~IMask >>> 1'b1; assign HotE = IMask & ~(IMask << 1'b1); assign HotEP1 = HotE >> 1'b1; From 43f5ec283c8d6d74279d3953ba1633a1006fa2ec Mon Sep 17 00:00:00 2001 From: slmnemo Date: Sat, 26 Oct 2024 02:02:14 -0700 Subject: [PATCH 08/15] Added -j6 to nightly_build to make tests quicker. Untested, git rebase -i once it is confirmed this does not affect coverage using a nightly run --- bin/nightly_build.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/bin/nightly_build.py b/bin/nightly_build.py index 349bdb378..8c184b66c 100755 --- a/bin/nightly_build.py +++ b/bin/nightly_build.py @@ -288,16 +288,17 @@ class TestRunner: makefile_location = self.cvw.joinpath(makefile_path) os.chdir(makefile_location) - output_file = self.log_dir.joinpath(f"make-{target}-output.log") + if target: + output_file = self.log_dir.joinpath(f"make-{target}-output.log") + else: output_file = self.log_dir.joinpath(f"make-output.log") - command = ["make"] + command = ["make", "-j6"] # Add target to the command if specified if target: command.append(target) - self.logger.info(f"Command used in directory {makefile_location}: {command[0]} {command[1]}") - else: - self.logger.info(f"Command used in directory {makefile_location}: {command[0]}") + + self.logger.info(f"Command used in directory {makefile_location}: {' '.join(command)}") # Execute the command using subprocess and save the output into a file with open(output_file, "w") as f: @@ -311,10 +312,10 @@ class TestRunner: # Check the result if result.returncode == 0: - self.logger.info(f"Tests have been made with target: {target}") + self.logger.info(f"Tests have been made with target: {' '.join(command)}") return True else: - self.logger.error(f"Error making the tests. Target: {target}") + self.logger.error(f"Error making the tests. Command: {' '.join(command)}") return False def run_tests(self, test_type=None, test_name=None, test_extensions=None): @@ -422,7 +423,7 @@ class TestRunner: elif "Failures detected in output" in line: # Text explicitly fails try: config_name = line.split(':')[0].strip() - log_file = os.path.abspath(os.path.join("logs", config_name, ".log")) + log_file = os.path.abspath(os.path.join("logs", config_name)) failed_configs.append((config_name, log_file)) except: failed_configs.append((config_name, "Log file not found")) @@ -672,7 +673,7 @@ def main(): parser.add_argument('--path',default = "nightly", help='specify the path for where the nightly repositories will be cloned ex: "nightly-runs') parser.add_argument('--repository',default = "https://github.com/openhwgroup/cvw", help='specify which github repository you want to clone') - parser.add_argument('--target', default = "--jobs", help='types of tests you can make are: all, wally-riscv-arch-test, no') + parser.add_argument('--target', default = "", help='types of tests you can make are: all, wally-riscv-arch-test, no') parser.add_argument('--tests', default = "nightly", help='types of tests you can run are: nightly, test, test_lint') parser.add_argument('--send_email',default = "", nargs="+", help='What emails to send test results to. Example: "[email1],[email2],..."') From f605cb693a94558a2ddd4e328e408ada0b973e5d Mon Sep 17 00:00:00 2001 From: slmnemo Date: Sat, 26 Oct 2024 02:15:37 -0700 Subject: [PATCH 09/15] Added --dry-run feature. Changed detection for buildrootboot sim when adding short buildroot tests with multiple sims to avoid unnecessary failures --- bin/regression-wally | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/bin/regression-wally b/bin/regression-wally index 643787adc..2b325f437 100755 --- a/bin/regression-wally +++ b/bin/regression-wally @@ -334,22 +334,29 @@ def search_log_for_text(text, grepfile): # print(" search_log_for_text invoking %s" % grepcmd) return os.system(grepcmd) == 0 -def run_test_case(config): - """Run the given test case, and return 0 if the test suceeds and 1 if it fails""" +def run_test_case(config, dryrun: bool = False): + """ + Run the given test case, and return 0 if the test suceeds and 1 if it fails + + Do not execute commands if dryrun + """ grepfile = config.grepfile cmd = config.cmd os.chdir(regressionDir) - # print(" run_test_case invoking %s" % cmd, flush=True) - os.system(cmd) - if search_log_for_text(config.grepstr, grepfile): - # Flush is needed to flush output to stdout when running in multiprocessing Pool -# print(f"{bcolors.OKGREEN}%s_%s: Success{bcolors.ENDC}" % (config.variant, config.name), flush=True) - print(f"{bcolors.OKGREEN}%s: Success{bcolors.ENDC}" % (config.cmd), flush=True) + if dryrun: + print(f"Executing {cmd}", flush=True) return 0 else: - print(f"{bcolors.FAIL}%s: Failures detected in output{bcolors.ENDC}" % (config.cmd), flush=True) - print(" Check %s" % grepfile) - return 1 + os.system(cmd) + if search_log_for_text(config.grepstr, grepfile): + # Flush is needed to flush output to stdout when running in multiprocessing Pool + # print(f"{bcolors.OKGREEN}%s_%s: Success{bcolors.ENDC}" % (config.variant, config.name), flush=True) + print(f"{bcolors.OKGREEN}%s: Success{bcolors.ENDC}" % (config.cmd), flush=True) + return 0 + else: + print(f"{bcolors.FAIL}%s: Failures detected in output{bcolors.ENDC}" % (config.cmd), flush=True) + print(" Check %s" % grepfile) + return 1 ################################## # Main body @@ -363,6 +370,7 @@ os.chdir(regressionDir) coveragesim = "questa" # Questa is required for code/functional coverage #defaultsim = "questa" # Default simulator for all other tests; change to Verilator when flow is ready defaultsim = "verilator" # Default simulator for all other tests +buildrootbootsim = "questa" parser = argparse.ArgumentParser() parser.add_argument("--ccov", help="Code Coverage", action="store_true") @@ -371,6 +379,7 @@ parser.add_argument("--nightly", help="Run large nightly regression", action="st parser.add_argument("--buildroot", help="Include Buildroot Linux boot test (takes many hours, done along with --nightly)", action="store_true") parser.add_argument("--testfloat", help="Include Testfloat floating-point unit tests", action="store_true") parser.add_argument("--fp", help="Include floating-point tests in coverage (slower runtime)", action="store_true") +parser.add_argument("--dryrun", help="Print commands invoked to console without running regression", action="store_true") args = parser.parse_args() if (args.nightly): @@ -404,7 +413,7 @@ configs = [ # run full buildroot boot simulation (slow) if buildroot flag is set. Start it early to overlap with other tests if (args.buildroot): # addTests(tests_buildrootboot, defaultsim) # non-lockstep with Verilator runs in about 2 hours - addTests(tests_buildrootbootlockstep, "questa") # lockstep with Questa and ImperasDV runs overnight + addTests(tests_buildrootbootlockstep, buildrootbootsim) # lockstep with Questa and ImperasDV runs overnight if (args.ccov): # only run RV64GC tests on Questa in code coverage mode addTests(tests64gc_nofp, coveragesim) @@ -417,7 +426,7 @@ elif (args.fcov): # only run RV64GC tests on Questa in lockstep in functional c else: for sim in sims: - if (not (args.buildroot and sim == defaultsim)): # skip short buildroot sim if running long one + if (not (args.buildroot and sim == buildrootbootsim)): # skip short buildroot sim if running long one addTests(tests_buildrootshort, sim) addTests(tests, sim) addTests(tests64gc_nofp, sim) @@ -428,6 +437,7 @@ if (args.nightly): addLockstepTestsByDir(WALLY+"/tests/coverage", "rv64gc", "questa", 0) addLockstepTestsByDir(WALLY+"/tests/riscof/work/wally-riscv-arch-test/rv64i_m", "rv64gc", "questa", 0) addTests(derivconfigtests, defaultsim) + addTests(bpredtests, defaultsim) # testfloat tests if (args.testfloat): # for testfloat alone, just run testfloat tests @@ -540,9 +550,9 @@ def main(): # Coverage report if args.ccov: - os.system('make QuestaCodeCoverage') + os.system('make QuestaCodeCoverage') if args.fcov: - os.system('make -f '+WALLY+'/addins/cvw-arch-verif/Makefile merge') + os.system('make -f '+WALLY+'/addins/cvw-arch-verif/Makefile merge') # Count the number of failures if num_fail: print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail) From 9284dd3a9a7c769cb011b2fc7e0dfd320f0dd76a Mon Sep 17 00:00:00 2001 From: slmnemo Date: Sun, 27 Oct 2024 17:59:00 -0700 Subject: [PATCH 10/15] Changed buildrootbootsim to lockstepsim and added lockstepsim to lockstep tests in nightly --- bin/regression-wally | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/regression-wally b/bin/regression-wally index 2b325f437..1f30a9dce 100755 --- a/bin/regression-wally +++ b/bin/regression-wally @@ -370,7 +370,7 @@ os.chdir(regressionDir) coveragesim = "questa" # Questa is required for code/functional coverage #defaultsim = "questa" # Default simulator for all other tests; change to Verilator when flow is ready defaultsim = "verilator" # Default simulator for all other tests -buildrootbootsim = "questa" +lockstepsim = "questa" parser = argparse.ArgumentParser() parser.add_argument("--ccov", help="Code Coverage", action="store_true") @@ -413,7 +413,7 @@ configs = [ # run full buildroot boot simulation (slow) if buildroot flag is set. Start it early to overlap with other tests if (args.buildroot): # addTests(tests_buildrootboot, defaultsim) # non-lockstep with Verilator runs in about 2 hours - addTests(tests_buildrootbootlockstep, buildrootbootsim) # lockstep with Questa and ImperasDV runs overnight + addTests(tests_buildrootbootlockstep, lockstepsim) # lockstep with Questa and ImperasDV runs overnight if (args.ccov): # only run RV64GC tests on Questa in code coverage mode addTests(tests64gc_nofp, coveragesim) @@ -426,7 +426,7 @@ elif (args.fcov): # only run RV64GC tests on Questa in lockstep in functional c else: for sim in sims: - if (not (args.buildroot and sim == buildrootbootsim)): # skip short buildroot sim if running long one + if (not (args.buildroot and sim == lockstepsim)): # skip short buildroot sim if running long one addTests(tests_buildrootshort, sim) addTests(tests, sim) addTests(tests64gc_nofp, sim) @@ -434,8 +434,8 @@ else: # run derivative configurations and lockstep tests in nightly regression if (args.nightly): - addLockstepTestsByDir(WALLY+"/tests/coverage", "rv64gc", "questa", 0) - addLockstepTestsByDir(WALLY+"/tests/riscof/work/wally-riscv-arch-test/rv64i_m", "rv64gc", "questa", 0) + addLockstepTestsByDir(WALLY+"/tests/coverage", "rv64gc", lockstepsim, 0) + addLockstepTestsByDir(WALLY+"/tests/riscof/work/wally-riscv-arch-test/rv64i_m", "rv64gc", lockstepsim, 0) addTests(derivconfigtests, defaultsim) addTests(bpredtests, defaultsim) From b9d215db7672984d8442df18c39c7deec6cd9e72 Mon Sep 17 00:00:00 2001 From: Kaitlin Lucio Date: Mon, 28 Oct 2024 16:05:39 -0700 Subject: [PATCH 11/15] Update regression-wally according to PR --- bin/regression-wally | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/regression-wally b/bin/regression-wally index 1f30a9dce..0a7a8fa69 100755 --- a/bin/regression-wally +++ b/bin/regression-wally @@ -437,7 +437,7 @@ if (args.nightly): addLockstepTestsByDir(WALLY+"/tests/coverage", "rv64gc", lockstepsim, 0) addLockstepTestsByDir(WALLY+"/tests/riscof/work/wally-riscv-arch-test/rv64i_m", "rv64gc", lockstepsim, 0) addTests(derivconfigtests, defaultsim) - addTests(bpredtests, defaultsim) + # addTests(bpredtests, defaultsim) # This is currently broken in regression due to something related to the new wsim script. # testfloat tests if (args.testfloat): # for testfloat alone, just run testfloat tests From c105c09cdeb5f99847592ceb645ed9d1a8262fa3 Mon Sep 17 00:00:00 2001 From: slmnemo Date: Wed, 30 Oct 2024 11:39:11 -0700 Subject: [PATCH 12/15] Added jobs flag to make during nightly regression --- bin/nightly_build.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/nightly_build.py b/bin/nightly_build.py index 8c184b66c..cb8583eef 100755 --- a/bin/nightly_build.py +++ b/bin/nightly_build.py @@ -292,11 +292,11 @@ class TestRunner: output_file = self.log_dir.joinpath(f"make-{target}-output.log") else: output_file = self.log_dir.joinpath(f"make-output.log") - command = ["make", "-j6"] - - # Add target to the command if specified - if target: - command.append(target) + # Execute make with target and cores/2 + if target: + command = ["make", target, "--jobs=$(($(nproc)/2))"] + else: + command = ["make", "--jobs=$(($(nproc)/2))"] self.logger.info(f"Command used in directory {makefile_location}: {' '.join(command)}") @@ -305,7 +305,7 @@ class TestRunner: formatted_datetime = self.current_datetime.strftime("%Y-%m-%d %H:%M:%S") f.write(formatted_datetime) f.write("\n\n") - result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True) + result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True, shell=True) # Execute the command using a subprocess and not save the output #result = subprocess.run(command, text=True) From 1636942166d7ef5b1603a1229b3864fb45f187d6 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Wed, 30 Oct 2024 15:37:33 -0700 Subject: [PATCH 13/15] Link ncurses6 to ncurses 5 on Ubuntu 24.04 for Vivado --- bin/wally-package-install.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bin/wally-package-install.sh b/bin/wally-package-install.sh index 725d3b201..ce79dc575 100755 --- a/bin/wally-package-install.sh +++ b/bin/wally-package-install.sh @@ -123,5 +123,14 @@ else eval "$UPDATE_COMMAND" # Install packages listed above using appropriate package manager sudo $PACKAGE_MANAGER install -y "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}" "${VIVADO_PACKAGES[@]}" + + # Post install steps + # Vivado looks for ncurses5 libraries, but Ubuntu 24.04 only has ncurses6 + # Create symbolic links to the ncurses6 libraries to fool Vivado + if (( UBUNTU_VERSION >= 24 )); then + ln -vsf /lib/x86_64-linux-gnu/libncurses.so.6 /lib/x86_64-linux-gnu/libncurses.so.5 + ln -vsf /lib/x86_64-linux-gnu/libtinfo.so.6 /lib/x86_64-linux-gnu/libntinfo.so.5 + fi + echo -e "${SUCCESS_COLOR}Packages successfully installed.${ENDC}" fi From e8bcbb42ac405cfa6ab8c7b510dcfc00ad898dbf Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Wed, 30 Oct 2024 15:39:01 -0700 Subject: [PATCH 14/15] Add sudo --- bin/wally-package-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/wally-package-install.sh b/bin/wally-package-install.sh index ce79dc575..1fc003189 100755 --- a/bin/wally-package-install.sh +++ b/bin/wally-package-install.sh @@ -128,8 +128,8 @@ else # Vivado looks for ncurses5 libraries, but Ubuntu 24.04 only has ncurses6 # Create symbolic links to the ncurses6 libraries to fool Vivado if (( UBUNTU_VERSION >= 24 )); then - ln -vsf /lib/x86_64-linux-gnu/libncurses.so.6 /lib/x86_64-linux-gnu/libncurses.so.5 - ln -vsf /lib/x86_64-linux-gnu/libtinfo.so.6 /lib/x86_64-linux-gnu/libntinfo.so.5 + sudo ln -vsf /lib/x86_64-linux-gnu/libncurses.so.6 /lib/x86_64-linux-gnu/libncurses.so.5 + sudo ln -vsf /lib/x86_64-linux-gnu/libtinfo.so.6 /lib/x86_64-linux-gnu/libntinfo.so.5 fi echo -e "${SUCCESS_COLOR}Packages successfully installed.${ENDC}" From 51800ad4d1e3429e3df67792f020c9e6a9301348 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Wed, 30 Oct 2024 15:40:38 -0700 Subject: [PATCH 15/15] Fix installation workflow check paths --- .github/workflows/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml index b87f4f116..b065cd924 100644 --- a/.github/workflows/install.yml +++ b/.github/workflows/install.yml @@ -18,7 +18,7 @@ on: paths: - 'bin/wally-tool-chain-install.sh' - 'bin/wally-distro-check.sh' - - 'wally-package-install.sh' + - 'bin/wally-package-install.sh' schedule: - cron: "0 7 * * 3" # Run at 12:00 AM Pacific Time on Wednesdays