mirror of https://github.com/YosysHQ/yosys.git
Merge branch 'upstream'
This commit is contained in:
commit
d1eb2e518d
|
@ -16,7 +16,7 @@ backends/cxxrtl/ @whitequark
|
||||||
passes/cmds/bugpoint.cc @whitequark
|
passes/cmds/bugpoint.cc @whitequark
|
||||||
passes/techmap/flowmap.cc @whitequark
|
passes/techmap/flowmap.cc @whitequark
|
||||||
passes/opt/opt_lut.cc @whitequark
|
passes/opt/opt_lut.cc @whitequark
|
||||||
passes/techmap/abc9*.cc @eddiehung
|
passes/techmap/abc9*.cc @eddiehung @Ravenslofty
|
||||||
backends/aiger/xaiger.cc @eddiehung
|
backends/aiger/xaiger.cc @eddiehung
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ backends/aiger/xaiger.cc @eddiehung
|
||||||
frontends/verilog/ @zachjs
|
frontends/verilog/ @zachjs
|
||||||
frontends/ast/ @zachjs
|
frontends/ast/ @zachjs
|
||||||
|
|
||||||
techlibs/intel_alm/ @ZirconiumX
|
techlibs/intel_alm/ @Ravenslofty
|
||||||
techlibs/gowin/ @pepijndevos
|
techlibs/gowin/ @pepijndevos
|
||||||
techlibs/gatemate/ @pu-cc
|
techlibs/gatemate/ @pu-cc
|
||||||
|
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -129,7 +129,7 @@ LDFLAGS += -rdynamic
|
||||||
LDLIBS += -lrt
|
LDLIBS += -lrt
|
||||||
endif
|
endif
|
||||||
|
|
||||||
YOSYS_VER := 0.18+3
|
YOSYS_VER := 0.18+20
|
||||||
|
|
||||||
# Note: We arrange for .gitcommit to contain the (short) commit hash in
|
# Note: We arrange for .gitcommit to contain the (short) commit hash in
|
||||||
# tarballs generated with git-archive(1) using .gitattributes. The git repo
|
# tarballs generated with git-archive(1) using .gitattributes. The git repo
|
||||||
|
|
|
@ -1402,6 +1402,7 @@ struct BtorBackend : public Backend {
|
||||||
log_header(design, "Executing BTOR backend.\n");
|
log_header(design, "Executing BTOR backend.\n");
|
||||||
|
|
||||||
log_push();
|
log_push();
|
||||||
|
Pass::call(design, "memory_map -rom-only");
|
||||||
Pass::call(design, "bmuxmap");
|
Pass::call(design, "bmuxmap");
|
||||||
Pass::call(design, "demuxmap");
|
Pass::call(design, "demuxmap");
|
||||||
log_pop();
|
log_pop();
|
||||||
|
|
|
@ -1609,6 +1609,7 @@ struct Smt2Backend : public Backend {
|
||||||
log_header(design, "Executing SMT2 backend.\n");
|
log_header(design, "Executing SMT2 backend.\n");
|
||||||
|
|
||||||
log_push();
|
log_push();
|
||||||
|
Pass::call(design, "memory_map -rom-only");
|
||||||
Pass::call(design, "bmuxmap");
|
Pass::call(design, "bmuxmap");
|
||||||
Pass::call(design, "demuxmap");
|
Pass::call(design, "demuxmap");
|
||||||
log_pop();
|
log_pop();
|
||||||
|
|
|
@ -58,6 +58,9 @@ USING_YOSYS_NAMESPACE
|
||||||
|
|
||||||
#ifdef YOSYSHQ_VERIFIC_EXTENSIONS
|
#ifdef YOSYSHQ_VERIFIC_EXTENSIONS
|
||||||
#include "InitialAssertions.h"
|
#include "InitialAssertions.h"
|
||||||
|
#include "VerificBasePass.h"
|
||||||
|
#include "TemplateGenerator.h"
|
||||||
|
#include "FormalApplication.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef YOSYSHQ_VERIFIC_API_VERSION
|
#ifndef YOSYSHQ_VERIFIC_API_VERSION
|
||||||
|
@ -149,6 +152,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static YosysStreamCallBackHandler stream_cb;
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
|
|
||||||
VerificImporter::VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover, bool mode_fullinit) :
|
VerificImporter::VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover, bool mode_fullinit) :
|
||||||
|
@ -2345,6 +2350,64 @@ bool check_noverific_env()
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_verific_global_flags()
|
||||||
|
{
|
||||||
|
static bool g_set_verific_global_flags = true;
|
||||||
|
|
||||||
|
if (g_set_verific_global_flags)
|
||||||
|
{
|
||||||
|
Message::SetConsoleOutput(0);
|
||||||
|
Message::RegisterCallBackMsg(msg_func);
|
||||||
|
|
||||||
|
RuntimeFlags::SetVar("db_preserve_user_instances", 1);
|
||||||
|
RuntimeFlags::SetVar("db_preserve_user_nets", 1);
|
||||||
|
RuntimeFlags::SetVar("db_preserve_x", 1);
|
||||||
|
|
||||||
|
RuntimeFlags::SetVar("db_allow_external_nets", 1);
|
||||||
|
RuntimeFlags::SetVar("db_infer_wide_operators", 1);
|
||||||
|
RuntimeFlags::SetVar("db_infer_set_reset_registers", 0);
|
||||||
|
|
||||||
|
RuntimeFlags::SetVar("veri_extract_dualport_rams", 0);
|
||||||
|
RuntimeFlags::SetVar("veri_extract_multiport_rams", 1);
|
||||||
|
RuntimeFlags::SetVar("veri_allow_any_ram_in_loop", 1);
|
||||||
|
|
||||||
|
#ifdef VERIFIC_VHDL_SUPPORT
|
||||||
|
RuntimeFlags::SetVar("vhdl_extract_dualport_rams", 0);
|
||||||
|
RuntimeFlags::SetVar("vhdl_extract_multiport_rams", 1);
|
||||||
|
RuntimeFlags::SetVar("vhdl_allow_any_ram_in_loop", 1);
|
||||||
|
|
||||||
|
RuntimeFlags::SetVar("vhdl_support_variable_slice", 1);
|
||||||
|
RuntimeFlags::SetVar("vhdl_ignore_assertion_statements", 0);
|
||||||
|
|
||||||
|
RuntimeFlags::SetVar("vhdl_preserve_assignments", 1);
|
||||||
|
//RuntimeFlags::SetVar("vhdl_preserve_comments", 1);
|
||||||
|
RuntimeFlags::SetVar("vhdl_preserve_drivers", 1);
|
||||||
|
#endif
|
||||||
|
RuntimeFlags::SetVar("veri_preserve_assignments", 1);
|
||||||
|
RuntimeFlags::SetVar("veri_preserve_comments", 1);
|
||||||
|
RuntimeFlags::SetVar("veri_preserve_drivers", 1);
|
||||||
|
|
||||||
|
// Workaround for VIPER #13851
|
||||||
|
RuntimeFlags::SetVar("veri_create_name_for_unnamed_gen_block", 1);
|
||||||
|
|
||||||
|
// WARNING: instantiating unknown module 'XYZ' (VERI-1063)
|
||||||
|
Message::SetMessageType("VERI-1063", VERIFIC_ERROR);
|
||||||
|
|
||||||
|
// https://github.com/YosysHQ/yosys/issues/1055
|
||||||
|
RuntimeFlags::SetVar("veri_elaborate_top_level_modules_having_interface_ports", 1) ;
|
||||||
|
|
||||||
|
RuntimeFlags::SetVar("verific_produce_verbose_syntax_error_message", 1);
|
||||||
|
|
||||||
|
#ifndef DB_PRESERVE_INITIAL_VALUE
|
||||||
|
# warning Verific was built without DB_PRESERVE_INITIAL_VALUE.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
veri_file::RegisterCallBackVerificStream(&stream_cb);
|
||||||
|
|
||||||
|
g_set_verific_global_flags = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct VerificPass : public Pass {
|
struct VerificPass : public Pass {
|
||||||
|
@ -2549,8 +2612,6 @@ struct VerificPass : public Pass {
|
||||||
#ifdef YOSYS_ENABLE_VERIFIC
|
#ifdef YOSYS_ENABLE_VERIFIC
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
{
|
{
|
||||||
static bool set_verific_global_flags = true;
|
|
||||||
|
|
||||||
if (check_noverific_env())
|
if (check_noverific_env())
|
||||||
log_cmd_error("This version of Yosys is built without Verific support.\n"
|
log_cmd_error("This version of Yosys is built without Verific support.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -2562,56 +2623,7 @@ struct VerificPass : public Pass {
|
||||||
|
|
||||||
log_header(design, "Executing VERIFIC (loading SystemVerilog and VHDL designs using Verific).\n");
|
log_header(design, "Executing VERIFIC (loading SystemVerilog and VHDL designs using Verific).\n");
|
||||||
|
|
||||||
if (set_verific_global_flags)
|
set_verific_global_flags();
|
||||||
{
|
|
||||||
Message::SetConsoleOutput(0);
|
|
||||||
Message::RegisterCallBackMsg(msg_func);
|
|
||||||
|
|
||||||
RuntimeFlags::SetVar("db_preserve_user_instances", 1);
|
|
||||||
RuntimeFlags::SetVar("db_preserve_user_nets", 1);
|
|
||||||
RuntimeFlags::SetVar("db_preserve_x", 1);
|
|
||||||
|
|
||||||
RuntimeFlags::SetVar("db_allow_external_nets", 1);
|
|
||||||
RuntimeFlags::SetVar("db_infer_wide_operators", 1);
|
|
||||||
RuntimeFlags::SetVar("db_infer_set_reset_registers", 0);
|
|
||||||
|
|
||||||
RuntimeFlags::SetVar("veri_extract_dualport_rams", 0);
|
|
||||||
RuntimeFlags::SetVar("veri_extract_multiport_rams", 1);
|
|
||||||
RuntimeFlags::SetVar("veri_allow_any_ram_in_loop", 1);
|
|
||||||
|
|
||||||
#ifdef VERIFIC_VHDL_SUPPORT
|
|
||||||
RuntimeFlags::SetVar("vhdl_extract_dualport_rams", 0);
|
|
||||||
RuntimeFlags::SetVar("vhdl_extract_multiport_rams", 1);
|
|
||||||
RuntimeFlags::SetVar("vhdl_allow_any_ram_in_loop", 1);
|
|
||||||
|
|
||||||
RuntimeFlags::SetVar("vhdl_support_variable_slice", 1);
|
|
||||||
RuntimeFlags::SetVar("vhdl_ignore_assertion_statements", 0);
|
|
||||||
|
|
||||||
RuntimeFlags::SetVar("vhdl_preserve_assignments", 1);
|
|
||||||
//RuntimeFlags::SetVar("vhdl_preserve_comments", 1);
|
|
||||||
RuntimeFlags::SetVar("vhdl_preserve_drivers", 1);
|
|
||||||
#endif
|
|
||||||
RuntimeFlags::SetVar("veri_preserve_assignments", 1);
|
|
||||||
RuntimeFlags::SetVar("veri_preserve_comments", 1);
|
|
||||||
RuntimeFlags::SetVar("veri_preserve_drivers", 1);
|
|
||||||
|
|
||||||
// Workaround for VIPER #13851
|
|
||||||
RuntimeFlags::SetVar("veri_create_name_for_unnamed_gen_block", 1);
|
|
||||||
|
|
||||||
// WARNING: instantiating unknown module 'XYZ' (VERI-1063)
|
|
||||||
Message::SetMessageType("VERI-1063", VERIFIC_ERROR);
|
|
||||||
|
|
||||||
// https://github.com/YosysHQ/yosys/issues/1055
|
|
||||||
RuntimeFlags::SetVar("veri_elaborate_top_level_modules_having_interface_ports", 1) ;
|
|
||||||
|
|
||||||
RuntimeFlags::SetVar("verific_produce_verbose_syntax_error_message", 1);
|
|
||||||
|
|
||||||
#ifndef DB_PRESERVE_INITIAL_VALUE
|
|
||||||
# warning Verific was built without DB_PRESERVE_INITIAL_VALUE.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
set_verific_global_flags = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
verific_verbose = 0;
|
verific_verbose = 0;
|
||||||
verific_sva_fsm_limit = 16;
|
verific_sva_fsm_limit = 16;
|
||||||
|
@ -2630,8 +2642,6 @@ struct VerificPass : public Pass {
|
||||||
|
|
||||||
int argidx = 1;
|
int argidx = 1;
|
||||||
std::string work = "work";
|
std::string work = "work";
|
||||||
YosysStreamCallBackHandler cb;
|
|
||||||
veri_file::RegisterCallBackVerificStream(&cb);
|
|
||||||
|
|
||||||
if (GetSize(args) > argidx && (args[argidx] == "-set-error" || args[argidx] == "-set-warning" ||
|
if (GetSize(args) > argidx && (args[argidx] == "-set-error" || args[argidx] == "-set-warning" ||
|
||||||
args[argidx] == "-set-info" || args[argidx] == "-set-ignore"))
|
args[argidx] == "-set-info" || args[argidx] == "-set-ignore"))
|
||||||
|
@ -3208,6 +3218,12 @@ struct VerificPass : public Pass {
|
||||||
#endif
|
#endif
|
||||||
} VerificPass;
|
} VerificPass;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef YOSYSHQ_VERIFIC_EXTENSIONS
|
||||||
|
VERIFIC_PASS(VerificTemplateGenerator, "template", "generate template")
|
||||||
|
VERIFIC_PASS(VerificFormalApplication, "formal_app", "running formal application")
|
||||||
|
#endif
|
||||||
|
|
||||||
struct ReadPass : public Pass {
|
struct ReadPass : public Pass {
|
||||||
ReadPass() : Pass("read", "load HDL designs") { }
|
ReadPass() : Pass("read", "load HDL designs") { }
|
||||||
void help() override
|
void help() override
|
||||||
|
|
|
@ -837,7 +837,7 @@ void MemMapping::handle_priority() {
|
||||||
if (!port2.priority_mask[p1idx])
|
if (!port2.priority_mask[p1idx])
|
||||||
continue;
|
continue;
|
||||||
for (auto &cfg: cfgs) {
|
for (auto &cfg: cfgs) {
|
||||||
auto &p1cfg = cfg.rd_ports[p1idx];
|
auto &p1cfg = cfg.wr_ports[p1idx];
|
||||||
auto &p2cfg = cfg.wr_ports[p2idx];
|
auto &p2cfg = cfg.wr_ports[p2idx];
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto &pgi: p2cfg.def->wrprio) {
|
for (auto &pgi: p2cfg.def->wrprio) {
|
||||||
|
@ -1706,10 +1706,11 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
|
||||||
if (pdef.wrbe_separate) {
|
if (pdef.wrbe_separate) {
|
||||||
cell->setPort(stringf("\\PORT_%s_WR_EN", name), State::S0);
|
cell->setPort(stringf("\\PORT_%s_WR_EN", name), State::S0);
|
||||||
cell->setPort(stringf("\\PORT_%s_WR_BE", name), hw_wren);
|
cell->setPort(stringf("\\PORT_%s_WR_BE", name), hw_wren);
|
||||||
cell->setParam(stringf("\\PORT_%s_WR_BE_WIDTH", name), GetSize(hw_wren));
|
if (cfg.def->width_mode != WidthMode::Single)
|
||||||
|
cell->setParam(stringf("\\PORT_%s_WR_BE_WIDTH", name), GetSize(hw_wren));
|
||||||
} else {
|
} else {
|
||||||
cell->setPort(stringf("\\PORT_%s_WR_EN", name), hw_wren);
|
cell->setPort(stringf("\\PORT_%s_WR_EN", name), hw_wren);
|
||||||
if (cfg.def->byte != 0)
|
if (cfg.def->byte != 0 && cfg.def->width_mode != WidthMode::Single)
|
||||||
cell->setParam(stringf("\\PORT_%s_WR_EN_WIDTH", name), GetSize(hw_wren));
|
cell->setParam(stringf("\\PORT_%s_WR_EN_WIDTH", name), GetSize(hw_wren));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
struct MemoryMapWorker
|
struct MemoryMapWorker
|
||||||
{
|
{
|
||||||
bool attr_icase = false;
|
bool attr_icase = false;
|
||||||
|
bool rom_only = false;
|
||||||
dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
|
dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
|
||||||
|
|
||||||
RTLIL::Design *design;
|
RTLIL::Design *design;
|
||||||
|
@ -107,11 +108,8 @@ struct MemoryMapWorker
|
||||||
|
|
||||||
SigSpec init_data = mem.get_init_data();
|
SigSpec init_data = mem.get_init_data();
|
||||||
|
|
||||||
// delete unused memory cell
|
if (!mem.wr_ports.empty() && rom_only)
|
||||||
if (mem.rd_ports.empty()) {
|
|
||||||
mem.remove();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// check if attributes allow us to infer FFRAM for this memory
|
// check if attributes allow us to infer FFRAM for this memory
|
||||||
for (const auto &attr : attributes) {
|
for (const auto &attr : attributes) {
|
||||||
|
@ -143,6 +141,12 @@ struct MemoryMapWorker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete unused memory cell
|
||||||
|
if (mem.rd_ports.empty()) {
|
||||||
|
mem.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// all write ports must share the same clock
|
// all write ports must share the same clock
|
||||||
RTLIL::SigSpec refclock;
|
RTLIL::SigSpec refclock;
|
||||||
bool refclock_pol = false;
|
bool refclock_pol = false;
|
||||||
|
@ -191,6 +195,10 @@ struct MemoryMapWorker
|
||||||
data_reg_out[idx] = static_cells_map[addr];
|
data_reg_out[idx] = static_cells_map[addr];
|
||||||
count_static++;
|
count_static++;
|
||||||
}
|
}
|
||||||
|
else if (mem.wr_ports.empty())
|
||||||
|
{
|
||||||
|
data_reg_out[idx] = init_data.extract(i*mem.width, mem.width);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RTLIL::Cell *c = module->addCell(genid(mem.memid, "", addr), ID($dff));
|
RTLIL::Cell *c = module->addCell(genid(mem.memid, "", addr), ID($dff));
|
||||||
|
@ -266,69 +274,72 @@ struct MemoryMapWorker
|
||||||
|
|
||||||
log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux);
|
log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux);
|
||||||
|
|
||||||
for (int i = 0; i < mem.size; i++)
|
if (!mem.wr_ports.empty())
|
||||||
{
|
{
|
||||||
int addr = i + mem.start_offset;
|
for (int i = 0; i < mem.size; i++)
|
||||||
int idx = addr & ((1 << abits) - 1);
|
|
||||||
if (static_cells_map.count(addr) > 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
RTLIL::SigSpec sig = data_reg_out[idx];
|
|
||||||
|
|
||||||
for (int j = 0; j < GetSize(mem.wr_ports); j++)
|
|
||||||
{
|
{
|
||||||
auto &port = mem.wr_ports[j];
|
int addr = i + mem.start_offset;
|
||||||
RTLIL::SigSpec wr_addr = port.addr.extract_end(port.wide_log2);
|
int idx = addr & ((1 << abits) - 1);
|
||||||
RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(addr >> port.wide_log2, GetSize(wr_addr)));
|
if (static_cells_map.count(addr) > 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
int sub = addr & ((1 << port.wide_log2) - 1);
|
RTLIL::SigSpec sig = data_reg_out[idx];
|
||||||
|
|
||||||
int wr_offset = 0;
|
for (int j = 0; j < GetSize(mem.wr_ports); j++)
|
||||||
while (wr_offset < mem.width)
|
|
||||||
{
|
{
|
||||||
int wr_width = 1;
|
auto &port = mem.wr_ports[j];
|
||||||
RTLIL::SigSpec wr_bit = port.en.extract(wr_offset + sub * mem.width, 1);
|
RTLIL::SigSpec wr_addr = port.addr.extract_end(port.wide_log2);
|
||||||
|
RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(addr >> port.wide_log2, GetSize(wr_addr)));
|
||||||
|
|
||||||
while (wr_offset + wr_width < mem.width) {
|
int sub = addr & ((1 << port.wide_log2) - 1);
|
||||||
RTLIL::SigSpec next_wr_bit = port.en.extract(wr_offset + wr_width + sub * mem.width, 1);
|
|
||||||
if (next_wr_bit != wr_bit)
|
|
||||||
break;
|
|
||||||
wr_width++;
|
|
||||||
}
|
|
||||||
|
|
||||||
RTLIL::Wire *w = w_seladdr;
|
int wr_offset = 0;
|
||||||
|
while (wr_offset < mem.width)
|
||||||
if (wr_bit != State::S1)
|
|
||||||
{
|
{
|
||||||
RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wren", addr, "", j, "", wr_offset), ID($and));
|
int wr_width = 1;
|
||||||
c->parameters[ID::A_SIGNED] = RTLIL::Const(0);
|
RTLIL::SigSpec wr_bit = port.en.extract(wr_offset + sub * mem.width, 1);
|
||||||
c->parameters[ID::B_SIGNED] = RTLIL::Const(0);
|
|
||||||
c->parameters[ID::A_WIDTH] = RTLIL::Const(1);
|
|
||||||
c->parameters[ID::B_WIDTH] = RTLIL::Const(1);
|
|
||||||
c->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
|
|
||||||
c->setPort(ID::A, w);
|
|
||||||
c->setPort(ID::B, wr_bit);
|
|
||||||
|
|
||||||
w = module->addWire(genid(mem.memid, "$wren", addr, "", j, "", wr_offset, "$y"));
|
while (wr_offset + wr_width < mem.width) {
|
||||||
c->setPort(ID::Y, RTLIL::SigSpec(w));
|
RTLIL::SigSpec next_wr_bit = port.en.extract(wr_offset + wr_width + sub * mem.width, 1);
|
||||||
|
if (next_wr_bit != wr_bit)
|
||||||
|
break;
|
||||||
|
wr_width++;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::Wire *w = w_seladdr;
|
||||||
|
|
||||||
|
if (wr_bit != State::S1)
|
||||||
|
{
|
||||||
|
RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wren", addr, "", j, "", wr_offset), ID($and));
|
||||||
|
c->parameters[ID::A_SIGNED] = RTLIL::Const(0);
|
||||||
|
c->parameters[ID::B_SIGNED] = RTLIL::Const(0);
|
||||||
|
c->parameters[ID::A_WIDTH] = RTLIL::Const(1);
|
||||||
|
c->parameters[ID::B_WIDTH] = RTLIL::Const(1);
|
||||||
|
c->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
|
||||||
|
c->setPort(ID::A, w);
|
||||||
|
c->setPort(ID::B, wr_bit);
|
||||||
|
|
||||||
|
w = module->addWire(genid(mem.memid, "$wren", addr, "", j, "", wr_offset, "$y"));
|
||||||
|
c->setPort(ID::Y, RTLIL::SigSpec(w));
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset), ID($mux));
|
||||||
|
c->parameters[ID::WIDTH] = wr_width;
|
||||||
|
c->setPort(ID::A, sig.extract(wr_offset, wr_width));
|
||||||
|
c->setPort(ID::B, port.data.extract(wr_offset + sub * mem.width, wr_width));
|
||||||
|
c->setPort(ID::S, RTLIL::SigSpec(w));
|
||||||
|
|
||||||
|
w = module->addWire(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset, "$y"), wr_width);
|
||||||
|
c->setPort(ID::Y, w);
|
||||||
|
|
||||||
|
sig.replace(wr_offset, w);
|
||||||
|
wr_offset += wr_width;
|
||||||
|
count_wrmux++;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset), ID($mux));
|
|
||||||
c->parameters[ID::WIDTH] = wr_width;
|
|
||||||
c->setPort(ID::A, sig.extract(wr_offset, wr_width));
|
|
||||||
c->setPort(ID::B, port.data.extract(wr_offset + sub * mem.width, wr_width));
|
|
||||||
c->setPort(ID::S, RTLIL::SigSpec(w));
|
|
||||||
|
|
||||||
w = module->addWire(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset, "$y"), wr_width);
|
|
||||||
c->setPort(ID::Y, w);
|
|
||||||
|
|
||||||
sig.replace(wr_offset, w);
|
|
||||||
wr_offset += wr_width;
|
|
||||||
count_wrmux++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->connect(RTLIL::SigSig(data_reg_in[idx], sig));
|
module->connect(RTLIL::SigSig(data_reg_in[idx], sig));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log(" write interface: %d write mux blocks.\n", count_wrmux);
|
log(" write interface: %d write mux blocks.\n", count_wrmux);
|
||||||
|
@ -366,10 +377,14 @@ struct MemoryMapPass : public Pass {
|
||||||
log(" -iattr\n");
|
log(" -iattr\n");
|
||||||
log(" for -attr, ignore case of <value>.\n");
|
log(" for -attr, ignore case of <value>.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -rom-only\n");
|
||||||
|
log(" only perform conversion for ROMs (memories with no write ports).\n");
|
||||||
|
log("\n");
|
||||||
}
|
}
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
{
|
{
|
||||||
bool attr_icase = false;
|
bool attr_icase = false;
|
||||||
|
bool rom_only = false;
|
||||||
dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
|
dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
|
||||||
|
|
||||||
log_header(design, "Executing MEMORY_MAP pass (converting memories to logic and flip-flops).\n");
|
log_header(design, "Executing MEMORY_MAP pass (converting memories to logic and flip-flops).\n");
|
||||||
|
@ -406,6 +421,11 @@ struct MemoryMapPass : public Pass {
|
||||||
attr_icase = true;
|
attr_icase = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-rom-only")
|
||||||
|
{
|
||||||
|
rom_only = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
@ -414,6 +434,7 @@ struct MemoryMapPass : public Pass {
|
||||||
MemoryMapWorker worker(design, mod);
|
MemoryMapWorker worker(design, mod);
|
||||||
worker.attr_icase = attr_icase;
|
worker.attr_icase = attr_icase;
|
||||||
worker.attributes = attributes;
|
worker.attributes = attributes;
|
||||||
|
worker.rom_only = rom_only;
|
||||||
worker.run();
|
worker.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue