From c00a29296c8d3446c7cfe253080c7e33358219b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 1 Mar 2021 20:01:39 +0100 Subject: sim: Avoid a crash on empty cell connection. Fixes #2513. --- passes/sat/sim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/sat') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 3ba66bd33..922be886c 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -271,7 +271,7 @@ struct SimInstance { auto child = children.at(cell); for (auto &conn: cell->connections()) - if (cell->input(conn.first)) { + if (cell->input(conn.first) && GetSize(conn.second)) { Const value = get_state(conn.second); child->set_state(child->module->wire(conn.first), value); } -- cgit v1.2.3 From c4cc888b2c51a6507b73fdcde1dc61c37384105d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 19:14:13 +0200 Subject: kernel/rtlil: Extract some helpers for checking memory cell types. There will soon be more (versioned) memory cells, so handle passes that only care if a cell is memory-related by a simple helper call instead of a hardcoded list. --- passes/sat/sim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/sat') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 922be886c..2e7a92cec 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -164,7 +164,7 @@ struct SimInstance ff_database[cell] = ff; } - if (cell->type.in(ID($mem), ID($meminit), ID($memwr), ID($memrd))) + if (cell->is_mem_cell()) { mem_cells[cell] = cell->parameters.at(ID::MEMID).decode_string(); } -- cgit v1.2.3 From 1c903d3e4742c015dc8f0b3b5d8c8c1895459822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 01:12:19 +0200 Subject: sim: Add wide port support. --- passes/sat/sim.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'passes/sat') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 2e7a92cec..684e00382 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -334,7 +334,7 @@ struct SimInstance { auto &port = mem.rd_ports[port_idx]; Const addr = get_state(port.addr); - Const data = Const(State::Sx, mem.width); + Const data = Const(State::Sx, mem.width << port.wide_log2); if (port.clk_enable) log_error("Memory %s.%s has clocked read ports. Run 'memory' with -nordff.\n", log_id(module), log_id(mem.memid)); @@ -342,7 +342,7 @@ struct SimInstance if (addr.is_fully_def()) { int index = addr.as_int() - mem.start_offset; if (index >= 0 && index < mem.size) - data = mdb.data.extract(index*mem.width, mem.width); + data = mdb.data.extract(index*mem.width, mem.width << port.wide_log2); } set_state(port.data, data); @@ -457,7 +457,7 @@ struct SimInstance { int index = addr.as_int() - mem.start_offset; if (index >= 0 && index < mem.size) - for (int i = 0; i < mem.width; i++) + for (int i = 0; i < (mem.width << port.wide_log2); i++) if (enable[i] == State::S1 && mdb.data.bits.at(index*mem.width+i) != data[i]) { mdb.data.bits.at(index*mem.width+i) = data[i]; dirty_memories.insert(mem.memid); -- cgit v1.2.3 From 72787f52fc31954e4b7dc3dc34d86705fc4e9dd1 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Tue, 8 Jun 2021 00:39:36 +0200 Subject: Fixing old e-mail addresses and deadnames s/((Claire|Xen|Xenia|Clifford)\s+)+(Wolf|Xen)\s+<(claire|clifford)@(symbioticeda.com|clifford.at|yosyshq.com)>/Claire Xenia Wolf /gi; s/((Nina|Nak|N\.)\s+)+Engelhardt\s+/N. Engelhardt /gi; s/((David)\s+)+Shah\s+<(dave|david)@(symbioticeda.com|yosyshq.com|ds0.me)>/David Shah /gi; s/((Miodrag)\s+)+Milanovic\s+<(miodrag|micko)@(symbioticeda.com|yosyshq.com)>/Miodrag Milanovic /gi; s,https?://www.clifford.at/yosys/,http://yosyshq.net/yosys/,g; --- passes/sat/assertpmux.cc | 2 +- passes/sat/async2sync.cc | 2 +- passes/sat/clk2fflogic.cc | 2 +- passes/sat/cutpoint.cc | 2 +- passes/sat/eval.cc | 4 ++-- passes/sat/expose.cc | 2 +- passes/sat/fmcombine.cc | 2 +- passes/sat/fminit.cc | 2 +- passes/sat/freduce.cc | 2 +- passes/sat/miter.cc | 2 +- passes/sat/mutate.cc | 2 +- passes/sat/sat.cc | 2 +- passes/sat/sim.cc | 2 +- passes/sat/supercover.cc | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) (limited to 'passes/sat') diff --git a/passes/sat/assertpmux.cc b/passes/sat/assertpmux.cc index f31b78804..abdcb2240 100644 --- a/passes/sat/assertpmux.cc +++ b/passes/sat/assertpmux.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index 3fa5a614c..a2b51677e 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index cbf7c5435..062083972 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index 6fc267d51..bca6a5ec6 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 085e7c5b8..056115031 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,7 +18,7 @@ */ // [[CITE]] VlogHammer Verilog Regression Test Suite -// http://www.clifford.at/yosys/vloghammer.html +// http://yosyshq.net/yosys/vloghammer.html #include "kernel/register.h" #include "kernel/celltypes.h" diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 2c65821cf..e7ec29ee4 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/fmcombine.cc b/passes/sat/fmcombine.cc index cb49edac3..e15bdf6a8 100644 --- a/passes/sat/fmcombine.cc +++ b/passes/sat/fmcombine.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/fminit.cc b/passes/sat/fminit.cc index c72e62548..5f4ec0068 100644 --- a/passes/sat/fminit.cc +++ b/passes/sat/fminit.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index f87b85da9..52e80f667 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index fe4a819f3..37efadfbd 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/mutate.cc b/passes/sat/mutate.cc index 95e0e0944..42eb0c6d0 100644 --- a/passes/sat/mutate.cc +++ b/passes/sat/mutate.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 9fdac6147..df2725b3c 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 684e00382..630e1aaa1 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/supercover.cc b/passes/sat/supercover.cc index aacc044fb..38dbd3cf9 100644 --- a/passes/sat/supercover.cc +++ b/passes/sat/supercover.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above -- cgit v1.2.3 From 0ada13cbe2f8e3c8568bc7e6731be9edb4c46e47 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 9 Jun 2021 12:16:56 +0200 Subject: Use HTTPS for website links, gatecat email git ls-tree -r --name-only HEAD | xargs sed -i -rf ~/fixemails.sed s/((Claire|Xen|Xenia|Clifford)\s+)+(Wolf|Xen)\s+<(claire|clifford)@(symbioticeda.com|clifford.at|yosyshq.com)>/Claire Xenia Wolf /gi; s/((Nina|Nak|N\.)\s+)+Engelhardt\s+/N. Engelhardt /gi; s/((David)\s+)+(Shah|gatecat)\s+<(dave|david|gatecat)@(symbioticeda.com|yosyshq.com|ds0.me)>/gatecat /gi; s/((Miodrag)\s+)+Milanovic\s+<(miodrag|micko)@(symbioticeda.com|yosyshq.com)>/Miodrag Milanovic /gi; s,https?://www.clifford.at/yosys/|http://yosyshq.net/yosys/,https://yosyshq.net/yosys/,g; --- passes/sat/eval.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/sat') diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 056115031..05879426e 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -18,7 +18,7 @@ */ // [[CITE]] VlogHammer Verilog Regression Test Suite -// http://yosyshq.net/yosys/vloghammer.html +// https://yosyshq.net/yosys/vloghammer.html #include "kernel/register.h" #include "kernel/celltypes.h" -- cgit v1.2.3 From 19720b970dff017c47805e37745b9fcf29843c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 21 May 2021 02:26:52 +0200 Subject: memory: Introduce $meminit_v2 cell, with EN input. --- passes/sat/sim.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'passes/sat') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 630e1aaa1..4e158da62 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -559,6 +559,7 @@ struct SimInstance MemInit minit; minit.addr = mem.mem->start_offset; minit.data = mem.data; + minit.en = Const(State::S1, mem.mem->width); mem.mem->inits.push_back(minit); mem.mem->emit(); } -- cgit v1.2.3 From 63b9df8693840d17def8abcb0e848112283b0231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 1 Oct 2021 23:50:48 +0200 Subject: kernel/ff: Refactor FfData to enable FFs with async load. - *_en is split into *_ce (clock enable) and *_aload (async load aka latch gate enable), so both can be present at once - has_d is removed - has_gclk is added (to have a clear marker for $ff) - d_is_const and val_d leftovers are removed - async2sync, clk2fflogic, opt_dff are updated to operate correctly on FFs with async load --- passes/sat/async2sync.cc | 61 +++++++++++++++++++++++++++++++++++------------ passes/sat/clk2fflogic.cc | 34 +++++++++++++------------- 2 files changed, 64 insertions(+), 31 deletions(-) (limited to 'passes/sat') diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index a2b51677e..f1b93d084 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -41,8 +41,6 @@ struct Async2syncPass : public Pass { log("reset value in the next cycle regardless of the data-in value at the time of\n"); log("the clock edge.\n"); log("\n"); - log("Currently only $adff, $dffsr, and $dlatch cells are supported by this pass.\n"); - log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { @@ -74,14 +72,11 @@ struct Async2syncPass : public Pass { FfData ff(&initvals, cell); // Skip for $_FF_ and $ff cells. - if (ff.has_d && !ff.has_clk && !ff.has_en) + if (ff.has_gclk) continue; if (ff.has_clk) { - if (!ff.has_sr && !ff.has_arst) - continue; - if (ff.has_sr) { ff.unmap_ce_srst(module); @@ -128,6 +123,39 @@ struct Async2syncPass : public Pass { ff.sig_d = new_d; ff.sig_q = new_q; ff.has_sr = false; + } else if (ff.has_aload) { + ff.unmap_ce_srst(module); + + log("Replacing %s.%s (%s): ALOAD=%s, AD=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_d), log_signal(ff.sig_q)); + + initvals.remove_init(ff.sig_q); + + Wire *new_d = module->addWire(NEW_ID, ff.width); + Wire *new_q = module->addWire(NEW_ID, ff.width); + + if (ff.pol_aload) { + if (!ff.is_fine) { + module->addMux(NEW_ID, new_q, ff.sig_ad, ff.sig_aload, ff.sig_q); + module->addMux(NEW_ID, ff.sig_d, ff.sig_ad, ff.sig_aload, new_d); + } else { + module->addMuxGate(NEW_ID, new_q, ff.sig_ad, ff.sig_aload, ff.sig_q); + module->addMuxGate(NEW_ID, ff.sig_d, ff.sig_ad, ff.sig_aload, new_d); + } + } else { + if (!ff.is_fine) { + module->addMux(NEW_ID, ff.sig_ad, new_q, ff.sig_aload, ff.sig_q); + module->addMux(NEW_ID, ff.sig_ad, ff.sig_d, ff.sig_aload, new_d); + } else { + module->addMuxGate(NEW_ID, ff.sig_ad, new_q, ff.sig_aload, ff.sig_q); + module->addMuxGate(NEW_ID, ff.sig_ad, ff.sig_d, ff.sig_aload, new_d); + } + } + + ff.sig_d = new_d; + ff.sig_q = new_q; + ff.has_aload = false; } else if (ff.has_arst) { ff.unmap_srst(module); @@ -154,9 +182,12 @@ struct Async2syncPass : public Pass { ff.sig_q = new_q; ff.has_arst = false; ff.has_srst = true; + ff.ce_over_srst = false; ff.val_srst = ff.val_arst; ff.sig_srst = ff.sig_arst; ff.pol_srst = ff.pol_arst; + } else { + continue; } } else @@ -164,25 +195,25 @@ struct Async2syncPass : public Pass { // Latch. log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_en), log_signal(ff.sig_d), log_signal(ff.sig_q)); + log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); initvals.remove_init(ff.sig_q); Wire *new_q = module->addWire(NEW_ID, ff.width); Wire *new_d; - if (ff.has_d) { + if (ff.has_aload) { new_d = module->addWire(NEW_ID, ff.width); - if (ff.pol_en) { + if (ff.pol_aload) { if (!ff.is_fine) - module->addMux(NEW_ID, new_q, ff.sig_d, ff.sig_en, new_d); + module->addMux(NEW_ID, new_q, ff.sig_ad, ff.sig_aload, new_d); else - module->addMuxGate(NEW_ID, new_q, ff.sig_d, ff.sig_en, new_d); + module->addMuxGate(NEW_ID, new_q, ff.sig_ad, ff.sig_aload, new_d); } else { if (!ff.is_fine) - module->addMux(NEW_ID, ff.sig_d, new_q, ff.sig_en, new_d); + module->addMux(NEW_ID, ff.sig_ad, new_q, ff.sig_aload, new_d); else - module->addMuxGate(NEW_ID, ff.sig_d, new_q, ff.sig_en, new_d); + module->addMuxGate(NEW_ID, ff.sig_ad, new_q, ff.sig_aload, new_d); } } else { new_d = new_q; @@ -231,10 +262,10 @@ struct Async2syncPass : public Pass { ff.sig_d = new_d; ff.sig_q = new_q; - ff.has_en = false; + ff.has_aload = false; ff.has_arst = false; ff.has_sr = false; - ff.has_d = true; + ff.has_gclk = true; } IdString name = cell->name; diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index 062083972..d90206b46 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -148,7 +148,7 @@ struct Clk2fflogicPass : public Pass { if (RTLIL::builtin_ff_cell_types().count(cell->type)) { FfData ff(&initvals, cell); - if (ff.has_d && !ff.has_clk && !ff.has_en) { + if (ff.has_gclk) { // Already a $ff or $_FF_ cell. continue; } @@ -202,25 +202,27 @@ struct Clk2fflogicPass : public Pass { qval = module->Mux(NEW_ID, past_q, past_d, clock_edge); else qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge); - } else if (ff.has_d) { - - log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_en), log_signal(ff.sig_d), log_signal(ff.sig_q)); + } else { + if (ff.has_aload) { + log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); + } else { + // $sr. + log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); + } + qval = past_q; + } - SigSpec sig_en = wrap_async_control(module, ff.sig_en, ff.pol_en); + if (ff.has_aload) { + SigSpec sig_aload = wrap_async_control(module, ff.sig_aload, ff.pol_aload); if (!ff.is_fine) - qval = module->Mux(NEW_ID, past_q, ff.sig_d, sig_en); + qval = module->Mux(NEW_ID, qval, ff.sig_ad, sig_aload); else - qval = module->MuxGate(NEW_ID, past_q, ff.sig_d, sig_en); - } else { - - log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); - - qval = past_q; + qval = module->MuxGate(NEW_ID, qval, ff.sig_ad, sig_aload); } if (ff.has_sr) { -- cgit v1.2.3 From 4e70c3077562e511d6f840c91dd30ade87d66517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 6 Oct 2021 22:16:55 +0200 Subject: FfData: some refactoring. - FfData now keeps track of the module and underlying cell, if any (so calling emit on FfData created from a cell will replace the existing cell) - FfData implementation is split off to its own .cc file for faster compilation - the "flip FF data sense by inserting inverters in front and after" functionality that zinit uses is moved onto FfData class and beefed up to have dffsr support, to support more use cases --- passes/sat/async2sync.cc | 11 ++++------- passes/sat/clk2fflogic.cc | 37 ++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 26 deletions(-) (limited to 'passes/sat') diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index f1b93d084..46c76eba9 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -78,7 +78,7 @@ struct Async2syncPass : public Pass { if (ff.has_clk) { if (ff.has_sr) { - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); log("Replacing %s.%s (%s): SET=%s, CLR=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), @@ -124,7 +124,7 @@ struct Async2syncPass : public Pass { ff.sig_q = new_q; ff.has_sr = false; } else if (ff.has_aload) { - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); log("Replacing %s.%s (%s): ALOAD=%s, AD=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), @@ -157,7 +157,7 @@ struct Async2syncPass : public Pass { ff.sig_q = new_q; ff.has_aload = false; } else if (ff.has_arst) { - ff.unmap_srst(module); + ff.unmap_srst(); log("Replacing %s.%s (%s): ARST=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), @@ -267,10 +267,7 @@ struct Async2syncPass : public Pass { ff.has_sr = false; ff.has_gclk = true; } - - IdString name = cell->name; - module->remove(cell); - ff.emit(module, name); + ff.emit(); } } } diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index d90206b46..a292941c8 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -153,6 +153,23 @@ struct Clk2fflogicPass : public Pass { continue; } + if (ff.has_clk) { + log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_clk), log_signal(ff.sig_d), log_signal(ff.sig_q)); + } else if (ff.has_aload) { + log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); + } else { + // $sr. + log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); + } + + ff.remove(); + Wire *past_q = module->addWire(NEW_ID, ff.width); if (!ff.is_fine) { module->addFf(NEW_ID, ff.sig_q, past_q); @@ -163,7 +180,7 @@ struct Clk2fflogicPass : public Pass { initvals.set_init(past_q, ff.val_init); if (ff.has_clk) { - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); Wire *past_clk = module->addWire(NEW_ID); initvals.set_init(past_clk, ff.pol_clk ? State::S1 : State::S0); @@ -173,10 +190,6 @@ struct Clk2fflogicPass : public Pass { else module->addFfGate(NEW_ID, ff.sig_clk, past_clk); - log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_clk), log_signal(ff.sig_d), log_signal(ff.sig_q)); - SigSpec clock_edge_pattern; if (ff.pol_clk) { @@ -203,16 +216,6 @@ struct Clk2fflogicPass : public Pass { else qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge); } else { - if (ff.has_aload) { - log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); - } else { - // $sr. - log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); - } qval = past_q; } @@ -246,10 +249,6 @@ struct Clk2fflogicPass : public Pass { } else { module->connect(ff.sig_q, qval); } - - initvals.remove_init(ff.sig_q); - module->remove(cell); - continue; } } } -- cgit v1.2.3 From ccfc00705a1658260e792e9604ae5319ec7b7c2a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 26 Jan 2022 09:26:19 +0100 Subject: Add ability to write to FST file --- passes/sat/sim.cc | 120 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 109 insertions(+), 11 deletions(-) (limited to 'passes/sat') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 4e158da62..ba7519be5 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -21,6 +21,7 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" #include "kernel/mem.h" +#include "libs/fst/fstapi.h" #include @@ -92,6 +93,7 @@ struct SimInstance std::vector memories; dict> vcd_database; + dict> fst_database; SimInstance(SimShared *shared, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) : shared(shared), module(module), instance(instance), parent(parent), sigmap(module) @@ -616,12 +618,60 @@ struct SimInstance for (auto child : children) child.second->write_vcd_step(f); } + + void write_fst_header(struct fstContext *f) + { + fstWriterSetScope(f, FST_ST_VCD_MODULE, stringf("%s",log_id(name())).c_str(), nullptr); + for (auto wire : module->wires()) + { + if (shared->hide_internal && wire->name[0] == '$') + continue; + + fstHandle id = fstWriterCreateVar(f, FST_VT_VCD_WIRE, FST_VD_IMPLICIT, GetSize(wire), + stringf("%s%s", wire->name[0] == '$' ? "\\" : "", log_id(wire)).c_str(), 0); + fst_database[wire] = make_pair(id, Const()); + } + + for (auto child : children) + child.second->write_fst_header(f); + + fstWriterSetUpscope(f); + } + + void write_fst_step(struct fstContext *f) + { + for (auto &it : fst_database) + { + Wire *wire = it.first; + Const value = get_state(wire); + fstHandle id = it.second.first; + + if (it.second.second == value) + continue; + + it.second.second = value; + std::stringstream ss; + for (int i = GetSize(value)-1; i >= 0; i--) { + switch (value[i]) { + case State::S0: ss << "0"; break; + case State::S1: ss << "1"; break; + case State::Sx: ss << "x"; break; + default: ss << "z"; + } + } + fstWriterEmitValueChange(f, id, ss.str().c_str()); + } + + for (auto child : children) + child.second->write_fst_step(f); + } }; struct SimWorker : SimShared { SimInstance *top = nullptr; std::ofstream vcdfile; + struct fstContext *fstfile = nullptr; pool clock, clockn, reset, resetn; std::string timescale; @@ -632,9 +682,6 @@ struct SimWorker : SimShared void write_vcd_header() { - if (!vcdfile.is_open()) - return; - vcdfile << stringf("$version %s $end\n", yosys_version_str); std::time_t t = std::time(nullptr); @@ -654,13 +701,53 @@ struct SimWorker : SimShared void write_vcd_step(int t) { - if (!vcdfile.is_open()) - return; - vcdfile << stringf("#%d\n", t); top->write_vcd_step(vcdfile); } + void write_fst_header() + { + std::time_t t = std::time(nullptr); + fstWriterSetDate(fstfile, asctime(std::localtime(&t))); + fstWriterSetVersion(fstfile, yosys_version_str); + if (!timescale.empty()) + fstWriterSetTimescaleFromString(fstfile, timescale.c_str()); + + fstWriterSetPackType(fstfile, FST_WR_PT_FASTLZ); + fstWriterSetRepackOnClose(fstfile, 1); + + top->write_fst_header(fstfile); + } + + void write_fst_step(int t) + { + fstWriterEmitTimeChange(fstfile, t); + + top->write_fst_step(fstfile); + } + + void write_output_header() + { + if (vcdfile.is_open()) + write_vcd_header(); + if (fstfile) + write_fst_header(); + } + + void write_output_step(int t) + { + if (vcdfile.is_open()) + write_vcd_step(t); + if (fstfile) + write_fst_step(t); + } + + void write_output_end() + { + if (fstfile) + fstWriterClose(fstfile); + } + void update() { while (1) @@ -714,8 +801,8 @@ struct SimWorker : SimShared update(); - write_vcd_header(); - write_vcd_step(0); + write_output_header(); + write_output_step(0); for (int cycle = 0; cycle < numcycles; cycle++) { @@ -726,7 +813,7 @@ struct SimWorker : SimShared set_inports(clockn, State::S1); update(); - write_vcd_step(10*cycle + 5); + write_output_step(10*cycle + 5); if (debug) log("\n===== %d =====\n", 10*cycle + 10); @@ -742,10 +829,12 @@ struct SimWorker : SimShared } update(); - write_vcd_step(10*cycle + 10); + write_output_step(10*cycle + 10); } - write_vcd_step(10*numcycles + 2); + write_output_step(10*numcycles + 2); + + write_output_end(); if (writeback) { pool wbmods; @@ -767,6 +856,9 @@ struct SimPass : public Pass { log(" -vcd \n"); log(" write the simulation results to the given VCD file\n"); log("\n"); + log(" -fst \n"); + log(" write the simulation results to the given FST file\n"); + log("\n"); log(" -clock \n"); log(" name of top-level clock input\n"); log("\n"); @@ -816,6 +908,12 @@ struct SimPass : public Pass { worker.vcdfile.open(vcd_filename.c_str()); continue; } + if (args[argidx] == "-fst" && argidx+1 < args.size()) { + std::string fst_filename = args[++argidx]; + rewrite_filename(fst_filename); + worker.fstfile = (struct fstContext *)fstWriterCreate(fst_filename.c_str(),1); + continue; + } if (args[argidx] == "-n" && argidx+1 < args.size()) { numcycles = atoi(args[++argidx].c_str()); continue; -- cgit v1.2.3 From 9a8939f0a4584c13bfceb978120cc8605ede03ee Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 26 Jan 2022 15:50:38 +0100 Subject: Read fst and use data to set inputs --- passes/sat/sim.cc | 102 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 92 insertions(+), 10 deletions(-) (limited to 'passes/sat') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index ba7519be5..99ea701d9 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -21,7 +21,7 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" #include "kernel/mem.h" -#include "libs/fst/fstapi.h" +#include "kernel/fstdata.h" #include @@ -35,6 +35,7 @@ struct SimShared bool writeback = false; bool zinit = false; int rstlen = 1; + FstData *fst = nullptr; }; void zinit(State &v) @@ -52,7 +53,8 @@ void zinit(Const &v) struct SimInstance { SimShared *shared; - + + std::string scope; Module *module; Cell *instance; @@ -95,8 +97,8 @@ struct SimInstance dict> vcd_database; dict> fst_database; - SimInstance(SimShared *shared, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) : - shared(shared), module(module), instance(instance), parent(parent), sigmap(module) + SimInstance(SimShared *shared, std::string scope, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) : + shared(shared), scope(scope), module(module), instance(instance), parent(parent), sigmap(module) { log_assert(module); @@ -146,7 +148,7 @@ struct SimInstance Module *mod = module->design->module(cell->type); if (mod != nullptr) { - dirty_children.insert(new SimInstance(shared, mod, cell, this)); + dirty_children.insert(new SimInstance(shared, scope + "." + RTLIL::unescape_id(module->name), mod, cell, this)); } for (auto &port : cell->connections()) { @@ -674,6 +676,8 @@ struct SimWorker : SimShared struct fstContext *fstfile = nullptr; pool clock, clockn, reset, resetn; std::string timescale; + std::string sim_filename; + std::string scope; ~SimWorker() { @@ -708,10 +712,10 @@ struct SimWorker : SimShared void write_fst_header() { std::time_t t = std::time(nullptr); - fstWriterSetDate(fstfile, asctime(std::localtime(&t))); - fstWriterSetVersion(fstfile, yosys_version_str); + fstWriterSetDate(fstfile, asctime(std::localtime(&t))); + fstWriterSetVersion(fstfile, yosys_version_str); if (!timescale.empty()) - fstWriterSetTimescaleFromString(fstfile, timescale.c_str()); + fstWriterSetTimescaleFromString(fstfile, timescale.c_str()); fstWriterSetPackType(fstfile, FST_WR_PT_FASTLZ); fstWriterSetRepackOnClose(fstfile, 1); @@ -786,7 +790,7 @@ struct SimWorker : SimShared void run(Module *topmod, int numcycles) { log_assert(top == nullptr); - top = new SimInstance(this, topmod); + top = new SimInstance(this, scope, topmod); if (debug) log("\n===== 0 =====\n"); @@ -841,6 +845,65 @@ struct SimWorker : SimShared top->writeback(wbmods); } } + + void run_cosim(Module *topmod, int numcycles) + { + log_assert(top == nullptr); + top = new SimInstance(this, scope, topmod); + + fst = new FstData(sim_filename); + + std::vector fst_clock; + + for (auto portname : clock) + { + Wire *w = topmod->wire(portname); + if (!w) + log_error("Can't find port %s on module %s.\n", log_id(portname), log_id(top->module)); + if (!w->port_input) + log_error("Clock port %s on module %s is not input.\n", log_id(portname), log_id(top->module)); + fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); + if (id==0) + log_error("Can't find port %s.%s in FST.\n", scope.c_str(), log_id(portname)); + fst_clock.push_back(id); + } + for (auto portname : clockn) + { + Wire *w = topmod->wire(portname); + if (!w) + log_error("Can't find port %s on module %s.\n", log_id(portname), log_id(top->module)); + if (!w->port_input) + log_error("Clock port %s on module %s is not input.\n", log_id(portname), log_id(top->module)); + fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); + if (id==0) + log_error("Can't find port %s.%s in FST.\n", scope.c_str(), log_id(portname)); + fst_clock.push_back(id); + } + if (fst_clock.size()==0) + log_error("No clock signals defined for input file\n"); + + SigMap sigmap(topmod); + log ("Get inputs\n"); + std::map inputs; + + for (auto wire : topmod->wires()) { + if (wire->port_input) { + fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name)); + log("Input %s\n",log_id(wire)); + inputs[wire] = id; + } + } + + fst->reconstruct(fst_clock); + auto edges = fst->edges(fst_clock.back(), true, true); + fst->reconstructAllAtTimes(edges); + for(auto &time : edges) { + for(auto &item : inputs) { + std::string v = fst->valueAt(item.second, time); + top->set_state(item.first, Const::from_string(v)); + } + update(); + } }; struct SimPass : public Pass { @@ -889,6 +952,12 @@ struct SimPass : public Pass { log(" -w\n"); log(" writeback mode: use final simulation state as new init state\n"); log("\n"); + log(" -r\n"); + log(" read simulation results file (file formats supported: FST)\n"); + log("\n"); + log(" -scope\n"); + log(" scope of simulation top model\n"); + log("\n"); log(" -d\n"); log(" enable debug output\n"); log("\n"); @@ -958,6 +1027,16 @@ struct SimPass : public Pass { worker.zinit = true; continue; } + if (args[argidx] == "-r" && argidx+1 < args.size()) { + std::string sim_filename = args[++argidx]; + rewrite_filename(sim_filename); + worker.sim_filename = sim_filename; + continue; + } + if (args[argidx] == "-scope" && argidx+1 < args.size()) { + worker.scope = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); @@ -976,7 +1055,10 @@ struct SimPass : public Pass { top_mod = mods.front(); } - worker.run(top_mod, numcycles); + if (worker.sim_filename.empty()) + worker.run(top_mod, numcycles); + else + worker.run_cosim(top_mod, numcycles); } } SimPass; -- cgit v1.2.3 From be7be63fece641db3e3fa1bd28f10603d07732bf Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 26 Jan 2022 15:51:43 +0100 Subject: Check if stimulated --- passes/sat/sim.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'passes/sat') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 99ea701d9..605dc8e1e 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -903,7 +903,21 @@ struct SimWorker : SimShared top->set_state(item.first, Const::from_string(v)); } update(); + + /*Wire *wire = topmod->wire("\\cnt"); + Const value = top->get_state(wire); + std::stringstream ss; + for (int i = GetSize(value)-1; i >= 0; i--) { + switch (value[i]) { + case State::S0: ss << "0"; break; + case State::S1: ss << "1"; break; + case State::Sx: ss << "x"; break; + default: ss << "z"; + } + } + log("%s\n",ss.str().c_str());*/ } + } }; struct SimPass : public Pass { -- cgit v1.2.3 From 40018e191b7f5e233b2da4eab823f37d51a07778 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 26 Jan 2022 16:52:36 +0100 Subject: Display values of outputs --- passes/sat/sim.cc | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'passes/sat') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 605dc8e1e..8cabcfbb4 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -885,6 +885,7 @@ struct SimWorker : SimShared SigMap sigmap(topmod); log ("Get inputs\n"); std::map inputs; + std::map outputs; for (auto wire : topmod->wires()) { if (wire->port_input) { @@ -892,6 +893,11 @@ struct SimWorker : SimShared log("Input %s\n",log_id(wire)); inputs[wire] = id; } + if (wire->port_output) { + fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name)); + log("Output %s %d\n",log_id(wire), id); + outputs[wire] = id; + } } fst->reconstruct(fst_clock); @@ -903,19 +909,11 @@ struct SimWorker : SimShared top->set_state(item.first, Const::from_string(v)); } update(); - - /*Wire *wire = topmod->wire("\\cnt"); - Const value = top->get_state(wire); - std::stringstream ss; - for (int i = GetSize(value)-1; i >= 0; i--) { - switch (value[i]) { - case State::S0: ss << "0"; break; - case State::S1: ss << "1"; break; - case State::Sx: ss << "x"; break; - default: ss << "z"; - } + for(auto &item : outputs) { + Const fst_val = Const::from_string(fst->valueAt(item.second, time)); + Const sim_val = top->get_state(item.first); + log("%s %s\n", log_signal(fst_val), log_signal(sim_val)); } - log("%s\n",ss.str().c_str());*/ } } }; -- cgit v1.2.3 From 3e35de2be108b7d8b24808aa55a0f0f9f8570705 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 28 Jan 2022 10:18:02 +0100 Subject: Add more options and time handling --- passes/sat/sim.cc | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 2 deletions(-) (limited to 'passes/sat') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 8cabcfbb4..d6f5f3a81 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -28,6 +28,41 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +enum class SimulationMode { + cmp, + gold, + gate, +}; + +static const std::map g_units = +{ + { "", -9 }, // default is ns + { "s", 0 }, + { "ms", -3 }, + { "us", -6 }, + { "ns", -9 }, + { "ps", -12 }, + { "fs", -15 }, + { "as", -18 }, + { "zs", -21 }, +}; + +static double stringToTime(std::string str) +{ + if (str=="END") return -1; + + char *endptr; + long value = strtol(str.c_str(), &endptr, 10); + + if (g_units.find(endptr)==g_units.end()) + log_error("Cannot parse '%s', bad unit '%s'\n", str.c_str(), endptr); + + if (value < 0) + log_error("Time value '%s' must be positive\n", str.c_str()); + + return value * pow(10.0, g_units.at(endptr)); +} + struct SimShared { bool debug = false; @@ -36,6 +71,9 @@ struct SimShared bool zinit = false; int rstlen = 1; FstData *fst = nullptr; + double start_time = 0; + double stop_time = -1; + SimulationMode sim_mode = SimulationMode::cmp; }; void zinit(State &v) @@ -900,10 +938,38 @@ struct SimWorker : SimShared } } + uint64_t startCount = 0; + uint64_t stopCount = 0; + if (start_time==0) { + if (start_time < fst->getStartTime()) + log_warning("Start time is before simulation file start time\n"); + startCount = fst->getStartTime(); + } else if (start_time==-1) + startCount = fst->getEndTime(); + else { + startCount = start_time / fst->getTimescale(); + if (startCount > fst->getEndTime()) { + startCount = fst->getEndTime(); + log_warning("Start time is after simulation file end time\n"); + } + } + if (stop_time==0) { + if (stop_time < fst->getStartTime()) + log_warning("Stop time is before simulation file start time\n"); + stopCount = fst->getStartTime(); + } else if (stop_time==-1) + stopCount = fst->getEndTime(); + else { + stopCount = stop_time / fst->getTimescale(); + if (stopCount > fst->getEndTime()) { + stopCount = fst->getEndTime(); + log_warning("Stop time is after simulation file end time\n"); + } + } fst->reconstruct(fst_clock); auto edges = fst->edges(fst_clock.back(), true, true); fst->reconstructAllAtTimes(edges); - for(auto &time : edges) { +/* for(auto &time : edges) { for(auto &item : inputs) { std::string v = fst->valueAt(item.second, time); top->set_state(item.first, Const::from_string(v)); @@ -914,7 +980,7 @@ struct SimWorker : SimShared Const sim_val = top->get_state(item.first); log("%s %s\n", log_signal(fst_val), log_signal(sim_val)); } - } + }*/ } }; @@ -970,6 +1036,21 @@ struct SimPass : public Pass { log(" -scope\n"); log(" scope of simulation top model\n"); log("\n"); + log(" -start