Skip to content

Commit 90dd8aa

Browse files
committed
libarchfpga: add secondary models to t_pb_type and t_pb_graph_node
Introduce secondary t_model and t_port to t_pb_types and secondary input/output/clock_pins in t_pb_graph_node. Also fill those fields with data required for processing. Signed-off-by: Pawel Czarnecki <pczarnecki@antmicro.com>
1 parent 15f6997 commit 90dd8aa

File tree

4 files changed

+225
-23
lines changed

4 files changed

+225
-23
lines changed

libs/libarchfpga/src/arch_util.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ static void free_pb_graph(t_pb_graph_node* pb_graph_node) {
326326
delete[] pb_graph_node->input_pins[i][j].parent_pin_class;
327327
}
328328
delete[] pb_graph_node->input_pins[i];
329+
if (pb_graph_node->has_secondary)
330+
delete[] pb_graph_node->input_pins_sec[i];
329331
}
330332
for (i = 0; i < pb_graph_node->num_output_ports; i++) {
331333
for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
@@ -343,19 +345,29 @@ static void free_pb_graph(t_pb_graph_node* pb_graph_node) {
343345
delete[] pb_graph_node->output_pins[i][j].num_connectable_primitive_input_pins;
344346
}
345347
delete[] pb_graph_node->output_pins[i];
348+
if (pb_graph_node->has_secondary)
349+
delete[] pb_graph_node->output_pins_sec[i];
346350
}
347351
for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
348352
for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
349353
if (pb_graph_node->clock_pins[i][j].parent_pin_class)
350354
delete[] pb_graph_node->clock_pins[i][j].parent_pin_class;
351355
}
352356
delete[] pb_graph_node->clock_pins[i];
357+
if (pb_graph_node->has_secondary)
358+
delete[] pb_graph_node->clock_pins_sec[i];
353359
}
354360

355361
delete[] pb_graph_node->input_pins;
356362
delete[] pb_graph_node->output_pins;
357363
delete[] pb_graph_node->clock_pins;
358364

365+
if (pb_graph_node->has_secondary) {
366+
delete[] pb_graph_node->input_pins_sec;
367+
delete[] pb_graph_node->output_pins_sec;
368+
delete[] pb_graph_node->clock_pins_sec;
369+
}
370+
359371
delete[] pb_graph_node->num_input_pins;
360372
delete[] pb_graph_node->num_output_pins;
361373
delete[] pb_graph_node->num_clock_pins;
@@ -472,14 +484,22 @@ static void free_pb_type(t_pb_type* pb_type) {
472484

473485
for (int i = 0; i < pb_type->num_ports; ++i) {
474486
vtr::free(pb_type->ports[i].name);
487+
if (pb_type->class_type == LATCH_CLASS)
488+
vtr::free(pb_type->ports_sec[i].name);
475489
if (pb_type->ports[i].port_class) {
476490
vtr::free(pb_type->ports[i].port_class);
491+
if (pb_type->class_type == LATCH_CLASS)
492+
vtr::free(pb_type->ports_sec[i].port_class);
477493
}
478494
if (pb_type->ports[i].port_power) {
479495
vtr::free(pb_type->ports[i].port_power);
496+
if (pb_type->class_type == LATCH_CLASS)
497+
vtr::free(pb_type->ports_sec[i].port_power);
480498
}
481499
}
482500
vtr::free(pb_type->ports);
501+
if (pb_type->class_type == LATCH_CLASS)
502+
vtr::free(pb_type->ports_sec);
483503
}
484504

485505
t_port* findPortByName(const char* name, t_pb_type* pb_type, int* high_index, int* low_index) {
@@ -622,6 +642,35 @@ void alloc_and_load_default_child_for_pb_type(t_pb_type* pb_type,
622642
copy->ports[i].port_power->buffer_type = POWER_BUFFER_TYPE_NONE;
623643
}
624644
}
645+
// Special case for latch - fill secondary data fields
646+
if (pb_type->class_type == LATCH_CLASS) {
647+
copy->num_ports_sec = pb_type->num_ports;
648+
copy->ports_sec = (t_port*)vtr::calloc(pb_type->num_ports, sizeof(t_port));
649+
for (i = 0; i < pb_type->num_ports; i++) {
650+
copy->ports_sec[i].is_clock = pb_type->ports[i].is_clock;
651+
copy->ports_sec[i].model_port = pb_type->ports[i].model_port;
652+
copy->ports_sec[i].type = pb_type->ports[i].type;
653+
copy->ports_sec[i].num_pins = pb_type->ports[i].num_pins;
654+
copy->ports_sec[i].parent_pb_type = copy;
655+
copy->ports_sec[i].name = vtr::strdup(pb_type->ports[i].name);
656+
copy->ports_sec[i].port_class = vtr::strdup(pb_type->ports[i].port_class);
657+
copy->ports_sec[i].port_index_by_type = pb_type->ports[i].port_index_by_type;
658+
copy->ports_sec[i].index = pb_type->ports[i].index;
659+
copy->ports_sec[i].absolute_first_pin_index = pb_type->ports[i].absolute_first_pin_index;
660+
661+
copy->ports_sec[i].port_power = (t_port_power*)vtr::calloc(1,
662+
sizeof(t_port_power));
663+
//Defaults
664+
if (copy->pb_type_power->estimation_method == POWER_METHOD_AUTO_SIZES) {
665+
copy->ports_sec[i].port_power->wire_type = POWER_WIRE_TYPE_AUTO;
666+
copy->ports_sec[i].port_power->buffer_type = POWER_BUFFER_TYPE_AUTO;
667+
} else if (copy->pb_type_power->estimation_method
668+
== POWER_METHOD_SPECIFY_SIZES) {
669+
copy->ports_sec[i].port_power->wire_type = POWER_WIRE_TYPE_IGNORED;
670+
copy->ports_sec[i].port_power->buffer_type = POWER_BUFFER_TYPE_NONE;
671+
}
672+
}
673+
}
625674

626675
copy->annotations = (t_pin_to_pin_annotation*)vtr::calloc(pb_type->num_annotations, sizeof(t_pin_to_pin_annotation));
627676
copy->num_annotations = pb_type->num_annotations;

libs/libarchfpga/src/physical_types.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "vtr_log.h"
55

66
#include "arch_util.h"
7+
#include "arch_types.h"
78

89
static bool switch_type_is_buffered(SwitchType type);
910
static bool switch_type_is_configurable(SwitchType type);
@@ -194,6 +195,131 @@ std::string t_pb_graph_node::hierarchical_type_name() const {
194195
return vtr::join(names.rbegin(), names.rend(), "/");
195196
}
196197

