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

Future ideas and planning #2

Open
rodrigomelo9 opened this issue Jan 19, 2021 · 10 comments
Open

Future ideas and planning #2

rodrigomelo9 opened this issue Jan 19, 2021 · 10 comments

Comments

@rodrigomelo9
Copy link
Contributor

Hi. Some ideas.

I think that the boardname_ prefix in each pin name is undesirable:

  • The boardname is already in the directory of the constraint file.
  • Avoiding the boardname, a change of board is easiest (or a copy & paste of the top-level needs less changes).
  • Is somebody realy loves to have the boardname as suffix, it can be added when generated (assuming the alternative of a YAML file).

Moreover, the pin names of each board should be identical for the same purpose (for ex, I saw Arty_GPIO_LED[6] and LED0) (in case of leds, swithces and push-buttons, maybe we can have the individual and vector versions).

@umarcor
Copy link
Member

umarcor commented Jan 19, 2021

Hi @rodrigomelo9!

The decision for adding the board name to the top-level port names comes from the knowledge in the Ada/VHDL communities: explicit is better than failing. You are correct that the board name is already in the directory, and the naming of the directory is non-trivial, since that's used by other projects submoduling this repo. However, when a new board or variant is added, it is a very easy human mistake to forget checking all and each of the ports. Having the board name hardcoded in the constraint files allows finding files copied raw. Otherwise, simulation might succeed and someone might program a board with a pinout that does not match! We absolutely don't want that.

Avoiding the boardname, a change of board is easiest (or a copy & paste of the top-level needs less changes).

That is trivial, since the board name can be easily replaced with any editor or with sed. If the change involves another board with the same device, it might feel unnecessarily complex to rename the ports. I do agree with that. However, we need to look at the big picture here:

We want "changing the board" or "adding support to a new board in an existing HDL project" to require a similar ammount of effort, regardless of which boards you supported already. Typically, the effort for doing so is related to reorganising the sources for moving all device-specific modules out of the core, finding specific hard-ip instantiation replacements, etc. Moreover, port names might not be the same, since we don't enforce that (although it's desirable and we do recommend so). Renaming the board name in the top-level port names is the least of the problems when adding support for a new board 😉!

Therefore, this repository is expected to be submoduled and used along with sources organised in four groups:

  • board/boardname/
  • device/devicename/
  • src/
  • test/testframework/

See, for instance, https://github.com/dbhi/vboard/tree/main/vga. Naturally, each project is free to organise those sources using any structure, and they can use one or many HDL sources (in any language) in each group. However, the overall idea must be preserved. In that conception, adding a new board involves potentially adding sources to boardname, devicename and test/*, so the time spent in editing a single file in boardname is negligible.

Overall, we want this repository to be appealing and used not only by "new generations" of hardware designers (say hackers, hobbyist and software people diving into the lowest level) but also to seasoned hardware designers. The "explicit before implicit" mantra is very important in the hardware industry, and we need to leverage that for good reason. Precisely, all the sources for non open source boards in this repository were donated (copied from) VLSI-EDA/PoC: ucf. And the reference project layout explained above is based on PLC2/Solution-StopWatch. @Paebbels is an expert in VHDL and FPGAs, who authored PoC at the University of Dresden and he is a trainer at @PLC2, as well as the vice-chair of the VHDL Analysis and Standardization Group (VASG, IEEE P1076). This it not meant to be an ad-hominem argument, but for explaining that the workflows proposed here are the result of how these resources were/are taught and used for many years.


Is somebody realy loves to have the boardname as suffix, it can be added when generated (assuming the alternative of a YAML file).

This is a different proposal, and I do agree with it; however, as an opt-out feature instead of an opt-in. If data/information is defined in YAML format, we can use anchors and aliases for defining common features in an abstract way, and then build the specific definition of the constraints of each board based on those (while maintaining a declarative approach). Adding/removing the board name when constraint files are generated is trivial, once the YAML data exists. Moreover, at that point, we might avoid having *.pcf, *.xdc, etc. in this repository. We might check in the YAML sources and the generator only. Then, users would use it as tool for generating constraints in their projects, instead of having this added as a submodule. We might publish releases for those who want to keep using constraint files as defined here. Anyway, those steps are too far yet. The YAML format needs to be defined first.

As referenced in the readme, there is already some duplication. Apart from your fpga_lib, Litex/migen/nmigen tools are used in SymbiFlow/Antmicro, and some of those do include the same information provided in this repo. There is also FuseSoC, which might potentially have this repo embedded in the CAPI format/syntax. My current perception is:

  • fpga_lib has a good selection of languages (YAML and Python), and the purpose is almost the same as this repo, but it is more of a concept than a ready-to-use solution. Very few boards are supported (https://github.com/INTI-CMNB-FPGA/fpga_lib/tree/master/boards), which makes it difficult to evaluate the suitability for most of the open source boards used nowadays.
  • litex-boards is also based on Python and it supports a much larger list of boards already (https://github.com/litex-hub/litex-boards/tree/master/litex_boards/platforms). However, data is defined in Python directly, it's not read from a YAML file. At the same time, LiteX is a subset of the community. It can be enhanced for reading YAML files, but the Python interface is likely specific for migen/nmigen. It'd be interesting to evaluate whether that can be isolated, and how does it compare to fpga_lib's script(s).
  • FuseSoC/edalize is the natural open source consumer of these resources, since CAPI is based on YAML files. *.core files are to be used for traditional HDL projects using Verilog and/or VHDL, so it would make sense for users to specify target board names and the interfaces they want to use; then have the constraint files retrieved or generated by FuseSoC. That is, FuseSoC/edalize might import the Python module that results from comparing/combining fpga_lib's and litex-board's constraint management features. That same Python module might be used by PyFPGA, pyIPCMI, tsfpga, Xeda, etc.

There is this nice joke about Europe:

Heaven in Europe is where

  • the English are the policemen
  • the French are the cooks
  • the German are the mechanics
  • the Italians are the lovers
  • and the Swiss organize everything

Hell in Europe is where

  • the German are the policemen
  • the English are the cooks
  • the French are the mechanics
  • the Swiss are the lovers
  • and the Italians organize everything

Let's try to build the heaven of open source eda resources by understanding what each of us is good at 😄


Moreover, the pin names of each board should be identical for the same purpose (for ex, I saw Arty_GPIO_LED[6] and LED0) (in case of leds, swithces and push-buttons, maybe we can have the individual and vector versions).

I don't think that individual versions are required. I believe that either Yosys or GHDL did not support vectors at the beginning. Therefore, many constraint files for open source boards defined pins individually. However, nowadays I believe that all the tools can handle vectors.

Honestly, I did not pay attention to that until now. I was focused on adding constraints for open source boards, and splitting them per interface/port (even though nextpnr does not support providing multiple constraint files yet). Hence, should you be willing to review that, contributions are very welcome!


Looking forward, these are my ideas/priorities for this project:

  • Add subdirs for devices, ddr memories and flash memories.
  • Have the discussion with you, Patrick, people from SymbiFlow (@mithro), people from Antmicro (@PiotrZierhoffer, @kgugala), @olof, anyone who wants to join... about the YAML format.
  • Add all the boards from .todo (there are 40, for now...).
  • Have these boards added/shown in hdl.github.io/awesome. That's why an info.yml file exists for each of the open source boards (it needs to be added to others). hdl/awesome's CI can read these sources the same way it reads the ones from it's repo, or as vhdl/news handles issues.

@umarcor umarcor changed the title Pin names Future ideas and planning Jan 19, 2021
@rodrigomelo9
Copy link
Contributor Author

I get your point about the board name in each pin name. I was thinking in situations where between boards you only need to change the constraints. For example, imagine something such as using a PMOD in a Zybo and a Zedboard. If pin names in the constraints files are equal (no board name as a prefix) you only need to specify a different constraint file, without any change in the HDL (the same top-level). Of course, for middle-sized final projects could be more difficult, but when developing, I have dealt with such situations several times.

Ok about vector versions for less and dip-switches, maybe push-buttons? What about names? LEDS, DIPS (or SWITCHES) and PBS (or BUTTONS)?

Regards

@umarcor
Copy link
Member

umarcor commented Jan 20, 2021

I think vectors should be used as much as possible. Any set of I/O (interface), except the ones with specific signal names (such as VGA or HDMI) should use vectors. From a VHDL perspective, "interfaces" were defined in 2019. Hence, it might make sense to check the naming in https://github.com/VHDL/Interfaces/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc. You will find that Patrick proposed the naming of the interfaces in that repo, so chances are that they will be consistent with the content here 😄. Anyway, I think it is desirable to focus on the YAML or adding new boards first, rather than renaming/fixing the existing constraints now, which will probably be overwritten later. I like @LarsAsplund's "boy scout rule": leave the code slightly better than you found it; but don't spend too much time looking for problems you didn't step into.

@rodrigomelo9
Copy link
Contributor Author

I am interested in the YAML to constraints converter. We need to define the desired YAML file but we have a starting point (boardfile.py).

@Paebbels
Copy link
Member

Sorry for the late reply.

The board name was added by intension. It's part of a bigger set of rules for naming pins in top-level. It might not be obvious to most users why we do it like this, but it reflects some bigger use cases compare to hobbyist usage of FPGA boards.

Rules:

  • Prefix all signals with board name e.g. Nexys4_.
  • Group signals by there interface e.g. LED, Ethernet, I²C, ...
  • Group signals by signal interface type e.g. GPIO.
  • Postfix low-active signals _n.

Responsibilities of a Top-Level:

  • normalize low-active signals to high-active signals
  • I/O buffers if needed
  • input synchronization
  • output flip-fliops
  • converting a tristate-bus (I, O, T) to a bi-directional inout signal (and bi-directional buffer)
  • debouncing and maybe edge-detection

If a top-level entity follows these responsibility rules, a truly generic design can be implemented that runs on different boards and even platforms. E.g. I made design running from Virtex-5 to all 7-Series FPGA from Xilinx and also on Stratix II to Stratix V. Only the top-level was exchanged!

If this explanation is not yet sufficient enough, we should add an excessive example to demonstrate it. @umarcor ?

@umarcor
Copy link
Member

umarcor commented Feb 21, 2021

If this explanation is not yet sufficient enough, we should add an excessive example to demonstrate it. @umarcor ?

This is my example: https://github.com/dbhi/vboard/tree/main/vga. It's referenced in the README.

I think it would make sense to create a site (GitHub Pages) for this repo and add these guidelines there.

@rodrigomelo9
Copy link
Contributor Author

rodrigomelo9 commented Feb 21, 2021

Hi @Paebbels I got the point about the board prefix, and I agree with the rules and top-level responsibilities which you exposed. I applied most of them in my previous designs. The only differences:

  • I use _i and _o for I/Os (a suffix instead of a prefix). I think that I can change it :P
  • I don't use the board prefix in pins. I don't want to have several almost identical top-levels. Anyway, this point is not a problem for me (I can always automatically remove the prefix with sed).

I think it would make sense to create a site (GitHub Pages) for this repo and add these guidelines there.

Yep, could be great to have the guidelines somewhere.

@Paebbels
Copy link
Member

@rodrigomelo9
Yes, in case some people don't like it, it's easy to be removed with sed as you explained or any editor's search&replace feature :)

Until now, I never had the need in specifying individual pins as in or out with _i and _o. I know the Wishbone specification used this, and I find it annoying, because we have the directions directly visible in VHDL code. People might argue, it's good for Verilog, but also Verilog can have directions and sizes at one place in the port declaration, just the right language revision and syntax must be used :).

Directions might be better encoded as:

  • GMII_RX_Clock, GMII_RX_Valid, GMII_RX_Data, GMII_RX_Error
  • GMII_TX_Clock, GMII_TX_Valid, GMII_TX_Data, GMII_TX_Error

In this example, the GMII interface is split into 2 sub interfaces for transmit and receive. This also expresses, both partial interfaces are independent from eachother.

@rodrigomelo9
Copy link
Contributor Author

I know the Wishbone specification used this, and I find it annoying, because we have the directions directly visible in VHDL code.

I inherited it from there. I used several times ports such as data_i and data_o in my designs.

Yes, it is visible in the interface (entity/module) declaration, but not in the instantiation. Yes, it is visible in the interface (entity/module) declaration, but not in the instantiation. In my opinion, is OK to employ RX/TX to define the direction of interfaces, but not the individual pins. Finally, you can always remove _i and _o with sed... haha

Anyway, I still think that the best option is to have a YAML definition per board, and add the board as prefix, of the direction as suffix when desidered.

@umarcor
Copy link
Member

umarcor commented Mar 4, 2021

I created a site and moved the content from the README there: hdl.github.io/constraints.

@umarcor umarcor pinned this issue Jan 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants