aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--backends/cxxrtl/cxxrtl_backend.cc1
-rw-r--r--backends/cxxrtl/cxxrtl_capi.cc8
-rw-r--r--backends/cxxrtl/cxxrtl_capi.h12
-rw-r--r--frontends/ast/simplify.cc2
-rw-r--r--frontends/verilog/Makefile.inc2
-rw-r--r--frontends/verilog/verilog_parser.y138
-rw-r--r--passes/opt/opt_expr.cc8
-rw-r--r--passes/opt/opt_merge.cc4
-rw-r--r--passes/proc/proc_dlatch.cc33
-rw-r--r--passes/sat/clk2fflogic.cc108
-rw-r--r--passes/techmap/clkbufmap.cc58
-rw-r--r--passes/techmap/dfflegalize.cc24
-rw-r--r--passes/techmap/dfflibmap.cc289
-rw-r--r--passes/techmap/extractinv.cc2
-rw-r--r--techlibs/achronix/synth_achronix.cc2
-rw-r--r--techlibs/ecp5/Makefile.inc3
-rw-r--r--techlibs/ecp5/cells_map.v143
-rw-r--r--techlibs/ecp5/ecp5_ffinit.cc197
-rw-r--r--techlibs/ecp5/synth_ecp5.cc7
-rw-r--r--techlibs/efinix/cells_map.v66
-rw-r--r--techlibs/efinix/synth_efinix.cc2
-rw-r--r--techlibs/gowin/Makefile.inc1
-rw-r--r--techlibs/gowin/cells_map.v185
-rw-r--r--techlibs/gowin/cells_sim.v359
-rw-r--r--techlibs/gowin/determine_init.cc72
-rw-r--r--techlibs/gowin/synth_gowin.cc34
-rw-r--r--techlibs/ice40/Makefile.inc1
-rw-r--r--techlibs/ice40/ff_map.v43
-rw-r--r--techlibs/ice40/ice40_ffinit.cc179
-rw-r--r--techlibs/ice40/synth_ice40.cc9
-rw-r--r--techlibs/intel/Makefile.inc1
-rw-r--r--techlibs/intel/common/ff_map.v11
-rw-r--r--techlibs/intel/cyclone10lp/cells_map.v35
-rw-r--r--techlibs/intel/cycloneiv/cells_map.v35
-rw-r--r--techlibs/intel/cycloneive/cells_map.v35
-rw-r--r--techlibs/intel/cyclonev/cells_map.v37
-rw-r--r--techlibs/intel/max10/cells_map.v35
-rw-r--r--techlibs/intel/synth_intel.cc6
-rw-r--r--techlibs/intel_alm/Makefile.inc2
-rw-r--r--techlibs/intel_alm/common/dff_map.v123
-rw-r--r--techlibs/intel_alm/common/dsp_map.v49
-rw-r--r--techlibs/intel_alm/common/dsp_sim.v35
-rw-r--r--techlibs/intel_alm/common/megafunction_bb.v28
-rw-r--r--techlibs/intel_alm/common/quartus_rename.v23
-rw-r--r--techlibs/intel_alm/synth_intel_alm.cc65
-rw-r--r--techlibs/sf2/cells_map.v56
-rw-r--r--techlibs/sf2/synth_sf2.cc1
-rw-r--r--techlibs/xilinx/Makefile.inc3
-rw-r--r--techlibs/xilinx/cells_map.v37
-rw-r--r--techlibs/xilinx/ff_map.v120
-rw-r--r--techlibs/xilinx/synth_xilinx.cc23
-rw-r--r--techlibs/xilinx/xc6s_ff_map.v256
-rw-r--r--techlibs/xilinx/xc7_ff_map.v178
-rw-r--r--tests/arch/gowin/init-error.ys5
-rw-r--r--tests/arch/gowin/init.ys12
-rw-r--r--tests/arch/intel_alm/add_sub.ys10
-rw-r--r--tests/arch/intel_alm/adffs.ys48
-rw-r--r--tests/arch/intel_alm/counter.ys14
-rw-r--r--tests/arch/intel_alm/dffs.ys22
-rw-r--r--tests/arch/intel_alm/fsm.ys24
-rw-r--r--tests/arch/intel_alm/logic.ys14
-rw-r--r--tests/arch/intel_alm/lutram.ys23
-rw-r--r--tests/arch/intel_alm/mul.ys23
-rw-r--r--tests/arch/intel_alm/mux.ys46
-rw-r--r--tests/arch/intel_alm/quartus_ice.ys14
-rw-r--r--tests/arch/intel_alm/shifter.ys11
-rw-r--r--tests/arch/intel_alm/tribuf.ys14
-rw-r--r--tests/arch/xilinx/nosrl.ys41
-rwxr-xr-xtests/liberty/run-test.sh2
-rw-r--r--tests/opt/bug2221.ys16
-rw-r--r--tests/techmap/clkbufmap.ys79
-rw-r--r--tests/techmap/dfflegalize_adff.ys4
-rw-r--r--tests/techmap/dfflegalize_adff_init.ys8
-rw-r--r--tests/techmap/dfflegalize_adlatch.ys2
-rw-r--r--tests/techmap/dfflegalize_adlatch_init.ys4
-rw-r--r--tests/techmap/dfflegalize_dffsr_init.ys8
-rw-r--r--tests/techmap/dfflegalize_dlatch_const.ys53
-rw-r--r--tests/techmap/dfflegalize_sr.ys12
-rw-r--r--tests/techmap/dfflegalize_sr_init.ys24
-rw-r--r--tests/techmap/dfflibmap-sim.v22
-rw-r--r--tests/techmap/dfflibmap.lib55
-rw-r--r--tests/techmap/dfflibmap.ys58
-rw-r--r--tests/various/integer_range_bad_syntax.ys6
-rw-r--r--tests/various/integer_real_bad_syntax.ys6
-rw-r--r--tests/various/logic_param_simple.ys9
86 files changed, 1892 insertions, 1990 deletions
diff --git a/Makefile b/Makefile
index 3d3e60359..ec8b38c48 100644
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,7 @@ ENABLE_GCOV := 0
ENABLE_GPROF := 0
ENABLE_DEBUG := 0
ENABLE_NDEBUG := 0
+ENABLE_CCACHE := 0
LINK_CURSES := 0
LINK_TERMCAP := 0
LINK_ABC := 0
@@ -246,7 +247,7 @@ CXXFLAGS := -std=c++11 $(filter-out -fPIC -ggdb,$(CXXFLAGS))
ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8"
EMCCFLAGS := -Os -Wno-warn-absolute-paths
EMCCFLAGS += --memory-init-file 0 --embed-file share -s NO_EXIT_RUNTIME=1
-EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg']"
+EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg','_memset']"
EMCCFLAGS += -s TOTAL_MEMORY=134217728
EMCCFLAGS += -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
# https://github.com/kripken/emscripten/blob/master/src/settings.js
@@ -528,6 +529,10 @@ ifeq ($(ENABLE_COVER),1)
CXXFLAGS += -DYOSYS_ENABLE_COVER
endif
+ifeq ($(ENABLE_CCACHE),1)
+CXX := ccache $(CXX)
+endif
+
define add_share_file
EXTRA_TARGETS += $(subst //,/,$(1)/$(notdir $(2)))
$(subst //,/,$(1)/$(notdir $(2))): $(2)
diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc
index 5e5ba5ac0..6d3c2f4f9 100644
--- a/backends/cxxrtl/cxxrtl_backend.cc
+++ b/backends/cxxrtl/cxxrtl_backend.cc
@@ -1935,6 +1935,7 @@ struct CxxrtlWorker {
f << "} // namespace " << design_ns << "\n";
f << "\n";
if (top_module != nullptr && debug_info) {
+ f << "extern \"C\"\n";
f << "cxxrtl_toplevel " << design_ns << "_create() {\n";
inc_indent();
std::string top_type = design_ns + "::" + mangle(top_module);
diff --git a/backends/cxxrtl/cxxrtl_capi.cc b/backends/cxxrtl/cxxrtl_capi.cc
index e0566e152..b77e4c491 100644
--- a/backends/cxxrtl/cxxrtl_capi.cc
+++ b/backends/cxxrtl/cxxrtl_capi.cc
@@ -43,6 +43,14 @@ void cxxrtl_destroy(cxxrtl_handle handle) {
delete handle;
}
+int cxxrtl_eval(cxxrtl_handle handle) {
+ return handle->module->eval();
+}
+
+int cxxrtl_commit(cxxrtl_handle handle) {
+ return handle->module->commit();
+}
+
size_t cxxrtl_step(cxxrtl_handle handle) {
return handle->module->step();
}
diff --git a/backends/cxxrtl/cxxrtl_capi.h b/backends/cxxrtl/cxxrtl_capi.h
index 599284898..1f1942803 100644
--- a/backends/cxxrtl/cxxrtl_capi.h
+++ b/backends/cxxrtl/cxxrtl_capi.h
@@ -55,6 +55,18 @@ cxxrtl_handle cxxrtl_create(cxxrtl_toplevel design);
// Release all resources used by a design and its handle.
void cxxrtl_destroy(cxxrtl_handle handle);
+// Evaluate the design, propagating changes on inputs to the `next` value of internal state and
+// output wires.
+//
+// Returns 1 if the design is known to immediately converge, 0 otherwise.
+int cxxrtl_eval(cxxrtl_handle handle);
+
+// Commit the design, replacing the `curr` value of internal state and output wires with the `next`
+// value.
+//
+// Return 1 if any of the `curr` values were updated, 0 otherwise.
+int cxxrtl_commit(cxxrtl_handle handle);
+
// Simulate the design to a fixed point.
//
// Returns the number of delta cycles.
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index c4df5c0a0..00f8c8df6 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -4231,6 +4231,8 @@ bool AstNode::detect_latch(const std::string &var)
case AST_POSEDGE:
case AST_NEGEDGE:
return false;
+ case AST_EDGE:
+ break;
case AST_BLOCK:
if (!c->detect_latch(var))
return false;
diff --git a/frontends/verilog/Makefile.inc b/frontends/verilog/Makefile.inc
index cf9b9531e..2c923f0b7 100644
--- a/frontends/verilog/Makefile.inc
+++ b/frontends/verilog/Makefile.inc
@@ -6,7 +6,7 @@ GENFILES += frontends/verilog/verilog_lexer.cc
frontends/verilog/verilog_parser.tab.cc: frontends/verilog/verilog_parser.y
$(Q) mkdir -p $(dir $@)
- $(P) $(BISON) -o $@ -d -r all -b frontends/verilog/verilog_parser $<
+ $(P) $(BISON) -Wall -Werror -o $@ -d -r all -b frontends/verilog/verilog_parser $<
frontends/verilog/verilog_parser.tab.hh: frontends/verilog/verilog_parser.tab.cc
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 656910c0c..63f0341d9 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -299,14 +299,14 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
%left '+' '-'
%left '*' '/' '%'
%left OP_POW
-%left OP_CAST
-%right UNARY_OPS
+%precedence OP_CAST
+%precedence UNARY_OPS
%define parse.error verbose
%define parse.lac full
-%nonassoc FAKE_THEN
-%nonassoc TOK_ELSE
+%precedence FAKE_THEN
+%precedence TOK_ELSE
%debug
%locations
@@ -333,7 +333,7 @@ design:
typedef_decl design |
package design |
interface design |
- /* empty */;
+ %empty;
attr:
{
@@ -355,7 +355,7 @@ attr_opt:
attr_opt ATTR_BEGIN opt_attr_list ATTR_END {
SET_RULE_LOC(@$, @2, @$);
}|
- /* empty */;
+ %empty;
defattr:
DEFATTR_BEGIN {
@@ -376,7 +376,7 @@ defattr:
} DEFATTR_END;
opt_attr_list:
- attr_list | /* empty */;
+ attr_list | %empty;
attr_list:
attr_assign |
@@ -449,13 +449,13 @@ module:
};
module_para_opt:
- '#' '(' { astbuf1 = nullptr; } module_para_list { if (astbuf1) delete astbuf1; } ')' | /* empty */;
+ '#' '(' { astbuf1 = nullptr; } module_para_list { if (astbuf1) delete astbuf1; } ')' | %empty;
module_para_list:
single_module_para | module_para_list ',' single_module_para;
single_module_para:
- /* empty */ |
+ %empty |
attr TOK_PARAMETER {
if (astbuf1) delete astbuf1;
astbuf1 = new AstNode(AST_PARAMETER);
@@ -471,13 +471,13 @@ single_module_para:
single_param_decl;
module_args_opt:
- '(' ')' | /* empty */ | '(' module_args optional_comma ')';
+ '(' ')' | %empty | '(' module_args optional_comma ')';
module_args:
module_arg | module_args ',' module_arg;
optional_comma:
- ',' | /* empty */;
+ ',' | %empty;
module_arg_opt_assignment:
'=' expr {
@@ -497,7 +497,7 @@ module_arg_opt_assignment:
} else
frontend_verilog_yyerror("SystemVerilog interface in module port list cannot have a default value.");
} |
- /* empty */;
+ %empty;
module_arg:
TOK_ID {
@@ -565,15 +565,10 @@ package:
};
package_body:
- package_body package_body_stmt
- | // optional
- ;
+ package_body package_body_stmt | %empty;
package_body_stmt:
- typedef_decl
- | localparam_decl
- | param_decl
- ;
+ typedef_decl | localparam_decl | param_decl;
interface:
TOK_INTERFACE {
@@ -599,7 +594,7 @@ interface:
};
interface_body:
- interface_body interface_body_stmt |;
+ interface_body interface_body_stmt | %empty;
interface_body_stmt:
param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
@@ -613,7 +608,7 @@ non_opt_delay:
'#' '(' expr ':' expr ':' expr ')' { delete $3; delete $5; delete $7; };
delay:
- non_opt_delay | /* empty */;
+ non_opt_delay | %empty;
wire_type:
{
@@ -725,7 +720,7 @@ range:
non_opt_range {
$$ = $1;
} |
- /* empty */ {
+ %empty {
$$ = NULL;
};
@@ -742,12 +737,13 @@ module_body:
module_body module_body_stmt |
/* the following line makes the generate..endgenrate keywords optional */
module_body gen_stmt |
- /* empty */;
+ module_body ';' |
+ %empty;
module_body_stmt:
task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
enum_decl | struct_decl |
- always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block | /* empty statement */ ';';
+ always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block;
checker_decl:
TOK_CHECKER TOK_ID ';' {
@@ -842,28 +838,28 @@ dpi_function_arg:
opt_dpi_function_args:
'(' dpi_function_args ')' |
- /* empty */;
+ %empty;
dpi_function_args:
dpi_function_args ',' dpi_function_arg |
dpi_function_args ',' |
dpi_function_arg |
- /* empty */;
+ %empty;
opt_automatic:
TOK_AUTOMATIC |
- /* empty */;
+ %empty;
opt_signed:
TOK_SIGNED {
$$ = true;
} |
- /* empty */ {
+ %empty {
$$ = false;
};
task_func_args_opt:
- '(' ')' | /* empty */ | '(' {
+ '(' ')' | %empty | '(' {
albuf = nullptr;
astbuf1 = nullptr;
astbuf2 = nullptr;
@@ -904,7 +900,7 @@ task_func_port:
task_func_body:
task_func_body behavioral_stmt |
- /* empty */;
+ %empty;
/*************************** specify parser ***************************/
@@ -913,7 +909,7 @@ specify_block:
specify_item_list:
specify_item specify_item_list |
- /* empty */;
+ %empty;
specify_item:
specify_if '(' specify_edge expr TOK_SPECIFY_OPER specify_target ')' '=' specify_rise_fall ';' {
@@ -1075,7 +1071,7 @@ specify_opt_triple:
',' specify_triple {
$$ = $2;
} |
- /* empty */ {
+ %empty {
$$ = nullptr;
};
@@ -1083,7 +1079,7 @@ specify_if:
TOK_IF '(' expr ')' {
$$ = $3;
} |
- /* empty */ {
+ %empty {
$$ = nullptr;
};
@@ -1091,7 +1087,7 @@ specify_condition:
TOK_SPECIFY_AND expr {
$$ = $2;
} |
- /* empty */ {
+ %empty {
$$ = nullptr;
};
@@ -1124,7 +1120,7 @@ specify_target:
specify_edge:
TOK_POSEDGE { $$ = 'p'; } |
TOK_NEGEDGE { $$ = 'n'; } |
- { $$ = 0; };
+ %empty { $$ = 0; };
specify_rise_fall:
specify_triple {
@@ -1231,7 +1227,7 @@ specparam_assignment:
ignspec_id '=' ignspec_expr ;
ignspec_opt_cond:
- TOK_IF '(' ignspec_expr ')' | /* empty */;
+ TOK_IF '(' ignspec_expr ')' | %empty;
path_declaration :
simple_path_declaration ';'
@@ -1282,9 +1278,7 @@ list_of_path_outputs :
list_of_path_outputs ',' specify_output_terminal_descriptor ;
opt_polarity_operator :
- '+'
- | '-'
- | ;
+ '+' | '-' | %empty;
// Good enough for the time being
specify_input_terminal_descriptor :
@@ -1333,37 +1327,31 @@ param_signed:
astbuf1->is_signed = true;
} | TOK_UNSIGNED {
astbuf1->is_signed = false;
- } | /* empty */;
+ } | %empty;
param_integer:
TOK_INTEGER {
- if (astbuf1->children.size() != 1)
- frontend_verilog_yyerror("Internal error in param_integer - should not happen?");
astbuf1->children.push_back(new AstNode(AST_RANGE));
astbuf1->children.back()->children.push_back(AstNode::mkconst_int(31, true));
astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true));
astbuf1->is_signed = true;
- }
+ };
param_real:
TOK_REAL {
- if (astbuf1->children.size() != 1)
- frontend_verilog_yyerror("Parameter already declared as integer, cannot set to real.");
astbuf1->children.push_back(new AstNode(AST_REALVALUE));
- }
+ };
param_range:
range {
if ($1 != NULL) {
- if (astbuf1->children.size() != 1)
- frontend_verilog_yyerror("integer/real parameters should not have a range.");
astbuf1->children.push_back($1);
}
};
-param_integer_type: param_integer param_signed
-param_range_type: type_vec param_signed param_range
-param_implicit_type: param_signed param_range
+param_integer_type: param_integer param_signed;
+param_range_type: type_vec param_signed param_range;
+param_implicit_type: param_signed param_range;
param_type:
param_integer_type | param_real | param_range_type | param_implicit_type |
@@ -1456,7 +1444,7 @@ enum_type: TOK_ENUM {
enum_base_type: type_atom type_signing
| type_vec type_signing range { if ($3) astbuf1->children.push_back($3); }
- | /* nothing */ { astbuf1->is_reg = true; addRange(astbuf1); }
+ | %empty { astbuf1->is_reg = true; addRange(astbuf1); }
;
type_atom: TOK_INTEGER { astbuf1->is_reg = true; addRange(astbuf1); } // 4-state signed
@@ -1472,7 +1460,7 @@ type_vec: TOK_REG { astbuf1->is_reg = true; } // unsigned
type_signing:
TOK_SIGNED { astbuf1->is_signed = true; }
| TOK_UNSIGNED { astbuf1->is_signed = false; }
- | // optional
+ | %empty
;
enum_name_list: enum_name_decl
@@ -1496,7 +1484,7 @@ enum_name_decl:
opt_enum_init:
'=' basic_expr { $$ = $2; } // TODO: restrict this
- | /* optional */ { $$ = NULL; }
+ | %empty { $$ = NULL; }
;
enum_var_list:
@@ -1537,14 +1525,14 @@ struct_union:
struct_body: opt_packed '{' struct_member_list '}'
;
-opt_packed: TOK_PACKED opt_signed_struct
- | { frontend_verilog_yyerror("Only PACKED supported at this time"); }
- ;
+opt_packed:
+ TOK_PACKED opt_signed_struct |
+ %empty { frontend_verilog_yyerror("Only PACKED supported at this time"); };
opt_signed_struct:
TOK_SIGNED { astbuf2->is_signed = true; }
| TOK_UNSIGNED { astbuf2->is_signed = false; }
- | // default is unsigned
+ | %empty // default is unsigned
;
struct_member_list: struct_member
@@ -1651,7 +1639,7 @@ wire_decl:
} opt_supply_wires ';';
opt_supply_wires:
- /* empty */ |
+ %empty |
opt_supply_wires ',' TOK_ID {
AstNode *wire_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-2)->clone();
AstNode *assign_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-1)->clone();
@@ -1882,13 +1870,13 @@ single_prim:
}
cell_parameter_list_opt:
- '#' '(' cell_parameter_list ')' | /* empty */;
+ '#' '(' cell_parameter_list ')' | %empty;
cell_parameter_list:
cell_parameter | cell_parameter_list ',' cell_parameter;
cell_parameter:
- /* empty */ |
+ %empty |
expr {
AstNode *node = new AstNode(AST_PARASET);
astbuf1->children.push_back(node);
@@ -2046,7 +2034,7 @@ always_cond:
'@' ATTR_BEGIN ')' |
'@' '(' ATTR_END |
'@' '*' |
- /* empty */;
+ %empty;
always_events:
always_event |
@@ -2076,7 +2064,7 @@ opt_label:
':' TOK_ID {
$$ = $2;
} |
- /* empty */ {
+ %empty {
$$ = NULL;
};
@@ -2084,7 +2072,7 @@ opt_sva_label:
TOK_SVA_LABEL ':' {
$$ = $1;
} |
- /* empty */ {
+ %empty {
$$ = NULL;
};
@@ -2095,7 +2083,7 @@ opt_property:
TOK_FINAL {
$$ = false;
} |
- /* empty */ {
+ %empty {
$$ = false;
};
@@ -2506,7 +2494,7 @@ behavioral_stmt:
};
unique_case_attr:
- /* empty */ {
+ %empty {
$$ = false;
} |
TOK_PRIORITY case_attr {
@@ -2542,11 +2530,11 @@ opt_synopsys_attr:
if (ast_stack.back()->attributes.count(ID::parallel_case) == 0)
ast_stack.back()->attributes[ID::parallel_case] = AstNode::mkconst_int(1, false);
} |
- /* empty */;
+ %empty;
behavioral_stmt_list:
behavioral_stmt_list behavioral_stmt |
- /* empty */;
+ %empty;
optional_else:
TOK_ELSE {
@@ -2560,11 +2548,11 @@ optional_else:
} behavioral_stmt {
SET_AST_NODE_LOC(ast_stack.back(), @3, @3);
} |
- /* empty */ %prec FAKE_THEN;
+ %empty %prec FAKE_THEN;
case_body:
case_body case_item |
- /* empty */;
+ %empty;
case_item:
{
@@ -2587,7 +2575,7 @@ case_item:
gen_case_body:
gen_case_body gen_case_item |
- /* empty */;
+ %empty;
gen_case_item:
{
@@ -2671,11 +2659,11 @@ lvalue_concat_list:
opt_arg_list:
'(' arg_list optional_comma ')' |
- /* empty */;
+ %empty;
arg_list:
arg_list2 |
- /* empty */;
+ %empty;
arg_list2:
single_arg |
@@ -2688,7 +2676,7 @@ single_arg:
module_gen_body:
module_gen_body gen_stmt_or_module_body_stmt |
- /* empty */;
+ %empty;
gen_stmt_or_module_body_stmt:
gen_stmt | module_body_stmt |
@@ -2767,7 +2755,7 @@ gen_stmt_block:
};
opt_gen_else:
- TOK_ELSE gen_stmt_block | /* empty */ %prec FAKE_THEN;
+ TOK_ELSE gen_stmt_block | %empty %prec FAKE_THEN;
expr:
basic_expr {
diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index 1051a59f2..649ad83a6 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -1596,6 +1596,14 @@ skip_identity:
log_debug("Removing low %d A and %d B bits from cell `%s' in module `%s'.\n",
a_zeros, b_zeros, cell->name.c_str(), module->name.c_str());
+ if (y_zeros >= GetSize(sig_y)) {
+ module->connect(sig_y, RTLIL::SigSpec(0, GetSize(sig_y)));
+ module->remove(cell);
+
+ did_something = true;
+ goto next_cell;
+ }
+
if (a_zeros) {
cell->setPort(ID::A, sig_a.extract_end(a_zeros));
cell->parameters[ID::A_WIDTH] = GetSize(sig_a) - a_zeros;
diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc
index f03faa9cf..9086943dc 100644
--- a/passes/opt/opt_merge.cc
+++ b/passes/opt/opt_merge.cc
@@ -173,9 +173,7 @@ struct OptMergeWorker
for (const auto &it : cell1->connections_) {
if (cell1->output(it.first)) {
- if (it.first == ID::Q && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") ||
- cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") ||
- cell1->type.in(ID($adff), ID($sr), ID($ff), ID($_FF_)))) {
+ if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell1->type)) {
// For the 'Q' output of state elements,
// use the (* init *) attribute value
auto &sig1 = conn1[it.first];
diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc
index e7c8a80dd..3ed158f37 100644
--- a/passes/proc/proc_dlatch.cc
+++ b/passes/proc/proc_dlatch.cc
@@ -37,6 +37,7 @@ struct proc_dlatch_db_t
dict<Cell*, vector<SigBit>> mux_srcbits;
dict<SigBit, pair<Cell*, int>> mux_drivers;
dict<SigBit, int> sigusers;
+ dict<SigBit, std::pair<State,SigBit>> initbits;
proc_dlatch_db_t(Module *module) : module(module), sigmap(module)
{
@@ -69,9 +70,34 @@ struct proc_dlatch_db_t
}
for (auto wire : module->wires())
+ {
if (wire->port_input)
for (auto bit : sigmap(wire))
sigusers[bit]++;
+ if (wire->attributes.count(ID::init)) {
+ SigSpec wirebits = sigmap(wire);
+ Const initval = wire->attributes.at(ID::init);
+
+ for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
+ {
+ SigBit bit = wirebits[i];
+ State val = initval[i];
+
+ if (val != State::S0 && val != State::S1 && bit.wire != nullptr)
+ continue;
+
+ if (initbits.count(bit)) {
+ if (initbits.at(bit).first != val)
+ log_error("Conflicting init values for signal %s (%s = %s != %s).\n",
+ log_signal(bit), log_signal(SigBit(wire, i)),
+ log_signal(val), log_signal(initbits.at(bit).first));
+ continue;
+ }
+
+ initbits[bit] = std::make_pair(val,SigBit(wire,i));
+ }
+ }
+ }
}
bool quickcheck(const SigSpec &haystack, const SigSpec &needle)
@@ -393,6 +419,13 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
else
log("No latch inferred for signal `%s.%s' from process `%s.%s'.\n",
db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str());
+ for (auto &bit : lhs) {
+ auto it = db.initbits.find(bit);
+ if (it != db.initbits.end()) {
+ log("Removing init bit %s for non-memory siginal `%s.%s` in process `%s.%s`.\n", log_signal(it->second.first), db.module->name.c_str(), log_signal(bit), db.module->name.c_str(), proc->name.c_str());
+ it->second.second.wire->attributes.at(ID::init)[it->second.second.offset] = State::Sx;
+ }
+ }
db.module->connect(lhs, rhs);
offset += chunk.width;
}
diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc
index e5c5d0486..cc24db6d4 100644
--- a/passes/sat/clk2fflogic.cc
+++ b/passes/sat/clk2fflogic.cc
@@ -36,6 +36,30 @@ struct Clk2fflogicPass : public Pass {
log("multiple clocks.\n");
log("\n");
}
+ SigSpec wrap_async_control(Module *module, SigSpec sig, bool polarity) {
+ Wire *past_sig = module->addWire(NEW_ID, GetSize(sig));
+ module->addFf(NEW_ID, sig, past_sig);
+ if (polarity)
+ sig = module->Or(NEW_ID, sig, past_sig);
+ else
+ sig = module->And(NEW_ID, sig, past_sig);
+ if (polarity)
+ return sig;
+ else
+ return module->Not(NEW_ID, sig);
+ }
+ SigSpec wrap_async_control_gate(Module *module, SigSpec sig, bool polarity) {
+ Wire *past_sig = module->addWire(NEW_ID);
+ module->addFfGate(NEW_ID, sig, past_sig);
+ if (polarity)
+ sig = module->OrGate(NEW_ID, sig, past_sig);
+ else
+ sig = module->AndGate(NEW_ID, sig, past_sig);
+ if (polarity)
+ return sig;
+ else
+ return module->NotGate(NEW_ID, sig);
+ }
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
// bool flag_noinit = false;
@@ -153,7 +177,7 @@ struct Clk2fflogicPass : public Pass {
cell->setPort(ID::WR_DATA, wr_data_port);
}
- if (cell->type.in(ID($dlatch), ID($dlatchsr)))
+ if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr)))
{
bool enpol = cell->parameters[ID::EN_POLARITY].as_bool();
@@ -165,32 +189,32 @@ struct Clk2fflogicPass : public Pass {
log_id(module), log_id(cell), log_id(cell->type),
log_signal(sig_en), log_signal(sig_d), log_signal(sig_q));
+ sig_en = wrap_async_control(module, sig_en, enpol);
+
Wire *past_q = module->addWire(NEW_ID, GetSize(sig_q));
module->addFf(NEW_ID, sig_q, past_q);
if (cell->type == ID($dlatch))
{
- if (enpol)
- module->addMux(NEW_ID, past_q, sig_d, sig_en, sig_q);
- else
- module->addMux(NEW_ID, sig_d, past_q, sig_en, sig_q);
+ module->addMux(NEW_ID, past_q, sig_d, sig_en, sig_q);
+ }
+ else if (cell->type == ID($adlatch))
+ {
+ SigSpec t = module->Mux(NEW_ID, past_q, sig_d, sig_en);
+ SigSpec arst = wrap_async_control(module, cell->getPort(ID::ARST), cell->parameters[ID::ARST_POLARITY].as_bool());
+ Const rstval = cell->parameters[ID::ARST_VALUE];
+
+ module->addMux(NEW_ID, t, rstval, arst, sig_q);
}
else
{
- SigSpec t;
- if (enpol)
- t = module->Mux(NEW_ID, past_q, sig_d, sig_en);
- else
- t = module->Mux(NEW_ID, sig_d, past_q, sig_en);
-
- SigSpec s = cell->getPort(ID::SET);
- if (!cell->parameters[ID::SET_POLARITY].as_bool())
- s = module->Not(NEW_ID, s);
+ SigSpec t = module->Mux(NEW_ID, past_q, sig_d, sig_en);
+
+ SigSpec s = wrap_async_control(module, cell->getPort(ID::SET), cell->parameters[ID::SET_POLARITY].as_bool());
t = module->Or(NEW_ID, t, s);
- SigSpec c = cell->getPort(ID::CLR);
- if (cell->parameters[ID::CLR_POLARITY].as_bool())
- c = module->Not(NEW_ID, c);
+ SigSpec c = wrap_async_control(module, cell->getPort(ID::CLR), cell->parameters[ID::CLR_POLARITY].as_bool());
+ c = module->Not(NEW_ID, c);
module->addAnd(NEW_ID, t, c, sig_q);
}
@@ -279,55 +303,30 @@ struct Clk2fflogicPass : public Pass {
if (cell->type == ID($adff))
{
- SigSpec arst = cell->getPort(ID::ARST);
+ SigSpec arst = wrap_async_control(module, cell->getPort(ID::ARST), cell->parameters[ID::ARST_POLARITY].as_bool());
SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge);
Const rstval = cell->parameters[ID::ARST_VALUE];
- Wire *past_arst = module->addWire(NEW_ID);
- module->addFf(NEW_ID, arst, past_arst);
- if (cell->parameters[ID::ARST_POLARITY].as_bool())
- arst = module->LogicOr(NEW_ID, arst, past_arst);
- else
- arst = module->LogicAnd(NEW_ID, arst, past_arst);
-
- if (cell->parameters[ID::ARST_POLARITY].as_bool())
- module->addMux(NEW_ID, qval, rstval, arst, sig_q);
- else
- module->addMux(NEW_ID, rstval, qval, arst, sig_q);
+ module->addMux(NEW_ID, qval, rstval, arst, sig_q);
}
else
if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
ID($_DFF_PP0_), ID($_DFF_PP1_), ID($_DFF_PN0_), ID($_DFF_PN1_)))
{
- SigSpec arst = cell->getPort(ID::R);
+ SigSpec arst = wrap_async_control_gate(module, cell->getPort(ID::R), cell->type[7] == 'P');
SigSpec qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge);
SigBit rstval = (cell->type[8] == '1');
- Wire *past_arst = module->addWire(NEW_ID);
- module->addFfGate(NEW_ID, arst, past_arst);
- if (cell->type[7] == 'P')
- arst = module->OrGate(NEW_ID, arst, past_arst);
- else
- arst = module->AndGate(NEW_ID, arst, past_arst);
-
- if (cell->type[7] == 'P')
- module->addMuxGate(NEW_ID, qval, rstval, arst, sig_q);
- else
- module->addMuxGate(NEW_ID, rstval, qval, arst, sig_q);
+ module->addMuxGate(NEW_ID, qval, rstval, arst, sig_q);
}
else
if (cell->type == ID($dffsr))
{
SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge);
- SigSpec setval = cell->getPort(ID::SET);
- SigSpec clrval = cell->getPort(ID::CLR);
-
- if (!cell->parameters[ID::SET_POLARITY].as_bool())
- setval = module->Not(NEW_ID, setval);
-
- if (cell->parameters[ID::CLR_POLARITY].as_bool())
- clrval = module->Not(NEW_ID, clrval);
+ SigSpec setval = wrap_async_control(module, cell->getPort(ID::SET), cell->parameters[ID::SET_POLARITY].as_bool());
+ SigSpec clrval = wrap_async_control(module, cell->getPort(ID::CLR), cell->parameters[ID::CLR_POLARITY].as_bool());
+ clrval = module->Not(NEW_ID, clrval);
qval = module->Or(NEW_ID, qval, setval);
module->addAnd(NEW_ID, qval, clrval, sig_q);
}
@@ -336,15 +335,10 @@ struct Clk2fflogicPass : public Pass {
ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_)))
{
SigSpec qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge);
- SigSpec setval = cell->getPort(ID::S);
- SigSpec clrval = cell->getPort(ID::R);
-
- if (cell->type[9] != 'P')
- setval = module->Not(NEW_ID, setval);
-
- if (cell->type[10] == 'P')
- clrval = module->Not(NEW_ID, clrval);
+ SigSpec setval = wrap_async_control_gate(module, cell->getPort(ID::S), cell->type[9] == 'P');
+ SigSpec clrval = wrap_async_control_gate(module, cell->getPort(ID::R), cell->type[10] == 'P');
+ clrval = module->NotGate(NEW_ID, clrval);
qval = module->OrGate(NEW_ID, qval, setval);
module->addAndGate(NEW_ID, qval, clrval, sig_q);
}
diff --git a/passes/techmap/clkbufmap.cc b/passes/techmap/clkbufmap.cc
index 451325fee..1cbd12e3d 100644
--- a/passes/techmap/clkbufmap.cc
+++ b/passes/techmap/clkbufmap.cc
@@ -2,7 +2,7 @@
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
- * Copyright (C) 2019 Marcin Kościelnicki <mwk@0x04.net>
+ * Copyright (C) 2019 Marcelina Kościelnicka <mwk@0x04.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -34,33 +34,34 @@ void split_portname_pair(std::string &port1, std::string &port2)
}
struct ClkbufmapPass : public Pass {
- ClkbufmapPass() : Pass("clkbufmap", "insert global buffers on clock networks") { }
+ ClkbufmapPass() : Pass("clkbufmap", "insert clock buffers on clock networks") { }
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" clkbufmap [options] [selection]\n");
log("\n");
- log("Inserts global buffers between nets connected to clock inputs and their drivers.\n");
+ log("Inserts clock buffers between nets connected to clock inputs and their drivers.\n");
log("\n");
log("In the absence of any selection, all wires without the 'clkbuf_inhibit'\n");
- log("attribute will be considered for global buffer insertion.\n");
+ log("attribute will be considered for clock buffer insertion.\n");
log("Alternatively, to consider all wires without the 'buffer_type' attribute set to\n");
log("'none' or 'bufr' one would specify:\n");
log(" 'w:* a:buffer_type=none a:buffer_type=bufr %%u %%d'\n");
log("as the selection.\n");
log("\n");
log(" -buf <celltype> <portname_out>:<portname_in>\n");
- log(" Specifies the cell type to use for the global buffers\n");
+ log(" Specifies the cell type to use for the clock buffers\n");
log(" and its port names. The first port will be connected to\n");
log(" the clock network sinks, and the second will be connected\n");
- log(" to the actual clock source. This option is required.\n");
+ log(" to the actual clock source.\n");
log("\n");
log(" -inpad <celltype> <portname_out>:<portname_in>\n");
log(" If specified, a PAD cell of the given type is inserted on\n");
log(" clock nets that are also top module's inputs (in addition\n");
- log(" to the global buffer).\n");
+ log(" to the clock buffer, if any).\n");
log("\n");
+ log("At least one of -buf or -inpad should be specified.\n");
}
void module_queue(Design *design, Module *module, std::vector<Module *> &modules_sorted, pool<Module *> &modules_processed) {
@@ -78,7 +79,7 @@ struct ClkbufmapPass : public Pass {
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
- log_header(design, "Executing CLKBUFMAP pass (inserting global clock buffers).\n");
+ log_header(design, "Executing CLKBUFMAP pass (inserting clock buffers).\n");
std::string buf_celltype, buf_portname, buf_portname2;
std::string inpad_celltype, inpad_portname, inpad_portname2;
@@ -109,8 +110,8 @@ struct ClkbufmapPass : public Pass {
extra_args(args, argidx, design);
}
- if (buf_celltype.empty())
- log_error("The -buf option is required.\n");
+ if (buf_celltype.empty() && inpad_celltype.empty())
+ log_error("Either the -buf option or -inpad option is required.\n");
// Cell type, port name, bit index.
pool<pair<IdString, pair<IdString, int>>> sink_ports;
@@ -118,6 +119,16 @@ struct ClkbufmapPass : public Pass {
dict<pair<IdString, pair<IdString, int>>, pair<IdString, int>> inv_ports_out;
dict<pair<IdString, pair<IdString, int>>, pair<IdString, int>> inv_ports_in;
+ // If true, use both ther -buf and -inpad cell for input ports that are clocks.
+ bool buffer_inputs = true;
+
+ Module *inpad_mod = design->module(RTLIL::escape_id(inpad_celltype));
+ if (inpad_mod) {
+ Wire *buf_wire = inpad_mod->wire(RTLIL::escape_id(buf_portname));
+ if (buf_wire && buf_wire->get_bool_attribute(ID::clkbuf_driver))
+ buffer_inputs = false;
+ }
+
// Process submodules before module using them.
std::vector<Module *> modules_sorted;
pool<Module *> modules_processed;
@@ -242,19 +253,30 @@ struct ClkbufmapPass : public Pass {
// Clock network not yet buffered, driven by one of
// our cells or a top-level input -- buffer it.
- log("Inserting %s on %s.%s[%d].\n", buf_celltype.c_str(), log_id(module), log_id(wire), i);
- RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(buf_celltype));
- Wire *iwire = module->addWire(NEW_ID);
- cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit);
- cell->setPort(RTLIL::escape_id(buf_portname2), iwire);
- if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute(ID::top)) {
+ Wire *iwire = nullptr;
+ RTLIL::Cell *cell = nullptr;
+ bool is_input = wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute(ID::top);
+ if (!buf_celltype.empty() && (!is_input || buffer_inputs)) {
+ log("Inserting %s on %s.%s[%d].\n", buf_celltype.c_str(), log_id(module), log_id(wire), i);
+ cell = module->addCell(NEW_ID, RTLIL::escape_id(buf_celltype));
+ iwire = module->addWire(NEW_ID);
+ cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit);
+ cell->setPort(RTLIL::escape_id(buf_portname2), iwire);
+ }
+ if (is_input) {
log("Inserting %s on %s.%s[%d].\n", inpad_celltype.c_str(), log_id(module), log_id(wire), i);
RTLIL::Cell *cell2 = module->addCell(NEW_ID, RTLIL::escape_id(inpad_celltype));
- cell2->setPort(RTLIL::escape_id(inpad_portname), iwire);
+ if (iwire) {
+ cell2->setPort(RTLIL::escape_id(inpad_portname), iwire);
+ } else {
+ cell2->setPort(RTLIL::escape_id(inpad_portname), mapped_wire_bit);
+ cell = cell2;
+ }
iwire = module->addWire(NEW_ID);
cell2->setPort(RTLIL::escape_id(inpad_portname2), iwire);
}
- buffered_bits[mapped_wire_bit] = make_pair(cell, iwire);
+ if (iwire)
+ buffered_bits[mapped_wire_bit] = make_pair(cell, iwire);
if (wire->port_input) {
input_bits.insert(i);
diff --git a/passes/techmap/dfflegalize.cc b/passes/techmap/dfflegalize.cc
index 7f2cdc6ac..13ce4f49a 100644
--- a/passes/techmap/dfflegalize.cc
+++ b/passes/techmap/dfflegalize.cc
@@ -364,7 +364,7 @@ flip_dqi:
// Some DFF is supported with this init val. Just pick a type.
if (ff_type == FF_DFF) {
// Try adding a set or reset pin.
- for (auto new_type: {FF_ADFF0, FF_ADFF1, FF_SDFF0, FF_SDFF1})
+ for (auto new_type: {FF_SDFF0, FF_SDFF1, FF_ADFF0, FF_ADFF1})
if (supported_cells[new_type] & initmask) {
ff_type = new_type;
sig_r = State::S0;
@@ -529,7 +529,7 @@ unmap_enable:
}
if (supported_dffsr & flip_initmask(initmask)) {
flip_dqisr:;
- log_warning("Flipping D/Q/init and inseerting set/reset fixup to handle init value on %s.%s [%s]\n", log_id(cell->module->name), log_id(cell->name), log_id(cell->type));
+ log_warning("Flipping D/Q/init and inserting set/reset fixup to handle init value on %s.%s [%s]\n", log_id(cell->module->name), log_id(cell->name), log_id(cell->type));
SigSpec new_r;
bool neg_r = (ff_neg & NEG_R);
bool neg_s = (ff_neg & NEG_S);
@@ -659,6 +659,24 @@ flip_dqisr:;
// This init value is not supported at all...
if (supported_dlatch & flip_initmask(initmask))
goto flip_dqi;
+
+ if ((sig_d == State::S0 && (supported_adff0 & initmask)) ||
+ (sig_d == State::S1 && (supported_adff1 & initmask)) ||
+ (sig_d == State::S0 && (supported_adff1 & flip_initmask(initmask))) ||
+ (sig_d == State::S1 && (supported_adff0 & flip_initmask(initmask)))
+ ) {
+ // Special case: const-D dlatch can be converted into adff with const clock.
+ ff_type = (sig_d == State::S0) ? FF_ADFF0 : FF_ADFF1;
+ if (ff_neg & NEG_E) {
+ ff_neg &= ~NEG_E;
+ ff_neg |= NEG_R;
+ }
+ sig_r = sig_e;
+ sig_d = State::Sx;
+ sig_c = State::S1;
+ continue;
+ }
+
if (!supported_dlatch)
reason = "dlatch are not supported";
else
@@ -1278,7 +1296,7 @@ unrecognized:
sigmap.set(module);
initbits.clear();
- for (auto wire : module->selected_wires())
+ for (auto wire : module->wires())
{
if (wire->attributes.count(ID::init) == 0)
continue;
diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc
index c189d649b..78a6f1c0d 100644
--- a/passes/techmap/dfflibmap.cc
+++ b/passes/techmap/dfflibmap.cc
@@ -115,7 +115,7 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name,
return false;
}
-static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool prepare_mode)
+static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval)
{
LibertyAst *best_cell = nullptr;
std::map<std::string, char> best_cell_ports;
@@ -222,21 +222,12 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
if (best_cell != nullptr) {
log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n",
best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str());
- if (prepare_mode) {
- cell_mappings[cell_type].cell_name = cell_type;
- cell_mappings[cell_type].ports["C"] = 'C';
- if (has_reset)
- cell_mappings[cell_type].ports["R"] = 'R';
- cell_mappings[cell_type].ports["D"] = 'D';
- cell_mappings[cell_type].ports["Q"] = 'Q';
- } else {
- cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
- cell_mappings[cell_type].ports = best_cell_ports;
- }
+ cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
+ cell_mappings[cell_type].ports = best_cell_ports;
}
}
-static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, bool prepare_mode)
+static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol)
{
LibertyAst *best_cell = nullptr;
std::map<std::string, char> best_cell_ports;
@@ -339,141 +330,12 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
if (best_cell != nullptr) {
log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n",
best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str());
- if (prepare_mode) {
- cell_mappings[cell_type].cell_name = cell_type;
- cell_mappings[cell_type].ports["C"] = 'C';
- cell_mappings[cell_type].ports["S"] = 'S';
- cell_mappings[cell_type].ports["R"] = 'R';
- cell_mappings[cell_type].ports["D"] = 'D';
- cell_mappings[cell_type].ports["Q"] = 'Q';
- } else {
- cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
- cell_mappings[cell_type].ports = best_cell_ports;
- }
+ cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
+ cell_mappings[cell_type].ports = best_cell_ports;
}
}
-static bool expand_cellmap_worker(std::string from, std::string to, std::string inv)
-{
- if (cell_mappings.count(to) > 0)
- return false;
-
- log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
- cell_mappings[to].cell_name = cell_mappings[from].cell_name;
- cell_mappings[to].ports = cell_mappings[from].ports;
-
- for (auto &it : cell_mappings[to].ports) {
- char cmp_ch = it.second;
- if ('a' <= cmp_ch && cmp_ch <= 'z')
- cmp_ch -= 'a' - 'A';
- if (inv.find(cmp_ch) == std::string::npos)
- continue;
- if ('a' <= it.second && it.second <= 'z')
- it.second -= 'a' - 'A';
- else if ('A' <= it.second && it.second <= 'Z')
- it.second += 'a' - 'A';
- }
- return true;
-}
-
-static bool expand_cellmap(std::string pattern, std::string inv)
-{
- std::vector<std::pair<std::string, std::string>> from_to_list;
- bool return_status = false;
-
- for (auto &it : cell_mappings) {
- std::string from = it.first.str(), to = it.first.str();
- if (from.size() != pattern.size())
- continue;
- for (size_t i = 0; i < from.size(); i++) {
- if (pattern[i] == '*') {
- to[i] = from[i] == 'P' ? 'N' :
- from[i] == 'N' ? 'P' :
- from[i] == '1' ? '0' :
- from[i] == '0' ? '1' : '*';
- } else
- if (pattern[i] != '?' && pattern[i] != from[i])
- goto pattern_failed;
- }
- from_to_list.push_back(std::pair<std::string, std::string>(from, to));
- pattern_failed:;
- }
-
- for (auto &it : from_to_list)
- return_status = return_status || expand_cellmap_worker(it.first, it.second, inv);
- return return_status;
-}
-
-static void map_sr_to_arst(IdString from, IdString to)
-{
- if (!cell_mappings.count(from) || cell_mappings.count(to) > 0)
- return;
-
- char from_clk_pol = from[8];
- char from_set_pol = from[9];
- char from_clr_pol = from[10];
- char to_clk_pol = to[6];
- char to_rst_pol = to[7];
- char to_rst_val = to[8];
-
- log_assert(from_clk_pol == to_clk_pol);
- log_assert(to_rst_pol == from_set_pol && to_rst_pol == from_clr_pol);
-
- log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
- cell_mappings[to].cell_name = cell_mappings[from].cell_name;
- cell_mappings[to].ports = cell_mappings[from].ports;
-
- for (auto &it : cell_mappings[to].ports)
- {
- bool is_set_pin = it.second == 'S' || it.second == 's';
- bool is_clr_pin = it.second == 'R' || it.second == 'r';
-
- if (!is_set_pin && !is_clr_pin)
- continue;
-
- if ((to_rst_val == '0' && is_set_pin) || (to_rst_val == '1' && is_clr_pin))
- {
- // this is the unused set/clr pin -- deactivate it
- if (is_set_pin)
- it.second = (from_set_pol == 'P') == (it.second == 'S') ? '0' : '1';
- else
- it.second = (from_clr_pol == 'P') == (it.second == 'R') ? '0' : '1';
- }
- else
- {
- // this is the used set/clr pin -- rename it to 'reset'
- if (it.second == 'S')
- it.second = 'R';
- if (it.second == 's')
- it.second = 'r';
- }
- }
-}
-
-static void map_adff_to_dff(IdString from, IdString to)
-{
- if (!cell_mappings.count(from) || cell_mappings.count(to) > 0)
- return;
-
- char from_clk_pol = from[6];
- char from_rst_pol = from[7];
- char to_clk_pol = to[6];
-
- log_assert(from_clk_pol == to_clk_pol);
-
- log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
- cell_mappings[to].cell_name = cell_mappings[from].cell_name;
- cell_mappings[to].ports = cell_mappings[from].ports;
-
- for (auto &it : cell_mappings[to].ports) {
- if (it.second == 'S' || it.second == 'R')
- it.second = from_rst_pol == 'P' ? '0' : '1';
- if (it.second == 's' || it.second == 'r')
- it.second = from_rst_pol == 'P' ? '1' : '0';
- }
-}
-
-static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare_mode)
+static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
{
log("Mapping DFF cells in module `%s':\n", module->name.c_str());
@@ -499,7 +361,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare
module->remove(cell);
cell_mapping &cm = cell_mappings[cell_type];
- RTLIL::Cell *new_cell = module->addCell(cell_name, prepare_mode ? cm.cell_name : cm.cell_name);
+ RTLIL::Cell *new_cell = module->addCell(cell_name, cm.cell_name);
new_cell->set_src_attribute(src);
@@ -552,7 +414,7 @@ struct DfflibmapPass : public Pass {
void help() override
{
log("\n");
- log(" dfflibmap [-prepare] -liberty <file> [selection]\n");
+ log(" dfflibmap [-prepare] [-map-only] [-info] -liberty <file> [selection]\n");
log("\n");
log("Map internal flip-flop cells to the flip-flop cells in the technology\n");
log("library specified in the given liberty file.\n");
@@ -562,15 +424,27 @@ struct DfflibmapPass : public Pass {
log("\n");
log("When called with -prepare, this command will convert the internal FF cells\n");
log("to the internal cell types that best match the cells found in the given\n");
- log("liberty file.\n");
+ log("liberty file, but won't actually map them to the target cells.\n");
+ log("\n");
+ log("When called with -map-only, this command will only map internal cell\n");
+ log("types that are already of exactly the right type to match the target\n");
+ log("cells, leaving remaining internal cells untouched.\n");
+ log("\n");
+ log("When called with -info, this command will only print the target cell\n");
+ log("list, along with their associated internal cell types, and the arguments");
+ log("that would be passed to the dfflegalize pass. The design will not be\n");
+ log("changed.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
log_header(design, "Executing DFFLIBMAP pass (mapping DFF cells to sequential cells from liberty file).\n");
+ log_push();
std::string liberty_file;
bool prepare_mode = false;
+ bool map_only_mode = false;
+ bool info_mode = false;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
@@ -585,10 +459,28 @@ struct DfflibmapPass : public Pass {
prepare_mode = true;
continue;
}
+ if (arg == "-map-only") {
+ map_only_mode = true;
+ continue;
+ }
+ if (arg == "-info") {
+ info_mode = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
+ int modes = 0;
+ if (prepare_mode)
+ modes++;
+ if (map_only_mode)
+ modes++;
+ if (info_mode)
+ modes++;
+ if (modes > 1)
+ log_cmd_error("Only one of -prepare, -map-only, or -info options should be given!\n");
+
if (liberty_file.empty())
log_cmd_error("Missing `-liberty liberty_file' option!\n");
@@ -599,74 +491,49 @@ struct DfflibmapPass : public Pass {
LibertyParser libparser(f);
f.close();
- find_cell(libparser.ast, ID($_DFF_N_), false, false, false, false, prepare_mode);
- find_cell(libparser.ast, ID($_DFF_P_), true, false, false, false, prepare_mode);
-
- find_cell(libparser.ast, ID($_DFF_NN0_), false, true, false, false, prepare_mode);
- find_cell(libparser.ast, ID($_DFF_NN1_), false, true, false, true, prepare_mode);
- find_cell(libparser.ast, ID($_DFF_NP0_), false, true, true, false, prepare_mode);
- find_cell(libparser.ast, ID($_DFF_NP1_), false, true, true, true, prepare_mode);
- find_cell(libparser.ast, ID($_DFF_PN0_), true, true, false, false, prepare_mode);
- find_cell(libparser.ast, ID($_DFF_PN1_), true, true, false, true, prepare_mode);
- find_cell(libparser.ast, ID($_DFF_PP0_), true, true, true, false, prepare_mode);
- find_cell(libparser.ast, ID($_DFF_PP1_), true, true, true, true, prepare_mode);
-
- find_cell_sr(libparser.ast, ID($_DFFSR_NNN_), false, false, false, prepare_mode);
- find_cell_sr(libparser.ast, ID($_DFFSR_NNP_), false, false, true, prepare_mode);
- find_cell_sr(libparser.ast, ID($_DFFSR_NPN_), false, true, false, prepare_mode);
- find_cell_sr(libparser.ast, ID($_DFFSR_NPP_), false, true, true, prepare_mode);
- find_cell_sr(libparser.ast, ID($_DFFSR_PNN_), true, false, false, prepare_mode);
- find_cell_sr(libparser.ast, ID($_DFFSR_PNP_), true, false, true, prepare_mode);
- find_cell_sr(libparser.ast, ID($_DFFSR_PPN_), true, true, false, prepare_mode);
- find_cell_sr(libparser.ast, ID($_DFFSR_PPP_), true, true, true, prepare_mode);
-
- // try to implement as many cells as possible just by inverting
- // the SET and RESET pins. If necessary, implement cell types
- // by inverting both D and Q. Only invert clock pins if there
- // is no other way of implementing the cell.
- while (1)
- {
- if (expand_cellmap("$_DFF_?*?_", "R") ||
- expand_cellmap("$_DFFSR_?*?_", "S") ||
- expand_cellmap("$_DFFSR_??*_", "R"))
- continue;
-
- if (expand_cellmap("$_DFF_??*_", "DQ"))
- continue;
-
- if (expand_cellmap("$_DFF_*_", "C") ||
- expand_cellmap("$_DFF_*??_", "C") ||
- expand_cellmap("$_DFFSR_*??_", "C"))
- continue;
-
- break;
- }
-
- map_sr_to_arst(ID($_DFFSR_NNN_), ID($_DFF_NN0_));
- map_sr_to_arst(ID($_DFFSR_NNN_), ID($_DFF_NN1_));
- map_sr_to_arst(ID($_DFFSR_NPP_), ID($_DFF_NP0_));
- map_sr_to_arst(ID($_DFFSR_NPP_), ID($_DFF_NP1_));
- map_sr_to_arst(ID($_DFFSR_PNN_), ID($_DFF_PN0_));
- map_sr_to_arst(ID($_DFFSR_PNN_), ID($_DFF_PN1_));
- map_sr_to_arst(ID($_DFFSR_PPP_), ID($_DFF_PP0_));
- map_sr_to_arst(ID($_DFFSR_PPP_), ID($_DFF_PP1_));
-
- map_adff_to_dff(ID($_DFF_NN0_), ID($_DFF_N_));
- map_adff_to_dff(ID($_DFF_NN1_), ID($_DFF_N_));
- map_adff_to_dff(ID($_DFF_NP0_), ID($_DFF_N_));
- map_adff_to_dff(ID($_DFF_NP1_), ID($_DFF_N_));
- map_adff_to_dff(ID($_DFF_PN0_), ID($_DFF_P_));
- map_adff_to_dff(ID($_DFF_PN1_), ID($_DFF_P_));
- map_adff_to_dff(ID($_DFF_PP0_), ID($_DFF_P_));
- map_adff_to_dff(ID($_DFF_PP1_), ID($_DFF_P_));
+ find_cell(libparser.ast, ID($_DFF_N_), false, false, false, false);
+ find_cell(libparser.ast, ID($_DFF_P_), true, false, false, false);
+
+ find_cell(libparser.ast, ID($_DFF_NN0_), false, true, false, false);
+ find_cell(libparser.ast, ID($_DFF_NN1_), false, true, false, true);
+ find_cell(libparser.ast, ID($_DFF_NP0_), false, true, true, false);
+ find_cell(libparser.ast, ID($_DFF_NP1_), false, true, true, true);
+ find_cell(libparser.ast, ID($_DFF_PN0_), true, true, false, false);
+ find_cell(libparser.ast, ID($_DFF_PN1_), true, true, false, true);
+ find_cell(libparser.ast, ID($_DFF_PP0_), true, true, true, false);
+ find_cell(libparser.ast, ID($_DFF_PP1_), true, true, true, true);
+
+ find_cell_sr(libparser.ast, ID($_DFFSR_NNN_), false, false, false);
+ find_cell_sr(libparser.ast, ID($_DFFSR_NNP_), false, false, true);
+ find_cell_sr(libparser.ast, ID($_DFFSR_NPN_), false, true, false);
+ find_cell_sr(libparser.ast, ID($_DFFSR_NPP_), false, true, true);
+ find_cell_sr(libparser.ast, ID($_DFFSR_PNN_), true, false, false);
+ find_cell_sr(libparser.ast, ID($_DFFSR_PNP_), true, false, true);
+ find_cell_sr(libparser.ast, ID($_DFFSR_PPN_), true, true, false);
+ find_cell_sr(libparser.ast, ID($_DFFSR_PPP_), true, true, true);
log(" final dff cell mappings:\n");
logmap_all();
- for (auto module : design->selected_modules())
- if (!module->get_blackbox_attribute())
- dfflibmap(design, module, prepare_mode);
+ if (!map_only_mode) {
+ std::string dfflegalize_cmd = "dfflegalize";
+ for (auto it : cell_mappings)
+ dfflegalize_cmd += stringf(" -cell %s 01", it.first.c_str());
+ dfflegalize_cmd += " t:$_DFF* t:$_SDFF*";
+ if (info_mode) {
+ log("dfflegalize command line: %s\n", dfflegalize_cmd.c_str());
+ } else {
+ Pass::call(design, dfflegalize_cmd);
+ }
+ }
+
+ if (!prepare_mode && !info_mode) {
+ for (auto module : design->selected_modules())
+ if (!module->get_blackbox_attribute())
+ dfflibmap(design, module);
+ }
+ log_pop();
cell_mappings.clear();
}
} DfflibmapPass;
diff --git a/passes/techmap/extractinv.cc b/passes/techmap/extractinv.cc
index 9b350456f..11463380c 100644
--- a/passes/techmap/extractinv.cc
+++ b/passes/techmap/extractinv.cc
@@ -2,7 +2,7 @@
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
- * Copyright (C) 2019 Marcin Kościelnicki <mwk@0x04.net>
+ * Copyright (C) 2019 Marcelina Kościelnicka <mwk@0x04.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc
index ddd9822b9..b203828d2 100644
--- a/techlibs/achronix/synth_achronix.cc
+++ b/techlibs/achronix/synth_achronix.cc
@@ -144,12 +144,12 @@ struct SynthAchronixPass : public ScriptPass {
run("opt -fast -mux_undef -undriven -fine -full");
run("memory_map");
run("opt -undriven -fine");
- run("dff2dffe -direct-match $_DFF_*");
run("opt -fine");
run("techmap -map +/techmap.v");
run("opt -full");
run("clean -purge");
run("setundef -undriven -zero");
+ run("dfflegalize -cell $_DFF_P_ x");
if (retime || help_mode)
run("abc -markgroups -dff -D 1", "(only if -retime)");
}
diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc
index 9d564c78c..4c1bc23b5 100644
--- a/techlibs/ecp5/Makefile.inc
+++ b/techlibs/ecp5/Makefile.inc
@@ -1,6 +1,5 @@
-OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o \
- techlibs/ecp5/ecp5_gsr.o
+OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_gsr.o
GENFILES += techlibs/ecp5/bram_init_1_2_4.vh
GENFILES += techlibs/ecp5/bram_init_9_18_36.vh
diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v
index 80f497cc3..dc83d96dc 100644
--- a/techlibs/ecp5/cells_map.v
+++ b/techlibs/ecp5/cells_map.v
@@ -1,64 +1,99 @@
-module \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
-module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
-
-module \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
-module \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
-
-module \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
-module \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
-
-module \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
-
-module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
-
-module \$_SDFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_SDFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_SDFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_SDFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
-
-module \$_SDFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_SDFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_SDFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_SDFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
-
-module \$_DFFE_NN0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_DFFE_NN1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_DFFE_PN0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_DFFE_PN1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
-
-module \$_DFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_DFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_DFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_DFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
-
-module \$_SDFFE_NN0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_SDFFE_NN1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
-module \$_SDFFE_PN0P_ (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 \$_SDFFE_PN1P_ (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 \$_SDFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
-module \$_SDFFE_PP0P_ (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 \$_SDFFE_PP1P_ (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 \$_DFF_N_ (input D, C, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q));
+ else
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q));
+ endgenerate
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+endmodule
+
+module \$_DFF_P_ (input D, C, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q));
+ else
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q));
+ endgenerate
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+endmodule
+
+module \$_DFFE_NN_ (input D, C, E, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q));
+ else
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q));
+ endgenerate
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+endmodule
+
+module \$_DFFE_PN_ (input D, C, E, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q));
+ else
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q));
+ endgenerate
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+endmodule
+
+module \$_DFFE_NP_ (input D, C, E, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q));
+ else
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q));
+ endgenerate
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+endmodule
+
+module \$_DFFE_PP_ (input D, C, E, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q));
+ else
+ TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q));
+ endgenerate
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+endmodule
+
+module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+
+module \$_SDFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_SDFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_SDFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_SDFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+
+module \$_DFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_DFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_DFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_DFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+
+module \$_DFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_DFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_DFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_DFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+
+module \$_SDFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_SDFFE_PP0P_ (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)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_SDFFE_PP1P_ (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)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+
+module \$_SDFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_SDFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule
+module \$_SDFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; 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
diff --git a/techlibs/ecp5/ecp5_ffinit.cc b/techlibs/ecp5/ecp5_ffinit.cc
deleted file mode 100644
index 0ecc86388..000000000
--- a/techlibs/ecp5/ecp5_ffinit.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * yosys -- Yosys Open SYnthesis Suite
- *
- * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
- * Copyright (C) 2018-19 David Shah <david@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/yosys.h"
-#include "kernel/sigtools.h"
-
-USING_YOSYS_NAMESPACE
-PRIVATE_NAMESPACE_BEGIN
-
-struct Ecp5FfinitPass : public Pass {
- Ecp5FfinitPass() : Pass("ecp5_ffinit", "ECP5: handle FF init values") { }
- void help() override
- {
- // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
- log("\n");
- log(" ecp5_ffinit [options] [selection]\n");
- log("\n");
- log("Remove init values for FF output signals when equal to reset value.\n");
- log("If reset is not used, set the reset value to the init value, otherwise\n");
- log("unmap out the reset (if not an async reset).\n");
- }
- void execute(std::vector<std::string> args, RTLIL::Design *design) override
- {
- log_header(design, "Executing ECP5_FFINIT pass (implement FF init values).\n");
-
- size_t argidx;
- for (argidx = 1; argidx < args.size(); argidx++)
- {
- // if (args[argidx] == "-singleton") {
- // singleton_mode = true;
- // continue;
- // }
- break;
- }
- extra_args(args, argidx, design);
-
- for (auto module : design->selected_modules())
- {
- log("Handling FF init values in %s.\n", log_id(module));
-
- SigMap sigmap(module);
- pool<Wire*> init_wires;
- dict<SigBit, State> initbits;
- dict<SigBit, SigBit> initbit_to_wire;
- pool<SigBit> handled_initbits;
-
- for (auto wire : module->selected_wires())
- {
- if (wire->attributes.count(ID::init) == 0)
- continue;
-
- SigSpec wirebits = sigmap(wire);
- Const initval = wire->attributes.at(ID::init);
- init_wires.insert(wire);
-
- for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
- {
- SigBit bit = wirebits[i];
- State val = initval[i];
-
- if (val != State::S0 && val != State::S1)
- continue;
-
- if (initbits.count(bit)) {
- if (initbits.at(bit) != val) {
- log_warning("Conflicting init values for signal %s (%s = %s, %s = %s).\n",
- log_signal(bit), log_signal(SigBit(wire, i)), log_signal(val),
- log_signal(initbit_to_wire[bit]), log_signal(initbits.at(bit)));
- initbits.at(bit) = State::Sx;
- }
- continue;
- }
-
- initbits[bit] = val;
- initbit_to_wire[bit] = SigBit(wire, i);
- }
- }
- for (auto cell : module->selected_cells())
- {
- if (cell->type != ID(TRELLIS_FF))
- continue;
- SigSpec sig_d = cell->getPort(ID(DI));
- SigSpec sig_q = cell->getPort(ID::Q);
- SigSpec sig_lsr = cell->getPort(ID(LSR));
-
- if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
- continue;
-
- SigBit bit_d = sigmap(sig_d[0]);
- SigBit bit_q = sigmap(sig_q[0]);
-
- std::string regset = cell->getParam(ID(REGSET)).decode_string();
- State resetState;
- if (regset == "SET")
- resetState = State::S1;
- else if (regset == "RESET")
- resetState = State::S0;
- else
- log_error("FF cell %s has illegal REGSET value %s.\n",
- log_id(cell), regset.c_str());
-
- if (!initbits.count(bit_q))
- continue;
-
- State val = initbits.at(bit_q);
-
- if (val == State::Sx)
- continue;
-
- log("FF init value for cell %s (%s): %s = %c\n", log_id(cell), log_id(cell->type),
- log_signal(bit_q), val != State::S0 ? '1' : '0');
- // Initval is the same as the reset state. Matches hardware, nowt more to do
- if (val == resetState) {
- handled_initbits.insert(bit_q);
- continue;
- }
-
- if (GetSize(sig_lsr) >= 1 && sig_lsr[0] != State::S0) {
- std::string srmode = cell->getParam(ID(SRMODE)).decode_string();
- if (srmode == "ASYNC") {
- log("Async reset value %c for FF cell %s inconsistent with init value %c.\n",
- resetState != State::S0 ? '1' : '0', log_id(cell), val != State::S0 ? '1' : '0');
- } else {
- SigBit bit_lsr = sigmap(sig_lsr[0]);
- Wire *new_bit_d = module->addWire(NEW_ID);
- if (resetState == State::S0) {
- module->addAndnotGate(NEW_ID, bit_d, bit_lsr, new_bit_d);
- } else {
- module->addOrGate(NEW_ID, bit_d, bit_lsr, new_bit_d);
- }
-
- cell->setPort(ID(DI), new_bit_d);
- cell->setPort(ID(LSR), State::S0);
-
- if(cell->hasPort(ID(CE))) {
- std::string cemux = cell->getParam(ID(CEMUX)).decode_string();
- SigSpec sig_ce = cell->getPort(ID(CE));
- if (GetSize(sig_ce) >= 1) {
- SigBit bit_ce = sigmap(sig_ce[0]);
- Wire *new_bit_ce = module->addWire(NEW_ID);
- if (cemux == "INV")
- module->addAndnotGate(NEW_ID, bit_ce, bit_lsr, new_bit_ce);
- else
- module->addOrGate(NEW_ID, bit_ce, bit_lsr, new_bit_ce);
- cell->setPort(ID(CE), new_bit_ce);
- }
- }
- cell->setParam(ID(REGSET), val != State::S0 ? Const("SET") : Const("RESET"));
- handled_initbits.insert(bit_q);
- }
- } else {
- cell->setParam(ID(REGSET), val != State::S0 ? Const("SET") : Const("RESET"));
- handled_initbits.insert(bit_q);
- }
- }
-
- for (auto wire : init_wires)
- {
- if (wire->attributes.count(ID::init) == 0)
- continue;
-
- SigSpec wirebits = sigmap(wire);
- Const &initval = wire->attributes.at(ID::init);
- bool remove_attribute = true;
-
- for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) {
- if (handled_initbits.count(wirebits[i]))
- initval[i] = State::Sx;
- else if (initval[i] != State::Sx)
- remove_attribute = false;
- }
-
- if (remove_attribute)
- wire->attributes.erase(ID::init);
- }
- }
- }
-} Ecp5FfinitPass;
-
-PRIVATE_NAMESPACE_END
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index 0874b954a..46d051e44 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -315,12 +315,17 @@ struct SynthEcp5Pass : public ScriptPass
run("opt_clean");
if (!nodffe)
run("dff2dffe -direct-match $_DFF_* -direct-match $_SDFF_*");
+ if (help_mode)
+ run("dfflegalize -cell $_DFF_?_ 01 -cell $_DFFE_??_ 01 -cell $_DFF_?P?_ r -cell $_DFFE_?P??_ r -cell $_SDFF_?P?_ r -cell $_SDFFE_?P??_ r -cell $_DLATCH_?_ x [-cell $_DFFSR_?PP_ x]", "($_DFFSR_*_ only if -asyncprld)");
+ else if (asyncprld)
+ run("dfflegalize -cell $_DFF_?_ 01 -cell $_DFFE_??_ 01 -cell $_DFF_?P?_ r -cell $_DFFE_?P??_ r -cell $_SDFF_?P?_ r -cell $_SDFFE_?P??_ r -cell $_DLATCH_?_ x -cell $_DFFSR_?PP_ x");
+ else
+ run("dfflegalize -cell $_DFF_?_ 01 -cell $_DFFE_??_ 01 -cell $_DFF_?P?_ r -cell $_DFFE_?P??_ r -cell $_SDFF_?P?_ r -cell $_SDFFE_?P??_ r -cell $_DLATCH_?_ x");
if ((abc9 && dff) || help_mode)
run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff");
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("simplemap");
- run("ecp5_ffinit");
run("ecp5_gsr");
run("attrmvcp -copy -attr syn_useioff");
run("opt_clean");
diff --git a/techlibs/efinix/cells_map.v b/techlibs/efinix/cells_map.v
index 1090f8b27..3091ad196 100644
--- a/techlibs/efinix/cells_map.v
+++ b/techlibs/efinix/cells_map.v
@@ -1,21 +1,59 @@
-module \$_DFF_N_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
-module \$_DFF_P_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
+(* techmap_celltype = "$_DFFE_PP0P_ $_DFFE_PP0N_ $_DFFE_PP1P_ $_DFFE_PP1N_ $_DFFE_PN0P_ $_DFFE_PN0N_ $_DFFE_PN1P_ $_DFFE_PN1N_ $_DFFE_NP0P_ $_DFFE_NP0N_ $_DFFE_NP1P_ $_DFFE_NP1N_ $_DFFE_NN0P_ $_DFFE_NN0N_ $_DFFE_NN1P_ $_DFFE_NN1N_" *)
+module \$_DFFE_xxxx_ (input D, C, R, E, output Q);
-module \$_DFFE_NN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
-module \$_DFFE_NP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
+ parameter _TECHMAP_CELLTYPE_ = "";
-module \$_DFFE_PN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
-module \$_DFFE_PP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
+ EFX_FF #(
+ .CLK_POLARITY(_TECHMAP_CELLTYPE_[39:32] == "P"),
+ .CE_POLARITY(_TECHMAP_CELLTYPE_[15:8] == "P"),
+ .SR_POLARITY(_TECHMAP_CELLTYPE_[31:24] == "P"),
+ .D_POLARITY(1'b1),
+ .SR_SYNC(1'b0),
+ .SR_VALUE(_TECHMAP_CELLTYPE_[23:16] == "1"),
+ .SR_SYNC_PRIORITY(1'b1)
+ ) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(R), .Q(Q));
-module \$_DFF_NN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .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_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .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 \$_DFF_PN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .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_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .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
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
-module \$_DFF_NP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .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_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .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 \$_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
+endmodule
+
+(* techmap_celltype = "$_SDFFE_PP0P_ $_SDFFE_PP0N_ $_SDFFE_PP1P_ $_SDFFE_PP1N_ $_SDFFE_PN0P_ $_SDFFE_PN0N_ $_SDFFE_PN1P_ $_SDFFE_PN1N_ $_SDFFE_NP0P_ $_SDFFE_NP0N_ $_SDFFE_NP1P_ $_SDFFE_NP1N_ $_SDFFE_NN0P_ $_SDFFE_NN0N_ $_SDFFE_NN1P_ $_SDFFE_NN1N_" *)
+module \$_SDFFE_xxxx_ (input D, C, R, E, output Q);
+
+ parameter _TECHMAP_CELLTYPE_ = "";
+
+ EFX_FF #(
+ .CLK_POLARITY(_TECHMAP_CELLTYPE_[39:32] == "P"),
+ .CE_POLARITY(_TECHMAP_CELLTYPE_[15:8] == "P"),
+ .SR_POLARITY(_TECHMAP_CELLTYPE_[31:24] == "P"),
+ .D_POLARITY(1'b1),
+ .SR_SYNC(1'b1),
+ .SR_VALUE(_TECHMAP_CELLTYPE_[23:16] == "1"),
+ .SR_SYNC_PRIORITY(1'b1)
+ ) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(R), .Q(Q));
+
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+
+endmodule
+
+(* techmap_celltype = "$_SDFFCE_PP0P_ $_SDFFCE_PP0N_ $_SDFFCE_PP1P_ $_SDFFCE_PP1N_ $_SDFFCE_PN0P_ $_SDFFCE_PN0N_ $_SDFFCE_PN1P_ $_SDFFCE_PN1N_ $_SDFFCE_NP0P_ $_SDFFCE_NP0N_ $_SDFFCE_NP1P_ $_SDFFCE_NP1N_ $_SDFFCE_NN0P_ $_SDFFCE_NN0N_ $_SDFFCE_NN1P_ $_SDFFCE_NN1N_" *)
+module \$_SDFFCE_xxxx_ (input D, C, R, E, output Q);
+
+ parameter _TECHMAP_CELLTYPE_ = "";
+
+ EFX_FF #(
+ .CLK_POLARITY(_TECHMAP_CELLTYPE_[39:32] == "P"),
+ .CE_POLARITY(_TECHMAP_CELLTYPE_[15:8] == "P"),
+ .SR_POLARITY(_TECHMAP_CELLTYPE_[31:24] == "P"),
+ .D_POLARITY(1'b1),
+ .SR_SYNC(1'b1),
+ .SR_VALUE(_TECHMAP_CELLTYPE_[23:16] == "1"),
+ .SR_SYNC_PRIORITY(1'b0)
+ ) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(R), .Q(Q));
+
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+
+endmodule
module \$_DLATCH_N_ (E, D, Q);
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc
index cc926235f..001b05945 100644
--- a/techlibs/efinix/synth_efinix.cc
+++ b/techlibs/efinix/synth_efinix.cc
@@ -182,8 +182,8 @@ struct SynthEfinixPass : public ScriptPass
if (check_label("map_ffs"))
{
+ run("dfflegalize -cell $_DFFE_????_ 0 -cell $_SDFFE_????_ 0 -cell $_SDFFCE_????_ 0 -cell $_DLATCH_?_ x");
run("techmap -D NO_LUT -map +/efinix/cells_map.v");
- run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit");
run("opt_expr -mux_undef");
run("simplemap");
}
diff --git a/techlibs/gowin/Makefile.inc b/techlibs/gowin/Makefile.inc
index 0756e3bcf..e6a6be970 100644
--- a/techlibs/gowin/Makefile.inc
+++ b/techlibs/gowin/Makefile.inc
@@ -1,6 +1,5 @@
OBJS += techlibs/gowin/synth_gowin.o
-OBJS += techlibs/gowin/determine_init.o
GENFILES += techlibs/gowin/bram_init_16.vh
diff --git a/techlibs/gowin/cells_map.v b/techlibs/gowin/cells_map.v
index 5460274ca..851ef20b2 100644
--- a/techlibs/gowin/cells_map.v
+++ b/techlibs/gowin/cells_map.v
@@ -3,228 +3,123 @@
//value regardless. The parameter is ignored.
// DFFN D Flip-Flop with Negative-Edge Clock
-module \$_DFF_N_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, output Q);
- generate
- if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(1'b0));
- else
- DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C));
- endgenerate
+module \$_DFF_N_ (input D, C, output Q);
+ DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C));
wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFF D Flip-Flop
-module \$_DFF_P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, output Q);
- generate
- if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(1'b0));
- else
- DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C));
- endgenerate
+module \$_DFF_P_ (input D, C, output Q);
+ DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C));
wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFE D Flip-Flop with Clock Enable
-module \$_DFFE_PP_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q);
- generate
- if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E), .SET(1'b0));
- else
- DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E));
- endgenerate
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-
-module \$_DFFE_PN_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q);
- generate
- if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E), .SET(1'b0));
- else
- DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E));
- endgenerate
+module \$_DFFE_PP_ (input D, C, E, output Q);
+ DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E));
wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFNE D Flip-Flop with Negative-Edge Clock and Clock Enable
-module \$_DFFE_NP_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q);
- generate
- if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E), .SET(1'b0));
- else
- DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E));
- endgenerate
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-
-module \$_DFFE_NN_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q);
- generate
- if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E), .SET(1'b0));
- else
- DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E));
- endgenerate
+module \$_DFFE_NP_ (input D, C, E, output Q);
+ DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E));
wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFR D Flip-Flop with Synchronous Reset
-module \$_SDFF_PN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
- DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
-endmodule
-
-module \$_SDFF_PP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
+module \$_SDFF_PP0_ (input D, C, R, output Q);
DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFNR D Flip-Flop with Negative-Edge Clock and Synchronous Reset
-module \$_SDFF_NN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
- DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
-endmodule
-module \$_SDFF_NP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
+module \$_SDFF_NP0_ (input D, C, R, output Q);
DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFRE D Flip-Flop with Clock Enable and Synchronous Reset
-module \$_SDFFE_PN0P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
- DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
-endmodule
-module \$_SDFFE_PP0P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
+module \$_SDFFE_PP0P_ (input D, C, R, E, output Q);
DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFNRE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Synchronous Reset
-module \$_SDFFE_NN0P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
- DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
-endmodule
-module \$_SDFFE_NP0P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
+module \$_SDFFE_NP0P_ (input D, C, R, E, output Q);
DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFS D Flip-Flop with Synchronous Set
-module \$_SDFF_PN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
- DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
-endmodule
-module \$_SDFF_PP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
+module \$_SDFF_PP1_ (input D, C, R, output Q);
DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFNS D Flip-Flop with Negative-Edge Clock and Synchronous Set
-module \$_SDFF_NN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
- DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
-endmodule
-module \$_SDFF_NP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
+module \$_SDFF_NP1_ (input D, C, R, output Q);
DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFSE D Flip-Flop with Clock Enable and Synchronous Set
-module \$_SDFFE_PN1P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
- DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
-endmodule
-module \$_SDFFE_PP1P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
+module \$_SDFFE_PP1P_ (input D, C, R, E, output Q);
DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFNSE D Flip-Flop with Negative-Edge Clock,Clock Enable,and Synchronous Set
-module \$_SDFFE_NN1P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
- DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
-endmodule
-module \$_SDFFE_NP1P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
+module \$_SDFFE_NP1P_ (input D, C, R, E, output Q);
DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFP D Flip-Flop with Asynchronous Preset
-module \$_DFF_PP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
+module \$_DFF_PP1_ (input D, C, R, output Q);
DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
-endmodule
-module \$_DFF_PN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
- DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFNP D Flip-Flop with Negative-Edge Clock and Asynchronous Preset
-module \$_DFF_NP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
+module \$_DFF_NP1_ (input D, C, R, output Q);
DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
-endmodule
-module \$_DFF_NN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
- DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFC D Flip-Flop with Asynchronous Clear
-module \$_DFF_PP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
+module \$_DFF_PP0_ (input D, C, R, output Q);
DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
-endmodule
-module \$_DFF_PN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
- DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFNC D Flip-Flop with Negative-Edge Clock and Asynchronous Clear
-module \$_DFF_NP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
+module \$_DFF_NP0_ (input D, C, R, output Q);
DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
-endmodule
-module \$_DFF_NN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q);
- DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFPE D Flip-Flop with Clock Enable and Asynchronous Preset
-module \$_DFFE_PP1P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
+module \$_DFFE_PP1P_ (input D, C, R, E, output Q);
DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
-endmodule
-module \$_DFFE_PN1P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
- DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFNPE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Asynchronous Preset
-module \$_DFFE_NP1P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
+module \$_DFFE_NP1P_ (input D, C, R, E, output Q);
DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
-endmodule
-module \$_DFFE_NN1P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
- DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFCE D Flip-Flop with Clock Enable and Asynchronous Clear
-module \$_DFFE_PP0P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
+module \$_DFFE_PP0P_ (input D, C, R, E, output Q);
DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
-endmodule
-module \$_DFFE_PN0P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
- DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
// DFFNCE D Flip-Flop with Negative-Edge Clock,Clock Enable and Asynchronous Clear
-module \$_DFFE_NP0P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
+module \$_DFFE_NP0P_ (input D, C, R, E, output Q);
DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
-endmodule
-module \$_DFFE_NN0P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q);
- DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E));
- wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1;
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
endmodule
diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v
index a67855dab..47ece84df 100644
--- a/techlibs/gowin/cells_sim.v
+++ b/techlibs/gowin/cells_sim.v
@@ -1,33 +1,112 @@
+(* abc9_lut=1 *)
module LUT1(output F, input I0);
parameter [1:0] INIT = 0;
+ specify
+ (I0 => F) = (555, 902);
+ endspecify
assign F = I0 ? INIT[1] : INIT[0];
endmodule
+(* abc9_lut=1 *)
module LUT2(output F, input I0, I1);
parameter [3:0] INIT = 0;
+ specify
+ (I0 => F) = (867, 1184);
+ (I1 => F) = (555, 902);
+ endspecify
wire [ 1: 0] s1 = I1 ? INIT[ 3: 2] : INIT[ 1: 0];
assign F = I0 ? s1[1] : s1[0];
endmodule
+(* abc9_lut=1 *)
module LUT3(output F, input I0, I1, I2);
parameter [7:0] INIT = 0;
+ specify
+ (I0 => F) = (1054, 1486);
+ (I1 => F) = (867, 1184);
+ (I2 => F) = (555, 902);
+ endspecify
wire [ 3: 0] s2 = I2 ? INIT[ 7: 4] : INIT[ 3: 0];
wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
assign F = I0 ? s1[1] : s1[0];
endmodule
+(* abc9_lut=1 *)
module LUT4(output F, input I0, I1, I2, I3);
parameter [15:0] INIT = 0;
+ specify
+ (I0 => F) = (1054, 1486);
+ (I1 => F) = (1053, 1583);
+ (I2 => F) = (867, 1184);
+ (I3 => F) = (555, 902);
+ endspecify
wire [ 7: 0] s3 = I3 ? INIT[15: 8] : INIT[ 7: 0];
wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
assign F = I0 ? s1[1] : s1[0];
endmodule
+(* abc9_lut=2 *)
+module __APICULA_LUT5(output F, input I0, I1, I2, I3, M0);
+ specify
+ (I0 => F) = (1187, 1638);
+ (I1 => F) = (1184, 1638);
+ (I2 => F) = (995, 1371);
+ (I3 => F) = (808, 1116);
+ (M0 => F) = (486, 680);
+ endspecify
+endmodule
+
+(* abc9_lut=4 *)
+module __APICULA_LUT6(output F, input I0, I1, I2, I3, M0, M1);
+ specify
+ (I0 => F) = (1187 + 136, 1638 + 255);
+ (I1 => F) = (1184 + 136, 1638 + 255);
+ (I2 => F) = (995 + 136, 1371 + 255);
+ (I3 => F) = (808 + 136, 1116 + 255);
+ (M0 => F) = (486 + 136, 680 + 255);
+ (M1 => F) = (478, 723);
+ endspecify
+endmodule
+
+(* abc9_lut=8 *)
+module __APICULA_LUT7(output F, input I0, I1, I2, I3, M0, M1, M2);
+ specify
+ (I0 => F) = (1187 + 136 + 136, 1638 + 255 + 255);
+ (I1 => F) = (1184 + 136 + 136, 1638 + 255 + 255);
+ (I2 => F) = (995 + 136 + 136, 1371 + 255 + 255);
+ (I3 => F) = (808 + 136 + 136, 1116 + 255 + 255);
+ (M0 => F) = (486 + 136 + 136, 680 + 255 + 255);
+ (M1 => F) = (478 + 136, 723 + 255);
+ (M2 => F) = (478, 723);
+ endspecify
+endmodule
+
+(* abc9_lut=16 *)
+module __APICULA_LUT8(output F, input I0, I1, I2, I3, M0, M1, M2, M3);
+ specify
+ (I0 => F) = (1187 + 136 + 136 + 136, 1638 + 255 + 255 + 255);
+ (I1 => F) = (1184 + 136 + 136 + 136, 1638 + 255 + 255 + 255);
+ (I2 => F) = (995 + 136 + 136 + 136, 1371 + 255 + 255 + 255);
+ (I3 => F) = (808 + 136 + 136 + 136, 1116 + 255 + 255 + 255);
+ (M0 => F) = (486 + 136 + 136 + 136, 680 + 255 + 255 + 255);
+ (M1 => F) = (478 + 136 + 136, 723 + 255 + 255);
+ (M2 => F) = (478 + 136, 723 + 255);
+ (M3 => F) = (478, 723);
+ endspecify
+ endmodule
+
module MUX2 (O, I0, I1, S0);
input I0,I1;
input S0;
output O;
+
+ specify
+ (I0 => O) = (141, 160);
+ (I1 => O) = (141, 160);
+ (S0 => O) = (486, 680);
+ endspecify
+
assign O = S0 ? I1 : I0;
endmodule
@@ -35,6 +114,13 @@ module MUX2_LUT5 (O, I0, I1, S0);
input I0,I1;
input S0;
output O;
+
+ specify
+ (I0 => O) = (141, 160);
+ (I1 => O) = (141, 160);
+ (S0 => O) = (486, 680);
+ endspecify
+
MUX2 mux2_lut5 (O, I0, I1, S0);
endmodule
@@ -42,6 +128,13 @@ module MUX2_LUT6 (O, I0, I1, S0);
input I0,I1;
input S0;
output O;
+
+ specify
+ (I0 => O) = (136, 255);
+ (I1 => O) = (136, 255);
+ (S0 => O) = (478, 723);
+ endspecify
+
MUX2 mux2_lut6 (O, I0, I1, S0);
endmodule
@@ -49,6 +142,13 @@ module MUX2_LUT7 (O, I0, I1, S0);
input I0,I1;
input S0;
output O;
+
+ specify
+ (I0 => O) = (136, 255);
+ (I1 => O) = (136, 255);
+ (S0 => O) = (478, 723);
+ endspecify
+
MUX2 mux2_lut7 (O, I0, I1, S0);
endmodule
@@ -56,29 +156,58 @@ module MUX2_LUT8 (O, I0, I1, S0);
input I0,I1;
input S0;
output O;
+
+ specify
+ (I0 => O) = (136, 255);
+ (I1 => O) = (136, 255);
+ (S0 => O) = (478, 723);
+ endspecify
+
MUX2 mux2_lut8 (O, I0, I1, S0);
endmodule
+(* abc9_flop, lib_whitebox *)
module DFF (output reg Q, input CLK, D);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ (posedge CLK => (Q : D)) = (480, 660);
+ $setup(D, posedge CLK, 576);
+ endspecify
+
always @(posedge CLK)
Q <= D;
endmodule
+(* abc9_flop, lib_whitebox *)
module DFFE (output reg Q, input D, CLK, CE);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ if (CE) (posedge CLK => (Q : D)) = (480, 660);
+ $setup(D, posedge CLK &&& CE, 576);
+ $setup(CE, posedge CLK, 63);
+ endspecify
+
always @(posedge CLK) begin
if (CE)
Q <= D;
end
endmodule // DFFE (positive clock edge; clock enable)
-
+(* abc9_box, lib_whitebox *)
module DFFS (output reg Q, input D, CLK, SET);
- parameter [0:0] INIT = 1'b0;
+ parameter [0:0] INIT = 1'b1;
initial Q = INIT;
+
+ specify
+ (posedge CLK => (Q : D)) = (480, 660);
+ $setup(D, posedge CLK, 576);
+ $setup(SET, posedge CLK, 63);
+ endspecify
+
always @(posedge CLK) begin
if (SET)
Q <= 1'b1;
@@ -87,10 +216,18 @@ module DFFS (output reg Q, input D, CLK, SET);
end
endmodule // DFFS (positive clock edge; synchronous set)
-
+(* abc9_box, lib_whitebox *)
module DFFSE (output reg Q, input D, CLK, CE, SET);
- parameter [0:0] INIT = 1'b0;
+ parameter [0:0] INIT = 1'b1;
initial Q = INIT;
+
+ specify
+ if (CE) (posedge CLK => (Q : D)) = (480, 660);
+ $setup(D, posedge CLK &&& CE, 576);
+ $setup(CE, posedge CLK, 63);
+ $setup(SET, posedge CLK, 63);
+ endspecify
+
always @(posedge CLK) begin
if (SET)
Q <= 1'b1;
@@ -99,10 +236,17 @@ module DFFSE (output reg Q, input D, CLK, CE, SET);
end
endmodule // DFFSE (positive clock edge; synchronous set takes precedence over clock enable)
-
+(* abc9_flop, lib_whitebox *)
module DFFR (output reg Q, input D, CLK, RESET);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ (posedge CLK => (Q : D)) = (480, 660);
+ $setup(D, posedge CLK, 576);
+ $setup(RESET, posedge CLK, 63);
+ endspecify
+
always @(posedge CLK) begin
if (RESET)
Q <= 1'b0;
@@ -111,10 +255,18 @@ module DFFR (output reg Q, input D, CLK, RESET);
end
endmodule // DFFR (positive clock edge; synchronous reset)
-
+(* abc9_flop, lib_whitebox *)
module DFFRE (output reg Q, input D, CLK, CE, RESET);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ if (CE) (posedge CLK => (Q : D)) = (480, 660);
+ $setup(D, posedge CLK &&& CE, 576);
+ $setup(CE, posedge CLK, 63);
+ $setup(RESET, posedge CLK, 63);
+ endspecify
+
always @(posedge CLK) begin
if (RESET)
Q <= 1'b0;
@@ -123,10 +275,17 @@ module DFFRE (output reg Q, input D, CLK, CE, RESET);
end
endmodule // DFFRE (positive clock edge; synchronous reset takes precedence over clock enable)
-
+(* abc9_box, lib_whitebox *)
module DFFP (output reg Q, input D, CLK, PRESET);
- parameter [0:0] INIT = 1'b0;
+ parameter [0:0] INIT = 1'b1;
initial Q = INIT;
+
+ specify
+ (posedge CLK => (Q : D)) = (480, 660);
+ (posedge PRESET => (Q : 1'b1)) = (1800, 2679);
+ $setup(D, posedge CLK, 576);
+ endspecify
+
always @(posedge CLK or posedge PRESET) begin
if(PRESET)
Q <= 1'b1;
@@ -135,10 +294,18 @@ module DFFP (output reg Q, input D, CLK, PRESET);
end
endmodule // DFFP (positive clock edge; asynchronous preset)
-
+(* abc9_box, lib_whitebox *)
module DFFPE (output reg Q, input D, CLK, CE, PRESET);
- parameter [0:0] INIT = 1'b0;
+ parameter [0:0] INIT = 1'b1;
initial Q = INIT;
+
+ specify
+ if (CE) (posedge CLK => (Q : D)) = (480, 660);
+ (posedge PRESET => (Q : 1'b1)) = (1800, 2679);
+ $setup(D, posedge CLK &&& CE, 576);
+ $setup(CE, posedge CLK, 63);
+ endspecify
+
always @(posedge CLK or posedge PRESET) begin
if(PRESET)
Q <= 1'b1;
@@ -147,10 +314,17 @@ module DFFPE (output reg Q, input D, CLK, CE, PRESET);
end
endmodule // DFFPE (positive clock edge; asynchronous preset; clock enable)
-
+(* abc9_box, lib_whitebox *)
module DFFC (output reg Q, input D, CLK, CLEAR);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ (posedge CLK => (Q : D)) = (480, 660);
+ (posedge CLEAR => (Q : 1'b0)) = (1800, 2679);
+ $setup(D, posedge CLK, 576);
+ endspecify
+
always @(posedge CLK or posedge CLEAR) begin
if(CLEAR)
Q <= 1'b0;
@@ -159,10 +333,18 @@ module DFFC (output reg Q, input D, CLK, CLEAR);
end
endmodule // DFFC (positive clock edge; asynchronous clear)
-
+(* abc9_box, lib_whitebox *)
module DFFCE (output reg Q, input D, CLK, CE, CLEAR);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ if (CE) (posedge CLK => (Q : D)) = (480, 660);
+ (posedge CLEAR => (Q : 1'b0)) = (1800, 2679);
+ $setup(D, posedge CLK &&& CE, 576);
+ $setup(CE, posedge CLK, 63);
+ endspecify
+
always @(posedge CLK or posedge CLEAR) begin
if(CLEAR)
Q <= 1'b0;
@@ -171,27 +353,48 @@ module DFFCE (output reg Q, input D, CLK, CE, CLEAR);
end
endmodule // DFFCE (positive clock edge; asynchronous clear; clock enable)
-
+(* abc9_flop, lib_whitebox *)
module DFFN (output reg Q, input CLK, D);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ (negedge CLK => (Q : D)) = (480, 660);
+ $setup(D, negedge CLK, 576);
+ endspecify
+
always @(negedge CLK)
Q <= D;
endmodule
+(* abc9_flop, lib_whitebox *)
module DFFNE (output reg Q, input D, CLK, CE);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ if (CE) (negedge CLK => (Q : D)) = (480, 660);
+ $setup(D, negedge CLK &&& CE, 576);
+ $setup(CE, negedge CLK, 63);
+ endspecify
+
always @(negedge CLK) begin
if (CE)
Q <= D;
end
endmodule // DFFNE (negative clock edge; clock enable)
-
+(* abc9_box, lib_whitebox *)
module DFFNS (output reg Q, input D, CLK, SET);
- parameter [0:0] INIT = 1'b0;
+ parameter [0:0] INIT = 1'b1;
initial Q = INIT;
+
+ specify
+ (negedge CLK => (Q : D)) = (480, 660);
+ $setup(D, negedge CLK, 576);
+ $setup(SET, negedge CLK, 63);
+ endspecify
+
always @(negedge CLK) begin
if (SET)
Q <= 1'b1;
@@ -200,10 +403,18 @@ module DFFNS (output reg Q, input D, CLK, SET);
end
endmodule // DFFNS (negative clock edge; synchronous set)
-
+(* abc9_box, lib_whitebox *)
module DFFNSE (output reg Q, input D, CLK, CE, SET);
- parameter [0:0] INIT = 1'b0;
+ parameter [0:0] INIT = 1'b1;
initial Q = INIT;
+
+ specify
+ if (CE) (negedge CLK => (Q : D)) = (480, 660);
+ $setup(D, negedge CLK &&& CE, 576);
+ $setup(CE, negedge CLK, 63);
+ $setup(SET, negedge CLK, 63);
+ endspecify
+
always @(negedge CLK) begin
if (SET)
Q <= 1'b1;
@@ -212,10 +423,17 @@ module DFFNSE (output reg Q, input D, CLK, CE, SET);
end
endmodule // DFFNSE (negative clock edge; synchronous set takes precedence over clock enable)
-
+(* abc9_flop, lib_whitebox *)
module DFFNR (output reg Q, input D, CLK, RESET);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ (negedge CLK => (Q : D)) = (480, 660);
+ $setup(D, negedge CLK, 576);
+ $setup(RESET, negedge CLK, 63);
+ endspecify
+
always @(negedge CLK) begin
if (RESET)
Q <= 1'b0;
@@ -224,10 +442,18 @@ module DFFNR (output reg Q, input D, CLK, RESET);
end
endmodule // DFFNR (negative clock edge; synchronous reset)
-
+(* abc9_flop, lib_whitebox *)
module DFFNRE (output reg Q, input D, CLK, CE, RESET);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ if (CE) (negedge CLK => (Q : D)) = (480, 660);
+ $setup(D, negedge CLK &&& CE, 576);
+ $setup(CE, negedge CLK, 63);
+ $setup(RESET, negedge CLK, 63);
+ endspecify
+
always @(negedge CLK) begin
if (RESET)
Q <= 1'b0;
@@ -236,10 +462,17 @@ module DFFNRE (output reg Q, input D, CLK, CE, RESET);
end
endmodule // DFFNRE (negative clock edge; synchronous reset takes precedence over clock enable)
-
+(* abc9_box, lib_whitebox *)
module DFFNP (output reg Q, input D, CLK, PRESET);
- parameter [0:0] INIT = 1'b0;
+ parameter [0:0] INIT = 1'b1;
initial Q = INIT;
+
+ specify
+ (negedge CLK => (Q : D)) = (480, 660);
+ (posedge PRESET => (Q : 1'b1)) = (1800, 2679);
+ $setup(D, negedge CLK, 576);
+ endspecify
+
always @(negedge CLK or posedge PRESET) begin
if(PRESET)
Q <= 1'b1;
@@ -248,10 +481,18 @@ module DFFNP (output reg Q, input D, CLK, PRESET);
end
endmodule // DFFNP (negative clock edge; asynchronous preset)
-
+(* abc9_box, lib_whitebox *)
module DFFNPE (output reg Q, input D, CLK, CE, PRESET);
- parameter [0:0] INIT = 1'b0;
+ parameter [0:0] INIT = 1'b1;
initial Q = INIT;
+
+ specify
+ if (CE) (negedge CLK => (Q : D)) = (480, 660);
+ (posedge PRESET => (Q : 1'b1)) = (1800, 2679);
+ $setup(D, negedge CLK &&& CE, 576);
+ $setup(CE, negedge CLK, 63);
+ endspecify
+
always @(negedge CLK or posedge PRESET) begin
if(PRESET)
Q <= 1'b1;
@@ -260,10 +501,17 @@ module DFFNPE (output reg Q, input D, CLK, CE, PRESET);
end
endmodule // DFFNPE (negative clock edge; asynchronous preset; clock enable)
-
+(* abc9_box, lib_whitebox *)
module DFFNC (output reg Q, input D, CLK, CLEAR);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ (negedge CLK => (Q : D)) = (480, 660);
+ (posedge CLEAR => (Q : 1'b0)) = (1800, 2679);
+ $setup(D, negedge CLK, 576);
+ endspecify
+
always @(negedge CLK or posedge CLEAR) begin
if(CLEAR)
Q <= 1'b0;
@@ -272,10 +520,18 @@ module DFFNC (output reg Q, input D, CLK, CLEAR);
end
endmodule // DFFNC (negative clock edge; asynchronous clear)
-
+(* abc9_box, lib_whitebox *)
module DFFNCE (output reg Q, input D, CLK, CE, CLEAR);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
+
+ specify
+ if (CE) (negedge CLK => (Q : D)) = (480, 660);
+ (posedge CLEAR => (Q : 1'b0)) = (1800, 2679);
+ $setup(D, negedge CLK &&& CE, 576);
+ $setup(CE, negedge CLK, 63);
+ endspecify
+
always @(negedge CLK or posedge CLEAR) begin
if(CLEAR)
Q <= 1'b0;
@@ -294,11 +550,23 @@ module GND(output G);
assign G = 0;
endmodule
+(* abc9_box *)
module IBUF(output O, input I);
+
+ specify
+ (I => O) = 0;
+ endspecify
+
assign O = I;
endmodule
+(* abc9_box *)
module OBUF(output O, input I);
+
+ specify
+ (I => O) = 0;
+ endspecify
+
assign O = I;
endmodule
@@ -320,14 +588,15 @@ module GSR (input GSRI);
wire GSRO = GSRI;
endmodule
+(* abc9_box, lib_whitebox *)
module ALU (SUM, COUT, I0, I1, I3, CIN);
input I0;
input I1;
input I3;
-input CIN;
+(* abc9_carry *) input CIN;
output SUM;
-output COUT;
+(* abc9_carry *) output COUT;
localparam ADD = 0;
localparam SUB = 1;
@@ -344,6 +613,17 @@ parameter ALU_MODE = 0;
reg S, C;
+specify
+ (I0 => SUM) = (1043, 1432);
+ (I1 => SUM) = (775, 1049);
+ (I3 => SUM) = (751, 1010);
+ (CIN => SUM) = (694, 811);
+ (I0 => COUT) = (1010, 1380);
+ (I1 => COUT) = (1021, 1505);
+ (I3 => COUT) = (483, 792);
+ (CIN => COUT) = (49, 82);
+endspecify
+
assign SUM = S ^ CIN;
assign COUT = S? CIN : C;
@@ -394,7 +674,6 @@ end
endmodule
-
module RAM16S4 (DO, DI, AD, WRE, CLK);
parameter WIDTH = 4;
parameter INIT_0 = 16'h0000;
@@ -408,6 +687,14 @@ module RAM16S4 (DO, DI, AD, WRE, CLK);
input CLK;
input WRE;
+ specify
+ (AD => DO) = (270, 405);
+ $setup(DI, posedge CLK, 62);
+ $setup(WRE, posedge CLK, 62);
+ $setup(AD, posedge CLK, 62);
+ (posedge CLK => (DO : {WIDTH{1'bx}})) = (474, 565);
+ endspecify
+
reg [15:0] mem0, mem1, mem2, mem3;
initial begin
@@ -516,5 +803,21 @@ input [31:0] DI;
input [2:0] BLKSEL;
output [31:0] DO;
+specify
+ (posedge CLKB => (DO : DI)) = (419, 493);
+ $setup(RESETA, posedge CLKA, 62);
+ $setup(RESETB, posedge CLKB, 62);
+ $setup(OCE, posedge CLKB, 62);
+ $setup(CEA, posedge CLKA, 62);
+ $setup(CEB, posedge CLKB, 62);
+ $setup(OCE, posedge CLKB, 62);
+ $setup(WREA, posedge CLKA, 62);
+ $setup(WREB, posedge CLKB, 62);
+ $setup(DI, posedge CLKA, 62);
+ $setup(ADA, posedge CLKA, 62);
+ $setup(ADB, posedge CLKB, 62);
+ $setup(BLKSEL, posedge CLKA, 62);
+endspecify
+
endmodule
diff --git a/techlibs/gowin/determine_init.cc b/techlibs/gowin/determine_init.cc
deleted file mode 100644
index 15ff115de..000000000
--- a/techlibs/gowin/determine_init.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * yosys -- Yosys Open SYnthesis Suite
- *
- * Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
- *
- * 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
-
-struct DetermineInitPass : public Pass {
- DetermineInitPass() : Pass("determine_init", "Determine the init value of cells") { }
- void help() override
- {
- log("\n");
- log(" determine_init [selection]\n");
- log("\n");
- log("Determine the init value of cells that doesn't allow unknown init value.\n");
- log("\n");
- }
-
- Const determine_init(Const init)
- {
- for (int i = 0; i < GetSize(init); i++) {
- if (init[i] != State::S0 && init[i] != State::S1)
- init[i] = State::S0;
- }
-
- return init;
- }
-
- void execute(std::vector<std::string> args, RTLIL::Design *design) override
- {
- log_header(design, "Executing DETERMINE_INIT pass (determine init value for cells).\n");
-
- extra_args(args, args.size(), design);
-
- int cnt = 0;
- for (auto module : design->selected_modules())
- {
- for (auto cell : module->selected_cells())
- {
- if (cell->type == ID(RAM16S4))
- {
- cell->setParam(ID(INIT_0), determine_init(cell->getParam(ID(INIT_0))));
- cell->setParam(ID(INIT_1), determine_init(cell->getParam(ID(INIT_1))));
- cell->setParam(ID(INIT_2), determine_init(cell->getParam(ID(INIT_2))));
- cell->setParam(ID(INIT_3), determine_init(cell->getParam(ID(INIT_3))));
- cnt++;
- }
- }
- }
- log_header(design, "Updated %d cells with determined init value.\n", cnt);
- }
-} DetermineInitPass;
-
-PRIVATE_NAMESPACE_END
diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc
index 32d9cc0a5..d7b11d431 100644
--- a/techlibs/gowin/synth_gowin.cc
+++ b/techlibs/gowin/synth_gowin.cc
@@ -69,9 +69,9 @@ struct SynthGowinPass : public ScriptPass
log("\n");
log(" -noiopads\n");
log(" do not emit IOB at top level ports\n");
- //log("\n");
- //log(" -abc9\n");
- //log(" use new ABC9 flow (EXPERIMENTAL)\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");
@@ -144,10 +144,10 @@ struct SynthGowinPass : public ScriptPass
nowidelut = true;
continue;
}
- //if (args[argidx] == "-abc9") {
- // abc9 = true;
- // continue;
- //}
+ if (args[argidx] == "-abc9") {
+ abc9 = true;
+ continue;
+ }
if (args[argidx] == "-noiopads") {
noiopads = true;
continue;
@@ -171,7 +171,7 @@ struct SynthGowinPass : public ScriptPass
{
if (check_label("begin"))
{
- run("read_verilog -lib +/gowin/cells_sim.v");
+ run("read_verilog -specify -lib +/gowin/cells_sim.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
@@ -198,7 +198,7 @@ struct SynthGowinPass : public ScriptPass
{
run("memory_bram -rules +/gowin/lutrams.txt");
run("techmap -map +/gowin/lutrams_map.v");
- run("determine_init");
+ run("setundef -params -zero t:RAM16S4");
}
if (check_label("map_ffram"))
@@ -223,6 +223,7 @@ struct SynthGowinPass : public ScriptPass
run("opt_clean");
if (!nodffe)
run("dff2dffe -direct-match $_DFF_* -direct-match $_SDFF_*");
+ run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_SDFF_?P?_ r -cell $_SDFFE_?P?P_ r -cell $_DFF_?P?_ r -cell $_DFFE_?P?P_ r");
run("techmap -map +/gowin/cells_map.v");
run("opt_expr -mux_undef");
run("simplemap");
@@ -230,13 +231,15 @@ struct SynthGowinPass : public ScriptPass
if (check_label("map_luts"))
{
- /*if (nowidelut && abc9) {
- run("abc9 -lut 4");
- } else*/ if (nowidelut && !abc9) {
+ if (nowidelut && abc9) {
+ run("read_verilog -icells -lib -specify +/abc9_model.v");
+ run("abc9 -maxlut 4 -W 500");
+ } else if (nowidelut && !abc9) {
run("abc -lut 4");
- } else /*if (!nowidelut && abc9) {
- run("abc9 -lut 4:8");
- } else*/ if (!nowidelut && !abc9) {
+ } else if (!nowidelut && abc9) {
+ run("read_verilog -icells -lib -specify +/abc9_model.v");
+ run("abc9 -maxlut 8 -W 500");
+ } else if (!nowidelut && !abc9) {
run("abc -lut 4:8");
}
run("clean");
@@ -252,6 +255,7 @@ struct SynthGowinPass : public ScriptPass
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");
+ run("autoname");
}
if (check_label("check"))
diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc
index 1a8caf9a9..4f4faf6d5 100644
--- a/techlibs/ice40/Makefile.inc
+++ b/techlibs/ice40/Makefile.inc
@@ -2,7 +2,6 @@
OBJS += techlibs/ice40/synth_ice40.o
OBJS += techlibs/ice40/ice40_braminit.o
OBJS += techlibs/ice40/ice40_ffssr.o
-OBJS += techlibs/ice40/ice40_ffinit.o
OBJS += techlibs/ice40/ice40_opt.o
GENFILES += techlibs/ice40/brams_init1.vh
diff --git a/techlibs/ice40/ff_map.v b/techlibs/ice40/ff_map.v
index 990cd74f1..8174323a2 100644
--- a/techlibs/ice40/ff_map.v
+++ b/techlibs/ice40/ff_map.v
@@ -1,28 +1,25 @@
-module \$_DFF_N_ (input D, C, output Q); SB_DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); endmodule
-module \$_DFF_P_ (input D, C, output Q); SB_DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); endmodule
+module \$_DFF_N_ (input D, C, output Q); SB_DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_DFF_P_ (input D, C, output Q); SB_DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
-module \$_DFFE_NN_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule
-module \$_DFFE_PN_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule
+module \$_DFFE_NP_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_DFFE_PP_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
-module \$_DFFE_NP_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule
-module \$_DFFE_PP_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule
+module \$_DFF_NP0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_DFF_NP1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_DFF_PP0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_DFF_PP1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
-module \$_DFF_NN0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule
-module \$_DFF_NN1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule
-module \$_DFF_PN0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule
-module \$_DFF_PN1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule
+module \$_DFFE_NP0P_ (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_DFFE_NP1P_ (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_DFFE_PP0P_ (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_DFFE_PP1P_ (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
-module \$_DFF_NP0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule
-module \$_DFF_NP1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule
-module \$_DFF_PP0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule
-module \$_DFF_PP1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule
+module \$_SDFF_NP0_ (input D, C, R, output Q); SB_DFFNSR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_SDFF_NP1_ (input D, C, R, output Q); SB_DFFNSS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_SDFF_PP0_ (input D, C, R, output Q); SB_DFFSR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_SDFF_PP1_ (input D, C, R, output Q); SB_DFFSS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
-module \$_DFFE_NN0P_ (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule
-module \$_DFFE_NN1P_ (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule
-module \$_DFFE_PN0P_ (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule
-module \$_DFFE_PN1P_ (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule
-
-module \$_DFFE_NP0P_ (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule
-module \$_DFFE_NP1P_ (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule
-module \$_DFFE_PP0P_ (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule
-module \$_DFFE_PP1P_ (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule
+module \$_SDFFCE_NP0P_ (input D, C, E, R, output Q); SB_DFFNESR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_SDFFCE_NP1P_ (input D, C, E, R, output Q); SB_DFFNESS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_SDFFCE_PP0P_ (input D, C, E, R, output Q); SB_DFFESR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
+module \$_SDFFCE_PP1P_ (input D, C, E, R, output Q); SB_DFFESS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule
diff --git a/techlibs/ice40/ice40_ffinit.cc b/techlibs/ice40/ice40_ffinit.cc
deleted file mode 100644
index 2eef3fa93..000000000
--- a/techlibs/ice40/ice40_ffinit.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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
-
-struct Ice40FfinitPass : public Pass {
- Ice40FfinitPass() : Pass("ice40_ffinit", "iCE40: handle FF init values") { }
- void help() override
- {
- // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
- log("\n");
- log(" ice40_ffinit [options] [selection]\n");
- log("\n");
- log("Remove zero init values for FF output signals. Add inverters to implement\n");
- log("nonzero init values.\n");
- log("\n");
- }
- void execute(std::vector<std::string> args, RTLIL::Design *design) override
- {
- log_header(design, "Executing ICE40_FFINIT pass (implement FF init values).\n");
-
- size_t argidx;
- for (argidx = 1; argidx < args.size(); argidx++)
- {
- // if (args[argidx] == "-singleton") {
- // singleton_mode = true;
- // continue;
- // }
- break;
- }
- extra_args(args, argidx, design);
-
- for (auto module : design->selected_modules())
- {
- log("Handling FF init values in %s.\n", log_id(module));
-
- SigMap sigmap(module);
- pool<Wire*> init_wires;
- dict<SigBit, State> initbits;
- dict<SigBit, SigBit> initbit_to_wire;
- pool<SigBit> handled_initbits;
-
- for (auto wire : module->selected_wires())
- {
- if (wire->attributes.count(ID::init) == 0)
- continue;
-
- SigSpec wirebits = sigmap(wire);
- Const initval = wire->attributes.at(ID::init);
- init_wires.insert(wire);
-
- for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
- {
- SigBit bit = wirebits[i];
- State val = initval[i];
-
- if (val != State::S0 && val != State::S1)
- continue;
-
- if (initbits.count(bit)) {
- if (initbits.at(bit) != val) {
- log_warning("Conflicting init values for signal %s (%s = %s, %s = %s).\n",
- log_signal(bit), log_signal(SigBit(wire, i)), log_signal(val),
- log_signal(initbit_to_wire[bit]), log_signal(initbits.at(bit)));
- initbits.at(bit) = State::Sx;
- }
- continue;
- }
-
- initbits[bit] = val;
- initbit_to_wire[bit] = SigBit(wire, i);
- }
- }
-
- pool<IdString> sb_dff_types = {
- ID(SB_DFF), ID(SB_DFFE), ID(SB_DFFSR), ID(SB_DFFR), ID(SB_DFFSS), ID(SB_DFFS), ID(SB_DFFESR),
- ID(SB_DFFER), ID(SB_DFFESS), ID(SB_DFFES), ID(SB_DFFN), ID(SB_DFFNE), ID(SB_DFFNSR), ID(SB_DFFNR),
- ID(SB_DFFNSS), ID(SB_DFFNS), ID(SB_DFFNESR), ID(SB_DFFNER), ID(SB_DFFNESS), ID(SB_DFFNES)
- };
-
- for (auto cell : module->selected_cells())
- {
- if (!sb_dff_types.count(cell->type))
- continue;
-
- SigSpec sig_d = cell->getPort(ID::D);
- SigSpec sig_q = cell->getPort(ID::Q);
-
- if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
- continue;
-
- SigBit bit_d = sigmap(sig_d[0]);
- SigBit bit_q = sigmap(sig_q[0]);
-
- if (!initbits.count(bit_q))
- continue;
-
- State val = initbits.at(bit_q);
-
- if (val == State::Sx)
- continue;
-
- handled_initbits.insert(bit_q);
-
- log("FF init value for cell %s (%s): %s = %c\n", log_id(cell), log_id(cell->type),
- log_signal(bit_q), val != State::S0 ? '1' : '0');
-
- if (val == State::S0)
- continue;
-
- string type_str = cell->type.str();
-
- if (type_str.back() == 'S') {
- type_str.back() = 'R';
- cell->type = type_str;
- cell->setPort(ID::R, cell->getPort(ID::S));
- cell->unsetPort(ID::S);
- } else
- if (type_str.back() == 'R') {
- type_str.back() = 'S';
- cell->type = type_str;
- cell->setPort(ID::S, cell->getPort(ID::R));
- cell->unsetPort(ID::R);
- }
-
- Wire *new_bit_d = module->addWire(NEW_ID);
- Wire *new_bit_q = module->addWire(NEW_ID);
-
- module->addNotGate(NEW_ID, bit_d, new_bit_d);
- module->addNotGate(NEW_ID, new_bit_q, bit_q);
-
- cell->setPort(ID::D, new_bit_d);
- cell->setPort(ID::Q, new_bit_q);
- }
-
- for (auto wire : init_wires)
- {
- if (wire->attributes.count(ID::init) == 0)
- continue;
-
- SigSpec wirebits = sigmap(wire);
- Const &initval = wire->attributes.at(ID::init);
- bool remove_attribute = true;
-
- for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) {
- if (handled_initbits.count(wirebits[i]))
- initval[i] = State::Sx;
- else if (initval[i] != State::Sx)
- remove_attribute = false;
- }
-
- if (remove_attribute)
- wire->attributes.erase(ID::init);
- }
- }
- }
-} Ice40FfinitPass;
-
-PRIVATE_NAMESPACE_END
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index 6464368eb..4ddb6ca70 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -358,15 +358,14 @@ struct SynthIce40Pass : public ScriptPass
run("dff2dffe -direct-match $_DFF_*");
if (min_ce_use >= 0) {
run("opt_merge");
- run(stringf("dff2dffe -unmap-mince %d", min_ce_use));
- run("simplemap t:$dff");
}
- if ((abc9 && dff) || help_mode)
- run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff");
+ if (nodffe)
+ run(stringf("dfflegalize -cell $_DFF_?_ 0 -cell $_DFF_?P?_ 0 -cell $_SDFF_?P?_ 0 -cell $_DLATCH_?_ x"));
+ else
+ run(stringf("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_DFF_?P?_ 0 -cell $_DFFE_?P?P_ 0 -cell $_SDFF_?P?_ 0 -cell $_SDFFCE_?P?P_ 0 -cell $_DLATCH_?_ x -mince %d", min_ce_use));
run("techmap -map +/ice40/ff_map.v");
run("opt_expr -mux_undef");
run("simplemap");
- run("ice40_ffinit");
run("ice40_ffssr");
run("ice40_opt -full");
}
diff --git a/techlibs/intel/Makefile.inc b/techlibs/intel/Makefile.inc
index f751e341f..fef6aab77 100644
--- a/techlibs/intel/Makefile.inc
+++ b/techlibs/intel/Makefile.inc
@@ -5,6 +5,7 @@ $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/m9k_bb.v))
$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/altpll_bb.v))
$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_m9k.txt))
$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_map_m9k.v))
+$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/ff_map.v))
# Add the cell models and mappings for the VQM backend
families := max10 arria10gx cyclonev cyclone10lp cycloneiv cycloneive
diff --git a/techlibs/intel/common/ff_map.v b/techlibs/intel/common/ff_map.v
new file mode 100644
index 000000000..e3f92adbb
--- /dev/null
+++ b/techlibs/intel/common/ff_map.v
@@ -0,0 +1,11 @@
+// Async Active Low Reset DFF
+module \$_DFFE_PN0P_ (input D, C, R, E, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) begin
+ dffeas #(.is_wysiwyg("TRUE"), .power_up("high")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(E), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
+ end else begin
+ dffeas #(.is_wysiwyg("TRUE"), .power_up("low")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(E), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
+ end
+ endgenerate
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
diff --git a/techlibs/intel/cyclone10lp/cells_map.v b/techlibs/intel/cyclone10lp/cells_map.v
index 25d73711c..22907b144 100644
--- a/techlibs/intel/cyclone10lp/cells_map.v
+++ b/techlibs/intel/cyclone10lp/cells_map.v
@@ -19,41 +19,6 @@
// > c60k28 (Viacheslav, VT) [at] yandex [dot] com
// > Intel FPGA technology mapping. User must first simulate the generated \
// > netlist before going to test it on board.
-// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed.
-
-// Normal mode DFF negedge clk, negedge reset
-module \$_DFF_N_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Normal mode DFF
-module \$_DFF_P_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-// Async Active Low Reset DFF
-module \$_DFF_PN0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Async Active High Reset DFF
-module \$_DFF_PP0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire R_i = ~ R;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-module \$_DFFE_PP0P_ (input D, C, E, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire E_i = ~ E;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0));
-endmodule
// Input buffer map
module \$__inpad (input I, output O);
diff --git a/techlibs/intel/cycloneiv/cells_map.v b/techlibs/intel/cycloneiv/cells_map.v
index 56d32e586..41afd94be 100644
--- a/techlibs/intel/cycloneiv/cells_map.v
+++ b/techlibs/intel/cycloneiv/cells_map.v
@@ -19,41 +19,6 @@
// > c60k28 (Viacheslav, VT) [at] yandex [dot] com
// > Intel FPGA technology mapping. User must first simulate the generated \
// > netlist before going to test it on board.
-// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed.
-
-// Normal mode DFF negedge clk, negedge reset
-module \$_DFF_N_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Normal mode DFF
-module \$_DFF_P_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-// Async Active Low Reset DFF
-module \$_DFF_PN0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Async Active High Reset DFF
-module \$_DFF_PP0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire R_i = ~ R;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-module \$_DFFE_PP0P_ (input D, C, E, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire E_i = ~ E;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0));
-endmodule
// Input buffer map
module \$__inpad (input I, output O);
diff --git a/techlibs/intel/cycloneive/cells_map.v b/techlibs/intel/cycloneive/cells_map.v
index 43a1183de..6d7f36ec5 100644
--- a/techlibs/intel/cycloneive/cells_map.v
+++ b/techlibs/intel/cycloneive/cells_map.v
@@ -19,41 +19,6 @@
// > c60k28 (Viacheslav, VT) [at] yandex [dot] com
// > Intel FPGA technology mapping. User must first simulate the generated \
// > netlist before going to test it on board.
-// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed.
-
-// Normal mode DFF negedge clk, negedge reset
-module \$_DFF_N_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Normal mode DFF
-module \$_DFF_P_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-// Async Active Low Reset DFF
-module \$_DFF_PN0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Async Active High Reset DFF
-module \$_DFF_PP0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire R_i = ~ R;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-module \$_DFFE_PP0P_ (input D, C, E, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire E_i = ~ E;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0));
-endmodule
// Input buffer map
module \$__inpad (input I, output O);
diff --git a/techlibs/intel/cyclonev/cells_map.v b/techlibs/intel/cyclonev/cells_map.v
index 8223df3c6..0041481ab 100644
--- a/techlibs/intel/cyclonev/cells_map.v
+++ b/techlibs/intel/cyclonev/cells_map.v
@@ -19,43 +19,6 @@
// > c60k28 (Viacheslav, VT) [at] yandex [dot] com
// > Intel FPGA technology mapping. User must first simulate the generated \
// > netlist before going to test it on board.
-// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed.
-// 2) Cyclone V 7-input LUT function was wrong implemented. Removed abc option to map this function \
-// and added the explanation in this file instead. Such function needs to be implemented.
-
-// Normal mode DFF negedge clk, negedge reset
-module \$_DFF_N_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Normal mode DFF
-module \$_DFF_P_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-// Async Active Low Reset DFF
-module \$_DFF_PN0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Async Active High Reset DFF
-module \$_DFF_PP0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire R_i = ~ R;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-module \$_DFFE_PP0P_ (input D, C, E, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire E_i = ~ E;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0));
-endmodule
// Input buffer map
module \$__inpad (input I, output O);
diff --git a/techlibs/intel/max10/cells_map.v b/techlibs/intel/max10/cells_map.v
index 55b393080..8f198daef 100644
--- a/techlibs/intel/max10/cells_map.v
+++ b/techlibs/intel/max10/cells_map.v
@@ -19,41 +19,6 @@
// > c60k28 (Viacheslav, VT) [at] yandex [dot] com
// > Intel FPGA technology mapping. User must first simulate the generated \
// > netlist before going to test it on board.
-// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed.
-
-// Normal mode DFF negedge clk, negedge reset
-module \$_DFF_N_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Normal mode DFF
-module \$_DFF_P_ (input D, C, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-// Async Active Low Reset DFF
-module \$_DFF_PN0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-// Async Active High Reset DFF
-module \$_DFF_PP0_ (input D, C, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire R_i = ~ R;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0));
-endmodule
-
-module \$_DFFE_PP0P_ (input D, C, E, R, output Q);
- parameter WYSIWYG="TRUE";
- parameter power_up=1'bx;
- wire E_i = ~ E;
- dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0));
-endmodule
// Input buffer map
module \$__inpad (input I, output O);
diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc
index f3709498c..1fa98d098 100644
--- a/techlibs/intel/synth_intel.cc
+++ b/techlibs/intel/synth_intel.cc
@@ -212,6 +212,11 @@ struct SynthIntelPass : public ScriptPass {
run("abc -markgroups -dff -D 1", "(only if -retime)");
}
+ if (check_label("map_ffs")) {
+ run("dfflegalize -cell $_DFFE_PN0P_ 01");
+ run("techmap -map +/intel/common/ff_map.v");
+ }
+
if (check_label("map_luts")) {
if (family_opt == "arria10gx" || family_opt == "cyclonev")
run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : ""));
@@ -224,7 +229,6 @@ struct SynthIntelPass : public ScriptPass {
if (iopads || help_mode)
run("iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I", "(if -iopads)");
run(stringf("techmap -map +/intel/%s/cells_map.v", family_opt.c_str()));
- run("dffinit -highlow -ff dffeas q power_up");
run("clean -purge");
}
diff --git a/techlibs/intel_alm/Makefile.inc b/techlibs/intel_alm/Makefile.inc
index 477be6353..552f00c65 100644
--- a/techlibs/intel_alm/Makefile.inc
+++ b/techlibs/intel_alm/Makefile.inc
@@ -10,6 +10,8 @@ $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/al
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/arith_alm_map.v))
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dff_map.v))
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dff_sim.v))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dsp_sim.v))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dsp_map.v))
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/mem_sim.v))
# RAM
diff --git a/techlibs/intel_alm/common/dff_map.v b/techlibs/intel_alm/common/dff_map.v
index 962be670c..1a4b5d65a 100644
--- a/techlibs/intel_alm/common/dff_map.v
+++ b/techlibs/intel_alm/common/dff_map.v
@@ -1,124 +1,13 @@
`default_nettype none
-// D flip-flops
-module \$_DFF_P_ (input D, C, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+// D flip-flop with async reset and enable
+module \$_DFFE_PN0P_ (input D, C, R, E, output Q);
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop that initialises to one");
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(R), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
endmodule
-module \$_DFF_N_ (input D, C, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+// D flip-flop with sync reset and enable (enable has priority)
+module \$_SDFFCE_PP0P_ (input D, C, R, E, output Q);
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop that initialises to one");
-endmodule
-
-// D flip-flops with reset
-module \$_DFF_PP0_ (input D, C, R, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop with reset that initialises to one");
-endmodule
-
-module \$_DFF_PN0_ (input D, C, R, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop with reset that initialises to one");
-endmodule
-
-module \$_DFF_NP0_ (input D, C, R, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop with reset that initialises to one");
-endmodule
-
-module \$_DFF_NN0_ (input D, C, R, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop with reset that initialises to one");
-endmodule
-
-// D flip-flops with set
-module \$_DFF_PP1_ (input D, C, R, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- wire Q_tmp;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
- assign Q = ~Q_tmp;
-end else $error("Cannot implement a flip-flop with set that initialises to zero");
-endmodule
-
-module \$_DFF_PN1_ (input D, C, R, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- wire Q_tmp;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
-end else $error("Cannot implement a flip-flop with set that initialises to zero");
-endmodule
-
-module \$_DFF_NP1_ (input D, C, R, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- wire Q_tmp;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(~C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
- assign Q = ~Q_tmp;
-end else $error("Cannot implement a flip-flop with set that initialises to zero");
-endmodule
-
-module \$_DFF_NN1_ (input D, C, R, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- wire Q_tmp;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(~C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
- assign Q = ~Q_tmp;
-end else $error("Cannot implement a flip-flop with set that initialises to zero");
-endmodule
-
-// D flip-flops with clock enable
-module \$_DFFE_PP_ (input D, C, E, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop with enable that initialises to one");
-endmodule
-
-module \$_DFFE_PN_ (input D, C, E, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(~E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop with enable that initialises to one");
-endmodule
-
-module \$_DFFE_NP_ (input D, C, E, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop with enable that initialises to one");
-endmodule
-
-module \$_DFFE_NN_ (input D, C, E, output Q);
-parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
-if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
- wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
- MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(~E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
-end else $error("Cannot implement a flip-flop with enable that initialises to one");
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(E), .SCLR(R), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
endmodule
diff --git a/techlibs/intel_alm/common/dsp_map.v b/techlibs/intel_alm/common/dsp_map.v
new file mode 100644
index 000000000..d1bc25e65
--- /dev/null
+++ b/techlibs/intel_alm/common/dsp_map.v
@@ -0,0 +1,49 @@
+module __MUL27X27(A, B, Y);
+
+parameter A_SIGNED = 1;
+parameter B_SIGNED = 1;
+parameter A_WIDTH = 27;
+parameter B_WIDTH = 27;
+parameter Y_WIDTH = 54;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+MISTRAL_MUL27X27 _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));
+
+endmodule
+
+
+module __MUL18X18(A, B, Y);
+
+parameter A_SIGNED = 1;
+parameter B_SIGNED = 1;
+parameter A_WIDTH = 18;
+parameter B_WIDTH = 18;
+parameter Y_WIDTH = 36;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+MISTRAL_MUL18X18 _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));
+
+endmodule
+
+
+module __MUL9X9(A, B, Y);
+
+parameter A_SIGNED = 1;
+parameter B_SIGNED = 1;
+parameter A_WIDTH = 9;
+parameter B_WIDTH = 9;
+parameter Y_WIDTH = 18;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+MISTRAL_MUL9X9 _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));
+
+endmodule
diff --git a/techlibs/intel_alm/common/dsp_sim.v b/techlibs/intel_alm/common/dsp_sim.v
new file mode 100644
index 000000000..5dc4c02de
--- /dev/null
+++ b/techlibs/intel_alm/common/dsp_sim.v
@@ -0,0 +1,35 @@
+(* abc9_box *)
+module MISTRAL_MUL27x27(input [26:0] A, input [26:0] B, output [53:0] Y);
+
+specify
+ (A *> Y) = 4057;
+ (B *> Y) = 4057;
+endspecify
+
+assign Y = $signed(A) * $signed(B);
+
+endmodule
+
+(* abc9_box *)
+module MISTRAL_MUL18X18(input [17:0] A, input [17:0] B, output [35:0] Y);
+
+specify
+ (A *> Y) = 4057;
+ (B *> Y) = 4057;
+endspecify
+
+assign Y = $signed(A) * $signed(B);
+
+endmodule
+
+(* abc9_box *)
+module MISTRAL_MUL9X9(input [8:0] A, input [8:0] B, output [17:0] Y);
+
+specify
+ (A *> Y) = 4057;
+ (B *> Y) = 4057;
+endspecify
+
+assign Y = $signed(A) * $signed(B);
+
+endmodule
diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v
index c749fa70b..b5a3d8892 100644
--- a/techlibs/intel_alm/common/megafunction_bb.v
+++ b/techlibs/intel_alm/common/megafunction_bb.v
@@ -129,3 +129,31 @@ output [data_width-1:0] portbdataout;
input ena0, clk0, clk1;
endmodule
+
+(* blackbox *)
+module cyclonev_mac(ax, ay, resulta);
+
+parameter ax_width = 9;
+parameter ay_scan_in_width = 9;
+parameter result_a_width = 18;
+parameter operation_mode = "M9x9";
+
+input [ax_width-1:0] ax;
+input [ay_scan_in_width-1:0] ay;
+output [result_a_width-1:0] resulta;
+
+endmodule
+
+(* blackbox *)
+module cyclone10gx_mac(ax, ay, resulta);
+
+parameter ax_width = 18;
+parameter ay_scan_in_width = 18;
+parameter result_a_width = 36;
+parameter operation_mode = "M18X18_FULL";
+
+input [ax_width-1:0] ax;
+input [ay_scan_in_width-1:0] ay;
+output [result_a_width-1:0] resulta;
+
+endmodule \ No newline at end of file
diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v
index c40a4e02d..46ef2aa0d 100644
--- a/techlibs/intel_alm/common/quartus_rename.v
+++ b/techlibs/intel_alm/common/quartus_rename.v
@@ -1,9 +1,11 @@
`ifdef cyclonev
`define LCELL cyclonev_lcell_comb
+`define MAC cyclonev_mac
`define MLAB cyclonev_mlab_cell
`endif
`ifdef cyclone10gx
`define LCELL cyclone10gx_lcell_comb
+`define MAC cyclone10gx_mac
`define MLAB cyclone10gx_mlab_cell
`endif
@@ -119,3 +121,24 @@ module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1
);
endmodule
+
+
+module MISTRAL_MUL27X27(input [26:0] A, B, output [53:0] Y);
+
+`MAC #(.ax_width(27), .ay_scan_in_width(27), .result_a_width(54), .operation_mode("M27x27")) _TECHMAP_REPLACE_ (.ax(A), .ay(B), .resulta(Y));
+
+endmodule
+
+
+module MISTRAL_MUL18X18(input [17:0] A, B, output [35:0] Y);
+
+`MAC #(.ax_width(18), .ay_scan_in_width(18), .result_a_width(36), .operation_mode("M18x18_FULL")) _TECHMAP_REPLACE_ (.ax(B), .ay(A), .resulta(Y));
+
+endmodule
+
+
+module MISTRAL_MUL9X9(input [8:0] A, B, output [17:0] Y);
+
+`MAC #(.ax_width(9), .ay_scan_in_width(9), .result_a_width(18), .operation_mode("M9x9")) _TECHMAP_REPLACE_ (.ax(A), .ay(B), .resulta(Y));
+
+endmodule
diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc
index 4bc943cb2..b751e8413 100644
--- a/techlibs/intel_alm/synth_intel_alm.cc
+++ b/techlibs/intel_alm/synth_intel_alm.cc
@@ -69,13 +69,16 @@ struct SynthIntelALMPass : public ScriptPass {
log(" -nobram\n");
log(" do not use block RAM cells in output netlist\n");
log("\n");
+ log(" -nodsp\n");
+ log(" do not map multipliers to MISTRAL_MUL cells\n");
+ log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
log("\n");
}
string top_opt, family_opt, bram_type, vout_file;
- bool flatten, quartus, nolutram, nobram, dff;
+ bool flatten, quartus, nolutram, nobram, dff, nodsp;
void clear_flags() override
{
@@ -88,6 +91,7 @@ struct SynthIntelALMPass : public ScriptPass {
nolutram = false;
nobram = false;
dff = false;
+ nodsp = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@@ -130,6 +134,10 @@ struct SynthIntelALMPass : public ScriptPass {
nobram = true;
continue;
}
+ if (args[argidx] == "-nodsp") {
+ nodsp = true;
+ continue;
+ }
if (args[argidx] == "-noflatten") {
flatten = false;
continue;
@@ -169,9 +177,11 @@ struct SynthIntelALMPass : public ScriptPass {
}
if (check_label("begin")) {
- run(stringf("read_verilog -sv -lib +/intel/%s/cells_sim.v", family_opt.c_str()));
+ if (family_opt == "cyclonev")
+ run(stringf("read_verilog -sv -lib +/intel/%s/cells_sim.v", family_opt.c_str()));
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/alm_sim.v", family_opt.c_str()));
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dff_sim.v", family_opt.c_str()));
+ run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dsp_sim.v", family_opt.c_str()));
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/mem_sim.v", family_opt.c_str()));
run(stringf("read_verilog -specify -lib -D %s -icells +/intel_alm/common/abc9_model.v", family_opt.c_str()));
@@ -181,16 +191,46 @@ struct SynthIntelALMPass : public ScriptPass {
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
- if (flatten && check_label("flatten", "(unless -noflatten)")) {
+ if (check_label("coarse")) {
run("proc");
- run("flatten");
+ if (flatten || help_mode)
+ run("flatten", "(skip if -noflatten)");
run("tribuf -logic");
run("deminout");
- }
-
- if (check_label("coarse")) {
- run("synth -run coarse -lut 6");
- run("techmap -map +/intel_alm/common/arith_alm_map.v");
+ run("opt_expr");
+ run("opt_clean");
+ run("check");
+ run("opt");
+ run("wreduce");
+ run("peepopt");
+ run("opt_clean");
+ run("share");
+ run("techmap -map +/cmp2lut.v -D LUT_WIDTH=6");
+ run("opt_expr");
+ run("opt_clean");
+ if (help_mode) {
+ run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)");
+ } else if (!nodsp) {
+ // Cyclone V supports 9x9 multiplication, Cyclone 10 GX does not.
+ run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=19 -D DSP_B_MINWIDTH=19 -D DSP_SIGNEDONLY -D DSP_NAME=__MUL27X27");
+ run("chtype -set $mul t:$__soft_mul");
+ if (family_opt == "cyclonev") {
+ run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=10 -D DSP_SIGNEDONLY -D DSP_NAME=__MUL18X18");
+ run("chtype -set $mul t:$__soft_mul");
+ run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=9 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_SIGNEDONLY -D DSP_NAME=__MUL9X9");
+ run("chtype -set $mul t:$__soft_mul");
+ } else if (family_opt == "cyclone10gx") {
+ run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_SIGNEDONLY -D DSP_NAME=__MUL18X18");
+ run("chtype -set $mul t:$__soft_mul");
+ }
+ }
+ run("alumacc");
+ run("techmap -map +/intel_alm/common/arith_alm_map.v -map +/intel_alm/common/dsp_map.v");
+ run("opt");
+ run("fsm");
+ run("opt -fast");
+ run("memory -nomap");
+ run("opt_clean");
}
if (!nobram && check_label("map_bram", "(skip if -nobram)")) {
@@ -208,11 +248,10 @@ struct SynthIntelALMPass : public ScriptPass {
}
if (check_label("map_ffs")) {
+ run("techmap");
run("dff2dffe");
- // As mentioned in common/dff_sim.v, Intel flops power up to zero,
- // so use `zinit` to add inverters where needed.
- run("zinit");
- run("techmap -map +/techmap.v -map +/intel_alm/common/dff_map.v");
+ run("dfflegalize -cell $_DFFE_PN0P_ 0 -cell $_SDFFCE_PP0P_ 0");
+ run("techmap -map +/intel_alm/common/dff_map.v");
run("opt -full -undriven -mux_undef");
run("clean -purge");
}
diff --git a/techlibs/sf2/cells_map.v b/techlibs/sf2/cells_map.v
index 70f3b3b16..88782995e 100644
--- a/techlibs/sf2/cells_map.v
+++ b/techlibs/sf2/cells_map.v
@@ -1,59 +1,27 @@
-module \$_DFF_N_ (input D, C, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(1'b1), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+module \$_DFFE_PN0P_ (input D, C, R, E, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
endmodule
-module \$_DFF_P_ (input D, C, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(1'b1), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+module \$_DFFE_PN1P_ (input D, C, R, E, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
endmodule
-module \$_DFF_NN0_ (input D, C, R, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+module \$_SDFFCE_PN0P_ (input D, C, R, E, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(1'b1), .ADn(1'b0), .SLn(R), .SD(1'b0), .LAT(1'b0), .Q(Q));
endmodule
-module \$_DFF_NN1_ (input D, C, R, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+module \$_SDFFCE_PN1P_ (input D, C, R, E, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(1'b1), .ADn(1'b0), .SLn(R), .SD(1'b1), .LAT(1'b0), .Q(Q));
endmodule
-module \$_DFF_NP0_ (input D, C, R, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(!R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+module \$_DLATCH_PN0_ (input D, R, E, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(E), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b1), .Q(Q));
endmodule
-module \$_DFF_NP1_ (input D, C, R, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(!R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+module \$_DLATCH_PN1_ (input D, R, E, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(E), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b1), .Q(Q));
endmodule
-module \$_DFF_PN0_ (input D, C, R, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
-endmodule
-
-module \$_DFF_PN1_ (input D, C, R, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
-endmodule
-
-module \$_DFF_PP0_ (input D, C, R, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(!R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
-endmodule
-
-module \$_DFF_PP1_ (input D, C, R, output Q);
- SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(!R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
-endmodule
-
-// module \$_DFFE_NN_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule
-// module \$_DFFE_PN_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule
-//
-// module \$_DFFE_NP_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule
-// module \$_DFFE_PP_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule
-//
-// module \$_DFFE_NN0P_ (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule
-// module \$_DFFE_NN1P_ (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule
-// module \$_DFFE_PN0P_ (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule
-// module \$_DFFE_PN1P_ (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule
-//
-// module \$_DFFE_NP0P_ (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule
-// module \$_DFFE_NP1P_ (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule
-// module \$_DFFE_PP0P_ (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule
-// module \$_DFFE_PP1P_ (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule
-
`ifndef NO_LUT
module \$lut (A, Y);
parameter WIDTH = 0;
diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc
index 6b2a3f9b8..e0c2a64fe 100644
--- a/techlibs/sf2/synth_sf2.cc
+++ b/techlibs/sf2/synth_sf2.cc
@@ -187,6 +187,7 @@ struct SynthSf2Pass : public ScriptPass
if (check_label("map_ffs"))
{
+ run("dfflegalize -cell $_DFFE_PN?P_ x -cell $_SDFFCE_PN?P_ x -cell $_DLATCH_PN?_ x");
run("techmap -D NO_LUT -map +/sf2/cells_map.v");
run("opt_expr -mux_undef");
run("simplemap");
diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc
index d4d863831..ba87278de 100644
--- a/techlibs/xilinx/Makefile.inc
+++ b/techlibs/xilinx/Makefile.inc
@@ -42,8 +42,7 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut4_lutrams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut6_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))
-$(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/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/xc3s_mult_map.v))
diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v
index 97f050f76..ec4635ac6 100644
--- a/techlibs/xilinx/cells_map.v
+++ b/techlibs/xilinx/cells_map.v
@@ -18,43 +18,6 @@
*
*/
-// Convert negative-polarity reset to positive-polarity
-(* techmap_celltype = "$_DFF_NN0_" *)
-module _90_dff_nn0_to_np0 (input D, C, R, output Q); \$_DFF_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
-(* techmap_celltype = "$_DFF_PN0_" *)
-module _90_dff_pn0_to_pp0 (input D, C, R, output Q); \$_DFF_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
-(* techmap_celltype = "$_DFF_NN1_" *)
-module _90_dff_nn1_to_np1 (input D, C, R, output Q); \$_DFF_NP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
-(* 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
-
-(* techmap_celltype = "$_DFFE_NN0P_" *)
-module _90_dffe_nn0_to_np0 (input D, C, R, E, output Q); \$_DFFE_NP0P_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
-(* techmap_celltype = "$_DFFE_PN0P_" *)
-module _90_dffe_pn0_to_pp0 (input D, C, R, E, output Q); \$_DFFE_PP0P_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
-(* techmap_celltype = "$_DFFE_NN1P_" *)
-module _90_dffe_nn1_to_np1 (input D, C, R, E, output Q); \$_DFFE_NP1P_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
-(* techmap_celltype = "$_DFFE_PN1P_" *)
-module _90_dffe_pn1_to_pp1 (input D, C, R, E, output Q); \$_DFFE_PP1P_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
-
-(* techmap_celltype = "$_SDFF_NN0_" *)
-module _90_dffs_nn0_to_np0 (input D, C, R, output Q); \$_SDFF_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
-(* techmap_celltype = "$_SDFF_PN0_" *)
-module _90_dffs_pn0_to_pp0 (input D, C, R, output Q); \$_SDFF_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
-(* techmap_celltype = "$_SDFF_NN1_" *)
-module _90_dffs_nn1_to_np1 (input D, C, R, output Q); \$_SDFF_NP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
-(* techmap_celltype = "$_SDFF_PN1_" *)
-module _90_dffs_pn1_to_pp1 (input D, C, R, output Q); \$_SDFF_PP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
-
-(* techmap_celltype = "$_SDFFE_NN0P_" *)
-module _90_dffse_nn0_to_np0 (input D, C, R, E, output Q); \$_SDFFE_NP0P_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
-(* techmap_celltype = "$_SDFFE_PN0P_" *)
-module _90_dffse_pn0_to_pp0 (input D, C, R, E, output Q); \$_SDFFE_PP0P_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
-(* techmap_celltype = "$_SDFFE_NN1P_" *)
-module _90_dffse_nn1_to_np1 (input D, C, R, E, output Q); \$_SDFFE_NP1P_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
-(* techmap_celltype = "$_SDFFE_PN1P_" *)
-module _90_dffse_pn1_to_pp1 (input D, C, R, E, output Q); \$_SDFFE_PP1P_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
-
module \$__SHREG_ (input C, input D, input E, output Q);
parameter DEPTH = 0;
parameter [DEPTH-1:0] INIT = 0;
diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v
new file mode 100644
index 000000000..45d202294
--- /dev/null
+++ b/techlibs/xilinx/ff_map.v
@@ -0,0 +1,120 @@
+/*
+ * 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 _NO_FFS
+
+// Async reset, enable.
+
+module \$_DFFE_NP0P_ (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_PP0P_ (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_NP1P_ (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_PP1P_ (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
+
+// Async set and reset, enable.
+
+module \$_DFFSRE_NPPP_ (input D, C, E, S, R, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ FDCPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R), .PRE(S));
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module \$_DFFSRE_PPPP_ (input D, C, E, S, R, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ FDCPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R), .PRE(S));
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+// Sync reset, enable.
+
+module \$_SDFFE_NP0P_ (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 \$_SDFFE_PP0P_ (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 \$_SDFFE_NP1P_ (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 \$_SDFFE_PP1P_ (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 with reset.
+
+module \$_DLATCH_NP0_ (input E, R, D, output Q);
+ 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(R));
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module \$_DLATCH_PP0_ (input E, R, D, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R));
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module \$_DLATCH_NP1_ (input E, R, D, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ LDPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(R));
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module \$_DLATCH_PP1_ (input E, R, D, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ LDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(R));
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+// Latches with set and reset.
+
+module \$_DLATCH_NPP_ (input E, S, R, D, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ LDCPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R), .PRE(S));
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module \$_DLATCH_PPP_ (input E, S, R, D, output Q);
+ parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+ LDCPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R), .PRE(S));
+ wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+`endif
+
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index b66dc850d..421602e62 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -342,13 +342,6 @@ struct SynthXilinxPass : public ScriptPass
std::string lut_size_s = std::to_string(lut_size);
if (help_mode)
lut_size_s = "[46]";
- std::string ff_map_file;
- if (help_mode)
- ff_map_file = "+/xilinx/{family}_ff_map.v";
- else if (family == "xc6s")
- ff_map_file = "+/xilinx/xc6s_ff_map.v";
- else
- ff_map_file = "+/xilinx/xc7_ff_map.v";
if (check_label("begin")) {
std::string read_args;
@@ -595,11 +588,17 @@ struct SynthXilinxPass : public ScriptPass
run("clean");
}
- if (check_label("map_ffs", "('-abc9' only)")) {
+ if (check_label("map_ffs")) {
+ if (family == "xc6s")
+ run("dfflegalize -cell $_DFFE_?P?P_ r -cell $_SDFFE_?P?P_ r -cell $_DLATCH_?P?_ r", "(for xc6s)");
+ else if (family == "xc6v" || family == "xc7" || family == "xcu" || family == "xcup")
+ run("dfflegalize -cell $_DFFE_?P?P_ 01 -cell $_SDFFE_?P?P_ 01 -cell $_DLATCH_?P?_ 01", "(for xc6v, xc7, xcu, xcup)");
+ else
+ run("dfflegalize -cell $_DFFE_?P?P_ 01 -cell $_DFFSRE_?PPP_ 01 -cell $_SDFFE_?P?P_ 01 -cell $_DLATCH_?P?_ 01 -cell $_DLATCHSR_?PP_ 01", "(for xc5v and older)");
if (abc9 || help_mode) {
if (dff || help_mode)
- run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "('-dff' only)");
- run("techmap -map " + ff_map_file);
+ run("zinit -all w:* t:$_SDFFE_*", "('-dff' only)");
+ run("techmap -map +/xilinx/ff_map.v", "('-abc9' only)");
}
}
@@ -653,13 +652,13 @@ struct SynthXilinxPass : public ScriptPass
}
run("clean");
+ if (help_mode || !abc9)
+ run("techmap -map +/xilinx/ff_map.v", "(only if not '-abc9')");
// This shregmap call infers fixed length shift registers after abc
// has performed any necessary retiming
if (!nosrl || help_mode)
run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')");
std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v";
- if (help_mode || !abc9)
- techmap_args += stringf(" -map %s", ff_map_file.c_str());
techmap_args += " -D LUT_WIDTH=" + lut_size_s;
run("techmap " + techmap_args);
if (help_mode)
diff --git a/techlibs/xilinx/xc6s_ff_map.v b/techlibs/xilinx/xc6s_ff_map.v
deleted file mode 100644
index a1e4218b9..000000000
--- a/techlibs/xilinx/xc6s_ff_map.v
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * 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.
- *
- */
-
-// ============================================================================
-// FF mapping for Spartan 6. The primitives used are the same as Series 7,
-// but with one major difference: the initial value is implied by the
-// primitive type used (FFs with reset pin must have INIT set to 0 or x, FFs
-// with set pin must have INIT set to 1 or x). For Yosys primitives without
-// set/reset, this means we have to pick the primitive type based on the INIT
-// value.
-
-`ifndef _NO_FFS
-
-// No reset.
-
-module \$_DFF_N_ (input D, C, output Q);
- parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
- generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S(1'b0));
- else
- FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
- endgenerate
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-module \$_DFF_P_ (input D, C, output Q);
- parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
- generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S(1'b0));
- else
- FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
- endgenerate
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-
-// No reset, enable.
-
-module \$_DFFE_NP_ (input D, C, E, output Q);
- parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
- generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(1'b0));
- else
- FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
- endgenerate
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-module \$_DFFE_PP_ (input D, C, E, output Q);
- parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
- generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(1'b0));
- else
- FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
- endgenerate
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-
-// Async reset.
-
-module \$_DFF_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 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_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 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_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 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_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 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
-
-// Async reset, enable.
-
-module \$_DFFE_NP0P_ (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_PP0P_ (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_NP1P_ (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_PP1P_ (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 \$_SDFF_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 \$_SDFF_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 \$_SDFF_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 \$_SDFF_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 \$_SDFFE_NP0P_ (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 \$_SDFFE_PP0P_ (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 \$_SDFFE_NP1P_ (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 \$_SDFFE_PP1P_ (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);
- parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
- generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- LDPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(1'b0));
- else
- LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
- endgenerate
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-module \$_DLATCH_P_ (input E, D, output Q);
- parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
- generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
- LDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(1'b0));
- else
- LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
- endgenerate
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-
-// Latches with reset (TODO).
-
-`endif
-
diff --git a/techlibs/xilinx/xc7_ff_map.v b/techlibs/xilinx/xc7_ff_map.v
deleted file mode 100644
index 750e8f8eb..000000000
--- a/techlibs/xilinx/xc7_ff_map.v
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.
- *
- */
-
-// ============================================================================
-// FF mapping for Virtex 6, Series 7 and Ultrascale. These families support
-// the following features:
-//
-// - a CLB flip-flop can be used as a latch or as a flip-flop
-// - a CLB flip-flop has the following pins:
-//
-// - data input
-// - clock (or gate for latches) (with optional inversion)
-// - clock enable (or gate enable, which is just ANDed with gate — unused by
-// synthesis)
-// - either a set or a reset input, which (for FFs) can be either
-// synchronous or asynchronous (with optional inversion)
-// - data output
-//
-// - a flip-flop also has an initial value, which is set at device
-// initialization (or whenever GSR is asserted)
-
-`ifndef _NO_FFS
-
-// No reset.
-
-module \$_DFF_N_ (input D, C, 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(1'b0));
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-module \$_DFF_P_ (input D, C, 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(1'b0));
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-
-// No reset, enable.
-
-module \$_DFFE_NP_ (input D, C, E, 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(1'b0));
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-module \$_DFFE_PP_ (input D, C, E, output Q);
- parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
- FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-
-// Async reset.
-
-module \$_DFF_NP0_ (input D, C, R, output Q);
- 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_PP0_ (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_NP1_ (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_PP1_ (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
-
-// Async reset, enable.
-
-module \$_DFFE_NP0P_ (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_PP0P_ (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_NP1P_ (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_PP1P_ (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 \$_SDFF_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 \$_SDFF_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 \$_SDFF_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 \$_SDFF_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 \$_SDFFE_NP0P_ (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 \$_SDFFE_PP0P_ (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 \$_SDFFE_NP1P_ (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 \$_SDFFE_PP1P_ (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);
- 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));
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-module \$_DLATCH_P_ (input E, D, output Q);
- parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
- LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
- wire _TECHMAP_REMOVEINIT_Q_ = 1;
-endmodule
-
-// Latches with reset (TODO).
-
-`endif
-
diff --git a/tests/arch/gowin/init-error.ys b/tests/arch/gowin/init-error.ys
new file mode 100644
index 000000000..de3813d6f
--- /dev/null
+++ b/tests/arch/gowin/init-error.ys
@@ -0,0 +1,5 @@
+read_verilog init.v
+chparam -set INIT 0 myDFF*P*
+hierarchy -top myDFFP
+logger -expect error "unsupported initial value and async reset value combination" 1
+synth_gowin
diff --git a/tests/arch/gowin/init.ys b/tests/arch/gowin/init.ys
index ddc0e4757..88e88c15a 100644
--- a/tests/arch/gowin/init.ys
+++ b/tests/arch/gowin/init.ys
@@ -30,16 +30,15 @@ select -assert-count 1 t:DFFRE
select -assert-count 1 t:DFFS
select -assert-count 1 t:DFFSE
-delete
design -load read
# these should synth to a flop with reset
chparam -set INIT 1 myDFF myDFFN myDFFE myDFFNE
-# async should give a warning
+# async would give an error
# sync should synth to a mux
-chparam -set INIT 0 myDFF*S* myDFF*P*
-chparam -set INIT 1 myDFF*R* myDFF*C*
+chparam -set INIT 0 myDFF*S*
+chparam -set INIT 1 myDFF*R*
proc
flatten
@@ -67,8 +66,3 @@ select -assert-count 0 t:DFFRE
select -assert-count 2 t:DFFS
select -assert-count 2 t:DFFSE
select -assert-count 12 t:LUT2
-
-# check the expected leftover init values
-# this would happen if your reset value is not the initial value
-# which would be weird
-select -assert-count 8 a:init
diff --git a/tests/arch/intel_alm/add_sub.ys b/tests/arch/intel_alm/add_sub.ys
index 4cb2c2e0d..0f552a27c 100644
--- a/tests/arch/intel_alm/add_sub.ys
+++ b/tests/arch/intel_alm/add_sub.ys
@@ -6,3 +6,13 @@ cd top # Constrain all select calls below inside the top module
stat
select -assert-count 8 t:MISTRAL_ALUT_ARITH
select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D
+
+design -reset
+read_verilog ../common/add_sub.v
+hierarchy -top top
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # 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
+stat
+select -assert-count 8 t:MISTRAL_ALUT_ARITH
+select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D
diff --git a/tests/arch/intel_alm/adffs.ys b/tests/arch/intel_alm/adffs.ys
index 5d8d3a220..04fa2ad24 100644
--- a/tests/arch/intel_alm/adffs.ys
+++ b/tests/arch/intel_alm/adffs.ys
@@ -13,6 +13,18 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D
design -load read
+hierarchy -top adff
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd adff # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_FF
+select -assert-count 1 t:MISTRAL_NOT
+
+select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D
+
+
+design -load read
hierarchy -top adffn
proc
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
@@ -24,6 +36,17 @@ select -assert-none t:MISTRAL_FF %% t:* %D
design -load read
+hierarchy -top adffn
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd adffn # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_FF
+
+select -assert-none t:MISTRAL_FF %% t:* %D
+
+
+design -load read
hierarchy -top dffs
proc
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
@@ -36,6 +59,18 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D
design -load read
+hierarchy -top dffs
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check
+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
+select -assert-count 1 t:MISTRAL_FF
+select -assert-count 1 t:MISTRAL_ALUT2
+
+select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D
+
+
+design -load read
hierarchy -top ndffnr
proc
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
@@ -46,3 +81,16 @@ select -assert-count 1 t:MISTRAL_NOT
select -assert-count 1 t:MISTRAL_ALUT2
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT t:MISTRAL_ALUT2 %% t:* %D
+
+
+design -load read
+hierarchy -top ndffnr
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd ndffnr # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_FF
+select -assert-count 1 t:MISTRAL_NOT
+select -assert-count 1 t:MISTRAL_ALUT2
+
+select -assert-none t:MISTRAL_FF t:MISTRAL_NOT t:MISTRAL_ALUT2 %% t:* %D
diff --git a/tests/arch/intel_alm/counter.ys b/tests/arch/intel_alm/counter.ys
index 945c318d8..50103fefc 100644
--- a/tests/arch/intel_alm/counter.ys
+++ b/tests/arch/intel_alm/counter.ys
@@ -9,5 +9,19 @@ cd top # Constrain all select calls below inside the top module
select -assert-count 2 t:MISTRAL_NOT
select -assert-count 8 t:MISTRAL_ALUT_ARITH
select -assert-count 8 t:MISTRAL_FF
+select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D
+
+
+design -reset
+read_verilog ../common/counter.v
+hierarchy -top top
+proc
+flatten
+equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # 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 2 t:MISTRAL_NOT
+select -assert-count 8 t:MISTRAL_ALUT_ARITH
+select -assert-count 8 t:MISTRAL_FF
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D
diff --git a/tests/arch/intel_alm/dffs.ys b/tests/arch/intel_alm/dffs.ys
index 149b3121a..9ae6c637a 100644
--- a/tests/arch/intel_alm/dffs.ys
+++ b/tests/arch/intel_alm/dffs.ys
@@ -11,6 +11,17 @@ select -assert-count 1 t:MISTRAL_FF
select -assert-none t:MISTRAL_FF %% t:* %D
design -load read
+hierarchy -top dff
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # 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:MISTRAL_FF
+
+select -assert-none t:MISTRAL_FF %% t:* %D
+
+
+design -load read
hierarchy -top dffe
proc
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
@@ -19,3 +30,14 @@ cd dffe # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_FF
select -assert-none t:MISTRAL_FF %% t:* %D
+
+
+design -load read
+hierarchy -top dffe
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # 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:MISTRAL_FF
+
+select -assert-none t:MISTRAL_FF %% t:* %D
diff --git a/tests/arch/intel_alm/fsm.ys b/tests/arch/intel_alm/fsm.ys
index 02e4a9789..6491b2e08 100644
--- a/tests/arch/intel_alm/fsm.ys
+++ b/tests/arch/intel_alm/fsm.ys
@@ -15,6 +15,28 @@ select -assert-count 6 t:MISTRAL_FF
select -assert-max 2 t:MISTRAL_ALUT2 # Clang returns 2, GCC returns 1
select -assert-count 1 t:MISTRAL_ALUT3
select -assert-max 1 t:MISTRAL_ALUT4 # Clang returns 0, GCC returns 1
-select -assert-max 5 t:MISTRAL_ALUT5 # Clang returns 5, GCC returns 4
+select -assert-max 6 t:MISTRAL_ALUT5 # Clang returns 5, GCC returns 4
+select -assert-max 2 t:MISTRAL_ALUT6 # Clang returns 1, GCC returns 2
+select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_ALUT4 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
+
+design -reset
+read_verilog ../common/fsm.v
+hierarchy -top fsm
+proc
+flatten
+
+equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx
+async2sync
+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 6 t:MISTRAL_FF
+select -assert-max 2 t:MISTRAL_ALUT2 # Clang returns 2, GCC returns 1
+select -assert-max 2 t:MISTRAL_ALUT3 # Clang returns 2, GCC returns 1
+select -assert-max 1 t:MISTRAL_ALUT4 # Clang returns 0, GCC returns 1
+select -assert-max 6 t:MISTRAL_ALUT5 # Clang returns 5, GCC returns 4
select -assert-max 2 t:MISTRAL_ALUT6 # Clang returns 1, GCC returns 2
select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_ALUT4 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
diff --git a/tests/arch/intel_alm/logic.ys b/tests/arch/intel_alm/logic.ys
index fad45db74..e8b26a524 100644
--- a/tests/arch/intel_alm/logic.ys
+++ b/tests/arch/intel_alm/logic.ys
@@ -9,3 +9,17 @@ select -assert-count 1 t:MISTRAL_NOT
select -assert-count 6 t:MISTRAL_ALUT2
select -assert-count 2 t:MISTRAL_ALUT4
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D
+
+
+design -reset
+read_verilog ../common/logic.v
+hierarchy -top top
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # 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:MISTRAL_NOT
+select -assert-count 6 t:MISTRAL_ALUT2
+select -assert-count 2 t:MISTRAL_ALUT4
+select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D \ No newline at end of file
diff --git a/tests/arch/intel_alm/lutram.ys b/tests/arch/intel_alm/lutram.ys
index 6f997b67b..66f8a1536 100644
--- a/tests/arch/intel_alm/lutram.ys
+++ b/tests/arch/intel_alm/lutram.ys
@@ -7,7 +7,7 @@ memory
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
+sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
design -load postopt
cd lutram_1w1r
@@ -18,3 +18,24 @@ select -assert-count 8 t:MISTRAL_ALUT3
select -assert-count 17 t:MISTRAL_FF
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_FF t:MISTRAL_MLAB %% t:* %D
+
+design -reset
+read_verilog ../common/lutram.v
+hierarchy -top lutram_1w1r
+proc
+memory -nomap
+equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram
+memory
+opt -full
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
+
+design -load postopt
+cd lutram_1w1r
+select -assert-count 16 t:MISTRAL_MLAB
+select -assert-count 1 t:MISTRAL_NOT
+select -assert-count 2 t:MISTRAL_ALUT2
+select -assert-count 8 t:MISTRAL_ALUT3
+select -assert-count 17 t:MISTRAL_FF
+select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_FF t:MISTRAL_MLAB %% t:* %D
diff --git a/tests/arch/intel_alm/mul.ys b/tests/arch/intel_alm/mul.ys
new file mode 100644
index 000000000..92f00156a
--- /dev/null
+++ b/tests/arch/intel_alm/mul.ys
@@ -0,0 +1,23 @@
+read_verilog ../common/mul.v
+hierarchy -top top
+proc
+equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # 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
+
+stat
+
+select -assert-count 1 t:MISTRAL_MUL9X9
+select -assert-none t:MISTRAL_MUL9X9 %% t:* %D
+
+design -reset
+read_verilog ../common/mul.v
+hierarchy -top top
+proc
+equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx # 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
+
+# Cyclone 10 GX does not have 9x9 multipliers, so we use 18x18.
+select -assert-count 1 t:MISTRAL_MUL18X18
+select -assert-none t:MISTRAL_MUL18X18 %% t:* %D
diff --git a/tests/arch/intel_alm/mux.ys b/tests/arch/intel_alm/mux.ys
index 308e45268..d109257bd 100644
--- a/tests/arch/intel_alm/mux.ys
+++ b/tests/arch/intel_alm/mux.ys
@@ -1,15 +1,26 @@
read_verilog ../common/mux.v
design -save read
+
hierarchy -top mux2
proc
equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # 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:MISTRAL_ALUT3
+select -assert-none t:MISTRAL_ALUT3 %% t:* %D
+
+design -load read
+hierarchy -top mux2
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # 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:MISTRAL_ALUT3
select -assert-none t:MISTRAL_ALUT3 %% t:* %D
+
design -load read
hierarchy -top mux4
proc
@@ -17,9 +28,19 @@ equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cycl
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:MISTRAL_ALUT6
+select -assert-none t:MISTRAL_ALUT6 %% t:* %D
+
+design -load read
+hierarchy -top mux4
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # 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:MISTRAL_ALUT6
select -assert-none t:MISTRAL_ALUT6 %% t:* %D
+
design -load read
hierarchy -top mux8
proc
@@ -29,9 +50,20 @@ cd mux8 # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_ALUT3
select -assert-count 1 t:MISTRAL_ALUT5
select -assert-count 2 t:MISTRAL_ALUT6
-
select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
+
+design -load read
+hierarchy -top mux8
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # 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 1 t:MISTRAL_ALUT3
+select -assert-count 2 t:MISTRAL_ALUT6
+select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT6 %% t:* %D
+
+
design -load read
hierarchy -top mux16
proc
@@ -41,5 +73,17 @@ cd mux16 # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_ALUT3
select -assert-count 2 t:MISTRAL_ALUT5
select -assert-count 4 t:MISTRAL_ALUT6
+select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
+
+
+design -load read
+hierarchy -top mux16
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # 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 1 t:MISTRAL_ALUT3
+select -assert-count 2 t:MISTRAL_ALUT5
+select -assert-count 4 t:MISTRAL_ALUT6
select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
diff --git a/tests/arch/intel_alm/quartus_ice.ys b/tests/arch/intel_alm/quartus_ice.ys
index 4b9b54d10..a88226e13 100644
--- a/tests/arch/intel_alm/quartus_ice.ys
+++ b/tests/arch/intel_alm/quartus_ice.ys
@@ -10,3 +10,17 @@ EOT
synth_intel_alm -family cyclonev -quartus
select -assert-none w:*[* w:*]*
+
+design -reset
+read_verilog <<EOT
+// Verilog has syntax for raw identifiers, where you start it with \ and end it with a space.
+// This test crashes Quartus due to it parsing \a[10] as a wire slice and not a raw identifier.
+module top();
+ (* keep *) wire [31:0] \a[10] ;
+ (* keep *) wire b;
+ assign b = \a[10] [31];
+endmodule
+EOT
+
+synth_intel_alm -family cyclone10gx -quartus
+select -assert-none w:*[* w:*]*
diff --git a/tests/arch/intel_alm/shifter.ys b/tests/arch/intel_alm/shifter.ys
index 014dbd1a8..e307b5486 100644
--- a/tests/arch/intel_alm/shifter.ys
+++ b/tests/arch/intel_alm/shifter.ys
@@ -6,5 +6,16 @@ equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm
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:MISTRAL_FF
+select -assert-none t:MISTRAL_FF %% t:* %D
+
+design -reset
+read_verilog ../common/shifter.v
+hierarchy -top top
+proc
+flatten
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # 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:MISTRAL_FF
select -assert-none t:MISTRAL_FF %% t:* %D
diff --git a/tests/arch/intel_alm/tribuf.ys b/tests/arch/intel_alm/tribuf.ys
index 71b05a747..7f3b38493 100644
--- a/tests/arch/intel_alm/tribuf.ys
+++ b/tests/arch/intel_alm/tribuf.ys
@@ -9,5 +9,19 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p
cd tristate # Constrain all select calls below inside the top module
#Internal cell type used. Need support it.
select -assert-count 1 t:$_TBUF_
+select -assert-none t:$_TBUF_ %% t:* %D
+
+design -reset
+read_verilog ../common/tribuf.v
+hierarchy -top tristate
+proc
+tribuf
+flatten
+synth
+equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclone10gx # 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
+#Internal cell type used. Need support it.
+select -assert-count 1 t:$_TBUF_
select -assert-none t:$_TBUF_ %% t:* %D
diff --git a/tests/arch/xilinx/nosrl.ys b/tests/arch/xilinx/nosrl.ys
new file mode 100644
index 000000000..31bd5d377
--- /dev/null
+++ b/tests/arch/xilinx/nosrl.ys
@@ -0,0 +1,41 @@
+read_verilog <<EOT
+
+module xilinx_srl_static_test(input i, clk, output [1:0] q);
+reg head = 1'b0;
+reg [3:0] shift1 = 4'b0000;
+reg [3:0] shift2 = 4'b0000;
+
+always @(posedge clk) begin
+ head <= i;
+ shift1 <= {shift1[2:0], head};
+ shift2 <= {shift2[2:0], head};
+end
+
+assign q = {shift2[3], shift1[3]};
+endmodule
+
+EOT
+
+design -save read
+
+hierarchy -top xilinx_srl_static_test
+proc
+#equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
+equiv_opt -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd xilinx_srl_static_test # Constrain all select calls below inside the top module
+stat
+select -assert-count 1 t:BUFG
+select -assert-count 1 t:SRL16E
+select -assert-none t:BUFG t:SRL16E %% t:* %D
+
+design -load read
+hierarchy -top xilinx_srl_static_test
+proc
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -nosrl -noiopad # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd xilinx_srl_static_test # Constrain all select calls below inside the top module
+stat
+select -assert-count 1 t:BUFG
+select -assert-count 5 t:FDRE
+select -assert-none t:BUFG t:FDRE %% t:* %D
diff --git a/tests/liberty/run-test.sh b/tests/liberty/run-test.sh
index 7e2ed2370..61f19b09b 100755
--- a/tests/liberty/run-test.sh
+++ b/tests/liberty/run-test.sh
@@ -5,6 +5,6 @@ for x in *.lib; do
echo "Running $x.."
echo "read_verilog small.v" > test.ys
echo "synth -top small" >> test.ys
- echo "dfflibmap -liberty ${x}" >> test.ys
+ echo "dfflibmap -info -liberty ${x}" >> test.ys
../../yosys -ql ${x%.lib}.log -s test.ys
done
diff --git a/tests/opt/bug2221.ys b/tests/opt/bug2221.ys
new file mode 100644
index 000000000..8ac380243
--- /dev/null
+++ b/tests/opt/bug2221.ys
@@ -0,0 +1,16 @@
+read_verilog <<EOT
+module test (
+ input [1:0] a,
+ input [1:0] b,
+ output [5:0] y
+);
+
+wire [5:0] aa = {a, 4'h0};
+wire [5:0] bb = {b, 4'h0};
+
+assign y = aa * bb;
+
+endmodule
+EOT
+
+equiv_opt -assert opt_expr
diff --git a/tests/techmap/clkbufmap.ys b/tests/techmap/clkbufmap.ys
index b81a35e74..abe830109 100644
--- a/tests/techmap/clkbufmap.ys
+++ b/tests/techmap/clkbufmap.ys
@@ -1,5 +1,7 @@
read_verilog <<EOT
module clkbuf (input i, (* clkbuf_driver *) output o); endmodule
+module inbuf (input i, output o); endmodule
+module clkinbuf (input i, (* clkbuf_driver *) output o); endmodule
module dff ((* clkbuf_sink *) input clk, input d, output q); endmodule
module dffe ((* clkbuf_sink *) input c, input d, e, output q); endmodule
module latch (input e, d, output q); endmodule
@@ -105,3 +107,80 @@ select -assert-count 0 w:clk1 %a %co t:clkbuf %i
select -assert-count 0 w:clk2 %a %co t:clkbuf %i
select -assert-count 0 top/t:clkbuf
select -assert-count 2 sub/t:clkbuf
+
+# ----------------------
+
+design -load ref
+clkbufmap -buf clkbuf o:i -inpad inbuf o:i
+select -assert-count 3 top/t:clkbuf
+select -assert-count 3 sub/t:clkbuf
+select -assert-count 2 top/t:inbuf
+select -assert-count 0 sub/t:inbuf
+select -set clk1 w:clk1 %a %co t:inbuf %i
+select -assert-count 1 @clk1
+select -assert-count 1 @clk1 %x:+[o] %co t:clkbuf %i
+select -set clk1b @clk1 %x:+[o] %co t:clkbuf %i
+select -assert-count 1 @clk1b %x:+[o] %co c:s* %i
+select -assert-count 1 @clk1b %x:+[o] %co c:s0 %i
+select -set clk2 w:clk2 %a %co t:inbuf %i
+select -assert-count 1 @clk2
+select -assert-count 1 @clk2 %x:+[o] %co t:clkbuf %i
+select -set clk2b @clk2 %x:+[o] %co t:clkbuf %i
+select -assert-count 1 @clk2b %x:+[o] %co c:s* %i
+select -assert-count 1 @clk2b %x:+[o] %co c:s1 %i
+select -set clk5 w:clk5 %a %ci t:clkbuf %i
+select -assert-count 1 @clk5
+select -assert-count 1 @clk5 %x:+[o] %co c:s5 %i
+select -assert-count 1 @clk5 %x:+[i] %ci c:s3 %i
+select -set sclk4 w:sclk4 %a %ci t:clkbuf %i
+select -assert-count 1 @sclk4
+select -assert-count 1 @sclk4 %x:+[o] %co c:s11 %i
+select -assert-count 1 @sclk4 %x:+[i] %ci c:s7 %i
+select -set sclk8 w:sclk8 %a %ci t:clkbuf %i
+select -assert-count 1 @sclk8
+select -assert-count 1 @sclk8 %x:+[o] %co c:s13 %i
+select -assert-count 1 @sclk8 %x:+[i] %ci c:s12 %i
+
+# ----------------------
+
+design -load ref
+clkbufmap -inpad inbuf o:i
+select -assert-count 2 top/t:inbuf
+select -assert-count 0 sub/t:inbuf
+select -set clk1 w:clk1 %a %co t:inbuf %i
+select -assert-count 1 @clk1
+select -assert-count 1 @clk1 %x:+[o] %co c:s* %i
+select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i
+select -set clk2 w:clk2 %a %co t:inbuf %i
+select -assert-count 1 @clk2
+select -assert-count 1 @clk2 %x:+[o] %co c:s* %i
+select -assert-count 1 @clk2 %x:+[o] %co c:s1 %i
+
+# ----------------------
+
+design -load ref
+clkbufmap -buf clkbuf o:i -inpad clkinbuf o:i
+select -assert-count 1 top/t:clkbuf
+select -assert-count 3 sub/t:clkbuf
+select -assert-count 2 top/t:clkinbuf
+select -assert-count 0 sub/t:clkinbuf
+select -set clk1 w:clk1 %a %co t:clkinbuf %i
+select -assert-count 1 @clk1
+select -assert-count 1 @clk1 %x:+[o] %co c:s* %i
+select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i
+select -set clk2 w:clk2 %a %co t:clkinbuf %i
+select -assert-count 1 @clk2
+select -assert-count 1 @clk2 %x:+[o] %co c:s* %i
+select -assert-count 1 @clk2 %x:+[o] %co c:s1 %i
+select -set clk5 w:clk5 %a %ci t:clkbuf %i
+select -assert-count 1 @clk5
+select -assert-count 1 @clk5 %x:+[o] %co c:s5 %i
+select -assert-count 1 @clk5 %x:+[i] %ci c:s3 %i
+select -set sclk4 w:sclk4 %a %ci t:clkbuf %i
+select -assert-count 1 @sclk4
+select -assert-count 1 @sclk4 %x:+[o] %co c:s11 %i
+select -assert-count 1 @sclk4 %x:+[i] %ci c:s7 %i
+select -set sclk8 w:sclk8 %a %ci t:clkbuf %i
+select -assert-count 1 @sclk8
+select -assert-count 1 @sclk8 %x:+[o] %co c:s13 %i
+select -assert-count 1 @sclk8 %x:+[i] %ci c:s12 %i
diff --git a/tests/techmap/dfflegalize_adff.ys b/tests/techmap/dfflegalize_adff.ys
index a563e8c61..cf3e925a3 100644
--- a/tests/techmap/dfflegalize_adff.ys
+++ b/tests/techmap/dfflegalize_adff.ys
@@ -39,8 +39,8 @@ design -save orig
flatten
equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFF_PP0_ x
equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFE_PP0P_ x
-#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ x
-#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ x
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ x
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ x
# Convert everything to ADFFs.
diff --git a/tests/techmap/dfflegalize_adff_init.ys b/tests/techmap/dfflegalize_adff_init.ys
index 92f249815..a10161701 100644
--- a/tests/techmap/dfflegalize_adff_init.ys
+++ b/tests/techmap/dfflegalize_adff_init.ys
@@ -45,10 +45,10 @@ equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFE_PP0P_ 0
equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFE_PP0P_ 1 -cell $_DLATCH_P_ 1
equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFE_PP1P_ 0 -cell $_DLATCH_P_ 1
equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFE_PP1P_ 1 -cell $_DLATCH_P_ 1
-#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 0
-#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 1
-#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 0
-#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 1
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 0
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 1
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 0
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 1
# Convert everything to ADFFs.
diff --git a/tests/techmap/dfflegalize_adlatch.ys b/tests/techmap/dfflegalize_adlatch.ys
index dee17e40c..ea5aaa53c 100644
--- a/tests/techmap/dfflegalize_adlatch.ys
+++ b/tests/techmap/dfflegalize_adlatch.ys
@@ -22,7 +22,7 @@ EOT
design -save orig
flatten
equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP0_ x
-#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ x
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ x
# Convert everything to ADLATCHs.
diff --git a/tests/techmap/dfflegalize_adlatch_init.ys b/tests/techmap/dfflegalize_adlatch_init.ys
index c221bbe0e..0a31d7736 100644
--- a/tests/techmap/dfflegalize_adlatch_init.ys
+++ b/tests/techmap/dfflegalize_adlatch_init.ys
@@ -25,8 +25,8 @@ equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP0_
equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP0_ 1
equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP1_ 0
equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP1_ 1
-#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ 0
-#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ 1
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ 0
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ 1
# Convert everything to ADLATCHs.
diff --git a/tests/techmap/dfflegalize_dffsr_init.ys b/tests/techmap/dfflegalize_dffsr_init.ys
index 646c086e0..a98bd0cfe 100644
--- a/tests/techmap/dfflegalize_dffsr_init.ys
+++ b/tests/techmap/dfflegalize_dffsr_init.ys
@@ -49,10 +49,10 @@ flatten
#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFE_PP0P_ 1 -cell $_SR_PP_ 0
#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFE_PP1P_ 0 -cell $_SR_PP_ 0
#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFE_PP1P_ 1 -cell $_SR_PP_ 0
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 0
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 1
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 0
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 1
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 0
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 1
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 0
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 1
# Convert everything to ADFFs.
diff --git a/tests/techmap/dfflegalize_dlatch_const.ys b/tests/techmap/dfflegalize_dlatch_const.ys
new file mode 100644
index 000000000..0b5167a06
--- /dev/null
+++ b/tests/techmap/dfflegalize_dlatch_const.ys
@@ -0,0 +1,53 @@
+read_verilog -icells <<EOT
+
+module dlatch(input E, D, (* init = 8'hf0 *) output [7:0] Q);
+$_DLATCH_P_ ff0 (.E(E), .D(1'b0), .Q(Q[0]));
+$_DLATCH_N_ ff1 (.E(E), .D(1'b0), .Q(Q[1]));
+$_DLATCH_P_ ff2 (.E(E), .D(1'b1), .Q(Q[2]));
+$_DLATCH_N_ ff3 (.E(E), .D(1'b1), .Q(Q[3]));
+$_DLATCH_P_ ff4 (.E(E), .D(1'b0), .Q(Q[4]));
+$_DLATCH_N_ ff5 (.E(E), .D(1'b0), .Q(Q[5]));
+$_DLATCH_P_ ff6 (.E(E), .D(1'b1), .Q(Q[6]));
+$_DLATCH_N_ ff7 (.E(E), .D(1'b1), .Q(Q[7]));
+endmodule
+
+EOT
+
+design -save orig
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFF_PP0_ 01
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFF_PP?_ 0
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 0
+equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 1
+
+# Convert everything to ADFFs.
+
+design -load orig
+dfflegalize -cell $_DFF_PP0_ 01
+
+select -assert-count 12 t:$_NOT_
+select -assert-count 8 t:$_DFF_PP0_
+select -assert-none t:$_DFF_PP0_ t:$_NOT_ %% %n t:* %i
+
+design -load orig
+dfflegalize -cell $_DFF_PP?_ 0
+
+select -assert-count 12 t:$_NOT_
+select -assert-count 4 t:$_DFF_PP0_
+select -assert-count 4 t:$_DFF_PP1_
+select -assert-none t:$_DFF_PP0_ t:$_DFF_PP1_ t:$_NOT_ %% %n t:* %i
+
+# Convert everything to DFFSREs.
+
+design -load orig
+dfflegalize -cell $_DFFSRE_PPPP_ 0
+
+select -assert-count 12 t:$_NOT_
+select -assert-count 8 t:$_DFFSRE_PPPP_
+select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ %% %n t:* %i
+
+design -load orig
+dfflegalize -cell $_DFFSRE_PPPP_ 1
+
+select -assert-count 12 t:$_NOT_
+select -assert-count 8 t:$_DFFSRE_PPPP_
+select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ %% %n t:* %i
diff --git a/tests/techmap/dfflegalize_sr.ys b/tests/techmap/dfflegalize_sr.ys
index a75068ae0..b8c91f753 100644
--- a/tests/techmap/dfflegalize_sr.ys
+++ b/tests/techmap/dfflegalize_sr.ys
@@ -9,12 +9,12 @@ endmodule
EOT
design -save orig
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_SR_PP_ x
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP0_ x
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP1_ x
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ x
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ x
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ x
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_SR_PP_ x
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP0_ x
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP1_ x
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ x
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ x
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ x
# Convert everything to SRs.
diff --git a/tests/techmap/dfflegalize_sr_init.ys b/tests/techmap/dfflegalize_sr_init.ys
index 39bfdcdcf..5c52a0b28 100644
--- a/tests/techmap/dfflegalize_sr_init.ys
+++ b/tests/techmap/dfflegalize_sr_init.ys
@@ -21,18 +21,18 @@ EOT
design -save orig
flatten
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_SR_PP_ 0
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_SR_PP_ 1
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP0_ 0
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP0_ 1
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP1_ 0
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP1_ 1
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ 0
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ 1
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 0
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 1
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 0
-equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 1
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_SR_PP_ 0
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_SR_PP_ 1
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP0_ 0
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP0_ 1
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP1_ 0
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCH_PP1_ 1
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ 0
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DLATCHSR_PPP_ 1
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 0
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSR_PPP_ 1
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 0
+#equiv_opt -assert -multiclock -map +/simcells.v dfflegalize -cell $_DFFSRE_PPPP_ 1
# Convert everything to SRs.
diff --git a/tests/techmap/dfflibmap-sim.v b/tests/techmap/dfflibmap-sim.v
new file mode 100644
index 000000000..1788a683b
--- /dev/null
+++ b/tests/techmap/dfflibmap-sim.v
@@ -0,0 +1,22 @@
+module dffn(input CLK, D, output reg Q, output QN);
+
+always @(negedge CLK)
+ Q <= D;
+
+assign QN = ~Q;
+
+endmodule
+
+module dffsr(input CLK, D, CLEAR, PRESET, output reg Q, output QN);
+
+always @(posedge CLK, posedge CLEAR, posedge PRESET)
+ if (CLEAR)
+ Q <= 0;
+ else if (PRESET)
+ Q <= 1;
+ else
+ Q <= D;
+
+assign QN = ~Q;
+
+endmodule
diff --git a/tests/techmap/dfflibmap.lib b/tests/techmap/dfflibmap.lib
new file mode 100644
index 000000000..ce460877e
--- /dev/null
+++ b/tests/techmap/dfflibmap.lib
@@ -0,0 +1,55 @@
+library(test) {
+ /* D-type flip-flop with asynchronous reset and preset */
+ cell (dffn) {
+ area : 6;
+ ff("IQ", "IQN") {
+ next_state : "D";
+ clocked_on : "!CLK";
+ }
+ pin(D) {
+ direction : input;
+ }
+ pin(CLK) {
+ direction : input;
+ }
+ pin(Q) {
+ direction: output;
+ function : "IQ";
+ }
+ pin(QN) {
+ direction: output;
+ function : "IQN";
+ }
+ }
+ cell (dffsr) {
+ area : 6;
+ ff("IQ", "IQN") {
+ next_state : "D";
+ clocked_on : "CLK";
+ clear : "CLEAR";
+ preset : "PRESET";
+ clear_preset_var1 : L;
+ clear_preset_var2 : L;
+ }
+ pin(D) {
+ direction : input;
+ }
+ pin(CLK) {
+ direction : input;
+ }
+ pin(CLEAR) {
+ direction : input;
+ }
+ pin(PRESET) {
+ direction : input;
+ }
+ pin(Q) {
+ direction: output;
+ function : "IQ";
+ }
+ pin(QN) {
+ direction: output;
+ function : "IQN";
+ }
+ }
+}
diff --git a/tests/techmap/dfflibmap.ys b/tests/techmap/dfflibmap.ys
new file mode 100644
index 000000000..04477eb14
--- /dev/null
+++ b/tests/techmap/dfflibmap.ys
@@ -0,0 +1,58 @@
+read_verilog -icells <<EOT
+
+module top(input C, D, S, R, output [9:0] Q);
+
+$_DFF_P_ ff0 (.C(C), .D(D), .Q(Q[0]));
+$_DFF_PP0_ ff1 (.C(C), .D(D), .R(R), .Q(Q[1]));
+$_DFF_PP1_ ff2 (.C(C), .D(D), .R(R), .Q(Q[2]));
+$_DFFSR_PPP_ ff3 (.C(C), .D(D), .R(R), .S(S), .Q(Q[3]));
+$_DFFSR_NNN_ ff4 (.C(C), .D(D), .R(R), .S(S), .Q(Q[4]));
+
+assign Q[9:5] = ~Q[4:0];
+
+endmodule
+
+EOT
+
+simplemap
+
+design -save orig
+
+#equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -liberty dfflibmap.lib
+#equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -prepare -liberty dfflibmap.lib
+dfflibmap -prepare -liberty dfflibmap.lib
+equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -map-only -liberty dfflibmap.lib
+
+design -load orig
+dfflibmap -liberty dfflibmap.lib
+clean
+
+select -assert-count 4 t:$_NOT_
+select -assert-count 1 t:dffn
+select -assert-count 4 t:dffsr
+select -assert-none t:dffn t:dffsr t:$_NOT_ %% %n t:* %i
+
+design -load orig
+dfflibmap -prepare -liberty dfflibmap.lib
+
+select -assert-count 9 t:$_NOT_
+select -assert-count 1 t:$_DFF_N_
+select -assert-count 4 t:$_DFFSR_PPP_
+select -assert-none t:$_DFF_N_ t:$_DFFSR_PPP_ t:$_NOT_ %% %n t:* %i
+
+design -load orig
+dfflibmap -map-only -liberty dfflibmap.lib
+
+select -assert-count 5 t:$_NOT_
+select -assert-count 0 t:dffn
+select -assert-count 1 t:dffsr
+
+design -load orig
+dfflibmap -prepare -liberty dfflibmap.lib
+dfflibmap -map-only -liberty dfflibmap.lib
+clean
+
+select -assert-count 4 t:$_NOT_
+select -assert-count 1 t:dffn
+select -assert-count 4 t:dffsr
+select -assert-none t:dffn t:dffsr t:$_NOT_ %% %n t:* %i
diff --git a/tests/various/integer_range_bad_syntax.ys b/tests/various/integer_range_bad_syntax.ys
new file mode 100644
index 000000000..4f427211f
--- /dev/null
+++ b/tests/various/integer_range_bad_syntax.ys
@@ -0,0 +1,6 @@
+logger -expect error "syntax error, unexpected" 1
+read_verilog -sv <<EOT
+module test_integer_range();
+parameter integer [31:0] a = 0;
+endmodule
+EOT
diff --git a/tests/various/integer_real_bad_syntax.ys b/tests/various/integer_real_bad_syntax.ys
new file mode 100644
index 000000000..942d8de77
--- /dev/null
+++ b/tests/various/integer_real_bad_syntax.ys
@@ -0,0 +1,6 @@
+logger -expect error "syntax error, unexpected TOK_REAL" 1
+read_verilog -sv <<EOT
+module test_integer_real();
+parameter integer real a = 0;
+endmodule
+EOT
diff --git a/tests/various/logic_param_simple.ys b/tests/various/logic_param_simple.ys
new file mode 100644
index 000000000..968564080
--- /dev/null
+++ b/tests/various/logic_param_simple.ys
@@ -0,0 +1,9 @@
+read_verilog -sv <<EOT
+module test_logic_param();
+parameter logic a = 0;
+parameter logic [31:0] e = 0;
+parameter logic signed b = 0;
+parameter logic unsigned c = 0;
+parameter logic unsigned [31:0] d = 0;
+endmodule
+EOT