From 3fc1b9f3fdd7f5e8aca25b266cbfea90b519cc42 Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Mon, 28 Aug 2017 22:13:36 -0700 Subject: Finished refactoring counter extraction to be nice and generic. Implemented techmapping from $__COUNT_ to GP_COUNTx cells. --- passes/techmap/extract_counter.cc | 36 +++++++++++++------ techlibs/greenpak4/cells_map.v | 68 +++++++++++++++++++++++++++++++++++ techlibs/greenpak4/synth_greenpak4.cc | 2 +- 3 files changed, 94 insertions(+), 12 deletions(-) diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc index 9f14f5d8b..c3e7e9400 100644 --- a/passes/techmap/extract_counter.cc +++ b/passes/techmap/extract_counter.cc @@ -105,15 +105,20 @@ struct CounterExtraction //attempt to extract a counter centered on the given adder cell //For now we only support DOWN counters. //TODO: up/down support -int counter_tryextract(ModIndex& index, Cell *cell, CounterExtraction& extract, pool& parallel_cells) +int counter_tryextract( + ModIndex& index, + Cell *cell, + CounterExtraction& extract, + pool& parallel_cells, + int maxwidth) { SigMap& sigmap = index.sigmap; //A counter with less than 2 bits makes no sense - //TODO: configurable min/max thresholds + //TODO: configurable min threshold int a_width = cell->getParam("\\A_WIDTH").as_int(); extract.width = a_width; - if(a_width < 2) + if( (a_width < 2) || (a_width > maxwidth) ) return 1; //Second input must be a single bit @@ -287,7 +292,8 @@ void counter_worker( unsigned int& total_counters, pool& cells_to_remove, pool>& cells_to_rename, - pool& parallel_cells) + pool& parallel_cells, + int maxwidth) { SigMap& sigmap = index.sigmap; @@ -295,8 +301,6 @@ void counter_worker( if (cell->type != "$alu") return; - log("Looking at cell %s\n", cell->name.c_str()); - //A input is the count value. Check if it has COUNT_EXTRACT set. //If it's not a wire, don't even try auto port = sigmap(cell->getPort("\\A")); @@ -336,7 +340,7 @@ void counter_worker( //Attempt to extract a counter CounterExtraction extract; - int reason = counter_tryextract(index, cell, extract, parallel_cells); + int reason = counter_tryextract(index, cell, extract, parallel_cells, maxwidth); //Nonzero code - we could not find a matchable counter. //Do nothing, unless extraction was forced in which case give an error @@ -414,7 +418,7 @@ void counter_worker( cell->unsetParam("\\Y_WIDTH"); //Change the cell type - cell->type = "$__COUNT__"; + cell->type = "$__COUNT_"; //Hook up resets if(extract.has_reset) @@ -432,13 +436,13 @@ void counter_worker( //Hook up other stuff //cell->setParam("\\CLKIN_DIVIDE", RTLIL::Const(1)); cell->setParam("\\COUNT_TO", RTLIL::Const(extract.count_value)); - + cell->setParam("\\WIDTH", RTLIL::Const(extract.width)); cell->setPort("\\CLK", extract.clk); cell->setPort("\\OUT", extract.outsig); //Hook up hard-wired ports (for now CE and up/=down are not supported), default to no parallel output cell->setParam("\\HAS_POUT", RTLIL::Const(0)); - cell->setParam("\\HAS_CE", RTLIL::Const("NO")); + cell->setParam("\\HAS_CE", RTLIL::Const(0)); cell->setParam("\\DIRECTION", RTLIL::Const("DOWN")); cell->setPort("\\CE", RTLIL::Const(1)); cell->setPort("\\UP", RTLIL::Const(1)); @@ -478,6 +482,8 @@ struct ExtractCounterPass : public Pass { log("counter cells. Use a target-specific 'techmap' map file to convert those cells\n"); log("to the actual target cells.\n"); log("\n"); + log(" -maxwidth N\n"); + log(" Only extract counters up to N bits wide\n"); log(" -pout X,Y,...\n"); log(" Only allow parallel output from the counter to the listed cell types\n"); log(" (if not specified, parallel outputs are not restricted)\n"); @@ -488,6 +494,7 @@ struct ExtractCounterPass : public Pass { { log_header(design, "Executing EXTRACT_COUNTER pass (find counters in netlist).\n"); + int maxwidth = 64; size_t argidx; pool parallel_cells; for (argidx = 1; argidx < args.size(); argidx++) @@ -513,6 +520,13 @@ struct ExtractCounterPass : public Pass { tmp += pouts[i]; } parallel_cells.insert(RTLIL::IdString(tmp)); + continue; + } + + if (args[argidx] == "-maxwidth" && argidx+1 < args.size()) + { + maxwidth = atoi(args[++argidx].c_str()); + continue; } } extra_args(args, argidx, design); @@ -526,7 +540,7 @@ struct ExtractCounterPass : public Pass { ModIndex index(module); for (auto cell : module->selected_cells()) - counter_worker(index, cell, total_counters, cells_to_remove, cells_to_rename, parallel_cells); + counter_worker(index, cell, total_counters, cells_to_remove, cells_to_rename, parallel_cells, maxwidth); for(auto cell : cells_to_remove) { diff --git a/techlibs/greenpak4/cells_map.v b/techlibs/greenpak4/cells_map.v index f8fb2569a..1450eac2e 100644 --- a/techlibs/greenpak4/cells_map.v +++ b/techlibs/greenpak4/cells_map.v @@ -144,3 +144,71 @@ module \$lut (A, Y); end endgenerate endmodule + +module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP); + + input wire CE; + input wire CLK; + output reg OUT; + output reg[WIDTH-1:0] POUT; + input wire RST; + input wire UP; + + parameter COUNT_TO = 1; + parameter RESET_MODE = "RISING"; + parameter HAS_POUT = 0; + parameter HAS_CE = 0; + parameter WIDTH = 8; + parameter DIRECTION = "DOWN"; + + //If we have a CE, or DIRECTION other than DOWN fail... GP_COUNTx_ADV is not supported yet + if(HAS_CE || (DIRECTION != "DOWN") ) begin + initial begin + $display("ERROR: \$__COUNT__ support for GP_COUNTx_ADV is not yet implemented. This counter should never have been extracted (bug in extract_counter pass?)."); + $finish; + end + end + + //If counter is more than 14 bits wide, complain (also shouldn't happen) + else if(WIDTH > 14) begin + initial begin + $display("ERROR: \$__COUNT__ support for cascaded counters is not yet implemented. This counter should never have been extracted (bug in extract_counter pass?)."); + $finish; + end + end + + //If counter is more than 8 bits wide and has parallel output, we have a problem + else if(WIDTH > 8 && HAS_POUT) begin + initial begin + $display("ERROR: \$__COUNT__ support for 9-14 bit counters with parallel output is not yet implemented. This counter should never have been extracted (bug in extract_counter pass?)."); + $finish; + end + end + + //Looks like a legal counter! Do something with it + else if(WIDTH <= 8) begin + GP_COUNT8 #( + .COUNT_TO(COUNT_TO), + .RESET_MODE(RESET_MODE), + .CLKIN_DIVIDE(1) + ) _TECHMAP_REPLACE_ ( + .CLK(CLK), + .RST(RST), + .OUT(OUT), + .POUT(POUT) + ); + end + + else begin + GP_COUNT14 #( + .COUNT_TO(COUNT_TO), + .RESET_MODE(RESET_MODE), + .CLKIN_DIVIDE(1) + ) _TECHMAP_REPLACE_ ( + .CLK(CLK), + .RST(RST), + .OUT(OUT) + ); + end + +endmodule diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc index 1fb99c348..56ea8003e 100644 --- a/techlibs/greenpak4/synth_greenpak4.cc +++ b/techlibs/greenpak4/synth_greenpak4.cc @@ -155,7 +155,7 @@ struct SynthGreenPAK4Pass : public ScriptPass if (check_label("fine")) { - run("extract_counter"); + run("extract_counter -pout \\GP_DCMP,\\GP_DAC -maxwidth 14"); run("clean"); run("opt -fast -mux_undef -undriven -fine"); run("memory_map"); -- cgit v1.2.3