Merge pull request #4132 from povik/opt_lut_ice40

opt_lut: Replace `-dlogic` with `-tech ice40`
This commit is contained in:
Martin Povišer 2024-01-17 14:26:28 +01:00 committed by GitHub
commit 6a7fad4dd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 30 deletions

View File

@ -24,6 +24,10 @@
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
// Type represents the following constraint: Preserve connections to dedicated
// logic cell <cell_type> that has ports connected to LUT inputs. This includes
// the case where both LUT and dedicated logic input are connected to the same
// constant.
struct dlogic_t { struct dlogic_t {
IdString cell_type; IdString cell_type;
// LUT input idx -> hard cell's port name // LUT input idx -> hard cell's port name
@ -515,16 +519,6 @@ struct OptLutWorker
} }
}; };
static void split(std::vector<std::string> &tokens, const std::string &text, char sep)
{
size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
}
struct OptLutPass : public Pass { struct OptLutPass : public Pass {
OptLutPass() : Pass("opt_lut", "optimize LUT cells") { } OptLutPass() : Pass("opt_lut", "optimize LUT cells") { }
void help() override void help() override
@ -541,6 +535,10 @@ struct OptLutPass : public Pass {
log(" the case where both LUT and dedicated logic input are connected to\n"); log(" the case where both LUT and dedicated logic input are connected to\n");
log(" the same constant.\n"); log(" the same constant.\n");
log("\n"); log("\n");
log(" -tech ice40\n");
log(" treat the design as a LUT-mapped circuit for the iCE40 architecture\n");
log(" and preserve connections to SB_CARRY as appropriate\n");
log("\n");
log(" -limit N\n"); log(" -limit N\n");
log(" only perform the first N combines, then stop. useful for debugging.\n"); log(" only perform the first N combines, then stop. useful for debugging.\n");
log("\n"); log("\n");
@ -555,28 +553,28 @@ struct OptLutPass : public Pass {
size_t argidx; size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) for (argidx = 1; argidx < args.size(); argidx++)
{ {
if (args[argidx] == "-dlogic" && argidx+1 < args.size()) if (args[argidx] == "-tech" && argidx+1 < args.size())
{ {
std::vector<std::string> tokens; std::string tech = args[++argidx];
split(tokens, args[++argidx], ':'); if (tech != "ice40")
if (tokens.size() < 2) log_cmd_error("Unsupported -tech argument: %s\n", tech.c_str());
log_cmd_error("The -dlogic option requires at least one connection.\n");
dlogic_t entry; dlogic = {{
entry.cell_type = "\\" + tokens[0]; ID(SB_CARRY),
for (auto it = tokens.begin() + 1; it != tokens.end(); ++it) { dict<int, IdString>{
std::vector<std::string> conn_tokens; std::make_pair(1, ID(I0)),
split(conn_tokens, *it, '='); std::make_pair(2, ID(I1)),
if (conn_tokens.size() != 2) std::make_pair(3, ID(CI))
log_cmd_error("Invalid format of -dlogic signal mapping.\n"); }
IdString logic_port = "\\" + conn_tokens[0]; }, {
int lut_input = atoi(conn_tokens[1].c_str()); ID(SB_CARRY),
entry.lut_input_port[lut_input] = logic_port; dict<int, IdString>{
} std::make_pair(3, ID(CO))
dlogic.push_back(entry); }
}};
continue; continue;
} }
if (args[argidx] == "-limit" && argidx + 1 < args.size()) if (args[argidx] == "-limit" && argidx + 1 < args.size()) {
{
limit = atoi(args[++argidx].c_str()); limit = atoi(args[++argidx].c_str());
continue; continue;
} }

View File

@ -432,7 +432,7 @@ struct SynthIce40Pass : public ScriptPass
run("ice40_wrapcarry -unwrap"); run("ice40_wrapcarry -unwrap");
run("techmap -map +/ice40/ff_map.v"); run("techmap -map +/ice40/ff_map.v");
run("clean"); run("clean");
run("opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3 -dlogic SB_CARRY:CO=3"); run("opt_lut -tech ice40");
} }
if (check_label("map_cells")) if (check_label("map_cells"))