diff options
30 files changed, 749 insertions, 52 deletions
@@ -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 |