Skip to content

Commit 5f7bd7c

Browse files
authored
Merge pull request verilog-to-routing#5 from litghost/fasm_param
Add initial FASM parameter support
2 parents b5ae26b + 4597f2d commit 5f7bd7c

File tree

5 files changed

+152
-1
lines changed

5 files changed

+152
-1
lines changed

utils/fasm/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ add_library(fasm
88
src/fasm.h
99
src/lut.cpp
1010
src/lut.h
11+
src/parameters.cpp
12+
src/parameters.h
1113
)
1214
target_include_directories(fasm PUBLIC src)
1315
target_link_libraries(fasm

utils/fasm/src/fasm.cpp

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ void FasmWriterVisitor::visit_all_impl(const t_pb_route *pb_route, const t_pb* p
228228

229229
void FasmWriterVisitor::visit_open_impl(const t_pb* atom) {
230230
check_for_lut(atom);
231+
check_for_param(atom);
231232
}
232233

233234
static AtomNetId _find_atom_input_logical_net(const t_pb* atom, const t_pb_route *pb_route, int atom_input_idx) {
@@ -264,7 +265,6 @@ static LogicVec lut_outputs(const t_pb* atom_pb, size_t num_inputs, const t_pb_r
264265

265266
VTR_ASSERT(gnode->num_input_ports == 1);
266267
//VTR_ASSERT(gnode->num_input_pins[0] >= num_inputs);
267-
std::cerr << num_inputs << std::endl;
268268
std::vector<vtr::LogicValue> inputs(num_inputs, vtr::LogicValue::DONT_CARE);
269269
std::vector<int> permutation(num_inputs, -1);
270270

@@ -424,6 +424,59 @@ static const t_pb_route *find_pb_route(const t_pb* pb) {
424424
return nullptr;
425425
}
426426

427+
void FasmWriterVisitor::check_for_param(const t_pb *atom) {
428+
auto& atom_ctx = g_vpr_ctx.atom();
429+
430+
auto atom_blk_id = atom_ctx.lookup.pb_atom(atom);
431+
if (atom_blk_id == AtomBlockId::INVALID()) {
432+
return;
433+
}
434+
435+
if(atom->pb_graph_node == nullptr ||
436+
atom->pb_graph_node->pb_type == nullptr ||
437+
atom->pb_graph_node->pb_type->meta == nullptr) {
438+
return;
439+
}
440+
441+
const auto *meta = atom->pb_graph_node->pb_type->meta;
442+
if(!meta->has("fasm_params")) {
443+
return;
444+
}
445+
446+
auto iter = parameters_.find(atom->pb_graph_node->pb_type);
447+
448+
if(iter == parameters_.end()) {
449+
Parameters params;
450+
std::string fasm_params = meta->one("fasm_params")->as_string();
451+
for(const auto param : vtr::split(fasm_params, "\n")) {
452+
auto param_parts = vtr::split(vtr::replace_all(param, " ", ""), "=");
453+
if(param_parts.size() == 0) {
454+
continue;
455+
}
456+
VTR_ASSERT(param_parts.size() == 2);
457+
458+
params.AddParameter(param_parts[1], param_parts[0]);
459+
}
460+
461+
auto ret = parameters_.insert(std::make_pair(
462+
atom->pb_graph_node->pb_type,
463+
params));
464+
465+
VTR_ASSERT(ret.second);
466+
iter = ret.first;
467+
}
468+
469+
auto &params = iter->second;
470+
471+
for(auto param : atom_ctx.nlist.block_params(atom_blk_id)) {
472+
auto feature = params.EmitFasmFeature(param.first, param.second);
473+
474+
if(feature.size() > 0) {
475+
output_fasm_features(feature);
476+
}
477+
}
478+
}
479+
427480
void FasmWriterVisitor::check_for_lut(const t_pb* atom) {
428481
auto& atom_ctx = g_vpr_ctx.atom();
429482

@@ -446,6 +499,7 @@ void FasmWriterVisitor::check_for_lut(const t_pb* atom) {
446499

447500
void FasmWriterVisitor::visit_atom_impl(const t_pb* atom) {
448501
check_for_lut(atom);
502+
check_for_param(atom);
449503
}
450504

451505
void FasmWriterVisitor::walk_routing() {

utils/fasm/src/fasm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "netlist_walker.h"
1515
#include "netlist_writer.h"
1616
#include "lut.h"
17+
#include "parameters.h"
1718

1819
namespace fasm {
1920

@@ -42,6 +43,7 @@ class FasmWriterVisitor : public NetlistVisitor {
4243
void walk_routing();
4344
std::string build_clb_prefix(const t_pb_graph_node* pb_graph_node) const;
4445
const LutOutputDefinition* find_lut(const t_pb_graph_node* pb_graph_node);
46+
void check_for_param(const t_pb *atom);
4547

4648
std::ostream& os_;
4749

@@ -53,6 +55,7 @@ class FasmWriterVisitor : public NetlistVisitor {
5355
ClusterBlockId current_blk_id_;
5456
std::vector<t_pb_graph_pin**> pb_graph_pin_lookup_from_index_by_type_;
5557
std::map<const t_pb_type*, std::vector<std::pair<std::string, LutOutputDefinition>>> lut_definitions_;
58+
std::map<const t_pb_type*, Parameters> parameters_;
5659
};
5760

5861
} // namespace fasm

utils/fasm/src/parameters.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include "parameters.h"
2+
#include "vtr_assert.h"
3+
4+
namespace fasm {
5+
6+
void Parameters::AddParameter(const std::string &eblif_parameter, const std::string &fasm_feature) {
7+
auto ret = features_.insert(std::make_pair(eblif_parameter, FeatureParameter()));
8+
9+
VTR_ASSERT(ret.second);
10+
11+
ret.first->second.feature = fasm_feature;
12+
ret.first->second.width = FeatureWidth(fasm_feature);
13+
}
14+
15+
std::string Parameters::EmitFasmFeature(const std::string &eblif_parameter, const std::string &value) {
16+
auto iter = features_.find(eblif_parameter);
17+
if(iter == features_.end()) {
18+
return "";
19+
}
20+
21+
// Parameter should have exactly the expected number of bits.
22+
if(value.size() != iter->second.width) {
23+
vpr_throw(VPR_ERROR_OTHER,
24+
__FILE__, __LINE__, "When emitting FASM for parameter %s, expected width of %d got width of %d, value = \"%s\".",
25+
eblif_parameter.c_str(), iter->second.width, value.size(), value.c_str());
26+
}
27+
VTR_ASSERT(value.size() == iter->second.width);
28+
29+
return vtr::string_fmt("%s=%d'b%s", iter->second.feature.c_str(),
30+
iter->second.width, value.c_str());
31+
}
32+
33+
size_t Parameters::FeatureWidth(const std::string &feature) const {
34+
size_t start_of_address = feature.rfind('[');
35+
size_t end_of_address = feature.rfind(']');
36+
37+
if(start_of_address == std::string::npos) {
38+
VTR_ASSERT(end_of_address == std::string::npos);
39+
return 1;
40+
}
41+
42+
VTR_ASSERT(end_of_address > start_of_address+1);
43+
44+
auto address = feature.substr(start_of_address+1, end_of_address - start_of_address - 1);
45+
46+
size_t address_split = address.find(':');
47+
48+
if(address_split == std::string::npos) {
49+
return 1;
50+
}
51+
52+
VTR_ASSERT(address_split > 0);
53+
VTR_ASSERT(address_split+1 < address.size());
54+
55+
int high_slice = vtr::atoi(address.substr(0, address_split));
56+
int low_slice = vtr::atoi(address.substr(address_split+1));
57+
VTR_ASSERT(high_slice >= low_slice);
58+
59+
return high_slice - low_slice + 1;
60+
}
61+
62+
} // namespace fasm

utils/fasm/src/parameters.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef PARAMETERS_H
2+
#define PARAMETERS_H
3+
4+
#include "netlist_writer.h"
5+
6+
namespace fasm {
7+
8+
// Utility class emit parameters from eblif
9+
class Parameters {
10+
public:
11+
// Adds a parameter mapping between an eblif parameter (e.g. .param <param> <value>)
12+
// to FASM feature.
13+
void AddParameter(const std::string &eblif_parameter, const std::string &fasm_feature);
14+
15+
// Return a FASM feature directive for the given parameter and value.
16+
std::string EmitFasmFeature(const std::string &eblif_parameter, const std::string &value);
17+
private:
18+
struct FeatureParameter {
19+
size_t width;
20+
std::string feature;
21+
};
22+
23+
std::unordered_map<std::string, FeatureParameter> features_;
24+
25+
size_t FeatureWidth(const std::string &feature) const;
26+
};
27+
28+
} // namespace fasm
29+
30+
#endif // PARAMETERS_H

0 commit comments

Comments
 (0)