From 67de78294694cfa1601aa8f431d6cdfb9df9ef01 Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Fri, 6 Mar 2020 18:29:46 +0100 Subject: [PATCH] Do NaN synthesis pattern matching via attributes The previous implementation of NaN synthesis used matching on cell types, which wouldn't scale with adding support for larger cell types. Using attributes allows for simply adding the appropriate width attributes and figuring things out from there. --- dff_nan.pmg | 4 ++-- erase_b2f.pmg | 5 +++-- example/example.ys | 3 ++- nangate.cc | 15 ++++++++++++--- share_nan.pmg | 4 ++-- techlib.sv | 5 +++-- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/dff_nan.pmg b/dff_nan.pmg index ac4cb8b..340e0f0 100644 --- a/dff_nan.pmg +++ b/dff_nan.pmg @@ -4,13 +4,13 @@ match dff endmatch match input - select input->type == \fp3_to_bit + select input->attributes.count(\nan_f2b) index port(input, \Y) === port(dff, \D) optional endmatch match output - select output->type == \bit_to_fp3 + select output->attributes.count(\nan_b2f) index port(output, \A) === port(dff, \Q) optional endmatch diff --git a/erase_b2f.pmg b/erase_b2f.pmg index 2a9acee..eb1aa11 100644 --- a/erase_b2f.pmg +++ b/erase_b2f.pmg @@ -1,8 +1,9 @@ match base - select base->type == \fp3_to_bit + select base->attributes.count(\nan_f2b) endmatch match target - select target->type == \bit_to_fp3 + select target->attributes.count(\nan_b2f) index port(target, \A) === port(base, \Y) + index target->attributes[\nan_b2f] === base->attributes[\nan_f2b] endmatch diff --git a/example/example.ys b/example/example.ys index 3de18f0..262cb4f 100644 --- a/example/example.ys +++ b/example/example.ys @@ -1,4 +1,5 @@ plugin -i nangate.so read_verilog -sv example/example.sv synth_nan -top hello -synth_ice40 -noflatten -top hello +show hello +# synth_ice40 -noflatten -top hello diff --git a/nangate.cc b/nangate.cc index 726b798..a64d4f0 100644 --- a/nangate.cc +++ b/nangate.cc @@ -23,8 +23,12 @@ struct NandToNaNWorker f2b_count += 1; RTLIL::Cell *b2fA = module->addCell(NEW_ID, "\\bit_to_fp3"); RTLIL::Cell *b2fB = module->addCell(NEW_ID, "\\bit_to_fp3"); - RTLIL::Cell *nan = module->addCell(NEW_ID, "\\nan"); + RTLIL::Cell *nan = module->addCell(NEW_ID, "\\nan_fp3"); RTLIL::Cell *f2b = module->addCell(NEW_ID, "\\fp3_to_bit"); + b2fA->attributes[ID(nan_b2f)] = 3; + b2fB->attributes[ID(nan_b2f)] = 3; + nan->attributes[ID(nan_cell)] = 3; + f2b->attributes[ID(nan_f2b)] = 3; b2fA->setPort("\\A", cell->getPort("\\A")); b2fA->setPort("\\Y", module->addWire(NEW_ID, 3)); b2fB->setPort("\\A", cell->getPort("\\B")); @@ -41,8 +45,11 @@ struct NandToNaNWorker not_count += 1; f2b_count += 1; RTLIL::Cell *b2f = module->addCell(NEW_ID, "\\bit_to_fp3"); - RTLIL::Cell *nan = module->addCell(NEW_ID, "\\nan"); + RTLIL::Cell *nan = module->addCell(NEW_ID, "\\nan_fp3"); RTLIL::Cell *f2b = module->addCell(NEW_ID, "\\fp3_to_bit"); + b2f->attributes[ID(nan_b2f)] = 3; + nan->attributes[ID(nan_cell)] = 3; + f2b->attributes[ID(nan_f2b)] = 3; b2f->setPort("\\A", cell->getPort("\\A")); b2f->setPort("\\Y", module->addWire(NEW_ID, 3)); f2b->setPort("\\A", module->addWire(NEW_ID, 3)); @@ -71,7 +78,7 @@ struct NandToNaNPass : public Pass { NandToNaNWorker worker(design, module); log("Replaced %d NAND gates and %d NOT gates.\n", worker.nand_count, worker.not_count); - log("Inserted:\n nan: %5d\n bit_to_fp3: %5d\n fp3_to_bit: %5d\n", + log("Inserted:\n nan_fp3: %5d\n bit_to_fp3: %5d\n fp3_to_bit: %5d\n", worker.nand_count + worker.not_count, worker.b2f_count, worker.f2b_count); } @@ -90,9 +97,11 @@ struct DffToFp3Pass : public Pass { pm.run([&]() { dffs.insert(pm.st.dff); }); for (auto &dff : dffs) { RTLIL::Cell *f2b = module->addCell(NEW_ID, "\\fp3_to_bit"); + f2b->attributes[ID(nan_f2b)] = 3; f2b->setPort("\\A", module->addWire(NEW_ID, 3)); f2b->setPort("\\Y", dff->getPort("\\Q")); RTLIL::Cell *b2f = module->addCell(NEW_ID, "\\bit_to_fp3"); + b2f->attributes[ID(nan_b2f)] = 3; b2f->setPort("\\A", dff->getPort("\\D")); b2f->setPort("\\Y", module->addWire(NEW_ID, 3)); for (int i = 0; i < 3; i++) { diff --git a/share_nan.pmg b/share_nan.pmg index 571f3b8..fa778ff 100644 --- a/share_nan.pmg +++ b/share_nan.pmg @@ -1,9 +1,9 @@ match cvt_a - select cvt_a->type.in(\fp3_to_bit, \bit_to_fp3) + select cvt_a->attributes.count(\nan_b2f) || cvt_a->attributes.count(\nan_f2b) endmatch match cvt_b - select cvt_b->type.in(\fp3_to_bit, \bit_to_fp3) + select cvt_b->attributes.count(\nan_b2f) || cvt_b->attributes.count(\nan_f2b) index cvt_b->type === cvt_a->type index port(cvt_b, \A) === port(cvt_a, \A) endmatch diff --git a/techlib.sv b/techlib.sv index bdcd6a1..4f4717a 100644 --- a/techlib.sv +++ b/techlib.sv @@ -11,9 +11,10 @@ // A NaN gate! Computes `Inf - max(x+y, -Inf)`. // See http://tom7.org/nand/ -module nan( +module nan_fp3( input [2:0] A, - input [2:0] B, output reg [2:0] Y + input [2:0] B, + output reg [2:0] Y ); always begin -- 2.43.2