Added initial implementation of "counters" pass to synth_greenpak4. Can only infer non-resettable down counters for now.

This commit is contained in:
Andrew Zonenberg 2016-03-30 22:40:14 -07:00
parent 1b42e0c471
commit 1ae33344f4
2 changed files with 39 additions and 25 deletions

View File

@ -87,7 +87,7 @@ bool is_unconnected(const RTLIL::SigSpec& port, ModIndex& index)
return true; return true;
} }
void counters_worker(ModIndex& index, Module */*module*/, Cell *cell, unsigned int& total_counters) void counters_worker(ModIndex& index, Module *module, Cell *cell, unsigned int& total_counters)
{ {
SigMap& sigmap = index.sigmap; SigMap& sigmap = index.sigmap;
@ -143,11 +143,11 @@ void counters_worker(ModIndex& index, Module */*module*/, Cell *cell, unsigned i
if(!is_full_bus(aluy, index, cell, "\\Y", count_mux, "\\A")) if(!is_full_bus(aluy, index, cell, "\\Y", count_mux, "\\A"))
return; return;
//B connection of the mux is our overflow value //B connection of the mux is our underflow value
const RTLIL::SigSpec overflow = sigmap(count_mux->getPort("\\B")); const RTLIL::SigSpec underflow = sigmap(count_mux->getPort("\\B"));
if(!overflow.is_fully_const()) if(!underflow.is_fully_const())
return; return;
int count_value = overflow.as_int(); int count_value = underflow.as_int();
//S connection of the mux must come from an inverter (need not be the only load) //S connection of the mux must come from an inverter (need not be the only load)
const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort("\\S")); const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort("\\S"));
@ -186,6 +186,9 @@ void counters_worker(ModIndex& index, Module */*module*/, Cell *cell, unsigned i
return; return;
if(!is_full_bus(cnout, index, count_reg, "\\Q", cell, "\\A", true)) if(!is_full_bus(cnout, index, count_reg, "\\Q", cell, "\\A", true))
return; return;
//Look up the clock from the register
const RTLIL::SigSpec clk = sigmap(count_reg->getPort("\\CLK"));
//Register output net must have an INIT attribute equal to the count value //Register output net must have an INIT attribute equal to the count value
auto rwire = cnout.as_wire(); auto rwire = cnout.as_wire();
@ -208,27 +211,36 @@ void counters_worker(ModIndex& index, Module */*module*/, Cell *cell, unsigned i
count_value, count_value,
log_id(rwire->name), log_id(rwire->name),
count_reg_src.c_str()); count_reg_src.c_str());
//Wipe all of the old connections to the ALU
cell->unsetPort("\\A");
cell->unsetPort("\\B");
cell->unsetPort("\\BI");
cell->unsetPort("\\CI");
cell->unsetPort("\\CO");
cell->unsetPort("\\X");
cell->unsetPort("\\Y");
cell->unsetParam("\\A_SIGNED");
cell->unsetParam("\\A_WIDTH");
cell->unsetParam("\\B_SIGNED");
cell->unsetParam("\\B_WIDTH");
cell->unsetParam("\\Y_WIDTH");
/* //Change the cell type
log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell)); cell->type = celltype;
if (GetSize(setctrl) == 1) { //Hook it up to everything
cell->setPort("\\ARST", setctrl); cell->setParam("\\RESET_MODE", RTLIL::Const("RISING"));
cell->setParam("\\ARST_POLARITY", setpol); cell->setParam("\\CLKIN_DIVIDE", RTLIL::Const(1));
} else { cell->setParam("\\COUNT_TO", RTLIL::Const(count_value));
cell->setPort("\\ARST", clrctrl); cell->setPort("\\CLK", clk);
cell->setParam("\\ARST_POLARITY", clrpol); cell->setPort("\\RST", RTLIL::SigSpec(false));
} cell->setPort("\\OUT", muxsel);
cell->type = "$adff"; //Delete the cells we've replaced (let opt_clean handle deleting the now-redundant wires)
cell->unsetPort("\\SET"); module->remove(count_mux);
cell->unsetPort("\\CLR"); module->remove(count_reg);
cell->setParam("\\ARST_VALUE", reset_val); module->remove(underflow_inv);
cell->unsetParam("\\SET_POLARITY");
cell->unsetParam("\\CLR_POLARITY");
return;
*/
} }
struct CountersPass : public Pass { struct CountersPass : public Pass {

View File

@ -187,6 +187,8 @@ struct SynthGreenPAK4Pass : public Pass {
if (check_label(active, run_from, run_to, "fine")) if (check_label(active, run_from, run_to, "fine"))
{ {
Pass::call(design, "counters");
Pass::call(design, "clean");
Pass::call(design, "opt -fast -mux_undef -undriven -fine"); Pass::call(design, "opt -fast -mux_undef -undriven -fine");
Pass::call(design, "memory_map"); Pass::call(design, "memory_map");
Pass::call(design, "opt -undriven -fine"); Pass::call(design, "opt -undriven -fine");