mirror of https://github.com/YosysHQ/yosys.git
Merge branch 'master' of github.com:YosysHQ/yosys
This commit is contained in:
commit
d0afe4e10d
|
@ -50,9 +50,12 @@ Yosys 0.9 .. Yosys 0.9-dev
|
||||||
- "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental)
|
- "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental)
|
||||||
- "synth_ice40 -dsp" to infer DSP blocks
|
- "synth_ice40 -dsp" to infer DSP blocks
|
||||||
- Added latch support to synth_xilinx
|
- Added latch support to synth_xilinx
|
||||||
|
- Added support for flip-flops with synchronous reset to synth_xilinx
|
||||||
|
- Added support for flip-flops with reset and enable to synth_xilinx
|
||||||
- Added "check -mapped"
|
- Added "check -mapped"
|
||||||
- Added checking of SystemVerilog always block types (always_comb,
|
- Added checking of SystemVerilog always block types (always_comb,
|
||||||
always_latch and always_ff)
|
always_latch and always_ff)
|
||||||
|
- Added "xilinx_dffopt" pass
|
||||||
|
|
||||||
Yosys 0.8 .. Yosys 0.9
|
Yosys 0.8 .. Yosys 0.9
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
|
||||||
|
|
||||||
This directory contains Verific bindings for Yosys.
|
This directory contains Verific bindings for Yosys.
|
||||||
See http://www.verific.com/ for details.
|
|
||||||
|
Use Symbiotic EDA Suite if you need Yosys+Verifc.
|
||||||
|
https://www.symbioticeda.com/seda-suite
|
||||||
|
|
||||||
|
Contact office@symbioticeda.com for free evaluation
|
||||||
|
binaries of Symbiotic EDA Suite.
|
||||||
|
|
||||||
|
|
||||||
Verific Features that should be enabled in your Verific library
|
Verific Features that should be enabled in your Verific library
|
||||||
|
|
|
@ -2065,7 +2065,12 @@ struct VerificPass : public Pass {
|
||||||
log(" -d <dump_file>\n");
|
log(" -d <dump_file>\n");
|
||||||
log(" Dump the Verific netlist as a verilog file.\n");
|
log(" Dump the Verific netlist as a verilog file.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("Visit http://verific.com/ for more information on Verific.\n");
|
log("\n");
|
||||||
|
log("Use Symbiotic EDA Suite if you need Yosys+Verifc.\n");
|
||||||
|
log("https://www.symbioticeda.com/seda-suite\n");
|
||||||
|
log("\n");
|
||||||
|
log("Contact office@symbioticeda.com for free evaluation\n");
|
||||||
|
log("binaries of Symbiotic EDA Suite.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
#ifdef YOSYS_ENABLE_VERIFIC
|
#ifdef YOSYS_ENABLE_VERIFIC
|
||||||
|
@ -2074,7 +2079,13 @@ struct VerificPass : public Pass {
|
||||||
static bool set_verific_global_flags = true;
|
static bool set_verific_global_flags = true;
|
||||||
|
|
||||||
if (check_noverific_env())
|
if (check_noverific_env())
|
||||||
log_cmd_error("This version of Yosys is built without Verific support.\n");
|
log_cmd_error("This version of Yosys is built without Verific support.\n"
|
||||||
|
"\n"
|
||||||
|
"Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"
|
||||||
|
"https://www.symbioticeda.com/seda-suite\n"
|
||||||
|
"\n"
|
||||||
|
"Contact office@symbioticeda.com for free evaluation\n"
|
||||||
|
"binaries of Symbiotic EDA Suite.\n");
|
||||||
|
|
||||||
log_header(design, "Executing VERIFIC (loading SystemVerilog and VHDL designs using Verific).\n");
|
log_header(design, "Executing VERIFIC (loading SystemVerilog and VHDL designs using Verific).\n");
|
||||||
|
|
||||||
|
@ -2493,7 +2504,13 @@ struct VerificPass : public Pass {
|
||||||
}
|
}
|
||||||
#else /* YOSYS_ENABLE_VERIFIC */
|
#else /* YOSYS_ENABLE_VERIFIC */
|
||||||
void execute(std::vector<std::string>, RTLIL::Design *) YS_OVERRIDE {
|
void execute(std::vector<std::string>, RTLIL::Design *) YS_OVERRIDE {
|
||||||
log_cmd_error("This version of Yosys is built without Verific support.\n");
|
log_cmd_error("This version of Yosys is built without Verific support.\n"
|
||||||
|
"\n"
|
||||||
|
"Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"
|
||||||
|
"https://www.symbioticeda.com/seda-suite\n"
|
||||||
|
"\n"
|
||||||
|
"Contact office@symbioticeda.com for free evaluation\n"
|
||||||
|
"binaries of Symbiotic EDA Suite.\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} VerificPass;
|
} VerificPass;
|
||||||
|
|
|
@ -32,3 +32,4 @@ OBJS += passes/cmds/chtype.o
|
||||||
OBJS += passes/cmds/blackbox.o
|
OBJS += passes/cmds/blackbox.o
|
||||||
OBJS += passes/cmds/ltp.o
|
OBJS += passes/cmds/ltp.o
|
||||||
OBJS += passes/cmds/bugpoint.o
|
OBJS += passes/cmds/bugpoint.o
|
||||||
|
OBJS += passes/cmds/scratchpad.o
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* yosys -- Yosys Open SYnthesis Suite
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||||
|
* 2019 Nina Engelhardt <nak@symbioticeda.com>
|
||||||
|
*
|
||||||
|
* 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/register.h"
|
||||||
|
#include "kernel/rtlil.h"
|
||||||
|
#include "kernel/log.h"
|
||||||
|
|
||||||
|
USING_YOSYS_NAMESPACE
|
||||||
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
struct ScratchpadPass : public Pass {
|
||||||
|
ScratchpadPass() : Pass("scratchpad", "get/set values in the scratchpad") { }
|
||||||
|
void help() YS_OVERRIDE
|
||||||
|
{
|
||||||
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
log("\n");
|
||||||
|
log(" scratchpad [options]\n");
|
||||||
|
log("\n");
|
||||||
|
log("This pass allows to read and modify values from the scratchpad of the current\n");
|
||||||
|
log("design. Options:\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -get <identifier>\n");
|
||||||
|
log(" print the value saved in the scratchpad under the given identifier.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -set <identifier> <value>\n");
|
||||||
|
log(" save the given value in the scratchpad under the given identifier.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -unset <identifier>\n");
|
||||||
|
log(" remove the entry for the given identifier from the scratchpad.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -copy <identifier_from> <identifier_to>\n");
|
||||||
|
log(" copy the value of the first identifier to the second identifier.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -assert <identifier> <value>\n");
|
||||||
|
log(" assert that the entry for the given identifier is set to the given value.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -assert-set <identifier>\n");
|
||||||
|
log(" assert that the entry for the given identifier exists.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -assert-unset <identifier>\n");
|
||||||
|
log(" assert that the entry for the given identifier does not exist.\n");
|
||||||
|
log("\n");
|
||||||
|
log("The identifier may not contain whitespace. By convention, it is usually prefixed\n");
|
||||||
|
log("by the name of the pass that uses it, e.g. 'opt.did_something'. If the value\n");
|
||||||
|
log("contains whitespace, it must be enclosed in double quotes.\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] == "-get" && argidx+1 < args.size()) {
|
||||||
|
string identifier = args[++argidx];
|
||||||
|
if (design->scratchpad.count(identifier)){
|
||||||
|
log("%s\n", design->scratchpad_get_string(identifier).c_str());
|
||||||
|
} else {
|
||||||
|
log("\"%s\" not set\n", identifier.c_str());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-set" && argidx+2 < args.size()) {
|
||||||
|
string identifier = args[++argidx];
|
||||||
|
string value = args[++argidx];
|
||||||
|
if (value.front() == '\"' && value.back() == '\"') value = value.substr(1, value.size() - 2);
|
||||||
|
design->scratchpad_set_string(identifier, value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-unset" && argidx+1 < args.size()) {
|
||||||
|
string identifier = args[++argidx];
|
||||||
|
design->scratchpad_unset(identifier);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-copy" && argidx+2 < args.size()) {
|
||||||
|
string identifier_from = args[++argidx];
|
||||||
|
string identifier_to = args[++argidx];
|
||||||
|
if (design->scratchpad.count(identifier_from) == 0) log_error("\"%s\" not set\n", identifier_from.c_str());
|
||||||
|
string value = design->scratchpad_get_string(identifier_from);
|
||||||
|
design->scratchpad_set_string(identifier_to, value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-assert" && argidx+2 < args.size()) {
|
||||||
|
string identifier = args[++argidx];
|
||||||
|
string expected = args[++argidx];
|
||||||
|
if (expected.front() == '\"' && expected.back() == '\"') expected = expected.substr(1, expected.size() - 2);
|
||||||
|
if (design->scratchpad.count(identifier) == 0)
|
||||||
|
log_error("Assertion failed: scratchpad entry '%s' is not defined\n", identifier.c_str());
|
||||||
|
string value = design->scratchpad_get_string(identifier);
|
||||||
|
if (value != expected) {
|
||||||
|
log_error("Assertion failed: scratchpad entry '%s' is set to '%s' instead of the asserted '%s'\n",
|
||||||
|
identifier.c_str(), value.c_str(), expected.c_str());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-assert-set" && argidx+1 < args.size()) {
|
||||||
|
string identifier = args[++argidx];
|
||||||
|
if (design->scratchpad.count(identifier) == 0)
|
||||||
|
log_error("Assertion failed: scratchpad entry '%s' is not defined\n", identifier.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-assert-unset" && argidx+1 < args.size()) {
|
||||||
|
string identifier = args[++argidx];
|
||||||
|
if (design->scratchpad.count(identifier) > 0)
|
||||||
|
log_error("Assertion failed: scratchpad entry '%s' is defined\n", identifier.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
extra_args(args, argidx, design, false);
|
||||||
|
}
|
||||||
|
} ScratchpadPass;
|
||||||
|
PRIVATE_NAMESPACE_END
|
|
@ -44,6 +44,10 @@ struct EquivOptPass:public ScriptPass
|
||||||
log(" expand the modules in this file before proving equivalence. this is\n");
|
log(" expand the modules in this file before proving equivalence. this is\n");
|
||||||
log(" useful for handling architecture-specific primitives.\n");
|
log(" useful for handling architecture-specific primitives.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -blacklist <file>\n");
|
||||||
|
log(" Do not match cells or signals that match the names in the file\n");
|
||||||
|
log(" (passed to equiv_make).\n");
|
||||||
|
log("\n");
|
||||||
log(" -assert\n");
|
log(" -assert\n");
|
||||||
log(" produce an error if the circuits are not equivalent.\n");
|
log(" produce an error if the circuits are not equivalent.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
@ -61,13 +65,14 @@ struct EquivOptPass:public ScriptPass
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string command, techmap_opts;
|
std::string command, techmap_opts, make_opts;
|
||||||
bool assert, undef, multiclock, async2sync;
|
bool assert, undef, multiclock, async2sync;
|
||||||
|
|
||||||
void clear_flags() YS_OVERRIDE
|
void clear_flags() YS_OVERRIDE
|
||||||
{
|
{
|
||||||
command = "";
|
command = "";
|
||||||
techmap_opts = "";
|
techmap_opts = "";
|
||||||
|
make_opts = "";
|
||||||
assert = false;
|
assert = false;
|
||||||
undef = false;
|
undef = false;
|
||||||
multiclock = false;
|
multiclock = false;
|
||||||
|
@ -93,6 +98,10 @@ struct EquivOptPass:public ScriptPass
|
||||||
techmap_opts += " -map " + args[++argidx];
|
techmap_opts += " -map " + args[++argidx];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-blacklist" && argidx + 1 < args.size()) {
|
||||||
|
make_opts += " -blacklist " + args[++argidx];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (args[argidx] == "-assert") {
|
if (args[argidx] == "-assert") {
|
||||||
assert = true;
|
assert = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -170,7 +179,12 @@ struct EquivOptPass:public ScriptPass
|
||||||
run("clk2fflogic", "(only with -multiclock)");
|
run("clk2fflogic", "(only with -multiclock)");
|
||||||
if (async2sync || help_mode)
|
if (async2sync || help_mode)
|
||||||
run("async2sync", " (only with -async2sync)");
|
run("async2sync", " (only with -async2sync)");
|
||||||
run("equiv_make gold gate equiv");
|
string opts;
|
||||||
|
if (help_mode)
|
||||||
|
opts = " -blacklist <filename> ...";
|
||||||
|
else
|
||||||
|
opts = make_opts;
|
||||||
|
run("equiv_make" + opts + " gold gate equiv");
|
||||||
if (help_mode)
|
if (help_mode)
|
||||||
run("equiv_induct [-undef] equiv");
|
run("equiv_induct [-undef] equiv");
|
||||||
else if (undef)
|
else if (undef)
|
||||||
|
|
|
@ -47,6 +47,21 @@ module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .
|
||||||
module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||||
module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||||
|
|
||||||
|
`ifdef ASYNC_PRLD
|
||||||
|
module \$_DLATCH_N_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(!E), .DI(1'b0), .M(D), .Q(Q)); endmodule
|
||||||
|
module \$_DLATCH_P_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(E), .DI(1'b0), .M(D), .Q(Q)); endmodule
|
||||||
|
|
||||||
|
module \$_DFFSR_NNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule
|
||||||
|
module \$_DFFSR_NNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule
|
||||||
|
module \$_DFFSR_NPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule
|
||||||
|
module \$_DFFSR_NPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule
|
||||||
|
|
||||||
|
module \$_DFFSR_PNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule
|
||||||
|
module \$_DFFSR_PNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule
|
||||||
|
module \$_DFFSR_PPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule
|
||||||
|
module \$_DFFSR_PPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule
|
||||||
|
`endif
|
||||||
|
|
||||||
`include "cells_ff.vh"
|
`include "cells_ff.vh"
|
||||||
`include "cells_io.vh"
|
`include "cells_io.vh"
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,9 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
log(" -nowidelut\n");
|
log(" -nowidelut\n");
|
||||||
log(" do not use PFU muxes to implement LUTs larger than LUT4s\n");
|
log(" do not use PFU muxes to implement LUTs larger than LUT4s\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -asyncprld\n");
|
||||||
|
log(" use async PRLD mode to implement DLATCH and DFFSR (EXPERIMENTAL)\n");
|
||||||
|
log("\n");
|
||||||
log(" -abc2\n");
|
log(" -abc2\n");
|
||||||
log(" run two passes of 'abc' for slightly improved logic density\n");
|
log(" run two passes of 'abc' for slightly improved logic density\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
@ -99,7 +102,7 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
}
|
}
|
||||||
|
|
||||||
string top_opt, blif_file, edif_file, json_file;
|
string top_opt, blif_file, edif_file, json_file;
|
||||||
bool noccu2, nodffe, nobram, nolutram, nowidelut, flatten, retime, abc2, abc9, nodsp, vpr;
|
bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, retime, abc2, abc9, nodsp, vpr;
|
||||||
|
|
||||||
void clear_flags() YS_OVERRIDE
|
void clear_flags() YS_OVERRIDE
|
||||||
{
|
{
|
||||||
|
@ -112,6 +115,7 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
nobram = false;
|
nobram = false;
|
||||||
nolutram = false;
|
nolutram = false;
|
||||||
nowidelut = false;
|
nowidelut = false;
|
||||||
|
asyncprld = false;
|
||||||
flatten = true;
|
flatten = true;
|
||||||
retime = false;
|
retime = false;
|
||||||
abc2 = false;
|
abc2 = false;
|
||||||
|
@ -176,6 +180,10 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
nobram = true;
|
nobram = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-asyncprld") {
|
||||||
|
asyncprld = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") {
|
if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") {
|
||||||
nolutram = true;
|
nolutram = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -292,7 +300,7 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
run("opt_clean");
|
run("opt_clean");
|
||||||
if (!nodffe)
|
if (!nodffe)
|
||||||
run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
|
run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
|
||||||
run("techmap -D NO_LUT -map +/ecp5/cells_map.v");
|
run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : "")));
|
||||||
run("opt_expr -undriven -mux_undef");
|
run("opt_expr -undriven -mux_undef");
|
||||||
run("simplemap");
|
run("simplemap");
|
||||||
run("ecp5_ffinit");
|
run("ecp5_ffinit");
|
||||||
|
@ -306,10 +314,11 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
if (abc2 || help_mode) {
|
if (abc2 || help_mode) {
|
||||||
run("abc", " (only if -abc2)");
|
run("abc", " (only if -abc2)");
|
||||||
}
|
}
|
||||||
std::string techmap_args = "-map +/ecp5/latches_map.v";
|
std::string techmap_args = asyncprld ? "" : "-map +/ecp5/latches_map.v";
|
||||||
if (abc9)
|
if (abc9)
|
||||||
techmap_args += " -map +/ecp5/abc9_map.v -max_iter 1";
|
techmap_args += " -map +/ecp5/abc9_map.v -max_iter 1";
|
||||||
run("techmap " + techmap_args);
|
if (!asyncprld || abc9)
|
||||||
|
run("techmap " + techmap_args);
|
||||||
|
|
||||||
if (abc9) {
|
if (abc9) {
|
||||||
run("read_verilog -icells -lib +/ecp5/abc9_model.v");
|
run("read_verilog -icells -lib +/ecp5/abc9_model.v");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
OBJS += techlibs/xilinx/synth_xilinx.o
|
OBJS += techlibs/xilinx/synth_xilinx.o
|
||||||
|
OBJS += techlibs/xilinx/xilinx_dffopt.o
|
||||||
|
|
||||||
GENFILES += techlibs/xilinx/brams_init_36.vh
|
GENFILES += techlibs/xilinx/brams_init_36.vh
|
||||||
GENFILES += techlibs/xilinx/brams_init_32.vh
|
GENFILES += techlibs/xilinx/brams_init_32.vh
|
||||||
|
|
|
@ -28,6 +28,33 @@ module _90_dff_nn1_to_np1 (input D, C, R, output Q); \$_DFF_NP1_ _TECHMAP_REPL
|
||||||
(* techmap_celltype = "$_DFF_PN1_" *)
|
(* techmap_celltype = "$_DFF_PN1_" *)
|
||||||
module _90_dff_pn1_to_pp1 (input D, C, R, output Q); \$_DFF_PP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
|
module _90_dff_pn1_to_pp1 (input D, C, R, output Q); \$_DFF_PP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
|
||||||
|
|
||||||
|
(* techmap_celltype = "$__DFFE_NN0" *)
|
||||||
|
module _90_dffe_nn0_to_np0 (input D, C, R, E, output Q); \$__DFFE_NP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
|
||||||
|
(* techmap_celltype = "$__DFFE_PN0" *)
|
||||||
|
module _90_dffe_pn0_to_pp0 (input D, C, R, E, output Q); \$__DFFE_PP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
|
||||||
|
(* techmap_celltype = "$__DFFE_NN1" *)
|
||||||
|
module _90_dffe_nn1_to_np1 (input D, C, R, E, output Q); \$__DFFE_NP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
|
||||||
|
(* techmap_celltype = "$__DFFE_PN1" *)
|
||||||
|
module _90_dffe_pn1_to_pp1 (input D, C, R, E, output Q); \$__DFFE_PP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
|
||||||
|
|
||||||
|
(* techmap_celltype = "$__DFFS_NN0_" *)
|
||||||
|
module _90_dffs_nn0_to_np0 (input D, C, R, output Q); \$__DFFS_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
|
||||||
|
(* techmap_celltype = "$__DFFS_PN0_" *)
|
||||||
|
module _90_dffs_pn0_to_pp0 (input D, C, R, output Q); \$__DFFS_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
|
||||||
|
(* techmap_celltype = "$__DFFS_NN1_" *)
|
||||||
|
module _90_dffs_nn1_to_np1 (input D, C, R, output Q); \$__DFFS_NP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
|
||||||
|
(* techmap_celltype = "$__DFFS_PN1_" *)
|
||||||
|
module _90_dffs_pn1_to_pp1 (input D, C, R, output Q); \$__DFFS_PP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
|
||||||
|
|
||||||
|
(* techmap_celltype = "$__DFFSE_NN0" *)
|
||||||
|
module _90_dffse_nn0_to_np0 (input D, C, R, E, output Q); \$__DFFSE_NP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
|
||||||
|
(* techmap_celltype = "$__DFFSE_PN0" *)
|
||||||
|
module _90_dffse_pn0_to_pp0 (input D, C, R, E, output Q); \$__DFFSE_PP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
|
||||||
|
(* techmap_celltype = "$__DFFSE_NN1" *)
|
||||||
|
module _90_dffse_nn1_to_np1 (input D, C, R, E, output Q); \$__DFFSE_NP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
|
||||||
|
(* techmap_celltype = "$__DFFSE_PN1" *)
|
||||||
|
module _90_dffse_pn1_to_pp1 (input D, C, R, E, output Q); \$__DFFSE_PP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
|
||||||
|
|
||||||
module \$__SHREG_ (input C, input D, input E, output Q);
|
module \$__SHREG_ (input C, input D, input E, output Q);
|
||||||
parameter DEPTH = 0;
|
parameter DEPTH = 0;
|
||||||
parameter [DEPTH-1:0] INIT = 0;
|
parameter [DEPTH-1:0] INIT = 0;
|
||||||
|
|
|
@ -329,6 +329,41 @@ module FDSE (
|
||||||
endcase endgenerate
|
endcase endgenerate
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
module FDRSE (
|
||||||
|
output reg Q,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
(* invertible_pin = "IS_C_INVERTED" *)
|
||||||
|
input C,
|
||||||
|
(* invertible_pin = "IS_CE_INVERTED" *)
|
||||||
|
input CE,
|
||||||
|
(* invertible_pin = "IS_D_INVERTED" *)
|
||||||
|
input D,
|
||||||
|
(* invertible_pin = "IS_R_INVERTED" *)
|
||||||
|
input R,
|
||||||
|
(* invertible_pin = "IS_S_INVERTED" *)
|
||||||
|
input S
|
||||||
|
);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||||
|
parameter [0:0] IS_CE_INVERTED = 1'b0;
|
||||||
|
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||||
|
parameter [0:0] IS_R_INVERTED = 1'b0;
|
||||||
|
parameter [0:0] IS_S_INVERTED = 1'b0;
|
||||||
|
initial Q <= INIT;
|
||||||
|
wire c = C ^ IS_C_INVERTED;
|
||||||
|
wire ce = CE ^ IS_CE_INVERTED;
|
||||||
|
wire d = D ^ IS_D_INVERTED;
|
||||||
|
wire r = R ^ IS_R_INVERTED;
|
||||||
|
wire s = S ^ IS_S_INVERTED;
|
||||||
|
always @(posedge c)
|
||||||
|
if (r)
|
||||||
|
Q <= 0;
|
||||||
|
else if (s)
|
||||||
|
Q <= 1;
|
||||||
|
else if (ce)
|
||||||
|
Q <= d;
|
||||||
|
endmodule
|
||||||
|
|
||||||
module FDCE (
|
module FDCE (
|
||||||
(* abc9_arrival=303 *)
|
(* abc9_arrival=303 *)
|
||||||
output reg Q,
|
output reg Q,
|
||||||
|
|
|
@ -66,7 +66,7 @@ CELLS = [
|
||||||
# CLB -- registers/latches.
|
# CLB -- registers/latches.
|
||||||
# Virtex 1/2/4/5, Spartan 3.
|
# Virtex 1/2/4/5, Spartan 3.
|
||||||
Cell('FDCPE', port_attrs={'C': ['clkbuf_sink']}),
|
Cell('FDCPE', port_attrs={'C': ['clkbuf_sink']}),
|
||||||
Cell('FDRSE', port_attrs={'C': ['clkbuf_sink']}),
|
# Cell('FDRSE', port_attrs={'C': ['clkbuf_sink']}),
|
||||||
Cell('LDCPE', port_attrs={'C': ['clkbuf_sink']}),
|
Cell('LDCPE', port_attrs={'C': ['clkbuf_sink']}),
|
||||||
# Virtex 6, Spartan 6, Series 7, Ultrascale.
|
# Virtex 6, Spartan 6, Series 7, Ultrascale.
|
||||||
# Cell('FDCE'),
|
# Cell('FDCE'),
|
||||||
|
|
|
@ -17,27 +17,6 @@ module FDCPE (...);
|
||||||
input PRE;
|
input PRE;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module FDRSE (...);
|
|
||||||
parameter [0:0] INIT = 1'b0;
|
|
||||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
|
||||||
parameter [0:0] IS_CE_INVERTED = 1'b0;
|
|
||||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
|
||||||
parameter [0:0] IS_R_INVERTED = 1'b0;
|
|
||||||
parameter [0:0] IS_S_INVERTED = 1'b0;
|
|
||||||
output Q;
|
|
||||||
(* clkbuf_sink *)
|
|
||||||
(* invertible_pin = "IS_C_INVERTED" *)
|
|
||||||
input C;
|
|
||||||
(* invertible_pin = "IS_CE_INVERTED" *)
|
|
||||||
input CE;
|
|
||||||
(* invertible_pin = "IS_D_INVERTED" *)
|
|
||||||
input D;
|
|
||||||
(* invertible_pin = "IS_R_INVERTED" *)
|
|
||||||
input R;
|
|
||||||
(* invertible_pin = "IS_S_INVERTED" *)
|
|
||||||
input S;
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
module LDCPE (...);
|
module LDCPE (...);
|
||||||
parameter [0:0] INIT = 1'b0;
|
parameter [0:0] INIT = 1'b0;
|
||||||
parameter [0:0] IS_CLR_INVERTED = 1'b0;
|
parameter [0:0] IS_CLR_INVERTED = 1'b0;
|
||||||
|
|
|
@ -444,6 +444,16 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_label("map_ffram")) {
|
if (check_label("map_ffram")) {
|
||||||
|
// Required for dffsr2dff to work.
|
||||||
|
run("simplemap t:$dff t:$adff t:$mux");
|
||||||
|
// Needs to be done before opt -mux_bool happens.
|
||||||
|
run("dffsr2dff");
|
||||||
|
if (help_mode)
|
||||||
|
run("dff2dffs [-match-init]", "(-match-init for xc6s only)");
|
||||||
|
else if (family == "xc6s")
|
||||||
|
run("dff2dffs -match-init");
|
||||||
|
else
|
||||||
|
run("dff2dffs");
|
||||||
if (widemux > 0)
|
if (widemux > 0)
|
||||||
run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover
|
run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover
|
||||||
// performs less efficiently
|
// performs less efficiently
|
||||||
|
@ -453,14 +463,11 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_label("fine")) {
|
if (check_label("fine")) {
|
||||||
run("dffsr2dff");
|
run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
|
||||||
run("dff2dffe");
|
|
||||||
if (help_mode) {
|
if (help_mode) {
|
||||||
run("simplemap t:$mux", " ('-widemux' only)");
|
|
||||||
run("muxcover <internal options>, ('-widemux' only)");
|
run("muxcover <internal options>, ('-widemux' only)");
|
||||||
}
|
}
|
||||||
else if (widemux > 0) {
|
else if (widemux > 0) {
|
||||||
run("simplemap t:$mux");
|
|
||||||
constexpr int cost_mux2 = 100;
|
constexpr int cost_mux2 = 100;
|
||||||
std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2);
|
std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2);
|
||||||
switch (widemux) {
|
switch (widemux) {
|
||||||
|
@ -563,6 +570,7 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
else
|
else
|
||||||
techmap_args += " -map " + ff_map_file;
|
techmap_args += " -map " + ff_map_file;
|
||||||
run("techmap " + techmap_args);
|
run("techmap " + techmap_args);
|
||||||
|
run("xilinx_dffopt");
|
||||||
run("clean");
|
run("clean");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
`ifndef _NO_FFS
|
`ifndef _NO_FFS
|
||||||
|
|
||||||
|
// No reset.
|
||||||
|
|
||||||
module \$_DFF_N_ (input D, C, output Q);
|
module \$_DFF_N_ (input D, C, output Q);
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
@ -46,6 +48,8 @@ module \$_DFF_P_ (input D, C, output Q);
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// No reset, enable.
|
||||||
|
|
||||||
module \$_DFFE_NP_ (input D, C, E, output Q);
|
module \$_DFFE_NP_ (input D, C, E, output Q);
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
@ -65,15 +69,8 @@ module \$_DFFE_PP_ (input D, C, E, output Q);
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module \$_DFF_NN0_ (input D, C, R, output Q);
|
// Async reset.
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
|
||||||
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
|
|
||||||
else
|
|
||||||
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
|
|
||||||
endgenerate
|
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
|
||||||
endmodule
|
|
||||||
module \$_DFF_NP0_ (input D, C, R, output Q);
|
module \$_DFF_NP0_ (input D, C, R, output Q);
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
@ -83,15 +80,6 @@ module \$_DFF_NP0_ (input D, C, R, output Q);
|
||||||
endgenerate
|
endgenerate
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
module \$_DFF_PN0_ (input D, C, R, output Q);
|
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
|
||||||
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
|
|
||||||
else
|
|
||||||
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
|
|
||||||
endgenerate
|
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
|
||||||
endmodule
|
|
||||||
module \$_DFF_PP0_ (input D, C, R, output Q);
|
module \$_DFF_PP0_ (input D, C, R, output Q);
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
@ -102,15 +90,6 @@ module \$_DFF_PP0_ (input D, C, R, output Q);
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module \$_DFF_NN1_ (input D, C, R, output Q);
|
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
|
||||||
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
|
|
||||||
else
|
|
||||||
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
|
|
||||||
endgenerate
|
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
|
||||||
endmodule
|
|
||||||
module \$_DFF_NP1_ (input D, C, R, output Q);
|
module \$_DFF_NP1_ (input D, C, R, output Q);
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||||
|
@ -120,15 +99,6 @@ module \$_DFF_NP1_ (input D, C, R, output Q);
|
||||||
endgenerate
|
endgenerate
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
module \$_DFF_PN1_ (input D, C, R, output Q);
|
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
|
||||||
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
|
|
||||||
else
|
|
||||||
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
|
|
||||||
endgenerate
|
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
|
||||||
endmodule
|
|
||||||
module \$_DFF_PP1_ (input D, C, R, output Q);
|
module \$_DFF_PP1_ (input D, C, R, output Q);
|
||||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||||
|
@ -139,6 +109,128 @@ module \$_DFF_PP1_ (input D, C, R, output Q);
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// Async reset, enable.
|
||||||
|
|
||||||
|
module \$__DFFE_NP0 (input D, C, E, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
|
||||||
|
else
|
||||||
|
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFE_PP0 (input D, C, E, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
|
||||||
|
else
|
||||||
|
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$__DFFE_NP1 (input D, C, E, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||||
|
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
|
||||||
|
else
|
||||||
|
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFE_PP1 (input D, C, E, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||||
|
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
|
||||||
|
else
|
||||||
|
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Sync reset.
|
||||||
|
|
||||||
|
module \$__DFFS_NP0_ (input D, C, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
$error("Spartan 6 doesn't support FFs with reset initialized to 1");
|
||||||
|
else
|
||||||
|
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFS_PP0_ (input D, C, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
$error("Spartan 6 doesn't support FFs with reset initialized to 1");
|
||||||
|
else
|
||||||
|
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$__DFFS_NP1_ (input D, C, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||||
|
$error("Spartan 6 doesn't support FFs with set initialized to 0");
|
||||||
|
else
|
||||||
|
FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFS_PP1_ (input D, C, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||||
|
$error("Spartan 6 doesn't support FFs with set initialized to 0");
|
||||||
|
else
|
||||||
|
FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Sync reset, enable.
|
||||||
|
|
||||||
|
module \$__DFFSE_NP0 (input D, C, E, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
$error("Spartan 6 doesn't support FFs with reset initialized to 1");
|
||||||
|
else
|
||||||
|
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFSE_PP0 (input D, C, E, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
$error("Spartan 6 doesn't support FFs with reset initialized to 1");
|
||||||
|
else
|
||||||
|
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$__DFFSE_NP1 (input D, C, E, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||||
|
$error("Spartan 6 doesn't support FFs with set initialized to 0");
|
||||||
|
else
|
||||||
|
FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFSE_PP1 (input D, C, E, R, output Q);
|
||||||
|
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||||
|
$error("Spartan 6 doesn't support FFs with set initialized to 0");
|
||||||
|
else
|
||||||
|
FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R));
|
||||||
|
endgenerate
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Latches (no reset).
|
||||||
|
|
||||||
module \$_DLATCH_N_ (input E, D, output Q);
|
module \$_DLATCH_N_ (input E, D, output Q);
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||||
|
@ -158,5 +250,7 @@ module \$_DLATCH_P_ (input E, D, output Q);
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// Latches with reset (TODO).
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
|
|
||||||
`ifndef _NO_FFS
|
`ifndef _NO_FFS
|
||||||
|
|
||||||
|
// No reset.
|
||||||
|
|
||||||
module \$_DFF_N_ (input D, C, output Q);
|
module \$_DFF_N_ (input D, C, output Q);
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
|
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
|
||||||
|
@ -48,6 +50,8 @@ module \$_DFF_P_ (input D, C, output Q);
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// No reset, enable.
|
||||||
|
|
||||||
module \$_DFFE_NP_ (input D, C, E, output Q);
|
module \$_DFFE_NP_ (input D, C, E, output Q);
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
|
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
|
||||||
|
@ -59,48 +63,104 @@ module \$_DFFE_PP_ (input D, C, E, output Q);
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module \$_DFF_NN0_ (input D, C, R, output Q);
|
// Async reset.
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
|
||||||
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
|
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
|
||||||
endmodule
|
|
||||||
module \$_DFF_NP0_ (input D, C, R, output Q);
|
module \$_DFF_NP0_ (input D, C, R, output Q);
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
|
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
module \$_DFF_PN0_ (input D, C, R, output Q);
|
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
|
||||||
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
|
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
|
||||||
endmodule
|
|
||||||
module \$_DFF_PP0_ (input D, C, R, output Q);
|
module \$_DFF_PP0_ (input D, C, R, output Q);
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
|
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module \$_DFF_NN1_ (input D, C, R, output Q);
|
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
|
||||||
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
|
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
|
||||||
endmodule
|
|
||||||
module \$_DFF_NP1_ (input D, C, R, output Q);
|
module \$_DFF_NP1_ (input D, C, R, output Q);
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
|
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
module \$_DFF_PN1_ (input D, C, R, output Q);
|
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
|
||||||
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
|
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
|
||||||
endmodule
|
|
||||||
module \$_DFF_PP1_ (input D, C, R, output Q);
|
module \$_DFF_PP1_ (input D, C, R, output Q);
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
|
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// Async reset, enable.
|
||||||
|
|
||||||
|
module \$__DFFE_NP0 (input D, C, E, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFE_PP0 (input D, C, E, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$__DFFE_NP1 (input D, C, E, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFE_PP1 (input D, C, E, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Sync reset.
|
||||||
|
|
||||||
|
module \$__DFFS_NP0_ (input D, C, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFS_PP0_ (input D, C, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$__DFFS_NP1_ (input D, C, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFS_PP1_ (input D, C, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Sync reset, enable.
|
||||||
|
|
||||||
|
module \$__DFFSE_NP0 (input D, C, E, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFSE_PP0 (input D, C, E, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$__DFFSE_NP1 (input D, C, E, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
module \$__DFFSE_PP1 (input D, C, E, R, output Q);
|
||||||
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
|
FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Latches (no reset).
|
||||||
|
|
||||||
module \$_DLATCH_N_ (input E, D, output Q);
|
module \$_DLATCH_N_ (input E, D, output Q);
|
||||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||||
LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
|
LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
|
||||||
|
@ -112,5 +172,7 @@ module \$_DLATCH_P_ (input E, D, output Q);
|
||||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// Latches with reset (TODO).
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,351 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
#include "kernel/sigtools.h"
|
||||||
|
|
||||||
|
USING_YOSYS_NAMESPACE
|
||||||
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
typedef std::pair<Const, std::vector<SigBit>> LutData;
|
||||||
|
|
||||||
|
// Compute a LUT implementing (select ^ select_inv) ? alt_data : data. Returns true if successful.
|
||||||
|
bool merge_lut(LutData &result, const LutData &data, const LutData select, bool select_inv, SigBit alt_data, int max_lut_size) {
|
||||||
|
// First, gather input signals.
|
||||||
|
result.second = data.second;
|
||||||
|
int idx_alt = -1;
|
||||||
|
if (alt_data.wire) {
|
||||||
|
// Check if we already have it.
|
||||||
|
for (int i = 0; i < GetSize(result.second); i++)
|
||||||
|
if (result.second[i] == alt_data)
|
||||||
|
idx_alt = i;
|
||||||
|
// If not, add it.
|
||||||
|
if (idx_alt == -1) {
|
||||||
|
idx_alt = GetSize(result.second);
|
||||||
|
result.second.push_back(alt_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::vector<int> idx_sel;
|
||||||
|
for (auto bit : select.second) {
|
||||||
|
int idx = -1;
|
||||||
|
for (int i = 0; i < GetSize(result.second); i++)
|
||||||
|
if (result.second[i] == bit)
|
||||||
|
idx = i;
|
||||||
|
if (idx == -1) {
|
||||||
|
idx = GetSize(result.second);
|
||||||
|
result.second.push_back(bit);
|
||||||
|
}
|
||||||
|
idx_sel.push_back(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If LUT would be too large, bail.
|
||||||
|
if (GetSize(result.second) > max_lut_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Okay, we're doing it — compute the LUT mask.
|
||||||
|
result.first = Const(0, 1 << GetSize(result.second));
|
||||||
|
for (int i = 0; i < GetSize(result.first); i++) {
|
||||||
|
int sel_lut_idx = 0;
|
||||||
|
for (int j = 0; j < GetSize(select.second); j++)
|
||||||
|
if (i & 1 << idx_sel[j])
|
||||||
|
sel_lut_idx |= 1 << j;
|
||||||
|
bool select_val = (select.first.bits[sel_lut_idx] == State::S1);
|
||||||
|
bool new_bit;
|
||||||
|
if (select_val ^ select_inv) {
|
||||||
|
// Use alt_data.
|
||||||
|
if (alt_data.wire)
|
||||||
|
new_bit = (i & 1 << idx_alt) != 0;
|
||||||
|
else
|
||||||
|
new_bit = alt_data.data == State::S1;
|
||||||
|
} else {
|
||||||
|
// Use original LUT.
|
||||||
|
int lut_idx = i & ((1 << GetSize(data.second)) - 1);
|
||||||
|
new_bit = data.first.bits[lut_idx] == State::S1;
|
||||||
|
}
|
||||||
|
result.first.bits[i] = new_bit ? State::S1 : State::S0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XilinxDffOptPass : public Pass {
|
||||||
|
XilinxDffOptPass() : Pass("xilinx_dffopt", "Xilinx: optimize FF control signal usage") { }
|
||||||
|
void help() YS_OVERRIDE
|
||||||
|
{
|
||||||
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
log("\n");
|
||||||
|
log(" xilinx_dffopt [options] [selection]\n");
|
||||||
|
log("\n");
|
||||||
|
log("Converts hardware clock enable and set/reset signals on FFs to emulation\n");
|
||||||
|
log("using LUTs, if doing so would improve area. Operates on post-techmap Xilinx\n");
|
||||||
|
log("cells (LUT*, FD*).\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -lut4\n");
|
||||||
|
log(" Assume a LUT4-based device (instead of a LUT6-based device).\n");
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
|
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||||
|
{
|
||||||
|
log_header(design, "Executing XILINX_DFFOPT pass (optimize FF control signal usage).\n");
|
||||||
|
|
||||||
|
size_t argidx;
|
||||||
|
int max_lut_size = 6;
|
||||||
|
for (argidx = 1; argidx < args.size(); argidx++)
|
||||||
|
{
|
||||||
|
if (args[argidx] == "-lut4") {
|
||||||
|
max_lut_size = 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
|
for (auto module : design->selected_modules())
|
||||||
|
{
|
||||||
|
log("Optimizing FFs in %s.\n", log_id(module));
|
||||||
|
|
||||||
|
SigMap sigmap(module);
|
||||||
|
dict<SigBit, pair<LutData, Cell *>> bit_to_lut;
|
||||||
|
dict<SigBit, int> bit_uses;
|
||||||
|
|
||||||
|
// Gather LUTs.
|
||||||
|
for (auto cell : module->selected_cells())
|
||||||
|
{
|
||||||
|
for (auto port : cell->connections())
|
||||||
|
for (auto bit : port.second)
|
||||||
|
bit_uses[sigmap(bit)]++;
|
||||||
|
if (cell->get_bool_attribute(ID::keep))
|
||||||
|
continue;
|
||||||
|
if (cell->type == ID(INV)) {
|
||||||
|
SigBit sigout = sigmap(cell->getPort(ID(O)));
|
||||||
|
SigBit sigin = sigmap(cell->getPort(ID(I)));
|
||||||
|
bit_to_lut[sigout] = make_pair(LutData(Const(1, 2), {sigin}), cell);
|
||||||
|
} else if (cell->type.in(ID(LUT1), ID(LUT2), ID(LUT3), ID(LUT4), ID(LUT5), ID(LUT6))) {
|
||||||
|
SigBit sigout = sigmap(cell->getPort(ID(O)));
|
||||||
|
const Const &init = cell->getParam(ID(INIT));
|
||||||
|
std::vector<SigBit> sigin;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(I0))));
|
||||||
|
if (cell->type == ID(LUT1))
|
||||||
|
goto lut_sigin_done;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(I1))));
|
||||||
|
if (cell->type == ID(LUT2))
|
||||||
|
goto lut_sigin_done;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(I2))));
|
||||||
|
if (cell->type == ID(LUT3))
|
||||||
|
goto lut_sigin_done;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(I3))));
|
||||||
|
if (cell->type == ID(LUT4))
|
||||||
|
goto lut_sigin_done;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(I4))));
|
||||||
|
if (cell->type == ID(LUT5))
|
||||||
|
goto lut_sigin_done;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(I5))));
|
||||||
|
lut_sigin_done:
|
||||||
|
bit_to_lut[sigout] = make_pair(LutData(init, sigin), cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto wire : module->wires())
|
||||||
|
if (wire->port_output || wire->port_input)
|
||||||
|
for (int i = 0; i < GetSize(wire); i++)
|
||||||
|
bit_uses[sigmap(SigBit(wire, i))]++;
|
||||||
|
|
||||||
|
// Iterate through FFs.
|
||||||
|
for (auto cell : module->selected_cells())
|
||||||
|
{
|
||||||
|
bool has_s = false, has_r = false;
|
||||||
|
if (cell->type.in(ID(FDCE), ID(FDPE), ID(FDCPE), ID(FDCE_1), ID(FDPE_1), ID(FDCPE_1))) {
|
||||||
|
// Async reset.
|
||||||
|
} else if (cell->type.in(ID(FDRE), ID(FDRE_1))) {
|
||||||
|
has_r = true;
|
||||||
|
} else if (cell->type.in(ID(FDSE), ID(FDSE_1))) {
|
||||||
|
has_s = true;
|
||||||
|
} else if (cell->type.in(ID(FDRSE), ID(FDRSE_1))) {
|
||||||
|
has_r = true;
|
||||||
|
has_s = true;
|
||||||
|
} else {
|
||||||
|
// Not a FF.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cell->get_bool_attribute(ID::keep))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Don't bother if D has more than one use.
|
||||||
|
SigBit sig_D = sigmap(cell->getPort(ID(D)));
|
||||||
|
if (bit_uses[sig_D] > 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Find the D LUT.
|
||||||
|
auto it_D = bit_to_lut.find(sig_D);
|
||||||
|
if (it_D == bit_to_lut.end())
|
||||||
|
continue;
|
||||||
|
LutData lut_d = it_D->second.first;
|
||||||
|
Cell *cell_d = it_D->second.second;
|
||||||
|
if (cell->hasParam(ID(IS_D_INVERTED)) && cell->getParam(ID(IS_D_INVERTED)).as_bool()) {
|
||||||
|
// Flip all bits in the LUT.
|
||||||
|
for (int i = 0; i < GetSize(lut_d.first); i++)
|
||||||
|
lut_d.first.bits[i] = (lut_d.first.bits[i] == State::S1) ? State::S0 : State::S1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LutData lut_d_post_ce;
|
||||||
|
LutData lut_d_post_s;
|
||||||
|
LutData lut_d_post_r;
|
||||||
|
bool worthy_post_ce = false;
|
||||||
|
bool worthy_post_s = false;
|
||||||
|
bool worthy_post_r = false;
|
||||||
|
|
||||||
|
// First, unmap CE.
|
||||||
|
SigBit sig_Q = sigmap(cell->getPort(ID(Q)));
|
||||||
|
SigBit sig_CE = sigmap(cell->getPort(ID(CE)));
|
||||||
|
LutData lut_ce = LutData(Const(2, 2), {sig_CE});
|
||||||
|
auto it_CE = bit_to_lut.find(sig_CE);
|
||||||
|
if (it_CE != bit_to_lut.end())
|
||||||
|
lut_ce = it_CE->second.first;
|
||||||
|
if (sig_CE.wire) {
|
||||||
|
// Merge CE LUT and D LUT into one. If it cannot be done, nothing to do about this FF.
|
||||||
|
if (!merge_lut(lut_d_post_ce, lut_d, lut_ce, true, sig_Q, max_lut_size))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If this gets rid of a CE LUT, it's worth it. If not, it still may be worth it, if we can remove set/reset as well.
|
||||||
|
if (it_CE != bit_to_lut.end())
|
||||||
|
worthy_post_ce = true;
|
||||||
|
} else if (sig_CE.data != State::S1) {
|
||||||
|
// Strange. Should not happen in a reasonable flow, so bail.
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
lut_d_post_ce = lut_d;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second, unmap S, if any.
|
||||||
|
lut_d_post_s = lut_d_post_ce;
|
||||||
|
if (has_s) {
|
||||||
|
SigBit sig_S = sigmap(cell->getPort(ID(S)));
|
||||||
|
LutData lut_s = LutData(Const(2, 2), {sig_S});
|
||||||
|
bool inv_s = cell->hasParam(ID(IS_S_INVERTED)) && cell->getParam(ID(IS_S_INVERTED)).as_bool();
|
||||||
|
auto it_S = bit_to_lut.find(sig_S);
|
||||||
|
if (it_S != bit_to_lut.end())
|
||||||
|
lut_s = it_S->second.first;
|
||||||
|
if (sig_S.wire) {
|
||||||
|
// Merge S LUT and D LUT into one. If it cannot be done, try to at least merge CE.
|
||||||
|
if (!merge_lut(lut_d_post_s, lut_d_post_ce, lut_s, inv_s, SigBit(State::S1), max_lut_size))
|
||||||
|
goto unmap;
|
||||||
|
// If this gets rid of an S LUT, it's worth it.
|
||||||
|
if (it_S != bit_to_lut.end())
|
||||||
|
worthy_post_s = true;
|
||||||
|
} else if (sig_S.data != (inv_s ? State::S1 : State::S0)) {
|
||||||
|
// Strange. Should not happen in a reasonable flow, so bail.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Third, unmap R, if any.
|
||||||
|
lut_d_post_r = lut_d_post_s;
|
||||||
|
if (has_r) {
|
||||||
|
SigBit sig_R = sigmap(cell->getPort(ID(R)));
|
||||||
|
LutData lut_r = LutData(Const(2, 2), {sig_R});
|
||||||
|
bool inv_r = cell->hasParam(ID(IS_R_INVERTED)) && cell->getParam(ID(IS_R_INVERTED)).as_bool();
|
||||||
|
auto it_R = bit_to_lut.find(sig_R);
|
||||||
|
if (it_R != bit_to_lut.end())
|
||||||
|
lut_r = it_R->second.first;
|
||||||
|
if (sig_R.wire) {
|
||||||
|
// Merge R LUT and D LUT into one. If it cannot be done, try to at least merge CE/S.
|
||||||
|
if (!merge_lut(lut_d_post_r, lut_d_post_s, lut_r, inv_r, SigBit(State::S0), max_lut_size))
|
||||||
|
goto unmap;
|
||||||
|
// If this gets rid of an S LUT, it's worth it.
|
||||||
|
if (it_R != bit_to_lut.end())
|
||||||
|
worthy_post_r = true;
|
||||||
|
} else if (sig_R.data != (inv_r ? State::S1 : State::S0)) {
|
||||||
|
// Strange. Should not happen in a reasonable flow, so bail.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unmap:
|
||||||
|
LutData final_lut;
|
||||||
|
if (worthy_post_r) {
|
||||||
|
final_lut = lut_d_post_r;
|
||||||
|
log(" Merging R LUT for %s/%s (%d -> %d)\n", log_id(cell), log_id(sig_Q.wire), GetSize(lut_d.second), GetSize(final_lut.second));
|
||||||
|
} else if (worthy_post_s) {
|
||||||
|
final_lut = lut_d_post_s;
|
||||||
|
log(" Merging S LUT for %s/%s (%d -> %d)\n", log_id(cell), log_id(sig_Q.wire), GetSize(lut_d.second), GetSize(final_lut.second));
|
||||||
|
} else if (worthy_post_ce) {
|
||||||
|
final_lut = lut_d_post_ce;
|
||||||
|
log(" Merging CE LUT for %s/%s (%d -> %d)\n", log_id(cell), log_id(sig_Q.wire), GetSize(lut_d.second), GetSize(final_lut.second));
|
||||||
|
} else {
|
||||||
|
// Nothing to do here.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Okay, we're doing it. Unmap ports.
|
||||||
|
if (worthy_post_r) {
|
||||||
|
cell->unsetParam(ID(IS_R_INVERTED));
|
||||||
|
cell->setPort(ID(R), Const(0, 1));
|
||||||
|
}
|
||||||
|
if (has_s && (worthy_post_r || worthy_post_s)) {
|
||||||
|
cell->unsetParam(ID(IS_S_INVERTED));
|
||||||
|
cell->setPort(ID(S), Const(0, 1));
|
||||||
|
}
|
||||||
|
cell->setPort(ID(CE), Const(1, 1));
|
||||||
|
cell->unsetParam(ID(IS_D_INVERTED));
|
||||||
|
|
||||||
|
// Create the new LUT.
|
||||||
|
Cell *lut_cell = 0;
|
||||||
|
switch (GetSize(final_lut.second)) {
|
||||||
|
case 1:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(LUT1));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(LUT2));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(LUT3));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(LUT4));
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(LUT5));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(LUT6));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log_assert(!"unknown lut size");
|
||||||
|
}
|
||||||
|
lut_cell->attributes = cell_d->attributes;
|
||||||
|
Wire *lut_out = module->addWire(NEW_ID);
|
||||||
|
lut_cell->setParam(ID(INIT), final_lut.first);
|
||||||
|
cell->setPort(ID(D), lut_out);
|
||||||
|
lut_cell->setPort(ID(O), lut_out);
|
||||||
|
lut_cell->setPort(ID(I0), final_lut.second[0]);
|
||||||
|
if (GetSize(final_lut.second) >= 2)
|
||||||
|
lut_cell->setPort(ID(I1), final_lut.second[1]);
|
||||||
|
if (GetSize(final_lut.second) >= 3)
|
||||||
|
lut_cell->setPort(ID(I2), final_lut.second[2]);
|
||||||
|
if (GetSize(final_lut.second) >= 4)
|
||||||
|
lut_cell->setPort(ID(I3), final_lut.second[3]);
|
||||||
|
if (GetSize(final_lut.second) >= 5)
|
||||||
|
lut_cell->setPort(ID(I4), final_lut.second[4]);
|
||||||
|
if (GetSize(final_lut.second) >= 6)
|
||||||
|
lut_cell->setPort(ID(I5), final_lut.second[5]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} XilinxDffOptPass;
|
||||||
|
|
||||||
|
PRIVATE_NAMESPACE_END
|
||||||
|
|
|
@ -32,10 +32,9 @@ equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivale
|
||||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
cd dffs # Constrain all select calls below inside the top module
|
cd dffs # Constrain all select calls below inside the top module
|
||||||
select -assert-count 1 t:BUFG
|
select -assert-count 1 t:BUFG
|
||||||
select -assert-count 1 t:FDRE
|
select -assert-count 1 t:FDSE
|
||||||
select -assert-count 1 t:LUT2
|
|
||||||
|
|
||||||
select -assert-none t:BUFG t:FDRE t:LUT2 %% t:* %D
|
select -assert-none t:BUFG t:FDSE %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
design -load read
|
design -load read
|
||||||
|
@ -46,6 +45,6 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p
|
||||||
cd ndffnr # Constrain all select calls below inside the top module
|
cd ndffnr # Constrain all select calls below inside the top module
|
||||||
select -assert-count 1 t:BUFG
|
select -assert-count 1 t:BUFG
|
||||||
select -assert-count 1 t:FDRE_1
|
select -assert-count 1 t:FDRE_1
|
||||||
select -assert-count 1 t:LUT2
|
select -assert-count 1 t:INV
|
||||||
|
|
||||||
select -assert-none t:BUFG t:FDRE_1 t:LUT2 %% t:* %D
|
select -assert-none t:BUFG t:FDRE_1 t:INV %% t:* %D
|
||||||
|
|
|
@ -11,8 +11,9 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p
|
||||||
cd fsm # Constrain all select calls below inside the top module
|
cd fsm # Constrain all select calls below inside the top module
|
||||||
|
|
||||||
select -assert-count 1 t:BUFG
|
select -assert-count 1 t:BUFG
|
||||||
select -assert-count 5 t:FDRE
|
select -assert-count 4 t:FDRE
|
||||||
select -assert-count 1 t:LUT3
|
select -assert-count 1 t:FDSE
|
||||||
select -assert-count 2 t:LUT4
|
select -assert-count 1 t:LUT2
|
||||||
select -assert-count 4 t:LUT6
|
select -assert-count 3 t:LUT5
|
||||||
select -assert-none t:BUFG t:FDRE t:LUT3 t:LUT4 t:LUT6 %% t:* %D
|
select -assert-count 1 t:LUT6
|
||||||
|
select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D
|
||||||
|
|
|
@ -23,9 +23,10 @@ miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
sat -verify -prove-asserts -seq 10 -show-inputs -show-outputs miter
|
sat -verify -prove-asserts -seq 10 -show-inputs -show-outputs miter
|
||||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
cd macc2 # Constrain all select calls below inside the top module
|
cd macc2 # Constrain all select calls below inside the top module
|
||||||
|
|
||||||
select -assert-count 1 t:BUFG
|
select -assert-count 1 t:BUFG
|
||||||
select -assert-count 1 t:DSP48E1
|
select -assert-count 1 t:DSP48E1
|
||||||
select -assert-count 1 t:FDRE
|
select -assert-count 1 t:FDRE
|
||||||
select -assert-count 1 t:LUT2
|
select -assert-count 1 t:LUT2
|
||||||
select -assert-count 41 t:LUT3
|
select -assert-count 40 t:LUT3
|
||||||
select -assert-none t:BUFG t:DSP48E1 t:FDRE t:LUT2 t:LUT3 %% t:* %D
|
select -assert-none t:BUFG t:DSP48E1 t:FDRE t:LUT2 t:LUT3 %% t:* %D
|
||||||
|
|
|
@ -40,6 +40,8 @@ proc
|
||||||
equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
|
equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
|
||||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
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
|
cd mux16 # Constrain all select calls below inside the top module
|
||||||
select -assert-count 5 t:LUT6
|
select -assert-min 5 t:LUT6
|
||||||
|
select -assert-max 7 t:LUT6
|
||||||
|
select -assert-max 2 t:MUXF7
|
||||||
|
|
||||||
select -assert-none t:LUT6 %% t:* %D
|
select -assert-none t:LUT6 t:MUXF7 %% t:* %D
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
read_verilog << EOT
|
||||||
|
|
||||||
|
// FDRE, mergeable CE and R.
|
||||||
|
|
||||||
|
module t0 (...);
|
||||||
|
input wire clk;
|
||||||
|
input wire [7:0] i;
|
||||||
|
output wire [7:0] o;
|
||||||
|
|
||||||
|
wire [7:0] tmp ;
|
||||||
|
|
||||||
|
LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0]));
|
||||||
|
LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1]));
|
||||||
|
LUT2 #(.INIT(4'h6)) lut2 (.I0(i[3]), .I1(i[4]), .O(tmp[2]));
|
||||||
|
|
||||||
|
FDRE ff (.D(tmp[0]), .CE(tmp[1]), .R(tmp[2]), .Q(o[0]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
EOT
|
||||||
|
|
||||||
|
design -save t0
|
||||||
|
|
||||||
|
equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt
|
||||||
|
design -load postopt
|
||||||
|
clean
|
||||||
|
|
||||||
|
select -assert-count 1 t:FDRE
|
||||||
|
select -assert-count 1 t:LUT6
|
||||||
|
select -assert-count 3 t:LUT2
|
||||||
|
select -assert-none t:FDRE t:LUT6 t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
design -load t0
|
||||||
|
|
||||||
|
equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4
|
||||||
|
design -load postopt
|
||||||
|
clean
|
||||||
|
|
||||||
|
select -assert-count 1 t:FDRE
|
||||||
|
select -assert-count 1 t:LUT4
|
||||||
|
select -assert-count 3 t:LUT2
|
||||||
|
select -assert-none t:FDRE t:LUT4 t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
|
||||||
|
|
||||||
|
read_verilog << EOT
|
||||||
|
|
||||||
|
// FDSE, mergeable CE and S, inversions.
|
||||||
|
|
||||||
|
module t0 (...);
|
||||||
|
input wire clk;
|
||||||
|
input wire [7:0] i;
|
||||||
|
output wire [7:0] o;
|
||||||
|
|
||||||
|
wire [7:0] tmp ;
|
||||||
|
|
||||||
|
LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0]));
|
||||||
|
LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1]));
|
||||||
|
LUT2 #(.INIT(4'h6)) lut2 (.I0(i[3]), .I1(i[4]), .O(tmp[2]));
|
||||||
|
|
||||||
|
FDSE #(.IS_D_INVERTED(1'b1), .IS_S_INVERTED(1'b1)) ff (.D(tmp[0]), .CE(tmp[1]), .S(tmp[2]), .Q(o[0]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
EOT
|
||||||
|
|
||||||
|
design -save t0
|
||||||
|
|
||||||
|
equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt
|
||||||
|
design -load postopt
|
||||||
|
clean
|
||||||
|
|
||||||
|
select -assert-count 1 t:FDSE
|
||||||
|
select -assert-count 1 t:LUT6
|
||||||
|
select -assert-count 3 t:LUT2
|
||||||
|
select -assert-none t:FDSE t:LUT6 t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
design -load t0
|
||||||
|
|
||||||
|
equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4
|
||||||
|
design -load postopt
|
||||||
|
clean
|
||||||
|
|
||||||
|
select -assert-count 1 t:FDSE
|
||||||
|
select -assert-count 1 t:LUT4
|
||||||
|
select -assert-count 3 t:LUT2
|
||||||
|
select -assert-none t:FDSE t:LUT4 t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
|
||||||
|
|
||||||
|
read_verilog << EOT
|
||||||
|
|
||||||
|
// FDCE, mergeable CE.
|
||||||
|
|
||||||
|
module t0 (...);
|
||||||
|
input wire clk;
|
||||||
|
input wire [7:0] i;
|
||||||
|
output wire [7:0] o;
|
||||||
|
|
||||||
|
wire [7:0] tmp ;
|
||||||
|
|
||||||
|
LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0]));
|
||||||
|
LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1]));
|
||||||
|
LUT2 #(.INIT(4'h6)) lut2 (.I0(i[3]), .I1(i[4]), .O(tmp[2]));
|
||||||
|
|
||||||
|
FDCE ff (.D(tmp[0]), .CE(tmp[1]), .CLR(tmp[2]), .Q(o[0]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
EOT
|
||||||
|
|
||||||
|
design -save t0
|
||||||
|
|
||||||
|
equiv_opt -async2sync -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt
|
||||||
|
design -load postopt
|
||||||
|
clean
|
||||||
|
|
||||||
|
select -assert-count 1 t:FDCE
|
||||||
|
select -assert-count 1 t:LUT4
|
||||||
|
select -assert-count 3 t:LUT2
|
||||||
|
select -assert-none t:FDCE t:LUT4 t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
|
||||||
|
|
||||||
|
read_verilog << EOT
|
||||||
|
|
||||||
|
// FDSE, mergeable CE and S, but CE only not worth it.
|
||||||
|
|
||||||
|
module t0 (...);
|
||||||
|
input wire clk;
|
||||||
|
input wire [7:0] i;
|
||||||
|
output wire [7:0] o;
|
||||||
|
|
||||||
|
wire [7:0] tmp ;
|
||||||
|
|
||||||
|
LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0]));
|
||||||
|
LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1]));
|
||||||
|
|
||||||
|
FDSE ff (.D(tmp[0]), .CE(i[7]), .S(tmp[1]), .Q(o[0]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
EOT
|
||||||
|
|
||||||
|
design -save t0
|
||||||
|
|
||||||
|
equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt
|
||||||
|
design -load postopt
|
||||||
|
clean
|
||||||
|
|
||||||
|
select -assert-count 1 t:FDSE
|
||||||
|
select -assert-count 1 t:LUT5
|
||||||
|
select -assert-count 2 t:LUT2
|
||||||
|
select -assert-none t:FDSE t:LUT5 t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
design -load t0
|
||||||
|
|
||||||
|
equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4
|
||||||
|
design -load postopt
|
||||||
|
clean
|
||||||
|
|
||||||
|
select -assert-count 1 t:FDSE
|
||||||
|
select -assert-count 2 t:LUT2
|
||||||
|
select -assert-none t:FDSE t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
|
||||||
|
|
||||||
|
read_verilog << EOT
|
||||||
|
|
||||||
|
// FDRSE, mergeable CE, S, R.
|
||||||
|
|
||||||
|
module t0 (...);
|
||||||
|
input wire clk;
|
||||||
|
input wire [7:0] i;
|
||||||
|
output wire [7:0] o;
|
||||||
|
|
||||||
|
wire [7:0] tmp ;
|
||||||
|
|
||||||
|
LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0]));
|
||||||
|
LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1]));
|
||||||
|
LUT2 #(.INIT(4'h8)) lut2 (.I0(i[2]), .I1(i[0]), .O(tmp[2]));
|
||||||
|
LUT2 #(.INIT(4'h6)) lut3 (.I0(i[3]), .I1(i[4]), .O(tmp[3]));
|
||||||
|
|
||||||
|
FDRSE ff (.D(tmp[0]), .CE(tmp[1]), .S(tmp[2]), .R(tmp[3]), .Q(o[0]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
EOT
|
||||||
|
|
||||||
|
design -save t0
|
||||||
|
|
||||||
|
equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt
|
||||||
|
design -load postopt
|
||||||
|
clean
|
||||||
|
|
||||||
|
select -assert-count 1 t:FDRSE
|
||||||
|
select -assert-count 1 t:LUT6
|
||||||
|
select -assert-count 4 t:LUT2
|
||||||
|
select -assert-none t:FDRSE t:LUT6 t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
design -load t0
|
||||||
|
|
||||||
|
equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4
|
||||||
|
design -load postopt
|
||||||
|
clean
|
||||||
|
|
||||||
|
select -assert-count 1 t:FDRSE
|
||||||
|
select -assert-count 1 t:LUT4
|
||||||
|
select -assert-count 4 t:LUT2
|
||||||
|
select -assert-none t:FDRSE t:LUT4 t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
design -reset
|
|
@ -0,0 +1,13 @@
|
||||||
|
lut0
|
||||||
|
lut1
|
||||||
|
lut2
|
||||||
|
lut3
|
||||||
|
ff
|
||||||
|
ff.D
|
||||||
|
ff.R
|
||||||
|
ff.S
|
||||||
|
ff.CE
|
||||||
|
ff.d
|
||||||
|
ff.r
|
||||||
|
ff.s
|
||||||
|
ff.ce
|
|
@ -0,0 +1,5 @@
|
||||||
|
scratchpad -set foo "bar baz"
|
||||||
|
scratchpad -copy foo oof
|
||||||
|
scratchpad -unset foo
|
||||||
|
scratchpad -assert oof "bar baz"
|
||||||
|
scratchpad -assert-unset foo
|
Loading…
Reference in New Issue