mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-06 17:44:09 +00:00
Added read-enable to memory model
This commit is contained in:
parent
ec92c89659
commit
924d9d6e86
|
@ -1220,6 +1220,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
id2ast->meminfo(mem_width, mem_size, addr_bits);
|
id2ast->meminfo(mem_width, mem_size, addr_bits);
|
||||||
|
|
||||||
cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1));
|
cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1));
|
||||||
|
cell->setPort("\\EN", RTLIL::SigSpec(RTLIL::State::Sx, 1));
|
||||||
cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits));
|
cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits));
|
||||||
cell->setPort("\\DATA", RTLIL::SigSpec(wire));
|
cell->setPort("\\DATA", RTLIL::SigSpec(wire));
|
||||||
|
|
||||||
|
|
|
@ -692,7 +692,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set<Netlist*
|
||||||
cell->parameters["\\TRANSPARENT"] = false;
|
cell->parameters["\\TRANSPARENT"] = false;
|
||||||
cell->parameters["\\ABITS"] = GetSize(addr);
|
cell->parameters["\\ABITS"] = GetSize(addr);
|
||||||
cell->parameters["\\WIDTH"] = GetSize(data);
|
cell->parameters["\\WIDTH"] = GetSize(data);
|
||||||
cell->setPort("\\CLK", RTLIL::State::S0);
|
cell->setPort("\\CLK", RTLIL::State::Sx);
|
||||||
|
cell->setPort("\\EN", RTLIL::State::Sx);
|
||||||
cell->setPort("\\ADDR", addr);
|
cell->setPort("\\ADDR", addr);
|
||||||
cell->setPort("\\DATA", data);
|
cell->setPort("\\DATA", data);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -122,7 +122,7 @@ struct CellTypes
|
||||||
void setup_internals_mem()
|
void setup_internals_mem()
|
||||||
{
|
{
|
||||||
IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN";
|
IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN";
|
||||||
IdString Q = "\\Q", D = "\\D", ADDR = "\\ADDR", DATA = "\\DATA";
|
IdString Q = "\\Q", D = "\\D", ADDR = "\\ADDR", DATA = "\\DATA", RD_EN = "\\RD_EN";
|
||||||
IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN";
|
IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN";
|
||||||
IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA";
|
IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA";
|
||||||
IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT";
|
IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT";
|
||||||
|
@ -135,10 +135,10 @@ struct CellTypes
|
||||||
setup_type("$dlatch", {EN, D}, {Q});
|
setup_type("$dlatch", {EN, D}, {Q});
|
||||||
setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q});
|
setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q});
|
||||||
|
|
||||||
setup_type("$memrd", {CLK, ADDR}, {DATA});
|
setup_type("$memrd", {CLK, EN, ADDR}, {DATA});
|
||||||
setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>());
|
setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>());
|
||||||
setup_type("$meminit", {ADDR, DATA}, pool<RTLIL::IdString>());
|
setup_type("$meminit", {ADDR, DATA}, pool<RTLIL::IdString>());
|
||||||
setup_type("$mem", {RD_CLK, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
|
setup_type("$mem", {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
|
||||||
|
|
||||||
setup_type("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT});
|
setup_type("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT});
|
||||||
}
|
}
|
||||||
|
|
|
@ -947,6 +947,7 @@ namespace {
|
||||||
param_bool("\\CLK_POLARITY");
|
param_bool("\\CLK_POLARITY");
|
||||||
param_bool("\\TRANSPARENT");
|
param_bool("\\TRANSPARENT");
|
||||||
port("\\CLK", 1);
|
port("\\CLK", 1);
|
||||||
|
port("\\EN", 1);
|
||||||
port("\\ADDR", param("\\ABITS"));
|
port("\\ADDR", param("\\ABITS"));
|
||||||
port("\\DATA", param("\\WIDTH"));
|
port("\\DATA", param("\\WIDTH"));
|
||||||
check_expected();
|
check_expected();
|
||||||
|
@ -986,6 +987,7 @@ namespace {
|
||||||
param_bits("\\WR_CLK_ENABLE", std::max(1, param("\\WR_PORTS")));
|
param_bits("\\WR_CLK_ENABLE", std::max(1, param("\\WR_PORTS")));
|
||||||
param_bits("\\WR_CLK_POLARITY", std::max(1, param("\\WR_PORTS")));
|
param_bits("\\WR_CLK_POLARITY", std::max(1, param("\\WR_PORTS")));
|
||||||
port("\\RD_CLK", param("\\RD_PORTS"));
|
port("\\RD_CLK", param("\\RD_PORTS"));
|
||||||
|
port("\\RD_EN", param("\\RD_PORTS"));
|
||||||
port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS"));
|
port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS"));
|
||||||
port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH"));
|
port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH"));
|
||||||
port("\\WR_CLK", param("\\WR_PORTS"));
|
port("\\WR_CLK", param("\\WR_PORTS"));
|
||||||
|
|
|
@ -220,8 +220,9 @@ cell is created. Having individual cells for read and write ports has the advant
|
||||||
consolidated using resource sharing passes. In some cases this drastically reduces the number of required
|
consolidated using resource sharing passes. In some cases this drastically reduces the number of required
|
||||||
ports on the memory cell.
|
ports on the memory cell.
|
||||||
|
|
||||||
The {\tt \$memrd} cells have a clock input \B{CLK}, an address input \B{ADDR} and a data output
|
The {\tt \$memrd} cells have a clock input \B{CLK}, an enable input \B{EN}, an
|
||||||
\B{DATA}. They also have the following parameters:
|
address input \B{ADDR}, and a data output \B{DATA}. They also have the
|
||||||
|
following parameters:
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \B{MEMID} \\
|
\item \B{MEMID} \\
|
||||||
|
@ -322,6 +323,9 @@ The {\tt \$mem} cell has the following ports:
|
||||||
\item \B{RD\_CLK} \\
|
\item \B{RD\_CLK} \\
|
||||||
This input is \B{RD\_PORTS} bits wide, containing all clock signals for the read ports.
|
This input is \B{RD\_PORTS} bits wide, containing all clock signals for the read ports.
|
||||||
|
|
||||||
|
\item \B{RD\_EN} \\
|
||||||
|
This input is \B{RD\_PORTS} bits wide, containing all enable signals for the read ports.
|
||||||
|
|
||||||
\item \B{RD\_ADDR} \\
|
\item \B{RD\_ADDR} \\
|
||||||
This input is \B{RD\_PORTS}*\B{ABITS} bits wide, containing all address signals for the read ports.
|
This input is \B{RD\_PORTS}*\B{ABITS} bits wide, containing all address signals for the read ports.
|
||||||
|
|
||||||
|
|
|
@ -112,15 +112,15 @@ struct rules_t
|
||||||
if (ports[i] != other.ports[i])
|
if (ports[i] != other.ports[i])
|
||||||
log_error("Bram %s variants %d and %d have different number of %c-ports.\n", log_id(name), variant, other.variant, 'A'+i);
|
log_error("Bram %s variants %d and %d have different number of %c-ports.\n", log_id(name), variant, other.variant, 'A'+i);
|
||||||
if (wrmode[i] != other.wrmode[i])
|
if (wrmode[i] != other.wrmode[i])
|
||||||
variant_params[stringf("\\CFG_WRMODE_%c", 'A' + i)] = wrmode[1];
|
variant_params[stringf("\\CFG_WRMODE_%c", 'A' + i)] = wrmode[i];
|
||||||
if (enable[i] != other.enable[i])
|
if (enable[i] != other.enable[i])
|
||||||
variant_params[stringf("\\CFG_ENABLE_%c", 'A' + i)] = enable[1];
|
variant_params[stringf("\\CFG_ENABLE_%c", 'A' + i)] = enable[i];
|
||||||
if (transp[i] != other.transp[i])
|
if (transp[i] != other.transp[i])
|
||||||
variant_params[stringf("\\CFG_TRANSP_%c", 'A' + i)] = transp[1];
|
variant_params[stringf("\\CFG_TRANSP_%c", 'A' + i)] = transp[i];
|
||||||
if (clocks[i] != other.clocks[i])
|
if (clocks[i] != other.clocks[i])
|
||||||
variant_params[stringf("\\CFG_CLOCKS_%c", 'A' + i)] = clocks[1];
|
variant_params[stringf("\\CFG_CLOCKS_%c", 'A' + i)] = clocks[i];
|
||||||
if (clkpol[i] != other.clkpol[i])
|
if (clkpol[i] != other.clkpol[i])
|
||||||
variant_params[stringf("\\CFG_CLKPOL_%c", 'A' + i)] = clkpol[1];
|
variant_params[stringf("\\CFG_CLKPOL_%c", 'A' + i)] = clkpol[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -429,6 +429,7 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram,
|
||||||
rd_clkpol.extend_u0(rd_ports);
|
rd_clkpol.extend_u0(rd_ports);
|
||||||
rd_transp.extend_u0(rd_ports);
|
rd_transp.extend_u0(rd_ports);
|
||||||
|
|
||||||
|
SigSpec rd_en = cell->getPort("\\RD_EN");
|
||||||
SigSpec rd_clk = cell->getPort("\\RD_CLK");
|
SigSpec rd_clk = cell->getPort("\\RD_CLK");
|
||||||
SigSpec rd_data = cell->getPort("\\RD_DATA");
|
SigSpec rd_data = cell->getPort("\\RD_DATA");
|
||||||
SigSpec rd_addr = cell->getPort("\\RD_ADDR");
|
SigSpec rd_addr = cell->getPort("\\RD_ADDR");
|
||||||
|
@ -688,6 +689,10 @@ grow_read_ports:;
|
||||||
log(" Bram port %c%d.%d has incompatible clock polarity.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
|
log(" Bram port %c%d.%d has incompatible clock polarity.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
|
||||||
goto skip_bram_rport;
|
goto skip_bram_rport;
|
||||||
}
|
}
|
||||||
|
if (rd_en[cell_port_i] != State::S1 && pi.enable == 0) {
|
||||||
|
log(" Bram port %c%d.%d has no read enable input.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
|
||||||
|
goto skip_bram_rport;
|
||||||
|
}
|
||||||
skip_bram_rport_clkcheck:
|
skip_bram_rport_clkcheck:
|
||||||
if (read_transp.count(pi.transp) && read_transp.at(pi.transp) != transp) {
|
if (read_transp.count(pi.transp) && read_transp.at(pi.transp) != transp) {
|
||||||
if (match.make_transp && wr_ports <= 1) {
|
if (match.make_transp && wr_ports <= 1) {
|
||||||
|
@ -713,6 +718,7 @@ grow_read_ports:;
|
||||||
clock_polarities[pi.clkpol] = clkdom.second;
|
clock_polarities[pi.clkpol] = clkdom.second;
|
||||||
read_transp[pi.transp] = transp;
|
read_transp[pi.transp] = transp;
|
||||||
pi.sig_clock = clkdom.first;
|
pi.sig_clock = clkdom.first;
|
||||||
|
pi.sig_en = rd_en[cell_port_i];
|
||||||
pi.effective_clkpol = clkdom.second;
|
pi.effective_clkpol = clkdom.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -886,6 +892,8 @@ grow_read_ports:;
|
||||||
|
|
||||||
if (pi.make_outreg) {
|
if (pi.make_outreg) {
|
||||||
SigSpec bram_dout_q = module->addWire(NEW_ID, bram.dbits);
|
SigSpec bram_dout_q = module->addWire(NEW_ID, bram.dbits);
|
||||||
|
if (!pi.sig_en.empty())
|
||||||
|
bram_dout = module->Mux(NEW_ID, bram_dout_q, bram_dout, pi.sig_en);
|
||||||
module->addDff(NEW_ID, pi.sig_clock, bram_dout, bram_dout_q, pi.effective_clkpol);
|
module->addDff(NEW_ID, pi.sig_clock, bram_dout, bram_dout_q, pi.effective_clkpol);
|
||||||
bram_dout = bram_dout_q;
|
bram_dout = bram_dout_q;
|
||||||
}
|
}
|
||||||
|
@ -1126,7 +1134,7 @@ struct MemoryBramPass : public Pass {
|
||||||
log(" groups 2 # number of port groups\n");
|
log(" groups 2 # number of port groups\n");
|
||||||
log(" ports 1 1 # number of ports in each group\n");
|
log(" ports 1 1 # number of ports in each group\n");
|
||||||
log(" wrmode 1 0 # set to '1' if this groups is write ports\n");
|
log(" wrmode 1 0 # set to '1' if this groups is write ports\n");
|
||||||
log(" enable 4 0 # number of enable bits (for write ports)\n");
|
log(" enable 4 1 # number of enable bits\n");
|
||||||
log(" transp 0 2 # transparent (for read ports)\n");
|
log(" transp 0 2 # transparent (for read ports)\n");
|
||||||
log(" clocks 1 2 # clock configuration\n");
|
log(" clocks 1 2 # clock configuration\n");
|
||||||
log(" clkpol 2 2 # clock polarity configuration\n");
|
log(" clkpol 2 2 # clock polarity configuration\n");
|
||||||
|
|
|
@ -57,6 +57,7 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
|
||||||
SigSpec sig_rd_transparent;
|
SigSpec sig_rd_transparent;
|
||||||
SigSpec sig_rd_addr;
|
SigSpec sig_rd_addr;
|
||||||
SigSpec sig_rd_data;
|
SigSpec sig_rd_data;
|
||||||
|
SigSpec sig_rd_en;
|
||||||
|
|
||||||
std::vector<Cell*> memcells;
|
std::vector<Cell*> memcells;
|
||||||
|
|
||||||
|
@ -139,22 +140,27 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
|
||||||
SigSpec transparent = SigSpec(cell->parameters["\\TRANSPARENT"]);
|
SigSpec transparent = SigSpec(cell->parameters["\\TRANSPARENT"]);
|
||||||
SigSpec addr = sigmap(cell->getPort("\\ADDR"));
|
SigSpec addr = sigmap(cell->getPort("\\ADDR"));
|
||||||
SigSpec data = sigmap(cell->getPort("\\DATA"));
|
SigSpec data = sigmap(cell->getPort("\\DATA"));
|
||||||
|
SigSpec en = sigmap(cell->getPort("\\EN"));
|
||||||
|
|
||||||
clk.extend_u0(1, false);
|
if (!en.is_fully_zero())
|
||||||
clk_enable.extend_u0(1, false);
|
{
|
||||||
clk_polarity.extend_u0(1, false);
|
clk.extend_u0(1, false);
|
||||||
transparent.extend_u0(1, false);
|
clk_enable.extend_u0(1, false);
|
||||||
addr.extend_u0(addr_bits, false);
|
clk_polarity.extend_u0(1, false);
|
||||||
data.extend_u0(memory->width, false);
|
transparent.extend_u0(1, false);
|
||||||
|
addr.extend_u0(addr_bits, false);
|
||||||
|
data.extend_u0(memory->width, false);
|
||||||
|
|
||||||
sig_rd_clk.append(clk);
|
sig_rd_clk.append(clk);
|
||||||
sig_rd_clk_enable.append(clk_enable);
|
sig_rd_clk_enable.append(clk_enable);
|
||||||
sig_rd_clk_polarity.append(clk_polarity);
|
sig_rd_clk_polarity.append(clk_polarity);
|
||||||
sig_rd_transparent.append(transparent);
|
sig_rd_transparent.append(transparent);
|
||||||
sig_rd_addr.append(addr);
|
sig_rd_addr.append(addr);
|
||||||
sig_rd_data.append(data);
|
sig_rd_data.append(data);
|
||||||
|
sig_rd_en.append(en);
|
||||||
|
|
||||||
rd_ports++;
|
rd_ports++;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,6 +209,7 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
|
||||||
mem->setPort("\\RD_CLK", sig_rd_clk);
|
mem->setPort("\\RD_CLK", sig_rd_clk);
|
||||||
mem->setPort("\\RD_ADDR", sig_rd_addr);
|
mem->setPort("\\RD_ADDR", sig_rd_addr);
|
||||||
mem->setPort("\\RD_DATA", sig_rd_data);
|
mem->setPort("\\RD_DATA", sig_rd_data);
|
||||||
|
mem->setPort("\\RD_EN", sig_rd_en);
|
||||||
|
|
||||||
for (auto c : memcells)
|
for (auto c : memcells)
|
||||||
module->remove(c);
|
module->remove(c);
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct MemoryDffWorker
|
||||||
vector<Cell*> dff_cells;
|
vector<Cell*> dff_cells;
|
||||||
dict<SigBit, SigBit> invbits;
|
dict<SigBit, SigBit> invbits;
|
||||||
dict<SigBit, int> sigbit_users_count;
|
dict<SigBit, int> sigbit_users_count;
|
||||||
|
dict<SigSpec, Cell*> mux_cells_a, mux_cells_b;
|
||||||
|
|
||||||
MemoryDffWorker(Module *module) : module(module), sigmap(module) { }
|
MemoryDffWorker(Module *module) : module(module), sigmap(module) { }
|
||||||
|
|
||||||
|
@ -150,16 +151,44 @@ struct MemoryDffWorker
|
||||||
if (sigbit_users_count[bit] > 1)
|
if (sigbit_users_count[bit] > 1)
|
||||||
goto skip_ff_after_read_merging;
|
goto skip_ff_after_read_merging;
|
||||||
|
|
||||||
if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx))
|
if (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data))
|
||||||
{
|
{
|
||||||
disconnect_dff(sig_data);
|
bool enable_invert = mux_cells_a.count(sig_data);
|
||||||
cell->setPort("\\CLK", clk_data);
|
Cell *mux = enable_invert ? mux_cells_a.at(sig_data) : mux_cells_b.at(sig_data);
|
||||||
cell->setPort("\\DATA", sig_data);
|
SigSpec check_q = sigmap(mux->getPort(enable_invert ? "\\B" : "\\A"));
|
||||||
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
|
|
||||||
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
|
sig_data = sigmap(mux->getPort("\\Y"));
|
||||||
cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
|
for (auto bit : sig_data)
|
||||||
log("merged data $dff to cell.\n");
|
if (sigbit_users_count[bit] > 1)
|
||||||
return;
|
goto skip_ff_after_read_merging;
|
||||||
|
|
||||||
|
if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx) && sig_data == check_q)
|
||||||
|
{
|
||||||
|
disconnect_dff(sig_data);
|
||||||
|
cell->setPort("\\CLK", clk_data);
|
||||||
|
cell->setPort("\\EN", enable_invert ? module->LogicNot(NEW_ID, mux->getPort("\\S")) : mux->getPort("\\S"));
|
||||||
|
cell->setPort("\\DATA", sig_data);
|
||||||
|
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
|
||||||
|
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
|
||||||
|
cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
|
||||||
|
log("merged data $dff with rd enable to cell.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx))
|
||||||
|
{
|
||||||
|
disconnect_dff(sig_data);
|
||||||
|
cell->setPort("\\CLK", clk_data);
|
||||||
|
cell->setPort("\\EN", State::S1);
|
||||||
|
cell->setPort("\\DATA", sig_data);
|
||||||
|
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
|
||||||
|
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
|
||||||
|
cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
|
||||||
|
log("merged data $dff to cell.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_ff_after_read_merging:;
|
skip_ff_after_read_merging:;
|
||||||
|
@ -169,6 +198,7 @@ struct MemoryDffWorker
|
||||||
clk_addr != RTLIL::SigSpec(RTLIL::State::Sx))
|
clk_addr != RTLIL::SigSpec(RTLIL::State::Sx))
|
||||||
{
|
{
|
||||||
cell->setPort("\\CLK", clk_addr);
|
cell->setPort("\\CLK", clk_addr);
|
||||||
|
cell->setPort("\\EN", State::S1);
|
||||||
cell->setPort("\\ADDR", sig_addr);
|
cell->setPort("\\ADDR", sig_addr);
|
||||||
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
|
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
|
||||||
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
|
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
|
||||||
|
@ -191,6 +221,10 @@ struct MemoryDffWorker
|
||||||
for (auto cell : module->cells()) {
|
for (auto cell : module->cells()) {
|
||||||
if (cell->type == "$dff")
|
if (cell->type == "$dff")
|
||||||
dff_cells.push_back(cell);
|
dff_cells.push_back(cell);
|
||||||
|
if (cell->type == "$mux") {
|
||||||
|
mux_cells_a[sigmap(cell->getPort("\\A"))] = cell;
|
||||||
|
mux_cells_b[sigmap(cell->getPort("\\B"))] = cell;
|
||||||
|
}
|
||||||
if (cell->type == "$not" || cell->type == "$_NOT_" || (cell->type == "$logic_not" && GetSize(cell->getPort("\\A")) == 1)) {
|
if (cell->type == "$not" || cell->type == "$_NOT_" || (cell->type == "$logic_not" && GetSize(cell->getPort("\\A")) == 1)) {
|
||||||
SigSpec sig_a = cell->getPort("\\A");
|
SigSpec sig_a = cell->getPort("\\A");
|
||||||
SigSpec sig_y = cell->getPort("\\Y");
|
SigSpec sig_y = cell->getPort("\\Y");
|
||||||
|
|
|
@ -200,34 +200,43 @@ struct MemoryMapWorker
|
||||||
|
|
||||||
if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1)
|
if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1)
|
||||||
{
|
{
|
||||||
|
RTLIL::Cell *dff_cell = nullptr;
|
||||||
|
|
||||||
if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1)
|
if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1)
|
||||||
{
|
{
|
||||||
RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
|
dff_cell = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
|
||||||
c->parameters["\\WIDTH"] = RTLIL::Const(mem_abits);
|
dff_cell->parameters["\\WIDTH"] = RTLIL::Const(mem_abits);
|
||||||
c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
|
dff_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
|
||||||
c->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
|
dff_cell->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
|
||||||
c->setPort("\\D", rd_addr);
|
dff_cell->setPort("\\D", rd_addr);
|
||||||
count_dff++;
|
count_dff++;
|
||||||
|
|
||||||
RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits);
|
RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits);
|
||||||
|
|
||||||
c->setPort("\\Q", RTLIL::SigSpec(w));
|
dff_cell->setPort("\\Q", RTLIL::SigSpec(w));
|
||||||
rd_addr = RTLIL::SigSpec(w);
|
rd_addr = RTLIL::SigSpec(w);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
|
dff_cell = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
|
||||||
c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
|
dff_cell->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
|
||||||
c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
|
dff_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
|
||||||
c->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
|
dff_cell->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
|
||||||
c->setPort("\\Q", rd_signals.back());
|
dff_cell->setPort("\\Q", rd_signals.back());
|
||||||
count_dff++;
|
count_dff++;
|
||||||
|
|
||||||
RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width);
|
RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width);
|
||||||
|
|
||||||
rd_signals.clear();
|
rd_signals.clear();
|
||||||
rd_signals.push_back(RTLIL::SigSpec(w));
|
rd_signals.push_back(RTLIL::SigSpec(w));
|
||||||
c->setPort("\\D", rd_signals.back());
|
dff_cell->setPort("\\D", rd_signals.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
SigBit en_bit = cell->getPort("\\RD_EN").extract(i);
|
||||||
|
if (en_bit != State::S1) {
|
||||||
|
SigSpec new_d = module->Mux(genid(cell->name, "$rdenmux", i),
|
||||||
|
dff_cell->getPort("\\Q"), dff_cell->getPort("\\D"), en_bit);
|
||||||
|
dff_cell->setPort("\\D", new_d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
|
||||||
cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_POLARITY")).extract(i, 1).as_const();
|
cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_POLARITY")).extract(i, 1).as_const();
|
||||||
cell->parameters["\\TRANSPARENT"] = RTLIL::SigSpec(memory->parameters.at("\\RD_TRANSPARENT")).extract(i, 1).as_const();
|
cell->parameters["\\TRANSPARENT"] = RTLIL::SigSpec(memory->parameters.at("\\RD_TRANSPARENT")).extract(i, 1).as_const();
|
||||||
cell->setPort("\\CLK", memory->getPort("\\RD_CLK").extract(i, 1));
|
cell->setPort("\\CLK", memory->getPort("\\RD_CLK").extract(i, 1));
|
||||||
|
cell->setPort("\\EN", memory->getPort("\\RD_EN").extract(i, 1));
|
||||||
cell->setPort("\\ADDR", memory->getPort("\\RD_ADDR").extract(i*abits, abits));
|
cell->setPort("\\ADDR", memory->getPort("\\RD_ADDR").extract(i*abits, abits));
|
||||||
cell->setPort("\\DATA", memory->getPort("\\RD_DATA").extract(i*mem->width, mem->width));
|
cell->setPort("\\DATA", memory->getPort("\\RD_DATA").extract(i*mem->width, mem->width));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1494,7 +1494,7 @@ endmodule
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
`ifndef SIMLIB_NOMEM
|
`ifndef SIMLIB_NOMEM
|
||||||
|
|
||||||
module \$memrd (CLK, ADDR, DATA);
|
module \$memrd (CLK, EN, ADDR, DATA);
|
||||||
|
|
||||||
parameter MEMID = "";
|
parameter MEMID = "";
|
||||||
parameter ABITS = 8;
|
parameter ABITS = 8;
|
||||||
|
@ -1504,7 +1504,7 @@ parameter CLK_ENABLE = 0;
|
||||||
parameter CLK_POLARITY = 0;
|
parameter CLK_POLARITY = 0;
|
||||||
parameter TRANSPARENT = 0;
|
parameter TRANSPARENT = 0;
|
||||||
|
|
||||||
input CLK;
|
input CLK, EN;
|
||||||
input [ABITS-1:0] ADDR;
|
input [ABITS-1:0] ADDR;
|
||||||
output [WIDTH-1:0] DATA;
|
output [WIDTH-1:0] DATA;
|
||||||
|
|
||||||
|
@ -1568,7 +1568,7 @@ endmodule
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
|
module \$mem (RD_CLK, RD_EN, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
|
||||||
|
|
||||||
parameter MEMID = "";
|
parameter MEMID = "";
|
||||||
parameter signed SIZE = 4;
|
parameter signed SIZE = 4;
|
||||||
|
@ -1587,6 +1587,7 @@ parameter WR_CLK_ENABLE = 1'b1;
|
||||||
parameter WR_CLK_POLARITY = 1'b1;
|
parameter WR_CLK_POLARITY = 1'b1;
|
||||||
|
|
||||||
input [RD_PORTS-1:0] RD_CLK;
|
input [RD_PORTS-1:0] RD_CLK;
|
||||||
|
input [RD_PORTS-1:0] RD_EN;
|
||||||
input [RD_PORTS*ABITS-1:0] RD_ADDR;
|
input [RD_PORTS*ABITS-1:0] RD_ADDR;
|
||||||
output reg [RD_PORTS*WIDTH-1:0] RD_DATA;
|
output reg [RD_PORTS*WIDTH-1:0] RD_DATA;
|
||||||
|
|
||||||
|
@ -1626,7 +1627,7 @@ always @(RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA) begin
|
||||||
#`SIMLIB_MEMDELAY;
|
#`SIMLIB_MEMDELAY;
|
||||||
`endif
|
`endif
|
||||||
for (i = 0; i < RD_PORTS; i = i+1) begin
|
for (i = 0; i < RD_PORTS; i = i+1) begin
|
||||||
if ((!RD_TRANSPARENT[i] && RD_CLK_ENABLE[i]) && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin
|
if (!RD_TRANSPARENT[i] && RD_CLK_ENABLE[i] && RD_EN[i] && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin
|
||||||
// $display("Read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS], memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]);
|
// $display("Read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS], memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]);
|
||||||
RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET];
|
RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET];
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ bram $__ICE40_RAM4K_M0
|
||||||
groups 2
|
groups 2
|
||||||
ports 1 1
|
ports 1 1
|
||||||
wrmode 0 1
|
wrmode 0 1
|
||||||
enable 0 16
|
enable 1 16
|
||||||
transp 0 0
|
transp 0 0
|
||||||
clocks 2 3
|
clocks 2 3
|
||||||
clkpol 2 3
|
clkpol 2 3
|
||||||
|
@ -22,7 +22,7 @@ bram $__ICE40_RAM4K_M123
|
||||||
groups 2
|
groups 2
|
||||||
ports 1 1
|
ports 1 1
|
||||||
wrmode 0 1
|
wrmode 0 1
|
||||||
enable 0 1
|
enable 1 1
|
||||||
transp 0 0
|
transp 0 0
|
||||||
clocks 2 3
|
clocks 2 3
|
||||||
clkpol 2 3
|
clkpol 2 3
|
||||||
|
|
|
@ -168,7 +168,7 @@ module \$__ICE40_RAM4K (
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
parameter [0:0] CLKPOL2 = 1;
|
parameter [0:0] CLKPOL2 = 1;
|
||||||
parameter [0:0] CLKPOL3 = 1;
|
parameter [0:0] CLKPOL3 = 1;
|
||||||
|
|
||||||
|
@ -179,6 +179,7 @@ module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
|
|
||||||
input [7:0] A1ADDR;
|
input [7:0] A1ADDR;
|
||||||
output [15:0] A1DATA;
|
output [15:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
input [7:0] B1ADDR;
|
input [7:0] B1ADDR;
|
||||||
input [15:0] B1DATA;
|
input [15:0] B1DATA;
|
||||||
|
@ -213,7 +214,7 @@ module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
.RADDR(A1ADDR_11),
|
.RADDR(A1ADDR_11),
|
||||||
.RCLK(CLK2),
|
.RCLK(CLK2),
|
||||||
.RCLKE(1'b1),
|
.RCLKE(1'b1),
|
||||||
.RE(1'b1),
|
.RE(A1EN),
|
||||||
.WDATA(B1DATA),
|
.WDATA(B1DATA),
|
||||||
.WADDR(B1ADDR_11),
|
.WADDR(B1ADDR_11),
|
||||||
.MASK(~B1EN),
|
.MASK(~B1EN),
|
||||||
|
@ -223,7 +224,7 @@ module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
);
|
);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
parameter CFG_ABITS = 9;
|
parameter CFG_ABITS = 9;
|
||||||
parameter CFG_DBITS = 8;
|
parameter CFG_DBITS = 8;
|
||||||
|
|
||||||
|
@ -242,6 +243,7 @@ module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
|
|
||||||
input [CFG_ABITS-1:0] A1ADDR;
|
input [CFG_ABITS-1:0] A1ADDR;
|
||||||
output [CFG_DBITS-1:0] A1DATA;
|
output [CFG_DBITS-1:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
input [CFG_ABITS-1:0] B1ADDR;
|
input [CFG_ABITS-1:0] B1ADDR;
|
||||||
input [CFG_DBITS-1:0] B1DATA;
|
input [CFG_DBITS-1:0] B1DATA;
|
||||||
|
@ -298,7 +300,7 @@ module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
.RADDR(A1ADDR_11),
|
.RADDR(A1ADDR_11),
|
||||||
.RCLK(CLK2),
|
.RCLK(CLK2),
|
||||||
.RCLKE(1'b1),
|
.RCLKE(1'b1),
|
||||||
.RE(1'b1),
|
.RE(A1EN),
|
||||||
.WDATA(B1DATA_16),
|
.WDATA(B1DATA_16),
|
||||||
.WADDR(B1ADDR_11),
|
.WADDR(B1ADDR_11),
|
||||||
.WCLK(CLK3),
|
.WCLK(CLK3),
|
||||||
|
|
|
@ -6,7 +6,7 @@ bram $__XILINX_RAMB36_SDP
|
||||||
groups 2
|
groups 2
|
||||||
ports 1 1
|
ports 1 1
|
||||||
wrmode 0 1
|
wrmode 0 1
|
||||||
enable 0 8
|
enable 1 8
|
||||||
transp 0 0
|
transp 0 0
|
||||||
clocks 2 3
|
clocks 2 3
|
||||||
clkpol 2 3
|
clkpol 2 3
|
||||||
|
@ -19,7 +19,7 @@ bram $__XILINX_RAMB18_SDP
|
||||||
groups 2
|
groups 2
|
||||||
ports 1 1
|
ports 1 1
|
||||||
wrmode 0 1
|
wrmode 0 1
|
||||||
enable 0 4
|
enable 1 4
|
||||||
transp 0 0
|
transp 0 0
|
||||||
clocks 2 3
|
clocks 2 3
|
||||||
clkpol 2 3
|
clkpol 2 3
|
||||||
|
@ -42,9 +42,9 @@ bram $__XILINX_RAMB36_TDP
|
||||||
groups 2
|
groups 2
|
||||||
ports 1 1
|
ports 1 1
|
||||||
wrmode 0 1
|
wrmode 0 1
|
||||||
enable 0 4 @a10d36
|
enable 1 4 @a10d36
|
||||||
enable 0 2 @a11d18
|
enable 1 2 @a11d18
|
||||||
enable 0 1 @a12d9 @a13d4 @a14d2 @a15d1
|
enable 1 1 @a12d9 @a13d4 @a14d2 @a15d1
|
||||||
transp 0 0
|
transp 0 0
|
||||||
clocks 2 3
|
clocks 2 3
|
||||||
clkpol 2 3
|
clkpol 2 3
|
||||||
|
@ -65,8 +65,8 @@ bram $__XILINX_RAMB18_TDP
|
||||||
groups 2
|
groups 2
|
||||||
ports 1 1
|
ports 1 1
|
||||||
wrmode 0 1
|
wrmode 0 1
|
||||||
enable 0 2 @a10d18
|
enable 1 2 @a10d18
|
||||||
enable 0 1 @a11d9 @a12d4 @a13d2 @a14d1
|
enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
|
||||||
transp 0 0
|
transp 0 0
|
||||||
clocks 2 3
|
clocks 2 3
|
||||||
clkpol 2 3
|
clkpol 2 3
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
parameter CLKPOL2 = 1;
|
parameter CLKPOL2 = 1;
|
||||||
parameter CLKPOL3 = 1;
|
parameter CLKPOL3 = 1;
|
||||||
parameter [36863:0] INIT = 36864'bx;
|
parameter [36863:0] INIT = 36864'bx;
|
||||||
|
@ -8,6 +8,7 @@ module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
|
|
||||||
input [8:0] A1ADDR;
|
input [8:0] A1ADDR;
|
||||||
output [71:0] A1DATA;
|
output [71:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
input [8:0] B1ADDR;
|
input [8:0] B1ADDR;
|
||||||
input [71:0] B1DATA;
|
input [71:0] B1DATA;
|
||||||
|
@ -47,7 +48,7 @@ module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
|
|
||||||
.ADDRARDADDR(A1ADDR_16),
|
.ADDRARDADDR(A1ADDR_16),
|
||||||
.CLKARDCLK(CLK2),
|
.CLKARDCLK(CLK2),
|
||||||
.ENARDEN(|1),
|
.ENARDEN(A1EN),
|
||||||
.REGCEAREGCE(|1),
|
.REGCEAREGCE(|1),
|
||||||
.RSTRAMARSTRAM(|0),
|
.RSTRAMARSTRAM(|0),
|
||||||
.RSTREGARSTREG(|0),
|
.RSTREGARSTREG(|0),
|
||||||
|
@ -65,7 +66,7 @@ endmodule
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
parameter CLKPOL2 = 1;
|
parameter CLKPOL2 = 1;
|
||||||
parameter CLKPOL3 = 1;
|
parameter CLKPOL3 = 1;
|
||||||
parameter [18431:0] INIT = 18432'bx;
|
parameter [18431:0] INIT = 18432'bx;
|
||||||
|
@ -75,6 +76,7 @@ module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
|
|
||||||
input [8:0] A1ADDR;
|
input [8:0] A1ADDR;
|
||||||
output [35:0] A1DATA;
|
output [35:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
input [8:0] B1ADDR;
|
input [8:0] B1ADDR;
|
||||||
input [35:0] B1DATA;
|
input [35:0] B1DATA;
|
||||||
|
@ -111,7 +113,7 @@ module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
|
|
||||||
.ADDRARDADDR(A1ADDR_14),
|
.ADDRARDADDR(A1ADDR_14),
|
||||||
.CLKARDCLK(CLK2),
|
.CLKARDCLK(CLK2),
|
||||||
.ENARDEN(|1),
|
.ENARDEN(A1EN),
|
||||||
.REGCEAREGCE(|1),
|
.REGCEAREGCE(|1),
|
||||||
.RSTRAMARSTRAM(|0),
|
.RSTRAMARSTRAM(|0),
|
||||||
.RSTREGARSTREG(|0),
|
.RSTREGARSTREG(|0),
|
||||||
|
@ -129,7 +131,7 @@ endmodule
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
parameter CFG_ABITS = 10;
|
parameter CFG_ABITS = 10;
|
||||||
parameter CFG_DBITS = 36;
|
parameter CFG_DBITS = 36;
|
||||||
parameter CFG_ENABLE_B = 4;
|
parameter CFG_ENABLE_B = 4;
|
||||||
|
@ -143,6 +145,7 @@ module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
|
|
||||||
input [CFG_ABITS-1:0] A1ADDR;
|
input [CFG_ABITS-1:0] A1ADDR;
|
||||||
output [CFG_DBITS-1:0] A1DATA;
|
output [CFG_DBITS-1:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
input [CFG_ABITS-1:0] B1ADDR;
|
input [CFG_ABITS-1:0] B1ADDR;
|
||||||
input [CFG_DBITS-1:0] B1DATA;
|
input [CFG_DBITS-1:0] B1DATA;
|
||||||
|
@ -181,7 +184,7 @@ module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
.DOPADOP(DOP[3:0]),
|
.DOPADOP(DOP[3:0]),
|
||||||
.ADDRARDADDR(A1ADDR_16),
|
.ADDRARDADDR(A1ADDR_16),
|
||||||
.CLKARDCLK(CLK2),
|
.CLKARDCLK(CLK2),
|
||||||
.ENARDEN(|1),
|
.ENARDEN(A1EN),
|
||||||
.REGCEAREGCE(|1),
|
.REGCEAREGCE(|1),
|
||||||
.RSTRAMARSTRAM(|0),
|
.RSTRAMARSTRAM(|0),
|
||||||
.RSTREGARSTREG(|0),
|
.RSTREGARSTREG(|0),
|
||||||
|
@ -219,7 +222,7 @@ module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
.DOPADOP(DOP[3:0]),
|
.DOPADOP(DOP[3:0]),
|
||||||
.ADDRARDADDR(A1ADDR_16),
|
.ADDRARDADDR(A1ADDR_16),
|
||||||
.CLKARDCLK(CLK2),
|
.CLKARDCLK(CLK2),
|
||||||
.ENARDEN(|1),
|
.ENARDEN(A1EN),
|
||||||
.REGCEAREGCE(|1),
|
.REGCEAREGCE(|1),
|
||||||
.RSTRAMARSTRAM(|0),
|
.RSTRAMARSTRAM(|0),
|
||||||
.RSTREGARSTREG(|0),
|
.RSTREGARSTREG(|0),
|
||||||
|
@ -242,7 +245,7 @@ endmodule
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
parameter CFG_ABITS = 10;
|
parameter CFG_ABITS = 10;
|
||||||
parameter CFG_DBITS = 18;
|
parameter CFG_DBITS = 18;
|
||||||
parameter CFG_ENABLE_B = 2;
|
parameter CFG_ENABLE_B = 2;
|
||||||
|
@ -256,6 +259,7 @@ module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
|
|
||||||
input [CFG_ABITS-1:0] A1ADDR;
|
input [CFG_ABITS-1:0] A1ADDR;
|
||||||
output [CFG_DBITS-1:0] A1DATA;
|
output [CFG_DBITS-1:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
input [CFG_ABITS-1:0] B1ADDR;
|
input [CFG_ABITS-1:0] B1ADDR;
|
||||||
input [CFG_DBITS-1:0] B1DATA;
|
input [CFG_DBITS-1:0] B1DATA;
|
||||||
|
@ -294,7 +298,7 @@ module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
.DOPADOP(DOP),
|
.DOPADOP(DOP),
|
||||||
.ADDRARDADDR(A1ADDR_14),
|
.ADDRARDADDR(A1ADDR_14),
|
||||||
.CLKARDCLK(CLK2),
|
.CLKARDCLK(CLK2),
|
||||||
.ENARDEN(|1),
|
.ENARDEN(A1EN),
|
||||||
.REGCEAREGCE(|1),
|
.REGCEAREGCE(|1),
|
||||||
.RSTRAMARSTRAM(|0),
|
.RSTRAMARSTRAM(|0),
|
||||||
.RSTREGARSTREG(|0),
|
.RSTREGARSTREG(|0),
|
||||||
|
@ -332,7 +336,7 @@ module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||||
.DOPADOP(DOP),
|
.DOPADOP(DOP),
|
||||||
.ADDRARDADDR(A1ADDR_14),
|
.ADDRARDADDR(A1ADDR_14),
|
||||||
.CLKARDCLK(CLK2),
|
.CLKARDCLK(CLK2),
|
||||||
.ENARDEN(|1),
|
.ENARDEN(A1EN),
|
||||||
.REGCEAREGCE(|1),
|
.REGCEAREGCE(|1),
|
||||||
.RSTRAMARSTRAM(|0),
|
.RSTRAMARSTRAM(|0),
|
||||||
.RSTREGARSTREG(|0),
|
.RSTREGARSTREG(|0),
|
||||||
|
|
|
@ -79,7 +79,6 @@ struct SynthXilinxPass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" coarse:\n");
|
log(" coarse:\n");
|
||||||
log(" synth -run coarse\n");
|
log(" synth -run coarse\n");
|
||||||
log(" dff2dffe\n");
|
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" bram:\n");
|
log(" bram:\n");
|
||||||
log(" memory_bram -rules +/xilinx/brams.txt\n");
|
log(" memory_bram -rules +/xilinx/brams.txt\n");
|
||||||
|
@ -92,6 +91,7 @@ struct SynthXilinxPass : public Pass {
|
||||||
log(" fine:\n");
|
log(" fine:\n");
|
||||||
log(" opt -fast -full\n");
|
log(" opt -fast -full\n");
|
||||||
log(" memory_map\n");
|
log(" memory_map\n");
|
||||||
|
log(" dff2dffe\n");
|
||||||
log(" opt -full\n");
|
log(" opt -full\n");
|
||||||
log(" techmap -map +/techmap.v -map +/xilinx/arith_map.v\n");
|
log(" techmap -map +/techmap.v -map +/xilinx/arith_map.v\n");
|
||||||
log(" opt -fast\n");
|
log(" opt -fast\n");
|
||||||
|
@ -178,7 +178,6 @@ struct SynthXilinxPass : public Pass {
|
||||||
if (check_label(active, run_from, run_to, "coarse"))
|
if (check_label(active, run_from, run_to, "coarse"))
|
||||||
{
|
{
|
||||||
Pass::call(design, "synth -run coarse");
|
Pass::call(design, "synth -run coarse");
|
||||||
Pass::call(design, "dff2dffe");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_label(active, run_from, run_to, "bram"))
|
if (check_label(active, run_from, run_to, "bram"))
|
||||||
|
@ -197,6 +196,7 @@ struct SynthXilinxPass : public Pass {
|
||||||
{
|
{
|
||||||
Pass::call(design, "opt -fast -full");
|
Pass::call(design, "opt -fast -full");
|
||||||
Pass::call(design, "memory_map");
|
Pass::call(design, "memory_map");
|
||||||
|
Pass::call(design, "dff2dffe");
|
||||||
Pass::call(design, "opt -full");
|
Pass::call(design, "opt -full");
|
||||||
Pass::call(design, "techmap -map +/techmap.v -map +/xilinx/arith_map.v");
|
Pass::call(design, "techmap -map +/techmap.v -map +/xilinx/arith_map.v");
|
||||||
Pass::call(design, "opt -fast");
|
Pass::call(design, "opt -fast");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
|
module \$mem (RD_CLK, RD_EN, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
|
||||||
parameter MEMID = "";
|
parameter MEMID = "";
|
||||||
parameter SIZE = 256;
|
parameter SIZE = 256;
|
||||||
parameter OFFSET = 0;
|
parameter OFFSET = 0;
|
||||||
|
@ -17,6 +17,7 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
|
||||||
parameter WR_CLK_POLARITY = 1'b1;
|
parameter WR_CLK_POLARITY = 1'b1;
|
||||||
|
|
||||||
input [RD_PORTS-1:0] RD_CLK;
|
input [RD_PORTS-1:0] RD_CLK;
|
||||||
|
input [RD_PORTS-1:0] RD_EN;
|
||||||
input [RD_PORTS*ABITS-1:0] RD_ADDR;
|
input [RD_PORTS*ABITS-1:0] RD_ADDR;
|
||||||
output reg [RD_PORTS*WIDTH-1:0] RD_DATA;
|
output reg [RD_PORTS*WIDTH-1:0] RD_DATA;
|
||||||
|
|
||||||
|
@ -30,6 +31,8 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
|
||||||
parameter _TECHMAP_CONNMAP_RD_CLK_ = 0;
|
parameter _TECHMAP_CONNMAP_RD_CLK_ = 0;
|
||||||
parameter _TECHMAP_CONNMAP_WR_CLK_ = 0;
|
parameter _TECHMAP_CONNMAP_WR_CLK_ = 0;
|
||||||
|
|
||||||
|
parameter _TECHMAP_CONSTVAL_RD_EN_ = 0;
|
||||||
|
|
||||||
parameter _TECHMAP_BITS_CONNMAP_ = 0;
|
parameter _TECHMAP_BITS_CONNMAP_ = 0;
|
||||||
parameter _TECHMAP_CONNMAP_WR_EN_ = 0;
|
parameter _TECHMAP_CONNMAP_WR_EN_ = 0;
|
||||||
|
|
||||||
|
@ -46,6 +49,10 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
|
||||||
if (RD_PORTS > 1 || WR_PORTS > 1)
|
if (RD_PORTS > 1 || WR_PORTS > 1)
|
||||||
_TECHMAP_FAIL_ <= 1;
|
_TECHMAP_FAIL_ <= 1;
|
||||||
|
|
||||||
|
// read enable must be constant high
|
||||||
|
if (_TECHMAP_CONSTVAL_RD_EN_[0] !== 1'b1)
|
||||||
|
_TECHMAP_FAIL_ <= 1;
|
||||||
|
|
||||||
// we expect positive read clock and non-transparent reads
|
// we expect positive read clock and non-transparent reads
|
||||||
if (RD_TRANSPARENT || !RD_CLK_ENABLE || !RD_CLK_POLARITY)
|
if (RD_TRANSPARENT || !RD_CLK_ENABLE || !RD_CLK_POLARITY)
|
||||||
_TECHMAP_FAIL_ <= 1;
|
_TECHMAP_FAIL_ <= 1;
|
||||||
|
|
Loading…
Reference in a new issue