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
Support "interface" and "endinterface" keywords #102
Comments
Original Redmine Comment I have created a test and edited verilog.l and verilog.y by adding to yINTERFACE and yENDINTERFACE. So, I think I just need instructions on how to go about adding the grammar rules. Thanks! |
Original Redmine Comment Obviously this is a good chunk of work. I'd urge you to do it in little feature pieces and it won't seem quite so daunting. Create test cases - you'll want to insure they work on another simulator. Add keywords to verilog.l Follow how the bison rules related to yINTERFACE work in the verilog-perl parser. Copy(ish) them into verilator. You'll want to see how verilator does module ports. I think it'll be mostly the same, but there might be some differences. Make the productions ({...} in bison) just be empty {} and get the test case to parse ok. Might want to "git commit" at this point. Create new AstInterface type in V3Ast.h. AstModule is probably a good start, but most the accessors don't need copying - I think you just need a list of pins will do. (A good reference of what is needed is to look at the language specification VPI for interface, though Verilator doesn't strictly do what it says.) Something like this
Also you need to know when an interface is used. It would be nice to define and use an AstInterfaceRef, but I think the language doesn't allow you to know the difference between a cell and interface until the names are linked with their definitions. So create AstCell and AstPin structures when an interface is used. (To simplify your life, you might want to test that interfaces can be parsed and completely get through verilator before trying to use an interface.) V3Link then would change AstCells to AstInterfaceRef's. Change the rules to create a new AstInterface + AstCell at the appropriate point, then signals under the interface will get attached to it. See how modules work as an example. When you run verilator with --debug, the .tree files will give you a good idea what's being formed; check the new interfaces seem to have the right info. Another good git commit point. Now to do something with the interfaces. I haven't thought a lot about it, but think they can get eliminated relatively early by pushing them into the modules that use them. Grep for "AstModule" and you'll get an idea where the code needs to be improved. Correlate this to the list that steps are executed in Verilator.cpp - probably everything after V3Inline is called won't need to know about interfaces. Some notes V3Link needs to remember the interface names, and when it sees an AstCell see if the name matches an interface. V3LinkCells likewise; it's legal to auto-find "interface.v" if you reference "interface" but haven't declared it yet. V3Dead should remove unused interfaces V3Param needs to resolve parameterized interfaces V3Inline is what inlines modules. I'd say use this as an example to make a new V3Interface.cpp that takes in the interfaced tree and flattens the interfaces signals into the modules. Run this before V3Inline by calling it in Verilator.cpp. Again the key is to use --dump to see the .tree that comes in and goes out. |
Original Redmine Comment Attaching a very basic testcase for interfaces that works in another simulator. |
Original Redmine Comment Hi Wilson, I'm working on getting the parser working for the attached testcase, the interface counter_io looks like:
and when the interface is instantiated in the counter module:
However when counter is instantiated in the module t, it sees the interface as just another pin:
The three errors I'm getting are:
I don't think (3) is a problem because the cell name will disappear later on. To solve (2), I think I need to expand interface cells to include PIN and VAR nodes, can this happen in V3Link? I'm not sure about (1), do I need to find some way of replacing the PIN with an interface cell and link them together? Does it sound as if I'm going along the right lines here? |
Original Redmine Comment Hmm, I'll make a stab, but not having done it before I suspect the approach will need adjusting as you discover more. I guess interfaces are both module like and also data-type (DType) like, in that they can be accessed like structures. (Though cells also work this way of course. In retrospect cells should probably have been a instantiation of a Module datatype.) Looking at counter's c_value, I'm wondering if it's right to have c_value as a cell. I think it might be closer to be a var (or new AstNode type) with dtype that references the interface (pointing to a InterfaceDType similar to RefDType) Then in t, it would remain a pin that connects to counter's c_value var, just as normal; what's special is it connects to cl.c_value, who's dtypep() is InterfaceDType. t.cl would still be a Cell (or InterfaceCell if you want to abstract it), if you need to know the difference V3Link could change from Cell to InterfaceCell. Later V3Inline/V3Cell would detect the pin's connecting cl_data->InterfaceCell->counter_io to cl->counter->Var->dtype->InterfaceDType->counter_io. Both are counter_io's so it's right. Also, give some thought to how modports would fit into this scheme. |
Original Redmine Comment Three patches attached to add support for interfaces and modports. There are a number of open issues with these patches:
|
Original Redmine Comment I applied patch 2, user5, as I didn't see a easy work around, and there's enough visitors squeezed into 4 that it's probably useful. I also applied 3, it seems safe in isolation from #1. The change I'd like to see to 1 is to not call ParseResolve twice; this will cause problems. Instead have V3LinkCells understand how to find interfaces (take the code you added from ParseResolve). If I'm missing some key flaw let me know. |
Original Redmine Comment Wilson Snyder wrote:
I'm assuming by ParseResolve you mean the second call to V3LinkCells::link(). The second call to V3LinkCells is there because this Cell is only created in V3LinkParse. This is only needed in the case where there is an interface in the port list of a top-level module. I've attached a testcase for this, if module t wasn't the top-level, the interface would be created as a cell elsewhere and we'd just link to it. But because t is a top-level module, the cell doesn't exist yet. I could probably create the Interface Cell inside V3LinkLevel instead of V3LinkParse but that's still too late for V3LinkParse. I might be able to create a new Cell for every interface in a port, mark them as temporary, then remove all of them outside the top-level later but that doesn't feel right either. |
Original Redmine Comment Ignore my last update. The new Cell for the top-level interface is created from an InterfaceDType after it has been linked, so I can just take the NodeModule pointer from there. I've attached a patch to go on top of 0001-Support-interfaces-and-modports.patch. The testcase included only does basic linting but needs to be extended to check trace and probably connectivity with a custom .cpp file. |
Original Redmine Comment Attached is a new patch set with my edits; please build off that, it replaces the previous patches.
I try to avoid CRELINE() and instead use a fileline from a token where
I replaced this with
What you had was a NOP. Although I'm a bit worried about doing this at
Added statistic so we know it didn't inline due to unsupported interfaces.
Put common code into a function. Now the questions
I'm leaning back towards your original suggestion of releasing without |
Original Redmine Comment Wilson Snyder wrote:
It seems to me like modports just assign an input/output to a Var and the same
With what I know now, I think this was the wrong way to do it. It's pretty ugly
Agreed, I think the Inst/Scope/LinkDot stages will change a lot and it's not as |
Original Redmine Comment Interface support added to git towards 3.848. Interfaces and modports, including with generated data types are supported. Generate blocks around modports are not supported, nor are virtual interfaces nor unnamed interfaces; these seem consistent with synthesis limitations. |
Original Redmine Comment In 3.850. |
Author Name: Alex Duller
Original Redmine Issue: 102 from https://www.veripool.org
Original Date: 2009-07-16
Original Assignee: Byron Bradley (@bbradley)
Add support for SystemVerilog interface and endinterface keywords
The text was updated successfully, but these errors were encountered: