From b5b1ba790e8fc1e5e75784ddb2dbd8f19bbecf7e Mon Sep 17 00:00:00 2001 From: Alex Mykyta Date: Sun, 22 Oct 2023 20:43:34 -0700 Subject: [PATCH] Simulator compatibility updates --- tests/conftest.py | 25 ++- tests/lib/base_testcase.py | 10 + .../cpuifs/axi4lite/axi4lite_intf_driver.sv | 204 ++++++++++++------ tests/lib/external_block.sv | 2 +- tests/lib/external_reg.sv | 3 +- tests/lib/sim_testcase.py | 3 +- tests/lib/simulators/__init__.py | 4 +- tests/lib/simulators/base.py | 4 + tests/lib/simulators/questa.py | 15 +- tests/lib/simulators/xilinx.py | 34 +-- tests/lib/tb_base.sv | 4 +- tests/test_buffered_swacc_swmod/testcase.py | 2 +- tests/test_counter_basics/testcase.py | 2 +- tests/test_external/tb_template.sv | 4 +- tests/test_field_types/testcase.py | 1 + tests/test_hw_access/testcase.py | 1 + tests/test_interrupts/testcase.py | 1 + tests/test_parity/tb_template.sv | 4 +- tests/test_pipelined_cpuif/tb_template.sv | 2 +- tests/test_precedence/testcase.py | 1 + tests/test_read_buffer/testcase.py | 1 + tests/test_reset_signals/testcase.py | 1 + tests/test_structural_sw_rw/tb_template.sv | 8 +- tests/test_swacc_swmod/testcase.py | 1 + tests/test_swwe/testcase.py | 1 + tests/test_wide_regs/tb_template.sv | 12 +- tests/test_wide_regs/testcase.py | 1 + tests/test_write_buffer/tb_template.sv | 10 +- tests/test_write_buffer/testcase.py | 2 + 29 files changed, 248 insertions(+), 115 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 26a0575..13dcb5d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,7 @@ def pytest_addoption(parser): parser.addoption( "--sim-tool", - choices=["questa", "xilinx", "stub", "skip", "auto"], + choices=["questa", "xsim", "stub", "skip", "auto"], default="auto", help=""" Select the simulator to use. @@ -12,6 +12,29 @@ def pytest_addoption(parser): """ ) + parser.addoption( + "--gui", + default=False, + action="store_true", + help=""", + Launch sim tool in GUI mode + + Only use this option when running a single test + """ + ) + + + parser.addoption( + "--rerun", + default=False, + action="store_true", + help=""", + Re-run simulation in-place without re-exporting regblock + + Useful if hand-editing a testcase interactively. + """ + ) + parser.addoption( "--synth-tool", choices=["vivado", "skip", "auto"], diff --git a/tests/lib/base_testcase.py b/tests/lib/base_testcase.py index e69f7f3..89c4e5d 100644 --- a/tests/lib/base_testcase.py +++ b/tests/lib/base_testcase.py @@ -49,6 +49,13 @@ class BaseTestCase(unittest.TestCase): def _load_request(self, request): self.request = request + @property + def rerun(self) -> bool: + """ + Re-run wothout deleting and re-generating prior output directory. + """ + return self.request.config.getoption("--rerun") + def get_testcase_dir(self) -> str: class_dir = os.path.dirname(inspect.getfile(self.__class__)) return class_dir @@ -114,6 +121,9 @@ def _export_regblock(self): ) def setUp(self) -> None: + if self.rerun: + return + # Create fresh build dir run_dir = self.get_run_dir() if os.path.exists(run_dir): diff --git a/tests/lib/cpuifs/axi4lite/axi4lite_intf_driver.sv b/tests/lib/cpuifs/axi4lite/axi4lite_intf_driver.sv index b55aada..856048a 100644 --- a/tests/lib/cpuifs/axi4lite/axi4lite_intf_driver.sv +++ b/tests/lib/cpuifs/axi4lite/axi4lite_intf_driver.sv @@ -95,79 +95,148 @@ interface axi4lite_intf_driver #( @cb; end - semaphore txn_aw_mutex = new(1); - semaphore txn_w_mutex = new(1); - semaphore txn_b_mutex = new(1); - semaphore txn_ar_mutex = new(1); - semaphore txn_r_mutex = new(1); + //-------------------------------------------------------------------------- + typedef struct { + logic [1:0] bresp; + } write_response_t; + + class write_request_t; + mailbox #(write_response_t) response_mbx; + logic [ADDR_WIDTH-1:0] addr; + logic [DATA_WIDTH-1:0] data; + logic [DATA_WIDTH/8-1:0] strb; + function new(); + this.response_mbx = new(); + endfunction + endclass + + mailbox #(write_request_t) aw_mbx = new(); + mailbox #(write_request_t) w_mbx = new(); + write_request_t write_queue[$]; + + // Issue AW transfers + initial forever begin + write_request_t req; + aw_mbx.get(req); + ##0; + repeat($urandom_range(2,0)) @cb; + cb.AWVALID <= '1; + cb.AWADDR <= req.addr; + cb.AWPROT <= '0; + @(cb); + while(cb.AWREADY !== 1'b1) @(cb); + cb.AWVALID <= '0; + end + + // Issue W transfers + initial forever begin + write_request_t req; + w_mbx.get(req); + ##0; + repeat($urandom_range(2,0)) @cb; + cb.WVALID <= '1; + cb.WDATA <= req.data; + cb.WSTRB <= req.strb; + @(cb); + while(cb.WREADY !== 1'b1) @(cb); + cb.WVALID <= '0; + cb.WSTRB <= '0; + end + + // Listen for R responses + initial forever begin + @cb; + while(rst || !(cb.BREADY === 1'b1 && cb.BVALID === 1'b1)) @cb; + if(write_queue.size() != 0) begin + // Can match this response with an existing request. + // Send response to requestor + write_request_t req; + write_response_t resp; + req = write_queue.pop_front(); + resp.bresp = cb.BRESP; + req.response_mbx.put(resp); + end else begin + $error("Got unmatched write response"); + end + end task automatic write(logic [ADDR_WIDTH-1:0] addr, logic [DATA_WIDTH-1:0] data, logic [DATA_WIDTH/8-1:0] strb = '1); - bit w_before_aw; - w_before_aw = $urandom_range(1,0); - - fork - begin - txn_aw_mutex.get(); - ##0; - if(w_before_aw) repeat($urandom_range(2,0)) @cb; - cb.AWVALID <= '1; - cb.AWADDR <= addr; - cb.AWPROT <= '0; - @(cb); - while(cb.AWREADY !== 1'b1) @(cb); - cb.AWVALID <= '0; - txn_aw_mutex.put(); - end - - begin - txn_w_mutex.get(); - ##0; - if(!w_before_aw) repeat($urandom_range(2,0)) @cb; - cb.WVALID <= '1; - cb.WDATA <= data; - cb.WSTRB <= strb; - @(cb); - while(cb.WREADY !== 1'b1) @(cb); - cb.WVALID <= '0; - cb.WSTRB <= '0; - txn_w_mutex.put(); - end - - begin - txn_b_mutex.get(); - @cb; - while(!(cb.BREADY === 1'b1 && cb.BVALID === 1'b1)) @(cb); - assert(!$isunknown(cb.BRESP)) else $error("Read from 0x%0x returned X's on BRESP", addr); - txn_b_mutex.put(); - end - join + write_request_t req; + write_response_t resp; + + req = new(); + req.addr = addr; + req.data = data; + req.strb = strb; + + aw_mbx.put(req); + w_mbx.put(req); + write_queue.push_back(req); + + // Wait for response + req.response_mbx.get(resp); + assert(!$isunknown(resp.bresp)) else $error("Read from 0x%0x returned X's on BRESP", addr); endtask + //-------------------------------------------------------------------------- + typedef struct { + logic [DATA_WIDTH-1: 0] rdata; + logic [1:0] rresp; + } read_response_t; + + class read_request_t; + mailbox #(read_response_t) response_mbx; + function new(); + this.response_mbx = new(); + endfunction + endclass + + semaphore txn_ar_mutex = new(1); + read_request_t read_queue[$]; + + // Listen for R responses + initial forever begin + @cb; + while(rst || !(cb.RREADY === 1'b1 && cb.RVALID === 1'b1)) @cb; + if(read_queue.size() != 0) begin + // Can match this response with an existing request. + // Send response to requestor + read_request_t req; + read_response_t resp; + req = read_queue.pop_front(); + resp.rdata = cb.RDATA; + resp.rresp = cb.RRESP; + req.response_mbx.put(resp); + end else begin + $error("Got unmatched read response"); + end + end + task automatic read(logic [ADDR_WIDTH-1:0] addr, output logic [DATA_WIDTH-1:0] data); + read_request_t req; + read_response_t resp; + + txn_ar_mutex.get(); + // Issue read request + ##0; + cb.ARVALID <= '1; + cb.ARADDR <= addr; + cb.ARPROT <= '0; + @(cb); + while(cb.ARREADY !== 1'b1) @(cb); + cb.ARVALID <= '0; + + // Push new request into queue + req = new(); + read_queue.push_back(req); + txn_ar_mutex.put(); + + // Wait for response + req.response_mbx.get(resp); - fork - begin - txn_ar_mutex.get(); - ##0; - cb.ARVALID <= '1; - cb.ARADDR <= addr; - cb.ARPROT <= '0; - @(cb); - while(cb.ARREADY !== 1'b1) @(cb); - cb.ARVALID <= '0; - txn_ar_mutex.put(); - end - - begin - txn_r_mutex.get(); - @cb; - while(!(cb.RREADY === 1'b1 && cb.RVALID === 1'b1)) @(cb); - assert(!$isunknown(cb.RDATA)) else $error("Read from 0x%0x returned X's on RDATA", addr); - assert(!$isunknown(cb.RRESP)) else $error("Read from 0x%0x returned X's on RRESP", addr); - data = cb.RDATA; - txn_r_mutex.put(); - end - join + assert(!$isunknown(resp.rdata)) else $error("Read from 0x%0x returned X's on RDATA", addr); + assert(!$isunknown(resp.rresp)) else $error("Read from 0x%0x returned X's on RRESP", addr); + data = resp.rdata; endtask task automatic assert_read(logic [ADDR_WIDTH-1:0] addr, logic [DATA_WIDTH-1:0] expected_data, logic [DATA_WIDTH-1:0] mask = '1); @@ -177,6 +246,7 @@ interface axi4lite_intf_driver #( assert(data == expected_data) else $error("Read from 0x%x returned 0x%x. Expected 0x%x", addr, data, expected_data); endtask + //-------------------------------------------------------------------------- initial begin reset(); end diff --git a/tests/lib/external_block.sv b/tests/lib/external_block.sv index ffde251..a1c75c9 100644 --- a/tests/lib/external_block.sv +++ b/tests/lib/external_block.sv @@ -14,7 +14,7 @@ module external_block #( output logic [WIDTH-1:0] rd_data, output logic wr_ack ); -timeunit 1ns; +timeunit 1ps; timeprecision 1ps; localparam ADDR_SHIFT = $clog2(WIDTH/8); diff --git a/tests/lib/external_reg.sv b/tests/lib/external_reg.sv index b7a09f5..9a51395 100644 --- a/tests/lib/external_reg.sv +++ b/tests/lib/external_reg.sv @@ -13,7 +13,7 @@ module external_reg #( output logic [WIDTH-1:0] rd_data, output logic wr_ack ); -timeunit 1ns; +timeunit 1ps; timeprecision 1ps; logic [SUBWORDS-1:0][WIDTH-1:0] value; @@ -69,6 +69,7 @@ initial begin #1ns; if(!rst && req) begin + $info("got request"); if(req_is_wr) do_write(req, wr_data, wr_biten); else do_read(req); end diff --git a/tests/lib/sim_testcase.py b/tests/lib/sim_testcase.py index 631061e..833e0d2 100644 --- a/tests/lib/sim_testcase.py +++ b/tests/lib/sim_testcase.py @@ -76,7 +76,8 @@ def setUp(self): super().setUp() # Create testbench from template - self._generate_tb() + if not self.rerun: + self._generate_tb() simulator = simulator_cls(self) diff --git a/tests/lib/simulators/__init__.py b/tests/lib/simulators/__init__.py index f8eef84..d9b7558 100644 --- a/tests/lib/simulators/__init__.py +++ b/tests/lib/simulators/__init__.py @@ -3,13 +3,13 @@ from .base import Simulator from .questa import Questa -from .xilinx import Xilinx +from .xilinx import XilinxXSIM from .stub import StubSimulator ALL_SIMULATORS: List[Simulator] ALL_SIMULATORS = [ Questa, - Xilinx, + XilinxXSIM, StubSimulator, ] diff --git a/tests/lib/simulators/base.py b/tests/lib/simulators/base.py index 2897666..115f6d5 100644 --- a/tests/lib/simulators/base.py +++ b/tests/lib/simulators/base.py @@ -13,6 +13,10 @@ def is_installed(cls) -> bool: def __init__(self, testcase: 'SimTestCase' = None) -> None: self.testcase = testcase + @property + def gui_mode(self) -> bool: + return self.testcase.request.config.getoption("--gui") + @property def tb_files(self) -> List[str]: files = [] diff --git a/tests/lib/simulators/questa.py b/tests/lib/simulators/questa.py index defe138..3e35667 100644 --- a/tests/lib/simulators/questa.py +++ b/tests/lib/simulators/questa.py @@ -48,14 +48,21 @@ def run(self, plusargs:List[str] = None) -> None: "vsim", "-quiet", "-voptargs=+acc", "-msgmode", "both", - "-do", "set WildcardFilter [lsearch -not -all -inline $WildcardFilter Memory]", - "-do", "log -r /*;", - "-do", "run -all; exit;", - "-c", "-l", "%s.log" % test_name, "-wlf", "%s.wlf" % test_name, "tb", + "-do", "set WildcardFilter [lsearch -not -all -inline $WildcardFilter Memory]", + "-do", "log -r /*;", ] + + if self.gui_mode: + cmd.append("-i") + else: + cmd.extend([ + "-do", "run -all; exit;", + "-c", + ]) + for plusarg in plusargs: cmd.append("+" + plusarg) subprocess.run(cmd, check=True) diff --git a/tests/lib/simulators/xilinx.py b/tests/lib/simulators/xilinx.py index 13c8c46..13a1013 100644 --- a/tests/lib/simulators/xilinx.py +++ b/tests/lib/simulators/xilinx.py @@ -5,17 +5,17 @@ from .base import Simulator -class Xilinx(Simulator): +class XilinxXSIM(Simulator): """ - Don't bother using the Xilinx simulator... Its buggy and extraordinarily slow. + Avoid using the Xilinx simulator... Its buggy and extraordinarily slow. As observed in v2023.2: - - clocking block assignments do not seem to actually simulate correctly. - assignment statements get ignored or the values get mangled. - - Streaming operators have all sorts of limitations. - - Keeping this here in case someday it works better... + - Clocking block assignments to struct members do not simulate correctly. + assignment statements get lost. + https://support.xilinx.com/s/question/0D54U00007ZIGfXSAX/xsim-bug-xsim-does-not-simulate-struct-assignments-in-clocking-blocks-correctly?language=en_US + - Streaming bit-swap within a conditional returns a corrupted value + https://support.xilinx.com/s/question/0D54U00007ZIIBPSA5/xsim-bug-xsim-corrupts-value-of-signal-that-is-bitswapped-within-a-conditional-operator?language=en_US """ - name = "xilinx" + name = "xsim" @classmethod def is_installed(cls) -> bool: @@ -30,7 +30,7 @@ def compile(self) -> None: "xvlog", "--sv", "--log", "compile.log", "--include", os.path.join(os.path.dirname(__file__), ".."), - "--define", "XSIM", + "--define", "XILINX_XSIM", ] cmd.extend(self.tb_files) subprocess.run(cmd, check=True) @@ -38,7 +38,7 @@ def compile(self) -> None: cmd = [ "xelab", "--log", "elaborate.log", - "--timescale", "1ns/1ps", + "--timescale", "1ps/1ps", "--debug", "all", "tb", ] @@ -50,13 +50,17 @@ def run(self, plusargs:List[str] = None) -> None: test_name = self.testcase.request.node.name - # call vsim - cmd = [ - "xsim", - "--R", + # call xsim + cmd = ["xsim"] + if self.gui_mode: + cmd.append("--gui") + else: + cmd.append("-R") + + cmd.extend([ "--log", "%s.log" % test_name, "tb", - ] + ]) for plusarg in plusargs: cmd.append("--testplusarg") diff --git a/tests/lib/tb_base.sv b/tests/lib/tb_base.sv index 9c6ea55..e6247dd 100644 --- a/tests/lib/tb_base.sv +++ b/tests/lib/tb_base.sv @@ -1,8 +1,10 @@ {% sv_line_anchor %} module tb; - timeunit 1ns; + timeunit 10ps; timeprecision 1ps; + `define bitswap(x) ($bits(x))'({<<{x}}) + logic rst = '1; logic clk = '0; initial forever begin diff --git a/tests/test_buffered_swacc_swmod/testcase.py b/tests/test_buffered_swacc_swmod/testcase.py index 41b42d2..51535f5 100644 --- a/tests/test_buffered_swacc_swmod/testcase.py +++ b/tests/test_buffered_swacc_swmod/testcase.py @@ -1,6 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): - incompatible_sim_tools = {"xilinx"} + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_counter_basics/testcase.py b/tests/test_counter_basics/testcase.py index 41b42d2..51535f5 100644 --- a/tests/test_counter_basics/testcase.py +++ b/tests/test_counter_basics/testcase.py @@ -1,6 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): - incompatible_sim_tools = {"xilinx"} + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_external/tb_template.sv b/tests/test_external/tb_template.sv index ac4cd59..a5f4029 100644 --- a/tests/test_external/tb_template.sv +++ b/tests/test_external/tb_template.sv @@ -145,8 +145,8 @@ .req(hwif_out.wide_ro_reg.req), .req_is_wr(hwif_out.wide_ro_reg.req_is_wr), - .wr_data(64'b0), - .wr_biten(64'b0), + .wr_data(32'b0), + .wr_biten(32'b0), .rd_ack(hwif_in.wide_ro_reg.rd_ack), .rd_data(hwif_in.wide_ro_reg.rd_data), .wr_ack() diff --git a/tests/test_field_types/testcase.py b/tests/test_field_types/testcase.py index 835b5ef..51535f5 100644 --- a/tests/test_field_types/testcase.py +++ b/tests/test_field_types/testcase.py @@ -1,5 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_hw_access/testcase.py b/tests/test_hw_access/testcase.py index 835b5ef..51535f5 100644 --- a/tests/test_hw_access/testcase.py +++ b/tests/test_hw_access/testcase.py @@ -1,5 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_interrupts/testcase.py b/tests/test_interrupts/testcase.py index 835b5ef..51535f5 100644 --- a/tests/test_interrupts/testcase.py +++ b/tests/test_interrupts/testcase.py @@ -1,5 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_parity/tb_template.sv b/tests/test_parity/tb_template.sv index 3309500..392a23a 100644 --- a/tests/test_parity/tb_template.sv +++ b/tests/test_parity/tb_template.sv @@ -24,8 +24,8 @@ disable fork; cpuif.write('h0, 'd0); - force dut.field_storage.r1.f1.value[3] = 1'b1; - release dut.field_storage.r1.f1.value[3]; + assign dut.field_storage.r1.f1.value = 16'd1; + deassign dut.field_storage.r1.f1.value; @cb; @cb; assert(cb.parity_error == 1'b1); diff --git a/tests/test_pipelined_cpuif/tb_template.sv b/tests/test_pipelined_cpuif/tb_template.sv index b9c349f..cfee40a 100644 --- a/tests/test_pipelined_cpuif/tb_template.sv +++ b/tests/test_pipelined_cpuif/tb_template.sv @@ -36,7 +36,7 @@ wait fork; // Mix read/writes - for(int i=0; i<64; i++) begin + for(int i=0; i<8; i++) begin fork automatic int i_fk = i; begin diff --git a/tests/test_precedence/testcase.py b/tests/test_precedence/testcase.py index 835b5ef..51535f5 100644 --- a/tests/test_precedence/testcase.py +++ b/tests/test_precedence/testcase.py @@ -1,5 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_read_buffer/testcase.py b/tests/test_read_buffer/testcase.py index 835b5ef..51535f5 100644 --- a/tests/test_read_buffer/testcase.py +++ b/tests/test_read_buffer/testcase.py @@ -1,5 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_reset_signals/testcase.py b/tests/test_reset_signals/testcase.py index 835b5ef..51535f5 100644 --- a/tests/test_reset_signals/testcase.py +++ b/tests/test_reset_signals/testcase.py @@ -1,5 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_structural_sw_rw/tb_template.sv b/tests/test_structural_sw_rw/tb_template.sv index bd7d4d3..ca7f153 100644 --- a/tests/test_structural_sw_rw/tb_template.sv +++ b/tests/test_structural_sw_rw/tb_template.sv @@ -71,13 +71,13 @@ cpuif.assert_read('h3000, 'h4DEAB000); // rw_reg_lsb0 - `ifndef XSIM - // Xilinx simulator has poor support for streaming operators. Skip + `ifndef XILINX_XSIM + // Skip due to xsim bug simulating internal RTL - bitswap inside conditional corrupts data cpuif.assert_read('h3004, 0); cpuif.write('h3004, 'h4DEAB000); @cb; - assert({<<{cb.hwif_out.rw_reg_lsb0.f1.value}} == 8'hAB); - assert({<<{cb.hwif_out.rw_reg_lsb0.f2.value}} == 11'h4DE); + assert(`bitswap(cb.hwif_out.rw_reg_lsb0.f1.value) == 8'hAB); + assert(`bitswap(cb.hwif_out.rw_reg_lsb0.f2.value) == 11'h4DE); cpuif.assert_read('h3004, 'h4DEAB000); `endif {% endblock %} diff --git a/tests/test_swacc_swmod/testcase.py b/tests/test_swacc_swmod/testcase.py index 835b5ef..51535f5 100644 --- a/tests/test_swacc_swmod/testcase.py +++ b/tests/test_swacc_swmod/testcase.py @@ -1,5 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_swwe/testcase.py b/tests/test_swwe/testcase.py index 835b5ef..51535f5 100644 --- a/tests/test_swwe/testcase.py +++ b/tests/test_swwe/testcase.py @@ -1,5 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_wide_regs/tb_template.sv b/tests/test_wide_regs/tb_template.sv index 001db27..005608a 100644 --- a/tests/test_wide_regs/tb_template.sv +++ b/tests/test_wide_regs/tb_template.sv @@ -50,10 +50,10 @@ cpuif.write('h14, 'h9ABC); cpuif.write('h16, 'hDEF1); @cb; - assert({<<{cb.hwif_out.rw_reg1_lsb0.f1.value}} == 8'h34); - assert({<<{cb.hwif_out.rw_reg1_lsb0.f2.value}} == 3'h1); - assert({<<{cb.hwif_out.rw_reg1_lsb0.f3.value}} == 1'h1); - assert({<<{cb.hwif_out.rw_reg1_lsb0.f4.value}} == 8'h9A); + assert(`bitswap(cb.hwif_out.rw_reg1_lsb0.f1.value) == 8'h34); + assert(`bitswap(cb.hwif_out.rw_reg1_lsb0.f2.value) == 3'h1); + assert(`bitswap(cb.hwif_out.rw_reg1_lsb0.f3.value) == 1'h1); + assert(`bitswap(cb.hwif_out.rw_reg1_lsb0.f4.value) == 8'h9A); cpuif.assert_read('h10, 'h1034); cpuif.assert_read('h12, 'h0000); cpuif.assert_read('h14, 'h9A10); @@ -67,8 +67,8 @@ cpuif.write('h1C, 'h9ABC); cpuif.write('h1E, 'hDEF1); @cb; - assert({<<{cb.hwif_out.rw_reg2_lsb0.f1.value}} == 4'h8); - assert({<<{cb.hwif_out.rw_reg2_lsb0.f2.value}} == 16'hDEF1); + assert(`bitswap(cb.hwif_out.rw_reg2_lsb0.f1.value) == 4'h8); + assert(`bitswap(cb.hwif_out.rw_reg2_lsb0.f2.value) == 16'hDEF1); cpuif.assert_read('h18, 'h0000); cpuif.assert_read('h1A, 'h0008); cpuif.assert_read('h1C, 'h0000); diff --git a/tests/test_wide_regs/testcase.py b/tests/test_wide_regs/testcase.py index 835b5ef..51535f5 100644 --- a/tests/test_wide_regs/testcase.py +++ b/tests/test_wide_regs/testcase.py @@ -1,5 +1,6 @@ from ..lib.sim_testcase import SimTestCase class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug def test_dut(self): self.run_test() diff --git a/tests/test_write_buffer/tb_template.sv b/tests/test_write_buffer/tb_template.sv index 42cb159..4c281eb 100644 --- a/tests/test_write_buffer/tb_template.sv +++ b/tests/test_write_buffer/tb_template.sv @@ -69,7 +69,7 @@ assert(cb.hwif_out.reg1_msb0.f1.value == 0); cpuif.write('hE, 'hDEF1); @cb; @cb; - assert({<<{cb.hwif_out.reg1_msb0.f1.value}} == 64'hDEF19ABC56781234); + assert(`bitswap(cb.hwif_out.reg1_msb0.f1.value) == 64'hDEF19ABC56781234); cpuif.assert_read('h8, 'h1234); cpuif.assert_read('hA, 'h5678); cpuif.assert_read('hC, 'h9ABC); @@ -104,8 +104,8 @@ assert(cb.hwif_out.reg2_msb0.f2.value == 0); cpuif.write('h16, 'hAA12); @cb; @cb; - assert({<<{cb.hwif_out.reg2_msb0.f1.value}} == 12'h234); - assert({<<{cb.hwif_out.reg2_msb0.f2.value}} == 4'h1); + assert(`bitswap(cb.hwif_out.reg2_msb0.f1.value) == 12'h234); + assert(`bitswap(cb.hwif_out.reg2_msb0.f2.value) == 4'h1); cpuif.assert_read('h14, 'h3400); cpuif.assert_read('h16, 'h0012); @@ -281,7 +281,7 @@ cpuif.assert_read('hA, 'h0200); cpuif.assert_read('hC, 'h0070); cpuif.assert_read('hE, 'h0002); - assert({<<{cb.hwif_out.reg1_msb0.f1.value}} == 'h0002_0070_0200_A000); + assert(`bitswap(cb.hwif_out.reg1_msb0.f1.value) == 'h0002_0070_0200_A000); // Check that strobes are cumulative cpuif.write('h8, 'h0030, 'h00F0); @@ -297,7 +297,7 @@ cpuif.assert_read('hA, 'h0278); cpuif.assert_read('hC, 'hA07D); cpuif.assert_read('hE, 'hAF02); - assert({<<{cb.hwif_out.reg1_msb0.f1.value}} == 'hAF02_A07D_0278_A230); + assert(`bitswap(cb.hwif_out.reg1_msb0.f1.value) == 'hAF02_A07D_0278_A230); {% endblock %} diff --git a/tests/test_write_buffer/testcase.py b/tests/test_write_buffer/testcase.py index 4c1be35..f6ed096 100644 --- a/tests/test_write_buffer/testcase.py +++ b/tests/test_write_buffer/testcase.py @@ -2,6 +2,8 @@ from ..lib.cpuifs.passthrough import Passthrough class Test(SimTestCase): + incompatible_sim_tools = {"xsim"} # due to cb struct assignment bug + cpuif = Passthrough() # test with bit strobes def test_dut(self):