Skip to content

Commit 293e6e7

Browse files
Merge remote-tracking branch 'origin/master' into temp_3d_sg
2 parents 15dfee5 + 004339f commit 293e6e7

File tree

6 files changed

+8393
-6566
lines changed

6 files changed

+8393
-6566
lines changed

doc/src/vtr/get_vtr.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ How to Cite
99
Citations are important in academia, as they ensure contributors receive credit for their efforts.
1010
Therefore please use the following paper as a general citation whenever you use VTR:
1111

12-
M. A. Elgammal, A. Mohaghegh, S. G. Shahrouz, F. Mahmoudi, F. Koşar, K. Talaei, J. Fife, D. Khadivi, K. E. Murray, A. Boutros, K.B. Kent, J. Goeders, V. Betz "VTR 9: Open-Source CAD for Fabric and Beyond FPGA Architecture Exploration" ACM TRETS, 2024
12+
M. A. Elgammal, A. Mohaghegh, S. G. Shahrouz, F. Mahmoudi, F. Koşar, K. Talaei, J. Fife, D. Khadivi, K. E. Murray, A. Boutros, K.B. Kent, J. Goeders, V. Betz "VTR 9: Open-Source CAD for Fabric and Beyond FPGA Architecture Exploration" ACM TRETS, 2025
1313

1414
Bibtex:
1515

libs/libvqm/vqm_parser.l

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
^[ \t]*\/\/[^\n\r]*(\n|\r\n) /* skip one-line comments */
4141
^[ \t]*\(\*[^\n\r]*\*\) /* skip synthesis attributes and directives */
4242
[ \t]+ /* skip white spaces */
43-
! /* skip the logical operator ! applied on the input ports of the lut - this results in lut mask not being valid anoymore */
43+
! /* skip the logical operator ! applied on the input ports of the lut - this results in lut mask not being valid anoymore */
4444
(\n|\r\n) /* skip empty lines */
4545
module return TOKEN_MODULE;
4646
endmodule return TOKEN_ENDMODULE;
@@ -67,6 +67,11 @@ assign return TOKEN_ASSIGN;
6767
strcpy(yylval.string, yytext+1);
6868
return TOKEN_ESCAPEDID;
6969
}
70+
~\\[^ ^\t^;]+ {
71+
yylval.string = (char *)malloc(yyleng - 1);
72+
strcpy(yylval.string, yytext+2);
73+
return TOKEN_ESCAPEDID;
74+
}
7075
\"[^\"]*\" {
7176
yylval.string = (char *)malloc(yyleng-1);
7277
strncpy(yylval.string, yytext+1, yyleng-2);

utils/vqm2blif/src/base/vqm2blif_util.cpp

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ void generate_opname_ram (t_node* vqm_node, const LogicalModels& arch_models, st
552552
reg_outputs = true;
553553
}
554554
} else {
555-
VTR_ASSERT(ram_info.mode == "dual_port" || ram_info.mode == "bidir_dual_port");
555+
VTR_ASSERT(ram_info.mode == "dual_port" || ram_info.mode == "bidir_dual_port" || ram_info.mode == "quad_port");
556556
VTR_ASSERT_MSG(ram_info.port_b_input_clock, "RAM inputs always assumed sequential");
557557

558558
if (ram_info.mode == "dual_port" && ram_info.port_b_output_clock) {
@@ -568,6 +568,16 @@ void generate_opname_ram (t_node* vqm_node, const LogicalModels& arch_models, st
568568
cout << " port A output sequential: " << bool(ram_info.port_a_output_clock) << "\n";
569569
cout << " port B output sequential: " << bool(ram_info.port_b_output_clock) << "\n";
570570
}
571+
} else {
572+
if (ram_info.port_a_output_clock && ram_info.port_b_output_clock) {
573+
reg_outputs = true; //Sequential output
574+
} else if (!ram_info.port_a_output_clock && !ram_info.port_b_output_clock) {
575+
reg_outputs = false; //Comb output
576+
} else {
577+
cout << "Unable to resolve whether quad port RAM " << vqm_node->name << " outputs are sequential or combinational:\n";
578+
cout << " port A output sequential: " << bool(ram_info.port_a_output_clock) << "\n";
579+
cout << " port B output sequential: " << bool(ram_info.port_b_output_clock) << "\n";
580+
}
571581
}
572582
}
573583

@@ -602,6 +612,8 @@ void generate_opname_ram (t_node* vqm_node, const LogicalModels& arch_models, st
602612
//&& (port_b_data_width == NULL) && (port_b_addr_width == NULL)) {
603613
if(ram_info.mode == "single_port" || ram_info.mode == "rom") {
604614
VTR_ASSERT(ram_info.port_b_addr_width == 0);
615+
VTR_ASSERT(ram_info.port_b_addr2_width == 0);
616+
VTR_ASSERT(ram_info.port_a_addr2_width == 0);
605617

606618
//Only print the address width, the data widths are handled by the VPR memory class
607619
mode_hash.append(".port_a_address_width{" + std::to_string(ram_info.port_a_addr_width) + "}");
@@ -613,8 +625,9 @@ void generate_opname_ram (t_node* vqm_node, const LogicalModels& arch_models, st
613625
}
614626

615627
//A dual port memory, both port A and B params have been found
616-
} else {
617-
VTR_ASSERT(ram_info.mode == "dual_port" || ram_info.mode == "bidir_dual_port");
628+
} else if (ram_info.mode == "dual_port" || ram_info.mode == "bidir_dual_port"){
629+
VTR_ASSERT(ram_info.port_b_addr2_width == 0);
630+
VTR_ASSERT(ram_info.port_a_addr2_width == 0);
618631

619632
//2) Both ports are the same size, so only append the address widths, the data widths are handled by the VPR memory class
620633
if ( (ram_info.port_a_data_width == ram_info.port_b_data_width)
@@ -645,6 +658,53 @@ void generate_opname_ram (t_node* vqm_node, const LogicalModels& arch_models, st
645658
tmp_mode_hash.append(".port_a_data_width{" + std::to_string(ram_info.port_a_data_width) + "}");
646659
tmp_mode_hash.append(".port_b_data_width{" + std::to_string(ram_info.port_b_data_width) + "}");
647660

661+
LogicalModelId arch_model_id = arch_models.get_model_by_name(tmp_mode_hash);
662+
if (!arch_model_id.is_valid()) {
663+
//3a) Not found, use the default name (no specific address/data widths)
664+
; // do nothing
665+
} else {
666+
//3b) Use the more detailed name, since it was found in the architecture
667+
mode_hash = tmp_mode_hash;
668+
}
669+
}
670+
} else {
671+
VTR_ASSERT(ram_info.mode == "quad_port");
672+
673+
//2) Both ports are the same size, so only append the address widths, the data widths are handled by the VPR memory class
674+
if ( (ram_info.port_a_data_width == ram_info.port_b_data_width)
675+
&& (ram_info.port_a_addr_width == ram_info.port_b_addr_width)
676+
&& (ram_info.port_a_addr_width == ram_info.port_b_addr2_width)
677+
&& (ram_info.port_a_addr2_width == ram_info.port_b_addr2_width)) {
678+
679+
mode_hash.append(".port_a_address_width{" + std::to_string(ram_info.port_a_addr_width) + "}");
680+
mode_hash.append(".port_a_address2_width{" + std::to_string(ram_info.port_a_addr2_width) + "}");
681+
mode_hash.append(".port_b_address_width{" + std::to_string(ram_info.port_b_addr_width) + "}");
682+
mode_hash.append(".port_b_address2_width{" + std::to_string(ram_info.port_b_addr2_width) + "}");
683+
684+
LogicalModelId arch_model_id = arch_models.get_model_by_name(mode_hash);
685+
if (!arch_model_id.is_valid()) {
686+
cout << "Error: could not find dual port (non-mixed_width) memory primitive '" << mode_hash << "' in architecture file";
687+
exit(1);
688+
}
689+
//3) Mixed width dual port ram
690+
} else {
691+
//Make a temporary copy of the mode hash
692+
string tmp_mode_hash = mode_hash;
693+
694+
/*
695+
* Try to see if the detailed version exists in the architecture,
696+
* if it does, use it. Otherwise use the operation mode only.
697+
*/
698+
699+
tmp_mode_hash.append(".port_a_address_width{" + std::to_string(ram_info.port_a_addr_width) + "}");
700+
tmp_mode_hash.append(".port_a_address2_width{" + std::to_string(ram_info.port_a_addr2_width) + "}");
701+
tmp_mode_hash.append(".port_b_address_width{" + std::to_string(ram_info.port_b_addr_width) + "}");
702+
tmp_mode_hash.append(".port_b_address2_width{" + std::to_string(ram_info.port_b_addr2_width) + "}");
703+
704+
//Each port has a different size, so print both the address and data widths. Mixed widths are not handled by the VPR memory class
705+
tmp_mode_hash.append(".port_a_data_width{" + std::to_string(ram_info.port_a_data_width) + "}");
706+
tmp_mode_hash.append(".port_b_data_width{" + std::to_string(ram_info.port_b_data_width) + "}");
707+
648708
LogicalModelId arch_model_id = arch_models.get_model_by_name(tmp_mode_hash);
649709
if (!arch_model_id.is_valid()) {
650710
//3a) Not found, use the default name (no specific address/data widths)
@@ -997,8 +1057,10 @@ RamInfo get_ram_info(const t_node* vqm_node, string device) {
9971057
//We need to save the ram data and address widths, to identfy the RAM type (singel port, rom, simple dual port, true dual port)
9981058
t_node_parameter* port_a_data_width = NULL;
9991059
t_node_parameter* port_a_addr_width = NULL;
1060+
t_node_parameter* port_a_addr2_width = NULL;
10001061
t_node_parameter* port_b_data_width = NULL;
10011062
t_node_parameter* port_b_addr_width = NULL;
1063+
t_node_parameter* port_b_addr2_width = NULL;
10021064

10031065
for (int i = 0; i < vqm_node->number_of_params; i++){
10041066
//Each parameter specifies a configuration of the node in the circuit.
@@ -1020,6 +1082,11 @@ RamInfo get_ram_info(const t_node* vqm_node, string device) {
10201082
port_a_addr_width = temp_param;
10211083
continue;
10221084
}
1085+
if (strcmp (temp_param->name, "port_a_address2_width") == 0){
1086+
VTR_ASSERT( temp_param->type == NODE_PARAMETER_INTEGER );
1087+
port_a_addr2_width = temp_param;
1088+
continue;
1089+
}
10231090
if (strcmp (temp_param->name, "port_b_data_width") == 0){
10241091
VTR_ASSERT( temp_param->type == NODE_PARAMETER_INTEGER );
10251092
port_b_data_width = temp_param;
@@ -1030,6 +1097,11 @@ RamInfo get_ram_info(const t_node* vqm_node, string device) {
10301097
port_b_addr_width = temp_param;
10311098
continue;
10321099
}
1100+
if (strcmp (temp_param->name, "port_b_address2_width") == 0){
1101+
VTR_ASSERT( temp_param->type == NODE_PARAMETER_INTEGER );
1102+
port_b_addr2_width = temp_param;
1103+
continue;
1104+
}
10331105
if (strcmp (temp_param->name, "port_a_address_clock") == 0){ // This parameter doesn't exist for Stratix 10 - clock0 is always used for port address_a
10341106
VTR_ASSERT( temp_param->type == NODE_PARAMETER_STRING );
10351107
port_a_address_clock = temp_param;
@@ -1096,6 +1168,12 @@ RamInfo get_ram_info(const t_node* vqm_node, string device) {
10961168
VTR_ASSERT(port_a_data_width);
10971169
ram_info.port_a_data_width = port_a_data_width->value.integer_value;
10981170

1171+
if (port_a_addr2_width) {
1172+
ram_info.port_a_addr2_width = port_a_addr2_width->value.integer_value;
1173+
}
1174+
if (port_b_addr2_width) {
1175+
ram_info.port_b_addr2_width = port_b_addr2_width->value.integer_value;
1176+
}
10991177
if (port_b_addr_width) {
11001178
ram_info.port_b_addr_width = port_b_addr_width->value.integer_value;
11011179
}

utils/vqm2blif/src/base/vqm2blif_util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ typedef pair <const char*, v_OptionBaseToken> tokpair;
9999
struct RamInfo {
100100
std::string mode = "";
101101
int port_a_addr_width = 0;
102+
int port_a_addr2_width = 0;
102103
int port_a_data_width = 0;
103104
t_node_port_association* port_a_input_clock = nullptr;
104105
t_node_port_association* port_a_input_ena = nullptr;
@@ -108,6 +109,7 @@ struct RamInfo {
108109
t_node_port_association* port_a_dataout_sclr = nullptr;
109110

110111
int port_b_addr_width = 0;
112+
int port_b_addr2_width = 0;
111113
int port_b_data_width = 0;
112114
t_node_port_association* port_b_input_clock = nullptr;
113115
t_node_port_association* port_b_input_ena = nullptr;

vpr/src/analytical_place/full_legalizer.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ FlatRecon::neighbor_clustering(ClusterLegalizer& cluster_legalizer,
492492
if (cluster_legalizer.is_mol_clustered(molecule_id))
493493
continue;
494494

495-
// Get 8-neighbouring tile locations of the current molecule in the same layer and same type.
495+
// Get 8-neighbouring tile locations of the current molecule in the same layer.
496496
std::vector<t_physical_tile_loc> neighbor_tile_locs;
497497
neighbor_tile_locs.reserve(8);
498498
auto [layers, width, height] = device_grid_.dim_sizes();
@@ -502,8 +502,6 @@ FlatRecon::neighbor_clustering(ClusterLegalizer& cluster_legalizer,
502502
int neighbor_x = loc.x + dx, neighbor_y = loc.y + dy;
503503
if (neighbor_x < 0 || neighbor_x >= (int)width || neighbor_y < 0 || neighbor_y >= (int)height)
504504
continue;
505-
if (device_grid_.get_physical_type(loc) != device_grid_.get_physical_type({neighbor_x, neighbor_y, loc.layer_num}))
506-
continue;
507505
neighbor_tile_locs.push_back({neighbor_x, neighbor_y, loc.layer_num});
508506
}
509507
}

0 commit comments

Comments
 (0)