From b7972b7ed0bf1d9d51506e21ecfe62d95daeba91 Mon Sep 17 00:00:00 2001 From: Lucas Klemmer Date: Mon, 13 May 2024 15:58:44 +0200 Subject: [PATCH] better handle arrays and structs --- tests/test_trace_eq.py | 35 +++++++++++++++++++++++++++++++ tests/test_trace_reader.py | 25 +++++++++++++++++++--- tests/traces/array.fst | Bin 564 -> 0 bytes tests/traces/array.vcd | 33 ----------------------------- tests/traces/sv_struct_array.fst | Bin 0 -> 527 bytes tests/traces/sv_struct_array.vcd | 25 ++++++++++++++++++++++ wal/implementation/core.py | 12 ++++------- wal/trace/fst.py | 6 ++++++ wal/trace/vcd.py | 8 ++++++- 9 files changed, 99 insertions(+), 45 deletions(-) delete mode 100644 tests/traces/array.fst delete mode 100644 tests/traces/array.vcd create mode 100644 tests/traces/sv_struct_array.fst create mode 100644 tests/traces/sv_struct_array.vcd diff --git a/tests/test_trace_eq.py b/tests/test_trace_eq.py index 743afe3..40b13db 100644 --- a/tests/test_trace_eq.py +++ b/tests/test_trace_eq.py @@ -59,6 +59,41 @@ def test_rising_clocks(self): def test_overflow(self): self.eval_eq('(count tb.overflow') + def test_signals(self): + self.eval_eq('SIGNALS') + + def test_scopes(self): + self.eval_eq('SCOPES') + + def test_local_scopes(self): + self.eval_eq('LOCAL-SCOPES') + self.eval_eq("(in-scope 'tb CS)") + self.eval_eq("(in-scope 'tb LOCAL-SCOPES)") + + def test_local_signals(self): + wal = "(in-scope 'tb LOCAL-SIGNALS)" + res = list(map(lambda t: self.wal_eval([t, wal]), self.traces)) + + for pair in combinations(res, 2): + self.assertEqual(sorted(pair[0]), sorted(pair[1])) + + +class SVArrayEqualTest(TraceEqTest, unittest.TestCase): + '''Test counter traces for equality''' + + def setUp(self): + self.traces = ['sv_struct_array.vcd', 'sv_struct_array.fst'] + super().setUp() + + def test_group_clk(self): + self.eval_eq('(groups something)') + + def test_signals(self): + self.eval_eq('SIGNALS') + + def test_scopes(self): + self.eval_eq('SCOPES') + def test_local_scopes(self): self.eval_eq('LOCAL-SCOPES') self.eval_eq("(in-scope 'tb CS)") diff --git a/tests/test_trace_reader.py b/tests/test_trace_reader.py index e09a5f3..9e17048 100644 --- a/tests/test_trace_reader.py +++ b/tests/test_trace_reader.py @@ -2,6 +2,7 @@ import unittest from wal.core import Wal +from wal.ast_defs import WalEvalError class BasicParserTest(unittest.TestCase): '''Test trace readers''' @@ -10,6 +11,24 @@ def test_sv_arrays(self): '''Test SystemVerilog arrays''' for trace_format in ['vcd', 'fst']: wal = Wal() - wal.load(f'tests/traces/array.{trace_format}') - self.assertEqual(wal.eval_str('TOP.tb.data<0>'), 2) - self.assertEqual(wal.eval_str('TOP.tb.data<1>'), 0) + wal.load(f'tests/traces/sv_struct_array.{trace_format}') + self.assertEqual(wal.eval_str('TOP.tb.data<0>.data.something'), 5) + + +class ReadUndefinedSignalTest(unittest.TestCase): + '''Test trace readers''' + + def test_read_undefined_signals(self): + '''Test SystemVerilog arrays''' + for trace_format in ['vcd', 'fst']: + wal = Wal() + wal.load(f'tests/traces/sv_struct_array.{trace_format}') + + with self.assertRaises(WalEvalError): + wal.eval_str('TOP.tb.data<0>.wrongname') + + with self.assertRaises(WalEvalError): + wal.eval_str('(in-scope "TOP.tb.data<0>" ~wrongname)') + + with self.assertRaises(WalEvalError): + wal.eval_str('(in-group "TOP.tb.data<0>" #.wrongname)') diff --git a/tests/traces/array.fst b/tests/traces/array.fst deleted file mode 100644 index d6b3325d9e32d364209adbf849c967779a76f450..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmZQz00Tx(2n{E>GQ&l>x%RU-!Lgu7!N^p>(98;mObiu_42(=*E~TmEK*M2yl!|5%%zm)|9d~R1c*(6*bIox Qf!IQb;esVxF~k4=0M~&mTmS$7 diff --git a/tests/traces/array.vcd b/tests/traces/array.vcd deleted file mode 100644 index c55f8cf..0000000 --- a/tests/traces/array.vcd +++ /dev/null @@ -1,33 +0,0 @@ -$version Generated by VerilatedVcd $end -$timescale 1ps $end - - $scope module TOP $end - $scope module tb $end - $var wire 8 # data[0] [7:0] $end - $var wire 8 $ data[1] [7:0] $end - $var wire 8 % data[2] [7:0] $end - $var wire 8 & data[3] [7:0] $end - $var wire 8 ' data[4] [7:0] $end - $var wire 8 ( data[5] [7:0] $end - $var wire 8 ) data[6] [7:0] $end - $var wire 8 * data[7] [7:0] $end - $var wire 8 + data[8] [7:0] $end - $var wire 8 , data[9] [7:0] $end - $upscope $end - $upscope $end -$enddefinitions $end - - -#0 -b00000010 # -b00000000 $ -b00000000 % -b00000000 & -b00000000 ' -b00000000 ( -b00000000 ) -b00000000 * -b00000000 + -b00000000 , -#10 -b00000100 # diff --git a/tests/traces/sv_struct_array.fst b/tests/traces/sv_struct_array.fst new file mode 100644 index 0000000000000000000000000000000000000000..6131c471590bf3ef0ee129a95929a75df8f23a28 GIT binary patch literal 527 zcmZQz00Tx(2n{E>GQ&l>x%RU', scope) for scope in self.scopes] + self.scopes = [ + re.sub(r'\[([0-9]+)\]', r'<\1>', scope) for scope in self.scopes] + # get mapping from name to tid and remove trailing signal width, ' [31:0]' etc. self.references_to_ids = {re.sub(r' *\[\d+:\d+\]', '', k): v for k, v in self.references_to_ids.items()} diff --git a/wal/trace/vcd.py b/wal/trace/vcd.py index 56bbb7c..639bbe5 100644 --- a/wal/trace/vcd.py +++ b/wal/trace/vcd.py @@ -41,7 +41,13 @@ def parse(self, vcddata): # header section while (not header_done) and tokens: if tokens[i] == '$scope': - scope.append(tokens[i + 2]) + name = tokens[i + 2] + + # array entries should not clash with WAL operators + name = re.sub(r'\[([0-9]+)\]', r'<\1>', name) + name = re.sub(r'\(([0-9]+)\)', r'<\1>', name) + + scope.append(name) self.scopes.append('.'.join(scope)) i += 4 elif tokens[i] == '$var':