mirror of https://github.com/YosysHQ/yosys.git
Added initial implementation of "counters" pass to synth_greenpak4. Can only infer non-resettable down counters for now.
This commit is contained in:
parent
1b42e0c471
commit
1ae33344f4
|
@ -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"));
|
||||||
|
@ -187,6 +187,9 @@ void counters_worker(ModIndex& index, Module */*module*/, Cell *cell, unsigned i
|
||||||
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();
|
||||||
if(rwire->attributes.find("\\init") == rwire->attributes.end())
|
if(rwire->attributes.find("\\init") == rwire->attributes.end())
|
||||||
|
@ -209,26 +212,35 @@ void counters_worker(ModIndex& index, Module */*module*/, Cell *cell, unsigned i
|
||||||
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
|
||||||
log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell));
|
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");
|
||||||
|
|
||||||
if (GetSize(setctrl) == 1) {
|
//Change the cell type
|
||||||
cell->setPort("\\ARST", setctrl);
|
cell->type = celltype;
|
||||||
cell->setParam("\\ARST_POLARITY", setpol);
|
|
||||||
} else {
|
|
||||||
cell->setPort("\\ARST", clrctrl);
|
|
||||||
cell->setParam("\\ARST_POLARITY", clrpol);
|
|
||||||
}
|
|
||||||
|
|
||||||
cell->type = "$adff";
|
//Hook it up to everything
|
||||||
cell->unsetPort("\\SET");
|
cell->setParam("\\RESET_MODE", RTLIL::Const("RISING"));
|
||||||
cell->unsetPort("\\CLR");
|
cell->setParam("\\CLKIN_DIVIDE", RTLIL::Const(1));
|
||||||
cell->setParam("\\ARST_VALUE", reset_val);
|
cell->setParam("\\COUNT_TO", RTLIL::Const(count_value));
|
||||||
cell->unsetParam("\\SET_POLARITY");
|
cell->setPort("\\CLK", clk);
|
||||||
cell->unsetParam("\\CLR_POLARITY");
|
cell->setPort("\\RST", RTLIL::SigSpec(false));
|
||||||
|
cell->setPort("\\OUT", muxsel);
|
||||||
|
|
||||||
return;
|
//Delete the cells we've replaced (let opt_clean handle deleting the now-redundant wires)
|
||||||
*/
|
module->remove(count_mux);
|
||||||
|
module->remove(count_reg);
|
||||||
|
module->remove(underflow_inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CountersPass : public Pass {
|
struct CountersPass : public Pass {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Loading…
Reference in New Issue