New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Interface getter functions for interface parameters return default (not overridden) value #996
Comments
Original Redmine Comment Good hunting. |
Original Redmine Comment This works and doesn't break anything else: https://github.com/toddstrader/verilator-dev/tree/intf_param_getter I can clean it up, but I first wanted to discuss to see if there was a more elegant way to do this. Some things I have learned along the way:
Using all of this, the solution just tries to connect the dots. Is there something simpler that could be done here? If not, I'll clean this up and re-post. |
Original Redmine Comment The test doesn't work even with the 2015.09 version of VCS, which is generally fairly aggressive language wise. Are you sure this is legal syntax according to IEEE? I'm generally reluctant to support stuff that is only in a single commercial simulator.
|
Original Redmine Comment I'm not entirely sure. Sometimes the LRM reads more like a story than a spec. I think this is one of those instances. Section 13.4.3 gives a list of rules for a constant function. getFoo() abides by all these rules, except for the fact that getFoo() isn't in the module's scope that is calling it. This detail isn't explicitly mentioned in section 13.4.3, but the general case is obvious. Clearly you can't have two modules, each with localparams that are defined using hierarchical references to each other. If you did this you'd have an elaboration loop. Interfaces create scope in the same way that modules do (section 23.9), so it would stand to reason that you couldn't treat i.getFoo() as a constant function. And sadly, section 25 on interfaces doesn't discuss the possibility of using interface functions to define parameters or localparams. However, I'd argue that this information can already be leaked from the interface by declaring a signal in the interface like so:
And then doing this in a module which gets the interface:
Which is effectively the same thing as i.getFoo(). It side-steps the rule about constification of hierarchical references, but it does so because with interfaces, the constant values are already paramed by the time we get to the module which refers to an interface. Of course, this is more an argument for the LRM working group, rather than you. Instead of all this, we can take this direction: http://www.edaplayground.com/x/UWi Which works with VCS and ModelSim. There's still the question of function constification, but now we have two commercial simulators that agree on this. Verilator appears to have two problems with this:
What do you think? Would you prefer i.FOO over i.getFoo()? I can switch gears and implement the former which agrees with more EDA tools. |
Original Redmine Comment I'd suggest we should side with the majority and use the eda playground example. |
Original Redmine Comment Sounds like a plan. I'll start working on it. |
Original Redmine Comment One other thing. We should probably make interface functions non-constible outside of the interface to match the other simulators' behavior as well. The current always-constifies-to-default behavior is confusing. Wilson, do you agree? I'll probably break this issue up into a few tasks. |
Original Redmine Comment Yes, but that's a separate mostly orthogonal task, as you noted. |
Original Redmine Comment Looking at this again: When I run t_interface_parameter_access.pl as-is, I get:
This happens because during param(), VarXRef varps are nuked: First off, I don't follow the comment "// Needs relink, as may remove pointed-to var". Can you explain why the VarXRef varps are being removed at this stage? Secondly, I guess I could try to preserve the varps for VarXRefs that are only pointing into interfaces. I don't know what side effects that might have, but even if that were benign, we still wouldn't have all the information we need. This is because the VarXRef we're assigning to THE_FOO
currently points at the interface's parameter (0xadca90)
not the parameter from the the_interface cell (0xae2b00).
Which means that best case scenario, we'd still be getting the default parameter value and not the value from the specific interface we're referencing. I'm still digging, but any advice on how to proceed would be appreciated. Also, as a side note, I noticed that Riviera likes i.getFoo() and does not like i.FOO: While I believe the two are morally equivalent, I do agree that i.FOO is probably more defensible per the LRM. But if all else fails, maybe we can consider i.getFoo() again. |
Original Redmine Comment OK, I think I just rubber ducked this. Please ignore the previous post. I've got something which is passing now. I need to spend some time cleaning up the mess I made, but I think it's pretty close. |
Original Redmine Comment Ready to go: Passes all Verilator tests and our internal tests. |
Original Redmine Comment Great! Thanks again for good work. Pushed to git towards 3.903. |
Original Redmine Comment In 3.904. |
Author Name: Todd Strader (@toddstrader)
Original Redmine Issue: 996 from https://www.veripool.org
Original Assignee: Todd Strader (@toddstrader)
https://github.com/toddstrader/verilator-dev/tree/intf_param_getter
See: t_interface_parameter_getter
The test doesn't work with ModelSim (at least the crusty, old version I'm stuck on right now), but I can confirm that this functionality works in Quartus. In any case, I believe it's clear that the function should return the overridden value. I'll start looking into the solution.
The text was updated successfully, but these errors were encountered: