Skip to content

Define different I/Os #268

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

Closed
pgaraccio opened this issue Dec 19, 2017 · 10 comments
Closed

Define different I/Os #268

pgaraccio opened this issue Dec 19, 2017 · 10 comments

Comments

@pgaraccio
Copy link

I need to define 4 different I/Os, one for each side of the FPGA.
I would like to define a different I/Os capacity according to the side of the FPGA.

Is it possible ? If yes, I would like an example of Architecture Specification.

@kmurray
Copy link
Contributor

kmurray commented Dec 19, 2017

You will need to create a top-level <pb_type> for each of the different types you want (e.g. 'io_left', 'io_top', 'io_right', 'io_bottom'). Each of these can have unique capacities and <pinlocations> to place the pins as needed to connect to the routing channels.

You can use the grid location specifications to the place the blocks wherever you wish.

Roughly:

...
<layout>
  <fixed_layout width="10" height="10">
    <col type="io_left", startx="0"/>
    <row type="io_top", starty="H-1"/>
    ...
  </fixed_layout>
</layout>
...
<complexblocklist>
  ...
  <pb_type name="io_left" capacity="2">
     ....
    <pinlocations type="custom">
      <loc side="right"> .... </loc>
    </pinlocations>
  </pb_type>

  <pb_type name="io_top" capacity="4">
    ...
    <pinlocations type="custom">
      <loc side="bottom"> .... </loc>
    </pinlocations>
  </pb_type>
  ...
</complexblocklist>
...

@pgaraccio
Copy link
Author

I get the following message:
Architecture contains multiple top-level block types containing both '.input' and '.output' BLIF models (expected one block type)

Note: for each <pb_type>, I did the following specification:

<pb_type name="io_left" capacity="4">
      <input name="outpad" num_pins="1"/>
      <output name="inpad" num_pins="1"/>
      <clock name="clock" num_pins="1"/>
      <!-- IOs can operate as either inputs or outputs -->
      <mode name="inpad">
          <pb_type name="inpad" blif_model=".input" num_pb="1">
              <output name="inpad" num_pins="1"/>
          </pb_type>
          <interconnect>
              <direct name="inpad" input="inpad.inpad" output="io_left.inpad">
                   <delay_constant max="500e-12" in_port="inpad.inpad" out_port="io_left.inpad"/>
                   <!-- Bitstreams STA give a value slightly below 300e-12 -->
              </direct>
          </interconnect>
      </mode>
      <mode name="outpad">
          <pb_type name="outpad" blif_model=".output" num_pb="1">
              <input name="outpad" num_pins="1"/>
          </pb_type>
          <interconnect>
              <direct name="outpad" input="io_left.outpad" output="outpad.outpad">
                  <delay_constant max="300e-12" in_port="io_left.outpad" out_port="outpad.outpad"/>
                  <!-- Bitstreams STA give a value slightly below 200e-12 -->
              </direct>
          </interconnect>
      </mode>
      <fc default_in_type="abs" default_in_val="16" default_out_type="abs" default_out_val="16"/>
      <pinlocations pattern="custom">
        <loc side="right">io_left.outpad io_left.inpad io_left.clock</loc>
      </pinlocations>
    </pb_type>

@kmurray
Copy link
Contributor

kmurray commented Dec 20, 2017

There were some legacy assumptions about a single IO type in the code, which I've removed in fb085bd. Your architecture should no longer cause errors related to multiple blocks with primary inputs/outputs.

However VPR currently packs all IOs into the first type it sees (eg io_left), and doesn't use the others. This is a limitation of the packer, since it currently does not try to balance block usage.

@pgaraccio
Copy link
Author

Is an improvement of the packer planned in order to make the IOs placement independent of the IO type?

@kmurray
Copy link
Contributor

kmurray commented Dec 21, 2017

I've added a very simple heuristic to the packer in fe0d75e, which tries to balance resource usage between different blocks which can implement the same type of primitive. This should mean that all of the IO types get used.

However, it is not a fully general solution. In particular, any I/O which the packer maps to a particular type (e.g. io_left) will only ever be placed in a location matching that exact type (e.g. along the device's left edge).

For example, even if an io_left and io_right were completely equivalent, after packing VPR would treat them as strictly different block types, and so they would never mix during placement.

Providing a fully general solution would break a large number of assumptions VPR currently makes, so it would be a much more drastic change which is unlikely to happen anytime soon.

@pgaraccio
Copy link
Author

Is it possible to define or fix the IO type of each I/O according to the pad locations (use --fix_pins option)?
Currently, I get the following error message when I try to specify pad locations:
Error 1: Block 161 type does not match grid location (1,0) type.
Indeed, "Block 161" has been previously packed heuristically to an IO type which does not match with the wanted pad placement.

If it is not possible, what other way do I have to specify an architecture with different I/O types in accordance with the IO placement?

@kmurray
Copy link
Contributor

kmurray commented Dec 22, 2017

The --fix_pins option only effects placement, and has no effect on packing, so that error makes sense.

VPR does not support additional constraints to fine-tune the implementation, so there is no way to specify which block type (e.g. io_left, io_right) a primitive (e.g. primary I/O) gets mapped into during packing.

@pgaraccio
Copy link
Author

To sum up:
To implement an fpga with different I/O blocks, we need to create a top-level <pb_type> for each of the different types. (Is there another way?) . But different types would never mix during placement.
So, if we want an fpga with different I/O blocks, we cannot use the --fix_pins option.

However, we need to implement an fpga with different I/O blocks and to specify I/O pad locations during placement.
In this goal, I sought a workaround to fix I/O pad locations in the case of an fpga with different I/O blocks.
I thought to proceed in three stages:
1- Run packing
2- Modify the packed netlist file (correct if necessary the IO types of each IO blocks in order to match with the pad location)
3- Run the others VPR stages (placement, routing and analysis) from the updated packed netlist file

What are your feelings about that?

@kmurray
Copy link
Contributor

kmurray commented Jan 15, 2018

To implement an fpga with different I/O blocks, we need to create a top-level <pb_type> for each of the different types.

Correct, if you need IO blocks with different characteristics (e.g. different numbers of I/Os per block) each must be defined as their own top-level <pb_type>.

But different types would never mix during placement.
So, if we want an fpga with different I/O blocks, we cannot use the --fix_pins option.

Correct. The --fix_pins option only controls placement; it has no effect during packing (which determines the top-level IO block as specific IO block primitive gets mapped into).

However, we need to implement an fpga with different I/O blocks and to specify I/O pad locations during placement.
In this goal, I sought a workaround to fix I/O pad locations in the case of an fpga with different I/O blocks.
I thought to proceed in three stages:
1- Run packing
2- Modify the packed netlist file (correct if necessary the IO types of each IO blocks in order to match with the pad location)
3- Run the others VPR stages (placement, routing and analysis) from the updated packed netlist file

What are your feelings about that?

This might work, but it seems very awkward and fragile. It also does not solve the more general problem of fine-tuning the design implementation based on user knowledge. As a result it is not an approach I would recommend.

The correct way to support this is by adding region-based location constraints to VPR.
This would allow users to specify that a specific primitive (e.g. a specific I/O) must be implemented in a specific region of the device (e.g. in a specific IO block, or set of IO blocks).

This would require updating VPR's algorithms (packing, placement, routing) to respect these constraints. However once this was done, it would allow you to control VPR's implementation in a variety of ways; including ensuring an IO was implemented in the correct block type.

However, we currently have many other higher priority things to working on, and limited motivation to add support for location constraints. As a result there is no timeline for adding such support. If you would like to see location constraints added to VPR we could discuss further.

@kmurray
Copy link
Contributor

kmurray commented Dec 11, 2019

Modelling different IO tiles with alternate pin-outs and capacities is now supported with the new equivalent placement site support from #988, so closing.

@kmurray kmurray closed this as completed Dec 11, 2019
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

2 participants