Normalizing struct with signal reference causes RuntimeError
Hi all,
I was experimenting with some more exotic ways to parametrize a register and ran into some issues here. I did not get any parser errors so I suppose that it should be correct syntactically. It's not really a big issue for me but since I did not find this on your limitations page I thought I might as well open an issue in case this is unknown to you.
And maybe I just misread the RDL spec, since value_normalization.py says that I
# Should never get [t]here
🙂
This is the RDL I tried to compile:
signal {activelow; async;} rst_async_n;
signal {activehigh;} rst_sync;
struct rst_struct {
signal rst;
};
reg myReg #(rst_struct RST_SIGNAL = rst_struct'{rst: rst_async_n}) {
field {
resetsignal = RST_SIGNAL.rst;
} data[0:0] = 0;
};
addrmap paremeters {
myReg reg0;
myReg #(.RST_SIGNAL(rst_struct'{rst: rst_sync})) reg1;
};
This is the runtime error I am seeing:
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/compiler.py", line 385, in elaborate
walker.RDLWalker(skip_not_present=False).walk(
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/walker.py", line 121, in walk
self.walk(child, *listeners)
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/walker.py", line 121, in walk
self.walk(child, *listeners)
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/walker.py", line 123, in walk
self.do_exit(node, listener)
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/walker.py", line 172, in do_exit
listener.exit_Component(node)
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/core/elaborate.py", line 578, in exit_Component
extra_type_name_segments.append(inst_parameter.get_normalized_parameter())
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/core/parameter.py", line 65, in get_normalized_parameter
return self.name + "_" + normalize(self.get_value())
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/core/value_normalization.py", line 24, in normalize
return normalize_struct(value)
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/core/value_normalization.py", line 112, in normalize_struct
norm_elements.append("%s_%s" % (member_name, normalize(member_value)))
File "/usr/lib/python3.9/site-packages/systemrdl_compiler-1.20.0-py3.9-linux-x86_64.egg/systemrdl/core/value_normalization.py", line 33, in normalize
raise RuntimeError(value)
RuntimeError: <systemrdl.rdltypes.ComponentRef object at 0x7f91bdd93520>
The problem seems to be related to the fact that a signal is being used in the struct. When replacing the signal with a string, everything works fine:
signal {activelow; async;} rst_async_n;
signal {activehigh;} rst_sync;
struct rst_struct {
string rst;
};
reg myReg #(rst_struct RST_SIGNAL = rst_struct'{rst: "test"}) {
field {
//resetsignal = RST_SIGNAL.rst;
desc = RST_SIGNAL.rst;
} data[0:0] = 0;
};
addrmap paremeters {
myReg reg0;
myReg #(.RST_SIGNAL(rst_struct'{rst: "test2"})) reg1;
};
I do think that it is allowed to reference signals in a struct since Section 6.3.2.1.2 of the SystemRDL 2.0 book says that
Structs may include all of the types defined in Table 7.
and Table 7 lists instance references.
Good find!
This is technically not supported. The SystemRDL spec has a habit of contradicting itself in a few sections. I write about this specific situation here: https://systemrdl-compiler.readthedocs.io/en/latest/dev_notes/rdl_spec_errata.html#inconsistent-definition-of-the-ref-type-keyword
Even though the ref type is listed in Table 7 and allows use of references in structs, the spec contradicts this later. When discussing parameters, clause 5.1.1.2-e explicitly states that references of any type cannot be used, even inside a struct:
e) Component instance references shall not be used as parameter values (either directly or as part of an aggregate type).
Regardless of any of that, you definitely found a bug! The compiler should not have thrown an exception like that. I'll look into cleaning up the error handling here. It might be easier for me to fix the underlying issue, and therefore ignore the super odd restriction that clause 5.1.1.2-e imposes. I never really understood why they did that.
Cool, thanks for elaborating on why the compiler behaves like it does, pretty clear.
Next time before filing an issue I will first try finding the reason for that particular behavior in your Spec Errata; I remember reading it in the past but kind of forgot about its existence again. I did indeed notice that there are unfortunately a couple of contradictions and/or vague definitions in the spec.
Finally got around to fixing this one. v1.25.5.
Thanks again for reporting this one. Despite it being a simple error case cleanup, it is worth fixing.