mirror of https://github.com/YosysHQ/yosys.git
Merge remote-tracking branch 'origin/master' into xaig_dff
This commit is contained in:
commit
09ee96e8c2
46
CodingReadme
46
CodingReadme
|
@ -202,6 +202,52 @@ of how to use the Yosys API:
|
|||
manual/PRESENTATION_Prog/my_cmd.cc
|
||||
|
||||
|
||||
Script Passes
|
||||
-------------
|
||||
|
||||
The ScriptPass base class can be used to implement passes that just call other passes,
|
||||
like a script. Examples for such passes are:
|
||||
|
||||
techlibs/common/prep.cc
|
||||
techlibs/common/synth.cc
|
||||
|
||||
In some cases it is easier to implement such a pass as regular pass, for example when
|
||||
ScriptPass doesn't provide the type of flow control desired. (But many of the
|
||||
script passes in Yosys that don't use ScriptPass simply predate the ScriptPass base
|
||||
class.) Examples for such passes are:
|
||||
|
||||
passes/opt/opt.cc
|
||||
passes/proc/proc.cc
|
||||
|
||||
Whether they use the ScriptPass base-class or not, a pass should always either
|
||||
call other passes without doing any non-trivial work itself, or should implement
|
||||
a non-trivial algorithm but not call any other passes. The reason for this is that
|
||||
this helps containing complexity in individual passes and simplifies debugging the
|
||||
entire system.
|
||||
|
||||
Exceptions to this rule should be rare and limited to cases where calling other
|
||||
passes is optional and only happens when requested by the user (such as for
|
||||
example `techmap -autoproc`), or where it is about commands that are "top-level
|
||||
commands" in their own right, not components to be used in regular synthesis
|
||||
flows (such as the `bugpoint` command).
|
||||
|
||||
A pass that would "naturally" call other passes and also do some work itself
|
||||
should be re-written in one of two ways:
|
||||
|
||||
1) It could be re-written as script pass with the parts that are not calls
|
||||
to other passes factored out into individual new passes. Usually in those
|
||||
cases the new sub passes share the same prefix as the top-level script pass.
|
||||
|
||||
2) It could be re-written so that it already expects the design in a certain
|
||||
state, expecting the calling script to set up this state before calling the
|
||||
pass in questions.
|
||||
|
||||
Many back-ends are examples for the 2nd approach. For example, `write_aiger`
|
||||
does not convert the design into AIG representation, but expects the design
|
||||
to be already in this form, and prints an `Unsupported cell type` error
|
||||
message otherwise.
|
||||
|
||||
|
||||
Notes on the existing codebase
|
||||
------------------------------
|
||||
|
||||
|
|
10
Makefile
10
Makefile
|
@ -147,9 +147,9 @@ $(info $(subst $$--$$,$(newline),$(shell sed 's,^,[Makefile.conf] ,; s,$$,$$--$$
|
|||
include Makefile.conf
|
||||
endif
|
||||
|
||||
PYTHON_EXECUTABLE := $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi)
|
||||
ifeq ($(ENABLE_PYOSYS),1)
|
||||
PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)"
|
||||
PYTHON_EXECUTABLE := $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi)
|
||||
PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"")
|
||||
PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.)
|
||||
PYTHON_PREFIX := $(shell $(PYTHON_EXECUTABLE)-config --prefix)
|
||||
|
@ -708,11 +708,17 @@ test: $(TARGETS) $(EXTRA_TARGETS)
|
|||
+cd tests/various && bash run-test.sh
|
||||
+cd tests/sat && bash run-test.sh
|
||||
+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/svtypes && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/proc && bash run-test.sh
|
||||
+cd tests/opt && bash run-test.sh
|
||||
+cd tests/aiger && bash run-test.sh $(ABCOPT)
|
||||
+cd tests/arch && bash run-test.sh
|
||||
+cd tests/ice40 && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/ice40 && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/xilinx && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/ecp5 && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/efinix && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/anlogic && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/gowin && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/rpc && bash run-test.sh
|
||||
@echo ""
|
||||
@echo " Passed \"make test\"."
|
||||
|
|
|
@ -510,6 +510,8 @@ from SystemVerilog:
|
|||
into a design with ``read_verilog``, all its packages are available to
|
||||
SystemVerilog files being read into the same design afterwards.
|
||||
|
||||
- typedefs are supported (including inside packages)
|
||||
|
||||
- SystemVerilog interfaces (SVIs) are supported. Modports for specifying whether
|
||||
ports are inputs or outputs are supported.
|
||||
|
||||
|
|
|
@ -91,6 +91,9 @@ struct AigerWriter
|
|||
} else
|
||||
if (alias_map.count(bit)) {
|
||||
a = bit2aig(alias_map.at(bit));
|
||||
} else
|
||||
if (initstate_bits.count(bit)) {
|
||||
a = initstate_ff;
|
||||
}
|
||||
|
||||
if (bit == State::Sx || bit == State::Sz)
|
||||
|
|
|
@ -1070,7 +1070,12 @@ struct BtorWorker
|
|||
bad_properties.push_back(nid_en_and_not_a);
|
||||
} else {
|
||||
int nid = next_nid++;
|
||||
btorf("%d bad %d\n", nid, nid_en_and_not_a);
|
||||
string infostr = log_id(cell);
|
||||
if (infostr[0] == '$' && cell->attributes.count("\\src")) {
|
||||
infostr = cell->attributes.at("\\src").decode_string().c_str();
|
||||
std::replace(infostr.begin(), infostr.end(), ' ', '_');
|
||||
}
|
||||
btorf("%d bad %d %s\n", nid, nid_en_and_not_a, infostr.c_str());
|
||||
}
|
||||
|
||||
btorf_pop(log_id(cell));
|
||||
|
|
|
@ -1032,12 +1032,17 @@ class MkVcd:
|
|||
print("$var integer 32 t smt_step $end", file=self.f)
|
||||
print("$var event 1 ! smt_clock $end", file=self.f)
|
||||
|
||||
def vcdescape(n):
|
||||
if n.startswith("$") or ":" in n:
|
||||
return "\\" + n
|
||||
return n
|
||||
|
||||
scope = []
|
||||
for path in sorted(self.nets):
|
||||
key, width = self.nets[path]
|
||||
|
||||
uipath = list(path)
|
||||
if "." in uipath[-1]:
|
||||
if "." in uipath[-1] and not uipath[-1].startswith("$"):
|
||||
uipath = uipath[0:-1] + uipath[-1].split(".")
|
||||
for i in range(len(uipath)):
|
||||
uipath[i] = re.sub(r"\[([^\]]*)\]", r"<\1>", uipath[i])
|
||||
|
@ -1048,15 +1053,13 @@ class MkVcd:
|
|||
|
||||
while uipath[:-1] != scope:
|
||||
scopename = uipath[len(scope)]
|
||||
if scopename.startswith("$"):
|
||||
scopename = "\\" + scopename
|
||||
print("$scope module %s $end" % scopename, file=self.f)
|
||||
print("$scope module %s $end" % vcdescape(scopename), file=self.f)
|
||||
scope.append(uipath[len(scope)])
|
||||
|
||||
if path in self.clocks and self.clocks[path][1] == "event":
|
||||
print("$var event 1 %s %s $end" % (key, uipath[-1]), file=self.f)
|
||||
print("$var event 1 %s %s $end" % (key, vcdescape(uipath[-1])), file=self.f)
|
||||
else:
|
||||
print("$var wire %d %s %s $end" % (width, key, uipath[-1]), file=self.f)
|
||||
print("$var wire %d %s %s $end" % (width, key, vcdescape(uipath[-1])), file=self.f)
|
||||
|
||||
for i in range(len(scope)):
|
||||
print("$upscope $end", file=self.f)
|
||||
|
|
|
@ -33,11 +33,11 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, defparam, decimal, siminit;
|
||||
int auto_name_counter, auto_name_offset, auto_name_digits;
|
||||
bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit;
|
||||
int auto_name_counter, auto_name_offset, auto_name_digits, extmem_counter;
|
||||
std::map<RTLIL::IdString, int> auto_name_map;
|
||||
std::set<RTLIL::IdString> reg_wires, reg_ct;
|
||||
std::string auto_prefix;
|
||||
std::string auto_prefix, extmem_prefix;
|
||||
|
||||
RTLIL::Module *active_module;
|
||||
dict<RTLIL::SigBit, RTLIL::State> active_initdata;
|
||||
|
@ -371,13 +371,14 @@ void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig)
|
|||
}
|
||||
}
|
||||
|
||||
void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n', bool modattr = false, bool as_comment = false)
|
||||
void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n', bool modattr = false, bool regattr = false, bool as_comment = false)
|
||||
{
|
||||
if (noattr)
|
||||
return;
|
||||
if (attr2comment)
|
||||
as_comment = true;
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
if (it->first == "\\init" && regattr) continue;
|
||||
f << stringf("%s" "%s %s", indent.c_str(), as_comment ? "/*" : "(*", id(it->first).c_str());
|
||||
f << stringf(" = ");
|
||||
if (modattr && (it->second == State::S0 || it->second == Const(0)))
|
||||
|
@ -392,7 +393,7 @@ void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString,
|
|||
|
||||
void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire)
|
||||
{
|
||||
dump_attributes(f, indent, wire->attributes);
|
||||
dump_attributes(f, indent, wire->attributes, '\n', /*modattr=*/false, /*regattr=*/reg_wires.count(wire->name));
|
||||
#if 0
|
||||
if (wire->port_input && !wire->port_output)
|
||||
f << stringf("%s" "input %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");
|
||||
|
@ -1068,14 +1069,64 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
f << stringf("%s" "reg [%d:%d] %s [%d:%d];\n", indent.c_str(), width-1, 0, mem_id.c_str(), size+offset-1, offset);
|
||||
if (use_init)
|
||||
{
|
||||
f << stringf("%s" "initial begin\n", indent.c_str());
|
||||
for (int i=0; i<size; i++)
|
||||
if (extmem)
|
||||
{
|
||||
f << stringf("%s" " %s[%d] = ", indent.c_str(), mem_id.c_str(), i);
|
||||
dump_const(f, cell->parameters["\\INIT"].extract(i*width, width));
|
||||
f << stringf(";\n");
|
||||
std::string extmem_filename = stringf("%s-%d.mem", extmem_prefix.c_str(), extmem_counter++);
|
||||
|
||||
std::string extmem_filename_esc;
|
||||
for (auto c : extmem_filename)
|
||||
{
|
||||
if (c == '\n')
|
||||
extmem_filename_esc += "\\n";
|
||||
else if (c == '\t')
|
||||
extmem_filename_esc += "\\t";
|
||||
else if (c < 32)
|
||||
extmem_filename_esc += stringf("\\%03o", c);
|
||||
else if (c == '"')
|
||||
extmem_filename_esc += "\\\"";
|
||||
else if (c == '\\')
|
||||
extmem_filename_esc += "\\\\";
|
||||
else
|
||||
extmem_filename_esc += c;
|
||||
}
|
||||
f << stringf("%s" "initial $readmemb(\"%s\", %s);\n", indent.c_str(), extmem_filename_esc.c_str(), mem_id.c_str());
|
||||
|
||||
std::ofstream extmem_f(extmem_filename, std::ofstream::trunc);
|
||||
if (extmem_f.fail())
|
||||
log_error("Can't open file `%s' for writing: %s\n", extmem_filename.c_str(), strerror(errno));
|
||||
else
|
||||
{
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
RTLIL::Const element = cell->parameters["\\INIT"].extract(i*width, width);
|
||||
for (int j=0; j<element.size(); j++)
|
||||
{
|
||||
switch (element[element.size()-j-1])
|
||||
{
|
||||
case State::S0: extmem_f << '0'; break;
|
||||
case State::S1: extmem_f << '1'; break;
|
||||
case State::Sx: extmem_f << 'x'; break;
|
||||
case State::Sz: extmem_f << 'z'; break;
|
||||
case State::Sa: extmem_f << '_'; break;
|
||||
case State::Sm: log_error("Found marker state in final netlist.");
|
||||
}
|
||||
}
|
||||
extmem_f << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
f << stringf("%s" "initial begin\n", indent.c_str());
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
f << stringf("%s" " %s[%d] = ", indent.c_str(), mem_id.c_str(), i);
|
||||
dump_const(f, cell->parameters["\\INIT"].extract(i*width, width));
|
||||
f << stringf(";\n");
|
||||
}
|
||||
f << stringf("%s" "end\n", indent.c_str());
|
||||
}
|
||||
f << stringf("%s" "end\n", indent.c_str());
|
||||
}
|
||||
|
||||
// create a map : "edge clk" -> expressions within that clock domain
|
||||
|
@ -1521,7 +1572,7 @@ void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw
|
|||
|
||||
bool got_default = false;
|
||||
for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it) {
|
||||
dump_attributes(f, indent + " ", (*it)->attributes, '\n', /*modattr=*/false, /*as_comment=*/true);
|
||||
dump_attributes(f, indent + " ", (*it)->attributes, '\n', /*modattr=*/false, /*regattr=*/false, /*as_comment=*/true);
|
||||
if ((*it)->compare.size() == 0) {
|
||||
if (got_default)
|
||||
continue;
|
||||
|
@ -1686,7 +1737,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
|
|||
}
|
||||
}
|
||||
|
||||
dump_attributes(f, indent, module->attributes, '\n', /*attr2comment=*/true);
|
||||
dump_attributes(f, indent, module->attributes, '\n', /*modattr=*/true);
|
||||
f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str());
|
||||
bool keep_running = true;
|
||||
for (int port_id = 1; keep_running; port_id++) {
|
||||
|
@ -1776,8 +1827,16 @@ struct VerilogBackend : public Backend {
|
|||
log(" deactivates this feature and instead will write string constants\n");
|
||||
log(" as binary numbers.\n");
|
||||
log("\n");
|
||||
log(" -extmem\n");
|
||||
log(" instead of initializing memories using assignments to individual\n");
|
||||
log(" elements, use the '$readmemh' function to read initialization data\n");
|
||||
log(" from a file. This data is written to a file named by appending\n");
|
||||
log(" a sequential index to the Verilog filename and replacing the extension\n");
|
||||
log(" with '.mem', e.g. 'write_verilog -extmem foo.v' writes 'foo-1.mem',\n");
|
||||
log(" 'foo-2.mem' and so on.\n");
|
||||
log("\n");
|
||||
log(" -defparam\n");
|
||||
log(" Use 'defparam' statements instead of the Verilog-2001 syntax for\n");
|
||||
log(" use 'defparam' statements instead of the Verilog-2001 syntax for\n");
|
||||
log(" cell parameters.\n");
|
||||
log("\n");
|
||||
log(" -blackboxes\n");
|
||||
|
@ -1811,6 +1870,7 @@ struct VerilogBackend : public Backend {
|
|||
nodec = false;
|
||||
nohex = false;
|
||||
nostr = false;
|
||||
extmem = false;
|
||||
defparam = false;
|
||||
decimal = false;
|
||||
siminit = false;
|
||||
|
@ -1884,6 +1944,11 @@ struct VerilogBackend : public Backend {
|
|||
nostr = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-extmem") {
|
||||
extmem = true;
|
||||
extmem_counter = 1;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-defparam") {
|
||||
defparam = true;
|
||||
continue;
|
||||
|
@ -1911,6 +1976,12 @@ struct VerilogBackend : public Backend {
|
|||
break;
|
||||
}
|
||||
extra_args(f, filename, args, argidx);
|
||||
if (extmem)
|
||||
{
|
||||
if (filename.empty())
|
||||
log_cmd_error("Option -extmem must be used with a filename.\n");
|
||||
extmem_prefix = filename.substr(0, filename.rfind('.'));
|
||||
}
|
||||
|
||||
design->sort();
|
||||
|
||||
|
|
|
@ -1,41 +1,10 @@
|
|||
// 50 MHz Clock
|
||||
IO_LOC "clk" D11;
|
||||
|
||||
// LEDs
|
||||
IO_LOC "leds[0]" D22;
|
||||
IO_LOC "leds[1]" E22;
|
||||
IO_LOC "leds[2]" G22;
|
||||
IO_LOC "leds[3]" J22;
|
||||
IO_LOC "leds[4]" L22;
|
||||
IO_LOC "leds[5]" L19;
|
||||
IO_LOC "leds[6]" L20;
|
||||
IO_LOC "leds[7]" M21;
|
||||
IO_LOC "leds[8]" N19;
|
||||
IO_LOC "leds[9]" R19;
|
||||
IO_LOC "leds[10]" T18;
|
||||
IO_LOC "leds[11]" AA22;
|
||||
IO_LOC "leds[12]" U18;
|
||||
IO_LOC "leds[13]" V20;
|
||||
IO_LOC "leds[14]" AA21;
|
||||
IO_LOC "leds[15]" AB21;
|
||||
|
||||
|
||||
// 7-Segment Display
|
||||
IO_LOC "seg7dig[0]" E20;
|
||||
IO_LOC "seg7dig[1]" G18;
|
||||
IO_LOC "seg7dig[2]" G20;
|
||||
IO_LOC "seg7dig[3]" F21;
|
||||
IO_LOC "seg7dig[4]" J20;
|
||||
IO_LOC "seg7dig[5]" H21;
|
||||
IO_LOC "seg7dig[6]" H18;
|
||||
IO_LOC "seg7dig[7]" D20;
|
||||
IO_LOC "seg7sel[0]" C19;
|
||||
IO_LOC "seg7sel[1]" B22;
|
||||
IO_LOC "seg7sel[2]" C20;
|
||||
IO_LOC "seg7sel[3]" C21;
|
||||
|
||||
// Switches
|
||||
IO_LOC "sw[0]" AB20;
|
||||
IO_LOC "sw[1]" AB19;
|
||||
IO_LOC "sw[2]" AB18;
|
||||
IO_LOC "sw[3]" AB17;
|
||||
IO_LOC "clk" 35;
|
||||
//IO_LOC "rst_n" 77;
|
||||
IO_LOC "leds[0]" 79;
|
||||
IO_LOC "leds[1]" 80;
|
||||
IO_LOC "leds[2]" 81;
|
||||
IO_LOC "leds[3]" 82;
|
||||
IO_LOC "leds[4]" 83;
|
||||
IO_LOC "leds[5]" 84;
|
||||
IO_LOC "leds[6]" 85;
|
||||
IO_LOC "leds[7]" 86;
|
|
@ -1,9 +1,7 @@
|
|||
module demo (
|
||||
input clk,
|
||||
input [3:0] sw,
|
||||
output [15:0] leds,
|
||||
output [7:0] seg7dig,
|
||||
output [3:0] seg7sel
|
||||
output unused
|
||||
);
|
||||
localparam PRESCALE = 20;
|
||||
reg [PRESCALE+3:0] counter = 0;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
set JTAG regular_io = false
|
||||
set SSPI regular_io = false
|
||||
set MSPI regular_io = false
|
||||
set READY regular_io = false
|
||||
set DONE regular_io = false
|
||||
set RECONFIG_N regular_io = false
|
||||
set MODE regular_io = false
|
||||
set CRC_check = true
|
||||
set compress = false
|
||||
set encryption = false
|
||||
set security_bit_enable = true
|
||||
set bsram_init_fuse_print = true
|
||||
set download_speed = 250/100
|
||||
set spi_flash_address = 0x00FFF000
|
||||
set format = txt
|
||||
set background_programming = false
|
|
@ -0,0 +1,8 @@
|
|||
-sdf
|
||||
-oc
|
||||
-ibs
|
||||
-posp
|
||||
-o
|
||||
-warning_all
|
||||
-tt
|
||||
-timing
|
|
@ -1,8 +1,7 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
yosys -p "synth_gowin -top demo -vout demo_syn.v" demo.v
|
||||
$GOWIN_HOME/bin/gowin -d demo_syn.v -cst demo.cst -sdc demo.sdc -p GW2A55-PBGA484-6 \
|
||||
-warning_all -out demo_out.v -rpt demo.rpt -tr demo_tr.html -bit demo.bit
|
||||
$GOWIN_HOME/bin/gowin -d demo_syn.v -cst demo.cst -sdc demo.sdc -p GW1NR-9-QFN88-6 -pn GW1NR-LV9QN88C6/I5 -cfg device.cfg -bit -tr -ph -timing -gpa -rpt -warning_all
|
||||
|
||||
# post place&route simulation (icarus verilog)
|
||||
if false; then
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# gw_sh run.tcl
|
||||
exec yosys -p "synth_gowin -top demo -vout demo_syn.v" demo.v
|
||||
add_file -cst demo.cst
|
||||
add_file -sdc demo.sdc
|
||||
add_file -vm demo_syn.v
|
||||
add_file -cfg device.cfg
|
||||
set_option -device GW1NR-9-QFN88-6
|
||||
set_option -pn GW1NR-LV9QN88C6/I5
|
||||
run_pnr -opt pnr.cfg
|
|
@ -164,6 +164,8 @@ std::string AST::type2str(AstNodeType type)
|
|||
X(AST_MODPORT)
|
||||
X(AST_MODPORTMEMBER)
|
||||
X(AST_PACKAGE)
|
||||
X(AST_WIRETYPE)
|
||||
X(AST_TYPEDEF)
|
||||
#undef X
|
||||
default:
|
||||
log_abort();
|
||||
|
@ -206,6 +208,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch
|
|||
was_checked = false;
|
||||
range_valid = false;
|
||||
range_swapped = false;
|
||||
is_custom_type = false;
|
||||
port_id = 0;
|
||||
range_left = -1;
|
||||
range_right = 0;
|
||||
|
|
|
@ -148,7 +148,10 @@ namespace AST
|
|||
AST_INTERFACEPORTTYPE,
|
||||
AST_MODPORT,
|
||||
AST_MODPORTMEMBER,
|
||||
AST_PACKAGE
|
||||
AST_PACKAGE,
|
||||
|
||||
AST_WIRETYPE,
|
||||
AST_TYPEDEF
|
||||
};
|
||||
|
||||
// convert an node type to a string (e.g. for debug output)
|
||||
|
@ -174,7 +177,7 @@ namespace AST
|
|||
// node content - most of it is unused in most node types
|
||||
std::string str;
|
||||
std::vector<RTLIL::State> bits;
|
||||
bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized;
|
||||
bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized, is_custom_type;
|
||||
int port_id, range_left, range_right;
|
||||
uint32_t integer;
|
||||
double realvalue;
|
||||
|
|
|
@ -863,6 +863,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
case AST_PACKAGE:
|
||||
case AST_MODPORT:
|
||||
case AST_MODPORTMEMBER:
|
||||
case AST_TYPEDEF:
|
||||
break;
|
||||
case AST_INTERFACEPORT: {
|
||||
// If a port in a module with unknown type is found, mark it with the attribute 'is_interface'
|
||||
|
|
|
@ -318,7 +318,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
}
|
||||
|
||||
// activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
|
||||
if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
|
||||
if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX || type == AST_TYPEDEF)
|
||||
const_fold = true;
|
||||
if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
|
||||
const_fold = true;
|
||||
|
@ -336,6 +336,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
std::map<std::string, AstNode*> this_wire_scope;
|
||||
for (size_t i = 0; i < children.size(); i++) {
|
||||
AstNode *node = children[i];
|
||||
|
||||
if (node->type == AST_WIRE) {
|
||||
if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
|
||||
for (auto c : node->children[0]->children) {
|
||||
|
@ -405,14 +406,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
this_wire_scope[node->str] = node;
|
||||
}
|
||||
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
|
||||
node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL) {
|
||||
node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL ||
|
||||
node->type == AST_TYPEDEF) {
|
||||
backup_scope[node->str] = current_scope[node->str];
|
||||
current_scope[node->str] = node;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < children.size(); i++) {
|
||||
AstNode *node = children[i];
|
||||
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY)
|
||||
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY || node->type == AST_TYPEDEF)
|
||||
while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
|
||||
did_something = true;
|
||||
}
|
||||
|
@ -780,6 +782,99 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
delete_children();
|
||||
}
|
||||
|
||||
// resolve typedefs
|
||||
if (type == AST_TYPEDEF) {
|
||||
log_assert(children.size() == 1);
|
||||
log_assert(children[0]->type == AST_WIRE || children[0]->type == AST_MEMORY);
|
||||
while(children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param))
|
||||
did_something = true;
|
||||
log_assert(!children[0]->is_custom_type);
|
||||
}
|
||||
|
||||
// resolve types of wires
|
||||
if (type == AST_WIRE || type == AST_MEMORY) {
|
||||
if (is_custom_type) {
|
||||
log_assert(children.size() >= 1);
|
||||
log_assert(children[0]->type == AST_WIRETYPE);
|
||||
if (!current_scope.count(children[0]->str))
|
||||
log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str());
|
||||
AstNode *resolved_type = current_scope.at(children[0]->str);
|
||||
if (resolved_type->type != AST_TYPEDEF)
|
||||
log_file_error(filename, linenum, "`%s' does not name a type\n", children[0]->str.c_str());
|
||||
log_assert(resolved_type->children.size() == 1);
|
||||
AstNode *templ = resolved_type->children[0];
|
||||
// Remove type reference
|
||||
delete children[0];
|
||||
children.erase(children.begin());
|
||||
|
||||
// Ensure typedef itself is fully simplified
|
||||
while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
|
||||
|
||||
if (type == AST_WIRE)
|
||||
type = templ->type;
|
||||
is_reg = templ->is_reg;
|
||||
is_logic = templ->is_logic;
|
||||
is_signed = templ->is_signed;
|
||||
is_string = templ->is_string;
|
||||
is_custom_type = templ->is_custom_type;
|
||||
|
||||
range_valid = templ->range_valid;
|
||||
range_swapped = templ->range_swapped;
|
||||
range_left = templ->range_left;
|
||||
range_right = templ->range_right;
|
||||
|
||||
// Insert clones children from template at beginning
|
||||
for (int i = 0; i < GetSize(templ->children); i++)
|
||||
children.insert(children.begin() + i, templ->children[i]->clone());
|
||||
|
||||
if (type == AST_MEMORY && GetSize(children) == 1) {
|
||||
// Single-bit memories must have [0:0] range
|
||||
AstNode *rng = new AstNode(AST_RANGE);
|
||||
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||
children.insert(children.begin(), rng);
|
||||
}
|
||||
|
||||
did_something = true;
|
||||
}
|
||||
log_assert(!is_custom_type);
|
||||
}
|
||||
|
||||
// resolve types of parameters
|
||||
if (type == AST_LOCALPARAM || type == AST_PARAMETER) {
|
||||
if (is_custom_type) {
|
||||
log_assert(children.size() == 2);
|
||||
log_assert(children[1]->type == AST_WIRETYPE);
|
||||
if (!current_scope.count(children[1]->str))
|
||||
log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str());
|
||||
AstNode *resolved_type = current_scope.at(children[1]->str);
|
||||
if (resolved_type->type != AST_TYPEDEF)
|
||||
log_file_error(filename, linenum, "`%s' does not name a type\n", children[1]->str.c_str());
|
||||
log_assert(resolved_type->children.size() == 1);
|
||||
AstNode *templ = resolved_type->children[0];
|
||||
delete children[1];
|
||||
children.pop_back();
|
||||
|
||||
// Ensure typedef itself is fully simplified
|
||||
while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
|
||||
|
||||
if (templ->type == AST_MEMORY)
|
||||
log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
|
||||
is_signed = templ->is_signed;
|
||||
is_string = templ->is_string;
|
||||
is_custom_type = templ->is_custom_type;
|
||||
|
||||
range_valid = templ->range_valid;
|
||||
range_swapped = templ->range_swapped;
|
||||
range_left = templ->range_left;
|
||||
range_right = templ->range_right;
|
||||
for (auto template_child : templ->children)
|
||||
children.push_back(template_child->clone());
|
||||
did_something = true;
|
||||
}
|
||||
log_assert(!is_custom_type);
|
||||
}
|
||||
|
||||
// resolve constant prefixes
|
||||
if (type == AST_PREFIX) {
|
||||
if (children[0]->type != AST_CONSTANT) {
|
||||
|
@ -1194,7 +1289,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
if (type == AST_BLOCK && str.empty())
|
||||
{
|
||||
for (size_t i = 0; i < children.size(); i++)
|
||||
if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM)
|
||||
if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF)
|
||||
log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n");
|
||||
}
|
||||
|
||||
|
@ -1206,7 +1301,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
|
||||
std::vector<AstNode*> new_children;
|
||||
for (size_t i = 0; i < children.size(); i++)
|
||||
if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM) {
|
||||
if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) {
|
||||
children[i]->simplify(false, false, false, stage, -1, false, false);
|
||||
current_ast_mod->children.push_back(children[i]);
|
||||
current_scope[children[i]->str] = children[i];
|
||||
|
@ -2906,7 +3001,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
|
|||
}
|
||||
}
|
||||
|
||||
if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL) && name_map.count(str) > 0)
|
||||
if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE) && name_map.count(str) > 0)
|
||||
str = name_map[str];
|
||||
|
||||
std::map<std::string, std::string> backup_name_map;
|
||||
|
@ -2914,7 +3009,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
|
|||
for (size_t i = 0; i < children.size(); i++) {
|
||||
AstNode *child = children[i];
|
||||
if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM ||
|
||||
child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL) {
|
||||
child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL || child->type == AST_TYPEDEF) {
|
||||
if (backup_name_map.size() == 0)
|
||||
backup_name_map = name_map;
|
||||
std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
|
||||
|
@ -2945,6 +3040,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
|
|||
child->expand_genblock(index_var, prefix, name_map);
|
||||
}
|
||||
|
||||
|
||||
if (backup_name_map.size() > 0)
|
||||
name_map.swap(backup_name_map);
|
||||
}
|
||||
|
@ -2998,6 +3094,9 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
|
|||
uint32_t children_flags = 0;
|
||||
int lhs_children_counter = 0;
|
||||
|
||||
if (type == AST_TYPEDEF)
|
||||
return; // don't touch content of typedefs
|
||||
|
||||
if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
|
||||
{
|
||||
// mark all memories that are used in a complex expression on the left side of an assignment
|
||||
|
@ -3155,6 +3254,9 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
|
|||
if (type == AST_FUNCTION || type == AST_TASK)
|
||||
return false;
|
||||
|
||||
if (type == AST_TYPEDEF)
|
||||
return false;
|
||||
|
||||
if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast))
|
||||
{
|
||||
log_assert(children[0]->type == AST_CONSTANT);
|
||||
|
|
|
@ -174,6 +174,12 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
if (module == nullptr)
|
||||
goto error;
|
||||
|
||||
if (!strcmp(cmd, ".blackbox"))
|
||||
{
|
||||
module->attributes["\\blackbox"] = RTLIL::Const(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, ".end"))
|
||||
{
|
||||
for (auto &wp : wideports_cache)
|
||||
|
@ -280,7 +286,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
|||
goto error_with_reason;
|
||||
}
|
||||
|
||||
module->rename(lastcell, p);
|
||||
module->rename(lastcell, RTLIL::escape_id(p));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -787,7 +787,18 @@ void VerificImporter::merge_past_ffs(pool<RTLIL::Cell*> &candidates)
|
|||
void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::set<Netlist*> &nl_todo)
|
||||
{
|
||||
std::string netlist_name = nl->GetAtt(" \\top") ? nl->CellBaseName() : nl->Owner()->Name();
|
||||
std::string module_name = nl->IsOperator() ? "$verific$" + netlist_name : RTLIL::escape_id(netlist_name);
|
||||
std::string module_name = netlist_name;
|
||||
|
||||
if (nl->IsOperator()) {
|
||||
module_name = "$verific$" + module_name;
|
||||
} else {
|
||||
if (*nl->Name()) {
|
||||
module_name += "(";
|
||||
module_name += nl->Name();
|
||||
module_name += ")";
|
||||
}
|
||||
module_name = "\\" + module_name;
|
||||
}
|
||||
|
||||
netlist = nl;
|
||||
|
||||
|
@ -1256,7 +1267,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
|
|||
if (inst->Type() == PRIM_SVA_ASSERT || inst->Type() == PRIM_SVA_IMMEDIATE_ASSERT)
|
||||
sva_asserts.insert(inst);
|
||||
|
||||
if (inst->Type() == PRIM_SVA_ASSUME || inst->Type() == PRIM_SVA_IMMEDIATE_ASSUME)
|
||||
if (inst->Type() == PRIM_SVA_ASSUME || inst->Type() == PRIM_SVA_IMMEDIATE_ASSUME || inst->Type() == PRIM_SVA_RESTRICT)
|
||||
sva_assumes.insert(inst);
|
||||
|
||||
if (inst->Type() == PRIM_SVA_COVER || inst->Type() == PRIM_SVA_IMMEDIATE_COVER)
|
||||
|
@ -1396,8 +1407,20 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
|
|||
import_verific_cells:
|
||||
nl_todo.insert(inst->View());
|
||||
|
||||
RTLIL::Cell *cell = module->addCell(inst_name, inst->IsOperator() ?
|
||||
std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name()));
|
||||
std::string inst_type = inst->View()->Owner()->Name();
|
||||
|
||||
if (inst->View()->IsOperator()) {
|
||||
inst_type = "$verific$" + inst_type;
|
||||
} else {
|
||||
if (*inst->View()->Name()) {
|
||||
inst_type += "(";
|
||||
inst_type += inst->View()->Name();
|
||||
inst_type += ")";
|
||||
}
|
||||
inst_type = "\\" + inst_type;
|
||||
}
|
||||
|
||||
RTLIL::Cell *cell = module->addCell(inst_name, inst_type);
|
||||
|
||||
if (inst->IsPrimitive() && mode_keep)
|
||||
cell->attributes["\\keep"] = 1;
|
||||
|
@ -1939,12 +1962,18 @@ struct VerificPass : public Pass {
|
|||
log("Load the specified VHDL files into Verific.\n");
|
||||
log("\n");
|
||||
log("\n");
|
||||
log(" verific -work <libname> {-sv|-vhdl|...} <hdl-file>\n");
|
||||
log(" verific [-work <libname>] {-sv|-vhdl|...} <hdl-file>\n");
|
||||
log("\n");
|
||||
log("Load the specified Verilog/SystemVerilog/VHDL file into the specified library.\n");
|
||||
log("(default library when -work is not present: \"work\")\n");
|
||||
log("\n");
|
||||
log("\n");
|
||||
log(" verific [-L <libname>] {-sv|-vhdl|...} <hdl-file>\n");
|
||||
log("\n");
|
||||
log("Look up external definitions in the specified library.\n");
|
||||
log("(-L may be used more than once)\n");
|
||||
log("\n");
|
||||
log("\n");
|
||||
log(" verific -vlog-incdir <directory>..\n");
|
||||
log("\n");
|
||||
log("Add Verilog include directories.\n");
|
||||
|
@ -2158,12 +2187,17 @@ struct VerificPass : public Pass {
|
|||
goto check_error;
|
||||
}
|
||||
|
||||
veri_file::RemoveAllLOptions();
|
||||
for (; argidx < GetSize(args); argidx++)
|
||||
{
|
||||
if (args[argidx] == "-work" && argidx+1 < GetSize(args)) {
|
||||
work = args[++argidx];
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-L" && argidx+1 < GetSize(args)) {
|
||||
veri_file::AddLOption(args[++argidx].c_str());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -490,13 +490,17 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
|
|||
}
|
||||
while (newline_count-- > 0)
|
||||
return_char('\n');
|
||||
// printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
|
||||
defines_map[name] = value;
|
||||
if (state == 2)
|
||||
defines_with_args.insert(name);
|
||||
else
|
||||
defines_with_args.erase(name);
|
||||
global_defines_cache[name] = std::pair<std::string, bool>(value, state == 2);
|
||||
if (strchr("abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789", name[0])) {
|
||||
// printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
|
||||
defines_map[name] = value;
|
||||
if (state == 2)
|
||||
defines_with_args.insert(name);
|
||||
else
|
||||
defines_with_args.erase(name);
|
||||
global_defines_cache[name] = std::pair<std::string, bool>(value, state == 2);
|
||||
} else {
|
||||
log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name.c_str());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -553,6 +553,12 @@ struct VerilogDefines : public Pass {
|
|||
log(" -Uname[=definition]\n");
|
||||
log(" undefine the preprocessor symbol 'name'\n");
|
||||
log("\n");
|
||||
log(" -reset\n");
|
||||
log(" clear list of defined preprocessor symbols\n");
|
||||
log("\n");
|
||||
log(" -list\n");
|
||||
log(" list currently defined preprocessor symbols\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
{
|
||||
|
@ -588,6 +594,16 @@ struct VerilogDefines : public Pass {
|
|||
design->verilog_defines.erase(name);
|
||||
continue;
|
||||
}
|
||||
if (arg == "-reset") {
|
||||
design->verilog_defines.clear();
|
||||
continue;
|
||||
}
|
||||
if (arg == "-list") {
|
||||
for (auto &it : design->verilog_defines) {
|
||||
log("`define %s%s %s\n", it.first.c_str(), it.second.second ? "()" : "", it.second.first.c_str());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ struct specify_rise_fall {
|
|||
|
||||
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
|
||||
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
|
||||
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id
|
||||
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id
|
||||
%type <boolean> opt_signed opt_property unique_case_attr
|
||||
%type <al> attr case_attr
|
||||
|
||||
|
@ -206,6 +206,7 @@ design:
|
|||
task_func_decl design |
|
||||
param_decl design |
|
||||
localparam_decl design |
|
||||
typedef_decl design |
|
||||
package design |
|
||||
interface design |
|
||||
/* empty */;
|
||||
|
@ -290,6 +291,9 @@ hierarchical_id:
|
|||
$$ = $1;
|
||||
};
|
||||
|
||||
hierarchical_type_id:
|
||||
'(' hierarchical_id ')' { $$ = $2; };
|
||||
|
||||
module:
|
||||
attr TOK_MODULE TOK_ID {
|
||||
do_not_require_port_stubs = false;
|
||||
|
@ -324,13 +328,13 @@ single_module_para:
|
|||
astbuf1 = new AstNode(AST_PARAMETER);
|
||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||
append_attr(astbuf1, $1);
|
||||
} param_signed param_integer param_range single_param_decl |
|
||||
} param_type single_param_decl |
|
||||
attr TOK_LOCALPARAM {
|
||||
if (astbuf1) delete astbuf1;
|
||||
astbuf1 = new AstNode(AST_LOCALPARAM);
|
||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||
append_attr(astbuf1, $1);
|
||||
} param_signed param_integer param_range single_param_decl |
|
||||
} param_type single_param_decl |
|
||||
single_param_decl;
|
||||
|
||||
module_args_opt:
|
||||
|
@ -426,6 +430,7 @@ package_body:
|
|||
package_body package_body_stmt |;
|
||||
|
||||
package_body_stmt:
|
||||
typedef_decl |
|
||||
localparam_decl;
|
||||
|
||||
interface:
|
||||
|
@ -452,7 +457,7 @@ interface_body:
|
|||
interface_body interface_body_stmt |;
|
||||
|
||||
interface_body_stmt:
|
||||
param_decl | localparam_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
|
||||
param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
|
||||
modport_stmt;
|
||||
|
||||
non_opt_delay:
|
||||
|
@ -475,8 +480,14 @@ wire_type:
|
|||
};
|
||||
|
||||
wire_type_token_list:
|
||||
wire_type_token | wire_type_token_list wire_type_token |
|
||||
wire_type_token_io ;
|
||||
wire_type_token |
|
||||
wire_type_token_list wire_type_token |
|
||||
wire_type_token_io |
|
||||
hierarchical_type_id {
|
||||
astbuf3->is_custom_type = true;
|
||||
astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
|
||||
astbuf3->children.back()->str = *$1;
|
||||
};
|
||||
|
||||
wire_type_token_io:
|
||||
TOK_INPUT {
|
||||
|
@ -591,7 +602,7 @@ module_body:
|
|||
/* empty */;
|
||||
|
||||
module_body_stmt:
|
||||
task_func_decl | specify_block |param_decl | localparam_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
|
||||
task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
|
||||
always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block;
|
||||
|
||||
checker_decl:
|
||||
|
@ -1149,12 +1160,20 @@ param_range:
|
|||
}
|
||||
};
|
||||
|
||||
param_type:
|
||||
param_signed param_integer param_real param_range |
|
||||
hierarchical_type_id {
|
||||
astbuf1->is_custom_type = true;
|
||||
astbuf1->children.push_back(new AstNode(AST_WIRETYPE));
|
||||
astbuf1->children.back()->str = *$1;
|
||||
};
|
||||
|
||||
param_decl:
|
||||
attr TOK_PARAMETER {
|
||||
astbuf1 = new AstNode(AST_PARAMETER);
|
||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||
append_attr(astbuf1, $1);
|
||||
} param_signed param_integer param_real param_range param_decl_list ';' {
|
||||
} param_type param_decl_list ';' {
|
||||
delete astbuf1;
|
||||
};
|
||||
|
||||
|
@ -1163,7 +1182,7 @@ localparam_decl:
|
|||
astbuf1 = new AstNode(AST_LOCALPARAM);
|
||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||
append_attr(astbuf1, $1);
|
||||
} param_signed param_integer param_real param_range param_decl_list ';' {
|
||||
} param_type param_decl_list ';' {
|
||||
delete astbuf1;
|
||||
};
|
||||
|
||||
|
@ -1327,7 +1346,7 @@ wire_name:
|
|||
if ($2 != NULL) {
|
||||
if (node->is_input || node->is_output)
|
||||
frontend_verilog_yyerror("input/output/inout ports cannot have unpacked dimensions.");
|
||||
if (!astbuf2) {
|
||||
if (!astbuf2 && !node->is_custom_type) {
|
||||
AstNode *rng = new AstNode(AST_RANGE);
|
||||
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||
|
@ -1377,6 +1396,45 @@ assign_expr:
|
|||
ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, $1, $3));
|
||||
};
|
||||
|
||||
typedef_decl:
|
||||
TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' {
|
||||
astbuf1 = $2;
|
||||
astbuf2 = $3;
|
||||
if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
|
||||
if (astbuf2) {
|
||||
frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions.");
|
||||
} else {
|
||||
astbuf2 = new AstNode(AST_RANGE);
|
||||
astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true));
|
||||
astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true));
|
||||
}
|
||||
}
|
||||
if (astbuf2 && astbuf2->children.size() != 2)
|
||||
frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
|
||||
if (astbuf2)
|
||||
astbuf1->children.push_back(astbuf2);
|
||||
|
||||
if ($5 != NULL) {
|
||||
if (!astbuf2) {
|
||||
AstNode *rng = new AstNode(AST_RANGE);
|
||||
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||
astbuf1->children.push_back(rng);
|
||||
}
|
||||
astbuf1->type = AST_MEMORY;
|
||||
auto *rangeNode = $5;
|
||||
if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) {
|
||||
// SV array size [n], rewrite as [n-1:0]
|
||||
rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true));
|
||||
rangeNode->children.push_back(AstNode::mkconst_int(0, false));
|
||||
}
|
||||
astbuf1->children.push_back(rangeNode);
|
||||
}
|
||||
|
||||
ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
|
||||
ast_stack.back()->children.back()->str = *$4;
|
||||
};
|
||||
|
||||
cell_stmt:
|
||||
attr TOK_ID {
|
||||
astbuf1 = new AstNode(AST_CELL);
|
||||
|
@ -1823,7 +1881,7 @@ simple_behavioral_stmt:
|
|||
|
||||
// this production creates the obligatory if-else shift/reduce conflict
|
||||
behavioral_stmt:
|
||||
defattr | assert | wire_decl | param_decl | localparam_decl |
|
||||
defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl |
|
||||
non_opt_delay behavioral_stmt |
|
||||
simple_behavioral_stmt ';' | ';' |
|
||||
hierarchical_id attr {
|
||||
|
|
|
@ -253,6 +253,8 @@ class WContainer:
|
|||
candidate = WType.from_string(arg.strip(), containing_file, line_number)
|
||||
if candidate == None:
|
||||
return None
|
||||
if candidate.name == "void":
|
||||
return None
|
||||
cont.args.append(candidate)
|
||||
return cont
|
||||
|
||||
|
@ -880,11 +882,8 @@ class WClass:
|
|||
text += fun.gen_def_virtual()
|
||||
return text
|
||||
|
||||
def gen_boost_py(self):
|
||||
text = "\n\t\tclass_<" + self.name
|
||||
if self.link_type == link_types.derive:
|
||||
text += "Wrap, boost::noncopyable"
|
||||
text += ">(\"" + self.name + "\""
|
||||
def gen_boost_py_body(self):
|
||||
text = ""
|
||||
if self.printable_constrs() == 0 or not self.contains_default_constr():
|
||||
text += ", no_init"
|
||||
text += ")"
|
||||
|
@ -907,6 +906,21 @@ class WClass:
|
|||
text += "\n\t\t\t;\n"
|
||||
return text
|
||||
|
||||
def gen_boost_py(self):
|
||||
body = self.gen_boost_py_body()
|
||||
if self.link_type == link_types.derive:
|
||||
text = "\n\t\tclass_<" + self.name + ">(\"Cpp" + self.name + "\""
|
||||
text += body
|
||||
text += "\n\t\tclass_<" + self.name
|
||||
text += "Wrap, boost::noncopyable"
|
||||
text += ">(\"" + self.name + "\""
|
||||
text += body
|
||||
else:
|
||||
text = "\n\t\tclass_<" + self.name + ">(\"" + self.name + "\""
|
||||
text += body
|
||||
return text
|
||||
|
||||
|
||||
def contains_default_constr(self):
|
||||
for c in self.found_constrs:
|
||||
if len(c.args) == 0:
|
||||
|
@ -974,6 +988,7 @@ blacklist_methods = ["YOSYS_NAMESPACE::Pass::run_register", "YOSYS_NAMESPACE::Mo
|
|||
enum_names = ["State","SyncType","ConstFlags"]
|
||||
|
||||
enums = [] #Do not edit
|
||||
glbls = []
|
||||
|
||||
unowned_functions = []
|
||||
|
||||
|
@ -1723,6 +1738,159 @@ class WMember:
|
|||
text += ")"
|
||||
return text
|
||||
|
||||
class WGlobal:
|
||||
orig_text = None
|
||||
wtype = attr_types.default
|
||||
name = None
|
||||
containing_file = None
|
||||
namespace = ""
|
||||
is_const = False
|
||||
|
||||
def from_string(str_def, containing_file, line_number, namespace):
|
||||
glbl = WGlobal()
|
||||
glbl.orig_text = str_def
|
||||
glbl.wtype = None
|
||||
glbl.name = ""
|
||||
glbl.containing_file = containing_file
|
||||
glbl.namespace = namespace
|
||||
glbl.is_const = False
|
||||
|
||||
if not str.startswith(str_def, "extern"):
|
||||
return None
|
||||
str_def = str_def[7:]
|
||||
|
||||
if str.startswith(str_def, "const "):
|
||||
glbl.is_const = True
|
||||
str_def = str_def[6:]
|
||||
|
||||
if str_def.count(" ") == 0:
|
||||
return None
|
||||
|
||||
parts = split_list(str_def.strip(), " ")
|
||||
|
||||
prefix = ""
|
||||
i = 0
|
||||
for part in parts:
|
||||
if part in ["unsigned", "long", "short"]:
|
||||
prefix += part + " "
|
||||
i += 1
|
||||
else:
|
||||
break
|
||||
parts = parts[i:]
|
||||
|
||||
if len(parts) <= 1:
|
||||
return None
|
||||
|
||||
glbl.wtype = WType.from_string(prefix + parts[0], containing_file, line_number)
|
||||
|
||||
if glbl.wtype == None:
|
||||
return None
|
||||
|
||||
str_def = parts[1]
|
||||
for part in parts[2:]:
|
||||
str_def = str_def + " " + part
|
||||
|
||||
if str_def.find("(") != -1 or str_def.find(")") != -1 or str_def.find("{") != -1 or str_def.find("}") != -1:
|
||||
return None
|
||||
|
||||
found = str_def.find(";")
|
||||
if found == -1:
|
||||
return None
|
||||
|
||||
found_eq = str_def.find("=")
|
||||
if found_eq != -1:
|
||||
found = found_eq
|
||||
|
||||
glbl.name = str_def[:found]
|
||||
str_def = str_def[found+1:]
|
||||
if glbl.name.find("*") == 0:
|
||||
glbl.name = glbl.name.replace("*", "")
|
||||
glbl.wtype.attr_type = attr_types.star
|
||||
if glbl.name.find("&&") == 0:
|
||||
glbl.name = glbl.name.replace("&&", "")
|
||||
glbl.wtype.attr_type = attr_types.ampamp
|
||||
if glbl.name.find("&") == 0:
|
||||
glbl.name = glbl.name.replace("&", "")
|
||||
glbl.wtype.attr_type = attr_types.amp
|
||||
|
||||
if(len(str_def.strip()) != 0):
|
||||
return None
|
||||
|
||||
if len(glbl.name.split(",")) > 1:
|
||||
glbl_list = []
|
||||
for name in glbl.name.split(","):
|
||||
name = name.strip();
|
||||
glbl_list.append(WGlobal())
|
||||
glbl_list[-1].orig_text = glbl.orig_text
|
||||
glbl_list[-1].wtype = glbl.wtype
|
||||
glbl_list[-1].name = name
|
||||
glbl_list[-1].containing_file = glbl.containing_file
|
||||
glbl_list[-1].namespace = glbl.namespace
|
||||
glbl_list[-1].is_const = glbl.is_const
|
||||
return glbl_list
|
||||
|
||||
return glbl
|
||||
|
||||
def gen_def(self):
|
||||
text = "\n\t"
|
||||
if self.is_const:
|
||||
text += "const "
|
||||
text += self.wtype.gen_text() + " get_var_py_" + self.name + "()"
|
||||
text += "\n\t{\n\t\t"
|
||||
if self.wtype.attr_type == attr_types.star:
|
||||
text += "if(" + self.namespace + "::" + self.name + " == NULL)\n\t\t\t"
|
||||
text += "throw std::runtime_error(\"" + self.namespace + "::" + self.name + " is NULL\");\n\t\t"
|
||||
if self.wtype.name in known_containers:
|
||||
text += self.wtype.gen_text_cpp()
|
||||
else:
|
||||
if self.is_const:
|
||||
text += "const "
|
||||
text += self.wtype.gen_text()
|
||||
|
||||
if self.wtype.name in classnames or (self.wtype.name in known_containers and self.wtype.attr_type == attr_types.star):
|
||||
text += "*"
|
||||
text += " ret_ = "
|
||||
if self.wtype.name in classnames:
|
||||
text += self.wtype.name + "::get_py_obj("
|
||||
if self.wtype.attr_type != attr_types.star:
|
||||
text += "&"
|
||||
text += self.namespace + "::" + self.name
|
||||
if self.wtype.name in classnames:
|
||||
text += ")"
|
||||
text += ";"
|
||||
|
||||
if self.wtype.name in classnames:
|
||||
text += "\n\t\treturn *ret_;"
|
||||
elif self.wtype.name in known_containers:
|
||||
text += known_containers[self.wtype.name].translate_cpp("ret_", self.wtype.cont.args, "\n\t\t", self.wtype.attr_type == attr_types.star)
|
||||
text += "\n\t\treturn ret____tmp;"
|
||||
else:
|
||||
text += "\n\t\treturn ret_;"
|
||||
text += "\n\t}\n"
|
||||
|
||||
if self.is_const:
|
||||
return text
|
||||
|
||||
ret = Attribute(self.wtype, "rhs");
|
||||
|
||||
if self.wtype.name in classnames:
|
||||
text += "\n\tvoid set_var_py_" + self.name + "(" + self.wtype.gen_text() + " *rhs)"
|
||||
else:
|
||||
text += "\n\tvoid set_var_py_" + self.name + "(" + self.wtype.gen_text() + " rhs)"
|
||||
text += "\n\t{"
|
||||
text += ret.gen_translation()
|
||||
text += "\n\t\t" + self.namespace + "::" + self.name + " = " + ret.gen_call() + ";"
|
||||
text += "\n\t}\n"
|
||||
|
||||
return text;
|
||||
|
||||
def gen_boost_py(self):
|
||||
text = "\n\t\t\t.add_static_property(\"" + self.name + "\", &" + "YOSYS_PYTHON::get_var_py_" + self.name
|
||||
if not self.is_const:
|
||||
text += ", &YOSYS_PYTHON::set_var_py_" + self.name
|
||||
text += ")"
|
||||
return text
|
||||
|
||||
def concat_namespace(tuple_list):
|
||||
if len(tuple_list) == 0:
|
||||
return ""
|
||||
|
@ -1859,6 +2027,16 @@ def parse_header(source):
|
|||
else:
|
||||
debug("\t\tFound member \"" + candidate.name + "\" of class \"" + class_[0].name + "\" of type \"" + candidate.wtype.name + "\"", 2)
|
||||
class_[0].found_vars.append(candidate)
|
||||
if candidate == None and class_ == None:
|
||||
candidate = WGlobal.from_string(ugly_line, source.name, i, concat_namespace(namespaces))
|
||||
if candidate != None:
|
||||
if type(candidate) == list:
|
||||
for c in candidate:
|
||||
glbls.append(c)
|
||||
debug("\tFound global \"" + c.name + "\" in namespace " + concat_namespace(namespaces), 2)
|
||||
else:
|
||||
glbls.append(candidate)
|
||||
debug("\tFound global \"" + candidate.name + "\" in namespace " + concat_namespace(namespaces), 2)
|
||||
|
||||
j = i
|
||||
line = unpretty_string(line)
|
||||
|
@ -1888,6 +2066,17 @@ def parse_header(source):
|
|||
debug("\t\tFound constructor of class \"" + class_[0].name + "\" in namespace " + concat_namespace(namespaces),2)
|
||||
class_[0].found_constrs.append(candidate)
|
||||
continue
|
||||
if class_ == None:
|
||||
candidate = WGlobal.from_string(line, source.name, i, concat_namespace(namespaces))
|
||||
if candidate != None:
|
||||
if type(candidate) == list:
|
||||
for c in candidate:
|
||||
glbls.append(c)
|
||||
debug("\tFound global \"" + c.name + "\" in namespace " + concat_namespace(namespaces), 2)
|
||||
else:
|
||||
glbls.append(candidate)
|
||||
debug("\tFound global \"" + candidate.name + "\" in namespace " + concat_namespace(namespaces), 2)
|
||||
continue
|
||||
if candidate != None:
|
||||
while i < j:
|
||||
i += 1
|
||||
|
@ -1990,6 +2179,7 @@ def gen_wrappers(filename, debug_level_ = 0):
|
|||
if len(class_.found_constrs) == 0:
|
||||
class_.found_constrs.append(WConstructor(source.name, class_))
|
||||
debug(str(len(unowned_functions)) + " functions are unowned", 1)
|
||||
debug(str(len(unowned_functions)) + " global variables", 1)
|
||||
for enum in enums:
|
||||
debug("Enum " + assure_length(enum.name, len(max(enum_names, key=len)), True) + " contains " + assure_length(str(len(enum.values)), 2, False) + " values", 1)
|
||||
debug("-"*col, 1)
|
||||
|
@ -2025,10 +2215,15 @@ def gen_wrappers(filename, debug_level_ = 0):
|
|||
#include <boost/python/wrapper.hpp>
|
||||
#include <boost/python/call.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
#include <iosfwd> // std::streamsize
|
||||
#include <iostream>
|
||||
#include <boost/iostreams/concepts.hpp> // boost::iostreams::sink
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
USING_YOSYS_NAMESPACE
|
||||
|
||||
namespace YOSYS_PYTHON {
|
||||
|
||||
struct YosysStatics{};
|
||||
""")
|
||||
|
||||
for source in sources:
|
||||
|
@ -2050,6 +2245,9 @@ namespace YOSYS_PYTHON {
|
|||
for fun in unowned_functions:
|
||||
wrapper_file.write(fun.gen_def())
|
||||
|
||||
for glbl in glbls:
|
||||
wrapper_file.write(glbl.gen_def())
|
||||
|
||||
wrapper_file.write(""" struct Initializer
|
||||
{
|
||||
Initializer() {
|
||||
|
@ -2068,12 +2266,89 @@ namespace YOSYS_PYTHON {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/// source: https://stackoverflow.com/questions/26033781/converting-python-io-object-to-stdostream-when-using-boostpython?noredirect=1&lq=1
|
||||
/// @brief Type that implements the Boost.IOStream's Sink and Flushable
|
||||
/// concept for writing data to Python object that support:
|
||||
/// n = object.write(str) # n = None or bytes written
|
||||
/// object.flush() # if flush exists, then it is callable
|
||||
class PythonOutputDevice
|
||||
{
|
||||
public:
|
||||
|
||||
// This class models both the Sink and Flushable concepts.
|
||||
struct category
|
||||
: boost::iostreams::sink_tag,
|
||||
boost::iostreams::flushable_tag
|
||||
{};
|
||||
|
||||
explicit
|
||||
PythonOutputDevice(boost::python::object object)
|
||||
: object_(object)
|
||||
{}
|
||||
|
||||
// Sink concept.
|
||||
public:
|
||||
|
||||
typedef char char_type;
|
||||
|
||||
std::streamsize write(const char* buffer, std::streamsize buffer_size)
|
||||
{
|
||||
namespace python = boost::python;
|
||||
// Copy the buffer to a python string.
|
||||
python::str data(buffer, buffer_size);
|
||||
|
||||
// Invoke write on the python object, passing in the data. The following
|
||||
// is equivalent to:
|
||||
// n = object_.write(data)
|
||||
python::extract<std::streamsize> bytes_written(
|
||||
object_.attr("write")(data));
|
||||
|
||||
// Per the Sink concept, return the number of bytes written. If the
|
||||
// Python return value provides a numeric result, then use it. Otherwise,
|
||||
// such as the case of a File object, use the buffer_size.
|
||||
return bytes_written.check()
|
||||
? bytes_written
|
||||
: buffer_size;
|
||||
}
|
||||
|
||||
// Flushable concept.
|
||||
public:
|
||||
|
||||
bool flush()
|
||||
{
|
||||
// If flush exists, then call it.
|
||||
boost::python::object flush = object_.attr("flush");
|
||||
if (!flush.is_none())
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
// Always return true. If an error occurs, an exception should be thrown.
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::python::object object_;
|
||||
};
|
||||
|
||||
/// @brief Use an auxiliary function to adapt the legacy function.
|
||||
void log_to_stream(boost::python::object object)
|
||||
{
|
||||
// Create an ostream that delegates to the python object.
|
||||
boost::iostreams::stream<PythonOutputDevice>* output = new boost::iostreams::stream<PythonOutputDevice>(object);
|
||||
Yosys::log_streams.insert(Yosys::log_streams.begin(), output);
|
||||
};
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(libyosys)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
class_<Initializer>("Initializer");
|
||||
scope().attr("_hidden") = new Initializer();
|
||||
|
||||
def("log_to_stream", &log_to_stream);
|
||||
""")
|
||||
|
||||
for enum in enums:
|
||||
|
@ -2086,6 +2361,11 @@ namespace YOSYS_PYTHON {
|
|||
for fun in unowned_functions:
|
||||
wrapper_file.write(fun.gen_boost_py())
|
||||
|
||||
wrapper_file.write("\n\n\t\tclass_<YosysStatics>(\"Yosys\")\n")
|
||||
for glbl in glbls:
|
||||
wrapper_file.write(glbl.gen_boost_py())
|
||||
wrapper_file.write("\t\t;\n")
|
||||
|
||||
wrapper_file.write("\n\t}\n}\n#endif")
|
||||
|
||||
def print_includes():
|
||||
|
|
|
@ -5,6 +5,7 @@ OBJS += passes/cmds/design.o
|
|||
OBJS += passes/cmds/select.o
|
||||
OBJS += passes/cmds/show.o
|
||||
OBJS += passes/cmds/rename.o
|
||||
OBJS += passes/cmds/autoname.o
|
||||
OBJS += passes/cmds/connect.o
|
||||
OBJS += passes/cmds/scatter.o
|
||||
OBJS += passes/cmds/setundef.o
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/yosys.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
int autoname_worker(Module *module)
|
||||
{
|
||||
dict<Cell*, pair<int, IdString>> proposed_cell_names;
|
||||
dict<Wire*, pair<int, IdString>> proposed_wire_names;
|
||||
dict<Wire*, int> wire_score;
|
||||
int best_score = -1;
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
for (auto &conn : cell->connections())
|
||||
for (auto bit : conn.second)
|
||||
if (bit.wire != nullptr)
|
||||
wire_score[bit.wire]++;
|
||||
|
||||
for (auto cell : module->selected_cells()) {
|
||||
if (cell->name[0] == '$') {
|
||||
for (auto &conn : cell->connections()) {
|
||||
string suffix = stringf("_%s_%s", log_id(cell->type), log_id(conn.first));
|
||||
for (auto bit : conn.second)
|
||||
if (bit.wire != nullptr && bit.wire->name[0] != '$') {
|
||||
IdString new_name(bit.wire->name.str() + suffix);
|
||||
int score = wire_score.at(bit.wire);
|
||||
if (cell->output(conn.first)) score = 0;
|
||||
score = 10000*score + new_name.size();
|
||||
if (!proposed_cell_names.count(cell) || score < proposed_cell_names.at(cell).first) {
|
||||
if (best_score < 0 || score < best_score)
|
||||
best_score = score;
|
||||
proposed_cell_names[cell] = make_pair(score, new_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (auto &conn : cell->connections()) {
|
||||
string suffix = stringf("_%s", log_id(conn.first));
|
||||
for (auto bit : conn.second)
|
||||
if (bit.wire != nullptr && bit.wire->name[0] == '$') {
|
||||
IdString new_name(cell->name.str() + suffix);
|
||||
int score = wire_score.at(bit.wire);
|
||||
if (cell->output(conn.first)) score = 0;
|
||||
score = 10000*score + new_name.size();
|
||||
if (!proposed_wire_names.count(bit.wire) || score < proposed_wire_names.at(bit.wire).first) {
|
||||
if (best_score < 0 || score < best_score)
|
||||
best_score = score;
|
||||
proposed_wire_names[bit.wire] = make_pair(score, new_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &it : proposed_cell_names) {
|
||||
if (best_score*2 < it.second.first)
|
||||
continue;
|
||||
IdString n = module->uniquify(it.second.second);
|
||||
log_debug("Rename cell %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n));
|
||||
module->rename(it.first, n);
|
||||
}
|
||||
|
||||
for (auto &it : proposed_wire_names) {
|
||||
if (best_score*2 < it.second.first)
|
||||
continue;
|
||||
IdString n = module->uniquify(it.second.second);
|
||||
log_debug("Rename wire %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n));
|
||||
module->rename(it.first, n);
|
||||
}
|
||||
|
||||
return proposed_cell_names.size() + proposed_wire_names.size();
|
||||
}
|
||||
|
||||
struct AutonamePass : public Pass {
|
||||
AutonamePass() : Pass("autoname", "automatically assign names to objects") { }
|
||||
void help() YS_OVERRIDE
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" autoname [selection]\n");
|
||||
log("\n");
|
||||
log("Assign auto-generated public names to objects with private names (the ones\n");
|
||||
log("with $-prefix).\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
{
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
// if (args[argidx] == "-foo") {
|
||||
// foo = true;
|
||||
// continue;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
|
||||
log_header(design, "Executing AUTONAME pass.\n");
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
{
|
||||
int count = 0, iter = 0;
|
||||
while (1) {
|
||||
iter++;
|
||||
int n = autoname_worker(module);
|
||||
if (!n) break;
|
||||
count += n;
|
||||
}
|
||||
if (count > 0)
|
||||
log("Renamed %d objects in module %s (%d iterations).\n", count, log_id(module), iter);
|
||||
}
|
||||
}
|
||||
} AutonamePass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
|
@ -158,22 +158,25 @@ static void detect_fsm(RTLIL::Wire *wire)
|
|||
std::set<sig2driver_entry_t> cellport_list;
|
||||
sig2user.find(sig_q, cellport_list);
|
||||
|
||||
auto sig_q_bits = sig_q.to_sigbit_pool();
|
||||
|
||||
for (auto &cellport : cellport_list)
|
||||
{
|
||||
RTLIL::Cell *cell = cellport.first;
|
||||
bool set_output = false, clr_output = false;
|
||||
|
||||
if (cell->type == "$ne")
|
||||
if (cell->type.in("$ne", "$reduce_or", "$reduce_bool"))
|
||||
set_output = true;
|
||||
|
||||
if (cell->type == "$eq")
|
||||
if (cell->type.in("$eq", "$logic_not", "$reduce_and"))
|
||||
clr_output = true;
|
||||
|
||||
if (!set_output && !clr_output) {
|
||||
clr_output = true;
|
||||
if (set_output || clr_output) {
|
||||
for (auto &port_it : cell->connections())
|
||||
if (port_it.first != "\\A" || port_it.first != "\\Y")
|
||||
clr_output = false;
|
||||
if (cell->input(port_it.first))
|
||||
for (auto bit : assign_map(port_it.second))
|
||||
if (bit.wire != nullptr && !sig_q_bits.count(bit))
|
||||
goto next_cellport;
|
||||
}
|
||||
|
||||
if (set_output || clr_output) {
|
||||
|
@ -184,6 +187,7 @@ static void detect_fsm(RTLIL::Wire *wire)
|
|||
ce.set(sig, val);
|
||||
}
|
||||
}
|
||||
next_cellport:;
|
||||
}
|
||||
|
||||
SigSpec sig_y = sig_d, sig_undef;
|
||||
|
|
|
@ -143,13 +143,18 @@ struct WreduceWorker
|
|||
|
||||
SigSpec sig_d = mi.sigmap(cell->getPort(ID(D)));
|
||||
SigSpec sig_q = mi.sigmap(cell->getPort(ID(Q)));
|
||||
Const initval;
|
||||
bool is_adff = (cell->type == ID($adff));
|
||||
Const initval, arst_value;
|
||||
|
||||
int width_before = GetSize(sig_q);
|
||||
|
||||
if (width_before == 0)
|
||||
return;
|
||||
|
||||
if (cell->parameters.count(ID(ARST_VALUE))) {
|
||||
arst_value = cell->parameters[ID(ARST_VALUE)];
|
||||
}
|
||||
|
||||
bool zero_ext = sig_d[GetSize(sig_d)-1] == State::S0;
|
||||
bool sign_ext = !zero_ext;
|
||||
|
||||
|
@ -163,7 +168,8 @@ struct WreduceWorker
|
|||
|
||||
for (int i = GetSize(sig_q)-1; i >= 0; i--)
|
||||
{
|
||||
if (zero_ext && sig_d[i] == State::S0 && (initval[i] == State::S0 || initval[i] == State::Sx)) {
|
||||
if (zero_ext && sig_d[i] == State::S0 && (initval[i] == State::S0 || initval[i] == State::Sx) &&
|
||||
(!is_adff || i >= GetSize(arst_value) || arst_value[i] == State::S0 || arst_value[i] == State::Sx)) {
|
||||
module->connect(sig_q[i], State::S0);
|
||||
remove_init_bits.insert(sig_q[i]);
|
||||
sig_d.remove(i);
|
||||
|
@ -171,7 +177,8 @@ struct WreduceWorker
|
|||
continue;
|
||||
}
|
||||
|
||||
if (sign_ext && i > 0 && sig_d[i] == sig_d[i-1] && initval[i] == initval[i-1]) {
|
||||
if (sign_ext && i > 0 && sig_d[i] == sig_d[i-1] && initval[i] == initval[i-1] &&
|
||||
(!is_adff || i >= GetSize(arst_value) || arst_value[i] == arst_value[i-1])) {
|
||||
module->connect(sig_q[i], sig_q[i-1]);
|
||||
remove_init_bits.insert(sig_q[i]);
|
||||
sig_d.remove(i);
|
||||
|
@ -214,7 +221,6 @@ struct WreduceWorker
|
|||
|
||||
// Narrow ARST_VALUE parameter to new size.
|
||||
if (cell->parameters.count(ID(ARST_VALUE))) {
|
||||
Const arst_value = cell->getParam(ID(ARST_VALUE));
|
||||
arst_value.bits.resize(GetSize(sig_q));
|
||||
cell->setParam(ID(ARST_VALUE), arst_value);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
%_pm.h: passes/pmgen/pmgen.py %.pmg
|
||||
$(P) mkdir -p passes/pmgen && python3 $< -o $@ -p $(subst _pm.h,,$(notdir $@)) $(filter-out $<,$^)
|
||||
$(P) mkdir -p passes/pmgen && $(PYTHON_EXECUTABLE) $< -o $@ -p $(subst _pm.h,,$(notdir $@)) $(filter-out $<,$^)
|
||||
|
||||
# --------------------------------------
|
||||
|
||||
|
@ -38,7 +38,7 @@ PEEPOPT_PATTERN += passes/pmgen/peepopt_muldiv.pmg
|
|||
PEEPOPT_PATTERN += passes/pmgen/peepopt_dffmux.pmg
|
||||
|
||||
passes/pmgen/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
|
||||
$(P) mkdir -p passes/pmgen && python3 $< -o $@ -p peepopt $(filter-out $<,$^)
|
||||
$(P) mkdir -p passes/pmgen && $(PYTHON_EXECUTABLE) $< -o $@ -p peepopt $(filter-out $<,$^)
|
||||
|
||||
# --------------------------------------
|
||||
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PMGEN_GENERATE
|
||||
#define PMGEN_GENERATE
|
||||
|
||||
#define GENERATE_PATTERN(pmclass, pattern) \
|
||||
generate_pattern<pmclass>([](pmclass &pm, std::function<void()> f){ return pm.run_ ## pattern(f); }, #pmclass, #pattern, design)
|
||||
|
||||
void pmtest_addports(Module *module)
|
||||
{
|
||||
pool<SigBit> driven_bits, used_bits;
|
||||
SigMap sigmap(module);
|
||||
int icnt = 0, ocnt = 0;
|
||||
|
||||
for (auto cell : module->cells())
|
||||
for (auto conn : cell->connections())
|
||||
{
|
||||
if (cell->input(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
used_bits.insert(bit);
|
||||
if (cell->output(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
driven_bits.insert(bit);
|
||||
}
|
||||
|
||||
for (auto wire : vector<Wire*>(module->wires()))
|
||||
{
|
||||
SigSpec ibits, obits;
|
||||
for (auto bit : sigmap(wire)) {
|
||||
if (!used_bits.count(bit))
|
||||
obits.append(bit);
|
||||
if (!driven_bits.count(bit))
|
||||
ibits.append(bit);
|
||||
}
|
||||
if (!ibits.empty()) {
|
||||
Wire *w = module->addWire(stringf("\\i%d", icnt++), GetSize(ibits));
|
||||
w->port_input = true;
|
||||
module->connect(ibits, w);
|
||||
}
|
||||
if (!obits.empty()) {
|
||||
Wire *w = module->addWire(stringf("\\o%d", ocnt++), GetSize(obits));
|
||||
w->port_output = true;
|
||||
module->connect(w, obits);
|
||||
}
|
||||
}
|
||||
|
||||
module->fixup_ports();
|
||||
}
|
||||
|
||||
template <class pm>
|
||||
void generate_pattern(std::function<void(pm&,std::function<void()>)> run, const char *pmclass, const char *pattern, Design *design)
|
||||
{
|
||||
log("Generating \"%s\" patterns for pattern matcher \"%s\".\n", pattern, pmclass);
|
||||
|
||||
int modcnt = 0;
|
||||
int maxmodcnt = 100;
|
||||
int maxsubcnt = 4;
|
||||
int timeout = 0;
|
||||
vector<Module*> mods;
|
||||
|
||||
while (modcnt < maxmodcnt)
|
||||
{
|
||||
int submodcnt = 0, itercnt = 0, cellcnt = 0;
|
||||
Module *mod = design->addModule(NEW_ID);
|
||||
|
||||
while (modcnt < maxmodcnt && submodcnt < maxsubcnt && itercnt++ < 1000)
|
||||
{
|
||||
if (timeout++ > 10000)
|
||||
log_error("pmgen generator is stuck: 10000 iterations with no matching module generated.\n");
|
||||
|
||||
pm matcher(mod, mod->cells());
|
||||
|
||||
matcher.rng(1);
|
||||
matcher.rngseed += modcnt;
|
||||
matcher.rng(1);
|
||||
matcher.rngseed += submodcnt;
|
||||
matcher.rng(1);
|
||||
matcher.rngseed += itercnt;
|
||||
matcher.rng(1);
|
||||
matcher.rngseed += cellcnt;
|
||||
matcher.rng(1);
|
||||
|
||||
if (GetSize(mod->cells()) != cellcnt)
|
||||
{
|
||||
bool found_match = false;
|
||||
run(matcher, [&](){ found_match = true; });
|
||||
cellcnt = GetSize(mod->cells());
|
||||
|
||||
if (found_match) {
|
||||
Module *m = design->addModule(stringf("\\pmtest_%s_%s_%05d",
|
||||
pmclass, pattern, modcnt++));
|
||||
log("Creating module %s with %d cells.\n", log_id(m), cellcnt);
|
||||
mod->cloneInto(m);
|
||||
pmtest_addports(m);
|
||||
mods.push_back(m);
|
||||
submodcnt++;
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
matcher.generate_mode = true;
|
||||
run(matcher, [](){});
|
||||
}
|
||||
|
||||
if (submodcnt && maxsubcnt < (1 << 16))
|
||||
maxsubcnt *= 2;
|
||||
|
||||
design->remove(mod);
|
||||
}
|
||||
|
||||
Module *m = design->addModule(stringf("\\pmtest_%s_%s", pmclass, pattern));
|
||||
log("Creating module %s with %d cells.\n", log_id(m), GetSize(mods));
|
||||
for (auto mod : mods) {
|
||||
Cell *c = m->addCell(mod->name, mod->name);
|
||||
for (auto port : mod->ports) {
|
||||
Wire *w = m->addWire(NEW_ID, GetSize(mod->wire(port)));
|
||||
c->setPort(port, w);
|
||||
}
|
||||
}
|
||||
pmtest_addports(m);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -24,8 +24,11 @@ USING_YOSYS_NAMESPACE
|
|||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
bool did_something;
|
||||
dict<SigBit, State> initbits;
|
||||
pool<SigBit> rminitbits;
|
||||
|
||||
#include "passes/pmgen/peepopt_pm.h"
|
||||
#include "generate.h"
|
||||
|
||||
struct PeepoptPass : public Pass {
|
||||
PeepoptPass() : Pass("peepopt", "collection of peephole optimizers") { }
|
||||
|
@ -40,27 +43,86 @@ struct PeepoptPass : public Pass {
|
|||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
{
|
||||
std::string genmode;
|
||||
|
||||
log_header(design, "Executing PEEPOPT pass (run peephole optimizers).\n");
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
// if (args[argidx] == "-singleton") {
|
||||
// singleton_mode = true;
|
||||
// continue;
|
||||
// }
|
||||
if (args[argidx] == "-generate" && argidx+1 < args.size()) {
|
||||
genmode = args[++argidx];
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
for (auto module : design->selected_modules()) {
|
||||
if (!genmode.empty())
|
||||
{
|
||||
initbits.clear();
|
||||
rminitbits.clear();
|
||||
|
||||
if (genmode == "shiftmul")
|
||||
GENERATE_PATTERN(peepopt_pm, shiftmul);
|
||||
else if (genmode == "muldiv")
|
||||
GENERATE_PATTERN(peepopt_pm, muldiv);
|
||||
else if (genmode == "dffmux")
|
||||
GENERATE_PATTERN(peepopt_pm, dffmux);
|
||||
else
|
||||
log_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
{
|
||||
did_something = true;
|
||||
while (did_something) {
|
||||
|
||||
while (did_something)
|
||||
{
|
||||
did_something = false;
|
||||
peepopt_pm pm(module, module->selected_cells());
|
||||
initbits.clear();
|
||||
rminitbits.clear();
|
||||
|
||||
peepopt_pm pm(module);
|
||||
|
||||
for (auto w : module->wires()) {
|
||||
auto it = w->attributes.find(ID(init));
|
||||
if (it != w->attributes.end()) {
|
||||
SigSpec sig = pm.sigmap(w);
|
||||
Const val = it->second;
|
||||
int len = std::min(GetSize(sig), GetSize(val));
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (sig[i].wire == nullptr)
|
||||
continue;
|
||||
if (val[i] != State::S0 && val[i] != State::S1)
|
||||
continue;
|
||||
initbits[sig[i]] = val[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pm.setup(module->selected_cells());
|
||||
|
||||
pm.run_shiftmul();
|
||||
pm.run_muldiv();
|
||||
pm.run_dffmux();
|
||||
|
||||
for (auto w : module->wires()) {
|
||||
auto it = w->attributes.find(ID(init));
|
||||
if (it != w->attributes.end()) {
|
||||
SigSpec sig = pm.sigmap(w);
|
||||
Const &val = it->second;
|
||||
int len = std::min(GetSize(sig), GetSize(val));
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (rminitbits.count(sig[i]))
|
||||
val[i] = State::Sx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initbits.clear();
|
||||
rminitbits.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,12 +60,13 @@ code
|
|||
SigSpec Q = port(dff, \Q);
|
||||
int width = GetSize(D);
|
||||
|
||||
SigSpec &dffD = dff->connections_.at(\D);
|
||||
SigSpec &dffQ = dff->connections_.at(\Q);
|
||||
Const init;
|
||||
for (const auto &b : Q) {
|
||||
auto it = b.wire->attributes.find(\init);
|
||||
init.bits.push_back(it == b.wire->attributes.end() ? State::Sx : it->second[b.offset]);
|
||||
SigSpec dffD = dff->getPort(\D);
|
||||
SigSpec dffQ = dff->getPort(\Q);
|
||||
|
||||
Const initval;
|
||||
for (auto b : Q) {
|
||||
auto it = initbits.find(b);
|
||||
initval.bits.push_back(it == initbits.end() ? State::Sx : it->second);
|
||||
}
|
||||
|
||||
auto cmpx = [=](State lhs, State rhs) {
|
||||
|
@ -76,56 +77,68 @@ code
|
|||
|
||||
int i = width-1;
|
||||
while (i > 1) {
|
||||
log_dump(i, D[i], D[i-1], rst[i], rst[i-1], init[i], init[i-1]);
|
||||
if (D[i] != D[i-1])
|
||||
break;
|
||||
if (!cmpx(rst[i], rst[i-1]))
|
||||
break;
|
||||
if (!cmpx(init[i], init[i-1]))
|
||||
if (!cmpx(initval[i], initval[i-1]))
|
||||
break;
|
||||
if (!cmpx(rst[i], init[i]))
|
||||
if (!cmpx(rst[i], initval[i]))
|
||||
break;
|
||||
rminitbits.insert(Q[i]);
|
||||
module->connect(Q[i], Q[i-1]);
|
||||
i--;
|
||||
}
|
||||
if (i < width-1) {
|
||||
did_something = true;
|
||||
if (cemux) {
|
||||
SigSpec &ceA = cemux->connections_.at(\A);
|
||||
SigSpec &ceB = cemux->connections_.at(\B);
|
||||
SigSpec &ceY = cemux->connections_.at(\Y);
|
||||
SigSpec ceA = cemux->getPort(\A);
|
||||
SigSpec ceB = cemux->getPort(\B);
|
||||
SigSpec ceY = cemux->getPort(\Y);
|
||||
ceA.remove(i, width-1-i);
|
||||
ceB.remove(i, width-1-i);
|
||||
ceY.remove(i, width-1-i);
|
||||
cemux->setPort(\A, ceA);
|
||||
cemux->setPort(\B, ceB);
|
||||
cemux->setPort(\Y, ceY);
|
||||
cemux->fixup_parameters();
|
||||
blacklist(cemux);
|
||||
}
|
||||
if (rstmux) {
|
||||
SigSpec &rstA = rstmux->connections_.at(\A);
|
||||
SigSpec &rstB = rstmux->connections_.at(\B);
|
||||
SigSpec &rstY = rstmux->connections_.at(\Y);
|
||||
SigSpec rstA = rstmux->getPort(\A);
|
||||
SigSpec rstB = rstmux->getPort(\B);
|
||||
SigSpec rstY = rstmux->getPort(\Y);
|
||||
rstA.remove(i, width-1-i);
|
||||
rstB.remove(i, width-1-i);
|
||||
rstY.remove(i, width-1-i);
|
||||
rstmux->setPort(\A, rstA);
|
||||
rstmux->setPort(\B, rstB);
|
||||
rstmux->setPort(\Y, rstY);
|
||||
rstmux->fixup_parameters();
|
||||
blacklist(rstmux);
|
||||
}
|
||||
dffD.remove(i, width-1-i);
|
||||
dffQ.remove(i, width-1-i);
|
||||
dff->setPort(\D, dffD);
|
||||
dff->setPort(\Q, dffQ);
|
||||
dff->fixup_parameters();
|
||||
blacklist(dff);
|
||||
|
||||
log("dffcemux pattern in %s: dff=%s, cemux=%s, rstmux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(cemux, "n/a"), log_id(rstmux, "n/a"), width-1-i);
|
||||
width = i+1;
|
||||
}
|
||||
if (cemux) {
|
||||
SigSpec &ceA = cemux->connections_.at(\A);
|
||||
SigSpec &ceB = cemux->connections_.at(\B);
|
||||
SigSpec &ceY = cemux->connections_.at(\Y);
|
||||
SigSpec ceA = cemux->getPort(\A);
|
||||
SigSpec ceB = cemux->getPort(\B);
|
||||
SigSpec ceY = cemux->getPort(\Y);
|
||||
|
||||
int count = 0;
|
||||
for (int i = width-1; i >= 0; i--) {
|
||||
if (D[i].wire)
|
||||
continue;
|
||||
if (cmpx(rst[i], D[i].data) && cmpx(init[i], D[i].data)) {
|
||||
if (cmpx(rst[i], D[i].data) && cmpx(initval[i], D[i].data)) {
|
||||
count++;
|
||||
rminitbits.insert(Q[i]);
|
||||
module->connect(Q[i], D[i]);
|
||||
ceA.remove(i);
|
||||
ceB.remove(i);
|
||||
|
@ -134,10 +147,21 @@ code
|
|||
dffQ.remove(i);
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
if (count > 0)
|
||||
{
|
||||
did_something = true;
|
||||
|
||||
cemux->setPort(\A, ceA);
|
||||
cemux->setPort(\B, ceB);
|
||||
cemux->setPort(\Y, ceY);
|
||||
cemux->fixup_parameters();
|
||||
blacklist(cemux);
|
||||
|
||||
dff->setPort(\D, dffD);
|
||||
dff->setPort(\Q, dffQ);
|
||||
dff->fixup_parameters();
|
||||
blacklist(dff);
|
||||
|
||||
log("dffcemux pattern in %s: dff=%s, cemux=%s, rstmux=%s; removed %d constant bits.\n", log_id(module), log_id(dff), log_id(cemux), log_id(rstmux, "n/a"), count);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,6 +362,7 @@ with open(outfile, "w") as f:
|
|||
print(" Module *module;", file=f)
|
||||
print(" SigMap sigmap;", file=f)
|
||||
print(" std::function<void()> on_accept;", file=f)
|
||||
print(" bool setup_done;", file=f)
|
||||
print(" bool generate_mode;", file=f)
|
||||
print(" int accept_cnt;", file=f)
|
||||
print("", file=f)
|
||||
|
@ -477,7 +478,17 @@ with open(outfile, "w") as f:
|
|||
print("", file=f)
|
||||
|
||||
print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(prefix), file=f)
|
||||
print(" module(module), sigmap(module), generate_mode(false), rngseed(12345678) {", file=f)
|
||||
print(" module(module), sigmap(module), setup_done(false), generate_mode(false), rngseed(12345678) {", file=f)
|
||||
print(" setup(cells);", file=f)
|
||||
print(" }", file=f)
|
||||
print("", file=f)
|
||||
|
||||
print(" {}_pm(Module *module) :".format(prefix), file=f)
|
||||
print(" module(module), sigmap(module), setup_done(false), generate_mode(false), rngseed(12345678) {", file=f)
|
||||
print(" }", file=f)
|
||||
print("", file=f)
|
||||
|
||||
print(" void setup(const vector<Cell*> &cells) {", file=f)
|
||||
for current_pattern in sorted(patterns.keys()):
|
||||
for s, t in sorted(udata_types[current_pattern].items()):
|
||||
if t.endswith("*"):
|
||||
|
@ -485,6 +496,8 @@ with open(outfile, "w") as f:
|
|||
else:
|
||||
print(" ud_{}.{} = {}();".format(current_pattern, s, t), file=f)
|
||||
current_pattern = None
|
||||
print(" log_assert(!setup_done);", file=f)
|
||||
print(" setup_done = true;", file=f)
|
||||
print(" for (auto port : module->ports)", file=f)
|
||||
print(" add_siguser(module->wire(port), nullptr);", file=f)
|
||||
print(" for (auto cell : module->cells())", file=f)
|
||||
|
@ -539,6 +552,7 @@ with open(outfile, "w") as f:
|
|||
|
||||
for current_pattern in sorted(patterns.keys()):
|
||||
print(" int run_{}(std::function<void()> on_accept_f) {{".format(current_pattern), file=f)
|
||||
print(" log_assert(setup_done);", file=f)
|
||||
print(" accept_cnt = 0;", file=f)
|
||||
print(" on_accept = on_accept_f;", file=f)
|
||||
print(" rollback = 0;", file=f)
|
||||
|
|
|
@ -23,13 +23,11 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
// for peepopt_pm
|
||||
bool did_something;
|
||||
|
||||
#include "passes/pmgen/test_pmgen_pm.h"
|
||||
#include "passes/pmgen/ice40_dsp_pm.h"
|
||||
#include "passes/pmgen/xilinx_srl_pm.h"
|
||||
#include "passes/pmgen/peepopt_pm.h"
|
||||
|
||||
#include "generate.h"
|
||||
|
||||
void reduce_chain(test_pmgen_pm &pm)
|
||||
{
|
||||
|
@ -118,123 +116,6 @@ void opt_eqpmux(test_pmgen_pm &pm)
|
|||
log(" -> %s (%s)\n", log_id(c), log_id(c->type));
|
||||
}
|
||||
|
||||
#define GENERATE_PATTERN(pmclass, pattern) \
|
||||
generate_pattern<pmclass>([](pmclass &pm, std::function<void()> f){ return pm.run_ ## pattern(f); }, #pmclass, #pattern, design)
|
||||
|
||||
void pmtest_addports(Module *module)
|
||||
{
|
||||
pool<SigBit> driven_bits, used_bits;
|
||||
SigMap sigmap(module);
|
||||
int icnt = 0, ocnt = 0;
|
||||
|
||||
for (auto cell : module->cells())
|
||||
for (auto conn : cell->connections())
|
||||
{
|
||||
if (cell->input(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
used_bits.insert(bit);
|
||||
if (cell->output(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
driven_bits.insert(bit);
|
||||
}
|
||||
|
||||
for (auto wire : vector<Wire*>(module->wires()))
|
||||
{
|
||||
SigSpec ibits, obits;
|
||||
for (auto bit : sigmap(wire)) {
|
||||
if (!used_bits.count(bit))
|
||||
obits.append(bit);
|
||||
if (!driven_bits.count(bit))
|
||||
ibits.append(bit);
|
||||
}
|
||||
if (!ibits.empty()) {
|
||||
Wire *w = module->addWire(stringf("\\i%d", icnt++), GetSize(ibits));
|
||||
w->port_input = true;
|
||||
module->connect(ibits, w);
|
||||
}
|
||||
if (!obits.empty()) {
|
||||
Wire *w = module->addWire(stringf("\\o%d", ocnt++), GetSize(obits));
|
||||
w->port_output = true;
|
||||
module->connect(w, obits);
|
||||
}
|
||||
}
|
||||
|
||||
module->fixup_ports();
|
||||
}
|
||||
|
||||
template <class pm>
|
||||
void generate_pattern(std::function<void(pm&,std::function<void()>)> run, const char *pmclass, const char *pattern, Design *design)
|
||||
{
|
||||
log("Generating \"%s\" patterns for pattern matcher \"%s\".\n", pattern, pmclass);
|
||||
|
||||
int modcnt = 0;
|
||||
int maxmodcnt = 100;
|
||||
int maxsubcnt = 4;
|
||||
int timeout = 0;
|
||||
vector<Module*> mods;
|
||||
|
||||
while (modcnt < maxmodcnt)
|
||||
{
|
||||
int submodcnt = 0, itercnt = 0, cellcnt = 0;
|
||||
Module *mod = design->addModule(NEW_ID);
|
||||
|
||||
while (modcnt < maxmodcnt && submodcnt < maxsubcnt && itercnt++ < 1000)
|
||||
{
|
||||
if (timeout++ > 10000)
|
||||
log_error("pmgen generator is stuck: 10000 iterations with no matching module generated.\n");
|
||||
|
||||
pm matcher(mod, mod->cells());
|
||||
|
||||
matcher.rng(1);
|
||||
matcher.rngseed += modcnt;
|
||||
matcher.rng(1);
|
||||
matcher.rngseed += submodcnt;
|
||||
matcher.rng(1);
|
||||
matcher.rngseed += itercnt;
|
||||
matcher.rng(1);
|
||||
matcher.rngseed += cellcnt;
|
||||
matcher.rng(1);
|
||||
|
||||
if (GetSize(mod->cells()) != cellcnt)
|
||||
{
|
||||
bool found_match = false;
|
||||
run(matcher, [&](){ found_match = true; });
|
||||
cellcnt = GetSize(mod->cells());
|
||||
|
||||
if (found_match) {
|
||||
Module *m = design->addModule(stringf("\\pmtest_%s_%s_%05d",
|
||||
pmclass, pattern, modcnt++));
|
||||
log("Creating module %s with %d cells.\n", log_id(m), cellcnt);
|
||||
mod->cloneInto(m);
|
||||
pmtest_addports(m);
|
||||
mods.push_back(m);
|
||||
submodcnt++;
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
matcher.generate_mode = true;
|
||||
run(matcher, [](){});
|
||||
}
|
||||
|
||||
if (submodcnt && maxsubcnt < (1 << 16))
|
||||
maxsubcnt *= 2;
|
||||
|
||||
design->remove(mod);
|
||||
}
|
||||
|
||||
Module *m = design->addModule(stringf("\\pmtest_%s_%s", pmclass, pattern));
|
||||
log("Creating module %s with %d cells.\n", log_id(m), GetSize(mods));
|
||||
for (auto mod : mods) {
|
||||
Cell *c = m->addCell(mod->name, mod->name);
|
||||
for (auto port : mod->ports) {
|
||||
Wire *w = m->addWire(NEW_ID, GetSize(mod->wire(port)));
|
||||
c->setPort(port, w);
|
||||
}
|
||||
}
|
||||
pmtest_addports(m);
|
||||
}
|
||||
|
||||
struct TestPmgenPass : public Pass {
|
||||
TestPmgenPass() : Pass("test_pmgen", "test pass for pmgen") { }
|
||||
void help() YS_OVERRIDE
|
||||
|
@ -355,12 +236,6 @@ struct TestPmgenPass : public Pass {
|
|||
if (pattern == "xilinx_srl.variable")
|
||||
return GENERATE_PATTERN(xilinx_srl_pm, variable);
|
||||
|
||||
if (pattern == "peepopt-muldiv")
|
||||
return GENERATE_PATTERN(peepopt_pm, muldiv);
|
||||
|
||||
if (pattern == "peepopt-shiftmul")
|
||||
return GENERATE_PATTERN(peepopt_pm, shiftmul);
|
||||
|
||||
log_cmd_error("Unknown pattern: %s\n", pattern.c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -98,16 +98,16 @@ code sigA sigB sigC sigD sigM clock
|
|||
if (param(dsp, \USE_MULT, Const("MULTIPLY")).decode_string() == "MULTIPLY") {
|
||||
// Only care about those bits that are used
|
||||
int i;
|
||||
for (i = 0; i < GetSize(P); i++) {
|
||||
if (nusers(P[i]) <= 1)
|
||||
for (i = GetSize(P)-1; i >= 0; i--)
|
||||
if (nusers(P[i]) > 1)
|
||||
break;
|
||||
sigM.append(P[i]);
|
||||
}
|
||||
i++;
|
||||
log_assert(nusers(P.extract_end(i)) <= 1);
|
||||
// This sigM could have no users if downstream sinks (e.g. $add) is
|
||||
// narrower than $mul result, for example
|
||||
if (sigM.empty())
|
||||
if (i == 0)
|
||||
reject;
|
||||
sigM = P.extract(0, i);
|
||||
}
|
||||
else
|
||||
sigM = P;
|
||||
|
@ -460,6 +460,8 @@ arg argD argQ clock
|
|||
|
||||
code
|
||||
dff = nullptr;
|
||||
if (GetSize(argQ) == 0)
|
||||
reject;
|
||||
for (const auto &c : argQ.chunks()) {
|
||||
// Abandon matches when 'Q' is a constant
|
||||
if (!c.wire)
|
||||
|
|
|
@ -63,12 +63,12 @@ code sigC sigP clock
|
|||
if (param(dsp, \USE_MULT, Const("MULTIPLY")).decode_string() == "MULTIPLY") {
|
||||
// Only care about those bits that are used
|
||||
int i;
|
||||
for (i = 0; i < GetSize(P); i++) {
|
||||
if (nusers(P[i]) <= 1)
|
||||
for (i = GetSize(P)-1; i >= 0; i--)
|
||||
if (nusers(P[i]) > 1)
|
||||
break;
|
||||
sigP.append(P[i]);
|
||||
}
|
||||
i++;
|
||||
log_assert(nusers(P.extract_end(i)) <= 1);
|
||||
sigP = P.extract(0, i);
|
||||
}
|
||||
else
|
||||
sigP = P;
|
||||
|
|
|
@ -262,10 +262,14 @@ struct ExtractFaWorker
|
|||
pool<SigBit> new_leaves = leaves;
|
||||
|
||||
new_leaves.erase(bit);
|
||||
if (cell->hasPort(ID::A)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::A))));
|
||||
if (cell->hasPort(ID::B)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::B))));
|
||||
if (cell->hasPort(ID(C))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(C)))));
|
||||
if (cell->hasPort(ID(D))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(D)))));
|
||||
for (auto port : {ID::A, ID::B, ID(C), ID(D)}) {
|
||||
if (!cell->hasPort(port))
|
||||
continue;
|
||||
auto bit = sigmap(SigBit(cell->getPort(port)));
|
||||
if (!bit.wire)
|
||||
continue;
|
||||
new_leaves.insert(bit);
|
||||
}
|
||||
|
||||
if (GetSize(new_leaves) > maxbreadth)
|
||||
continue;
|
||||
|
|
|
@ -394,7 +394,7 @@ struct FlowGraph
|
|||
|
||||
pair<pool<RTLIL::SigBit>, pool<RTLIL::SigBit>> edge_cut()
|
||||
{
|
||||
pool<RTLIL::SigBit> x, xi;
|
||||
pool<RTLIL::SigBit> x = {source}, xi; // X and X̅ in the paper
|
||||
|
||||
NodePrime source_prime = {source, true};
|
||||
pool<NodePrime> visited;
|
||||
|
@ -437,6 +437,7 @@ struct FlowGraph
|
|||
for (auto collapsed_node : collapsed[sink])
|
||||
xi.insert(collapsed_node);
|
||||
|
||||
log_assert(x[source] && !xi[source]);
|
||||
log_assert(!x[sink] && xi[sink]);
|
||||
return {x, xi};
|
||||
}
|
||||
|
@ -1050,7 +1051,7 @@ struct FlowmapWorker
|
|||
|
||||
auto cut_inputs = cut_lut_at_gate(lut, lut_gate);
|
||||
pool<RTLIL::SigBit> gate_inputs = cut_inputs.first, other_inputs = cut_inputs.second;
|
||||
if (gate_inputs.empty() && (int)other_inputs.size() == order)
|
||||
if (gate_inputs.empty() && (int)other_inputs.size() >= order)
|
||||
{
|
||||
if (debug_relax)
|
||||
log(" Breaking would result in a (k+1)-LUT.\n");
|
||||
|
|
|
@ -9,12 +9,12 @@ GENFILES += techlibs/common/simcells_help.inc
|
|||
|
||||
techlibs/common/simlib_help.inc: techlibs/common/cellhelp.py techlibs/common/simlib.v
|
||||
$(Q) mkdir -p techlibs/common
|
||||
$(P) python3 $^ > $@.new
|
||||
$(P) $(PYTHON_EXECUTABLE) $^ > $@.new
|
||||
$(Q) mv $@.new $@
|
||||
|
||||
techlibs/common/simcells_help.inc: techlibs/common/cellhelp.py techlibs/common/simcells.v
|
||||
$(Q) mkdir -p techlibs/common
|
||||
$(P) python3 $^ > $@.new
|
||||
$(P) $(PYTHON_EXECUTABLE) $^ > $@.new
|
||||
$(Q) mv $@.new $@
|
||||
|
||||
kernel/register.o: techlibs/common/simlib_help.inc techlibs/common/simcells_help.inc
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// with n <= k inputs should be techmapped in this way, because this shortens the critical path
|
||||
// from n to 1 by avoiding carry chains.
|
||||
|
||||
(* techmap_celltype = "$eq $ne $lt $le $gt $ge" *)
|
||||
(* techmap_celltype = "$lt $le $gt $ge" *)
|
||||
module _90_lut_cmp_ (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
|
@ -27,12 +27,12 @@ EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
|
|||
|
||||
techlibs/ecp5/brams_init.mk: techlibs/ecp5/brams_init.py
|
||||
$(Q) mkdir -p techlibs/ecp5
|
||||
$(P) python3 $<
|
||||
$(P) $(PYTHON_EXECUTABLE) $<
|
||||
$(Q) touch $@
|
||||
|
||||
techlibs/ecp5/brams_connect.mk: techlibs/ecp5/brams_connect.py
|
||||
$(Q) mkdir -p techlibs/ecp5
|
||||
$(P) python3 $<
|
||||
$(P) $(PYTHON_EXECUTABLE) $<
|
||||
$(Q) touch $@
|
||||
|
||||
|
||||
|
|
|
@ -333,6 +333,13 @@ module ECLKSYNCB(
|
|||
);
|
||||
endmodule
|
||||
|
||||
(* blackbox *)
|
||||
module ECLKBRIDGECS(
|
||||
input CLK0, CLK1, SEL,
|
||||
output ECSOUT
|
||||
);
|
||||
endmodule
|
||||
|
||||
(* blackbox *)
|
||||
module DCCA(
|
||||
input CLKI, CE,
|
||||
|
|
|
@ -23,15 +23,15 @@ module FD1S3JX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLI
|
|||
// module FL1S3AY(); endmodule
|
||||
|
||||
// Diamond I/O registers
|
||||
module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module OFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
// TODO: Diamond I/O latches
|
||||
// module IFS1S1B(input PD, D, SCLK, output Q); endmodule
|
||||
|
|
|
@ -297,6 +297,7 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
run("simplemap");
|
||||
run("ecp5_ffinit");
|
||||
run("ecp5_gsr");
|
||||
run("attrmvcp -copy -attr syn_useioff");
|
||||
run("opt_clean");
|
||||
}
|
||||
|
||||
|
@ -313,9 +314,9 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
if (abc9) {
|
||||
run("read_verilog -icells -lib +/ecp5/abc9_model.v");
|
||||
if (nowidelut)
|
||||
run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200");
|
||||
run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
|
||||
else
|
||||
run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200");
|
||||
run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
|
||||
run("techmap -map +/ecp5/abc9_unmap.v");
|
||||
} else {
|
||||
if (nowidelut)
|
||||
|
@ -338,6 +339,7 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
|
||||
if (check_label("check"))
|
||||
{
|
||||
run("autoname");
|
||||
run("hierarchy -check");
|
||||
run("stat");
|
||||
run("check -noinit");
|
||||
|
|
|
@ -17,6 +17,18 @@ module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE
|
|||
module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
|
||||
|
||||
module \$_DLATCH_N_ (E, D, Q);
|
||||
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
|
||||
input E, D;
|
||||
output Q = !E ? D : Q;
|
||||
endmodule
|
||||
|
||||
module \$_DLATCH_P_ (E, D, Q);
|
||||
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
|
||||
input E, D;
|
||||
output Q = E ? D : Q;
|
||||
endmodule
|
||||
|
||||
`ifndef NO_LUT
|
||||
module \$lut (A, Y);
|
||||
parameter WIDTH = 0;
|
||||
|
|
|
@ -59,7 +59,9 @@ module EFX_FF(
|
|||
assign ce = CE_POLARITY ? CE : ~CE;
|
||||
assign sr = SR_POLARITY ? SR : ~SR;
|
||||
assign d = D_POLARITY ? D : ~D;
|
||||
|
||||
|
||||
initial Q = 1'b0;
|
||||
|
||||
generate
|
||||
if (SR_SYNC == 1)
|
||||
begin
|
||||
|
|
|
@ -15,3 +15,13 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/dram.txt))
|
|||
|
||||
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_init3.vh))
|
||||
|
||||
EXTRA_OBJS += techlibs/gowin/brams_init.mk
|
||||
.SECONDARY: techlibs/gowin/brams_init.mk
|
||||
|
||||
techlibs/gowin/brams_init.mk: techlibs/gowin/brams_init.py
|
||||
$(Q) mkdir -p techlibs/gowin
|
||||
$(P) python3 $<
|
||||
$(Q) touch $@
|
||||
|
||||
techlibs/gowin/bram_init_16.vh: techlibs/gowin/brams_init.mk
|
||||
$(eval $(call add_gen_share_file,share/gowin,techlibs/gowin/bram_init_16.vh))
|
||||
|
|
|
@ -40,15 +40,15 @@ module _80_gw1n_alu(A, B, CI, BI, X, Y, CO);
|
|||
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
|
||||
|
||||
wire [Y_WIDTH-1:0] AA = A_buf;
|
||||
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
|
||||
wire [Y_WIDTH-1:0] BB = B_buf;
|
||||
wire [Y_WIDTH-1:0] C = {CO, CI};
|
||||
|
||||
genvar i;
|
||||
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
|
||||
ALU #(.ALU_MODE(32'b0))
|
||||
ALU #(.ALU_MODE(2)) // ADDSUB I3 ? add : sub
|
||||
alu(.I0(AA[i]),
|
||||
.I1(BB[i]),
|
||||
.I3(1'b0),
|
||||
.I3(~BI),
|
||||
.CIN(C[i]),
|
||||
.COUT(CO[i]),
|
||||
.SUM(Y[i])
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
bram $__GW1NR_SDP
|
||||
# uncomment when done
|
||||
# init 1
|
||||
init 1
|
||||
abits 9 @a9d36
|
||||
dbits 32 @a9d36
|
||||
abits 10 @a10d18
|
||||
dbits 16 @a10d18
|
||||
abits 11 @a11d9
|
||||
|
@ -14,7 +15,8 @@ bram $__GW1NR_SDP
|
|||
groups 2
|
||||
ports 1 1
|
||||
wrmode 1 0
|
||||
enable 1 1 @a10d18
|
||||
enable 4 1 @a9d36
|
||||
enable 2 1 @a10d18
|
||||
enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
|
||||
transp 0 0
|
||||
clocks 2 3
|
||||
|
@ -24,6 +26,6 @@ endbram
|
|||
match $__GW1NR_SDP
|
||||
min bits 2048
|
||||
min efficiency 5
|
||||
shuffle_enable B
|
||||
shuffle_enable A
|
||||
make_transp
|
||||
endmatch
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
with open("techlibs/gowin/bram_init_16.vh", "w") as f:
|
||||
for i in range(0, 0x40):
|
||||
low = i << 8
|
||||
hi = ((i+1) << 8)-1
|
||||
snippet = "INIT[%d:%d]" % (hi, low)
|
||||
print(".INIT_RAM_%02X({%s})," % (i, snippet), file=f)
|
|
@ -8,26 +8,28 @@
|
|||
module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||
parameter CFG_ABITS = 10;
|
||||
parameter CFG_DBITS = 16;
|
||||
parameter CFG_ENABLE_A = 3;
|
||||
|
||||
parameter [16383:0] INIT = 16384'hx;
|
||||
parameter CLKPOL2 = 1;
|
||||
parameter CLKPOL3 = 1;
|
||||
parameter CFG_ENABLE_A = 1;
|
||||
parameter [16383:0] INIT = 16384'hx;
|
||||
parameter CLKPOL2 = 1;
|
||||
parameter CLKPOL3 = 1;
|
||||
|
||||
input CLK2;
|
||||
input CLK3;
|
||||
|
||||
input [CFG_ABITS-1:0] A1ADDR;
|
||||
input [CFG_DBITS-1:0] A1DATA;
|
||||
input [CFG_ENABLE_A-1:0] A1EN;
|
||||
input [CFG_ENABLE_A-1:0] A1EN;
|
||||
|
||||
input [CFG_ABITS-1:0] B1ADDR;
|
||||
output [CFG_DBITS-1:0] B1DATA;
|
||||
input B1EN;
|
||||
|
||||
wire [31-CFG_DBITS:0] open;
|
||||
|
||||
|
||||
generate if (CFG_DBITS == 1) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(1),
|
||||
.BIT_WIDTH_1(1),
|
||||
|
@ -38,10 +40,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
||||
.WREB(1'b0), .CEB(B1EN),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS == 2) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(2),
|
||||
.BIT_WIDTH_1(2),
|
||||
|
@ -52,10 +58,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
||||
.WREB(1'b0), .CEB(B1EN),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS <= 4) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(4),
|
||||
.BIT_WIDTH_1(4),
|
||||
|
@ -66,10 +76,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.WREA(A1EN), .OCE(1'b0),
|
||||
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS <= 8) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(8),
|
||||
.BIT_WIDTH_1(8),
|
||||
|
@ -80,10 +94,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
||||
.WREB(1'b0), .CEB(B1EN),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS <= 16) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(16),
|
||||
.BIT_WIDTH_1(16),
|
||||
|
@ -91,10 +109,31 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.RESET_MODE("SYNC")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.CLKA(CLK2), .CLKB(CLK3),
|
||||
.WREA(A1EN), .OCE(1'b0),
|
||||
.WREA(|A1EN), .OCE(1'b0),
|
||||
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(12-CFG_ABITS){1'b0}}, A1EN}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS <= 32) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(32),
|
||||
.BIT_WIDTH_1(32),
|
||||
.BLK_SEL(3'b000),
|
||||
.RESET_MODE("SYNC")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.CLKA(CLK2), .CLKB(CLK3),
|
||||
.WREA(|A1EN), .OCE(1'b0),
|
||||
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA),
|
||||
.DO(B1DATA),
|
||||
.ADA({A1ADDR, {(10-CFG_ABITS){1'b0}}, A1EN}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else begin
|
||||
wire TECHMAP_FAIL = 1'b1;
|
||||
|
|
|
@ -1,9 +1,83 @@
|
|||
module \$_DFF_N_ (input D, C, output Q); DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||
module \$_DFF_P_ #(parameter INIT = 1'b0) (input D, C, output Q); DFF #(.INIT(INIT)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||
//All DFF* have INIT, but the hardware is always initialised to the reset
|
||||
//value regardless. The parameter is ignored.
|
||||
|
||||
// DFFN D Flip-Flop with Negative-Edge Clock
|
||||
module \$_DFF_N_ (input D, C, output Q); DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||
// DFF D Flip-Flop
|
||||
module \$_DFF_P_ (input D, C, output Q); DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||
|
||||
// DFFE D Flip-Flop with Clock Enable
|
||||
module \$_DFFE_PP_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule
|
||||
module \$_DFFE_PN_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule
|
||||
|
||||
// DFFNE D Flip-Flop with Negative-Edge Clock and Clock Enable
|
||||
module \$_DFFE_NP_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule
|
||||
module \$_DFFE_NN_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule
|
||||
|
||||
// DFFR D Flip-Flop with Synchronous Reset
|
||||
module \$__DFFS_PN0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule
|
||||
module \$__DFFS_PP0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
||||
module \$__DFFS_PP1_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
||||
|
||||
// DFFNR D Flip-Flop with Negative-Edge Clock and Synchronous Reset
|
||||
module \$__DFFS_NN0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule
|
||||
module \$__DFFS_NP0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
||||
|
||||
// DFFRE D Flip-Flop with Clock Enable and Synchronous Reset
|
||||
module \$__DFFSE_PN0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); endmodule
|
||||
module \$__DFFSE_PP0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule
|
||||
|
||||
// DFFNRE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Synchronous Reset
|
||||
module \$__DFFNSE_PN0 (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); endmodule
|
||||
module \$__DFFNSE_PP0 (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule
|
||||
|
||||
// DFFS D Flip-Flop with Synchronous Set
|
||||
module \$__DFFS_PN1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule
|
||||
module \$__DFFS_PP1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule
|
||||
|
||||
// DFFNS D Flip-Flop with Negative-Edge Clock and Synchronous Set
|
||||
module \$__DFFS_NN1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule
|
||||
module \$__DFFS_NP1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule
|
||||
|
||||
// DFFSE D Flip-Flop with Clock Enable and Synchronous Set
|
||||
module \$__DFFSE_PN1 (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); endmodule
|
||||
module \$__DFFSE_PP1 (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule
|
||||
|
||||
// DFFNSE D Flip-Flop with Negative-Edge Clock,Clock Enable,and Synchronous Set
|
||||
module \$__DFFSE_NN1 (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); endmodule
|
||||
module \$__DFFSE_NP1 (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule
|
||||
|
||||
// DFFP D Flip-Flop with Asynchronous Preset
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule
|
||||
module \$_DFF_PN1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule
|
||||
|
||||
// DFFNP D Flip-Flop with Negative-Edge Clock and Asynchronous Preset
|
||||
module \$_DFF_NP1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule
|
||||
module \$_DFF_NN1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule
|
||||
|
||||
// DFFC D Flip-Flop with Asynchronous Clear
|
||||
module \$_DFF_PP0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule
|
||||
module \$_DFF_PN0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule
|
||||
|
||||
// DFFNC D Flip-Flop with Negative-Edge Clock and Asynchronous Clear
|
||||
module \$_DFF_NP0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule
|
||||
module \$_DFF_NN0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule
|
||||
|
||||
// DFFPE D Flip-Flop with Clock Enable and Asynchronous Preset
|
||||
module \$__DFFE_PP1 (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); endmodule
|
||||
module \$__DFFE_PN1 (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule
|
||||
|
||||
// DFFNPE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Asynchronous Preset
|
||||
module \$__DFFE_NP1 (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); endmodule
|
||||
module \$__DFFE_NN1 (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule
|
||||
|
||||
// DFFCE D Flip-Flop with Clock Enable and Asynchronous Clear
|
||||
module \$__DFFE_PP0 (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); endmodule
|
||||
module \$__DFFE_PN0 (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule
|
||||
|
||||
// DFFNCE D Flip-Flop with Negative-Edge Clock,Clock Enable and Asynchronous Clear
|
||||
module \$__DFFE_NP0 (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); endmodule
|
||||
module \$__DFFE_NN0 (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule
|
||||
|
||||
|
||||
module \$lut (A, Y);
|
||||
parameter WIDTH = 0;
|
||||
|
@ -28,6 +102,30 @@ module \$lut (A, Y);
|
|||
if (WIDTH == 4) begin
|
||||
LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y),
|
||||
.I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3]));
|
||||
end else
|
||||
if (WIDTH == 5) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[15: 0]), .WIDTH(4)) lut0 (.A(A[3:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[31:16]), .WIDTH(4)) lut1 (.A(A[3:0]), .Y(f1));
|
||||
MUX2_LUT5 mux5(.I0(f0), .I1(f1), .S0(A[4]), .O(Y));
|
||||
end else
|
||||
if (WIDTH == 6) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[31: 0]), .WIDTH(5)) lut0 (.A(A[4:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[63:32]), .WIDTH(5)) lut1 (.A(A[4:0]), .Y(f1));
|
||||
MUX2_LUT6 mux6(.I0(f0), .I1(f1), .S0(A[5]), .O(Y));
|
||||
end else
|
||||
if (WIDTH == 7) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[63: 0]), .WIDTH(6)) lut0 (.A(A[5:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[127:64]), .WIDTH(6)) lut1 (.A(A[5:0]), .Y(f1));
|
||||
MUX2_LUT7 mux7(.I0(f0), .I1(f1), .S0(A[6]), .O(Y));
|
||||
end else
|
||||
if (WIDTH == 8) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[127: 0]), .WIDTH(7)) lut0 (.A(A[6:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[255:128]), .WIDTH(7)) lut1 (.A(A[6:0]), .Y(f1));
|
||||
MUX2_LUT8 mux8(.I0(f0), .I1(f1), .S0(A[7]), .O(Y));
|
||||
end else begin
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
end
|
||||
|
|
|
@ -24,6 +24,41 @@ module LUT4(output F, input I0, I1, I2, I3);
|
|||
assign F = I0 ? s1[1] : s1[0];
|
||||
endmodule
|
||||
|
||||
module MUX2 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
assign O = S0 ? I1 : I0;
|
||||
endmodule
|
||||
|
||||
module MUX2_LUT5 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
MUX2 mux2_lut5 (O, I0, I1, S0);
|
||||
endmodule
|
||||
|
||||
module MUX2_LUT6 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
MUX2 mux2_lut6 (O, I0, I1, S0);
|
||||
endmodule
|
||||
|
||||
module MUX2_LUT7 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
MUX2 mux2_lut7 (O, I0, I1, S0);
|
||||
endmodule
|
||||
|
||||
module MUX2_LUT8 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
MUX2 mux2_lut8 (O, I0, I1, S0);
|
||||
endmodule
|
||||
|
||||
module DFF (output reg Q, input CLK, D);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
|
@ -31,6 +66,112 @@ module DFF (output reg Q, input CLK, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module DFFE (output reg Q, input D, CLK, CE);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFE (positive clock edge; clock enable)
|
||||
|
||||
|
||||
module DFFS (output reg Q, input D, CLK, SET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (SET)
|
||||
Q <= 1'b1;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFS (positive clock edge; synchronous set)
|
||||
|
||||
|
||||
module DFFSE (output reg Q, input D, CLK, CE, SET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (SET)
|
||||
Q <= 1'b1;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFSE (positive clock edge; synchronous set takes precedence over clock enable)
|
||||
|
||||
|
||||
module DFFR (output reg Q, input D, CLK, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFR (positive clock edge; synchronous reset)
|
||||
|
||||
|
||||
module DFFRE (output reg Q, input D, CLK, CE, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFRE (positive clock edge; synchronous reset takes precedence over clock enable)
|
||||
|
||||
|
||||
module DFFP (output reg Q, input D, CLK, PRESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK or posedge PRESET) begin
|
||||
if(PRESET)
|
||||
Q <= 1'b1;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFP (positive clock edge; asynchronous preset)
|
||||
|
||||
|
||||
module DFFPE (output reg Q, input D, CLK, CE, PRESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK or posedge PRESET) begin
|
||||
if(PRESET)
|
||||
Q <= 1'b1;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFPE (positive clock edge; asynchronous preset; clock enable)
|
||||
|
||||
|
||||
module DFFC (output reg Q, input D, CLK, CLEAR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK or posedge CLEAR) begin
|
||||
if(CLEAR)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFC (positive clock edge; asynchronous clear)
|
||||
|
||||
|
||||
module DFFCE (output reg Q, input D, CLK, CE, CLEAR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK or posedge CLEAR) begin
|
||||
if(CLEAR)
|
||||
Q <= 1'b0;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFCE (positive clock edge; asynchronous clear; clock enable)
|
||||
|
||||
|
||||
module DFFN (output reg Q, input CLK, D);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
|
@ -38,16 +179,112 @@ module DFFN (output reg Q, input CLK, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module DFFR (output reg Q, input D, CLK, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFR (positive clock edge; synchronous reset)
|
||||
module DFFNE (output reg Q, input D, CLK, CE);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNE (negative clock edge; clock enable)
|
||||
|
||||
|
||||
module DFFNS (output reg Q, input D, CLK, SET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (SET)
|
||||
Q <= 1'b1;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNS (negative clock edge; synchronous set)
|
||||
|
||||
|
||||
module DFFNSE (output reg Q, input D, CLK, CE, SET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (SET)
|
||||
Q <= 1'b1;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNSE (negative clock edge; synchronous set takes precedence over clock enable)
|
||||
|
||||
|
||||
module DFFNR (output reg Q, input D, CLK, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNR (negative clock edge; synchronous reset)
|
||||
|
||||
|
||||
module DFFNRE (output reg Q, input D, CLK, CE, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNRE (negative clock edge; synchronous reset takes precedence over clock enable)
|
||||
|
||||
|
||||
module DFFNP (output reg Q, input D, CLK, PRESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK or posedge PRESET) begin
|
||||
if(PRESET)
|
||||
Q <= 1'b1;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNP (negative clock edge; asynchronous preset)
|
||||
|
||||
|
||||
module DFFNPE (output reg Q, input D, CLK, CE, PRESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK or posedge PRESET) begin
|
||||
if(PRESET)
|
||||
Q <= 1'b1;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNPE (negative clock edge; asynchronous preset; clock enable)
|
||||
|
||||
|
||||
module DFFNC (output reg Q, input D, CLK, CLEAR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK or posedge CLEAR) begin
|
||||
if(CLEAR)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNC (negative clock edge; asynchronous clear)
|
||||
|
||||
|
||||
module DFFNCE (output reg Q, input D, CLK, CE, CLEAR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK or posedge CLEAR) begin
|
||||
if(CLEAR)
|
||||
Q <= 1'b0;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNCE (negative clock edge; asynchronous clear; clock enable)
|
||||
|
||||
// TODO add more DFF sim cells
|
||||
|
||||
module VCC(output V);
|
||||
assign V = 1;
|
||||
|
@ -65,14 +302,98 @@ module OBUF(output O, input I);
|
|||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module TBUF (O, I, OEN);
|
||||
input I, OEN;
|
||||
output O;
|
||||
assign O = OEN ? I : 1'bz;
|
||||
endmodule
|
||||
|
||||
module IOBUF (O, IO, I, OEN);
|
||||
input I,OEN;
|
||||
output O;
|
||||
inout IO;
|
||||
assign IO = OEN ? I : 1'bz;
|
||||
assign I = IO;
|
||||
endmodule
|
||||
|
||||
module GSR (input GSRI);
|
||||
wire GSRO = GSRI;
|
||||
endmodule
|
||||
|
||||
module ALU (input I0, input I1, input I3, input CIN, output COUT, output SUM);
|
||||
parameter [3:0] ALU_MODE = 0; // default 0 = ADD
|
||||
assign {COUT, SUM} = CIN + I1 + I0;
|
||||
endmodule // alu
|
||||
module ALU (SUM, COUT, I0, I1, I3, CIN);
|
||||
|
||||
input I0;
|
||||
input I1;
|
||||
input I3;
|
||||
input CIN;
|
||||
output SUM;
|
||||
output COUT;
|
||||
|
||||
localparam ADD = 0;
|
||||
localparam SUB = 1;
|
||||
localparam ADDSUB = 2;
|
||||
localparam NE = 3;
|
||||
localparam GE = 4;
|
||||
localparam LE = 5;
|
||||
localparam CUP = 6;
|
||||
localparam CDN = 7;
|
||||
localparam CUPCDN = 8;
|
||||
localparam MULT = 9;
|
||||
|
||||
parameter ALU_MODE = 0;
|
||||
|
||||
reg S, C;
|
||||
|
||||
assign SUM = S ^ CIN;
|
||||
assign COUT = S? CIN : C;
|
||||
|
||||
always @* begin
|
||||
case (ALU_MODE)
|
||||
ADD: begin
|
||||
S = I0 ^ I1;
|
||||
C = I0;
|
||||
end
|
||||
SUB: begin
|
||||
S = I0 ^ ~I1;
|
||||
C = I0;
|
||||
end
|
||||
ADDSUB: begin
|
||||
S = I3? I0 ^ I1 : I0 ^ ~I1;
|
||||
C = I0;
|
||||
end
|
||||
NE: begin
|
||||
S = I0 ^ ~I1;
|
||||
C = 1'b1;
|
||||
end
|
||||
GE: begin
|
||||
S = I0 ^ ~I1;
|
||||
C = I0;
|
||||
end
|
||||
LE: begin
|
||||
S = ~I0 ^ I1;
|
||||
C = I1;
|
||||
end
|
||||
CUP: begin
|
||||
S = I0;
|
||||
C = 1'b0;
|
||||
end
|
||||
CDN: begin
|
||||
S = ~I0;
|
||||
C = 1'b1;
|
||||
end
|
||||
CUPCDN: begin
|
||||
S = I3? I0 : ~I0;
|
||||
C = I0;
|
||||
end
|
||||
MULT: begin
|
||||
S = I0 & I1;
|
||||
C = I0 & I1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module RAM16S4 (DO, DI, AD, WRE, CLK);
|
||||
parameter WIDTH = 4;
|
||||
|
|
|
@ -64,6 +64,12 @@ struct SynthGowinPass : public ScriptPass
|
|||
log(" -retime\n");
|
||||
log(" run 'abc' with -dff option\n");
|
||||
log("\n");
|
||||
log(" -nowidelut\n");
|
||||
log(" do not use muxes to implement LUTs larger than LUT4s\n");
|
||||
log("\n");
|
||||
log(" -abc9\n");
|
||||
log(" use new ABC9 flow (EXPERIMENTAL)\n");
|
||||
log("\n");
|
||||
log("\n");
|
||||
log("The following commands are executed by this synthesis command:\n");
|
||||
help_script();
|
||||
|
@ -71,7 +77,7 @@ struct SynthGowinPass : public ScriptPass
|
|||
}
|
||||
|
||||
string top_opt, vout_file;
|
||||
bool retime, nobram, nodram, flatten, nodffe;
|
||||
bool retime, nobram, nodram, flatten, nodffe, nowidelut, abc9;
|
||||
|
||||
void clear_flags() YS_OVERRIDE
|
||||
{
|
||||
|
@ -82,6 +88,8 @@ struct SynthGowinPass : public ScriptPass
|
|||
nobram = false;
|
||||
nodffe = false;
|
||||
nodram = false;
|
||||
nowidelut = false;
|
||||
abc9 = false;
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
|
@ -128,6 +136,14 @@ struct SynthGowinPass : public ScriptPass
|
|||
flatten = false;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nowidelut") {
|
||||
nowidelut = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-abc9") {
|
||||
abc9 = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
@ -163,8 +179,8 @@ struct SynthGowinPass : public ScriptPass
|
|||
{
|
||||
run("synth -run coarse");
|
||||
}
|
||||
|
||||
if (!nobram && check_label("bram", "(skip if -nobram)"))
|
||||
|
||||
if (!nobram && check_label("bram", "(skip if -nobram)"))
|
||||
{
|
||||
run("memory_bram -rules +/gowin/bram.txt");
|
||||
run("techmap -map +/gowin/brams_map.v -map +/gowin/cells_sim.v");
|
||||
|
@ -186,6 +202,7 @@ struct SynthGowinPass : public ScriptPass
|
|||
run("techmap -map +/techmap.v");
|
||||
if (retime || help_mode)
|
||||
run("abc -dff", "(only if -retime)");
|
||||
run("splitnets");
|
||||
}
|
||||
|
||||
if (check_label("map_ffs"))
|
||||
|
@ -202,16 +219,25 @@ struct SynthGowinPass : public ScriptPass
|
|||
|
||||
if (check_label("map_luts"))
|
||||
{
|
||||
run("abc -lut 4");
|
||||
if (nowidelut && abc9) {
|
||||
run("abc9 -lut 4");
|
||||
} else if (nowidelut && !abc9) {
|
||||
run("abc -lut 4");
|
||||
} else if (!nowidelut && abc9) {
|
||||
run("abc9 -lut 4:8");
|
||||
} else if (!nowidelut && !abc9) {
|
||||
run("abc -lut 4:8");
|
||||
}
|
||||
run("clean");
|
||||
}
|
||||
|
||||
if (check_label("map_cells"))
|
||||
{
|
||||
run("techmap -map +/gowin/cells_map.v");
|
||||
run("hilomap -hicell VCC V -locell GND G");
|
||||
run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O", "(unless -noiopads)");
|
||||
run("dffinit -ff DFF Q INIT");
|
||||
run("setundef -undriven -params -zero");
|
||||
run("hilomap -singleton -hicell VCC V -locell GND G");
|
||||
run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O "
|
||||
"-toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO", "(unless -noiopads)");
|
||||
run("clean");
|
||||
|
||||
}
|
||||
|
@ -226,7 +252,7 @@ struct SynthGowinPass : public ScriptPass
|
|||
if (check_label("vout"))
|
||||
{
|
||||
if (!vout_file.empty() || help_mode)
|
||||
run(stringf("write_verilog -nodec -attr2comment -defparam -renameprefix gen %s",
|
||||
run(stringf("write_verilog -decimal -attr2comment -defparam -renameprefix gen %s",
|
||||
help_mode ? "<file-name>" : vout_file.c_str()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ EXTRA_OBJS += techlibs/ice40/brams_init.mk
|
|||
|
||||
techlibs/ice40/brams_init.mk: techlibs/ice40/brams_init.py
|
||||
$(Q) mkdir -p techlibs/ice40
|
||||
$(P) python3 $<
|
||||
$(P) $(PYTHON_EXECUTABLE) $<
|
||||
$(Q) touch techlibs/ice40/brams_init.mk
|
||||
|
||||
techlibs/ice40/brams_init1.vh: techlibs/ice40/brams_init.mk
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
`timescale 1ps / 1ps
|
||||
`define SB_DFF_REG reg Q = 0
|
||||
// `define SB_DFF_REG reg Q
|
||||
|
||||
|
@ -81,6 +81,37 @@ module SB_IO (
|
|||
if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
|
||||
endgenerate
|
||||
`endif
|
||||
`ifdef TIMING
|
||||
specify
|
||||
(INPUT_CLK => D_IN_0) = (0:0:0, 0:0:0);
|
||||
(INPUT_CLK => D_IN_1) = (0:0:0, 0:0:0);
|
||||
(PACKAGE_PIN => D_IN_0) = (0:0:0, 0:0:0);
|
||||
(OUTPUT_CLK => PACKAGE_PIN) = (0:0:0, 0:0:0);
|
||||
(D_OUT_0 => PACKAGE_PIN) = (0:0:0, 0:0:0);
|
||||
(OUTPUT_ENABLE => PACKAGE_PIN) = (0:0:0, 0:0:0);
|
||||
|
||||
$setuphold(posedge OUTPUT_CLK, posedge D_OUT_0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge OUTPUT_CLK, negedge D_OUT_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge OUTPUT_CLK, posedge D_OUT_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge OUTPUT_CLK, negedge D_OUT_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge OUTPUT_CLK, posedge D_OUT_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge OUTPUT_CLK, negedge D_OUT_0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge OUTPUT_CLK, posedge D_OUT_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge OUTPUT_CLK, negedge D_OUT_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge INPUT_CLK, posedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge INPUT_CLK, negedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge OUTPUT_CLK, posedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge OUTPUT_CLK, negedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge INPUT_CLK, posedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge INPUT_CLK, negedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge INPUT_CLK, posedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge INPUT_CLK, negedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge OUTPUT_CLK, posedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge OUTPUT_CLK, negedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge OUTPUT_CLK, posedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge OUTPUT_CLK, negedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
||||
endspecify
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
module SB_GB_IO (
|
||||
|
@ -127,6 +158,11 @@ module SB_GB (
|
|||
output GLOBAL_BUFFER_OUTPUT
|
||||
);
|
||||
assign GLOBAL_BUFFER_OUTPUT = USER_SIGNAL_TO_GLOBAL_BUFFER;
|
||||
`ifdef TIMING
|
||||
specify
|
||||
(USER_SIGNAL_TO_GLOBAL_BUFFER => GLOBAL_BUFFER_OUTPUT) = (0:0:0, 0:0:0);
|
||||
endspecify
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
// SiliconBlue Logic Cells
|
||||
|
@ -830,33 +866,81 @@ module ICESTORM_LC (
|
|||
parameter [0:0] CIN_CONST = 0;
|
||||
parameter [0:0] CIN_SET = 0;
|
||||
|
||||
wire I0_pd = (I0 === 1'bz) ? 1'b0 : I0;
|
||||
wire I1_pd = (I1 === 1'bz) ? 1'b0 : I1;
|
||||
wire I2_pd = (I2 === 1'bz) ? 1'b0 : I2;
|
||||
wire I3_pd = (I3 === 1'bz) ? 1'b0 : I3;
|
||||
wire SR_pd = (SR === 1'bz) ? 1'b0 : SR;
|
||||
wire CEN_pu = (CEN === 1'bz) ? 1'b1 : CEN;
|
||||
|
||||
wire mux_cin = CIN_CONST ? CIN_SET : CIN;
|
||||
|
||||
assign COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && mux_cin) : 1'bx;
|
||||
assign COUT = CARRY_ENABLE ? (I1_pd && I2_pd) || ((I1_pd || I2_pd) && mux_cin) : 1'bx;
|
||||
|
||||
wire [7:0] lut_s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
|
||||
wire [3:0] lut_s2 = I2 ? lut_s3[ 7:4] : lut_s3[3:0];
|
||||
wire [1:0] lut_s1 = I1 ? lut_s2[ 3:2] : lut_s2[1:0];
|
||||
wire lut_o = I0 ? lut_s1[ 1] : lut_s1[ 0];
|
||||
wire [7:0] lut_s3 = I3_pd ? LUT_INIT[15:8] : LUT_INIT[7:0];
|
||||
wire [3:0] lut_s2 = I2_pd ? lut_s3[ 7:4] : lut_s3[3:0];
|
||||
wire [1:0] lut_s1 = I1_pd ? lut_s2[ 3:2] : lut_s2[1:0];
|
||||
wire lut_o = I0_pd ? lut_s1[ 1] : lut_s1[ 0];
|
||||
|
||||
assign LO = lut_o;
|
||||
|
||||
wire polarized_clk;
|
||||
assign polarized_clk = CLK ^ NEG_CLK;
|
||||
|
||||
reg o_reg;
|
||||
reg o_reg = 1'b0;
|
||||
always @(posedge polarized_clk)
|
||||
if (CEN)
|
||||
o_reg <= SR ? SET_NORESET : lut_o;
|
||||
if (CEN_pu)
|
||||
o_reg <= SR_pd ? SET_NORESET : lut_o;
|
||||
|
||||
reg o_reg_async;
|
||||
reg o_reg_async = 1'b0;
|
||||
always @(posedge polarized_clk, posedge SR)
|
||||
if (SR)
|
||||
o_reg <= SET_NORESET;
|
||||
else if (CEN)
|
||||
o_reg <= lut_o;
|
||||
if (SR_pd)
|
||||
o_reg_async <= SET_NORESET;
|
||||
else if (CEN_pu)
|
||||
o_reg_async <= lut_o;
|
||||
|
||||
assign O = DFF_ENABLE ? ASYNC_SR ? o_reg_async : o_reg : lut_o;
|
||||
`ifdef TIMING
|
||||
specify
|
||||
(I0 => O) = (0:0:0, 0:0:0);
|
||||
(I1 => O) = (0:0:0, 0:0:0);
|
||||
(I2 => O) = (0:0:0, 0:0:0);
|
||||
(I3 => O) = (0:0:0, 0:0:0);
|
||||
(I0 => LO) = (0:0:0, 0:0:0);
|
||||
(I1 => LO) = (0:0:0, 0:0:0);
|
||||
(I2 => LO) = (0:0:0, 0:0:0);
|
||||
(I3 => LO) = (0:0:0, 0:0:0);
|
||||
(I1 => COUT) = (0:0:0, 0:0:0);
|
||||
(I2 => COUT) = (0:0:0, 0:0:0);
|
||||
(CIN => COUT) = (0:0:0, 0:0:0);
|
||||
(CLK => O) = (0:0:0, 0:0:0);
|
||||
(SR => O) = (0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, posedge I0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, negedge I0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, posedge I0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, negedge I0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, posedge I1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, negedge I1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, posedge I1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, negedge I1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, posedge I2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, negedge I2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, posedge I2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, negedge I2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, posedge I3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, negedge I3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, posedge I3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, negedge I3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, posedge CEN, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, negedge CEN, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, posedge CEN, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, negedge CEN, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, posedge SR, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge CLK, negedge SR, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, posedge SR, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge CLK, negedge SR, 0:0:0, 0:0:0);
|
||||
endspecify
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
// SiliconBlue PLL Cells
|
||||
|
@ -1576,3 +1660,341 @@ module SB_MAC16 (
|
|||
assign LCI = (BOTADDSUB_CARRYSELECT == 0) ? 1'b0 : (BOTADDSUB_CARRYSELECT == 1) ? 1'b1 : (BOTADDSUB_CARRYSELECT == 2) ? ACCUMCI : CI;
|
||||
assign O = {Oh, Ol};
|
||||
endmodule
|
||||
|
||||
// Post-place-and-route RAM model
|
||||
module ICESTORM_RAM(
|
||||
output RDATA_15, RDATA_14, RDATA_13, RDATA_12, RDATA_11, RDATA_10, RDATA_9, RDATA_8, RDATA_7, RDATA_6, RDATA_5, RDATA_4, RDATA_3, RDATA_2, RDATA_1, RDATA_0,
|
||||
input RCLK, RCLKE, RE,
|
||||
input RADDR_10, RADDR_9, RADDR_8, RADDR_7, RADDR_6, RADDR_5, RADDR_4, RADDR_3, RADDR_2, RADDR_1, RADDR_0,
|
||||
input WCLK, WCLKE, WE,
|
||||
input WADDR_10, WADDR_9, WADDR_8, WADDR_7, WADDR_6, WADDR_5, WADDR_4, WADDR_3, WADDR_2, WADDR_1, WADDR_0,
|
||||
input MASK_15, MASK_14, MASK_13, MASK_12, MASK_11, MASK_10, MASK_9, MASK_8, MASK_7, MASK_6, MASK_5, MASK_4, MASK_3, MASK_2, MASK_1, MASK_0,
|
||||
input WDATA_15, WDATA_14, WDATA_13, WDATA_12, WDATA_11, WDATA_10, WDATA_9, WDATA_8, WDATA_7, WDATA_6, WDATA_5, WDATA_4, WDATA_3, WDATA_2, WDATA_1, WDATA_0
|
||||
);
|
||||
parameter WRITE_MODE = 0;
|
||||
parameter READ_MODE = 0;
|
||||
|
||||
parameter NEG_CLK_R = 1'b0;
|
||||
parameter NEG_CLK_W = 1'b0;
|
||||
|
||||
parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
// Pull-down and pull-up functions
|
||||
function pd;
|
||||
input x;
|
||||
begin
|
||||
pd = (x === 1'bz) ? 1'b0 : x;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function pu;
|
||||
input x;
|
||||
begin
|
||||
pu = (x === 1'bz) ? 1'b1 : x;
|
||||
end
|
||||
endfunction
|
||||
|
||||
SB_RAM40_4K #(
|
||||
.WRITE_MODE(WRITE_MODE),
|
||||
.READ_MODE (READ_MODE ),
|
||||
.INIT_0 (INIT_0 ),
|
||||
.INIT_1 (INIT_1 ),
|
||||
.INIT_2 (INIT_2 ),
|
||||
.INIT_3 (INIT_3 ),
|
||||
.INIT_4 (INIT_4 ),
|
||||
.INIT_5 (INIT_5 ),
|
||||
.INIT_6 (INIT_6 ),
|
||||
.INIT_7 (INIT_7 ),
|
||||
.INIT_8 (INIT_8 ),
|
||||
.INIT_9 (INIT_9 ),
|
||||
.INIT_A (INIT_A ),
|
||||
.INIT_B (INIT_B ),
|
||||
.INIT_C (INIT_C ),
|
||||
.INIT_D (INIT_D ),
|
||||
.INIT_E (INIT_E ),
|
||||
.INIT_F (INIT_F )
|
||||
) RAM (
|
||||
.RDATA({RDATA_15, RDATA_14, RDATA_13, RDATA_12, RDATA_11, RDATA_10, RDATA_9, RDATA_8, RDATA_7, RDATA_6, RDATA_5, RDATA_4, RDATA_3, RDATA_2, RDATA_1, RDATA_0}),
|
||||
.RCLK (pd(RCLK) ^ NEG_CLK_R),
|
||||
.RCLKE(pu(RCLKE)),
|
||||
.RE (pd(RE)),
|
||||
.RADDR({pd(RADDR_10), pd(RADDR_9), pd(RADDR_8), pd(RADDR_7), pd(RADDR_6), pd(RADDR_5), pd(RADDR_4), pd(RADDR_3), pd(RADDR_2), pd(RADDR_1), pd(RADDR_0)}),
|
||||
.WCLK (pd(WCLK) ^ NEG_CLK_W),
|
||||
.WCLKE(pu(WCLKE)),
|
||||
.WE (pd(WE)),
|
||||
.WADDR({pd(WADDR_10), pd(WADDR_9), pd(WADDR_8), pd(WADDR_7), pd(WADDR_6), pd(WADDR_5), pd(WADDR_4), pd(WADDR_3), pd(WADDR_2), pd(WADDR_1), pd(WADDR_0)}),
|
||||
.MASK ({pd(MASK_15), pd(MASK_14), pd(MASK_13), pd(MASK_12), pd(MASK_11), pd(MASK_10), pd(MASK_9), pd(MASK_8),
|
||||
pd(MASK_7), pd(MASK_6), pd(MASK_5), pd(MASK_4), pd(MASK_3), pd(MASK_2), pd(MASK_1), pd(MASK_0)}),
|
||||
.WDATA({pd(WDATA_15), pd(WDATA_14), pd(WDATA_13), pd(WDATA_12), pd(WDATA_11), pd(WDATA_10), pd(WDATA_9), pd(WDATA_8),
|
||||
pd(WDATA_7), pd(WDATA_6), pd(WDATA_5), pd(WDATA_4), pd(WDATA_3), pd(WDATA_2), pd(WDATA_1), pd(WDATA_0)})
|
||||
);
|
||||
|
||||
`ifdef TIMING
|
||||
specify
|
||||
(RCLK => RDATA_15) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_14) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_13) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_12) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_11) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_10) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_9) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_8) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_7) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_6) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_5) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_4) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_3) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_2) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_1) = (0:0:0, 0:0:0);
|
||||
(RCLK => RDATA_0) = (0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RCLKE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RCLKE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RCLKE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RCLKE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_10, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_10, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_10, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_10, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_9, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_9, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_9, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_9, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_8, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_8, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_8, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_8, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_7, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_7, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_7, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_7, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_6, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_6, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_6, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_6, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_5, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_5, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_5, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_5, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_4, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_4, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_4, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_4, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, posedge RADDR_0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge RCLK, negedge RADDR_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, posedge RADDR_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge RCLK, negedge RADDR_0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WCLKE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WCLKE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WCLKE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WCLKE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WE, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WE, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_10, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_10, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_10, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_10, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_9, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_9, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_9, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_9, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_8, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_8, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_8, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_8, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_7, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_7, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_7, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_7, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_6, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_6, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_6, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_6, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_5, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_5, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_5, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_5, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_4, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_4, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_4, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_4, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WADDR_0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WADDR_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WADDR_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WADDR_0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_15, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_15, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_15, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_15, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_14, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_14, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_14, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_14, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_13, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_13, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_13, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_13, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_12, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_12, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_12, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_12, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_11, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_11, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_11, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_11, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_10, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_10, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_10, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_10, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_9, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_9, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_9, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_9, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_8, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_8, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_8, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_8, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_7, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_7, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_7, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_7, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_6, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_6, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_6, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_6, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_5, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_5, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_5, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_5, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_4, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_4, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_4, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_4, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge MASK_0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge MASK_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge MASK_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge MASK_0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_15, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_15, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_15, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_15, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_14, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_14, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_14, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_14, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_13, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_13, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_13, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_13, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_12, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_12, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_12, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_12, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_11, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_11, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_11, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_11, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_10, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_10, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_10, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_10, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_9, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_9, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_9, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_9, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_8, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_8, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_8, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_8, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_7, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_7, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_7, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_7, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_6, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_6, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_6, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_6, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_5, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_5, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_5, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_5, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_4, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_4, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_4, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_4, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_3, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_3, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_2, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_2, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_1, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_1, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, posedge WDATA_0, 0:0:0, 0:0:0);
|
||||
$setuphold(posedge WCLK, negedge WDATA_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, posedge WDATA_0, 0:0:0, 0:0:0);
|
||||
$setuphold(negedge WCLK, negedge WDATA_0, 0:0:0, 0:0:0);
|
||||
|
||||
endspecify
|
||||
`endif
|
||||
endmodule
|
||||
|
|
|
@ -273,6 +273,7 @@ struct SynthIce40Pass : public ScriptPass
|
|||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
if (help_mode || dsp) {
|
||||
run("memory_dff");
|
||||
run("techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 "
|
||||
"-D DSP_NAME=$__MUL16X16", "(if -dsp)");
|
||||
|
@ -379,6 +380,7 @@ struct SynthIce40Pass : public ScriptPass
|
|||
|
||||
if (check_label("check"))
|
||||
{
|
||||
run("autoname");
|
||||
run("hierarchy -check");
|
||||
run("stat");
|
||||
run("check -noinit");
|
||||
|
|
|
@ -13,7 +13,7 @@ EXTRA_OBJS += techlibs/xilinx/brams_init.mk
|
|||
|
||||
techlibs/xilinx/brams_init.mk: techlibs/xilinx/brams_init.py
|
||||
$(Q) mkdir -p techlibs/xilinx
|
||||
$(P) python3 $<
|
||||
$(P) $(PYTHON_EXECUTABLE) $<
|
||||
$(Q) touch $@
|
||||
|
||||
techlibs/xilinx/brams_init_36.vh: techlibs/xilinx/brams_init.mk
|
||||
|
@ -25,16 +25,14 @@ techlibs/xilinx/brams_init_8.vh: techlibs/xilinx/brams_init.mk
|
|||
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6v_cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams.txt))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_bb.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams.txt))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_xcu_brams.txt))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_bb.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_brams_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams.txt))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams.txt))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
|
||||
|
@ -42,7 +40,13 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_ff_map.v))
|
|||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_ff_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3s_mult_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3sda_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc4v_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc5v_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_dsp_map.v))
|
||||
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_unmap.v))
|
||||
|
|
|
@ -38,6 +38,17 @@ module IBUF(
|
|||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module IBUFG(
|
||||
output O,
|
||||
(* iopad_external_pin *)
|
||||
input I);
|
||||
parameter CAPACITANCE = "DONT_CARE";
|
||||
parameter IBUF_DELAY_VALUE = "0";
|
||||
parameter IBUF_LOW_PWR = "TRUE";
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module OBUF(
|
||||
(* iopad_external_pin *)
|
||||
output O,
|
||||
|
@ -578,6 +589,515 @@ module SRLC32E (
|
|||
endgenerate
|
||||
endmodule
|
||||
|
||||
// DSP
|
||||
|
||||
// Virtex 2, Virtex 2 Pro, Spartan 3.
|
||||
|
||||
// Asynchronous mode.
|
||||
|
||||
module MULT18X18 (
|
||||
input signed [17:0] A,
|
||||
input signed [17:0] B,
|
||||
output signed [35:0] P
|
||||
);
|
||||
|
||||
assign P = A * B;
|
||||
|
||||
endmodule
|
||||
|
||||
// Synchronous mode.
|
||||
|
||||
module MULT18X18S (
|
||||
input signed [17:0] A,
|
||||
input signed [17:0] B,
|
||||
output reg signed [35:0] P,
|
||||
(* clkbuf_sink *)
|
||||
input C,
|
||||
input CE,
|
||||
input R
|
||||
);
|
||||
|
||||
always @(posedge C)
|
||||
if (R)
|
||||
P <= 0;
|
||||
else if (CE)
|
||||
P <= A * B;
|
||||
|
||||
endmodule
|
||||
|
||||
// Spartan 3E, Spartan 3A.
|
||||
|
||||
module MULT18X18SIO (
|
||||
input signed [17:0] A,
|
||||
input signed [17:0] B,
|
||||
output signed [35:0] P,
|
||||
(* clkbuf_sink *)
|
||||
input CLK,
|
||||
input CEA,
|
||||
input CEB,
|
||||
input CEP,
|
||||
input RSTA,
|
||||
input RSTB,
|
||||
input RSTP,
|
||||
input signed [17:0] BCIN,
|
||||
output signed [17:0] BCOUT
|
||||
);
|
||||
|
||||
parameter integer AREG = 1;
|
||||
parameter integer BREG = 1;
|
||||
parameter B_INPUT = "DIRECT";
|
||||
parameter integer PREG = 1;
|
||||
|
||||
// The multiplier.
|
||||
wire signed [35:0] P_MULT;
|
||||
assign P_MULT = A_MULT * B_MULT;
|
||||
|
||||
// The cascade output.
|
||||
assign BCOUT = B_MULT;
|
||||
|
||||
// The B input multiplexer.
|
||||
wire signed [17:0] B_MUX;
|
||||
assign B_MUX = (B_INPUT == "DIRECT") ? B : BCIN;
|
||||
|
||||
// The registers.
|
||||
reg signed [17:0] A_REG;
|
||||
reg signed [17:0] B_REG;
|
||||
reg signed [35:0] P_REG;
|
||||
|
||||
initial begin
|
||||
A_REG = 0;
|
||||
B_REG = 0;
|
||||
P_REG = 0;
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if (RSTA)
|
||||
A_REG <= 0;
|
||||
else if (CEA)
|
||||
A_REG <= A;
|
||||
|
||||
if (RSTB)
|
||||
B_REG <= 0;
|
||||
else if (CEB)
|
||||
B_REG <= B_MUX;
|
||||
|
||||
if (RSTP)
|
||||
P_REG <= 0;
|
||||
else if (CEP)
|
||||
P_REG <= P_MULT;
|
||||
end
|
||||
|
||||
// The register enables.
|
||||
wire signed [17:0] A_MULT;
|
||||
wire signed [17:0] B_MULT;
|
||||
assign A_MULT = (AREG == 1) ? A_REG : A;
|
||||
assign B_MULT = (BREG == 1) ? B_REG : B_MUX;
|
||||
assign P = (PREG == 1) ? P_REG : P_MULT;
|
||||
|
||||
endmodule
|
||||
|
||||
// Spartan 3A DSP.
|
||||
|
||||
module DSP48A (
|
||||
input signed [17:0] A,
|
||||
input signed [17:0] B,
|
||||
input signed [47:0] C,
|
||||
input signed [17:0] D,
|
||||
input signed [47:0] PCIN,
|
||||
input CARRYIN,
|
||||
input [7:0] OPMODE,
|
||||
output signed [47:0] P,
|
||||
output signed [17:0] BCOUT,
|
||||
output signed [47:0] PCOUT,
|
||||
output CARRYOUT,
|
||||
(* clkbuf_sink *)
|
||||
input CLK,
|
||||
input CEA,
|
||||
input CEB,
|
||||
input CEC,
|
||||
input CED,
|
||||
input CEM,
|
||||
input CECARRYIN,
|
||||
input CEOPMODE,
|
||||
input CEP,
|
||||
input RSTA,
|
||||
input RSTB,
|
||||
input RSTC,
|
||||
input RSTD,
|
||||
input RSTM,
|
||||
input RSTCARRYIN,
|
||||
input RSTOPMODE,
|
||||
input RSTP
|
||||
);
|
||||
|
||||
parameter integer A0REG = 0;
|
||||
parameter integer A1REG = 1;
|
||||
parameter integer B0REG = 0;
|
||||
parameter integer B1REG = 1;
|
||||
parameter integer CREG = 1;
|
||||
parameter integer DREG = 1;
|
||||
parameter integer MREG = 1;
|
||||
parameter integer CARRYINREG = 1;
|
||||
parameter integer OPMODEREG = 1;
|
||||
parameter integer PREG = 1;
|
||||
parameter CARRYINSEL = "CARRYIN";
|
||||
parameter RSTTYPE = "SYNC";
|
||||
|
||||
// This is a strict subset of Spartan 6 -- reuse its model.
|
||||
|
||||
DSP48A1 #(
|
||||
.A0REG(A0REG),
|
||||
.A1REG(A1REG),
|
||||
.B0REG(B0REG),
|
||||
.B1REG(B1REG),
|
||||
.CREG(CREG),
|
||||
.DREG(DREG),
|
||||
.MREG(MREG),
|
||||
.CARRYINREG(CARRYINREG),
|
||||
.CARRYOUTREG(0),
|
||||
.OPMODEREG(OPMODEREG),
|
||||
.PREG(PREG),
|
||||
.CARRYINSEL(CARRYINSEL),
|
||||
.RSTTYPE(RSTTYPE)
|
||||
) upgrade (
|
||||
.A(A),
|
||||
.B(B),
|
||||
.C(C),
|
||||
.D(D),
|
||||
.PCIN(PCIN),
|
||||
.CARRYIN(CARRYIN),
|
||||
.OPMODE(OPMODE),
|
||||
// M unconnected
|
||||
.P(P),
|
||||
.BCOUT(BCOUT),
|
||||
.PCOUT(PCOUT),
|
||||
.CARRYOUT(CARRYOUT),
|
||||
// CARRYOUTF unconnected
|
||||
.CLK(CLK),
|
||||
.CEA(CEA),
|
||||
.CEB(CEB),
|
||||
.CEC(CEC),
|
||||
.CED(CED),
|
||||
.CEM(CEM),
|
||||
.CECARRYIN(CECARRYIN),
|
||||
.CEOPMODE(CEOPMODE),
|
||||
.CEP(CEP),
|
||||
.RSTA(RSTA),
|
||||
.RSTB(RSTB),
|
||||
.RSTC(RSTC),
|
||||
.RSTD(RSTD),
|
||||
.RSTM(RSTM),
|
||||
.RSTCARRYIN(RSTCARRYIN),
|
||||
.RSTOPMODE(RSTOPMODE),
|
||||
.RSTP(RSTP)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
// Spartan 6.
|
||||
|
||||
module DSP48A1 (
|
||||
input signed [17:0] A,
|
||||
input signed [17:0] B,
|
||||
input signed [47:0] C,
|
||||
input signed [17:0] D,
|
||||
input signed [47:0] PCIN,
|
||||
input CARRYIN,
|
||||
input [7:0] OPMODE,
|
||||
output signed [35:0] M,
|
||||
output signed [47:0] P,
|
||||
output signed [17:0] BCOUT,
|
||||
output signed [47:0] PCOUT,
|
||||
output CARRYOUT,
|
||||
output CARRYOUTF,
|
||||
(* clkbuf_sink *)
|
||||
input CLK,
|
||||
input CEA,
|
||||
input CEB,
|
||||
input CEC,
|
||||
input CED,
|
||||
input CEM,
|
||||
input CECARRYIN,
|
||||
input CEOPMODE,
|
||||
input CEP,
|
||||
input RSTA,
|
||||
input RSTB,
|
||||
input RSTC,
|
||||
input RSTD,
|
||||
input RSTM,
|
||||
input RSTCARRYIN,
|
||||
input RSTOPMODE,
|
||||
input RSTP
|
||||
);
|
||||
|
||||
parameter integer A0REG = 0;
|
||||
parameter integer A1REG = 1;
|
||||
parameter integer B0REG = 0;
|
||||
parameter integer B1REG = 1;
|
||||
parameter integer CREG = 1;
|
||||
parameter integer DREG = 1;
|
||||
parameter integer MREG = 1;
|
||||
parameter integer CARRYINREG = 1;
|
||||
parameter integer CARRYOUTREG = 1;
|
||||
parameter integer OPMODEREG = 1;
|
||||
parameter integer PREG = 1;
|
||||
parameter CARRYINSEL = "OPMODE5";
|
||||
parameter RSTTYPE = "SYNC";
|
||||
|
||||
wire signed [35:0] M_MULT;
|
||||
wire signed [47:0] P_IN;
|
||||
wire signed [17:0] A0_OUT;
|
||||
wire signed [17:0] B0_OUT;
|
||||
wire signed [17:0] A1_OUT;
|
||||
wire signed [17:0] B1_OUT;
|
||||
wire signed [17:0] B1_IN;
|
||||
wire signed [47:0] C_OUT;
|
||||
wire signed [17:0] D_OUT;
|
||||
wire signed [7:0] OPMODE_OUT;
|
||||
wire CARRYIN_OUT;
|
||||
wire CARRYOUT_IN;
|
||||
wire CARRYIN_IN;
|
||||
reg signed [47:0] XMUX;
|
||||
reg signed [47:0] ZMUX;
|
||||
|
||||
// The registers.
|
||||
reg signed [17:0] A0_REG;
|
||||
reg signed [17:0] A1_REG;
|
||||
reg signed [17:0] B0_REG;
|
||||
reg signed [17:0] B1_REG;
|
||||
reg signed [47:0] C_REG;
|
||||
reg signed [17:0] D_REG;
|
||||
reg signed [35:0] M_REG;
|
||||
reg signed [47:0] P_REG;
|
||||
reg [7:0] OPMODE_REG;
|
||||
reg CARRYIN_REG;
|
||||
reg CARRYOUT_REG;
|
||||
|
||||
initial begin
|
||||
A0_REG = 0;
|
||||
A1_REG = 0;
|
||||
B0_REG = 0;
|
||||
B1_REG = 0;
|
||||
C_REG = 0;
|
||||
D_REG = 0;
|
||||
M_REG = 0;
|
||||
P_REG = 0;
|
||||
OPMODE_REG = 0;
|
||||
CARRYIN_REG = 0;
|
||||
CARRYOUT_REG = 0;
|
||||
end
|
||||
|
||||
generate
|
||||
|
||||
if (RSTTYPE == "SYNC") begin
|
||||
always @(posedge CLK) begin
|
||||
if (RSTA) begin
|
||||
A0_REG <= 0;
|
||||
A1_REG <= 0;
|
||||
end else if (CEA) begin
|
||||
A0_REG <= A;
|
||||
A1_REG <= A0_OUT;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if (RSTB) begin
|
||||
B0_REG <= 0;
|
||||
B1_REG <= 0;
|
||||
end else if (CEB) begin
|
||||
B0_REG <= B;
|
||||
B1_REG <= B1_IN;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if (RSTC) begin
|
||||
C_REG <= 0;
|
||||
end else if (CEC) begin
|
||||
C_REG <= C;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if (RSTD) begin
|
||||
D_REG <= 0;
|
||||
end else if (CED) begin
|
||||
D_REG <= D;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if (RSTM) begin
|
||||
M_REG <= 0;
|
||||
end else if (CEM) begin
|
||||
M_REG <= M_MULT;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if (RSTP) begin
|
||||
P_REG <= 0;
|
||||
end else if (CEP) begin
|
||||
P_REG <= P_IN;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if (RSTOPMODE) begin
|
||||
OPMODE_REG <= 0;
|
||||
end else if (CEOPMODE) begin
|
||||
OPMODE_REG <= OPMODE;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if (RSTCARRYIN) begin
|
||||
CARRYIN_REG <= 0;
|
||||
CARRYOUT_REG <= 0;
|
||||
end else if (CECARRYIN) begin
|
||||
CARRYIN_REG <= CARRYIN_IN;
|
||||
CARRYOUT_REG <= CARRYOUT_IN;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
always @(posedge CLK, posedge RSTA) begin
|
||||
if (RSTA) begin
|
||||
A0_REG <= 0;
|
||||
A1_REG <= 0;
|
||||
end else if (CEA) begin
|
||||
A0_REG <= A;
|
||||
A1_REG <= A0_OUT;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK, posedge RSTB) begin
|
||||
if (RSTB) begin
|
||||
B0_REG <= 0;
|
||||
B1_REG <= 0;
|
||||
end else if (CEB) begin
|
||||
B0_REG <= B;
|
||||
B1_REG <= B1_IN;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK, posedge RSTC) begin
|
||||
if (RSTC) begin
|
||||
C_REG <= 0;
|
||||
end else if (CEC) begin
|
||||
C_REG <= C;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK, posedge RSTD) begin
|
||||
if (RSTD) begin
|
||||
D_REG <= 0;
|
||||
end else if (CED) begin
|
||||
D_REG <= D;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK, posedge RSTM) begin
|
||||
if (RSTM) begin
|
||||
M_REG <= 0;
|
||||
end else if (CEM) begin
|
||||
M_REG <= M_MULT;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK, posedge RSTP) begin
|
||||
if (RSTP) begin
|
||||
P_REG <= 0;
|
||||
end else if (CEP) begin
|
||||
P_REG <= P_IN;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK, posedge RSTOPMODE) begin
|
||||
if (RSTOPMODE) begin
|
||||
OPMODE_REG <= 0;
|
||||
end else if (CEOPMODE) begin
|
||||
OPMODE_REG <= OPMODE;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge CLK, posedge RSTCARRYIN) begin
|
||||
if (RSTCARRYIN) begin
|
||||
CARRYIN_REG <= 0;
|
||||
CARRYOUT_REG <= 0;
|
||||
end else if (CECARRYIN) begin
|
||||
CARRYIN_REG <= CARRYIN_IN;
|
||||
CARRYOUT_REG <= CARRYOUT_IN;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
// The register enables.
|
||||
assign A0_OUT = (A0REG == 1) ? A0_REG : A;
|
||||
assign A1_OUT = (A1REG == 1) ? A1_REG : A0_OUT;
|
||||
assign B0_OUT = (B0REG == 1) ? B0_REG : B;
|
||||
assign B1_OUT = (B1REG == 1) ? B1_REG : B1_IN;
|
||||
assign C_OUT = (CREG == 1) ? C_REG : C;
|
||||
assign D_OUT = (DREG == 1) ? D_REG : D;
|
||||
assign M = (MREG == 1) ? M_REG : M_MULT;
|
||||
assign P = (PREG == 1) ? P_REG : P_IN;
|
||||
assign OPMODE_OUT = (OPMODEREG == 1) ? OPMODE_REG : OPMODE;
|
||||
assign CARRYIN_OUT = (CARRYINREG == 1) ? CARRYIN_REG : CARRYIN_IN;
|
||||
assign CARRYOUT = (CARRYOUTREG == 1) ? CARRYOUT_REG : CARRYOUT_IN;
|
||||
assign CARRYOUTF = CARRYOUT;
|
||||
|
||||
// The pre-adder.
|
||||
wire signed [17:0] PREADDER;
|
||||
assign B1_IN = OPMODE_OUT[4] ? PREADDER : B0_OUT;
|
||||
assign PREADDER = OPMODE_OUT[6] ? D_OUT - B0_OUT : D_OUT + B0_OUT;
|
||||
|
||||
// The multiplier.
|
||||
assign M_MULT = A1_OUT * B1_OUT;
|
||||
|
||||
// The carry in selection.
|
||||
assign CARRYIN_IN = (CARRYINSEL == "OPMODE5") ? OPMODE_OUT[5] : CARRYIN;
|
||||
|
||||
// The post-adder inputs.
|
||||
always @* begin
|
||||
case (OPMODE_OUT[1:0])
|
||||
2'b00: XMUX <= 0;
|
||||
2'b01: XMUX <= M;
|
||||
2'b10: XMUX <= P;
|
||||
2'b11: XMUX <= {D_OUT[11:0], B1_OUT, A1_OUT};
|
||||
default: XMUX <= 48'hxxxxxxxxxxxx;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @* begin
|
||||
case (OPMODE_OUT[3:2])
|
||||
2'b00: ZMUX <= 0;
|
||||
2'b01: ZMUX <= PCIN;
|
||||
2'b10: ZMUX <= P;
|
||||
2'b11: ZMUX <= C_OUT;
|
||||
default: ZMUX <= 48'hxxxxxxxxxxxx;
|
||||
endcase
|
||||
end
|
||||
|
||||
// The post-adder.
|
||||
wire signed [48:0] X_EXT;
|
||||
wire signed [48:0] Z_EXT;
|
||||
assign X_EXT = XMUX;
|
||||
assign Z_EXT = ZMUX;
|
||||
assign {CARRYOUT_IN, P_IN} = OPMODE_OUT[7] ? (Z_EXT - (X_EXT + CARRYIN_OUT)) : (Z_EXT + X_EXT + CARRYIN_OUT);
|
||||
|
||||
// Cascade outputs.
|
||||
assign BCOUT = B1_OUT;
|
||||
assign PCOUT = P;
|
||||
|
||||
endmodule
|
||||
|
||||
// TODO: DSP48 (Virtex 4).
|
||||
|
||||
// TODO: DSP48E (Virtex 5).
|
||||
|
||||
// Virtex 6, Series 7.
|
||||
|
||||
module DSP48E1 (
|
||||
output [29:0] ACOUT,
|
||||
output [17:0] BCOUT,
|
||||
|
@ -1040,3 +1560,5 @@ module DSP48E1 (
|
|||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
// TODO: DSP48E2 (Ultrascale).
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -46,7 +46,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
log(" -top <module>\n");
|
||||
log(" use the specified module as top module\n");
|
||||
log("\n");
|
||||
log(" -family {xcup|xcu|xc7|xc6v|xc6s}\n");
|
||||
log(" -family {xcup|xcu|xc7|xc6v|xc5v|xc6s}\n");
|
||||
log(" run synthesis for the specified Xilinx architecture\n");
|
||||
log(" generate the synthesis netlist for the specified family.\n");
|
||||
log(" default: xc7\n");
|
||||
|
@ -93,6 +93,9 @@ struct SynthXilinxPass : public ScriptPass
|
|||
log(" -noclkbuf\n");
|
||||
log(" disable automatic clock buffer insertion\n");
|
||||
log("\n");
|
||||
log(" -uram\n");
|
||||
log(" infer URAM288s for large memories (xcup only)\n");
|
||||
log("\n");
|
||||
log(" -widemux <int>\n");
|
||||
log(" enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n");
|
||||
log(" above this number of inputs (minimum value 2, recommended value >= 5).\n");
|
||||
|
@ -119,7 +122,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
}
|
||||
|
||||
std::string top_opt, edif_file, blif_file, family;
|
||||
bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, abc9;
|
||||
bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram, abc9;
|
||||
bool flatten_before_abc;
|
||||
int widemux;
|
||||
|
||||
|
@ -143,6 +146,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
nocarry = false;
|
||||
nowidelut = false;
|
||||
nodsp = false;
|
||||
uram = false;
|
||||
abc9 = false;
|
||||
flatten_before_abc = false;
|
||||
widemux = 0;
|
||||
|
@ -248,11 +252,15 @@ struct SynthXilinxPass : public ScriptPass
|
|||
nodsp = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-uram") {
|
||||
uram = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6v" && family != "xc6s")
|
||||
if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6v" && family != "xc5v" && family != "xc6s")
|
||||
log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str());
|
||||
|
||||
if (widemux != 0 && widemux < 2)
|
||||
|
@ -289,24 +297,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
read_args += " -lib +/xilinx/cells_sim.v";
|
||||
run("read_verilog" + read_args);
|
||||
|
||||
if (help_mode)
|
||||
run("read_verilog -lib +/xilinx/{family}_cells_xtra.v");
|
||||
else if (family == "xc6s")
|
||||
run("read_verilog -lib +/xilinx/xc6s_cells_xtra.v");
|
||||
else if (family == "xc6v")
|
||||
run("read_verilog -lib +/xilinx/xc6v_cells_xtra.v");
|
||||
else if (family == "xc7")
|
||||
run("read_verilog -lib +/xilinx/xc7_cells_xtra.v");
|
||||
else if (family == "xcu" || family == "xcup")
|
||||
run("read_verilog -lib +/xilinx/xcu_cells_xtra.v");
|
||||
|
||||
if (help_mode) {
|
||||
run("read_verilog -lib +/xilinx/{family}_brams_bb.v");
|
||||
} else if (family == "xc6s") {
|
||||
run("read_verilog -lib +/xilinx/xc6s_brams_bb.v");
|
||||
} else if (family == "xc6v" || family == "xc7") {
|
||||
run("read_verilog -lib +/xilinx/xc7_brams_bb.v");
|
||||
}
|
||||
run("read_verilog -lib +/xilinx/cells_xtra.v");
|
||||
|
||||
run(stringf("hierarchy -check %s", top_opt.c_str()));
|
||||
}
|
||||
|
@ -342,15 +333,53 @@ struct SynthXilinxPass : public ScriptPass
|
|||
|
||||
if (check_label("map_dsp", "(skip if '-nodsp')")) {
|
||||
if (!nodsp || help_mode) {
|
||||
run("memory_dff"); // xilinx_dsp will merge registers, reserve memory port registers first
|
||||
// NB: Xilinx multipliers are signed only
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/dsp_map.v -D DSP_A_MAXWIDTH=25 "
|
||||
"-D DSP_A_MAXWIDTH_PARTIAL=18 -D DSP_B_MAXWIDTH=18 " // Partial multipliers are intentionally
|
||||
// limited to 18x18 in order to take
|
||||
// advantage of the (PCOUT << 17) -> PCIN
|
||||
// dedicated cascade chain capability
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||
if (help_mode)
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/{family}_dsp_map.v {options}");
|
||||
else if (family == "xc2v" || family == "xc3s" || family == "xc3se" || family == "xc3sa")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc3s_mult_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||
else if (family == "xc3sda")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc3sda_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||
else if (family == "xc6s")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc6s_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||
else if (family == "xc4v")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc4v_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||
else if (family == "xc5v")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc5v_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||
else if (family == "xc6v" || family == "xc7")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc7_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
|
||||
// limited to 18x18 in order to take
|
||||
// advantage of the (PCOUT << 17) -> PCIN
|
||||
// dedicated cascade chain capability
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||
else if (family == "xcu" || family == "xcup")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xcu_dsp_map.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
|
||||
// limited to 18x18 in order to take
|
||||
// advantage of the (PCOUT << 17) -> PCIN
|
||||
// dedicated cascade chain capability
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL27X18");
|
||||
run("select a:mul2dsp");
|
||||
run("setattr -unset mul2dsp");
|
||||
run("opt_expr -fine");
|
||||
|
@ -371,6 +400,20 @@ struct SynthXilinxPass : public ScriptPass
|
|||
run("opt_clean");
|
||||
}
|
||||
|
||||
if (check_label("map_uram", "(only if '-uram')")) {
|
||||
if (help_mode) {
|
||||
run("memory_bram -rules +/xilinx/{family}_urams.txt");
|
||||
run("techmap -map +/xilinx/{family}_urams_map.v");
|
||||
} else if (uram) {
|
||||
if (family == "xcup") {
|
||||
run("memory_bram -rules +/xilinx/xcup_urams.txt");
|
||||
run("techmap -map +/xilinx/xcup_urams_map.v");
|
||||
} else {
|
||||
log_warning("UltraRAM inference not supported for family %s.\n", family.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (check_label("map_bram", "(skip if '-nobram')")) {
|
||||
if (help_mode) {
|
||||
run("memory_bram -rules +/xilinx/{family}_brams.txt");
|
||||
|
@ -380,8 +423,11 @@ struct SynthXilinxPass : public ScriptPass
|
|||
run("memory_bram -rules +/xilinx/xc6s_brams.txt");
|
||||
run("techmap -map +/xilinx/xc6s_brams_map.v");
|
||||
} else if (family == "xc6v" || family == "xc7") {
|
||||
run("memory_bram -rules +/xilinx/xc7_brams.txt");
|
||||
run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
|
||||
run("techmap -map +/xilinx/xc7_brams_map.v");
|
||||
} else if (family == "xcu" || family == "xcup") {
|
||||
run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
|
||||
run("techmap -map +/xilinx/xcu_brams_map.v");
|
||||
} else {
|
||||
log_warning("Block RAM inference not yet supported for family %s.\n", family.c_str());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
MULT18X18 _TECHMAP_REPLACE_ (
|
||||
.A(A),
|
||||
.B(B),
|
||||
.P(Y)
|
||||
);
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48A #(
|
||||
// Disable all registers
|
||||
.A0REG(0),
|
||||
.A1REG(0),
|
||||
.B0REG(0),
|
||||
.B1REG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSEL("OPMODE5"),
|
||||
.CREG(0),
|
||||
.DREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A(A),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.D(18'b0),
|
||||
.P(P_48),
|
||||
|
||||
.OPMODE(8'b0000010)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48 #(
|
||||
// Disable all registers
|
||||
.AREG(0),
|
||||
.BREG(0),
|
||||
.B_INPUT("DIRECT"),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSELREG(0),
|
||||
.CREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0),
|
||||
.SUBTRACTREG(0),
|
||||
.LEGACY_MODE("MULT18X18")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A(A),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.P(P_48),
|
||||
|
||||
.SUBTRACT(1'b0),
|
||||
.OPMODE(7'b000101),
|
||||
.CARRYINSEL(2'b00),
|
||||
|
||||
.BCIN(18'b0),
|
||||
.PCIN(48'b0),
|
||||
.CARRYIN(1'b0)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
|
@ -0,0 +1,45 @@
|
|||
module \$__MUL25X18 (input [24:0] A, input [17:0] B, output [42:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48E #(
|
||||
// Disable all registers
|
||||
.ACASCREG(0),
|
||||
.A_INPUT("DIRECT"),
|
||||
.ALUMODEREG(0),
|
||||
.AREG(0),
|
||||
.BCASCREG(0),
|
||||
.B_INPUT("DIRECT"),
|
||||
.BREG(0),
|
||||
.MULTCARRYINREG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSELREG(0),
|
||||
.CREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0),
|
||||
.USE_MULT("MULT"),
|
||||
.USE_SIMD("ONE48")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A({{5{A[24]}}, A}),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.P(P_48),
|
||||
|
||||
.ALUMODE(4'b0000),
|
||||
.OPMODE(7'b000101),
|
||||
.CARRYINSEL(3'b000),
|
||||
|
||||
.ACIN(30'b0),
|
||||
.BCIN(18'b0),
|
||||
.PCIN(48'b0),
|
||||
.CARRYIN(1'b0)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
module RAMB8BWER (
|
||||
(* clkbuf_sink *)
|
||||
input CLKAWRCLK,
|
||||
(* clkbuf_sink *)
|
||||
input CLKBRDCLK,
|
||||
input ENAWREN,
|
||||
input ENBRDEN,
|
||||
input REGCEA,
|
||||
input REGCEBREGCE,
|
||||
input RSTA,
|
||||
input RSTBRST,
|
||||
|
||||
input [12:0] ADDRAWRADDR,
|
||||
input [12:0] ADDRBRDADDR,
|
||||
input [15:0] DIADI,
|
||||
input [15:0] DIBDI,
|
||||
input [1:0] DIPADIP,
|
||||
input [1:0] DIPBDIP,
|
||||
input [1:0] WEAWEL,
|
||||
input [1:0] WEBWEU,
|
||||
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [15:0] DOADO,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [15:0] DOBDO,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [1:0] DOPADOP,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [1:0] DOPBDOP
|
||||
);
|
||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
parameter RAM_MODE = "TDP";
|
||||
parameter integer DOA_REG = 0;
|
||||
parameter integer DOB_REG = 0;
|
||||
|
||||
parameter integer DATA_WIDTH_A = 0;
|
||||
parameter integer DATA_WIDTH_B = 0;
|
||||
|
||||
parameter WRITE_MODE_A = "WRITE_FIRST";
|
||||
parameter WRITE_MODE_B = "WRITE_FIRST";
|
||||
|
||||
parameter EN_RSTRAM_A = "TRUE";
|
||||
parameter EN_RSTRAM_B = "TRUE";
|
||||
|
||||
parameter INIT_A = 18'h000000000;
|
||||
parameter INIT_B = 18'h000000000;
|
||||
parameter SRVAL_A = 18'h000000000;
|
||||
parameter SRVAL_B = 18'h000000000;
|
||||
|
||||
parameter RST_PRIORITY_A = "CE";
|
||||
parameter RST_PRIORITY_B = "CE";
|
||||
|
||||
parameter RSTTYPE = "SYNC";
|
||||
|
||||
parameter SIM_COLLISION_CHECK = "ALL";
|
||||
endmodule
|
||||
|
||||
module RAMB16BWER (
|
||||
(* clkbuf_sink *)
|
||||
input CLKA,
|
||||
(* clkbuf_sink *)
|
||||
input CLKB,
|
||||
input ENA,
|
||||
input ENB,
|
||||
input REGCEA,
|
||||
input REGCEB,
|
||||
input RSTA,
|
||||
input RSTB,
|
||||
|
||||
input [13:0] ADDRA,
|
||||
input [13:0] ADDRB,
|
||||
input [31:0] DIA,
|
||||
input [31:0] DIB,
|
||||
input [3:0] DIPA,
|
||||
input [3:0] DIPB,
|
||||
input [3:0] WEA,
|
||||
input [3:0] WEB,
|
||||
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [31:0] DOA,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [31:0] DOB,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [3:0] DOPA,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [3:0] DOPB
|
||||
);
|
||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
parameter integer DOA_REG = 0;
|
||||
parameter integer DOB_REG = 0;
|
||||
|
||||
parameter integer DATA_WIDTH_A = 0;
|
||||
parameter integer DATA_WIDTH_B = 0;
|
||||
|
||||
parameter WRITE_MODE_A = "WRITE_FIRST";
|
||||
parameter WRITE_MODE_B = "WRITE_FIRST";
|
||||
|
||||
parameter EN_RSTRAM_A = "TRUE";
|
||||
parameter EN_RSTRAM_B = "TRUE";
|
||||
|
||||
parameter INIT_A = 36'h000000000;
|
||||
parameter INIT_B = 36'h000000000;
|
||||
parameter SRVAL_A = 36'h000000000;
|
||||
parameter SRVAL_B = 36'h000000000;
|
||||
|
||||
parameter RST_PRIORITY_A = "CE";
|
||||
parameter RST_PRIORITY_B = "CE";
|
||||
|
||||
parameter RSTTYPE = "SYNC";
|
||||
|
||||
parameter SIM_COLLISION_CHECK = "ALL";
|
||||
endmodule
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,35 @@
|
|||
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48A1 #(
|
||||
// Disable all registers
|
||||
.A0REG(0),
|
||||
.A1REG(0),
|
||||
.B0REG(0),
|
||||
.B1REG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSEL("OPMODE5"),
|
||||
.CREG(0),
|
||||
.DREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A(A),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.D(18'b0),
|
||||
.P(P_48),
|
||||
|
||||
.OPMODE(8'b0000010)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,349 +0,0 @@
|
|||
// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/f8e0364116b2983ac72a3dc8c509ea1cc79e2e3d/artix7/timings/BRAM_L.sdf#L138-L147
|
||||
|
||||
module RAMB18E1 (
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
|
||||
input CLKARDCLK,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
|
||||
input CLKBWRCLK,
|
||||
(* invertible_pin = "IS_ENARDEN_INVERTED" *)
|
||||
input ENARDEN,
|
||||
(* invertible_pin = "IS_ENBWREN_INVERTED" *)
|
||||
input ENBWREN,
|
||||
input REGCEAREGCE,
|
||||
input REGCEB,
|
||||
(* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
|
||||
input RSTRAMARSTRAM,
|
||||
(* invertible_pin = "IS_RSTRAMB_INVERTED" *)
|
||||
input RSTRAMB,
|
||||
(* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
|
||||
input RSTREGARSTREG,
|
||||
(* invertible_pin = "IS_RSTREGB_INVERTED" *)
|
||||
input RSTREGB,
|
||||
|
||||
input [13:0] ADDRARDADDR,
|
||||
input [13:0] ADDRBWRADDR,
|
||||
input [15:0] DIADI,
|
||||
input [15:0] DIBDI,
|
||||
input [1:0] DIPADIP,
|
||||
input [1:0] DIPBDIP,
|
||||
input [1:0] WEA,
|
||||
input [3:0] WEBWE,
|
||||
|
||||
(* abc9_arrival=2454 *)
|
||||
output [15:0] DOADO,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [15:0] DOBDO,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [1:0] DOPADOP,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [1:0] DOPBDOP
|
||||
);
|
||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
parameter IS_CLKARDCLK_INVERTED = 1'b0;
|
||||
parameter IS_CLKBWRCLK_INVERTED = 1'b0;
|
||||
parameter IS_ENARDEN_INVERTED = 1'b0;
|
||||
parameter IS_ENBWREN_INVERTED = 1'b0;
|
||||
parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
|
||||
parameter IS_RSTRAMB_INVERTED = 1'b0;
|
||||
parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
|
||||
parameter IS_RSTREGB_INVERTED = 1'b0;
|
||||
|
||||
parameter RAM_MODE = "TDP";
|
||||
parameter integer DOA_REG = 0;
|
||||
parameter integer DOB_REG = 0;
|
||||
|
||||
parameter integer READ_WIDTH_A = 0;
|
||||
parameter integer READ_WIDTH_B = 0;
|
||||
parameter integer WRITE_WIDTH_A = 0;
|
||||
parameter integer WRITE_WIDTH_B = 0;
|
||||
|
||||
parameter WRITE_MODE_A = "WRITE_FIRST";
|
||||
parameter WRITE_MODE_B = "WRITE_FIRST";
|
||||
|
||||
parameter SIM_DEVICE = "VIRTEX6";
|
||||
endmodule
|
||||
|
||||
module RAMB36E1 (
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
|
||||
input CLKARDCLK,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
|
||||
input CLKBWRCLK,
|
||||
(* invertible_pin = "IS_ENARDEN_INVERTED" *)
|
||||
input ENARDEN,
|
||||
(* invertible_pin = "IS_ENBWREN_INVERTED" *)
|
||||
input ENBWREN,
|
||||
input REGCEAREGCE,
|
||||
input REGCEB,
|
||||
(* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
|
||||
input RSTRAMARSTRAM,
|
||||
(* invertible_pin = "IS_RSTRAMB_INVERTED" *)
|
||||
input RSTRAMB,
|
||||
(* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
|
||||
input RSTREGARSTREG,
|
||||
(* invertible_pin = "IS_RSTREGB_INVERTED" *)
|
||||
input RSTREGB,
|
||||
|
||||
input [15:0] ADDRARDADDR,
|
||||
input [15:0] ADDRBWRADDR,
|
||||
input [31:0] DIADI,
|
||||
input [31:0] DIBDI,
|
||||
input [3:0] DIPADIP,
|
||||
input [3:0] DIPBDIP,
|
||||
input [3:0] WEA,
|
||||
input [7:0] WEBWE,
|
||||
|
||||
(* abc9_arrival=2454 *)
|
||||
output [31:0] DOADO,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [31:0] DOBDO,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [3:0] DOPADOP,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [3:0] DOPBDOP
|
||||
);
|
||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITP_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_40 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_41 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_42 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_43 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_44 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_45 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_46 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_47 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_48 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_49 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_4A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_4B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_4C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_4D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_4E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_4F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_50 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_51 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_52 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_53 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_54 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_55 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_56 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_57 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_58 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_59 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_5A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_5B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_5C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_5D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_5E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_5F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_60 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_61 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_62 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_63 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_64 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_65 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_66 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_67 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_68 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_69 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_6A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_6B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_6C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_6D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_6E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_6F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_70 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_71 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_72 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_73 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_74 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_75 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_76 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_77 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_78 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_79 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_7A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_7B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_7C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_7D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_7E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_7F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
parameter IS_CLKARDCLK_INVERTED = 1'b0;
|
||||
parameter IS_CLKBWRCLK_INVERTED = 1'b0;
|
||||
parameter IS_ENARDEN_INVERTED = 1'b0;
|
||||
parameter IS_ENBWREN_INVERTED = 1'b0;
|
||||
parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
|
||||
parameter IS_RSTRAMB_INVERTED = 1'b0;
|
||||
parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
|
||||
parameter IS_RSTREGB_INVERTED = 1'b0;
|
||||
|
||||
parameter RAM_MODE = "TDP";
|
||||
parameter integer DOA_REG = 0;
|
||||
parameter integer DOB_REG = 0;
|
||||
|
||||
parameter integer READ_WIDTH_A = 0;
|
||||
parameter integer READ_WIDTH_B = 0;
|
||||
parameter integer WRITE_WIDTH_A = 0;
|
||||
parameter integer WRITE_WIDTH_B = 0;
|
||||
|
||||
parameter WRITE_MODE_A = "WRITE_FIRST";
|
||||
parameter WRITE_MODE_B = "WRITE_FIRST";
|
||||
|
||||
parameter SIM_DEVICE = "VIRTEX6";
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,384 @@
|
|||
module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||
parameter CLKPOL2 = 1;
|
||||
parameter CLKPOL3 = 1;
|
||||
parameter [36863:0] INIT = 36864'bx;
|
||||
|
||||
input CLK2;
|
||||
input CLK3;
|
||||
|
||||
input [8:0] A1ADDR;
|
||||
output [71:0] A1DATA;
|
||||
input A1EN;
|
||||
|
||||
input [8:0] B1ADDR;
|
||||
input [71:0] B1DATA;
|
||||
input [7:0] B1EN;
|
||||
|
||||
wire [15:0] A1ADDR_16 = {A1ADDR, 6'b0};
|
||||
wire [15:0] B1ADDR_16 = {B1ADDR, 6'b0};
|
||||
|
||||
wire [7:0] DIP, DOP;
|
||||
wire [63:0] DI, DO;
|
||||
|
||||
assign A1DATA = { DOP[7], DO[63:56], DOP[6], DO[55:48], DOP[5], DO[47:40], DOP[4], DO[39:32],
|
||||
DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
|
||||
|
||||
assign { DIP[7], DI[63:56], DIP[6], DI[55:48], DIP[5], DI[47:40], DIP[4], DI[39:32],
|
||||
DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
|
||||
|
||||
RAMB36E2 #(
|
||||
.READ_WIDTH_A(72),
|
||||
.WRITE_WIDTH_B(72),
|
||||
.WRITE_MODE_A("READ_FIRST"),
|
||||
.WRITE_MODE_B("READ_FIRST"),
|
||||
.DOA_REG(0),
|
||||
.DOB_REG(0),
|
||||
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||
`include "brams_init_36.vh"
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DOUTBDOUT(DO[63:32]),
|
||||
.DOUTADOUT(DO[31:0]),
|
||||
.DOUTPBDOUTP(DOP[7:4]),
|
||||
.DOUTPADOUTP(DOP[3:0]),
|
||||
.DINBDIN(DI[63:32]),
|
||||
.DINADIN(DI[31:0]),
|
||||
.DINPBDINP(DIP[7:4]),
|
||||
.DINPADINP(DIP[3:0]),
|
||||
|
||||
.ADDRARDADDR(A1ADDR_16),
|
||||
.CLKARDCLK(CLK2),
|
||||
.ENARDEN(A1EN),
|
||||
.ADDRENA(|1),
|
||||
.REGCEAREGCE(|1),
|
||||
.RSTRAMARSTRAM(|0),
|
||||
.RSTREGARSTREG(|0),
|
||||
.WEA(4'b0),
|
||||
|
||||
.ADDRBWRADDR(B1ADDR_16),
|
||||
.CLKBWRCLK(CLK3),
|
||||
.ENBWREN(|1),
|
||||
.ADDRENB(|1),
|
||||
.REGCEB(|1),
|
||||
.RSTRAMB(|0),
|
||||
.RSTREGB(|0),
|
||||
.WEBWE(B1EN),
|
||||
|
||||
.SLEEP(|0)
|
||||
);
|
||||
endmodule
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||
parameter CLKPOL2 = 1;
|
||||
parameter CLKPOL3 = 1;
|
||||
parameter [18431:0] INIT = 18432'bx;
|
||||
|
||||
input CLK2;
|
||||
input CLK3;
|
||||
|
||||
input [8:0] A1ADDR;
|
||||
output [35:0] A1DATA;
|
||||
input A1EN;
|
||||
|
||||
input [8:0] B1ADDR;
|
||||
input [35:0] B1DATA;
|
||||
input [3:0] B1EN;
|
||||
|
||||
wire [13:0] A1ADDR_14 = {A1ADDR, 5'b0};
|
||||
wire [13:0] B1ADDR_14 = {B1ADDR, 5'b0};
|
||||
|
||||
wire [3:0] DIP, DOP;
|
||||
wire [31:0] DI, DO;
|
||||
|
||||
assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
|
||||
assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
|
||||
|
||||
RAMB18E2 #(
|
||||
.READ_WIDTH_A(36),
|
||||
.WRITE_WIDTH_B(36),
|
||||
.WRITE_MODE_A("READ_FIRST"),
|
||||
.WRITE_MODE_B("READ_FIRST"),
|
||||
.DOA_REG(0),
|
||||
.DOB_REG(0),
|
||||
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||
`include "brams_init_18.vh"
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DOUTBDOUT(DO[31:16]),
|
||||
.DOUTADOUT(DO[15:0]),
|
||||
.DOUTPBDOUTP(DOP[3:2]),
|
||||
.DOUTPADOUTP(DOP[1:0]),
|
||||
.DINBDIN(DI[31:16]),
|
||||
.DINADIN(DI[15:0]),
|
||||
.DINPBDINP(DIP[3:2]),
|
||||
.DINPADINP(DIP[1:0]),
|
||||
|
||||
.ADDRARDADDR(A1ADDR_14),
|
||||
.CLKARDCLK(CLK2),
|
||||
.ENARDEN(A1EN),
|
||||
.ADDRENA(|1),
|
||||
.REGCEAREGCE(|1),
|
||||
.RSTRAMARSTRAM(|0),
|
||||
.RSTREGARSTREG(|0),
|
||||
.WEA(2'b0),
|
||||
|
||||
.ADDRBWRADDR(B1ADDR_14),
|
||||
.CLKBWRCLK(CLK3),
|
||||
.ENBWREN(|1),
|
||||
.ADDRENB(|1),
|
||||
.REGCEB(|1),
|
||||
.RSTRAMB(|0),
|
||||
.RSTREGB(|0),
|
||||
.WEBWE(B1EN),
|
||||
|
||||
.SLEEP(|0)
|
||||
);
|
||||
endmodule
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||
parameter CFG_ABITS = 10;
|
||||
parameter CFG_DBITS = 36;
|
||||
parameter CFG_ENABLE_B = 4;
|
||||
|
||||
parameter CLKPOL2 = 1;
|
||||
parameter CLKPOL3 = 1;
|
||||
parameter [36863:0] INIT = 36864'bx;
|
||||
|
||||
input CLK2;
|
||||
input CLK3;
|
||||
|
||||
input [CFG_ABITS-1:0] A1ADDR;
|
||||
output [CFG_DBITS-1:0] A1DATA;
|
||||
input A1EN;
|
||||
|
||||
input [CFG_ABITS-1:0] B1ADDR;
|
||||
input [CFG_DBITS-1:0] B1DATA;
|
||||
input [CFG_ENABLE_B-1:0] B1EN;
|
||||
|
||||
wire [15:0] A1ADDR_16 = A1ADDR << (15 - CFG_ABITS);
|
||||
wire [15:0] B1ADDR_16 = B1ADDR << (15 - CFG_ABITS);
|
||||
wire [7:0] B1EN_8 = B1EN;
|
||||
|
||||
wire [3:0] DIP, DOP;
|
||||
wire [31:0] DI, DO;
|
||||
|
||||
wire [31:0] DOBDO;
|
||||
wire [3:0] DOPBDOP;
|
||||
|
||||
assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
|
||||
assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
|
||||
|
||||
generate if (CFG_DBITS > 8) begin
|
||||
RAMB36E2 #(
|
||||
.READ_WIDTH_A(CFG_DBITS),
|
||||
.READ_WIDTH_B(CFG_DBITS),
|
||||
.WRITE_WIDTH_A(CFG_DBITS),
|
||||
.WRITE_WIDTH_B(CFG_DBITS),
|
||||
.WRITE_MODE_A("READ_FIRST"),
|
||||
.WRITE_MODE_B("READ_FIRST"),
|
||||
.DOA_REG(0),
|
||||
.DOB_REG(0),
|
||||
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||
`include "brams_init_36.vh"
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DINADIN(32'hFFFFFFFF),
|
||||
.DINPADINP(4'hF),
|
||||
.DOUTADOUT(DO[31:0]),
|
||||
.DOUTPADOUTP(DOP[3:0]),
|
||||
.ADDRARDADDR(A1ADDR_16),
|
||||
.CLKARDCLK(CLK2),
|
||||
.ENARDEN(A1EN),
|
||||
.ADDRENA(|1),
|
||||
.REGCEAREGCE(|1),
|
||||
.RSTRAMARSTRAM(|0),
|
||||
.RSTREGARSTREG(|0),
|
||||
.WEA(4'b0),
|
||||
|
||||
.DINBDIN(DI),
|
||||
.DINPBDINP(DIP),
|
||||
.DOUTBDOUT(DOBDO),
|
||||
.DOUTPBDOUTP(DOPBDOP),
|
||||
.ADDRBWRADDR(B1ADDR_16),
|
||||
.CLKBWRCLK(CLK3),
|
||||
.ENBWREN(|1),
|
||||
.ADDRENB(|1),
|
||||
.REGCEB(|0),
|
||||
.RSTRAMB(|0),
|
||||
.RSTREGB(|0),
|
||||
.WEBWE(B1EN_8),
|
||||
|
||||
.SLEEP(|0)
|
||||
);
|
||||
end else begin
|
||||
RAMB36E2 #(
|
||||
.READ_WIDTH_A(CFG_DBITS),
|
||||
.READ_WIDTH_B(CFG_DBITS),
|
||||
.WRITE_WIDTH_A(CFG_DBITS),
|
||||
.WRITE_WIDTH_B(CFG_DBITS),
|
||||
.WRITE_MODE_A("READ_FIRST"),
|
||||
.WRITE_MODE_B("READ_FIRST"),
|
||||
.DOA_REG(0),
|
||||
.DOB_REG(0),
|
||||
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||
`include "brams_init_32.vh"
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DINADIN(32'hFFFFFFFF),
|
||||
.DINPADINP(4'hF),
|
||||
.DOUTADOUT(DO[31:0]),
|
||||
.DOUTPADOUTP(DOP[3:0]),
|
||||
.ADDRARDADDR(A1ADDR_16),
|
||||
.CLKARDCLK(CLK2),
|
||||
.ENARDEN(A1EN),
|
||||
.ADDRENA(|1),
|
||||
.REGCEAREGCE(|1),
|
||||
.RSTRAMARSTRAM(|0),
|
||||
.RSTREGARSTREG(|0),
|
||||
.WEA(4'b0),
|
||||
|
||||
.DINBDIN(DI),
|
||||
.DINPBDINP(DIP),
|
||||
.DOUTBDOUT(DOBDO),
|
||||
.DOUTPBDOUTP(DOPBDOP),
|
||||
.ADDRBWRADDR(B1ADDR_16),
|
||||
.CLKBWRCLK(CLK3),
|
||||
.ENBWREN(|1),
|
||||
.ADDRENB(|1),
|
||||
.REGCEB(|0),
|
||||
.RSTRAMB(|0),
|
||||
.RSTREGB(|0),
|
||||
.WEBWE(B1EN_8),
|
||||
|
||||
.SLEEP(|0)
|
||||
);
|
||||
end endgenerate
|
||||
endmodule
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||
parameter CFG_ABITS = 10;
|
||||
parameter CFG_DBITS = 18;
|
||||
parameter CFG_ENABLE_B = 2;
|
||||
|
||||
parameter CLKPOL2 = 1;
|
||||
parameter CLKPOL3 = 1;
|
||||
parameter [18431:0] INIT = 18432'bx;
|
||||
|
||||
input CLK2;
|
||||
input CLK3;
|
||||
|
||||
input [CFG_ABITS-1:0] A1ADDR;
|
||||
output [CFG_DBITS-1:0] A1DATA;
|
||||
input A1EN;
|
||||
|
||||
input [CFG_ABITS-1:0] B1ADDR;
|
||||
input [CFG_DBITS-1:0] B1DATA;
|
||||
input [CFG_ENABLE_B-1:0] B1EN;
|
||||
|
||||
wire [13:0] A1ADDR_14 = A1ADDR << (14 - CFG_ABITS);
|
||||
wire [13:0] B1ADDR_14 = B1ADDR << (14 - CFG_ABITS);
|
||||
wire [3:0] B1EN_4 = B1EN;
|
||||
|
||||
wire [1:0] DIP, DOP;
|
||||
wire [15:0] DI, DO;
|
||||
|
||||
wire [15:0] DOBDO;
|
||||
wire [1:0] DOPBDOP;
|
||||
|
||||
assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
|
||||
assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
|
||||
|
||||
generate if (CFG_DBITS > 8) begin
|
||||
RAMB18E2 #(
|
||||
.READ_WIDTH_A(CFG_DBITS),
|
||||
.READ_WIDTH_B(CFG_DBITS),
|
||||
.WRITE_WIDTH_A(CFG_DBITS),
|
||||
.WRITE_WIDTH_B(CFG_DBITS),
|
||||
.WRITE_MODE_A("READ_FIRST"),
|
||||
.WRITE_MODE_B("READ_FIRST"),
|
||||
.DOA_REG(0),
|
||||
.DOB_REG(0),
|
||||
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||
`include "brams_init_18.vh"
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DINADIN(16'hFFFF),
|
||||
.DINPADINP(2'b11),
|
||||
.DOUTADOUT(DO),
|
||||
.DOUTPADOUTP(DOP),
|
||||
.ADDRARDADDR(A1ADDR_14),
|
||||
.CLKARDCLK(CLK2),
|
||||
.ENARDEN(A1EN),
|
||||
.ADDRENA(|1),
|
||||
.REGCEAREGCE(|1),
|
||||
.RSTRAMARSTRAM(|0),
|
||||
.RSTREGARSTREG(|0),
|
||||
.WEA(2'b0),
|
||||
|
||||
.DINBDIN(DI),
|
||||
.DINPBDINP(DIP),
|
||||
.DOUTBDOUT(DOBDO),
|
||||
.DOUTPBDOUTP(DOPBDOP),
|
||||
.ADDRBWRADDR(B1ADDR_14),
|
||||
.CLKBWRCLK(CLK3),
|
||||
.ENBWREN(|1),
|
||||
.ADDRENB(|1),
|
||||
.REGCEB(|0),
|
||||
.RSTRAMB(|0),
|
||||
.RSTREGB(|0),
|
||||
.WEBWE(B1EN_4),
|
||||
|
||||
.SLEEP(|0)
|
||||
);
|
||||
end else begin
|
||||
RAMB18E2 #(
|
||||
//.RAM_MODE("TDP"),
|
||||
.READ_WIDTH_A(CFG_DBITS),
|
||||
.READ_WIDTH_B(CFG_DBITS),
|
||||
.WRITE_WIDTH_A(CFG_DBITS),
|
||||
.WRITE_WIDTH_B(CFG_DBITS),
|
||||
.WRITE_MODE_A("READ_FIRST"),
|
||||
.WRITE_MODE_B("READ_FIRST"),
|
||||
.DOA_REG(0),
|
||||
.DOB_REG(0),
|
||||
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||
`include "brams_init_16.vh"
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DINADIN(16'hFFFF),
|
||||
.DINPADINP(2'b11),
|
||||
.DOUTADOUT(DO),
|
||||
.DOUTPADOUTP(DOP),
|
||||
.ADDRARDADDR(A1ADDR_14),
|
||||
.CLKARDCLK(CLK2),
|
||||
.ENARDEN(A1EN),
|
||||
.ADDRENA(|1),
|
||||
.REGCEAREGCE(|1),
|
||||
.RSTRAMARSTRAM(|0),
|
||||
.RSTREGARSTREG(|0),
|
||||
.WEA(2'b0),
|
||||
|
||||
.DINBDIN(DI),
|
||||
.DINPBDINP(DIP),
|
||||
.DOUTBDOUT(DOBDO),
|
||||
.DOUTPBDOUTP(DOPBDOP),
|
||||
.ADDRBWRADDR(B1ADDR_14),
|
||||
.CLKBWRCLK(CLK3),
|
||||
.ENBWREN(|1),
|
||||
.ADDRENB(|1),
|
||||
.REGCEB(|0),
|
||||
.RSTRAMB(|0),
|
||||
.RSTREGB(|0),
|
||||
.WEBWE(B1EN_4),
|
||||
|
||||
.SLEEP(|0)
|
||||
);
|
||||
end endgenerate
|
||||
endmodule
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,51 @@
|
|||
module \$__MUL27X18 (input [26:0] A, input [17:0] B, output [44:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48E2 #(
|
||||
// Disable all registers
|
||||
.ACASCREG(0),
|
||||
.ADREG(0),
|
||||
.A_INPUT("DIRECT"),
|
||||
.ALUMODEREG(0),
|
||||
.AREG(0),
|
||||
.BCASCREG(0),
|
||||
.B_INPUT("DIRECT"),
|
||||
.BREG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSELREG(0),
|
||||
.CREG(0),
|
||||
.DREG(0),
|
||||
.INMODEREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0),
|
||||
.USE_MULT("MULTIPLY"),
|
||||
.USE_SIMD("ONE48"),
|
||||
.AMULTSEL("A"),
|
||||
.BMULTSEL("B")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A({{3{A[26]}}, A}),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.D(27'b0),
|
||||
.P(P_48),
|
||||
|
||||
.INMODE(5'b00000),
|
||||
.ALUMODE(4'b0000),
|
||||
.OPMODE(9'b00000101),
|
||||
.CARRYINSEL(3'b000),
|
||||
|
||||
.ACIN(30'b0),
|
||||
.BCIN(18'b0),
|
||||
.PCIN(48'b0),
|
||||
.CARRYIN(1'b0)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
bram $__XILINX_URAM288
|
||||
init 0
|
||||
abits 12
|
||||
dbits 72
|
||||
groups 2
|
||||
ports 1 1
|
||||
wrmode 0 1
|
||||
enable 1 9
|
||||
transp 0 0
|
||||
clocks 2 2
|
||||
clkpol 2 2
|
||||
endbram
|
||||
|
||||
match $__XILINX_URAM288
|
||||
min bits 131072
|
||||
min efficiency 15
|
||||
shuffle_enable B
|
||||
make_transp
|
||||
endmatch
|
|
@ -0,0 +1,47 @@
|
|||
module \$__XILINX_URAM288 (CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||
parameter CLKPOL2 = 1;
|
||||
|
||||
input CLK2;
|
||||
|
||||
input [11:0] A1ADDR;
|
||||
output [71:0] A1DATA;
|
||||
input A1EN;
|
||||
|
||||
input [11:0] B1ADDR;
|
||||
input [71:0] B1DATA;
|
||||
input [8:0] B1EN;
|
||||
|
||||
|
||||
URAM288 #(
|
||||
.BWE_MODE_A("PARITY_INDEPENDENT"),
|
||||
.BWE_MODE_B("PARITY_INDEPENDENT"),
|
||||
.EN_AUTO_SLEEP_MODE("FALSE"),
|
||||
.IREG_PRE_A("FALSE"),
|
||||
.IREG_PRE_B("FALSE"),
|
||||
.IS_CLK_INVERTED(!CLKPOL2),
|
||||
.OREG_A("FALSE"),
|
||||
.OREG_B("FALSE")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ADDR_A({11'b0, A1ADDR}),
|
||||
.BWE_A(9'b0),
|
||||
.DIN_A(72'b0),
|
||||
.EN_A(A1EN),
|
||||
.RDB_WR_A(1'b0),
|
||||
.INJECT_DBITERR_A(1'b0),
|
||||
.INJECT_SBITERR_A(1'b0),
|
||||
.RST_A(1'b0),
|
||||
.DOUT_A(A1DATA),
|
||||
|
||||
.ADDR_B({11'b0, B1ADDR}),
|
||||
.BWE_B(B1EN),
|
||||
.DIN_B(B1DATA),
|
||||
.EN_B(|B1EN),
|
||||
.RDB_WR_B(1'b1),
|
||||
.INJECT_DBITERR_B(1'b0),
|
||||
.INJECT_SBITERR_B(1'b0),
|
||||
.RST_B(1'b0),
|
||||
|
||||
.CLK(CLK2),
|
||||
.SLEEP(1'b0)
|
||||
);
|
||||
endmodule
|
|
@ -0,0 +1,10 @@
|
|||
read_verilog ../common/add_sub.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
select -assert-count 10 t:AL_MAP_ADDER
|
||||
select -assert-count 4 t:AL_MAP_LUT1
|
||||
|
||||
select -assert-none t:AL_MAP_LUT1 t:AL_MAP_ADDER %% t:* %D
|
|
@ -0,0 +1,11 @@
|
|||
read_verilog ../common/counter.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
flatten
|
||||
equiv_opt -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 9 t:AL_MAP_ADDER
|
||||
select -assert-count 8 t:AL_MAP_SEQ
|
||||
select -assert-none t:AL_MAP_SEQ t:AL_MAP_ADDER %% t:* %D
|
|
@ -0,0 +1,20 @@
|
|||
read_verilog ../common/dffs.v
|
||||
design -save read
|
||||
|
||||
hierarchy -top dff
|
||||
proc
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd dff # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:AL_MAP_SEQ
|
||||
select -assert-none t:AL_MAP_SEQ %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top dffe
|
||||
proc
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd dffe # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:AL_MAP_LUT3
|
||||
select -assert-count 1 t:AL_MAP_SEQ
|
||||
select -assert-none t:AL_MAP_LUT3 t:AL_MAP_SEQ %% t:* %D
|
|
@ -0,0 +1,18 @@
|
|||
read_verilog ../common/fsm.v
|
||||
hierarchy -top fsm
|
||||
proc
|
||||
flatten
|
||||
|
||||
equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic
|
||||
miter -equiv -make_assert -flatten gold gate miter
|
||||
sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
|
||||
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd fsm # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 1 t:AL_MAP_LUT2
|
||||
select -assert-count 5 t:AL_MAP_LUT5
|
||||
select -assert-count 1 t:AL_MAP_LUT6
|
||||
select -assert-count 6 t:AL_MAP_SEQ
|
||||
|
||||
select -assert-none t:AL_MAP_LUT2 t:AL_MAP_LUT5 t:AL_MAP_LUT6 t:AL_MAP_SEQ %% t:* %D
|
|
@ -0,0 +1,33 @@
|
|||
read_verilog ../common/latches.v
|
||||
design -save read
|
||||
|
||||
hierarchy -top latchp
|
||||
proc
|
||||
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||
synth_anlogic
|
||||
cd latchp # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:AL_MAP_LUT3
|
||||
|
||||
select -assert-none t:AL_MAP_LUT3 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top latchn
|
||||
proc
|
||||
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||
synth_anlogic
|
||||
cd latchn # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:AL_MAP_LUT3
|
||||
|
||||
select -assert-none t:AL_MAP_LUT3 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top latchsr
|
||||
proc
|
||||
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||
synth_anlogic
|
||||
cd latchsr # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:AL_MAP_LUT5
|
||||
|
||||
select -assert-none t:AL_MAP_LUT5 %% t:* %D
|
|
@ -0,0 +1,11 @@
|
|||
read_verilog ../common/logic.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 1 t:AL_MAP_LUT1
|
||||
select -assert-count 6 t:AL_MAP_LUT2
|
||||
select -assert-count 2 t:AL_MAP_LUT4
|
||||
select -assert-none t:AL_MAP_LUT1 t:AL_MAP_LUT2 t:AL_MAP_LUT4 %% t:* %D
|
|
@ -0,0 +1,21 @@
|
|||
read_verilog ../common/memory.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
memory -nomap
|
||||
equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic
|
||||
memory
|
||||
opt -full
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||
#ERROR: Failed to import cell gate.mem.0.0.0 (type EG_LOGIC_DRAM16X4) to SAT database.
|
||||
#sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||
|
||||
design -load postopt
|
||||
cd top
|
||||
|
||||
select -assert-count 8 t:AL_MAP_LUT2
|
||||
select -assert-count 8 t:AL_MAP_LUT4
|
||||
select -assert-count 8 t:AL_MAP_LUT5
|
||||
select -assert-count 36 t:AL_MAP_SEQ
|
||||
select -assert-count 8 t:EG_LOGIC_DRAM16X4 #Why not AL_LOGIC_BRAM?
|
||||
select -assert-none t:AL_MAP_LUT2 t:AL_MAP_LUT4 t:AL_MAP_LUT5 t:AL_MAP_SEQ t:EG_LOGIC_DRAM16X4 %% t:* %D
|
|
@ -0,0 +1,42 @@
|
|||
read_verilog ../common/mux.v
|
||||
design -save read
|
||||
|
||||
hierarchy -top mux2
|
||||
proc
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux2 # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:AL_MAP_LUT3
|
||||
|
||||
select -assert-none t:AL_MAP_LUT3 %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux4
|
||||
proc
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux4 # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:AL_MAP_LUT6
|
||||
|
||||
select -assert-none t:AL_MAP_LUT6 %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux8
|
||||
proc
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux8 # Constrain all select calls below inside the top module
|
||||
select -assert-count 3 t:AL_MAP_LUT4
|
||||
select -assert-count 1 t:AL_MAP_LUT6
|
||||
|
||||
select -assert-none t:AL_MAP_LUT4 t:AL_MAP_LUT6 %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux16
|
||||
proc
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux16 # Constrain all select calls below inside the top module
|
||||
select -assert-count 5 t:AL_MAP_LUT6
|
||||
|
||||
select -assert-none t:AL_MAP_LUT6 %% t:* %D
|
|
@ -6,7 +6,7 @@ for x in *.ys; do
|
|||
echo "all:: run-$x"
|
||||
echo "run-$x:"
|
||||
echo " @echo 'Running $x..'"
|
||||
echo " @../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x"
|
||||
echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x"
|
||||
done
|
||||
for s in *.sh; do
|
||||
if [ "$s" != "run-test.sh" ]; then
|
|
@ -0,0 +1,10 @@
|
|||
read_verilog ../common/shifter.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
flatten
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
select -assert-count 8 t:AL_MAP_SEQ
|
||||
|
||||
select -assert-none t:AL_MAP_SEQ %% t:* %D
|
|
@ -0,0 +1,9 @@
|
|||
read_verilog ../common/tribuf.v
|
||||
hierarchy -top tristate
|
||||
proc
|
||||
flatten
|
||||
equiv_opt -assert -map +/anlogic/cells_sim.v -map +/simcells.v synth_anlogic # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd tristate # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:$_TBUF_
|
||||
select -assert-none t:$_TBUF_ %% t:* %D
|
|
@ -0,0 +1,12 @@
|
|||
module top
|
||||
(
|
||||
input [3:0] x,
|
||||
input [3:0] y,
|
||||
|
||||
output [3:0] A,
|
||||
output [3:0] B
|
||||
);
|
||||
|
||||
assign A = x + y;
|
||||
assign B = x - y;
|
||||
endmodule
|
|
@ -0,0 +1,43 @@
|
|||
module adff( input d, clk, clr, output reg q );
|
||||
initial begin
|
||||
q = 0;
|
||||
end
|
||||
always @( posedge clk, posedge clr )
|
||||
if ( clr )
|
||||
q <= 1'b0;
|
||||
else
|
||||
q <= d;
|
||||
endmodule
|
||||
|
||||
module adffn( input d, clk, clr, output reg q );
|
||||
initial begin
|
||||
q = 0;
|
||||
end
|
||||
always @( posedge clk, negedge clr )
|
||||
if ( !clr )
|
||||
q <= 1'b0;
|
||||
else
|
||||
q <= d;
|
||||
endmodule
|
||||
|
||||
module dffs( input d, clk, pre, clr, output reg q );
|
||||
initial begin
|
||||
q = 0;
|
||||
end
|
||||
always @( posedge clk )
|
||||
if ( pre )
|
||||
q <= 1'b1;
|
||||
else
|
||||
q <= d;
|
||||
endmodule
|
||||
|
||||
module ndffnr( input d, clk, pre, clr, output reg q );
|
||||
initial begin
|
||||
q = 0;
|
||||
end
|
||||
always @( negedge clk )
|
||||
if ( !clr )
|
||||
q <= 1'b0;
|
||||
else
|
||||
q <= d;
|
||||
endmodule
|
|
@ -0,0 +1,11 @@
|
|||
module top ( out, clk, reset );
|
||||
output [7:0] out;
|
||||
input clk, reset;
|
||||
reg [7:0] out;
|
||||
|
||||
always @(posedge clk, posedge reset)
|
||||
if (reset)
|
||||
out <= 8'b0;
|
||||
else
|
||||
out <= out + 1;
|
||||
endmodule
|
|
@ -0,0 +1,13 @@
|
|||
module dff ( input d, clk, output reg q );
|
||||
always @( posedge clk )
|
||||
q <= d;
|
||||
endmodule
|
||||
|
||||
module dffe( input d, clk, en, output reg q );
|
||||
initial begin
|
||||
q = 0;
|
||||
end
|
||||
always @( posedge clk )
|
||||
if ( en )
|
||||
q <= d;
|
||||
endmodule
|
|
@ -0,0 +1,51 @@
|
|||
module fsm ( clock, reset, req_0, req_1, gnt_0, gnt_1 );
|
||||
input clock,reset,req_0,req_1;
|
||||
output gnt_0,gnt_1;
|
||||
wire clock,reset,req_0,req_1;
|
||||
reg gnt_0,gnt_1;
|
||||
|
||||
parameter SIZE = 3;
|
||||
parameter IDLE = 3'b001;
|
||||
parameter GNT0 = 3'b010;
|
||||
parameter GNT1 = 3'b100;
|
||||
parameter GNT2 = 3'b101;
|
||||
|
||||
reg [SIZE-1:0] state;
|
||||
reg [SIZE-1:0] next_state;
|
||||
|
||||
always @ (posedge clock)
|
||||
begin : FSM
|
||||
if (reset == 1'b1) begin
|
||||
state <= #1 IDLE;
|
||||
gnt_0 <= 0;
|
||||
gnt_1 <= 0;
|
||||
end
|
||||
else
|
||||
case(state)
|
||||
IDLE : if (req_0 == 1'b1) begin
|
||||
state <= #1 GNT0;
|
||||
gnt_0 <= 1;
|
||||
end else if (req_1 == 1'b1) begin
|
||||
gnt_1 <= 1;
|
||||
state <= #1 GNT0;
|
||||
end else begin
|
||||
state <= #1 IDLE;
|
||||
end
|
||||
GNT0 : if (req_0 == 1'b1) begin
|
||||
state <= #1 GNT0;
|
||||
end else begin
|
||||
gnt_0 <= 0;
|
||||
state <= #1 IDLE;
|
||||
end
|
||||
GNT1 : if (req_1 == 1'b1) begin
|
||||
state <= #1 GNT2;
|
||||
gnt_1 <= req_0;
|
||||
end
|
||||
GNT2 : if (req_0 == 1'b1) begin
|
||||
state <= #1 GNT1;
|
||||
gnt_1 <= req_1;
|
||||
end
|
||||
default : state <= #1 IDLE;
|
||||
endcase
|
||||
end
|
||||
endmodule
|
|
@ -0,0 +1,21 @@
|
|||
module latchp ( input d, clk, en, output reg q );
|
||||
always @*
|
||||
if ( en )
|
||||
q <= d;
|
||||
endmodule
|
||||
|
||||
module latchn ( input d, clk, en, output reg q );
|
||||
always @*
|
||||
if ( !en )
|
||||
q <= d;
|
||||
endmodule
|
||||
|
||||
module latchsr ( input d, clk, en, clr, pre, output reg q );
|
||||
always @*
|
||||
if ( clr )
|
||||
q <= 1'b0;
|
||||
else if ( pre )
|
||||
q <= 1'b1;
|
||||
else if ( en )
|
||||
q <= d;
|
||||
endmodule
|
|
@ -0,0 +1,16 @@
|
|||
module top
|
||||
(
|
||||
input [0:7] in,
|
||||
output B1,B2,B3,B4,B5,B6,B7,B8,B9,B10
|
||||
);
|
||||
assign B1 = in[0] & in[1];
|
||||
assign B2 = in[0] | in[1];
|
||||
assign B3 = in[0] ~& in[1];
|
||||
assign B4 = in[0] ~| in[1];
|
||||
assign B5 = in[0] ^ in[1];
|
||||
assign B6 = in[0] ~^ in[1];
|
||||
assign B7 = ~in[0];
|
||||
assign B8 = in[0];
|
||||
assign B9 = in[0:1] && in [2:3];
|
||||
assign B10 = in[0:1] || in [2:3];
|
||||
endmodule
|
|
@ -0,0 +1,9 @@
|
|||
module top
|
||||
(
|
||||
input [5:0] x,
|
||||
input [5:0] y,
|
||||
|
||||
output [11:0] A,
|
||||
);
|
||||
assign A = x * y;
|
||||
endmodule
|
|
@ -0,0 +1,60 @@
|
|||
module mux2 (S,A,B,Y);
|
||||
input S;
|
||||
input A,B;
|
||||
output reg Y;
|
||||
|
||||
always @(*)
|
||||
Y = (S)? B : A;
|
||||
endmodule
|
||||
|
||||
module mux4 ( S, D, Y );
|
||||
input[1:0] S;
|
||||
input[3:0] D;
|
||||
output Y;
|
||||
|
||||
reg Y;
|
||||
wire[1:0] S;
|
||||
wire[3:0] D;
|
||||
|
||||
always @*
|
||||
begin
|
||||
case( S )
|
||||
0 : Y = D[0];
|
||||
1 : Y = D[1];
|
||||
2 : Y = D[2];
|
||||
3 : Y = D[3];
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
||||
module mux8 ( S, D, Y );
|
||||
input[2:0] S;
|
||||
input[7:0] D;
|
||||
output Y;
|
||||
|
||||
reg Y;
|
||||
wire[2:0] S;
|
||||
wire[7:0] D;
|
||||
|
||||
always @*
|
||||
begin
|
||||
case( S )
|
||||
0 : Y = D[0];
|
||||
1 : Y = D[1];
|
||||
2 : Y = D[2];
|
||||
3 : Y = D[3];
|
||||
4 : Y = D[4];
|
||||
5 : Y = D[5];
|
||||
6 : Y = D[6];
|
||||
7 : Y = D[7];
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
||||
module mux16 (D, S, Y);
|
||||
input [15:0] D;
|
||||
input [3:0] S;
|
||||
output Y;
|
||||
|
||||
assign Y = D[S];
|
||||
endmodule
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue