Skip to content

Commit f056ec4

Browse files
committed
vpr: interchange: add interchange netlist reading support
Signed-off-by: Alessandro Comodi <[email protected]>
1 parent e6c2049 commit f056ec4

13 files changed

+668
-46
lines changed

libs/libarchfpga/src/physical_types.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,6 +1732,12 @@ struct t_clock_arch_spec {
17321732
std::vector<t_clock_connection_arch> clock_connections_arch;
17331733
};
17341734

1735+
struct t_lut_cell {
1736+
std::string name;
1737+
std::string init_param;
1738+
std::vector<std::string> inputs;
1739+
};
1740+
17351741
/* Detailed routing architecture */
17361742
struct t_arch {
17371743
mutable vtr::string_internment strings;
@@ -1750,11 +1756,23 @@ struct t_arch {
17501756
int num_switches;
17511757
t_direct_inf* Directs = nullptr;
17521758
int num_directs = 0;
1759+
17531760
t_model* models = nullptr;
17541761
t_model* model_library = nullptr;
1762+
17551763
t_power_arch* power = nullptr;
17561764
t_clock_arch* clocks = nullptr;
17571765

1766+
// Constants
1767+
std::string gnd_cell;
1768+
std::string vcc_cell;
1769+
1770+
std::string gnd_net = "$__gnd_net";
1771+
std::string vcc_net = "$__vcc_net";
1772+
1773+
// Luts
1774+
std::vector<t_lut_cell> lut_cells;
1775+
17581776
//The name of the switch used for the input connection block (i.e. to
17591777
//connect routing tracks to block pins).
17601778
//This should correspond to a switch in Switches

libs/libarchfpga/src/read_fpga_interchange_arch.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ struct ArchReader {
122122
}
123123

124124
void read_arch() {
125+
process_luts();
125126
process_models();
126127
process_device();
127128

@@ -232,6 +233,14 @@ struct ArchReader {
232233
"Model output ports can not have combinational sink ports");
233234
}
234235

236+
model_port->min_size = 1;
237+
model_port->size = 1;
238+
if (port.isBus()) {
239+
int s = port.getBus().getBusStart();
240+
int e = port.getBus().getBusEnd();
241+
model_port->size = std::abs(e - s) + 1;
242+
}
243+
235244
port_names.insert(std::pair<std::string, enum PORTS>(model_port->name, dir));
236245
//Add the port
237246
if (dir == IN_PORT) {
@@ -245,6 +254,25 @@ struct ArchReader {
245254
}
246255
}
247256

257+
void process_luts() {
258+
// Add LUT Cell definitions
259+
// This is helpful to understand which cells are LUTs
260+
auto lut_def = ar_.getLutDefinitions();
261+
262+
for (auto lut_cell : lut_def.getLutCells()) {
263+
t_lut_cell cell;
264+
cell.name = lut_cell.getCell().cStr();
265+
for (auto input : lut_cell.getInputPins())
266+
cell.inputs.push_back(input.cStr());
267+
268+
auto equation = lut_cell.getEquation();
269+
if (equation.isInitParam())
270+
cell.init_param = equation.getInitParam().cStr();
271+
272+
arch_->lut_cells.push_back(cell);
273+
}
274+
}
275+
248276
// Layout Processing
249277
void process_layout() {
250278
auto strList = ar_.getStrList();

libs/libvtrutil/src/vtr_hash.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ inline void hash_combine(std::size_t& seed, const T& v) {
1515
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
1616
}
1717

18+
struct hash_pair {
19+
template<class T1, class T2>
20+
std::size_t operator()(const std::pair<T1, T2>& pair) const noexcept {
21+
auto hash1 = std::hash<T1>{}(pair.first);
22+
auto hash2 = std::hash<T2>{}(pair.second);
23+
24+
return hash1 ^ hash2;
25+
}
26+
};
27+
1828
} // namespace vtr
1929

2030
#endif

vpr/src/base/atom_netlist_utils.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ void print_netlist_as_blif(FILE* f, const AtomNetlist& netlist) {
9595
AtomPinId pin = *netlist.block_pins(blk_id).begin();
9696

9797
std::string blk_name = netlist.block_name(blk_id);
98-
std::string out_name(blk_name.begin() + 4, blk_name.end()); //+4 to trim out: prefix
98+
99+
std::string out_prefix("out:");
100+
int strip_size = blk_name.substr(0, out_prefix.size()) == out_prefix ? out_prefix.size() : 0;
101+
std::string out_name(blk_name.begin() + strip_size, blk_name.end()); //+4 to trim out: prefix if present
99102

100103
fprintf(f, "%s%s", INDENT, out_name.c_str());
101104

@@ -307,7 +310,7 @@ void print_netlist_as_blif(FILE* f, const AtomNetlist& netlist) {
307310
ports.push_back(port_id);
308311
}
309312

310-
fprintf(f, ".subckt %s \\\n", blk_model->name);
313+
fprintf(f, ".subckt %s \\\n", netlist.block_name(blk_id).c_str());
311314
for (size_t i = 0; i < ports.size(); i++) {
312315
auto width = netlist.port_width(ports[i]);
313316
for (size_t j = 0; j < width; ++j) {

vpr/src/base/read_circuit.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "read_circuit.h"
22
#include "read_blif.h"
3+
#include "read_interchange_netlist.h"
34
#include "atom_netlist.h"
45
#include "atom_netlist_utils.h"
56
#include "echo_files.h"
@@ -21,20 +22,23 @@ static void process_circuit(AtomNetlist& netlist,
2122

2223
static void show_circuit_stats(const AtomNetlist& netlist);
2324

24-
AtomNetlist read_and_process_circuit(e_circuit_format circuit_format,
25-
const char* circuit_file,
26-
const t_model* user_models,
27-
const t_model* library_models,
28-
e_const_gen_inference const_gen_inference,
29-
bool should_absorb_buffers,
30-
bool should_sweep_dangling_primary_ios,
31-
bool should_sweep_dangling_nets,
32-
bool should_sweep_dangling_blocks,
33-
bool should_sweep_constant_primary_outputs,
34-
int verbosity) {
25+
AtomNetlist read_and_process_circuit(e_circuit_format circuit_format, t_vpr_setup& vpr_setup, t_arch& arch) {
26+
// Options
27+
const char* circuit_file = vpr_setup.PackerOpts.circuit_file_name.c_str();
28+
const t_model* user_models = vpr_setup.user_models;
29+
const t_model* library_models = vpr_setup.library_models;
30+
e_const_gen_inference const_gen_inference = vpr_setup.NetlistOpts.const_gen_inference;
31+
bool should_absorb_buffers = vpr_setup.NetlistOpts.absorb_buffer_luts;
32+
bool should_sweep_dangling_primary_ios = vpr_setup.NetlistOpts.sweep_dangling_primary_ios;
33+
bool should_sweep_dangling_nets = vpr_setup.NetlistOpts.sweep_dangling_nets;
34+
bool should_sweep_dangling_blocks = vpr_setup.NetlistOpts.sweep_dangling_blocks;
35+
bool should_sweep_constant_primary_outputs = vpr_setup.NetlistOpts.sweep_constant_primary_outputs;
36+
bool verbosity = vpr_setup.NetlistOpts.netlist_verbosity;
37+
3538
if (circuit_format == e_circuit_format::AUTO) {
3639
auto name_ext = vtr::split_ext(circuit_file);
3740

41+
VTR_LOG("%s\n", circuit_file);
3842
if (name_ext[1] == ".blif") {
3943
circuit_format = e_circuit_format::BLIF;
4044
} else if (name_ext[1] == ".eblif") {
@@ -49,10 +53,18 @@ AtomNetlist read_and_process_circuit(e_circuit_format circuit_format,
4953
{
5054
vtr::ScopedStartFinishTimer t("Load circuit");
5155

52-
VTR_ASSERT(circuit_format == e_circuit_format::BLIF
53-
|| circuit_format == e_circuit_format::EBLIF);
54-
55-
netlist = read_blif(circuit_format, circuit_file, user_models, library_models);
56+
switch (circuit_format) {
57+
case e_circuit_format::BLIF:
58+
case e_circuit_format::EBLIF:
59+
netlist = read_blif(circuit_format, circuit_file, user_models, library_models);
60+
break;
61+
case e_circuit_format::FPGA_INTERCHANGE:
62+
netlist = read_interchange_netlist(circuit_file, arch);
63+
break;
64+
default:
65+
VTR_ASSERT(false);
66+
break;
67+
}
5668
}
5769

5870
if (isEchoFileEnabled(E_ECHO_ATOM_NETLIST_ORIG)) {

vpr/src/base/read_circuit.h

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,11 @@
55
#include "vpr_types.h"
66

77
enum class e_circuit_format {
8-
AUTO, ///<Infer from file extension
9-
BLIF, ///<Strict structural BLIF
10-
EBLIF ///<Structural blif with extensions
8+
AUTO, ///<Infer from file extension
9+
BLIF, ///<Strict structural BLIF
10+
EBLIF, ///<Structural blif with extensions
11+
FPGA_INTERCHANGE ///<FPGA Interhange logical netlis format
1112
};
1213

13-
AtomNetlist read_and_process_circuit(const e_circuit_format circuit_format,
14-
const char* circuit_file,
15-
const t_model* user_models,
16-
const t_model* library_models,
17-
e_const_gen_inference const_gen_inference,
18-
bool should_absorb_buffers,
19-
bool should_sweep_dangling_primary_ios,
20-
bool should_sweep_dangling_nets,
21-
bool should_sweep_dangling_blocks,
22-
bool should_sweep_constant_primary_outputs,
23-
int verbosity);
14+
AtomNetlist read_and_process_circuit(e_circuit_format circuit_format, t_vpr_setup& vpr_setup, t_arch& arch);
2415
#endif

0 commit comments

Comments
 (0)