aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--backends/smt2/smt2.cc3
-rw-r--r--backends/smt2/smtio.py40
-rw-r--r--examples/intel/DE2i-150/run_cycloneiv2
-rw-r--r--examples/intel/MAX10/run_max102
-rwxr-xr-xexamples/intel/asicworld_lfsr/run_cycloneiv2
-rwxr-xr-xexamples/intel/asicworld_lfsr/run_max102
-rw-r--r--frontends/verilog/preproc.cc24
-rw-r--r--frontends/verilog/verilog_lexer.l1
-rw-r--r--frontends/verilog/verilog_parser.y31
-rw-r--r--kernel/driver.cc16
-rw-r--r--kernel/yosys.cc23
-rw-r--r--passes/cmds/Makefile.inc1
-rw-r--r--passes/cmds/ltp.cc185
-rw-r--r--passes/cmds/show.cc4
-rw-r--r--passes/opt/opt_clean.cc2
-rw-r--r--passes/opt/opt_rmdff.cc3
-rwxr-xr-xtechlibs/achronix/Makefile.inc4
-rwxr-xr-xtechlibs/achronix/speedster22i/cells_arith.v (renamed from techlibs/achronix/speedster22i/cells_arith_speedster.v)0
-rwxr-xr-xtechlibs/achronix/speedster22i/cells_map.v (renamed from techlibs/achronix/speedster22i/cells_map_speedster.v)0
-rwxr-xr-xtechlibs/achronix/speedster22i/cells_sim.v (renamed from techlibs/achronix/speedster22i/cells_comb_speedster.v)0
-rwxr-xr-xtechlibs/achronix/synth_speedster.cc4
-rw-r--r--techlibs/ice40/cells_map.v2
-rw-r--r--techlibs/ice40/cells_sim.v103
-rw-r--r--techlibs/ice40/synth_ice40.cc32
-rw-r--r--techlibs/intel/Makefile.inc2
-rw-r--r--techlibs/intel/cyclone10/cells_arith.v65
-rw-r--r--techlibs/intel/cyclone10/cells_map.v99
-rw-r--r--techlibs/intel/cyclone10/cells_sim.v137
-rw-r--r--techlibs/intel/synth_intel.cc6
30 files changed, 749 insertions, 52 deletions
diff --git a/Makefile b/Makefile
index eb8f0f594..924fd88b7 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,7 @@ ENABLE_TCL := 1
ENABLE_ABC := 1
ENABLE_PLUGINS := 1
ENABLE_READLINE := 1
+ENABLE_EDITLINE := 0
ENABLE_VERIFIC := 0
ENABLE_COVER := 1
ENABLE_LIBYOSYS := 0
@@ -226,6 +227,11 @@ endif
ifeq ($(CONFIG),mxe)
LDLIBS += -ltermcap
endif
+else
+ifeq ($(ENABLE_EDITLINE),1)
+CXXFLAGS += -DYOSYS_ENABLE_EDITLINE
+LDLIBS += -ledit -ltinfo -lbsd
+endif
endif
ifeq ($(ENABLE_PLUGINS),1)
diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc
index dce7c25de..8daa52eb3 100644
--- a/backends/smt2/smt2.cc
+++ b/backends/smt2/smt2.cc
@@ -811,6 +811,9 @@ struct Smt2Worker
Module *m = module->design->module(cell->type);
log_assert(m != nullptr);
+ hier.push_back(stringf(" (= (|%s_is| state) (|%s_is| %s))\n",
+ get_id(module), get_id(cell->type), cell_state.c_str()));
+
for (auto &conn : cell->connections())
{
Wire *w = m->wire(conn.first);
diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py
index 6e7b68242..61ac14c82 100644
--- a/backends/smt2/smtio.py
+++ b/backends/smt2/smtio.py
@@ -20,7 +20,7 @@ import sys, subprocess, re, os
from copy import deepcopy
from select import select
from time import time
-from queue import Queue
+from queue import Queue, Empty
from threading import Thread
@@ -213,32 +213,52 @@ class SmtIo:
def p_thread_main(self):
while True:
- data = self.p_queue.get()
- if data is None: break
- self.p.stdin.write(data[0])
- if data[1]: self.p.stdin.flush()
+ data = self.p.stdout.readline().decode("ascii")
+ if data == "": break
+ self.p_queue.put(data)
+ self.p_running = False
def p_open(self):
assert self.p is None
self.p = subprocess.Popen(self.popen_vargs, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ self.p_running = True
+ self.p_next = None
self.p_queue = Queue()
self.p_thread = Thread(target=self.p_thread_main)
self.p_thread.start()
def p_write(self, data, flush):
assert self.p is not None
- self.p_queue.put((bytes(data, "ascii"), flush))
+ self.p.stdin.write(bytes(data, "ascii"))
+ if flush: self.p.stdin.flush()
def p_read(self):
assert self.p is not None
- return self.p.stdout.readline().decode("ascii")
+ assert self.p_running
+ if self.p_next is not None:
+ data = self.p_next
+ self.p_next = None
+ return data
+ return self.p_queue.get()
+
+ def p_poll(self):
+ assert self.p is not None
+ assert self.p_running
+ if self.p_next is not None:
+ return False
+ try:
+ self.p_next = self.p_queue.get(True, 0.1)
+ return False
+ except Empty:
+ return True
def p_close(self):
assert self.p is not None
- self.p_queue.put(None)
- self.p_thread.join()
self.p.stdin.close()
+ self.p_thread.join()
+ assert not self.p_running
self.p = None
+ self.p_next = None
self.p_queue = None
self.p_thread = None
@@ -485,7 +505,7 @@ class SmtIo:
count = 0
num_bs = 0
- while select([self.p.stdout], [], [], 0.1) == ([], [], []):
+ while self.p_poll():
count += 1
if count < 25:
diff --git a/examples/intel/DE2i-150/run_cycloneiv b/examples/intel/DE2i-150/run_cycloneiv
index 321ed2778..518807b57 100644
--- a/examples/intel/DE2i-150/run_cycloneiv
+++ b/examples/intel/DE2i-150/run_cycloneiv
@@ -1,2 +1,2 @@
#/bin/env bash
-yosys -p "synth_intel -family cycloneiv -top top -vout top.vqm" top.v sevenseg.v
+yosys -p "synth_intel -family cycloneiv -top top -vqm top.vqm" top.v sevenseg.v
diff --git a/examples/intel/MAX10/run_max10 b/examples/intel/MAX10/run_max10
index ef7649afb..0378e4fa7 100644
--- a/examples/intel/MAX10/run_max10
+++ b/examples/intel/MAX10/run_max10
@@ -1 +1 @@
-yosys -p "synth_intel -family max10 -top top -vout top.vqm" top.v sevenseg.v
+yosys -p "synth_intel -family max10 -top top -vqm top.vqm" top.v sevenseg.v
diff --git a/examples/intel/asicworld_lfsr/run_cycloneiv b/examples/intel/asicworld_lfsr/run_cycloneiv
index cb7f5c9b1..c7498bded 100755
--- a/examples/intel/asicworld_lfsr/run_cycloneiv
+++ b/examples/intel/asicworld_lfsr/run_cycloneiv
@@ -1,2 +1,2 @@
#!/bin/env bash
-yosys -p "synth_intel -family cycloneiv -top lfsr_updown -vout top.vqm" lfsr_updown.v
+yosys -p "synth_intel -family cycloneiv -top lfsr_updown -vqm top.vqm" lfsr_updown.v
diff --git a/examples/intel/asicworld_lfsr/run_max10 b/examples/intel/asicworld_lfsr/run_max10
index 6bb812c16..b75d552bb 100755
--- a/examples/intel/asicworld_lfsr/run_max10
+++ b/examples/intel/asicworld_lfsr/run_max10
@@ -1,2 +1,2 @@
#!/bin/env bash
-yosys -p "synth_intel -family max10 -top lfsr_updown -vout top.vqm" lfsr_updown.v
+yosys -p "synth_intel -family max10 -top lfsr_updown -vqm top.vqm" lfsr_updown.v
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc
index ee742d485..00bdcee43 100644
--- a/frontends/verilog/preproc.cc
+++ b/frontends/verilog/preproc.cc
@@ -366,14 +366,31 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
ff.clear();
std::string fixed_fn = fn;
ff.open(fixed_fn.c_str());
- if (ff.fail() && fn.size() > 0 && fn[0] != '/' && filename.find('/') != std::string::npos) {
+
+ bool filename_path_sep_found;
+ bool fn_relative;
+#ifdef _WIN32
+ // Both forward and backslash are acceptable separators on Windows.
+ filename_path_sep_found = (filename.find_first_of("/\\") != std::string::npos);
+ // Easier just to invert the check for an absolute path (e.g. C:\ or C:/)
+ fn_relative = !(fn[1] == ':' && (fn[2] == '/' || fn[2] == '\\'));
+#else
+ filename_path_sep_found = (filename.find('/') != std::string::npos);
+ fn_relative = (fn[0] != '/');
+#endif
+
+ if (ff.fail() && fn.size() > 0 && fn_relative && filename_path_sep_found) {
// if the include file was not found, it is not given with an absolute path, and the
// currently read file is given with a path, then try again relative to its directory
ff.clear();
+#ifdef _WIN32
+ fixed_fn = filename.substr(0, filename.find_last_of("/\\")+1) + fn;
+#else
fixed_fn = filename.substr(0, filename.rfind('/')+1) + fn;
+#endif
ff.open(fixed_fn);
}
- if (ff.fail() && fn.size() > 0 && fn[0] != '/') {
+ if (ff.fail() && fn.size() > 0 && fn_relative) {
// if the include file was not found and it is not given with an absolute path, then
// search it in the include path
for (auto incdir : include_dirs) {
@@ -505,7 +522,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
if (try_expand_macro(defines_with_args, defines_map, tok))
continue;
-
+
output_code.push_back(tok);
}
@@ -521,4 +538,3 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
}
YOSYS_NAMESPACE_END
-
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l
index 07d85bed8..d6d00c371 100644
--- a/frontends/verilog/verilog_lexer.l
+++ b/frontends/verilog/verilog_lexer.l
@@ -170,6 +170,7 @@ YOSYS_NAMESPACE_END
"endgenerate" { return TOK_ENDGENERATE; }
"while" { return TOK_WHILE; }
"repeat" { return TOK_REPEAT; }
+"automatic" { return TOK_AUTOMATIC; }
"unique" { SV_KEYWORD(TOK_UNIQUE); }
"unique0" { SV_KEYWORD(TOK_UNIQUE); }
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index ec92f6628..9aa01c9f0 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -108,7 +108,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
%token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG
%token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL
%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT
-%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR
+%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC
%token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT
%token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK
%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL
@@ -359,6 +359,7 @@ package_body_stmt:
non_opt_delay:
'#' TOK_ID { delete $2; } |
'#' TOK_CONSTVAL { delete $2; } |
+ '#' TOK_REALVAL { delete $2; } |
'#' '(' expr ')' { delete $3; } |
'#' '(' expr ':' expr ':' expr ')' { delete $3; delete $5; delete $7; };
@@ -523,35 +524,35 @@ task_func_decl:
} opt_dpi_function_args ';' {
current_function_or_task = NULL;
} |
- attr TOK_TASK TOK_ID {
+ attr TOK_TASK opt_automatic TOK_ID {
current_function_or_task = new AstNode(AST_TASK);
- current_function_or_task->str = *$3;
+ current_function_or_task->str = *$4;
append_attr(current_function_or_task, $1);
ast_stack.back()->children.push_back(current_function_or_task);
ast_stack.push_back(current_function_or_task);
current_function_or_task_port_id = 1;
- delete $3;
+ delete $4;
} task_func_args_opt ';' task_func_body TOK_ENDTASK {
current_function_or_task = NULL;
ast_stack.pop_back();
} |
- attr TOK_FUNCTION opt_signed range_or_signed_int TOK_ID {
+ attr TOK_FUNCTION opt_automatic opt_signed range_or_signed_int TOK_ID {
current_function_or_task = new AstNode(AST_FUNCTION);
- current_function_or_task->str = *$5;
+ current_function_or_task->str = *$6;
append_attr(current_function_or_task, $1);
ast_stack.back()->children.push_back(current_function_or_task);
ast_stack.push_back(current_function_or_task);
AstNode *outreg = new AstNode(AST_WIRE);
- outreg->str = *$5;
- outreg->is_signed = $3;
- if ($4 != NULL) {
- outreg->children.push_back($4);
- outreg->is_signed = $3 || $4->is_signed;
- $4->is_signed = false;
+ outreg->str = *$6;
+ outreg->is_signed = $4;
+ if ($5 != NULL) {
+ outreg->children.push_back($5);
+ outreg->is_signed = $4 || $5->is_signed;
+ $5->is_signed = false;
}
current_function_or_task->children.push_back(outreg);
current_function_or_task_port_id = 1;
- delete $5;
+ delete $6;
} task_func_args_opt ';' task_func_body TOK_ENDFUNCTION {
current_function_or_task = NULL;
ast_stack.pop_back();
@@ -578,6 +579,10 @@ dpi_function_args:
dpi_function_arg |
/* empty */;
+opt_automatic:
+ TOK_AUTOMATIC |
+ /* empty */;
+
opt_signed:
TOK_SIGNED {
$$ = true;
diff --git a/kernel/driver.cc b/kernel/driver.cc
index 1fe61b499..c5e31d718 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -25,6 +25,10 @@
# include <readline/history.h>
#endif
+#ifdef YOSYS_ENABLE_EDITLINE
+# include <editline/readline.h>
+#endif
+
#include <stdio.h>
#include <string.h>
#include <limits.h>
@@ -119,27 +123,33 @@ const char *prompt()
#else /* EMSCRIPTEN */
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
int yosys_history_offset = 0;
std::string yosys_history_file;
#endif
void yosys_atexit()
{
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
if (!yosys_history_file.empty()) {
+#if defined(YOSYS_ENABLE_READLINE)
if (yosys_history_offset > 0) {
history_truncate_file(yosys_history_file.c_str(), 100);
append_history(where_history() - yosys_history_offset, yosys_history_file.c_str());
} else
write_history(yosys_history_file.c_str());
+#else
+ write_history(yosys_history_file.c_str());
+#endif
}
clear_history();
+#if defined(YOSYS_ENABLE_READLINE)
HIST_ENTRY **hist_list = history_list();
if (hist_list != NULL)
free(hist_list);
#endif
+#endif
}
int main(int argc, char **argv)
@@ -159,7 +169,7 @@ int main(int argc, char **argv)
bool mode_v = false;
bool mode_q = false;
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
if (getenv("HOME") != NULL) {
yosys_history_file = stringf("%s/.yosys_history", getenv("HOME"));
read_history(yosys_history_file.c_str());
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index e5b22eba7..34665a0ad 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -25,6 +25,10 @@
# include <readline/history.h>
#endif
+#ifdef YOSYS_ENABLE_EDITLINE
+# include <editline/readline.h>
+#endif
+
#ifdef YOSYS_ENABLE_PLUGINS
# include <dlfcn.h>
#endif
@@ -938,7 +942,7 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
Backend::backend_call(design, NULL, filename, command);
}
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
static char *readline_cmd_generator(const char *text, int state)
{
static std::map<std::string, Pass*>::iterator it;
@@ -1025,14 +1029,14 @@ void shell(RTLIL::Design *design)
recursion_counter++;
log_cmd_error_throw = true;
-#ifdef YOSYS_ENABLE_READLINE
- rl_readline_name = "yosys";
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
+ rl_readline_name = (char*)"yosys";
rl_attempted_completion_function = readline_completion;
- rl_basic_word_break_characters = " \t\n";
+ rl_basic_word_break_characters = (char*)" \t\n";
#endif
char *command = NULL;
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
while ((command = readline(create_prompt(design, recursion_counter))) != NULL)
{
#else
@@ -1046,7 +1050,7 @@ void shell(RTLIL::Design *design)
#endif
if (command[strspn(command, " \t\r\n")] == 0)
continue;
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
add_history(command);
#endif
@@ -1114,7 +1118,7 @@ struct ShellPass : public Pass {
}
} ShellPass;
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
struct HistoryPass : public Pass {
HistoryPass() : Pass("history", "show last interactive commands") { }
virtual void help() {
@@ -1128,8 +1132,13 @@ struct HistoryPass : public Pass {
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
extra_args(args, 1, design, false);
+#ifdef YOSYS_ENABLE_READLINE
for(HIST_ENTRY **list = history_list(); *list != NULL; list++)
log("%s\n", (*list)->line);
+#else
+ for (int i = where_history(); history_get(i); i++)
+ log("%s\n", history_get(i)->line);
+#endif
}
} HistoryPass;
#endif
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index 9e3934e16..44a83b2b9 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -28,4 +28,5 @@ OBJS += passes/cmds/edgetypes.o
OBJS += passes/cmds/chformal.o
OBJS += passes/cmds/chtype.o
OBJS += passes/cmds/blackbox.o
+OBJS += passes/cmds/ltp.o
diff --git a/passes/cmds/ltp.cc b/passes/cmds/ltp.cc
new file mode 100644
index 000000000..42dc794ec
--- /dev/null
+++ b/passes/cmds/ltp.cc
@@ -0,0 +1,185 @@
+/*
+ * 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/celltypes.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct LtpWorker
+{
+ RTLIL::Design *design;
+ RTLIL::Module *module;
+ SigMap sigmap;
+
+ dict<SigBit, tuple<int, SigBit, Cell*>> bits;
+ dict<SigBit, dict<SigBit, Cell*>> bit2bits;
+ dict<SigBit, tuple<SigBit, Cell*>> bit2ff;
+
+ int maxlvl;
+ SigBit maxbit;
+ pool<SigBit> busy;
+
+ LtpWorker(RTLIL::Module *module, bool noff) : design(module->design), module(module), sigmap(module)
+ {
+ CellTypes ff_celltypes;
+
+ if (noff) {
+ ff_celltypes.setup_internals_mem();
+ ff_celltypes.setup_stdcells_mem();
+ }
+
+ for (auto wire : module->selected_wires())
+ for (auto bit : sigmap(wire))
+ bits[bit] = tuple<int, SigBit, Cell*>(-1, State::Sx, nullptr);
+
+ for (auto cell : module->selected_cells())
+ {
+ pool<SigBit> src_bits, dst_bits;
+
+ for (auto &conn : cell->connections())
+ for (auto bit : sigmap(conn.second)) {
+ if (cell->input(conn.first))
+ src_bits.insert(bit);
+ if (cell->output(conn.first))
+ dst_bits.insert(bit);
+ }
+
+ if (noff && ff_celltypes.cell_known(cell->type)) {
+ for (auto s : src_bits)
+ for (auto d : dst_bits) {
+ bit2ff[s] = tuple<SigBit, Cell*>(d, cell);
+ break;
+ }
+ continue;
+ }
+
+ for (auto s : src_bits)
+ for (auto d : dst_bits)
+ bit2bits[s][d] = cell;
+ }
+
+ maxlvl = -1;
+ maxbit = State::Sx;
+ }
+
+ void runner(SigBit bit, int level, SigBit from, Cell *via)
+ {
+ auto &bitinfo = bits.at(bit);
+
+ if (get<0>(bitinfo) >= level)
+ return;
+
+ if (busy.count(bit) > 0) {
+ log_warning("Detected loop at %s in %s\n", log_signal(bit), log_id(module));
+ return;
+ }
+
+ busy.insert(bit);
+ get<0>(bitinfo) = level;
+ get<1>(bitinfo) = from;
+ get<2>(bitinfo) = via;
+
+ if (level > maxlvl) {
+ maxlvl = level;
+ maxbit = bit;
+ }
+
+ if (bit2bits.count(bit)) {
+ for (auto &it : bit2bits.at(bit))
+ runner(it.first, level+1, bit, it.second);
+ }
+
+ busy.erase(bit);
+ }
+
+ void printpath(SigBit bit)
+ {
+ auto &bitinfo = bits.at(bit);
+ if (get<2>(bitinfo)) {
+ printpath(get<1>(bitinfo));
+ log("%5d: %s (via %s)\n", get<0>(bitinfo), log_signal(bit), log_id(get<2>(bitinfo)));
+ } else {
+ log("%5d: %s\n", get<0>(bitinfo), log_signal(bit));
+ }
+ }
+
+ void run()
+ {
+ for (auto &it : bits)
+ if (get<0>(it.second) < 0)
+ runner(it.first, 0, State::Sx, nullptr);
+
+ log("\n");
+ log("Longest topological path in %s (length=%d):\n", log_id(module), maxlvl);
+
+ if (maxlvl >= 0)
+ printpath(maxbit);
+
+ if (bit2ff.count(maxbit))
+ log("%5s: %s (via %s)\n", "ff", log_signal(get<0>(bit2ff.at(maxbit))), log_id(get<1>(bit2ff.at(maxbit))));
+ }
+};
+
+struct LtpPass : public Pass {
+ LtpPass() : Pass("ltp", "print longest topological path") { }
+ virtual void help()
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" ltp [options] [selection]\n");
+ log("\n");
+ log("This command prints the longest topological path in the design. (Only considers\n");
+ log("paths within a single module, so the design must be flattened.)\n");
+ log("\n");
+ log(" -noff\n");
+ log(" automatically exclude FF cell types\n");
+ log("\n");
+ }
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ {
+ bool noff = false;
+
+ log_header(design, "Executing LTP pass (find longest path).\n");
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++) {
+ if (args[argidx] == "-noff") {
+ noff = true;
+ continue;
+ }
+ break;
+ }
+
+ extra_args(args, argidx, design);
+
+ for (Module *module : design->selected_modules())
+ {
+ if (module->has_processes_warn())
+ continue;
+
+ LtpWorker worker(module, noff);
+ worker.run();
+ }
+ }
+} LtpPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc
index 3a3939a81..02624cf30 100644
--- a/passes/cmds/show.cc
+++ b/passes/cmds/show.cc
@@ -30,6 +30,10 @@
# include <readline/readline.h>
#endif
+#ifdef YOSYS_ENABLE_EDITLINE
+# include <editline/readline.h>
+#endif
+
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc
index fb1851868..2d2ffa9a1 100644
--- a/passes/opt/opt_clean.cc
+++ b/passes/opt/opt_clean.cc
@@ -392,7 +392,7 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
}
if (verbose)
- log(" removing redundent init attribute on %s.\n", log_id(wire));
+ log(" removing redundant init attribute on %s.\n", log_id(wire));
wire->attributes.erase("\\init");
did_something = true;
diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc
index 02f3e93f5..edec42c4d 100644
--- a/passes/opt/opt_rmdff.cc
+++ b/passes/opt/opt_rmdff.cc
@@ -430,6 +430,8 @@ struct OptRmdffPass : public Pass {
assign_map.set(module);
dff_init_map.set(module);
+ mux_drivers.clear();
+ init_attributes.clear();
for (auto wire : module->wires())
{
@@ -534,6 +536,7 @@ struct OptRmdffPass : public Pass {
assign_map.clear();
mux_drivers.clear();
+ init_attributes.clear();
if (total_count || total_initdrv)
design->scratchpad_set_bool("opt.did_something", true);
diff --git a/techlibs/achronix/Makefile.inc b/techlibs/achronix/Makefile.inc
index 4dfa59856..affe0334a 100755
--- a/techlibs/achronix/Makefile.inc
+++ b/techlibs/achronix/Makefile.inc
@@ -1,6 +1,6 @@
OBJS += techlibs/achronix/synth_speedster.o
-$(eval $(call add_share_file,share/achronix/speedster22i/,techlibs/achronix/speedster22i/cells_comb_speedster.v))
-$(eval $(call add_share_file,share/achronix/speedster22i/,techlibs/achronix/speedster22i/cells_map_speedster.v))
+$(eval $(call add_share_file,share/achronix/speedster22i/,techlibs/achronix/speedster22i/cells_sim.v))
+$(eval $(call add_share_file,share/achronix/speedster22i/,techlibs/achronix/speedster22i/cells_map.v))
diff --git a/techlibs/achronix/speedster22i/cells_arith_speedster.v b/techlibs/achronix/speedster22i/cells_arith.v
index 9ef073f7c..9ef073f7c 100755
--- a/techlibs/achronix/speedster22i/cells_arith_speedster.v
+++ b/techlibs/achronix/speedster22i/cells_arith.v
diff --git a/techlibs/achronix/speedster22i/cells_map_speedster.v b/techlibs/achronix/speedster22i/cells_map.v
index fb26eabf0..fb26eabf0 100755
--- a/techlibs/achronix/speedster22i/cells_map_speedster.v
+++ b/techlibs/achronix/speedster22i/cells_map.v
diff --git a/techlibs/achronix/speedster22i/cells_comb_speedster.v b/techlibs/achronix/speedster22i/cells_sim.v
index 24c57c41a..24c57c41a 100755
--- a/techlibs/achronix/speedster22i/cells_comb_speedster.v
+++ b/techlibs/achronix/speedster22i/cells_sim.v
diff --git a/techlibs/achronix/synth_speedster.cc b/techlibs/achronix/synth_speedster.cc
index 8158c56fd..3808af6f1 100755
--- a/techlibs/achronix/synth_speedster.cc
+++ b/techlibs/achronix/synth_speedster.cc
@@ -122,7 +122,7 @@ struct SynthIntelPass : public ScriptPass {
{
if (check_label("begin"))
{
- run("read_verilog -sv -lib +/achronix/speedster22i/cells_comb_speedster.v");
+ run("read_verilog -sv -lib +/achronix/speedster22i/cells_sim.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
@@ -164,7 +164,7 @@ struct SynthIntelPass : public ScriptPass {
if (check_label("map_cells"))
{
run("iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I");
- run("techmap -map +/achronix/speedster22i/cells_map_speedster.v");
+ run("techmap -map +/achronix/speedster22i/cells_map.v");
run("dffinit -ff dffeas Q INIT");
run("clean -purge");
}
diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v
index 0227ffadb..6550b75cf 100644
--- a/techlibs/ice40/cells_map.v
+++ b/techlibs/ice40/cells_map.v
@@ -27,6 +27,7 @@ module \$__DFFE_NP1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (
module \$__DFFE_PP0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule
module \$__DFFE_PP1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule
+`ifndef NO_SB_LUT4
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
@@ -55,3 +56,4 @@ module \$lut (A, Y);
end
endgenerate
endmodule
+`endif
diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v
index 7778b5519..2bcab8884 100644
--- a/techlibs/ice40/cells_sim.v
+++ b/techlibs/ice40/cells_sim.v
@@ -881,3 +881,106 @@ module SB_WARMBOOT (
input S0
);
endmodule
+
+// UltraPlus feature cells
+(* blackbox *)
+module SB_MAC16 (
+ input CLK,
+ input CE,
+ input [15:0] C,
+ input [15:0] A,
+ input [15:0] B,
+ input [15:0] D,
+ input AHOLD,
+ input BHOLD,
+ input CHOLD,
+ input DHOLD,
+ input IRSTTOP,
+ input IRSTBOT,
+ input ORSTTOP,
+ input ORSTBOT,
+ input OLOADTOP,
+ input OLOADBOT,
+ input ADDSUBTOP,
+ input ADDSUBBOT,
+ input OHOLDTOP,
+ input OHOLDBOT,
+ input CI,
+ input ACCUMCI,
+ input SIGNEXTIN,
+ output [31:0] O,
+ output CO,
+ output ACCUMCO,
+ output SIGNEXTOUT
+);
+parameter NEG_TRIGGER = 1'b0;
+parameter C_REG = 1'b0;
+parameter A_REG = 1'b0;
+parameter B_REG = 1'b0;
+parameter D_REG = 1'b0;
+parameter TOP_8x8_MULT_REG = 1'b0;
+parameter BOT_8x8_MULT_REG = 1'b0;
+parameter PIPELINE_16x16_MULT_REG1 = 1'b0;
+parameter PIPELINE_16x16_MULT_REG2 = 1'b0;
+parameter TOPOUTPUT_SELECT = 2'b00;
+parameter TOPADDSUB_LOWERINPUT = 2'b00;
+parameter TOPADDSUB_UPPERINPUT = 1'b0;
+parameter TOPADDSUB_CARRYSELECT = 2'b00;
+parameter BOTOUTPUT_SELECT = 2'b00;
+parameter BOTADDSUB_LOWERINPUT = 2'b00;
+parameter BOTADDSUB_UPPERINPUT = 1'b0;
+parameter BOTADDSUB_CARRYSELECT = 2'b00;
+parameter MODE_8x8 = 1'b0;
+parameter A_SIGNED = 1'b0;
+parameter B_SIGNED = 1'b0;
+endmodule
+
+(* blackbox *)
+module SB_SPRAM256KA(
+ input [13:0] ADDRESS,
+ input [15:0] DATAIN,
+ input [3:0] MASKWREN,
+ input WREN,
+ input CHIPSELECT,
+ input CLOCK,
+ input STANDBY,
+ input SLEEP,
+ input POWEROFF,
+ output [15:0] DATAOUT
+);
+endmodule
+
+(* blackbox *)
+module SB_HFOSC(
+ input CLKHFPU,
+ input CLKHFEN,
+ output CLKHF
+);
+parameter CLKHF_DIV = "0b00";
+endmodule
+
+(* blackbox *)
+module SB_LFOSC(
+ input CLKLFPU,
+ input CLKLFEN,
+ output CLKLF
+);
+endmodule
+
+(* blackbox *)
+module SB_RGBA_DRV(
+ input CURREN,
+ input RGBLEDEN,
+ input RGB0PWM,
+ input RGB1PWM,
+ input RGB2PWM,
+ output RGB0,
+ output RGB1,
+ output RGB2
+);
+parameter CURRENT_MODE = "0b0";
+parameter RGB0_CURRENT = "0b000000";
+parameter RGB1_CURRENT = "0b000000";
+parameter RGB2_CURRENT = "0b000000";
+endmodule
+
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index a49372c8a..57f96ca1a 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -68,6 +68,10 @@ struct SynthIce40Pass : public ScriptPass
log(" -abc2\n");
log(" run two passes of 'abc' for slightly improved logic density\n");
log("\n");
+ log(" -vpr\n");
+ log(" generate an output netlist (and BLIF file) suitable for VPR\n");
+ log(" (this fueature is experimental and incomplete)\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -75,7 +79,7 @@ struct SynthIce40Pass : public ScriptPass
}
string top_opt, blif_file, edif_file;
- bool nocarry, nobram, flatten, retime, abc2;
+ bool nocarry, nobram, flatten, retime, abc2, vpr;
virtual void clear_flags() YS_OVERRIDE
{
@@ -87,6 +91,7 @@ struct SynthIce40Pass : public ScriptPass
flatten = true;
retime = false;
abc2 = false;
+ vpr = false;
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -141,6 +146,10 @@ struct SynthIce40Pass : public ScriptPass
abc2 = true;
continue;
}
+ if (args[argidx] == "-vpr") {
+ vpr = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -201,7 +210,7 @@ struct SynthIce40Pass : public ScriptPass
{
run("dffsr2dff");
run("dff2dffe -direct-match $_DFF_*");
- run("techmap -map +/ice40/cells_map.v");
+ run("techmap -D NO_SB_LUT4 -map +/ice40/cells_map.v");
run("opt_expr -mux_undef");
run("simplemap");
run("ice40_ffinit");
@@ -222,7 +231,11 @@ struct SynthIce40Pass : public ScriptPass
if (check_label("map_cells"))
{
- run("techmap -map +/ice40/cells_map.v");
+ if (vpr)
+ run("techmap -D NO_SB_LUT4 -map +/ice40/cells_map.v");
+ else
+ run("techmap -map +/ice40/cells_map.v", "(with -D NO_SB_LUT4 in vpr mode)");
+
run("clean");
}
@@ -235,8 +248,17 @@ struct SynthIce40Pass : public ScriptPass
if (check_label("blif"))
{
- if (!blif_file.empty() || help_mode)
- run(stringf("write_blif -gates -attr -param %s", help_mode ? "<file-name>" : blif_file.c_str()));
+ if (!blif_file.empty() || help_mode) {
+ if (vpr || help_mode) {
+ run(stringf("opt_clean -purge"),
+ " (vpr mode)");
+ run(stringf("write_blif %s", help_mode ? "<file-name>" : blif_file.c_str()),
+ " (vpr mode)");
+ }
+ if (!vpr)
+ run(stringf("write_blif -gates -attr -param %s",
+ help_mode ? "<file-name>" : blif_file.c_str()), "(non-vpr mode)");
+ }
}
if (check_label("edif"))
diff --git a/techlibs/intel/Makefile.inc b/techlibs/intel/Makefile.inc
index 429d23677..ec7cea379 100644
--- a/techlibs/intel/Makefile.inc
+++ b/techlibs/intel/Makefile.inc
@@ -8,11 +8,13 @@ $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_map.
$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/cells_sim.v))
$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/cells_sim.v))
$(eval $(call add_share_file,share/intel/cyclonev,techlibs/intel/cyclonev/cells_sim.v))
+$(eval $(call add_share_file,share/intel/cyclone10,techlibs/intel/cyclone10/cells_sim.v))
$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/cells_sim.v))
$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/cells_sim.v))
$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/cells_map.v))
$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/cells_map.v))
$(eval $(call add_share_file,share/intel/cyclonev,techlibs/intel/cyclonev/cells_map.v))
+$(eval $(call add_share_file,share/intel/cyclone10,techlibs/intel/cyclone10/cells_map.v))
$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/cells_map.v))
$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/cells_map.v))
#$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/arith_map.v))
diff --git a/techlibs/intel/cyclone10/cells_arith.v b/techlibs/intel/cyclone10/cells_arith.v
new file mode 100644
index 000000000..5ae8d6cea
--- /dev/null
+++ b/techlibs/intel/cyclone10/cells_arith.v
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ *
+ */
+
+// NOTE: This is still WIP.
+(* techmap_celltype = "$alu" *)
+module _80_altera_a10gx_alu (A, B, CI, BI, X, Y, CO);
+ parameter A_SIGNED = 0;
+ parameter B_SIGNED = 0;
+ parameter A_WIDTH = 1;
+ parameter B_WIDTH = 1;
+ parameter Y_WIDTH = 1;
+
+ input [A_WIDTH-1:0] A;
+ input [B_WIDTH-1:0] B;
+ output [Y_WIDTH-1:0] X, Y;
+
+ input CI, BI;
+ //output [Y_WIDTH-1:0] CO;
+ output CO;
+
+ wire _TECHMAP_FAIL_ = Y_WIDTH <= 4;
+
+ wire [Y_WIDTH-1:0] A_buf, B_buf;
+ \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+ \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+ wire [Y_WIDTH-1:0] AA = A_buf;
+ wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+ //wire [Y_WIDTH:0] C = {CO, CI};
+ wire [Y_WIDTH+1:0] COx;
+ wire [Y_WIDTH+1:0] C = {COx, CI};
+
+ /* Start implementation */
+ (* keep *) cyclone10lp_lcell_comb #(.lut_mask(16'b0000_0000_1010_1010), .sum_lutc_input("cin")) carry_start (.cout(COx[0]), .dataa(C[0]), .datab(1'b1), .datac(1'b1), .datad(1'b1));
+
+ genvar i;
+ generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice
+ if(i==Y_WIDTH-1) begin
+ (* keep *) cyclone10lp_lcell_comb #(.lut_mask(16'b1111_0000_1110_0000), .sum_lutc_input("cin")) carry_end (.combout(COx[Y_WIDTH]), .dataa(1'b1), .datab(1'b1), .datac(1'b1), .datad(1'b1), .cin(C[Y_WIDTH]));
+ assign CO = COx[Y_WIDTH];
+ end
+ else
+ cyclone10lp_lcell_comb #(.lut_mask(16'b1001_0110_1110_1000), .sum_lutc_input("cin")) arith_cell (.combout(Y[i]), .cout(COx[i+1]), .dataa(AA[i]), .datab(BB[i]), .datac(1'b1), .datad(1'b1), .cin(C[i+1]));
+ end: slice
+ endgenerate
+ /* End implementation */
+ assign X = AA ^ BB;
+
+endmodule
diff --git a/techlibs/intel/cyclone10/cells_map.v b/techlibs/intel/cyclone10/cells_map.v
new file mode 100644
index 000000000..8ac5a55ec
--- /dev/null
+++ b/techlibs/intel/cyclone10/cells_map.v
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ *
+ */
+// Normal mode DFF negedge clk, negedge reset
+module \$_DFF_N_ (input D, C, output Q);
+ parameter WYSIWYG="TRUE";
+ dffeas #(.is_wysiwyg(WYSIWYG)) _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";
+ dffeas #(.is_wysiwyg(WYSIWYG)) _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";
+ dffeas #(.is_wysiwyg(WYSIWYG)) _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";
+ wire R_i = ~ R;
+ dffeas #(.is_wysiwyg(WYSIWYG)) _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_PP0 (input D, C, E, R, output Q);
+ parameter WYSIWYG="TRUE";
+ wire E_i = ~ E;
+ dffeas #(.is_wysiwyg(WYSIWYG)) _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);
+ cyclone10lp_io_ibuf _TECHMAP_REPLACE_ (.o(O), .i(I), .ibar(1'b0));
+endmodule
+
+// Output buffer map
+module \$__outpad (input I, output O);
+ cyclone10lp_io_obuf _TECHMAP_REPLACE_ (.o(O), .i(I), .oe(1'b1));
+endmodule
+
+// LUT Map
+/* 0 -> datac
+ 1 -> cin */
+module \$lut (A, Y);
+ parameter WIDTH = 0;
+ parameter LUT = 0;
+ input [WIDTH-1:0] A;
+ output Y;
+ generate
+ if (WIDTH == 1) begin
+ assign Y = ~A[0]; // Not need to spend 1 logic cell for such an easy function
+ end else
+ if (WIDTH == 2) begin
+ cyclone10lp_lcell_comb #(.lut_mask({4{LUT}}),
+ .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y),
+ .dataa(A[0]),
+ .datab(A[1]),
+ .datac(1'b1),
+ .datad(1'b1));
+ end else
+ if(WIDTH == 3) begin
+ cyclone10lp_lcell_comb #(.lut_mask({2{LUT}}),
+ .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y),
+ .dataa(A[0]),
+ .datab(A[1]),
+ .datac(A[2]),
+ .datad(1'b1));
+ end else
+ if(WIDTH == 4) begin
+ cyclone10lp_lcell_comb #(.lut_mask(LUT),
+ .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y),
+ .dataa(A[0]),
+ .datab(A[1]),
+ .datac(A[2]),
+ .datad(A[3]));
+ end else
+ wire _TECHMAP_FAIL_ = 1;
+ endgenerate
+
+endmodule
+
+
diff --git a/techlibs/intel/cyclone10/cells_sim.v b/techlibs/intel/cyclone10/cells_sim.v
new file mode 100644
index 000000000..f5a8aee2b
--- /dev/null
+++ b/techlibs/intel/cyclone10/cells_sim.v
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ *
+ */
+module VCC (output V);
+ assign V = 1'b1;
+endmodule // VCC
+
+module GND (output G);
+ assign G = 1'b0;
+endmodule // GND
+
+/* Altera Cyclone 10 LP devices Input Buffer Primitive */
+module cyclone10lp_io_ibuf
+ (output o, input i, input ibar);
+ assign ibar = ibar;
+ assign o = i;
+endmodule // cyclone10lp_io_ibuf
+
+/* Altera Cyclone 10 LP devices Output Buffer Primitive */
+module cyclone10lp_io_obuf
+ (output o, input i, input oe);
+ assign o = i;
+ assign oe = oe;
+endmodule // cyclone10lp_io_obuf
+
+/* Altera Cyclone IV (E) 4-input non-fracturable LUT Primitive */
+module cyclone10lp_lcell_comb
+ (output combout, cout,
+ input dataa, datab, datac, datad, cin);
+
+ /* Internal parameters which define the behaviour
+ of the LUT primitive.
+ lut_mask define the lut function, can be expressed in 16-digit bin or hex.
+ sum_lutc_input define the type of LUT (combinational | arithmetic).
+ dont_touch for retiming || carry options.
+ lpm_type for WYSIWYG */
+
+ parameter lut_mask = 16'hFFFF;
+ parameter dont_touch = "off";
+ parameter lpm_type = "cyclone10lp_lcell_comb";
+ parameter sum_lutc_input = "datac";
+
+ reg [1:0] lut_type;
+ reg cout_rt;
+ reg combout_rt;
+ wire dataa_w;
+ wire datab_w;
+ wire datac_w;
+ wire datad_w;
+ wire cin_w;
+
+ assign dataa_w = dataa;
+ assign datab_w = datab;
+ assign datac_w = datac;
+ assign datad_w = datad;
+
+ function lut_data;
+ input [15:0] mask;
+ input dataa, datab, datac, datad;
+ reg [7:0] s3;
+ reg [3:0] s2;
+ reg [1:0] s1;
+ begin
+ s3 = datad ? mask[15:8] : mask[7:0];
+ s2 = datac ? s3[7:4] : s3[3:0];
+ s1 = datab ? s2[3:2] : s2[1:0];
+ lut_data = dataa ? s1[1] : s1[0];
+ end
+
+ endfunction
+
+ initial begin
+ if (sum_lutc_input == "datac") lut_type = 0;
+ else
+ if (sum_lutc_input == "cin") lut_type = 1;
+ else begin
+ $error("Error in sum_lutc_input. Parameter %s is not a valid value.\n", sum_lutc_input);
+ $finish();
+ end
+ end
+
+ always @(dataa_w or datab_w or datac_w or datad_w or cin_w) begin
+ if (lut_type == 0) begin // logic function
+ combout_rt = lut_data(lut_mask, dataa_w, datab_w,
+ datac_w, datad_w);
+ end
+ else if (lut_type == 1) begin // arithmetic function
+ combout_rt = lut_data(lut_mask, dataa_w, datab_w,
+ cin_w, datad_w);
+ end
+ cout_rt = lut_data(lut_mask, dataa_w, datab_w, cin_w, 'b0);
+ end
+
+ assign combout = combout_rt & 1'b1;
+ assign cout = cout_rt & 1'b1;
+
+endmodule // cyclone10lp_lcell_comb
+
+/* Altera D Flip-Flop Primitive */
+module dffeas
+ (output q,
+ input d, clk, clrn, prn, ena,
+ input asdata, aload, sclr, sload);
+
+ // Timing simulation is not covered
+ parameter power_up="dontcare";
+ parameter is_wysiwyg="false";
+
+ reg q_tmp;
+ wire reset;
+ reg [7:0] debug_net;
+
+ assign reset = (prn && sclr && ~clrn && ena);
+ assign q = q_tmp & 1'b1;
+
+ always @(posedge clk, posedge aload) begin
+ if(reset) q_tmp <= 0;
+ else q_tmp <= d;
+ end
+ assign q = q_tmp;
+
+endmodule // dffeas
diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc
index 9e4b33601..9b3e92b14 100644
--- a/techlibs/intel/synth_intel.cc
+++ b/techlibs/intel/synth_intel.cc
@@ -127,7 +127,7 @@ struct SynthIntelPass : public ScriptPass {
if (!design->full_selection())
log_cmd_error("This command only operates on fully selected designs!\n");
- if (family_opt != "max10" && family_opt !="a10gx" && family_opt != "cyclonev" && family_opt !="cycloneiv" && family_opt !="cycloneive")
+ if (family_opt != "max10" && family_opt !="a10gx" && family_opt != "cyclonev" && family_opt !="cycloneiv" && family_opt !="cycloneive" && family_opt != "cyclone10")
log_cmd_error("Invalid or not family specified: '%s'\n", family_opt.c_str());
log_header(design, "Executing SYNTH_INTEL pass.\n");
@@ -148,6 +148,8 @@ struct SynthIntelPass : public ScriptPass {
run("read_verilog -sv -lib +/intel/a10gx/cells_sim.v");
else if(check_label("family") && family_opt=="cyclonev")
run("read_verilog -sv -lib +/intel/cyclonev/cells_sim.v");
+ else if(check_label("family") && family_opt=="cyclone10")
+ run("read_verilog -sv -lib +/intel/cyclone10/cells_sim.v");
else if(check_label("family") && family_opt=="cycloneiv")
run("read_verilog -sv -lib +/intel/cycloneiv/cells_sim.v");
else
@@ -211,6 +213,8 @@ struct SynthIntelPass : public ScriptPass {
run("techmap -map +/intel/a10gx/cells_map.v");
else if(family_opt=="cyclonev")
run("techmap -map +/intel/cyclonev/cells_map.v");
+ else if(family_opt=="cyclone10")
+ run("techmap -map +/intel/cyclone10/cells_map.v");
else if(family_opt=="cycloneiv")
run("techmap -map +/intel/cycloneiv/cells_map.v");
else