mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #1603 from whitequark/ice40-ram_style
ice40/ecp5: add support for both 1364.1 and Synplify/LSE RAM/ROM attributes
This commit is contained in:
commit
93ef516d91
|
@ -137,9 +137,26 @@ struct rules_t
|
||||||
vector<vector<std::tuple<bool,IdString,Const>>> attributes;
|
vector<vector<std::tuple<bool,IdString,Const>>> attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool attr_icase;
|
||||||
dict<IdString, vector<bram_t>> brams;
|
dict<IdString, vector<bram_t>> brams;
|
||||||
vector<match_t> matches;
|
vector<match_t> matches;
|
||||||
|
|
||||||
|
std::string map_case(std::string value) const
|
||||||
|
{
|
||||||
|
if (attr_icase) {
|
||||||
|
for (char &c : value)
|
||||||
|
c = tolower(c);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::Const map_case(RTLIL::Const value) const
|
||||||
|
{
|
||||||
|
if (value.flags & RTLIL::CONST_FLAG_STRING)
|
||||||
|
return map_case(value.decode_string());
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
std::ifstream infile;
|
std::ifstream infile;
|
||||||
vector<string> tokens;
|
vector<string> tokens;
|
||||||
vector<string> labels;
|
vector<string> labels;
|
||||||
|
@ -337,7 +354,7 @@ struct rules_t
|
||||||
IdString key = RTLIL::escape_id(tokens[idx].substr(c1, c2));
|
IdString key = RTLIL::escape_id(tokens[idx].substr(c1, c2));
|
||||||
Const val = c2 != std::string::npos ? tokens[idx].substr(c2+1) : RTLIL::Const(1);
|
Const val = c2 != std::string::npos ? tokens[idx].substr(c2+1) : RTLIL::Const(1);
|
||||||
|
|
||||||
data.attributes.back().emplace_back(exists, key, val);
|
data.attributes.back().emplace_back(exists, key, map_case(val));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -351,6 +368,7 @@ struct rules_t
|
||||||
rewrite_filename(filename);
|
rewrite_filename(filename);
|
||||||
infile.open(filename);
|
infile.open(filename);
|
||||||
linecount = 0;
|
linecount = 0;
|
||||||
|
attr_icase = false;
|
||||||
|
|
||||||
if (infile.fail())
|
if (infile.fail())
|
||||||
log_error("Can't open rules file `%s'.\n", filename.c_str());
|
log_error("Can't open rules file `%s'.\n", filename.c_str());
|
||||||
|
@ -360,6 +378,11 @@ struct rules_t
|
||||||
if (!labels.empty())
|
if (!labels.empty())
|
||||||
syntax_error();
|
syntax_error();
|
||||||
|
|
||||||
|
if (GetSize(tokens) == 2 && tokens[0] == "attr_icase") {
|
||||||
|
attr_icase = atoi(tokens[1].c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (tokens[0] == "bram") {
|
if (tokens[0] == "bram") {
|
||||||
parse_bram();
|
parse_bram();
|
||||||
continue;
|
continue;
|
||||||
|
@ -843,7 +866,7 @@ grow_read_ports:;
|
||||||
}
|
}
|
||||||
else if (!exists)
|
else if (!exists)
|
||||||
continue;
|
continue;
|
||||||
if (it->second != value)
|
if (rules.map_case(it->second) != value)
|
||||||
continue;
|
continue;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -855,7 +878,7 @@ grow_read_ports:;
|
||||||
ss << "!";
|
ss << "!";
|
||||||
IdString key = std::get<1>(sums.front());
|
IdString key = std::get<1>(sums.front());
|
||||||
ss << log_id(key);
|
ss << log_id(key);
|
||||||
const Const &value = std::get<2>(sums.front());
|
const Const &value = rules.map_case(std::get<2>(sums.front()));
|
||||||
if (exists && value != Const(1))
|
if (exists && value != Const(1))
|
||||||
ss << "=\"" << value.decode_string() << "\"";
|
ss << "=\"" << value.decode_string() << "\"";
|
||||||
|
|
||||||
|
@ -1167,7 +1190,7 @@ void handle_cell(Cell *cell, const rules_t &rules)
|
||||||
}
|
}
|
||||||
else if (!exists)
|
else if (!exists)
|
||||||
continue;
|
continue;
|
||||||
if (it->second != value)
|
if (rules.map_case(it->second) != value)
|
||||||
continue;
|
continue;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1179,7 +1202,7 @@ void handle_cell(Cell *cell, const rules_t &rules)
|
||||||
ss << "!";
|
ss << "!";
|
||||||
IdString key = std::get<1>(sums.front());
|
IdString key = std::get<1>(sums.front());
|
||||||
ss << log_id(key);
|
ss << log_id(key);
|
||||||
const Const &value = std::get<2>(sums.front());
|
const Const &value = rules.map_case(std::get<2>(sums.front()));
|
||||||
if (exists && value != Const(1))
|
if (exists && value != Const(1))
|
||||||
ss << "=\"" << value.decode_string() << "\"";
|
ss << "=\"" << value.decode_string() << "\"";
|
||||||
|
|
||||||
|
@ -1252,8 +1275,13 @@ struct MemoryBramPass : public Pass {
|
||||||
log("The given rules file describes the available resources and how they should be\n");
|
log("The given rules file describes the available resources and how they should be\n");
|
||||||
log("used.\n");
|
log("used.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("The rules file contains a set of block ram description and a sequence of match\n");
|
log("The rules file contains configuration options, a set of block ram description\n");
|
||||||
log("rules. A block ram description looks like this:\n");
|
log("and a sequence of match rules.\n");
|
||||||
|
log("\n");
|
||||||
|
log("The option 'attr_icase' configures how attribute values are matched. The value 0\n");
|
||||||
|
log("means case-sensitive, 1 means case-insensitive.\n");
|
||||||
|
log("\n");
|
||||||
|
log("A block ram description looks like this:\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" bram RAMB1024X32 # name of BRAM cell\n");
|
log(" bram RAMB1024X32 # name of BRAM cell\n");
|
||||||
log(" init 1 # set to '1' if BRAM can be initialized\n");
|
log(" init 1 # set to '1' if BRAM can be initialized\n");
|
||||||
|
|
|
@ -28,11 +28,32 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct MemoryMapWorker
|
struct MemoryMapWorker
|
||||||
{
|
{
|
||||||
|
bool attr_icase = false;
|
||||||
|
dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
|
||||||
|
|
||||||
RTLIL::Design *design;
|
RTLIL::Design *design;
|
||||||
RTLIL::Module *module;
|
RTLIL::Module *module;
|
||||||
|
|
||||||
std::map<std::pair<RTLIL::SigSpec, RTLIL::SigSpec>, RTLIL::SigBit> decoder_cache;
|
std::map<std::pair<RTLIL::SigSpec, RTLIL::SigSpec>, RTLIL::SigBit> decoder_cache;
|
||||||
|
|
||||||
|
MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module) {}
|
||||||
|
|
||||||
|
std::string map_case(std::string value) const
|
||||||
|
{
|
||||||
|
if (attr_icase) {
|
||||||
|
for (char &c : value)
|
||||||
|
c = tolower(c);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::Const map_case(RTLIL::Const value) const
|
||||||
|
{
|
||||||
|
if (value.flags & RTLIL::CONST_FLAG_STRING)
|
||||||
|
return map_case(value.decode_string());
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
std::string genid(RTLIL::IdString name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "")
|
std::string genid(RTLIL::IdString name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "")
|
||||||
{
|
{
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
|
@ -98,6 +119,36 @@ struct MemoryMapWorker
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if attributes allow us to infer FFRAM for this cell
|
||||||
|
for (const auto &attr : attributes) {
|
||||||
|
if (cell->attributes.count(attr.first)) {
|
||||||
|
const auto &cell_attr = cell->attributes[attr.first];
|
||||||
|
if (attr.second.empty()) {
|
||||||
|
log("Not mapping memory cell %s in module %s (attribute %s is set).\n",
|
||||||
|
cell->name.c_str(), module->name.c_str(), attr.first.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (auto &value : attr.second) {
|
||||||
|
if (map_case(cell_attr) == map_case(value)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
if (cell_attr.flags & RTLIL::CONST_FLAG_STRING) {
|
||||||
|
log("Not mapping memory cell %s in module %s (attribute %s is set to \"%s\").\n",
|
||||||
|
cell->name.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.decode_string().c_str());
|
||||||
|
} else {
|
||||||
|
log("Not mapping memory cell %s in module %s (attribute %s is set to %d).\n",
|
||||||
|
cell->name.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.as_int());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// all write ports must share the same clock
|
// all write ports must share the same clock
|
||||||
RTLIL::SigSpec clocks = cell->getPort(ID::WR_CLK);
|
RTLIL::SigSpec clocks = cell->getPort(ID::WR_CLK);
|
||||||
RTLIL::Const clocks_pol = cell->parameters[ID::WR_CLK_POLARITY];
|
RTLIL::Const clocks_pol = cell->parameters[ID::WR_CLK_POLARITY];
|
||||||
|
@ -339,7 +390,7 @@ struct MemoryMapWorker
|
||||||
module->remove(cell);
|
module->remove(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module)
|
void run()
|
||||||
{
|
{
|
||||||
std::vector<RTLIL::Cell*> cells;
|
std::vector<RTLIL::Cell*> cells;
|
||||||
for (auto cell : module->selected_cells())
|
for (auto cell : module->selected_cells())
|
||||||
|
@ -356,17 +407,73 @@ struct MemoryMapPass : public Pass {
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" memory_map [selection]\n");
|
log(" memory_map [options] [selection]\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("This pass converts multiport memory cells as generated by the memory_collect\n");
|
log("This pass converts multiport memory cells as generated by the memory_collect\n");
|
||||||
log("pass to word-wide DFFs and address decoders.\n");
|
log("pass to word-wide DFFs and address decoders.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -attr !<name>\n");
|
||||||
|
log(" do not map memories that have attribute <name> set.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -attr <name>[=<value>]\n");
|
||||||
|
log(" for memories that have attribute <name> set, only map them if its value\n");
|
||||||
|
log(" is a string <value> (if specified), or an integer 1 (otherwise). if this\n");
|
||||||
|
log(" option is specified multiple times, map the memory if the attribute is\n");
|
||||||
|
log(" to any of the values.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -iattr\n");
|
||||||
|
log(" for -attr, ignore case of <value>.\n");
|
||||||
|
log("\n");
|
||||||
}
|
}
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
|
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||||
|
{
|
||||||
|
bool attr_icase = false;
|
||||||
|
dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
|
||||||
|
|
||||||
log_header(design, "Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops).\n");
|
log_header(design, "Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops).\n");
|
||||||
extra_args(args, 1, design);
|
|
||||||
for (auto mod : design->selected_modules())
|
size_t argidx;
|
||||||
MemoryMapWorker(design, mod);
|
for (argidx = 1; argidx < args.size(); argidx++)
|
||||||
|
{
|
||||||
|
if (args[argidx] == "-attr" && argidx + 1 < args.size())
|
||||||
|
{
|
||||||
|
std::string attr_arg = args[++argidx];
|
||||||
|
std::string name;
|
||||||
|
RTLIL::Const value;
|
||||||
|
size_t eq_at = attr_arg.find('=');
|
||||||
|
if (eq_at != std::string::npos) {
|
||||||
|
name = attr_arg.substr(0, eq_at);
|
||||||
|
value = attr_arg.substr(eq_at + 1);
|
||||||
|
} else {
|
||||||
|
name = attr_arg;
|
||||||
|
value = RTLIL::Const(1);
|
||||||
|
}
|
||||||
|
if (attr_arg.size() > 1 && attr_arg[0] == '!') {
|
||||||
|
if (value != RTLIL::Const(1)) {
|
||||||
|
--argidx;
|
||||||
|
break; // we don't support -attr !<name>=<value>
|
||||||
|
}
|
||||||
|
attributes[RTLIL::escape_id(name.substr(1))].clear();
|
||||||
|
} else {
|
||||||
|
attributes[RTLIL::escape_id(name)].push_back(value);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-iattr")
|
||||||
|
{
|
||||||
|
attr_icase = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
|
for (auto mod : design->selected_modules()) {
|
||||||
|
MemoryMapWorker worker(design, mod);
|
||||||
|
worker.attr_icase = attr_icase;
|
||||||
|
worker.attributes = attributes;
|
||||||
|
worker.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} MemoryMapPass;
|
} MemoryMapPass;
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,17 @@ bram $__ECP5_DP16KD
|
||||||
clkpol 2 3
|
clkpol 2 3
|
||||||
endbram
|
endbram
|
||||||
|
|
||||||
|
# The syn_* attributes are described in:
|
||||||
|
# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
|
||||||
|
attr_icase 1
|
||||||
|
|
||||||
match $__ECP5_PDPW16KD
|
match $__ECP5_PDPW16KD
|
||||||
|
# implicitly requested RAM or ROM
|
||||||
|
attribute !syn_ramstyle syn_ramstyle=auto
|
||||||
|
attribute !syn_romstyle syn_romstyle=auto
|
||||||
|
attribute !ram_block
|
||||||
|
attribute !rom_block
|
||||||
|
attribute !logic_block
|
||||||
min bits 2048
|
min bits 2048
|
||||||
min efficiency 5
|
min efficiency 5
|
||||||
shuffle_enable A
|
shuffle_enable A
|
||||||
|
@ -45,8 +55,60 @@ match $__ECP5_PDPW16KD
|
||||||
or_next_if_better
|
or_next_if_better
|
||||||
endmatch
|
endmatch
|
||||||
|
|
||||||
|
match $__ECP5_PDPW16KD
|
||||||
|
# explicitly requested RAM
|
||||||
|
attribute syn_ramstyle=block_ram ram_block
|
||||||
|
attribute !syn_romstyle
|
||||||
|
attribute !rom_block
|
||||||
|
attribute !logic_block
|
||||||
|
min wports 1
|
||||||
|
shuffle_enable A
|
||||||
|
make_transp
|
||||||
|
or_next_if_better
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
match $__ECP5_PDPW16KD
|
||||||
|
# explicitly requested ROM
|
||||||
|
attribute syn_romstyle=ebr rom_block
|
||||||
|
attribute !syn_ramstyle
|
||||||
|
attribute !ram_block
|
||||||
|
attribute !logic_block
|
||||||
|
max wports 0
|
||||||
|
shuffle_enable A
|
||||||
|
make_transp
|
||||||
|
or_next_if_better
|
||||||
|
endmatch
|
||||||
|
|
||||||
match $__ECP5_DP16KD
|
match $__ECP5_DP16KD
|
||||||
|
# implicitly requested RAM or ROM
|
||||||
|
attribute !syn_ramstyle syn_ramstyle=auto
|
||||||
|
attribute !syn_romstyle syn_romstyle=auto
|
||||||
|
attribute !ram_block
|
||||||
|
attribute !rom_block
|
||||||
|
attribute !logic_block
|
||||||
min bits 2048
|
min bits 2048
|
||||||
min efficiency 5
|
min efficiency 5
|
||||||
shuffle_enable A
|
shuffle_enable A
|
||||||
|
or_next_if_better
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
match $__ECP5_DP16KD
|
||||||
|
# explicitly requested RAM
|
||||||
|
attribute syn_ramstyle=block_ram ram_block
|
||||||
|
attribute !syn_romstyle
|
||||||
|
attribute !rom_block
|
||||||
|
attribute !logic_block
|
||||||
|
min wports 1
|
||||||
|
shuffle_enable A
|
||||||
|
or_next_if_better
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
match $__ECP5_DP16KD
|
||||||
|
# explicitly requested ROM
|
||||||
|
attribute syn_romstyle=ebr rom_block
|
||||||
|
attribute !syn_ramstyle
|
||||||
|
attribute !ram_block
|
||||||
|
attribute !logic_block
|
||||||
|
max wports 0
|
||||||
|
shuffle_enable A
|
||||||
endmatch
|
endmatch
|
||||||
|
|
|
@ -11,7 +11,16 @@ bram $__TRELLIS_DPR16X4
|
||||||
clkpol 0 2
|
clkpol 0 2
|
||||||
endbram
|
endbram
|
||||||
|
|
||||||
|
# The syn_* attributes are described in:
|
||||||
|
# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
|
||||||
|
attr_icase 1
|
||||||
|
|
||||||
match $__TRELLIS_DPR16X4
|
match $__TRELLIS_DPR16X4
|
||||||
|
attribute !syn_ramstyle syn_ramstyle=auto syn_ramstyle=distributed
|
||||||
|
attribute !syn_romstyle syn_romstyle=auto
|
||||||
|
attribute !ram_block
|
||||||
|
attribute !rom_block
|
||||||
|
attribute !logic_block
|
||||||
make_outreg
|
make_outreg
|
||||||
min wports 1
|
min wports 1
|
||||||
endmatch
|
endmatch
|
||||||
|
|
|
@ -279,7 +279,9 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
if (check_label("map_ffram"))
|
if (check_label("map_ffram"))
|
||||||
{
|
{
|
||||||
run("opt -fast -mux_undef -undriven -fine");
|
run("opt -fast -mux_undef -undriven -fine");
|
||||||
run("memory_map");
|
run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
|
||||||
|
"-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
|
||||||
|
"-attr syn_romstyle=auto -attr syn_romstyle=logic");
|
||||||
run("opt -undriven -fine");
|
run("opt -undriven -fine");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,73 @@ bram $__ICE40_RAM4K_M123
|
||||||
clkpol 2 3
|
clkpol 2 3
|
||||||
endbram
|
endbram
|
||||||
|
|
||||||
|
# The syn_* attributes are described in:
|
||||||
|
# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
|
||||||
|
attr_icase 1
|
||||||
|
|
||||||
match $__ICE40_RAM4K_M0
|
match $__ICE40_RAM4K_M0
|
||||||
|
# implicitly requested RAM or ROM
|
||||||
|
attribute !syn_ramstyle syn_ramstyle=auto
|
||||||
|
attribute !syn_romstyle syn_romstyle=auto
|
||||||
|
attribute !ram_block
|
||||||
|
attribute !rom_block
|
||||||
|
attribute !logic_block
|
||||||
|
min efficiency 2
|
||||||
|
make_transp
|
||||||
|
or_next_if_better
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
match $__ICE40_RAM4K_M0
|
||||||
|
# explicitly requested RAM
|
||||||
|
attribute syn_ramstyle=block_ram ram_block
|
||||||
|
attribute !syn_romstyle
|
||||||
|
attribute !rom_block
|
||||||
|
attribute !logic_block
|
||||||
|
min wports 1
|
||||||
|
make_transp
|
||||||
|
or_next_if_better
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
match $__ICE40_RAM4K_M0
|
||||||
|
# explicitly requested ROM
|
||||||
|
attribute syn_romstyle=ebr rom_block
|
||||||
|
attribute !syn_ramstyle
|
||||||
|
attribute !ram_block
|
||||||
|
attribute !logic_block
|
||||||
|
max wports 0
|
||||||
|
make_transp
|
||||||
|
or_next_if_better
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
match $__ICE40_RAM4K_M123
|
||||||
|
# implicitly requested RAM or ROM
|
||||||
|
attribute !syn_ramstyle syn_ramstyle=auto
|
||||||
|
attribute !syn_romstyle syn_romstyle=auto
|
||||||
|
attribute !ram_block
|
||||||
|
attribute !rom_block
|
||||||
|
attribute !logic_block
|
||||||
min efficiency 2
|
min efficiency 2
|
||||||
make_transp
|
make_transp
|
||||||
or_next_if_better
|
or_next_if_better
|
||||||
endmatch
|
endmatch
|
||||||
|
|
||||||
match $__ICE40_RAM4K_M123
|
match $__ICE40_RAM4K_M123
|
||||||
min efficiency 2
|
# explicitly requested RAM
|
||||||
|
attribute syn_ramstyle=block_ram ram_block
|
||||||
|
attribute !syn_romstyle
|
||||||
|
attribute !rom_block
|
||||||
|
attribute !logic_block
|
||||||
|
min wports 1
|
||||||
|
make_transp
|
||||||
|
or_next_if_better
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
match $__ICE40_RAM4K_M123
|
||||||
|
# explicitly requested ROM
|
||||||
|
attribute syn_romstyle=ebr rom_block
|
||||||
|
attribute !syn_ramstyle
|
||||||
|
attribute !ram_block
|
||||||
|
attribute !logic_block
|
||||||
|
max wports 0
|
||||||
make_transp
|
make_transp
|
||||||
endmatch
|
endmatch
|
||||||
|
|
|
@ -319,7 +319,9 @@ struct SynthIce40Pass : public ScriptPass
|
||||||
if (check_label("map_ffram"))
|
if (check_label("map_ffram"))
|
||||||
{
|
{
|
||||||
run("opt -fast -mux_undef -undriven -fine");
|
run("opt -fast -mux_undef -undriven -fine");
|
||||||
run("memory_map");
|
run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
|
||||||
|
"-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
|
||||||
|
"-attr syn_romstyle=auto -attr syn_romstyle=logic");
|
||||||
run("opt -undriven -fine");
|
run("opt -undriven -fine");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,19 +5,20 @@ module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
|
||||||
input wire [ADDRESS_WIDTH-1:0] address_in,
|
input wire [ADDRESS_WIDTH-1:0] address_in,
|
||||||
output wire [DATA_WIDTH-1:0] data_out);
|
output wire [DATA_WIDTH-1:0] data_out);
|
||||||
|
|
||||||
localparam WORD = (DATA_WIDTH-1);
|
localparam WORD = (DATA_WIDTH-1);
|
||||||
localparam DEPTH = (2**ADDRESS_WIDTH-1);
|
localparam DEPTH = (2**ADDRESS_WIDTH-1);
|
||||||
|
|
||||||
reg [WORD:0] data_out_r;
|
reg [WORD:0] data_out_r;
|
||||||
reg [WORD:0] memory [0:DEPTH];
|
reg [WORD:0] memory [0:DEPTH];
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (write_enable)
|
if (write_enable)
|
||||||
memory[address_in] <= data_in;
|
memory[address_in] <= data_in;
|
||||||
data_out_r <= memory[address_in];
|
data_out_r <= memory[address_in];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
assign data_out = data_out_r;
|
||||||
|
|
||||||
assign data_out = data_out_r;
|
|
||||||
endmodule // sync_ram_sp
|
endmodule // sync_ram_sp
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,18 +29,19 @@ module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
|
||||||
input wire [ADDRESS_WIDTH-1:0] address_in_r, address_in_w,
|
input wire [ADDRESS_WIDTH-1:0] address_in_r, address_in_w,
|
||||||
output wire [DATA_WIDTH-1:0] data_out);
|
output wire [DATA_WIDTH-1:0] data_out);
|
||||||
|
|
||||||
localparam WORD = (DATA_WIDTH-1);
|
localparam WORD = (DATA_WIDTH-1);
|
||||||
localparam DEPTH = (2**ADDRESS_WIDTH-1);
|
localparam DEPTH = (2**ADDRESS_WIDTH-1);
|
||||||
|
|
||||||
reg [WORD:0] data_out_r;
|
reg [WORD:0] data_out_r;
|
||||||
reg [WORD:0] memory [0:DEPTH];
|
reg [WORD:0] memory [0:DEPTH];
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (write_enable)
|
if (write_enable)
|
||||||
memory[address_in_w] <= data_in;
|
memory[address_in_w] <= data_in;
|
||||||
data_out_r <= memory[address_in_r];
|
data_out_r <= memory[address_in_r];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
assign data_out = data_out_r;
|
||||||
|
|
||||||
assign data_out = data_out_r;
|
|
||||||
endmodule // sync_ram_sdp
|
endmodule // sync_ram_sdp
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
`default_nettype none
|
||||||
|
module sync_rom #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
|
||||||
|
(input wire clk,
|
||||||
|
input wire [ADDRESS_WIDTH-1:0] address_in,
|
||||||
|
output wire [DATA_WIDTH-1:0] data_out);
|
||||||
|
|
||||||
|
localparam WORD = (DATA_WIDTH-1);
|
||||||
|
localparam DEPTH = (2**ADDRESS_WIDTH-1);
|
||||||
|
|
||||||
|
reg [WORD:0] data_out_r;
|
||||||
|
reg [WORD:0] memory [0:DEPTH];
|
||||||
|
|
||||||
|
integer i,j = 64'hF4B1CA8127865242;
|
||||||
|
initial
|
||||||
|
for (i = 0; i <= DEPTH; i++) begin
|
||||||
|
// In case this ROM will be implemented in fabric: fill the memory with some data
|
||||||
|
// uncorrelated with the address, or Yosys might see through the ruse and e.g. not
|
||||||
|
// emit any LUTs at all for `memory[i] = i;`, just a latch.
|
||||||
|
memory[i] = j * 64'h2545F4914F6CDD1D;
|
||||||
|
j = j ^ (j >> 12);
|
||||||
|
j = j ^ (j << 25);
|
||||||
|
j = j ^ (j >> 27);
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
data_out_r <= memory[address_in];
|
||||||
|
end
|
||||||
|
|
||||||
|
assign data_out = data_out_r;
|
||||||
|
|
||||||
|
endmodule // sync_rom
|
|
@ -0,0 +1,330 @@
|
||||||
|
# ================================ RAM ================================
|
||||||
|
# RAM bits <= 18K; Data width <= 36; Address width <= 9: -> PDPW16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:PDPW16KD
|
||||||
|
|
||||||
|
## With parameters
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:PDPW16KD # too inefficient
|
||||||
|
select -assert-count 9 t:TRELLIS_DPR16X4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "block_ram" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:PDPW16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "Block_RAM" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:PDPW16KD # any case works
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
setattr -set ram_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:PDPW16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "registers" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:PDPW16KD # requested FFRAM explicitly
|
||||||
|
select -assert-count 180 t:TRELLIS_FF
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
setattr -set logic_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:PDPW16KD # requested FFRAM explicitly
|
||||||
|
select -assert-count 180 t:TRELLIS_FF
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
setattr -set syn_romstyle "ebr" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but this is a RAM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
setattr -set rom_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but this is a RAM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "block_ram" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
setattr -set ram_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
|
||||||
|
|
||||||
|
# RAM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 11 -set DATA_WIDTH 9 sync_ram_sdp
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 12 -set DATA_WIDTH 4 sync_ram_sdp
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 13 -set DATA_WIDTH 2 sync_ram_sdp
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
## With parameters
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:DP16KD # too inefficient
|
||||||
|
select -assert-count 5 t:TRELLIS_DPR16X4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "block_ram" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "Block_RAM" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:DP16KD # any case works
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set ram_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "registers" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:DP16KD # requested FFRAM explicitly
|
||||||
|
select -assert-count 90 t:TRELLIS_FF
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set logic_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:DP16KD # requested FFRAM explicitly
|
||||||
|
select -assert-count 90 t:TRELLIS_FF
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set syn_romstyle "ebr" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but this is a RAM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set rom_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but this is a RAM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "block_ram" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set ram_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
|
||||||
|
|
||||||
|
# RAM bits <= 64; Data width <= 4; Address width <= 4: -> DPR16X4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:TRELLIS_DPR16X4
|
||||||
|
|
||||||
|
## With parameters
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "distributed" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:TRELLIS_DPR16X4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "registers" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:TRELLIS_DPR16X4 # requested FFRAM explicitly
|
||||||
|
select -assert-count 68 t:TRELLIS_FF
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
|
||||||
|
setattr -set logic_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:TRELLIS_DPR16X4 # requested FFRAM explicitly
|
||||||
|
select -assert-count 68 t:TRELLIS_FF
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "distributed" m:memory
|
||||||
|
synth_ecp5 -top sync_ram_sdp -nolutram; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested LUTRAM but LUTRAM is disabled
|
||||||
|
|
||||||
|
# ================================ ROM ================================
|
||||||
|
# ROM bits <= 18K; Data width <= 36; Address width <= 9: -> PDPW16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_rom
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:PDPW16KD
|
||||||
|
|
||||||
|
## With parameters
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom
|
||||||
|
write_ilang
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 0 t:PDPW16KD # too inefficient
|
||||||
|
select -assert-min 18 t:LUT4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
|
||||||
|
setattr -set syn_romstyle "ebr" m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:PDPW16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
|
||||||
|
setattr -set rom_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:PDPW16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom
|
||||||
|
setattr -set syn_romstyle "logic" m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 0 t:PDPW16KD # requested LUTROM explicitly
|
||||||
|
select -assert-min 18 t:LUT4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom
|
||||||
|
setattr -set logic_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 0 t:PDPW16KD # requested LUTROM explicitly
|
||||||
|
select -assert-min 18 t:LUT4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
|
||||||
|
setattr -set syn_ramstyle "block_ram" m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but this is a ROM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
|
||||||
|
setattr -set ram_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but this is a ROM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
|
||||||
|
setattr -set syn_ramstyle "block_rom" m:memory
|
||||||
|
synth_ecp5 -top sync_rom -nobram; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
|
||||||
|
setattr -set rom_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_rom -nobram; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
|
||||||
|
|
||||||
|
# ROM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_rom
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
## With parameters
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom
|
||||||
|
write_ilang
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 0 t:DP16KD # too inefficient
|
||||||
|
select -assert-min 9 t:LUT4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
|
||||||
|
setattr -set syn_romstyle "ebr" m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
|
||||||
|
setattr -set rom_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:DP16KD
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom
|
||||||
|
setattr -set syn_romstyle "logic" m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 0 t:DP16KD # requested LUTROM explicitly
|
||||||
|
select -assert-min 9 t:LUT4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom
|
||||||
|
setattr -set logic_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 0 t:DP16KD # requested LUTROM explicitly
|
||||||
|
select -assert-min 9 t:LUT4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
|
||||||
|
setattr -set syn_ramstyle "block_ram" m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but this is a ROM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
|
||||||
|
setattr -set ram_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but this is a ROM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
|
||||||
|
setattr -set syn_ramstyle "block_rom" m:memory
|
||||||
|
synth_ecp5 -top sync_rom -nobram; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
|
||||||
|
setattr -set rom_block 1 m:memory
|
||||||
|
synth_ecp5 -top sync_rom -nobram; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
|
|
@ -1,15 +0,0 @@
|
||||||
read_verilog ../common/lutram.v
|
|
||||||
hierarchy -top lutram_1w1r
|
|
||||||
proc
|
|
||||||
memory -nomap
|
|
||||||
equiv_opt -run :prove -map +/ice40/cells_sim.v synth_ice40
|
|
||||||
memory
|
|
||||||
opt -full
|
|
||||||
|
|
||||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
|
||||||
sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
|
|
||||||
|
|
||||||
design -load postopt
|
|
||||||
cd lutram_1w1r
|
|
||||||
select -assert-count 1 t:SB_RAM40_4K
|
|
||||||
select -assert-none t:SB_RAM40_4K %% t:* %D
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
# ================================ RAM ================================
|
||||||
|
# RAM bits <= 4K; Data width <= 16; Address width <= 11: -> SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 11 -set DATA_WIDTH 2 sync_ram_sdp
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 4 sync_ram_sdp
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 16 sync_ram_sdp
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
## With parameters
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:SB_RAM40_4K # too inefficient
|
||||||
|
select -assert-min 1 t:SB_DFFE
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "block_ram" m:memory
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "Block_RAM" m:memory
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K # any case works
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
setattr -set ram_block 1 m:memory
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "registers" m:memory
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:SB_RAM40_4K # requested FFRAM explicitly
|
||||||
|
select -assert-min 1 t:SB_DFFE
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
setattr -set logic_block 1 m:memory
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:SB_RAM40_4K # requested FFRAM explicitly
|
||||||
|
select -assert-min 1 t:SB_DFFE
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
setattr -set syn_romstyle "ebr" m:memory
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but this is a RAM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
setattr -set rom_block 1 m:memory
|
||||||
|
synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but this is a RAM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
setattr -set syn_ramstyle "block_ram" m:memory
|
||||||
|
synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
|
||||||
|
setattr -set ram_block 1 m:memory
|
||||||
|
synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
|
||||||
|
|
||||||
|
# ================================ ROM ================================
|
||||||
|
# ROM bits <= 4K; Data width <= 16; Address width <= 11: -> SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 11 -set DATA_WIDTH 2 sync_rom
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 4 sync_rom
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 8 sync_rom
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 16 sync_rom
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
## With parameters
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
|
||||||
|
write_ilang
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 0 t:SB_RAM40_4K # too inefficient
|
||||||
|
select -assert-min 1 t:SB_LUT4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
|
||||||
|
setattr -set syn_romstyle "ebr" m:memory
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
|
||||||
|
setattr -set rom_block 1 m:memory
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:SB_RAM40_4K
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
|
||||||
|
setattr -set syn_romstyle "logic" m:memory
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 0 t:SB_RAM40_4K # requested LUTROM explicitly
|
||||||
|
select -assert-min 1 t:SB_LUT4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
|
||||||
|
setattr -set logic_block 1 m:memory
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 0 t:SB_RAM40_4K # requested LUTROM explicitly
|
||||||
|
select -assert-min 1 t:SB_LUT4
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
|
||||||
|
setattr -set syn_ramstyle "block_ram" m:memory
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but this is a ROM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
|
||||||
|
setattr -set ram_block 1 m:memory
|
||||||
|
synth_ice40 -top sync_rom; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BRAM but this is a ROM
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
|
||||||
|
setattr -set syn_romstyle "ebr" m:memory
|
||||||
|
synth_ice40 -top sync_rom -nobram; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
|
||||||
|
|
||||||
|
design -reset; read_verilog ../common/blockrom.v
|
||||||
|
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
|
||||||
|
setattr -set rom_block 1 m:memory
|
||||||
|
synth_ice40 -top sync_rom -nobram; cd sync_rom
|
||||||
|
select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
|
Loading…
Reference in New Issue