Skip to content

Subtile Pin Location #3129

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

Merged
merged 24 commits into from
Jun 13, 2025
Merged

Subtile Pin Location #3129

merged 24 commits into from
Jun 13, 2025

Conversation

amin1377
Copy link
Contributor

@amin1377 amin1377 commented Jun 10, 2025

In the architecture file, when a sub-tile has a capacity bigger than one, it is assumed that the pin location of all sub-tiles should be assigned together:

<tile name="io">
      <sub_tile name="io" capacity="2">
       ....
             <pinlocations pattern="custom">
                      <loc side="left">  io.core_in[0:24]  io.core_out[0:19]  io.clk[0:2]</loc>
       ....

In the above case, the first half of the IO pins for both sub-tiles will be placed on the left side of the device.

In this PR, a feature from OpenFPGA is added where one can define different locations for each sub-tile capacity if necessary:

<tile name="io">
      <sub_tile name="io" capacity="2">
       ....
             <pinlocations pattern="custom">
                      <loc side="left">  io[0:0].core_in[0:24]  io[0:0].core_out[0:19]  io[1:1].clk[0:2]</loc>
       ....

@github-actions github-actions bot added libarchfpga Library for handling FPGA Architecture descriptions lang-cpp C/C++ code labels Jun 10, 2025
Copy link
Contributor

@AlexandreSinger AlexandreSinger left a comment

Choose a reason for hiding this comment

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

This looks good to me other than some minor comments. I am not as familiar with this code, but I gave some general comments.

Can you please add some documentation for this new feature to the architecture docs? I think you can just directly copy the docs from OpenFPGA.

auto token = tokens[token_index];

if (token.type != TOKEN_STRING || 0 != strcmp(token.data, type->name.c_str())) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Locations),
Copy link
Contributor

Choose a reason for hiding this comment

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

Although it is not "required", I think freeTokens should be called before all of the throw statements in the function for cleanliness. I have run into issues in the past where throws fail due to memory not being deallocated properly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting! I added a helper function throw_xml_arch_error that takes the tokens and frees them before throwing an error. I replaced all archfpga_throw calls with this helper function (it took me a while :) )

static void throw_xml_arch_error(const char* filename, 
                                  int line, 
                                  const std::string& err_msg, 
                                  t_token* tokens, 
                                  int num_tokens);

@@ -123,6 +123,11 @@ static std::pair<int, int> ProcessPinString(pugi::xml_node Locations,
T type,
const char* pin_loc_string,
const pugiutil::loc_data& loc_data);
template<typename T>
static std::pair<int, int> ProcessInstanceString(pugi::xml_node Locations,
Copy link
Contributor

Choose a reason for hiding this comment

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

Most function names in this file are camel case, but the rest of code base uses snake case. We should gradually change this. NoC-realted function names are snake case. I think new functions should use snake case too.

Why is this a template function? It is only called once with T=t_sub_tile*. I also suggest we pass it by const reference instead of pointer.

Add doxygen comment for this function

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the name of all functions in this file from camel case to snake case.

@@ -703,10 +708,15 @@ static void LoadPinLoc(pugi::xml_node Locations,
&sub_tile,
token.c_str(),
loc_data);

/* Get the offset in the capacity range */
auto capacity_range = ProcessInstanceString<t_sub_tile*>(Locations,
Copy link
Contributor

Choose a reason for hiding this comment

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

You can use auto to unpack the pair and give each of its members a name. For example:
auto [capacity_range_low, capacity_range_high] = ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Look who’s suddenly in favor of using auto :)) (just kidding)

Copy link
Contributor

@soheilshahrouz soheilshahrouz left a comment

Choose a reason for hiding this comment

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

Thanks for this new feature.
I think it should be also documented in the architecture reference.

@github-actions github-actions bot added VPR VPR FPGA Placement & Routing Tool Odin Odin II Logic Synthesis Tool: Unsorted item libvtrutil Parmys labels Jun 11, 2025
@amin1377
Copy link
Contributor Author

@soheilshahrouz @AlexandreSinger: Thanks for reviewing this PR. I’ve applied your comments. Please let me know if you have any further suggestions.

Copy link
Contributor

@AlexandreSinger AlexandreSinger left a comment

Choose a reason for hiding this comment

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

LGTM. The throw function freeing memory makes sense, but its a bit unclear to someone using the code that they need to do that; however I know that Soheil is working on cleaning up the token code to prevent this so it does not matter.

I still think it would be good to document this change!

@amin1377
Copy link
Contributor Author

@AlexandreSinger:

I added the following Doxygen comment for throw_xml_arch_error :

/**
 * @brief Throws an error with a message and frees the tokens
 *
 * @param filename File name associated with the error
 * @param line Line number associated with the error
 * @param err_msg Error message to be displayed
 * @param tokens If tokens are allocated before calling this function,
 * they will be freed here. If not, nullptr should be passed.
 * @param num_tokens Number of tokens to be freed. If not, 0 should be passed.
 */

Also, inside of the function I added the following comment:

// We need to free the tokens here, otherwise,
// archfpga_throw will face issues since memory is
// not deallocated properly.
```.

@amin1377
Copy link
Contributor Author

amin1377 commented Jun 12, 2025

@AlexandreSinger: Added the following to architecture documentation:

If the subtile capacity is greater than 1, you can specify the capacity range when defining the pin locations. For example:

        .. code-block:: xml

            <sub_tile name="io_bottom" capacity="6">
                <equivalent_sites>
                    <site pb_type="io"/>
                </equivalent_sites>
                <input name="outpad" num_pins="1"/>
                <output name="inpad" num_pins="1"/>
                <fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
                <pinlocations pattern="custom">
                    <loc side="top">io_bottom[0:1].outpad io_bottom[0:3].inpad io_bottom[2:5].outpad io_bottom[4:5].inpad</loc>
                </pinlocations>
            </sub_tile>
        
        If no capacity range is specified, it is assumed that the location applies to all capacity instances.

@github-actions github-actions bot added the docs Documentation label Jun 12, 2025
Copy link
Contributor

@AlexandreSinger AlexandreSinger left a comment

Choose a reason for hiding this comment

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

LGTM thanks for adding the documentation!

@soheilshahrouz
Copy link
Contributor

@amin1377 Thanks for all these changes!

As discussed yesterday, I created a class to avoid using raw pointers in vtr_tokens. Is it possible to revert changes you made to vtr_tokens to avoid merge confilicts? If not, I'll resolve them later.

@amin1377
Copy link
Contributor Author

@soheilshahrouz: Sure. I'll revert the commit.

@amin1377 amin1377 merged commit f44c58a into master Jun 13, 2025
33 checks passed
@amin1377 amin1377 deleted the subtile_pin_loc branch June 13, 2025 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation lang-cpp C/C++ code libarchfpga Library for handling FPGA Architecture descriptions libvtrutil Odin Odin II Logic Synthesis Tool: Unsorted item Parmys VPR VPR FPGA Placement & Routing Tool
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants