Open fl4shk opened 4 years ago
This is pretty interesting! I had never really considered that classes could be used in synthesizable code. This is something I can add.
It's the only way to parameterize a struct placed onto a port in SystemVerilog
Isn't it possible to use a struct from a parameterized interface modport? This might be a little clunky, but I think it might be another way to achieve a similar result.
I am unsure if it's possible to do what you've suggested, though it does sound reasonable.
What seems impossible with SV is the ability to use interfaces as namespaces. The SV standard people seem to have intended that classes be usable for that, but as I mentioned, I don't believe any synthesis tools support that use case for classes. They give up at the sight of the class
keyword, despite this specific use case being mentioned in the SV standard.
Also, I made a mistake in showing the use of classes as namespaces: ::
is used rather than .
. The enum
usage should have been like so: AluNs(.WIDTH(WIDTH))::OP_ADD
rather than AluNs(.WIDTH(WIDTH)).OP_ADD
.
There may be a relatively straightforward way to add support, provided that any identifiers in the class parameter bindings only refer to declarations at the top level of the module, rather than localparams defined within a procedure or generate block. Do you think this would still satisfy most use cases?
I think it'd definitely be best, in general, to also support the localparams defined within a procedure or generate block. Many, many use cases would be solved with just top level parameters and localparams, though, from what I can tell. Here is why: you can just move the parameter to the top level of the module, at least for procedures. Generate blocks might want to have a localparam based upon the loop variable, though, which may cause a problem in some cases?
Sorry for the delay over here! I have been making progress behind the scenes and have pushed what I've got so far. I've added initial support for using classes in this way, but there is a key limitation. While these class scoped identifiers can be used in any context, parameter overrides can only refer to declarations the global or module scope. Please let me know if it works for you!
As of 3955c47e7a0d84e599ef561e4f6a62f456811fc9, the parameter overrides can refer to declarations in a local generate scope. I'm still eager to see if this implementation is working as you'd expect it to!
Hello again!
To add to this current discussion on using classes as namespaces, it would be really nice if the following was supported.
class adder #(
parameter type T = logic[31:0]);
static function T operate(T operand0, T operand1);
return operand0+operand1;
endfunction
endclass
module reduce(clock, reset, operand0, operand1, result);
parameter type T = logic[31:0];
parameter type OPERATION = adder;
input logic clock, reset;
flow.receive operand0, operand1;
flow.send result;
always_ff @(posedge clock) begin
if (reset) begin
result.valid <= 0;
end else begin
result.valid <= operand0.valid&&operand1.valid;
end;
result.data <= OPERATION#(.T(T))::operate(operand0.data, operand1.data);
end;
endmodule
The main thing is supporting static functions and tasks so that even operations can be abstracted from modules. This actually builds in Vivado 2020.2.
EDIT: Oops. There was a mistake with the example. I made the correction. I meant to use OPERATION
to call the add operation.
I've just added proper support for static methods. sv2v doesn't yet support class types as parameters (parameter type OPERATION = adder;
). The current architecture surrounding the elaboration of type parameters and classes does not lend itself well to this extension, but I can look into some options.
Pulled down the changes and I can see that the static functions convert. Thanks again!
Here is a feature that I've yet to see supported in synthesis of SystemVerilog that I think would be useful, the ability to use a class as a namespace.
It's the only way to parameterize a struct placed onto a port in SystemVerilog, and it's explicitly mentioned as the way to do that in the SystemVerilog standard. I've attached an example of what I mean.
alu_module.txt