198+
void t_pb_graph_node::update_pins() {
199+
int i, j, i_input = 0, i_output = 0, i_clockport = 0;
200+
t_port* pb_type_ports = pb_type->ports_sec;
201+
202+
VTR_ASSERT(this->has_secondary == false);
203+
this->has_secondary = true;
204+
205+
int pin_count_in_cluster;
206+
for (i = 0; i < this->pb_type->num_ports; i++) {
207+
if (pb_type_ports[i].model_port) {
208+
VTR_ASSERT(this->pb_type->num_modes == 0);
209+
} else {
210+
VTR_ASSERT(this->pb_type->num_modes != 0 || pb_type_ports[i].is_clock);
211+
}
212+
if (pb_type_ports[i].type == IN_PORT && !pb_type_ports[i].is_clock) {
213+
this->input_pins_sec = new t_pb_graph_pin* [this->num_input_ports] { nullptr };
214+
this->input_pins_sec[i_input] = new t_pb_graph_pin[pb_type_ports[i].num_pins];
215+
for (j = 0; j < pb_type_ports[i].num_pins; j++) {
216+
this->input_pins_sec[i_input][j].pin_number = j;
217+
this->input_pins_sec[i_input][j].port = &pb_type_ports[i];
218+
this->input_pins_sec[i_input][j].parent_node = this;
219+
this->input_pins_sec[i_input][j].pin_count_in_cluster = this->input_pins[i_input][j].pin_count_in_cluster;
220+
this->input_pins_sec[i_input][j].parent_pin_class = this->input_pins[i_input][j].parent_pin_class;
221+
if (this->pb_type->blif_model != nullptr) {
222+
if (strcmp(this->pb_type->blif_model, MODEL_OUTPUT) == 0) {
223+
this->input_pins_sec[i_input][j].type = PB_PIN_OUTPAD;
224+
} else if (this->num_clock_ports != 0) {
225+
this->input_pins_sec[i_input][j].type = PB_PIN_SEQUENTIAL;
226+
} else {
227+
this->input_pins_sec[i_input][j].type = PB_PIN_TERMINAL;
228+
}
229+
}
230+
pin_count_in_cluster++;
231+
232+
//Copy timings from primary pins
233+
// sequential timing information
234+
this->input_pins_sec[i_input][j].tsu = this->input_pins[i_input][j].tsu;
235+
this->input_pins_sec[i_input][j].thld = this->input_pins[i_input][j].thld;
236+
this->input_pins_sec[i_input][j].tco_min = this->input_pins[i_input][j].tco_min;
237+
this->input_pins_sec[i_input][j].tco_max = this->input_pins[i_input][j].tco_max;
238+
//this->input_pins_sec[i_input][j].t_pb_graph_pin* associated_clock_pin = nullptr; /* For sequentail elements, the associated clock */
239+
240+
// combinational timing information
241+
this->input_pins_sec[i_input][j].num_pin_timing = this->input_pins[i_input][j].num_pin_timing;
242+
this->input_pins_sec[i_input][j].pin_timing_del_max = this->input_pins[i_input][j].pin_timing_del_max;
243+
this->input_pins_sec[i_input][j].pin_timing_del_min = this->input_pins[i_input][j].pin_timing_del_min;
244+
this->input_pins_sec[i_input][j].num_pin_timing_del_max_annotated = this->input_pins[i_input][j].num_pin_timing_del_max_annotated;
245+
this->input_pins_sec[i_input][j].num_pin_timing_del_min_annotated = this->input_pins[i_input][j].num_pin_timing_del_min_annotated;
246+
//this->input_pins_sec[i_input][j].std::vector<t_pb_graph_pin*> pin_timing; /* timing edge sink pins [0..num_pin_timing-1]*/
247+
}
248+
i_input++;
249+
} else if (pb_type_ports[i].type == OUT_PORT) {
250+
this->output_pins_sec = new t_pb_graph_pin* [this->num_input_ports] { nullptr };
251+
this->output_pins_sec[i_output] = new t_pb_graph_pin[pb_type_ports[i].num_pins];
252+
for (j = 0; j < pb_type_ports[i].num_pins; j++) {
253+
this->output_pins_sec[i_output][j].pin_number = j;
254+
this->output_pins_sec[i_output][j].port = &pb_type_ports[i];
255+
this->output_pins_sec[i_output][j].parent_node = this;
256+
this->output_pins_sec[i_output][j].pin_count_in_cluster = this->output_pins[i_output][j].pin_count_in_cluster;
257+
this->output_pins_sec[i_output][j].parent_pin_class = this->output_pins[i_output][j].parent_pin_class;
258+
this->output_pins_sec[i_output][j].list_of_connectable_input_pin_ptrs = this->output_pins[i_output][j].list_of_connectable_input_pin_ptrs;
259+
this->output_pins_sec[i_output][j].num_connectable_primitive_input_pins = this->output_pins[i_output][j].num_connectable_primitive_input_pins;
260+
if (this->pb_type->blif_model != nullptr) {
261+
if (strcmp(this->pb_type->blif_model, MODEL_INPUT) == 0) {
262+
this->output_pins_sec[i_output][j].type = PB_PIN_INPAD;
263+
} else if (this->num_clock_ports != 0) {
264+
this->output_pins_sec[i_output][j].type = PB_PIN_SEQUENTIAL;
265+
} else {
266+
this->output_pins_sec[i_output][j].type = PB_PIN_TERMINAL;
267+
}
268+
}
269+
pin_count_in_cluster++;
270+
271+
//Copy timings from primary pins
272+
// sequential timing information
273+
this->output_pins_sec[i_output][j].tsu = this->output_pins[i_output][j].tsu;
274+
this->output_pins_sec[i_output][j].thld = this->output_pins[i_output][j].thld;
275+
this->output_pins_sec[i_output][j].tco_min = this->output_pins[i_output][j].tco_min;
276+
this->output_pins_sec[i_output][j].tco_max = this->output_pins[i_output][j].tco_max;
277+
//this->output_pins_sec[i_input][j].t_pb_graph_pin* associated_clock_pin = nullptr; /* For sequentail elements, the associated clock */
278+
279+
// combinational timing information
280+
this->output_pins_sec[i_output][j].num_pin_timing = this->output_pins[i_output][j].num_pin_timing;
281+
this->output_pins_sec[i_output][j].pin_timing_del_max = this->output_pins[i_output][j].pin_timing_del_max;
282+
this->output_pins_sec[i_output][j].pin_timing_del_min = this->output_pins[i_output][j].pin_timing_del_min;
283+
this->output_pins_sec[i_output][j].num_pin_timing_del_max_annotated = this->output_pins[i_output][j].num_pin_timing_del_max_annotated;
284+
this->output_pins_sec[i_output][j].num_pin_timing_del_min_annotated = this->output_pins[i_output][j].num_pin_timing_del_min_annotated;
285+
//this->output_pins_sec[i_input][j].std::vector<t_pb_graph_pin*> pin_timing; /* timing edge sink pins [0..num_pin_timing-1]*/
286+
}
287+
i_output++;
288+
} else {
289+
VTR_ASSERT(pb_type_ports[i].is_clock && pb_type_ports[i].type == IN_PORT);
290+
this->clock_pins_sec = new t_pb_graph_pin* [this->num_input_ports] { nullptr };
291+
this->clock_pins_sec[i_clockport] = new t_pb_graph_pin[pb_type_ports[i].num_pins];
292+
for (j = 0; j < pb_type_ports[i].num_pins; j++) {
293+
this->clock_pins_sec[i_clockport][j].pin_number = j;
294+
this->clock_pins_sec[i_clockport][j].port = &pb_type_ports[i];
295+
this->clock_pins_sec[i_clockport][j].parent_node = this;
296+
this->clock_pins_sec[i_clockport][j].pin_count_in_cluster = this->clock_pins[i_clockport][j].pin_count_in_cluster;
297+
this->clock_pins_sec[i_clockport][j].parent_pin_class = this->clock_pins[i_clockport][j].parent_pin_class;
298+
if (this->pb_type->blif_model != nullptr) {
299+
this->clock_pins_sec[i_clockport][j].type = PB_PIN_CLOCK;
300+
}
301+
pin_count_in_cluster++;
302+
303+
//Copy timings from primary pins
304+
// sequential timing information
305+
this->clock_pins_sec[i_clockport][j].tsu = this->clock_pins[i_clockport][j].tsu;
306+
this->clock_pins_sec[i_clockport][j].thld = this->clock_pins[i_clockport][j].thld;
307+
this->clock_pins_sec[i_clockport][j].tco_min = this->clock_pins[i_clockport][j].tco_min;
308+
this->clock_pins_sec[i_clockport][j].tco_max = this->clock_pins[i_clockport][j].tco_max;
309+
//this->clock_pins_sec[i_clockport][j].t_pb_graph_pin* associated_clock_pin = nullptr; /* For sequentail elements, the associated clock */
310+
311+
// combinational timing information
312+
this->clock_pins_sec[i_clockport][j].num_pin_timing = this->clock_pins[i_clockport][j].num_pin_timing;
313+
this->clock_pins_sec[i_clockport][j].pin_timing_del_max = this->clock_pins[i_clockport][j].pin_timing_del_max;
314+
this->clock_pins_sec[i_clockport][j].pin_timing_del_min = this->clock_pins[i_clockport][j].pin_timing_del_min;
315+
this->clock_pins_sec[i_clockport][j].num_pin_timing_del_max_annotated = this->clock_pins[i_clockport][j].num_pin_timing_del_max_annotated;
316+
this->clock_pins_sec[i_clockport][j].num_pin_timing_del_min_annotated = this->clock_pins[i_clockport][j].num_pin_timing_del_min_annotated;
317+
//this->clock_pins_sec[i_clockport][j].std::vector<t_pb_graph_pin*> pin_timing; /* timing edge sink pins [0..num_pin_timing-1]*/
318+
}
319+
i_clockport++;
320+
}
321+
}
322+
}
197323
/**
198324
* t_pb_graph_pin
199325
*/

libs/libarchfpga/src/physical_types.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -910,9 +910,12 @@ struct t_logical_block_type {
910910
* name: name of the physical block type
911911
* num_pb: maximum number of instances of this physical block type sharing one parent
912912
* blif_model: the string in the blif circuit that corresponds with this pb type
913+
* model: logical model
914+
* model_sec: secondary logical model - used for pb_types matched to 2 available .latch models
913915
* class_type: Special library name
914916
* modes: Different modes accepted
915917
* ports: I/O and clock ports
918+
* ports_sec: secondary I/O and clock ports - used for pb_types matched to 2 available .latch models
916919
* num_clock_pins: A count of the total number of clock pins
917920
* num_input_pins: A count of the total number of input pins
918921
* num_output_pins: A count of the total number of output pins
@@ -927,12 +930,15 @@ struct t_pb_type {
927930
int num_pb = 0;
928931
char* blif_model = nullptr;
929932
t_model* model = nullptr;
933+
t_model* model_sec = nullptr;
930934
enum e_pb_type_class class_type = UNKNOWN_CLASS;
931935

932936
t_mode* modes = nullptr; /* [0..num_modes-1] */
933937
int num_modes = 0;
934938
t_port* ports = nullptr; /* [0..num_ports] */
935939
int num_ports = 0;
940+
t_port* ports_sec = nullptr; /* [0..num_ports] */
941+
int num_ports_sec = 0;
936942

937943
int num_clock_pins = 0;
938944
int num_input_pins = 0; /* inputs not including clock pins */
@@ -1166,6 +1172,7 @@ struct t_pin_to_pin_annotation {
11661172
class t_pb_graph_node {
11671173
public:
11681174
t_pb_type* pb_type;
1175+
bool has_secondary;
11691176

11701177
int placement_index;
11711178

@@ -1189,9 +1196,12 @@ class t_pb_graph_node {
11891196
* */
11901197
std::vector<int> illegal_modes;
11911198

1192-
t_pb_graph_pin** input_pins; /* [0..num_input_ports-1] [0..num_port_pins-1]*/
1193-
t_pb_graph_pin** output_pins; /* [0..num_output_ports-1] [0..num_port_pins-1]*/
1194-
t_pb_graph_pin** clock_pins; /* [0..num_clock_ports-1] [0..num_port_pins-1]*/
1199+
t_pb_graph_pin** input_pins; /* [0..num_input_ports-1] [0..num_port_pins-1]*/
1200+
t_pb_graph_pin** output_pins; /* [0..num_output_ports-1] [0..num_port_pins-1]*/
1201+
t_pb_graph_pin** clock_pins; /* [0..num_clock_ports-1] [0..num_port_pins-1]*/
1202+
t_pb_graph_pin** input_pins_sec; /* [0..num_input_ports-1] [0..num_port_pins-1]*/
1203+
t_pb_graph_pin** output_pins_sec; /* [0..num_output_ports-1] [0..num_port_pins-1]*/
1204+
t_pb_graph_pin** clock_pins_sec; /* [0..num_clock_ports-1] [0..num_port_pins-1]*/
11951205

11961206
int num_input_ports;
11971207
int num_output_ports;
@@ -1234,6 +1244,8 @@ class t_pb_graph_node {
12341244
// Returns a string containing the hierarchical type name of the pb_graph_node
12351245
// Ex: clb[0][default]/lab[0][default]/fle[3][n1_lut6]/ble6[0][default]/lut6[0]
12361246
std::string hierarchical_type_name() const;
1247+
1248+
void update_pins();
12371249
};
12381250

12391251
/* Identify pb pin type for timing purposes */

0 commit comments

Comments
 (0)