Skip to content

Eliminate vtr_free and vtr_malloc/vtr_calloc/vtr_realloc #3040

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 18 commits into from
May 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 46 additions & 115 deletions libs/libarchfpga/src/arch_util.cpp

Large diffs are not rendered by default.

57 changes: 25 additions & 32 deletions libs/libarchfpga/src/echo_arch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,19 +335,19 @@ void PrintArchInfo(FILE* Echo, const t_arch* arch) {
fprintf(Echo, "*************************************************\n");
fprintf(Echo, "Clock:\n");
if (arch->clocks) {
for (int i = 0; i < arch->clocks->num_global_clocks; i++) {
if (arch->clocks->clock_inf[i].autosize_buffer) {
fprintf(Echo, "\tClock[%d]: buffer_size auto C_wire %e", i + 1,
arch->clocks->clock_inf->C_wire);
for (size_t i = 0; i < arch->clocks->size(); i++) {
if ((*arch->clocks)[i].autosize_buffer) {
fprintf(Echo, "\tClock[%zu]: buffer_size auto C_wire %e", i + 1,
(*arch->clocks)[i].C_wire);
} else {
fprintf(Echo, "\tClock[%d]: buffer_size %e C_wire %e", i + 1,
arch->clocks->clock_inf[i].buffer_size,
arch->clocks->clock_inf[i].C_wire);
fprintf(Echo, "\tClock[%zu]: buffer_size %e C_wire %e", i + 1,
(*arch->clocks)[i].buffer_size,
(*arch->clocks)[i].C_wire);
}
fprintf(Echo, "\t\t\t\tstat_prob %f switch_density %f period %e",
arch->clocks->clock_inf[i].prob,
arch->clocks->clock_inf[i].dens,
arch->clocks->clock_inf[i].period);
(*arch->clocks)[i].prob,
(*arch->clocks)[i].dens,
(*arch->clocks)[i].period);
}
}

Expand Down Expand Up @@ -381,51 +381,45 @@ static void print_model(FILE* echo, const t_model& model) {
}

static void PrintPb_types_rec(FILE* Echo, const t_pb_type* pb_type, int level, const LogicalModels& models) {
char* tabs;
std::string tabs = std::string(level, '\t');

tabs = (char*)vtr::malloc((level + 1) * sizeof(char));
for (int i = 0; i < level; i++) {
tabs[i] = '\t';
}
tabs[level] = '\0';

fprintf(Echo, "%spb_type name: %s\n", tabs, pb_type->name);
fprintf(Echo, "%s\tblif_model: %s\n", tabs, pb_type->blif_model);
fprintf(Echo, "%s\tclass_type: %d\n", tabs, pb_type->class_type);
fprintf(Echo, "%s\tnum_modes: %d\n", tabs, pb_type->num_modes);
fprintf(Echo, "%s\tnum_ports: %d\n", tabs, pb_type->num_ports);
fprintf(Echo, "%spb_type name: %s\n", tabs.c_str(), pb_type->name);
fprintf(Echo, "%s\tblif_model: %s\n", tabs.c_str(), pb_type->blif_model);
fprintf(Echo, "%s\tclass_type: %d\n", tabs.c_str(), pb_type->class_type);
fprintf(Echo, "%s\tnum_modes: %d\n", tabs.c_str(), pb_type->num_modes);
fprintf(Echo, "%s\tnum_ports: %d\n", tabs.c_str(), pb_type->num_ports);
for (int i = 0; i < pb_type->num_ports; i++) {
fprintf(Echo, "%s\tport %s type %d num_pins %d\n", tabs,
fprintf(Echo, "%s\tport %s type %d num_pins %d\n", tabs.c_str(),
pb_type->ports[i].name, pb_type->ports[i].type,
pb_type->ports[i].num_pins);
}

if (pb_type->num_modes > 0) { /*one or more modes*/
for (int i = 0; i < pb_type->num_modes; i++) {
fprintf(Echo, "%s\tmode %s:\n", tabs, pb_type->modes[i].name);
fprintf(Echo, "%s\tmode %s:\n", tabs.c_str(), pb_type->modes[i].name);
for (int j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
PrintPb_types_rec(Echo, &pb_type->modes[i].pb_type_children[j],
level + 2, models);
}
for (int j = 0; j < pb_type->modes[i].num_interconnect; j++) {
fprintf(Echo, "%s\t\tinterconnect %d %s %s\n", tabs,
fprintf(Echo, "%s\t\tinterconnect %d %s %s\n", tabs.c_str(),
pb_type->modes[i].interconnect[j].type,
pb_type->modes[i].interconnect[j].input_string,
pb_type->modes[i].interconnect[j].output_string);
for (int k = 0;
k < pb_type->modes[i].interconnect[j].num_annotations;
k++) {
fprintf(Echo, "%s\t\t\tannotation %s %s %d: %s\n", tabs,
fprintf(Echo, "%s\t\t\tannotation %s %s %d: %s\n", tabs.c_str(),
pb_type->modes[i].interconnect[j].annotations[k].input_pins,
pb_type->modes[i].interconnect[j].annotations[k].output_pins,
pb_type->modes[i].interconnect[j].annotations[k].format,
pb_type->modes[i].interconnect[j].annotations[k].value[0]);
pb_type->modes[i].interconnect[j].annotations[k].annotation_entries[0].second.c_str());
}
//Print power info for interconnects
if (pb_type->modes[i].interconnect[j].interconnect_power) {
if (pb_type->modes[i].interconnect[j].interconnect_power->power_usage.dynamic
|| pb_type->modes[i].interconnect[j].interconnect_power->power_usage.leakage) {
fprintf(Echo, "%s\t\t\tpower %e %e\n", tabs,
fprintf(Echo, "%s\t\t\tpower %e %e\n", tabs.c_str(),
pb_type->modes[i].interconnect[j].interconnect_power->power_usage.dynamic,
pb_type->modes[i].interconnect[j].interconnect_power->power_usage.leakage);
}
Expand All @@ -442,20 +436,19 @@ static void PrintPb_types_rec(FILE* Echo, const t_pb_type* pb_type, int level, c
&& pb_type_model_name != LogicalModels::MODEL_INPUT
&& pb_type_model_name != LogicalModels::MODEL_OUTPUT) {
for (int k = 0; k < pb_type->num_annotations; k++) {
fprintf(Echo, "%s\t\t\tannotation %s %s %s %d: %s\n", tabs,
fprintf(Echo, "%s\t\t\tannotation %s %s %s %d: %s\n", tabs.c_str(),
pb_type->annotations[k].clock,
pb_type->annotations[k].input_pins,
pb_type->annotations[k].output_pins,
pb_type->annotations[k].format,
pb_type->annotations[k].value[0]);
pb_type->annotations[k].annotation_entries[0].second.c_str());
}
}
}

if (pb_type->pb_type_power) {
PrintPb_types_recPower(Echo, pb_type, tabs);
PrintPb_types_recPower(Echo, pb_type, tabs.c_str());
}
free(tabs);
}

//Added May 2013 Daniel Chen, help dump arch info after loading from XML
Expand Down
2 changes: 1 addition & 1 deletion libs/libarchfpga/src/logic_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void LogicalModels::free_model_data(t_model& model) {
while (vptr) {
vtr::t_linked_vptr* vptr_prev = vptr;
vptr = vptr->next;
vtr::free(vptr_prev);
delete vptr_prev;
}

if (model.instances)
Expand Down
124 changes: 101 additions & 23 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
#include "clock_types.h"

//Forward declarations
struct t_clock_arch;
struct t_clock_network;
struct t_power_arch;
struct t_interconnect_pins;
Expand Down Expand Up @@ -407,12 +406,6 @@ struct t_grid_def {

/************************* POWER ***********************************/

/* Global clock architecture */
struct t_clock_arch {
int num_global_clocks;
t_clock_network* clock_inf; /* Details about each clock */
};

/* Architecture information for a single clock */
struct t_clock_network {
bool autosize_buffer; /* autosize clock buffers */
Expand All @@ -422,6 +415,15 @@ struct t_clock_network {
float prob; /* Static probability of net assigned to this clock */
float dens; /* Switching density of net assigned to this clock */
float period; /* Period of clock */

t_clock_network() {
autosize_buffer = false;
buffer_size = 0.0f;
C_wire = 0.0f;
prob = 0.0f;
dens = 0.0f;
period = 0.0f;
}
};

/* Power-related architecture information */
Expand All @@ -434,12 +436,26 @@ struct t_power_arch {
float mux_transistor_size;
float FF_size;
float LUT_transistor_size;

t_power_arch() {
C_wire_local = 0.0f;
logical_effort_factor = 0.0f;
local_interc_factor = 0.0f;
transistors_per_SRAM_bit = 0.0f;
mux_transistor_size = 0.0f;
FF_size = 0.0f;
LUT_transistor_size = 0.0f;
}
};

/* Power usage for an entity */
struct t_power_usage {
float dynamic;
float leakage;
t_power_usage() {
dynamic = 0.0f;
leakage = 0.0f;
}
};

/*************************************************************************************************/
Expand Down Expand Up @@ -534,6 +550,18 @@ struct t_port_power {
t_port* scaled_by_port;
int scaled_by_port_pin_idx;
bool reverse_scaled; /* Scale by (1-prob) */

t_port_power() {
wire_type = (e_power_wire_type)0;
wire = {0.0f}; // Default to C = 0.0f
buffer_type = (e_power_buffer_type)0;
buffer_size = 0.0f;
pin_toggle_initialized = false;
energy_per_toggle = 0.0f;
scaled_by_port = nullptr;
scaled_by_port_pin_idx = 0;
reverse_scaled = false;
}
};

/**
Expand Down Expand Up @@ -1150,24 +1178,39 @@ struct t_mode {
*/
struct t_interconnect {
enum e_interconnect type;
char* name = nullptr;
char* name;

char* input_string = nullptr;
char* output_string = nullptr;
char* input_string;
char* output_string;

t_pin_to_pin_annotation* annotations = nullptr; /* [0..num_annotations-1] */
int num_annotations = 0;
bool infer_annotations = false;
t_pin_to_pin_annotation* annotations; /* [0..num_annotations-1] */
int num_annotations;
Copy link
Contributor

Choose a reason for hiding this comment

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

Future: convert annotations and num_annotations to a vector

bool infer_annotations;

int line_num = 0; /* Interconnect is processed later, need to know what line number it messed up on to give proper error message */
int line_num; /* Interconnect is processed later, need to know what line number it messed up on to give proper error message */

int parent_mode_index = 0;
int parent_mode_index;

/* Power related members */
t_mode* parent_mode = nullptr;
t_mode* parent_mode;

t_interconnect_power* interconnect_power = nullptr;
t_interconnect_power* interconnect_power;
t_metadata_dict meta;

t_interconnect() {
type = (e_interconnect)0;
name = nullptr;
input_string = nullptr;
output_string = nullptr;
annotations = nullptr;
num_annotations = 0;
infer_annotations = false;
line_num = 0;
parent_mode_index = 0;
parent_mode = nullptr;
interconnect_power = nullptr;
meta = t_metadata_dict();
}
};

/** Describes I/O and clock ports
Expand Down Expand Up @@ -1205,6 +1248,22 @@ struct t_port {
int absolute_first_pin_index;

t_port_power* port_power;

t_port() {
name = nullptr;
model_port = nullptr;
type = (PORTS)0;
is_clock = false;
is_non_clock_global = false;
num_pins = 0;
equivalent = (PortEquivalence)0;
parent_pb_type = nullptr;
port_class = nullptr;
index = 0;
port_index_by_type = 0;
absolute_first_pin_index = 0;
port_power = nullptr;
}
};

struct t_pb_type_power {
Expand All @@ -1231,6 +1290,15 @@ struct t_interconnect_power {
int num_output_ports;
int num_pins_per_port;
float transistor_cnt;

t_interconnect_power() {
power_usage = t_power_usage();
port_info_initialized = false;
num_input_ports = 0;
num_output_ports = 0;
num_pins_per_port = 0;
transistor_cnt = 0.0f;
}
};

struct t_interconnect_pins {
Expand All @@ -1249,18 +1317,16 @@ struct t_mode_power {
* This is later for additional information.
*
* Data Members:
* value: value/property pair
* prop: value/property pair
* annotation_entries: pairs of annotation subtypes and the annotation values
* type: type of annotation
* format: formatting of data
* input_pins: input pins as string affected by annotation
* output_pins: output pins as string affected by annotation
* clock_pin: clock as string affected by annotation
*/
struct t_pin_to_pin_annotation {
char** value; /* [0..num_value_prop_pairs - 1] */
int* prop; /* [0..num_value_prop_pairs - 1] */
int num_value_prop_pairs;

std::vector<std::pair<int, std::string>> annotation_entries;

enum e_pin_to_pin_annotation_type type;
enum e_pin_to_pin_annotation_format format;
Expand All @@ -1270,6 +1336,17 @@ struct t_pin_to_pin_annotation {
char* clock;

int line_num; /* used to report what line number this annotation is found in architecture file */

t_pin_to_pin_annotation() {
annotation_entries = std::vector<std::pair<int, std::string>>();
input_pins = nullptr;
output_pins = nullptr;
clock = nullptr;

line_num = 0;
type = (e_pin_to_pin_annotation_type)0;
format = (e_pin_to_pin_annotation_format)0;
}
};

/*************************************************************************************************
Expand Down Expand Up @@ -2207,7 +2284,8 @@ struct t_arch {
LogicalModels models;

t_power_arch* power = nullptr;
t_clock_arch* clocks = nullptr;

std::shared_ptr<std::vector<t_clock_network>> clocks;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this a shared_ptr? Do we have multiple copies of this pointer? If not, I think unique_ptr would be a better choice.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is shared by device_ctx.clock_arch. I think @vaughnbetz mentioned that in the future, we should get rid of the pointer entirely by assigning the value to device_ctx.clock_arch at the end. Currently, the code is creating two pointers with the same memory address and assigning a value after which can be dangerous.


//determine which layers in multi-die FPGAs require to build global routing resources
std::vector<bool> layer_global_routing;
Expand Down
Loading