wal icon indicating copy to clipboard operation
wal copied to clipboard

access signals that are arrays?

Open jiahzhang opened this issue 1 year ago • 8 comments

May be a dumb question, but how does one index into signals that are really SV arrays? This doesn't seem to work:

#array[0].something

jiahzhang avatar Apr 24 '24 22:04 jiahzhang

Hi, I think this depends a bit on how your simulator outputs array elements. For example, Verilator creates a signal arra[0], array[1], etc., for each element of the array. Since in WAL [] gets you bit ranges from a signal, those signal names are translated to array<0>

I just updated WAL's trace readers to improve this., so if you install from the latest main branch, it hopefully works.

LucasKl avatar Apr 25 '24 15:04 LucasKl

I installed from main, and still see the same error

Traceback (most recent call last):
  File "/home/jzhang/.local/bin/wal", line 8, in <module>
    sys.exit(run())
             ^^^^^
  File "/home/jzhang/.local/lib/python3.11/site-packages/wal/wal.py", line 44, in run
    sys.exit(main())
             ^^^^^^
  File "/home/jzhang/.local/lib/python3.11/site-packages/wal/wal.py", line 95, in main
    resolved = resolve(optimized, start=wal.eval_context.global_environment.environment)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jzhang/.local/lib/python3.11/site-packages/wal/passes.py", line 182, in resolve
    return(resolve_vars(expr))
           ^^^^^^^^^^^^^^^^^^
  File "/home/jzhang/.local/lib/python3.11/site-packages/wal/passes.py", line 165, in resolve_vars
    return WList([resolve_vars(sub) for sub in expr], line_info=expr.line_info)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jzhang/.local/lib/python3.11/site-packages/wal/passes.py", line 165, in <listcomp>
    return WList([resolve_vars(sub) for sub in expr], line_info=expr.line_info)
                  ^^^^^^^^^^^^^^^^^
  File "/home/jzhang/.local/lib/python3.11/site-packages/wal/passes.py", line 165, in resolve_vars
    return WList([resolve_vars(sub) for sub in expr], line_info=expr.line_info)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jzhang/.local/lib/python3.11/site-packages/wal/passes.py", line 165, in <listcomp>
    return WList([resolve_vars(sub) for sub in expr], line_info=expr.line_info)
                  ^^^^^^^^^^^^^^^^^
  File "/home/jzhang/.local/lib/python3.11/site-packages/wal/passes.py", line 138, in resolve_vars
    env[binding[0].name] = True
        ~~~~~~~^^^
TypeError: 'Symbol' object is not subscriptable

jiahzhang avatar Apr 25 '24 15:04 jiahzhang

I see. Can you share the trace file or the signal names generated for your array?

LucasKl avatar Apr 25 '24 15:04 LucasKl

I just noticed it fails even if I comment out the array reference. Does this syntax look right to you?

(load "example.vcd")
(in-groups '("something.something.")
  (print CG ":")
  (print SIGNALS)
  (whenever (&& #clk #reset_n)
    (let [d 0]
     (print "d: " d)
    )
  )
)

jiahzhang avatar Apr 25 '24 15:04 jiahzhang

You miss a pair of parentheses in the let. But that is probably my fault, I didn't keep the documentation up to date (fixed that now too).

(load "example.vcd")
(in-groups '("something.something.")
  (print CG ":")
  (print SIGNALS)
  (whenever (&& #clk #reset_n)
    (let ([d 0])
     (print "d: " d))))

With the parentheses and the counter example trace I get:

something.something.:
("tb.overflow" "tb.clk" "tb.reset" "tb._tmp" "tb.dut.clk" "tb.dut.reset" "tb.dut.overflow" "tb.dut.counter")

LucasKl avatar Apr 25 '24 15:04 LucasKl

Runs now thanks. I'll close this issue.

jiahzhang avatar Apr 25 '24 16:04 jiahzhang

Great. If anything else comes up, feel free to contact me.

LucasKl avatar Apr 25 '24 16:04 LucasKl

Actually when I try to access a signal within the array of structs I just see a bunch of Nones. Any ideas? It works fine when I print like like an integer from the top-level -- not within the array (print #clocks)

jiahzhang avatar Apr 26 '24 20:04 jiahzhang

@LucasKl FWIW, this does work

(in-scope "something" (print #something))

so maybe something wrong with the frontend parsing?

jiahzhang avatar Apr 29 '24 20:04 jiahzhang

and this doesn't

(in-scope "something.something" (print #something))

jiahzhang avatar Apr 29 '24 20:04 jiahzhang

There are two systems for evaluating signals at different places. Scopes and groups. They work similarly but require different operators to resolve a signal.

If you use groups you need to use #signal, and if you use scopes you need to use ~signal.

So try either (in-scope "something.something" (print ~something)) or (in-group "something.something." (print #something)). Please note the added . for the group (scopes add the dot automatically).

LucasKl avatar Apr 30 '24 07:04 LucasKl

I don't think either works, are we allowed to nest in-group/in-scope within another in-groups for example? Also, in general, whether in-scope or in-group I can't access fields within a struct

jiahzhang avatar Apr 30 '24 15:04 jiahzhang

In WAL there are no structs, only signals from the waveform. How structs are mapped to signals is up to the simulator. If you can produce a minimal example, I can try to improve support for your use-case.

LucasKl avatar May 03 '24 07:05 LucasKl

It just looks like

struct obj {
  logic [2:0] something;
}

struct obj2 {
  obj data;
}

What's confusing is the SIGNALS represents this how I would expect (.'s). But it doesn't get picked up when running. Perhaps it would be helpful if it does some fuzzy search on available variable names within the scope and/or outside of the scope to figure out what the var name should look like in WAL.

jiahzhang avatar May 07 '24 20:05 jiahzhang

also why do undeclared signals return None values? Would it be better to throw an error? Let me know if you'd like help implementing these if you think they might take a while to add support for.

jiahzhang avatar May 07 '24 20:05 jiahzhang

Ok, I spend a little more time with SV arrays and structs. This is something which I have not worked with much in the past. I simulated the following code using Verilator:

typedef struct {
  logic [2:0] something;
} obj;

typedef struct {
  obj data;
} obj2;


module tb();
  obj2 data [0:1];

  initial begin
    $dumpfile("trace.vcd");
    $dumpvars;
    data[0].data.something = 3'b101;
    #10
    data[0].data.something = 3'b010;
  end
endmodule

And then got this vcd:

$version Generated by VerilatedVcd $end
$timescale 1ps $end

 $scope module TOP $end
  $scope module tb $end
   $scope module data[0] $end
    $scope module data $end
     $var wire  3 # something [2:0] $end
    $upscope $end
   $upscope $end
   $scope module data[1] $end
    $scope module data $end
     $var wire  3 $ something [2:0] $end
    $upscope $end
   $upscope $end
  $upscope $end
 $upscope $end
$enddefinitions $end


#0
b101 #
b000 $
#10
b010 #

This already mostly worked as expected. I only had to slighlty correct the handling of scopes names in commit b7972b7.

Now WAL behaves like this:

WAL 0.8.1
Exit to OS or terminate running evaluations with CTRL-C
>-> (load "trace.vcd")
t0(0) >-> SIGNALS
("TOP.tb.data<0>.data.something" "TOP.tb.data<1>.data.something")
t0(0) >-> SCOPES
("TOP" "TOP.tb" "TOP.tb.data<0>" "TOP.tb.data<0>.data" "TOP.tb.data<1>" "TOP.tb.data<1>.data")
t0(0) >-> TOP.tb.data<0>.data.something
5
t0(0) >-> (in-scope 'TOP.tb.data<0>.data ~something)
5
t0(0) >->

WAL will now also throw an error if a scope or group resolution leads to an undefined signal. Thanks for the pointer.

LucasKl avatar May 13 '24 14:05 LucasKl

Can you try the latest commit and let me know if that works for you? I have not used much "advanced SystemVerilog" constructs, so I am very happy to hear your comments.

LucasKl avatar May 13 '24 14:05 LucasKl

Works great now thanks

jiahzhang avatar May 13 '24 16:05 jiahzhang