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 for interfaces in top level ports #1185
Comments
Original Redmine Comment Interfaces work in Verilator by creating a variable on both the upper and lower scope that links into an instantiated interface (CELL in the AST). The top doesn't have any upper scope to contain this. The other problem would be how would you access the variables from C? Verilator doesn't presently create structs that C can use, so it's not obvious what this would look like. You could of course make wrapper code that flattened the interfaces into normal signals for C. I realize this isn't clean of course. |
Original Redmine Comment This is unlikely to be supported in the medium term due to the complexities of mapping into C++. A wrapper is suggested instead. If someone wants to contribute a fix, we can discuss. |
I guess this feature seems outdated features, and I would love to contribute for simulating above. My situation is I need to simulate the AXI Interface with Interface AXI_BUS on top module. And I also need the C variables to access the Interface modports. Would it be able to get any information what I have to see for further feature enhancement on it? |
I still think the most reasonable way is to manually (or with Verilog AUTOS) make a Verilog wrapper that converts the interface signals to normal I/O which you then attach to with C++. The Verilator enhancement would be to make this wrapper automatically when an interface is on the top level. If you want to look into this let's first agree what the manual version would look like and get that working, then the Verilator code would land in an improved V3LinkLevel::wrapTop. |
Sorry for late comment. Could you give more details on what manual version is? |
I mean make a full forking and lint-clean example by hand of what you think eventually verilog-mode should automate. |
I had checked the verilog top module. Using the -lint-only options with discarding some warnings on "Undriven, DECLFILENAME, UNUSED" below is my result. I guess reusing the name user had written in their design might be better. /* verilator lint_off DECLFILENAME */
/* verilator lint_off UNDRIVEN */
/* verilator lint_off UNUSED */
interface APB;
logic [31:0] PADDR;
logic PSEL;
logic PENABLE;
logic PWRITE;
logic [31:0] PWDATA;
logic [31:0] PRDATA;
logic PREADY;
modport master (
output PADDR, PSEL, PENABLE, PWRITE, PWDATA,
input PRDATA, PREADY
);
modport slave (
input PADDR, PSEL, PENABLE, PWRITE, PWDATA,
output PRDATA, PREADY
);
endinterface
/* verilator lint_on DECLFILENAME */
module SYSREG(
clk,
resetn,
APB.slave slave
);
input clk;
input resetn;
endmodule
module SYSREG_WRAP(
clk,
resetn,
APB_PADDR,
APB_PSEL,
APB_PWRITE,
APB_PWDATA,
APB_PRDATA,
APB_PREADY
);
input clk;
input resetn;
input [31:0] APB_PADDR;
input APB_PSEL;
input APB_PWRITE;
input [31:0] APB_PWDATA;
output [31:0] APB_PRDATA;
output APB_PREADY;
APB slave;
assign slave.PADDR = APB_PADDR;
assign slave.PSEL = APB_PSEL;
assign slave.PWRITE = APB_PWRITE;
assign slave.PWDATA = APB_PWDATA;
assign APB_PRDATA = slave.PRDATA;
assign APB_PREADY = slave.PREADY;
SYSREG sysreg_wrap(
.clk,
.resetn,
.slave
);
endmodule |
BTW to make generating such wrappers more (but not fully) automated, see AUTOINOUTMODPORT in Verilog-Mode, https://www.veripool.org/wiki/verilog-mode/Verilog-mode-Help#verilog-auto-inout-modport |
Thanks for your link. But here is one question. |
Yes, it's intentionally removing the grouping, same as your wrapper example does. |
Recently, I tried on commercial simulator with the top module having interface port. And it seems they output the Error message on using the interface as input and output. Which seems kinda reasonable for the verilator to print out the error message with no support. |
The message is intended. For other tools my reading is IEEE 23.3.3.4 says it must be connected. For Verilator one could argue it could still support interfaces on the top as the interface will be connected "above" the Verilated model, but this is currently unsupported. |
Hmm I actually thought having Interface on top module is acceptable on the Verilog Standard, but it seemed not. |
Can we have this feature only for linting? Because it is nice to use verilator with languageservers for quick file linting. |
I can see the value for linting. @kkanhere is this something perhaps you'd be willing to work on? Interfaces are painful to implement so might be a fair bit of work that is unlikely to happen soon otherwise. |
I can give it a try. What would the approach be like? Will be good to have a rough list of tasks to do. |
I'm not sure what issues this will hit, which is part of the complication. First is to make a test_regress test case that have the top level interface, using the lint() call, copy one of the existing lint tests. If this is only for lint, probably it's easiest to have Verilator instantiate the interface for you in the wrapper module it creates in V3LinkLevel. Then it should all hook up ok. There will likely be some false warnings due to doing this, if so when the wrapper interface is made those warnings would need to be suppressed (change the FileLine and call warnOff - see examples in V3Force.cpp. |
I have been looking at verilator's code and thinking about the approach of instantiating the interface in the wrapper module. I am unable to resolve how we would go about instantiating the interface. For example an interface could be parametrized, so what parameters to use while instantiating it? |
Presumably we'd have to use whatever the defaults are for the parameters, as we do for top level modules with parameters (unless -G given at runtime). |
But parameters don't necessarily need to have defaults. Or are you talking about defaults for the respective data types? |
If an interface parameter doesn't have a default I don't see any way to make it work, |
Is there any mechanism to black box those interface instantiations? Will the linter be fine with a black box? |
I expect black boxing an interface would be difficult, as it currently needs to look inside to resolve any dotted references. |
How does verilator linting handle top level parameters without a default value? I am guessing that is supported. // some_module.sv
module some_module (some_if.master some_i);
endmodule
// some_if.sv
interface some_if #(parameter DATA_WIDTH) ();
logic [DATA_WIDTH-1:0] some_data;
endinterface add a wrapper module some_module_wrapper #(parameter DATA_WIDTH) ();
some_if #(.DATA_WIDTH (DATA_WIDTH)) some_i ();
some_module some_module_I (.some_i (some_i));
endmoule If it is possible to edit the AST to introduce such a wrapper, then I believe linting could be supported for top wrapper. What do you think? |
Verilator will give an error I believe on a parameter without default on the top level. So it is probably reasonable to do likewise for the interface parameter example. Editing the Ast to do the insertion is reasonable, look at wrapTop for an example. |
Author Name: Kevin Kiningham (@kkiningh)
Original Redmine Issue: 1185 from https://www.veripool.org
I'd like to add support for interfaces in top level ports. A simple test cast:
@interface bus_if(input wire clock);
logic data;
modport slave(input data);
modport master(output data);
endinterface
module top(bus_if.slave bus);
endmodule@
Current git HEAD (ca26596) currently fails with the following:
kkiningh@kkiningh:~/Workspace/$ ./verilator/build/bin/verilator test.sv -cc
%Error: test.sv:8: Unsupported: Interfaced port on top level module
%Error: test.sv:8: Parent cell's interface is not found: bus_if
%Error: Exiting due to 2 error(s)
%Error: See the manual and http://www.veripool.org/verilator for more assistance.
%Error: Command Failed /home/kkiningh/Workspace/verilator/build/bin/verilator_bin test.sv -cc
How much work would it be to support this feature? Can you give me a few hints on how to get started? I've looked in verilator/src/V3LinkParse.cpp and can see where the error is generated but cannot figure out how to proceed. Also, can you expand a bit on what the comment on line 198 is talking about ("What breaks later is we don't have a Scope/Cell representing the interface to attach to")?
Thanks!
The text was updated successfully, but these errors were encountered: