FPGA-Research-Manchester / FABulous

Fabric generator and CAD tools
https://fabulous.readthedocs.io/en/latest/
Apache License 2.0
142 stars 31 forks source link

Mux input ordering #165

Open RobB720 opened 3 months ago

RobB720 commented 3 months ago

Hi,

I have found that the input order specified in a tile's .list file is not mapped across to the Verilog description generated.

If I am correct and this is the case, could the code be changed to maintain the order set in the list file?

Best regards, Rob.

KelvinChung2000 commented 3 months ago

The connection order generated in the Verilog file will always be normal wires (NESW wire), bel wire, and jump wire. This specific order ensures we can correctly line up all the ports.

RobB720 commented 3 months ago

Thanks for the information - I didn't realise the order was adjusted in this way. Do you add structure when you implement the layout e.g. by placing the muxes at controlled locations?

I am using FABulous unconventionally with full-custom layout and PnR at a tile level. My routing muxes are in a bank and I was assuming that the order was as defined in the .list file and I could change the order to line up inputs. I wrote a script to optimise the order in the .list file and create pre-routes for the pnr but it sounds like this is not how the tool works.

I can extract the order from the FABulous switch matrix verilog and use that for the pre-routes, but looking at the Verilog the alphabetic order in the NESW normal routes could be improved on. Is there any other way the order can be changed?

Many thanks, Rob.

KelvinChung2000 commented 3 months ago

You might want to modify the code generation process to match the list file. You can find the code generation at fabric_generator/fabric_gen.py.

We have done work on optimizing the configuration cell and the port placement but not the muxes (the paper). There are some constraints in the NESW port location; for example, the north end port and south begin port will need to be placed along the north side of the tile so that the tile can line up. As far as I know, the rest is letting the PnR tool decide.

KelvinChung2000 commented 3 months ago

We have got a parseList function in fabric_generator/file_parser.py. You can modify fabric_generator/fabric_gen.py line 396-407 to not covert the list file into a switch matrix file and directly use parseList and collect by sink (or source, I am unsure which way round). You then use what returned by parseList for the connection variable, then the generated Verilog should then follow the list file.

dirk-koch commented 3 months ago

Hi Rob, Cool stuff you are doing. The list files are "just" translated into the adjacency matrix which is then used for the rest of the flow. You see from the adjacency matrix that each row corresponds to one mux. The reason for list files are that that is an easy way to specify these things. We are currently playing with this to allow users to add custom tiles without touching the list file. We are also thinking to add includes so shared things are only specified once. Anyway, to what you want to do, I would probably add an extra file specifying the mux input mapping order. This is something we have on our radar screen. Its just that the optimizations Kelvin referred to are already helping a lot and we run into diminishing return. The point is that mux input order is done in alphabetical order which (without further thinking about it) exploits some locality doe to common name prefixes ;-)

RobB720 commented 3 months ago

Hi Dirk, Kelvin,

Thank-you for both of your inputs here. I see the adjacency matrix columns follow the NESW, bel, jump order. I presume the adjacency matrix then feeds into the bitstream generation.

I am wondering if what I want to do will break the adjacency matrix as the mux input reordering might require the matrix columns to be in a different order for different muxes. Would your proposed input mapping file get around this issue?

My motivation here is issues I am having routing my cell. It could be that the optimisations you have in place will help and I just need to place my preroutes using the verilog switch matrix order, so I will try this as a first step.

Many thanks, Rob.

KelvinChung2000 commented 3 months ago

The model generation does not care about the "generation" order, which you can check and tell from the genNextpnrModel function. After the PnR with nextpnr, we will get a FASM file. The bit_gen.py will take the bitStreamSpec.csv inside the .FABulous folder, the FASM file, to generate a bitstream.

The changes in the adjacency matrix/list file will not, in theory, affect the tile and fabric generation. With what you would like in #166, I think you can create your bitStreamSpec.csv or modify the generateBitsStreamSpec function to match the bitstream with the optimization and convert the bitstream to the form you like with your version of bit_gen.py'.

dirk-koch commented 3 months ago

What Kelvin writes could do. Well, you can simulate/emulate your bitstreams. I would be a little careful right now as we have another bitstream indirection as in https://dl.acm.org/doi/10.1145/3490422.3502371 that we want to include first in the main branch. That is using configuration bit swapping and gave like 20% in area... But mux input swapping will be one of the upcoming optimizations.