Skip to content
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

Closed
veripoolbot opened this issue Jul 19, 2017 · 25 comments
Closed

Support for interfaces in top level ports #1185

veripoolbot opened this issue Jul 19, 2017 · 25 comments
Labels
resolution: wontfix Closed; work won't continue on an issue or pull request type: feature-IEEE Request to add new feature, described in IEEE 1800

Comments

@veripoolbot
Copy link
Contributor


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!

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2017-07-23T01:51:45Z


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.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2019-10-09T01:03:12Z


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.

@veripoolbot veripoolbot added resolution: wontfix Closed; work won't continue on an issue or pull request type: feature-IEEE Request to add new feature, described in IEEE 1800 labels Dec 22, 2019
@WonHoYoo
Copy link

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?

@wsnyder
Copy link
Member

wsnyder commented Feb 14, 2021

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.

@WonHoYoo
Copy link

Sorry for late comment. Could you give more details on what manual version is?

@wsnyder
Copy link
Member

wsnyder commented Feb 19, 2021

I mean make a full forking and lint-clean example by hand of what you think eventually verilog-mode should automate.

@WonHoYoo
Copy link

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.
The Top module in Below code would be SYSREG_WRAP.

/* 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

@wsnyder
Copy link
Member

wsnyder commented Feb 25, 2021

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

@WonHoYoo
Copy link

Thanks for your link. But here is one question.
Most hardware engineer uses the interface for grouping their signal and see the transaction as packet. With those hierarchy view, the debug could be efficient for them. But with AUTOINOUTMODPORT method, the hierarchy view is erased on the WRAPPER side. Is the AUTOINOUTMODPORT script intending to just erasing the structure and flattening input and output signals?

@wsnyder
Copy link
Member

wsnyder commented Feb 26, 2021

Yes, it's intentionally removing the grouping, same as your wrapper example does.

@WonHoYoo
Copy link

WonHoYoo commented Mar 5, 2021

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.
My question is whether the error message on this is intended.

@wsnyder
Copy link
Member

wsnyder commented Mar 5, 2021

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.

@WonHoYoo
Copy link

WonHoYoo commented Mar 5, 2021

Hmm I actually thought having Interface on top module is acceptable on the Verilog Standard, but it seemed not.
In aspect of flexibility to simulate, making a wrapper could be helpful for developers but this could lead to misunderstanding as I do. Wouldn't it be better to update the verilator diagnostic message on this particular case? Could be better mentioning the IEEE Standard for better understanding the background on this issue.

@kkanhere
Copy link
Contributor

kkanhere commented Jun 2, 2022

Can we have this feature only for linting? Because it is nice to use verilator with languageservers for quick file linting.
But presently, because of lack of support for top level interfaces, I have even seen verilator crash with a bunch of "Parent instance's interface is not found" errors.

@wsnyder
Copy link
Member

wsnyder commented Jun 3, 2022

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.

@kkanhere
Copy link
Contributor

kkanhere commented Jun 3, 2022

I can give it a try. What would the approach be like? Will be good to have a rough list of tasks to do.

@wsnyder
Copy link
Member

wsnyder commented Jun 12, 2022

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.

@kkanhere
Copy link
Contributor

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?

@wsnyder
Copy link
Member

wsnyder commented Jun 15, 2022

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).

@kkanhere
Copy link
Contributor

But parameters don't necessarily need to have defaults. Or are you talking about defaults for the respective data types?

@wsnyder
Copy link
Member

wsnyder commented Jun 15, 2022

If an interface parameter doesn't have a default I don't see any way to make it work,

@kkanhere
Copy link
Contributor

Is there any mechanism to black box those interface instantiations? Will the linter be fine with a black box?

@wsnyder
Copy link
Member

wsnyder commented Jun 16, 2022

I expect black boxing an interface would be difficult, as it currently needs to look inside to resolve any dotted references.

@kkanhere
Copy link
Contributor

kkanhere commented Aug 17, 2022

How does verilator linting handle top level parameters without a default value? I am guessing that is supported.
If it is, maybe I can create a wrapper that instantiates the interface with parameter initialization from the wrapper parameters. i.e. for the below code

// 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?

@wsnyder
Copy link
Member

wsnyder commented Aug 17, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
resolution: wontfix Closed; work won't continue on an issue or pull request type: feature-IEEE Request to add new feature, described in IEEE 1800
Projects
None yet
Development

No branches or pull requests

4 participants