VPR compilation

Compile BLIF to FASM by VPR <– architecture.xml + routing_resources.xml

VPR (Versatile Place and Route) is a place and route tool from the VTR project that can be used to program a fabric generated by FABulous, using either Yosys or ODIN II for the logic synthesis. The VTR genfasm tool can then be used to generate an FPGA Assembly (FASM) file from which the bitstream can be generated.

To generate the necessary materials to program using VPR, run $FAB_ROOT/fabric_generator/fabric_gen.py with the -genVPRModel flag. In the $FAB_ROOT/fabric_generator/vproutput directory, two files will be created - architecture.xml and routing_resources.xml.

architecture.xml contains a description of the various tiles, ports and BELs - everything in the architecture except for the routing resources.

routing_resources.xml contains the specifications of these routing resources, which contains a graph within which the nodes are routing wires and ports, and the edges are the switch matrix interconnects that connect these resources.

To run the flow with ODIN II, the run_vtr_flow.py script in $VTR_ROOT/vtr_flow/scripts can be used, passing in your verilog circuit, followed by the genfasm utility.

To use Yosys (recommended with FABulous for improved functionality), follow the Yosys flow description found at Yosys compilation and specify an output file with a .blif file extension. The synthesis script will detect this file extension and automatically produce a Berkeley Logic Interchange Format (BLIF) file synthesised appropriately for the VPR flow. This BLIF file can then be used as an argument for the VPR executable, followed by the genfasm utility to generate FASM.

When generating the VPR model, FABulous will print out a maximum width for routing channels in the form Max Width: <max_width>. This number should be noted, as it will be used as an argument when calling VPR.

To run the VPR flow (with VPR 8.1.0 installed) , the following command can be used:

vpr <architecture.xml> <circuit.blif> --read_rr_graph <routing_resources.xml> --route_chan_width <max_width>

<architecture.xml> and <routing_resources.xml> should be paths to the corresponding files in $FAB_ROOT/fabric_generator/vproutput.

--disp on can be appended to the end if a GUI is desired.

To generate FASM, you should then use the command:

genfasm <architecture.xml> <circuit.blif> --read_rr_graph <routing_resources.xml> --route_chan_width <max_width>`

The genfasm utility is part of the VTR flow, so should be installed alongside VPR. While the two commands are very similar, both must be called in sequence.

Placement Constraints

VPR accepts placement constraints in the form of an XML file, documented here. FABulous generates one of these automatically for you, constraining the placement of IO BELs (InPass4_frame_config, OutPass4_frame_config and IO_1_bidirectional_frame_config_pass blocks). This can be found in $FAB_ROOT/fabric_generator/vprout/fab_constraints.xml, and is designed to constrain an automatically generated template file found at $FAB_ROOT/fabric_generator/vprout/template.v. Other BELs can also be constrained using this technique, but these constraints are not automatically generated.

To make use of these constraints, first add your design to $FAB_ROOT/fabric_generator/vprout/template.v, where all IO BELs are instantiated and their connected wires can be used. The BEL instances within this file are intuitively named - the first BEL (in order of declaration in fabric.csv) on tile X0Y1, for example, is instantiated with the name Tile_X0Y1_A. The second is named Tile_X0Y1_B, and so on. The elements are instantiated explicitly, so it should be clear which wires in the template file correspond to which BEL ports. Any inputs or outputs you do not connect to the instantiated BELs (i.e. leave as explicit HDL inputs and outputs) will be mapped to free IO primitives. Removing unused input BEL instances from the template file will not have any adverse effects, but removing output BEL instances will lead to incorrect placement of your instantiated BELs. This is because VPR generates its own name for BEL instances, and usually uses the name of the first net driven by a BEL to generate this name. However, BELs that do not drive anything are enumerated - the first is named unnamed_subckt0, the second is unnamed_subckt1 and so on. This means that removing non-driving instantiations will change the names given to the BELs, and so they will be assigned to the wrong constraint region.

Once your design is integrated into the template Verilog file, synthesise it using Yosys as normal, and run VPR with the command:

vpr <architecture.xml> <circuit.blif> --read_rr_graph <routing_resources.xml> --route_chan_width <max_width> --read_vpr_constraints <fab_constraints.xml> --timing_analysis on --sweep_dangling_blocks off

If you are not instantiating any outputs then the --timing_analysis on --sweep_dangling_blocks off arguments are not required. These are used because VPR’s timing analysis is unable to infer timing information from nets that end in a connection to a blackbox module (so we disable it), and without setting the --sweep_dangling_blocks VPR’s optimisations will try and remove blocks that do not drive anything (such as output BELs).