diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | backends/aiger/aiger.cc | 25 | ||||
-rw-r--r-- | backends/smt2/smtbmc.py | 195 | ||||
-rw-r--r-- | backends/smt2/smtio.py | 12 | ||||
-rw-r--r-- | kernel/mem.cc | 5 | ||||
-rw-r--r-- | kernel/rtlil.cc | 5 | ||||
-rw-r--r-- | misc/create_vcxsrc.sh | 2 | ||||
-rw-r--r-- | passes/techmap/abc9.cc | 8 | ||||
-rw-r--r-- | passes/techmap/abc9_ops.cc | 15 | ||||
-rw-r--r-- | techlibs/gowin/cells_sim.v | 34 |
10 files changed, 230 insertions, 73 deletions
@@ -129,7 +129,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.15+53 +YOSYS_VER := 0.15+73 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 35935b847..547d131ee 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -606,7 +606,7 @@ struct AigerWriter f << stringf("c\nGenerated by %s\n", yosys_version_str); } - void write_map(std::ostream &f, bool verbose_map) + void write_map(std::ostream &f, bool verbose_map, bool no_startoffset) { dict<int, string> input_lines; dict<int, string> init_lines; @@ -627,32 +627,33 @@ struct AigerWriter continue; int a = aig_map.at(sig[i]); + int index = no_startoffset ? i : (wire->start_offset+i); if (verbose_map) - wire_lines[a] += stringf("wire %d %d %s\n", a, wire->start_offset+i, log_id(wire)); + wire_lines[a] += stringf("wire %d %d %s\n", a, index, log_id(wire)); if (wire->port_input) { log_assert((a & 1) == 0); - input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, wire->start_offset+i, log_id(wire)); + input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, index, log_id(wire)); } if (wire->port_output) { int o = ordered_outputs.at(sig[i]); - output_lines[o] += stringf("output %d %d %s\n", o, wire->start_offset+i, log_id(wire)); + output_lines[o] += stringf("output %d %d %s\n", o, index, log_id(wire)); } if (init_inputs.count(sig[i])) { int a = init_inputs.at(sig[i]); log_assert((a & 1) == 0); - init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, wire->start_offset+i, log_id(wire)); + init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, index, log_id(wire)); } if (ordered_latches.count(sig[i])) { int l = ordered_latches.at(sig[i]); if (zinit_mode && (aig_latchinit.at(l) == 1)) - latch_lines[l] += stringf("invlatch %d %d %s\n", l, wire->start_offset+i, log_id(wire)); + latch_lines[l] += stringf("invlatch %d %d %s\n", l, index, log_id(wire)); else - latch_lines[l] += stringf("latch %d %d %s\n", l, wire->start_offset+i, log_id(wire)); + latch_lines[l] += stringf("latch %d %d %s\n", l, index, log_id(wire)); } } } @@ -713,6 +714,9 @@ struct AigerBackend : public Backend { log(" -vmap <filename>\n"); log(" like -map, but more verbose\n"); log("\n"); + log(" -no-startoffset\n"); + log(" make indexes zero based, enable using map files with smt solvers.\n"); + log("\n"); log(" -I, -O, -B, -L\n"); log(" If the design contains no input/output/assert/flip-flop then create one\n"); log(" dummy input/output/bad_state-pin or latch to make the tools reading the\n"); @@ -730,6 +734,7 @@ struct AigerBackend : public Backend { bool omode = false; bool bmode = false; bool lmode = false; + bool no_startoffset = false; std::string map_filename; log_header(design, "Executing AIGER backend.\n"); @@ -762,6 +767,10 @@ struct AigerBackend : public Backend { verbose_map = true; continue; } + if (args[argidx] == "-no-startoffset") { + no_startoffset = true; + continue; + } if (args[argidx] == "-I") { imode = true; continue; @@ -804,7 +813,7 @@ struct AigerBackend : public Backend { mapf.open(map_filename.c_str(), std::ofstream::trunc); if (mapf.fail()) log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno)); - writer.write_map(mapf, verbose_map); + writer.write_map(mapf, verbose_map, no_startoffset); } } } AigerBackend; diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py index 7527f4105..137182f33 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -50,6 +50,7 @@ smtcinit = False smtctop = None noinit = False binarymode = False +keep_going = False so = SmtOpts() @@ -143,7 +144,7 @@ def usage(): --dump-all when using -g or -i, create a dump file for each - step. The character '%' is replaces in all dump + step. The character '%' is replaced in all dump filenames with the step number. --append <num_steps> @@ -153,6 +154,13 @@ def usage(): --binary dump anyconst values as raw bit strings + + --keep-going + continue BMC after the first failed assertion and report + further failed assertions. To output multiple traces + covering all found failed assertions, the character '%' is + replaced in all dump filenames with an increasing number. + """ + so.helpmsg()) sys.exit(1) @@ -161,7 +169,7 @@ try: opts, args = getopt.getopt(sys.argv[1:], so.shortopts + "t:igcm:", so.longopts + ["final-only", "assume-skipped=", "smtc=", "cex=", "aig=", "aig-noheader", "btorwit=", "presat", "dump-vcd=", "dump-vlogtb=", "vlogtb-top=", "dump-smtc=", "dump-all", "noinfo", "append=", - "smtc-init", "smtc-top=", "noinit", "binary"]) + "smtc-init", "smtc-top=", "noinit", "binary", "keep-going"]) except: usage() @@ -234,6 +242,8 @@ for o, a in opts: topmod = a elif o == "--binary": binarymode = True + elif o == "--keep-going": + keep_going = True elif so.handle(o, a): pass else: @@ -341,13 +351,13 @@ for fn in inconstr: assert False -def get_constr_expr(db, state, final=False, getvalues=False): +def get_constr_expr(db, state, final=False, getvalues=False, individual=False): if final: if ("final-%d" % state) not in db: - return ([], [], []) if getvalues else "true" + return ([], [], []) if getvalues or individual else "true" else: if state not in db: - return ([], [], []) if getvalues else "true" + return ([], [], []) if getvalues or individual else "true" netref_regex = re.compile(r'(^|[( ])\[(-?[0-9]+:|)([^\]]*|\S*)\](?=[ )]|$)') @@ -368,15 +378,18 @@ def get_constr_expr(db, state, final=False, getvalues=False): expr_list = list() for loc, expr in db[("final-%d" % state) if final else state]: actual_expr = netref_regex.sub(replace_netref, expr) - if getvalues: + if getvalues or individual: expr_list.append((loc, expr, actual_expr)) else: expr_list.append(actual_expr) - if getvalues: - loc_list, expr_list, acual_expr_list = zip(*expr_list) - value_list = smt.get_list(acual_expr_list) - return loc_list, expr_list, value_list + if getvalues or individual: + loc_list, expr_list, actual_expr_list = zip(*expr_list) + if individual: + return loc_list, expr_list, actual_expr_list + else: + value_list = smt.get_list(actual_expr_list) + return loc_list, expr_list, value_list if len(expr_list) == 0: return "true" @@ -829,7 +842,7 @@ def char_ok_in_verilog(c,i): return False def escape_identifier(identifier): - if type(identifier) is list: + if type(identifier) is list: return map(escape_identifier, identifier) if "." in identifier: return ".".join(escape_identifier(identifier.split("."))) @@ -1071,7 +1084,7 @@ def write_trace(steps_start, steps_stop, index): write_constr_trace(steps_start, steps_stop, index) -def print_failed_asserts_worker(mod, state, path, extrainfo): +def print_failed_asserts_worker(mod, state, path, extrainfo, infomap, infokey=()): assert mod in smt.modinfo found_failed_assert = False @@ -1079,29 +1092,31 @@ def print_failed_asserts_worker(mod, state, path, extrainfo): return for cellname, celltype in smt.modinfo[mod].cells.items(): - if print_failed_asserts_worker(celltype, "(|%s_h %s| %s)" % (mod, cellname, state), path + "." + cellname, extrainfo): + cell_infokey = (mod, cellname, infokey) + if print_failed_asserts_worker(celltype, "(|%s_h %s| %s)" % (mod, cellname, state), path + "." + cellname, extrainfo, infomap, cell_infokey): found_failed_assert = True for assertfun, assertinfo in smt.modinfo[mod].asserts.items(): if smt.get("(|%s| %s)" % (assertfun, state)) in ["false", "#b0"]: - print_msg("Assert failed in %s: %s%s" % (path, assertinfo, extrainfo)) + assert_key = (assertfun, infokey) + print_msg("Assert failed in %s: %s%s%s" % (path, assertinfo, extrainfo, infomap.get(assert_key, ''))) found_failed_assert = True return found_failed_assert -def print_failed_asserts(state, final=False, extrainfo=""): +def print_failed_asserts(state, final=False, extrainfo="", infomap={}): if noinfo: return loc_list, expr_list, value_list = get_constr_expr(constr_asserts, state, final=final, getvalues=True) found_failed_assert = False for loc, expr, value in zip(loc_list, expr_list, value_list): if smt.bv2int(value) == 0: - print_msg("Assert %s failed: %s%s" % (loc, expr, extrainfo)) + print_msg("Assert %s failed: %s%s%s" % (loc, expr, extrainfo, infomap.get(loc, ''))) found_failed_assert = True if not final: - if print_failed_asserts_worker(topmod, "s%d" % state, topmod, extrainfo): + if print_failed_asserts_worker(topmod, "s%d" % state, topmod, extrainfo, infomap): found_failed_assert = True return found_failed_assert @@ -1148,6 +1163,43 @@ def get_cover_list(mod, base): return cover_expr, cover_desc + +def get_assert_map(mod, base, path, key_base=()): + assert mod in smt.modinfo + + assert_map = dict() + + for expr, desc in smt.modinfo[mod].asserts.items(): + assert_map[(expr, key_base)] = ("(|%s| %s)" % (expr, base), path, desc) + + for cell, submod in smt.modinfo[mod].cells.items(): + assert_map.update(get_assert_map(submod, "(|%s_h %s| %s)" % (mod, cell, base), path + "." + cell, (mod, cell, key_base))) + + return assert_map + + +def get_assert_keys(): + keys = set() + keys.update(get_assert_map(topmod, 'state', topmod).keys()) + for step_constr_asserts in constr_asserts.values(): + keys.update(loc for loc, expr in step_constr_asserts) + + return keys + + +def get_active_assert_map(step, active): + assert_map = dict() + for key, assert_data in get_assert_map(topmod, "s%s" % step, topmod).items(): + if key in active: + assert_map[key] = assert_data + + for loc, expr, actual_expr in zip(*get_constr_expr(constr_asserts, step, individual=True)): + if loc in active: + assert_map[loc] = (actual_expr, None, (expr, loc)) + + return assert_map + + states = list() asserts_antecedent_cache = [list()] asserts_consequent_cache = [list()] @@ -1457,6 +1509,10 @@ elif covermode: print_msg("Unreached cover statement at %s." % cover_desc[i]) else: # not tempind, covermode + active_assert_keys = get_assert_keys() + failed_assert_infomap = dict() + traceidx = 0 + step = 0 retstatus = "PASSED" while step < num_steps: @@ -1510,44 +1566,83 @@ else: # not tempind, covermode break if not final_only: - if last_check_step == step: - print_msg("Checking assertions in step %d.." % (step)) - else: - print_msg("Checking assertions in steps %d to %d.." % (step, last_check_step)) - smt_push() - - smt_assert("(not (and %s))" % " ".join(["(|%s_a| s%d)" % (topmod, i) for i in range(step, last_check_step+1)] + - [get_constr_expr(constr_asserts, i) for i in range(step, last_check_step+1)])) - - if smt_check_sat() == "sat": - print("%s BMC failed!" % smt.timestamp()) - if append_steps > 0: - for i in range(last_check_step+1, last_check_step+1+append_steps): - print_msg("Appending additional step %d." % i) - smt_state(i) - smt_assert_antecedent("(not (|%s_is| s%d))" % (topmod, i)) - smt_assert_consequent("(|%s_u| s%d)" % (topmod, i)) - smt_assert_antecedent("(|%s_h| s%d)" % (topmod, i)) - smt_assert_antecedent("(|%s_t| s%d s%d)" % (topmod, i-1, i)) - smt_assert_consequent(get_constr_expr(constr_assumes, i)) - print_msg("Re-solving with appended steps..") - if smt_check_sat() == "unsat": - print("%s Cannot append steps without violating assumptions!" % smt.timestamp()) - retstatus = "FAILED" - break - print_anyconsts(step) + recheck_current_step = True + while recheck_current_step: + recheck_current_step = False + if last_check_step == step: + print_msg("Checking assertions in step %d.." % (step)) + else: + print_msg("Checking assertions in steps %d to %d.." % (step, last_check_step)) + smt_push() + + active_assert_maps = dict() + active_assert_exprs = list() for i in range(step, last_check_step+1): - print_failed_asserts(i) - write_trace(0, last_check_step+1+append_steps, '%') - retstatus = "FAILED" - break + assert_expr_map = get_active_assert_map(i, active_assert_keys) + active_assert_maps[i] = assert_expr_map + active_assert_exprs.extend(assert_data[0] for assert_data in assert_expr_map.values()) - smt_pop() + if active_assert_exprs: + if len(active_assert_exprs) == 1: + active_assert_expr = active_assert_exprs[0] + else: + active_assert_expr = "(and %s)" % " ".join(active_assert_exprs) + + smt_assert("(not %s)" % active_assert_expr) + else: + smt_assert("false") + + + if smt_check_sat() == "sat": + if retstatus != "FAILED": + print("%s BMC failed!" % smt.timestamp()) + + if append_steps > 0: + for i in range(last_check_step+1, last_check_step+1+append_steps): + print_msg("Appending additional step %d." % i) + smt_state(i) + smt_assert_antecedent("(not (|%s_is| s%d))" % (topmod, i)) + smt_assert_consequent("(|%s_u| s%d)" % (topmod, i)) + smt_assert_antecedent("(|%s_h| s%d)" % (topmod, i)) + smt_assert_antecedent("(|%s_t| s%d s%d)" % (topmod, i-1, i)) + smt_assert_consequent(get_constr_expr(constr_assumes, i)) + print_msg("Re-solving with appended steps..") + if smt_check_sat() == "unsat": + print("%s Cannot append steps without violating assumptions!" % smt.timestamp()) + retstatus = "FAILED" + break + print_anyconsts(step) + + for i in range(step, last_check_step+1): + print_failed_asserts(i, infomap=failed_assert_infomap) + + if keep_going: + for i in range(step, last_check_step+1): + for key, (expr, path, desc) in active_assert_maps[i].items(): + if key in active_assert_keys and not smt.bv2int(smt.get(expr)): + failed_assert_infomap[key] = " [failed before]" + + active_assert_keys.remove(key) + + if active_assert_keys: + recheck_current_step = True + + write_trace(0, last_check_step+1+append_steps, "%d" % traceidx if keep_going else '%') + traceidx += 1 + retstatus = "FAILED" + + smt_pop() + if recheck_current_step: + print_msg("Checking remaining assertions..") + + if retstatus == "FAILED" and not (keep_going and active_assert_keys): + break if (constr_final_start is not None) or (last_check_step+1 != num_steps): for i in range(step, last_check_step+1): - smt_assert("(|%s_a| s%d)" % (topmod, i)) - smt_assert(get_constr_expr(constr_asserts, i)) + assert_expr_map = get_active_assert_map(i, active_assert_keys) + for assert_data in assert_expr_map.values(): + smt_assert(assert_data[0]) if constr_final_start is not None: for i in range(step, last_check_step+1): diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 3d458e6cf..14feec30d 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -20,7 +20,7 @@ import sys, re, os, signal import subprocess if os.name == "posix": import resource -from copy import deepcopy +from copy import copy from select import select from time import time from queue import Queue, Empty @@ -301,7 +301,7 @@ class SmtIo: key = tuple(stmt) if key not in self.unroll_cache: - decl = deepcopy(self.unroll_decls[key[0]]) + decl = copy(self.unroll_decls[key[0]]) self.unroll_cache[key] = "|UNROLL#%d|" % self.unroll_idcnt decl[1] = self.unroll_cache[key] @@ -442,10 +442,10 @@ class SmtIo: if stmt == "(push 1)": self.unroll_stack.append(( - deepcopy(self.unroll_sorts), - deepcopy(self.unroll_objs), - deepcopy(self.unroll_decls), - deepcopy(self.unroll_cache), + copy(self.unroll_sorts), + copy(self.unroll_objs), + copy(self.unroll_decls), + copy(self.unroll_cache), )) if stmt == "(pop 1)": diff --git a/kernel/mem.cc b/kernel/mem.cc index 059f8f934..e5e855ef7 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -1633,7 +1633,10 @@ void Mem::emulate_read_first(FfInitVals *initvals) { ff_en.pol_clk = port.clk_polarity; ff_en.sig_d = compressed.first; ff_en.sig_q = new_en;; - ff_en.val_init = Const(State::S0, ff_en.width); + if (inits.empty()) + ff_en.val_init = Const(State::Sx, ff_en.width); + else + ff_en.val_init = Const(State::S0, ff_en.width); ff_en.emit(); port.data = new_data; port.addr = new_addr; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a89edd992..72dcb89af 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -207,6 +207,7 @@ RTLIL::Const::Const() RTLIL::Const::Const(std::string str) { flags = RTLIL::CONST_FLAG_STRING; + bits.reserve(str.size() * 8); for (int i = str.size()-1; i >= 0; i--) { unsigned char ch = str[i]; for (int j = 0; j < 8; j++) { @@ -219,6 +220,7 @@ RTLIL::Const::Const(std::string str) RTLIL::Const::Const(int val, int width) { flags = RTLIL::CONST_FLAG_NONE; + bits.reserve(width); for (int i = 0; i < width; i++) { bits.push_back((val & 1) != 0 ? State::S1 : State::S0); val = val >> 1; @@ -228,6 +230,7 @@ RTLIL::Const::Const(int val, int width) RTLIL::Const::Const(RTLIL::State bit, int width) { flags = RTLIL::CONST_FLAG_NONE; + bits.reserve(width); for (int i = 0; i < width; i++) bits.push_back(bit); } @@ -235,6 +238,7 @@ RTLIL::Const::Const(RTLIL::State bit, int width) RTLIL::Const::Const(const std::vector<bool> &bits) { flags = RTLIL::CONST_FLAG_NONE; + this->bits.reserve(bits.size()); for (const auto &b : bits) this->bits.emplace_back(b ? State::S1 : State::S0); } @@ -242,6 +246,7 @@ RTLIL::Const::Const(const std::vector<bool> &bits) RTLIL::Const::Const(const RTLIL::Const &c) { flags = c.flags; + this->bits.reserve(c.size()); for (const auto &b : c.bits) this->bits.push_back(b); } diff --git a/misc/create_vcxsrc.sh b/misc/create_vcxsrc.sh index e3c1ad991..8b39d59e3 100644 --- a/misc/create_vcxsrc.sh +++ b/misc/create_vcxsrc.sh @@ -7,7 +7,7 @@ gitsha="$3" rm -rf YosysVS-Tpl-v2.zip YosysVS wget https://yosyshq.net/yosys/nogit/YosysVS-Tpl-v2.zip -wget https://zlib.net/zlib-1.2.11.tar.gz +wget https://www.zlib.net/fossils/zlib-1.2.11.tar.gz unzip YosysVS-Tpl-v2.zip rm -f YosysVS-Tpl-v2.zip diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 1f00fc3e7..fe0802d70 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -74,12 +74,18 @@ struct Abc9Pass : public ScriptPass /* Comm3 */ "&synch2 -K 6 -C 500; &if -m "/*"-E 5"*/" {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save; "\ "&load"; - // Based on ABC's &flow3 + // Based on ABC's &flow3 -m RTLIL::constpad["abc9.script.flow3"] = "+&scorr; &sweep;" \ "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} {R} -v; &save; &load;"\ "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} {R} -v; &save; &load;"\ "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &save; &load;"\ "&mfs"; + // As above, but with &mfs calls as in the original &flow3 + RTLIL::constpad["abc9.script.flow3mfs"] = "+&scorr; &sweep;" \ + "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} {R} -v; &mfs; &save; &load;"\ + "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &mfs; &save; &load;"\ + "&mfs"; } void help() override { diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 29fe74ec7..b8975f178 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -167,10 +167,6 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) derived_module = inst_module; } else { - // Check potential for any one of those three - // (since its value may depend on a parameter, but not its existence) - if (!inst_module->has_attribute(ID::abc9_flop) && !inst_module->has_attribute(ID::abc9_box) && !inst_module->get_bool_attribute(ID::abc9_bypass)) - continue; derived_type = inst_module->derive(design, cell->parameters); derived_module = design->module(derived_type); } @@ -180,7 +176,16 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) continue; } else { - if (!derived_module->get_bool_attribute(ID::abc9_box) && !derived_module->get_bool_attribute(ID::abc9_bypass)) { + bool has_timing = false; + for (auto derived_cell : derived_module->cells()) { + if (derived_cell->type.in(ID($specify2), ID($specify3), ID($specrule))) { + // If the module contains timing; then we potentially care about deriving its content too, + // as timings (or associated port widths) could be dependent on parameters. + has_timing = true; + break; + } + } + if (!derived_module->get_bool_attribute(ID::abc9_box) && !derived_module->get_bool_attribute(ID::abc9_bypass) && !has_timing) { if (unmap_design->module(derived_type)) { // If derived_type is present in unmap_design, it means that it was processed previously, but found to be incompatible -- e.g. if // it contained a non-zero initial state. In this case, continue to replace the cell type/parameters so that it has the same properties diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 64b76139c..736aa0707 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -1551,3 +1551,37 @@ parameter CLKOUTD3_SRC = "CLKOUT"; // CLKOUT, CLKOUTP parameter DEVICE = "GW1N-1"; // "GW1N-1", "GW1N-4", "GW1N-9", "GW1NR-4", "GW1NR-9", "GW1N-4B", "GW1NR-4B", "GW1NS-2", "GW1NS-2C", "GW1NZ-1", "GW1NSR-2", "GW1NSR-2C", "GW1N-1S", "GW1NSE-2C", "GW1NRF-4B", "GW1N-9C", "GW1NR-9C", "GW1N-4C", "GW1NR-4C" endmodule + +(* blackbox *) +module OSC(OSCOUT); +output OSCOUT; + +parameter FREQ_DIV = 100; +parameter DEVICE = "GW1N-4"; +endmodule + +(* blackbox *) +module OSCZ(OSCOUT, OSCEN); +input OSCEN; + +output OSCOUT; + +parameter FREQ_DIV = 100; +endmodule + +(* blackbox *) +module OSCF(OSCOUT, OSCOUT30M, OSCEN); +input OSCEN; + +output OSCOUT; +output OSCOUT30M; + +parameter FREQ_DIV = 100; +endmodule + +(* blackbox *) +module OSCH(OSCOUT); +output OSCOUT; + +parameter FREQ_DIV = 96; +endmodule |