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

Add command to generate repack design constraints #1889

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

fkosar-ql
Copy link
Collaborator

This adds a command gen_repack_constraints which can take a .pcf file and generate a repack_design_constraints.xml file with the clock pin assignments in it. If a .pcf is not provided it assigns clock nets to the first available pin.

There are some points I need to resolve before this is ready for merge:

  • Take an existing repack_design_constraints.xml file and change it instead of generating one from scratch, since the file has more functions outside of clock pin assignment.
  • Make sure this the right way to do it. This works for now, but the pcf pin assignments can go directly into repack instead of writing a file and reading it back in.

@tangxifan
Copy link
Collaborator

@fkosar-ql Great motivation. @Tulong4Dev Please take a look and see if the current spec fits our device.

Copy link
Collaborator

@tangxifan tangxifan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fkosar-ql I have read the code. As you said in the PR notes, we should think carefully about the methodology. Here is my proposal:

  • We should probably integrate this command into repack. We can add a new option --file_format [pcf|xml] where we can avoid conflicts from two design constraints.
  • In your code, you are trying to get the port information from pb_type and then use the pin index to determine the net-to-pin mapping. However, this is not a general purpose way. The net used in your PCF file (which is global port) is not a valid port in VPR's context. They are named by OpenFPGA because global ports have to be treated in a special way.

A general purpose method is to use the FabricGlobalPortInfo data structure and the tile_annotation data from openfpga_architecture.

namespace openfpga {

static inline RepackDesignConstraints gen_repack_constraints(openfpga::PcfData* pcf_data){
auto& cluster_ctx = g_vpr_ctx.clustering();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid to use any more global variables. Pass them through arguments (const reference). We have seen enough troubles by using global variables. Any new codes should be clean at the beginning.

/* begin namespace openfpga */
namespace openfpga {

static inline RepackDesignConstraints gen_repack_constraints(openfpga::PcfData* pcf_data){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use constant reference for PcfData (const openfpga::PcfData& pcf_data) as it is read-only in this function.

@tangxifan
Copy link
Collaborator

@fkosar-ql A detailed example is here.

Your pcf may look like

# set_io <net> <pin>
set_io ck0 fpga_clk0 # alternatively you may have your own command for global ports, such as set_clk, set_reset 
set_io ck1 fpga_clk1

The fpga_clk[0] should be a valid global port of the fpga_top module, rather than a valid port of a pb_type.
The global port connections are defined in the OpenFPGA architecture (see the link below)

https://openfpga.readthedocs.io/en/master/manual/arch_lang/annotate_vpr_arch/#physical-tile-annotation

In the example I give, the tile_annotation may look like

<tile_annotations>
  <global_port name="fpga_clk0" is_clock="true" default_val="0">
      <tile name="clb" port="clk[0:0]" x="-1" y="-1"/>
      <tile name="io_topL" port="clk[0:0]" x="-1" y="-1"/>
      <tile name="io_rightL" port="clk[0:0]" x="-1" y="-1"/>
      <tile name="io_bottomL" port="clk[0:0]" x="-1" y="-1"/>
      <tile name="io_leftL" port="clk[0:0]" x="-1" y="-1"/>
  </global_port>
  <global_port name="fpga_clk1" is_clock="true" default_val="0">
      <tile name="clb" port="clk[1:1]" x="-1" y="-1"/>
  </global_port>
</tile_annotations>

When OpenFPGA models the FPGA fabric, all the global ports are managed by a dedicated data structure

class FabricGlobalPortInfo {
public: /* Types */
typedef vtr::vector<FabricGlobalPortId, FabricGlobalPortId>::const_iterator
global_port_iterator;
/* Create range */
typedef vtr::Range<global_port_iterator> global_port_range;
public: /* Constructor */
FabricGlobalPortInfo();

Their names to appear in the top-level module and functionality are all recorded here, as the only legal source for such information. You can easily validate if your pcf is not doing anything wrong.

So you see that combined with the two data structures FabricGlobalPortInfo and TileAnnotation, you can find the proper net-to-pin mapping that is required to create design constraints for repack.

@tangxifan
Copy link
Collaborator

@fkosar-ql Let me know if it makes sense to you. We can schedule a meeting if you are confused.

@fkosar-ql
Copy link
Collaborator Author

@tpagarani @coolbreeze413

@tpagarani
Copy link
Collaborator

@ganeshgore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants