Closed stnolting closed 5 months ago
Normally we had the .f file(s) in parallel with the RTL files, or if you have a lot of sub-dirs for RTL functions at the root. In our case we don't so just in the RTL directorty.
Here is a simple write up of what a .f (dot-f) file is from Icarus Verilog: https://iverilog.fandom.com/wiki/Command_File_Format. This is basically an industry standard right now, which is supported by all commercial tools and some open source EDA tools.
In our case I made quite a few .f files, such that I could add in features or not via .f as well.
Compile order really only matters for top level files. So for us that meant when you get to an entity that uses other entities it should be compiled after. In the case of the core it would be something like:
Normally we had the .f file(s) in parallel with the RTL files, or if you have a lot of sub-dirs for RTL functions at the root. In our case we don't so just in the RTL directorty.
So in this case this would be rtl
, right?
Here is a simple write up of what a .f (dot-f) file is from Icarus Verilog: https://iverilog.fandom.com/wiki/Command_File_Format. This is basically an industry standard right now, which is supported by all commercial tools and some open source EDA tools.
I like that format and I'm glad that comments are supported. That might help to make things a little less obscure. 😅
In our case I made quite a few .f files, such that I could add in features or not via .f as well. [...] Compile order really only matters for top level files.
How would be handle this here?
One core for each rtl sub-folder? Individual files for each of the processor_templates, system_integration wrappers, testbenches, ... ?
Note that GHDL has command elab-order
to "Display ordered source files". So, the compile order file can be autogenerated/autoupdated in CI instead of maintaining it manually. See https://ghdl.github.io/ghdl/using/InvokingGHDL.html#cmdoption-ghdl-elab-order.
@umarcor thats a good point :) The .f file discussion is less about GHDL and more about general portability. Its a talk @stnolting and I had in a different thread about synthesis tools and file reading order where I highlighted that in ASIC land we use these .f files to create portability between simulation and implementation.
In ASIC land, to ensure we don't end up implementing a chip that has different content than what we verify we use .f files. The advantage here is designers create .f files for their IP that contain the source files need to build the IP. When we integrate a given IP on a chip we include said .f files to build the entire thing and simulate it. But we also use the same .f files with out synthesis tools to ensure that when we implement the chip we use the correct source files.
Prior to .f files being a pseudo industry standard, every company had their own equivalent OR they sat down and did script reviews to ensure that the right files where used for chip build.. and yes I've sat through those :)
So what @stnolting is working on here is to create one or more .f file(s) that can be provided together with the core that makes it easier for others (like me) to quickly pick up the core and its IP and integrate it. Its less about making it easier with GHDL :)
I've copied in the set of .f files I use in this branch: https://github.com/mikaelsky/neorv32/tree/file-list-example Fair warning I haven't kept it up to date as I'm only using the core itself, everything else incl. bus-fabric is in-house custom verilog to fit our application.
For Vivado we have 2 scrips, a pre-parsing script that reads in the .f file chain and creates a flat list of just files. This is then read in using this simple .tcl addition:
# Define filesets
set vhdl_filelist {}
# Need to pre-process the .f files into 1 file with no comments etc.
# Read in fpga vhdl file list
set fp [open "./fpga_list.f" r]
while {[gets $fp line] >= 0} {
lappend vhdl_filelist $line
}
close $fp
add_files -norecurse $vhdl_filelist
set_property library neorv32 [get_files $vhdl_filelist]
The neorv32_top.f file is sorta the top level if you want the entire core with peripherals and everything. For test benches you would have e.g. a tb.f file that has the test bench code that then includes the neorv32_top.f file using -f/-F.
@mikaelsky I am not proposing to require users to call GHDL in order to get .f
files, but for NEORV32 developers to use GHDL to either keep those files up to date or check/test that those files are up to date.
As a rule of thumb, code files which need to be manually updated and are not tested do tend to get out of sync. Hence, for quality purposes they need to be either autogenerated or, if manually generated, they need to be automatically tested. GHDL is helpful in either case.
@umarcor sounds pretty neat :) I do like that it outputs the list in dependency order as that is one challenge I've faced when pushing the core through Genus (Synthesis). As VHDL is a 2nd class citizen in commercial tools the VHDL parsers have.. challenges. We get some odd-ball parsing errors (e.g. use string types) that was root-caused to be caused be the move away from component declarations in the code base (A move I support 100%) combined with the source files being read in out of dependency order.
We get some odd-ball parsing errors (e.g. use string types) that was root-caused to be caused be the move away from component declarations in the code base (A move I support 100%) combined with the source files being read in out of dependency order.
I also encountered this problem when working with some "non-mainstream" FPGA tools. It's a real nightmare 😅
As a rule of thumb, code files which need to be manually updated and are not tested do tend to get out of sync. Hence, for quality purposes they need to be either autogenerated or, if manually generated, they need to be automatically tested. GHDL is helpful in either case.
I like this idea. But would we implement that?
Let GHDL emit a file/hierarchy list within some CI workflow and then push that to main or open a dependabot-like pull request?
But one step after another.
At first we should try to integrate GHDL's elab-order
command in some script (main makefile?) to convert the output into something similar to the *.f
files provided by @mikaelsky. 🤔
Let GHDL emit a file/hierarchy list within some CI workflow and then push that to main or open a dependabot-like pull request?
I believe that's not necessary. It would be enough to just execute the target in the main makefile and check if the content changed. Similar to a linter. Don't need CI to automatically update the main branch, because that's something we prefer humans to do.
At first we should try to integrate GHDL's elab-order command in some script (main makefile?) to convert the output into something similar to the *.f files provided by @mikaelsky.
Yes, this is the main feature I'm thinking about. That would already allow to automatically test if something changed and take action if needed.
That would be a really cool feature, I think.
It would make setting up the rtl files much easier and we could finally drop all the hard-to-follow hierarchy stuff in https://stnolting.github.io/neorv32/#_vhdl_file_hierarchy :wink:
@mikaelsky has suggested (in some issue I cannot find right now) to add a "
*.f
" file that list all required HDL files in their according compile order. This file could be consumed by synthesis tools to ease correct project setup.Open questions:
As always, help with this is highly appreciated! :wink: