From 94913a9f5ada47ec714933d014a9e206e7ebec61 Mon Sep 17 00:00:00 2001 From: Asherah Connor Date: Tue, 27 Aug 2024 17:34:56 +0300 Subject: [PATCH 001/133] cxxrtl: use octal encoding of non-printables. "\x0a" is a perfectly valid escape sequence, but unfortunately "\x0ac" is equivalent to "\xac", and not "\x0a" "c" as we might expect --- *any* number of hexadecimal characters after the "\x" is accepted. This can be hit pretty easily if a newline is present in a format string. "\x{...}" syntax is only available as of C++23, so use octal format instead; a maximum of 3 digits following the backslash is accepted. The alternative would be to render every escape like `" "\x0a" "`, but it seems more effort that way. --- kernel/fmt.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index d1c6b8ac9..44ad8351d 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -634,10 +634,11 @@ std::string escape_cxx_string(const std::string &input) output.push_back('\\'); output.push_back(c); } else { - char l = c & 0xf, h = (c >> 4) & 0xf; - output.append("\\x"); - output.push_back((h < 10 ? '0' + h : 'a' + h - 10)); - output.push_back((l < 10 ? '0' + l : 'a' + l - 10)); + char l = c & 0x7, m = (c >> 3) & 0x7, h = (c >> 6) & 0x3; + output.push_back('\\'); + output.push_back('0' + h); + output.push_back('0' + m); + output.push_back('0' + l); } } output.push_back('"'); From d0da1b56beb90f9633ed58cf0b52ea79d979ac86 Mon Sep 17 00:00:00 2001 From: Asherah Connor Date: Tue, 27 Aug 2024 18:36:43 +0300 Subject: [PATCH 002/133] cxxrtl: backend: don't drop bits 2 and 5 on non-printable format. --- backends/cxxrtl/cxxrtl_backend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 8dc14863d..7e7bace6c 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -616,7 +616,7 @@ std::string escape_c_string(const std::string &input) output.push_back('\\'); output.push_back(c); } else { - char l = c & 0x3, m = (c >> 3) & 0x3, h = (c >> 6) & 0x3; + char l = c & 0x7, m = (c >> 3) & 0x7, h = (c >> 6) & 0x3; output.append("\\"); output.push_back('0' + h); output.push_back('0' + m); From 8e508f2a2ade89e5e301de18c922155698ae6960 Mon Sep 17 00:00:00 2001 From: mszelwiga Date: Fri, 8 Nov 2024 15:41:20 +0100 Subject: [PATCH 003/133] Fix setting bits of parameters in setundef pass This commit also adds test that verifies correctness of this change. --- passes/cmds/setundef.cc | 2 +- tests/various/setundef.sv | 10 ++++++++++ tests/various/setundef.ys | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/various/setundef.sv create mode 100644 tests/various/setundef.ys diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 4ba58036b..dce33c05b 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -243,7 +243,7 @@ struct SetundefPass : public Pass { { for (auto *cell : module->selected_cells()) { for (auto ¶meter : cell->parameters) { - for (auto bit : parameter.second) { + for (auto &bit : parameter.second.bits()) { if (bit > RTLIL::State::S1) bit = worker.next_bit(); } diff --git a/tests/various/setundef.sv b/tests/various/setundef.sv new file mode 100644 index 000000000..59a553fbb --- /dev/null +++ b/tests/various/setundef.sv @@ -0,0 +1,10 @@ +module foo #(parameter [1:0] a) (output [1:0] o); + assign o = a; +endmodule + +module top(output [1:0] o); + foo #(2'b0x) foo(o); + always_comb begin + assert(o == 2'b00); + end +endmodule diff --git a/tests/various/setundef.ys b/tests/various/setundef.ys new file mode 100644 index 000000000..269e5a40f --- /dev/null +++ b/tests/various/setundef.ys @@ -0,0 +1,8 @@ +read_verilog -sv setundef.sv +setundef -zero -params +hierarchy -top top +flatten +proc +async2sync +write_json +sat -seq 5 -prove-asserts From 9a112043294ddca6f0b09892def8db59d277d147 Mon Sep 17 00:00:00 2001 From: Aritz Erkiaga Date: Sun, 22 Dec 2024 18:26:30 +0100 Subject: [PATCH 004/133] Update ALU MULT mode in gowin to match nextpnr --- techlibs/gowin/cells_sim.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 76635355d..58a2f52e6 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -1005,7 +1005,7 @@ always @* begin C = I0; end MULT: begin - S = I0 & I1; + S = (I0 & I1) ^ I3; C = I0 & I1; end endcase From 1fdb2a451151f339b31c7eac135370a2d3fd5e41 Mon Sep 17 00:00:00 2001 From: Patrick Urban Date: Fri, 10 Jan 2025 10:25:10 +0100 Subject: [PATCH 005/133] gatemate: Add `CC_SERDES` parameters and update port names --- techlibs/gatemate/cells_bb.v | 231 +++++++++++++++++++++++++++++++++-- 1 file changed, 219 insertions(+), 12 deletions(-) diff --git a/techlibs/gatemate/cells_bb.v b/techlibs/gatemate/cells_bb.v index f928a3d7a..c0cd64c89 100644 --- a/techlibs/gatemate/cells_bb.v +++ b/techlibs/gatemate/cells_bb.v @@ -50,14 +50,221 @@ endmodule (* blackbox *) (* keep *) module CC_SERDES #( - parameter SERDES_CFG = "" + parameter [4:0] RX_BUF_RESET_TIME = 3, + parameter [4:0] RX_PCS_RESET_TIME = 3, + parameter [4:0] RX_RESET_TIMER_PRESC = 0, + parameter [0:0] RX_RESET_DONE_GATE = 0, + parameter [4:0] RX_CDR_RESET_TIME = 3, + parameter [4:0] RX_EQA_RESET_TIME = 3, + parameter [4:0] RX_PMA_RESET_TIME = 3, + parameter [0:0] RX_WAIT_CDR_LOCK = 1, + parameter [0:0] RX_CALIB_EN = 0, + parameter [0:0] RX_CALIB_OVR = 0, + parameter [3:0] RX_CALIB_VAL = 0, + parameter [2:0] RX_RTERM_VCMSEL = 4, + parameter [0:0] RX_RTERM_PD = 0, + parameter [7:0] RX_EQA_CKP_LF = 8'hA3, + parameter [7:0] RX_EQA_CKP_HF = 8'hA3, + parameter [7:0] RX_EQA_CKP_OFFSET = 8'h01, + parameter [0:0] RX_EN_EQA = 0, + parameter [3:0] RX_EQA_LOCK_CFG = 0, + parameter [4:0] RX_TH_MON1 = 8, + parameter [3:0] RX_EN_EQA_EXT_VALUE = 0, + parameter [4:0] RX_TH_MON2 = 8, + parameter [4:0] RX_TAPW = 8, + parameter [4:0] RX_AFE_OFFSET = 8, + parameter [15:0] RX_EQA_CONFIG = 16'h01C0, + parameter [4:0] RX_AFE_PEAK = 16, + parameter [3:0] RX_AFE_GAIN = 8, + parameter [2:0] RX_AFE_VCMSEL = 4, + parameter [7:0] RX_CDR_CKP = 8'hF8, + parameter [7:0] RX_CDR_CKI = 0, + parameter [8:0] RX_CDR_TRANS_TH = 128, + parameter [5:0] RX_CDR_LOCK_CFG = 8'h0B, + parameter [14:0] RX_CDR_FREQ_ACC = 0, + parameter [15:0] RX_CDR_PHASE_ACC = 0, + parameter [1:0] RX_CDR_SET_ACC_CONFIG = 0, + parameter [0:0] RX_CDR_FORCE_LOCK = 0, + parameter [9:0] RX_ALIGN_MCOMMA_VALUE = 10'h283, + parameter [0:0] RX_MCOMMA_ALIGN_OVR = 0, + parameter [0:0] RX_MCOMMA_ALIGN = 0, + parameter [9:0] RX_ALIGN_PCOMMA_VALUE = 10'h17C, + parameter [0:0] RX_PCOMMA_ALIGN_OVR = 0, + parameter [0:0] RX_PCOMMA_ALIGN = 0, + parameter [1:0] RX_ALIGN_COMMA_WORD = 0, + parameter [9:0] RX_ALIGN_COMMA_ENABLE = 10'h3FF, + parameter [1:0] RX_SLIDE_MODE = 0, + parameter [0:0] RX_COMMA_DETECT_EN_OVR = 0, + parameter [0:0] RX_COMMA_DETECT_EN = 0, + parameter [1:0] RX_SLIDE = 0, + parameter [0:0] RX_EYE_MEAS_EN = 0, + parameter [14:0] RX_EYE_MEAS_CFG = 0, + parameter [5:0] RX_MON_PH_OFFSET = 0, + parameter [3:0] RX_EI_BIAS = 0, + parameter [3:0] RX_EI_BW_SEL = 4, + parameter [0:0] RX_EN_EI_DETECTOR_OVR = 0, + parameter [0:0] RX_EN_EI_DETECTOR = 0, + parameter [0:0] RX_DATA_SEL = 0, + parameter [0:0] RX_BUF_BYPASS = 0, + parameter [0:0] RX_CLKCOR_USE = 0, + parameter [5:0] RX_CLKCOR_MIN_LAT = 32, + parameter [5:0] RX_CLKCOR_MAX_LAT = 39, + parameter [9:0] RX_CLKCOR_SEQ_1_0 = 10'h1F7, + parameter [9:0] RX_CLKCOR_SEQ_1_1 = 10'h1F7, + parameter [9:0] RX_CLKCOR_SEQ_1_2 = 10'h1F7, + parameter [9:0] RX_CLKCOR_SEQ_1_3 = 10'h1F7, + parameter [0:0] RX_PMA_LOOPBACK = 0, + parameter [0:0] RX_PCS_LOOPBACK = 0, + parameter [1:0] RX_DATAPATH_SEL = 3, + parameter [0:0] RX_PRBS_OVR = 0, + parameter [2:0] RX_PRBS_SEL = 0, + parameter [0:0] RX_LOOPBACK_OVR = 0, + parameter [0:0] RX_PRBS_CNT_RESET = 0, + parameter [0:0] RX_POWER_DOWN_OVR = 0, + parameter [0:0] RX_POWER_DOWN_N = 0, + parameter [0:0] RX_RESET_OVR = 0, + parameter [0:0] RX_RESET = 0, + parameter [0:0] RX_PMA_RESET_OVR = 0, + parameter [0:0] RX_PMA_RESET = 0, + parameter [0:0] RX_EQA_RESET_OVR = 0, + parameter [0:0] RX_EQA_RESET = 0, + parameter [0:0] RX_CDR_RESET_OVR = 0, + parameter [0:0] RX_CDR_RESET = 0, + parameter [0:0] RX_PCS_RESET_OVR = 0, + parameter [0:0] RX_PCS_RESET = 0, + parameter [0:0] RX_BUF_RESET_OVR = 0, + parameter [0:0] RX_BUF_RESET = 0, + parameter [0:0] RX_POLARITY_OVR = 0, + parameter [0:0] RX_POLARITY = 0, + parameter [0:0] RX_8B10B_EN_OVR = 0, + parameter [0:0] RX_8B10B_EN = 0, + parameter [7:0] RX_8B10B_BYPASS = 0, + parameter [0:0] RX_BYTE_REALIGN = 0, + parameter [0:0] RX_DBG_EN = 0, + parameter [1:0] RX_DBG_SEL = 0, + parameter [0:0] RX_DBG_MODE = 0, + parameter [5:0] RX_DBG_SRAM_DELAY = 6'h05, + parameter [9:0] RX_DBG_ADDR = 0, + parameter [0:0] RX_DBG_RE = 0, + parameter [0:0] RX_DBG_WE = 0, + parameter [19:0] RX_DBG_DATA = 0, + parameter [4:0] TX_SEL_PRE = 0, + parameter [4:0] TX_SEL_POST = 0, + parameter [4:0] TX_AMP = 15, + parameter [4:0] TX_BRANCH_EN_PRE = 0, + parameter [5:0] TX_BRANCH_EN_MAIN = 6'h3F, + parameter [4:0] TX_BRANCH_EN_POST = 0, + parameter [2:0] TX_TAIL_CASCODE = 4, + parameter [6:0] TX_DC_ENABLE = 63, + parameter [4:0] TX_DC_OFFSET = 0, + parameter [4:0] TX_CM_RAISE = 0, + parameter [4:0] TX_CM_THRESHOLD_0 = 14, + parameter [4:0] TX_CM_THRESHOLD_1 = 16, + parameter [4:0] TX_SEL_PRE_EI = 0, + parameter [4:0] TX_SEL_POST_EI = 0, + parameter [4:0] TX_AMP_EI = 15, + parameter [4:0] TX_BRANCH_EN_PRE_EI = 0, + parameter [5:0] TX_BRANCH_EN_MAIN_EI = 6'h3F, + parameter [4:0] TX_BRANCH_EN_POST_EI = 0, + parameter [2:0] TX_TAIL_CASCODE_EI = 4, + parameter [6:0] TX_DC_ENABLE_EI = 63, + parameter [4:0] TX_DC_OFFSET_EI = 0, + parameter [4:0] TX_CM_RAISE_EI = 0, + parameter [4:0] TX_CM_THRESHOLD_0_EI = 14, + parameter [4:0] TX_CM_THRESHOLD_1_EI = 16, + parameter [4:0] TX_SEL_PRE_RXDET = 0, + parameter [4:0] TX_SEL_POST_RXDET = 0, + parameter [4:0] TX_AMP_RXDET = 15, + parameter [4:0] TX_BRANCH_EN_PRE_RXDET = 0, + parameter [5:0] TX_BRANCH_EN_MAIN_RXDET = 6'h3F, + parameter [4:0] TX_BRANCH_EN_POST_RXDET = 0, + parameter [2:0] TX_TAIL_CASCODE_RXDET = 4, + parameter [6:0] TX_DC_ENABLE_RXDET = 63, + parameter [4:0] TX_DC_OFFSET_RXDET = 0, + parameter [4:0] TX_CM_RAISE_RXDET = 0, + parameter [4:0] TX_CM_THRESHOLD_0_RXDET = 14, + parameter [4:0] TX_CM_THRESHOLD_1_RXDET = 16, + parameter [0:0] TX_CALIB_EN = 0, + parameter [0:0] TX_CALIB_OVR = 0, + parameter [3:0] TX_CALIB_VAL = 0, + parameter [7:0] TX_CM_REG_KI = 8'h80, + parameter [0:0] TX_CM_SAR_EN = 0, + parameter [0:0] TX_CM_REG_EN = 1, + parameter [4:0] TX_PMA_RESET_TIME = 3, + parameter [4:0] TX_PCS_RESET_TIME = 3, + parameter [0:0] TX_PCS_RESET_OVR = 0, + parameter [0:0] TX_PCS_RESET = 0, + parameter [0:0] TX_PMA_RESET_OVR = 0, + parameter [0:0] TX_PMA_RESET = 0, + parameter [0:0] TX_RESET_OVR = 0, + parameter [0:0] TX_RESET = 0, + parameter [1:0] TX_PMA_LOOPBACK = 0, + parameter [0:0] TX_PCS_LOOPBACK = 0, + parameter [1:0] TX_DATAPATH_SEL = 3, + parameter [0:0] TX_PRBS_OVR = 0, + parameter [2:0] TX_PRBS_SEL = 0, + parameter [0:0] TX_PRBS_FORCE_ERR = 0, + parameter [0:0] TX_LOOPBACK_OVR = 0, + parameter [0:0] TX_POWER_DOWN_OVR = 0, + parameter [0:0] TX_POWER_DOWN_N = 0, + parameter [0:0] TX_ELEC_IDLE_OVR = 0, + parameter [0:0] TX_ELEC_IDLE = 0, + parameter [0:0] TX_DETECT_RX_OVR = 0, + parameter [0:0] TX_DETECT_RX = 0, + parameter [0:0] TX_POLARITY_OVR = 0, + parameter [0:0] TX_POLARITY = 0, + parameter [0:0] TX_8B10B_EN_OVR = 0, + parameter [0:0] TX_8B10B_EN = 0, + parameter [0:0] TX_DATA_OVR = 0, + parameter [2:0] TX_DATA_CNT = 0, + parameter [0:0] TX_DATA_VALID = 0, + parameter [0:0] PLL_EN_ADPLL_CTRL = 0, + parameter [0:0] PLL_CONFIG_SEL = 0, + parameter [0:0] PLL_SET_OP_LOCK = 0, + parameter [0:0] PLL_ENFORCE_LOCK = 0, + parameter [0:0] PLL_DISABLE_LOCK = 0, + parameter [0:0] PLL_LOCK_WINDOW = 1, + parameter [0:0] PLL_FAST_LOCK = 1, + parameter [0:0] PLL_SYNC_BYPASS = 0, + parameter [0:0] PLL_PFD_SELECT = 0, + parameter [0:0] PLL_REF_BYPASS = 0, + parameter [0:0] PLL_REF_SEL = 0, + parameter [0:0] PLL_REF_RTERM = 1, + parameter [5:0] PLL_FCNTRL = 58, + parameter [5:0] PLL_MAIN_DIVSEL = 27, + parameter [1:0] PLL_OUT_DIVSEL = 0, + parameter [4:0] PLL_CI = 3, + parameter [9:0] PLL_CP = 80, + parameter [3:0] PLL_AO = 0, + parameter [2:0] PLL_SCAP = 0, + parameter [1:0] PLL_FILTER_SHIFT = 2, + parameter [2:0] PLL_SAR_LIMIT = 2, + parameter [10:0] PLL_FT = 512, + parameter [0:0] PLL_OPEN_LOOP = 0, + parameter [0:0] PLL_SCAP_AUTO_CAL = 1, + parameter [2:0] PLL_BISC_MODE = 4, + parameter [3:0] PLL_BISC_TIMER_MAX = 15, + parameter [0:0] PLL_BISC_OPT_DET_IND = 0, + parameter [0:0] PLL_BISC_PFD_SEL = 0, + parameter [0:0] PLL_BISC_DLY_DIR = 0, + parameter [2:0] PLL_BISC_COR_DLY = 1, + parameter [0:0] PLL_BISC_CAL_SIGN = 0, + parameter [0:0] PLL_BISC_CAL_AUTO = 1, + parameter [4:0] PLL_BISC_CP_MIN = 4, + parameter [4:0] PLL_BISC_CP_MAX = 18, + parameter [4:0] PLL_BISC_CP_START = 12, + parameter [4:0] PLL_BISC_DLY_PFD_MON_REF = 0, + parameter [4:0] PLL_BISC_DLY_PFD_MON_DIV = 2, + parameter [0:0] SERDES_ENABLE = 0, + parameter [0:0] SERDES_AUTO_INIT = 0, + parameter [0:0] SERDES_TESTMODE = 0 )( input [63:0] TX_DATA_I, input TX_RESET_I, input TX_PCS_RESET_I, input TX_PMA_RESET_I, input PLL_RESET_I, - input TX_POWERDOWN_N_I, + input TX_POWER_DOWN_N_I, input TX_POLARITY_I, input [2:0] TX_PRBS_SEL_I, input TX_PRBS_FORCE_ERR_I, @@ -69,15 +276,15 @@ module CC_SERDES #( input TX_ELEC_IDLE_I, input TX_DETECT_RX_I, input [2:0] LOOPBACK_I, - input CLK_CORE_TX_I, - input CLK_CORE_RX_I, + input TX_CLK_I, + input RX_CLK_I, input RX_RESET_I, input RX_PMA_RESET_I, input RX_EQA_RESET_I, input RX_CDR_RESET_I, input RX_PCS_RESET_I, input RX_BUF_RESET_I, - input RX_POWERDOWN_N_I, + input RX_POWER_DOWN_N_I, input RX_POLARITY_I, input [2:0] RX_PRBS_SEL_I, input RX_PRBS_CNT_RESET_I, @@ -88,7 +295,7 @@ module CC_SERDES #( input RX_SLIDE_I, input RX_MCOMMA_ALIGN_I, input RX_PCOMMA_ALIGN_I, - input CLK_REG_I, + input REGFILE_CLK_I, input REGFILE_WE_I, input REGFILE_EN_I, input [7:0] REGFILE_ADDR_I, @@ -99,18 +306,18 @@ module CC_SERDES #( output [7:0] RX_CHAR_IS_COMMA_O, output [7:0] RX_CHAR_IS_K_O, output [7:0] RX_DISP_ERR_O, - output RX_DETECT_DONE_O, - output RX_PRESENT_O, + output TX_DETECT_RX_DONE_O, + output TX_DETECT_RX_PRESENT_O, output TX_BUF_ERR_O, - output TX_RESETDONE_O, + output TX_RESET_DONE_O, output RX_PRBS_ERR_O, output RX_BUF_ERR_O, output RX_BYTE_IS_ALIGNED_O, output RX_BYTE_REALIGN_O, - output RX_RESETDONE_O, + output RX_RESET_DONE_O, output RX_EI_EN_O, - output CLK_CORE_RX_O, - output CLK_CORE_PLL_O, + output RX_CLK_O, + output PLL_CLK_O, output [15:0] REGFILE_DO_O, output REGFILE_RDY_O ); From 08394c51a2fb99caf52394931e91120f2a1aae07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 13 Dec 2024 18:59:35 +0100 Subject: [PATCH 006/133] rtlil: Add const append helper --- kernel/rtlil.cc | 6 ++++++ kernel/rtlil.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index cb0f7da78..d705813d9 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -540,6 +540,12 @@ void RTLIL::Const::bitvectorize() const { } } +void RTLIL::Const::append(const RTLIL::Const &other) { + bitvectorize(); + bitvectype& bv = get_bits(); + bv.insert(bv.end(), other.begin(), other.end()); +} + RTLIL::State RTLIL::Const::const_iterator::operator*() const { if (auto bv = parent.get_if_bits()) return (*bv)[idx]; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f9cacd151..33742cb70 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -738,6 +738,8 @@ public: bool empty() const; void bitvectorize() const; + void append(const RTLIL::Const &other); + class const_iterator { private: const Const& parent; From c5fd96ebb0c9067927bd4df381af92783bb4b547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 13 Dec 2024 19:01:41 +0100 Subject: [PATCH 007/133] macc_v2: Start new cell --- kernel/constids.inc | 4 ++ kernel/macc.h | 102 ++++++++++++++++++---------- kernel/rtlil.cc | 29 ++++++++ passes/techmap/maccmap.cc | 2 +- tests/alumacc/macc_infer_n_unmap.ys | 19 ++++++ 5 files changed, 119 insertions(+), 37 deletions(-) create mode 100644 tests/alumacc/macc_infer_n_unmap.ys diff --git a/kernel/constids.inc b/kernel/constids.inc index d68e2dfe6..15d3cc83b 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -276,3 +276,7 @@ X(Y) X(Y_WIDTH) X(area) X(capacitance) +X(NTERMS) +X(TERM_NEGATED) +X(A_WIDTHS) +X(B_WIDTHS) diff --git a/kernel/macc.h b/kernel/macc.h index 55940769d..e969dd86d 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -82,7 +82,7 @@ struct Macc new_ports.swap(ports); } - void from_cell(RTLIL::Cell *cell) + void from_cell_v1(RTLIL::Cell *cell) { RTLIL::SigSpec port_a = cell->getPort(ID::A); @@ -136,52 +136,82 @@ struct Macc log_assert(port_a_cursor == GetSize(port_a)); } - void to_cell(RTLIL::Cell *cell) const + void from_cell(RTLIL::Cell *cell) { - RTLIL::SigSpec port_a; - std::vector config_bits; - int max_size = 0, num_bits = 0; - - for (auto &port : ports) { - max_size = max(max_size, GetSize(port.in_a)); - max_size = max(max_size, GetSize(port.in_b)); + if (cell->type == ID($macc)) { + from_cell_v1(cell); + return; } + log_assert(cell->type == ID($macc_v2)); - while (max_size) - num_bits++, max_size /= 2; + RTLIL::SigSpec port_a = cell->getPort(ID::A); + RTLIL::SigSpec port_b = cell->getPort(ID::B); - log_assert(num_bits < 16); - config_bits.push_back(num_bits & 1 ? State::S1 : State::S0); - config_bits.push_back(num_bits & 2 ? State::S1 : State::S0); - config_bits.push_back(num_bits & 4 ? State::S1 : State::S0); - config_bits.push_back(num_bits & 8 ? State::S1 : State::S0); + ports.clear(); - for (auto &port : ports) - { - if (GetSize(port.in_a) == 0) - continue; + int nterms = cell->getParam(ID::NTERMS).as_int(); + const Const &neg = cell->getParam(ID::TERM_NEGATED); + const Const &a_widths = cell->getParam(ID::A_WIDTHS); + const Const &b_widths = cell->getParam(ID::B_WIDTHS); + const Const &a_signed = cell->getParam(ID::A_SIGNED); + const Const &b_signed = cell->getParam(ID::B_SIGNED); - config_bits.push_back(port.is_signed ? State::S1 : State::S0); - config_bits.push_back(port.do_subtract ? State::S1 : State::S0); + int ai = 0, bi = 0; + for (int i = 0; i < nterms; i++) { + port_t term; - int size_a = GetSize(port.in_a); - for (int i = 0; i < num_bits; i++) - config_bits.push_back(size_a & (1 << i) ? State::S1 : State::S0); + log_assert(a_signed[i] == b_signed[i]); + term.is_signed = (a_signed[i] == State::S1); + int a_width = a_widths.extract(16 * i, 16).as_int(false); + int b_width = b_widths.extract(16 * i, 16).as_int(false); - int size_b = GetSize(port.in_b); - for (int i = 0; i < num_bits; i++) - config_bits.push_back(size_b & (1 << i) ? State::S1 : State::S0); + term.in_a = port_a.extract(ai, a_width); + ai += a_width; + term.in_b = port_b.extract(bi, b_width); + bi += b_width; + term.do_subtract = (neg[i] == State::S1); - port_a.append(port.in_a); - port_a.append(port.in_b); + ports.push_back(term); } + log_assert(port_a.size() == ai); + log_assert(port_b.size() == bi); + } - cell->setPort(ID::A, port_a); - cell->setPort(ID::B, {}); - cell->setParam(ID::CONFIG, config_bits); - cell->setParam(ID::CONFIG_WIDTH, GetSize(config_bits)); - cell->setParam(ID::A_WIDTH, GetSize(port_a)); - cell->setParam(ID::B_WIDTH, 0); + void to_cell(RTLIL::Cell *cell) + { + cell->type = ID($macc_v2); + + int nterms = ports.size(); + const auto Sx = State::Sx; + Const a_signed(Sx, nterms), b_signed(Sx, nterms), negated(Sx, nterms); + Const a_widths, b_widths; + SigSpec a, b; + + for (int i = 0; i < nterms; i++) { + SigSpec term_a = ports[i].in_a, term_b = ports[i].in_b; + + a_widths.append(Const(term_a.size(), 16)); + b_widths.append(Const(term_b.size(), 16)); + + a_signed.bits()[i] = b_signed.bits()[i] = + (ports[i].is_signed ? RTLIL::S1 : RTLIL::S0); + negated.bits()[i] = (ports[i].do_subtract ? RTLIL::S1 : RTLIL::S0); + + a.append(term_a); + b.append(term_b); + } + negated.is_fully_def(); + a_signed.is_fully_def(); + b_signed.is_fully_def(); + + cell->setParam(ID::NTERMS, nterms); + cell->setParam(ID::TERM_NEGATED, negated); + cell->setParam(ID::A_SIGNED, a_signed); + cell->setParam(ID::B_SIGNED, b_signed); + cell->setParam(ID::A_WIDTHS, a_widths); + cell->setParam(ID::B_WIDTHS, b_widths); + cell->setPort(ID::A, a); + cell->setPort(ID::B, b); } bool eval(RTLIL::Const &result) const diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d705813d9..ac491f4cd 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1467,6 +1467,30 @@ namespace { return; } + if (cell->type == ID($macc_v2)) { + if (param(ID::NTERMS) <= 0) + error(__LINE__); + param_bits(ID::TERM_NEGATED, param(ID::NTERMS)); + param_bits(ID::A_SIGNED, param(ID::NTERMS)); + param_bits(ID::B_SIGNED, param(ID::NTERMS)); + if (cell->getParam(ID::A_SIGNED) != cell->getParam(ID::B_SIGNED)) + error(__LINE__); + param_bits(ID::A_WIDTHS, param(ID::NTERMS) * 16); + param_bits(ID::B_WIDTHS, param(ID::NTERMS) * 16); + const Const &a_width = cell->getParam(ID::A_WIDTHS); + const Const &b_width = cell->getParam(ID::B_WIDTHS); + int a_width_sum = 0, b_width_sum = 0; + for (int i = 0; i < param(ID::NTERMS); i++) { + a_width_sum += a_width.extract(16 * i, 16).as_int(false); + b_width_sum += b_width.extract(16 * i, 16).as_int(false); + } + port(ID::A, a_width_sum); + port(ID::B, b_width_sum); + port(ID::Y, param(ID::Y_WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($logic_not)) { param_bool(ID::A_SIGNED); port(ID::A, param(ID::A_WIDTH)); @@ -4099,6 +4123,11 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) return; } + if (type == ID($macc_v2)) { + parameters[ID::Y_WIDTH] = GetSize(connections_[ID::Y]); + return; + } + bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc)); if (connections_.count(ID::A)) { diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index 911d66cfa..3dde92438 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -403,7 +403,7 @@ struct MaccmapPass : public Pass { for (auto mod : design->selected_modules()) for (auto cell : mod->selected_cells()) - if (cell->type == ID($macc)) { + if (cell->type.in(ID($macc), ID($macc_v2))) { log("Mapping %s.%s (%s).\n", log_id(mod), log_id(cell), log_id(cell->type)); maccmap(mod, cell, unmap_mode); mod->remove(cell); diff --git a/tests/alumacc/macc_infer_n_unmap.ys b/tests/alumacc/macc_infer_n_unmap.ys new file mode 100644 index 000000000..569511b64 --- /dev/null +++ b/tests/alumacc/macc_infer_n_unmap.ys @@ -0,0 +1,19 @@ +read_verilog < Date: Fri, 10 Jan 2025 11:44:54 +0100 Subject: [PATCH 008/133] macc_v2: Add C port --- kernel/constids.inc | 8 +++-- kernel/macc.h | 79 +++++++++++++++++++++++++++++++-------------- kernel/rtlil.cc | 26 ++++++++++----- 3 files changed, 78 insertions(+), 35 deletions(-) diff --git a/kernel/constids.inc b/kernel/constids.inc index 15d3cc83b..4fdbb3dc8 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -276,7 +276,11 @@ X(Y) X(Y_WIDTH) X(area) X(capacitance) -X(NTERMS) -X(TERM_NEGATED) +X(NPRODUCTS) +X(NADDENDS) +X(PRODUCT_NEGATED) +X(ADDEND_NEGATED) X(A_WIDTHS) X(B_WIDTHS) +X(C_WIDTHS) +X(C_SIGNED) diff --git a/kernel/macc.h b/kernel/macc.h index e969dd86d..fdd738d45 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -146,18 +146,18 @@ struct Macc RTLIL::SigSpec port_a = cell->getPort(ID::A); RTLIL::SigSpec port_b = cell->getPort(ID::B); + RTLIL::SigSpec port_c = cell->getPort(ID::C); ports.clear(); - int nterms = cell->getParam(ID::NTERMS).as_int(); - const Const &neg = cell->getParam(ID::TERM_NEGATED); + int nproducts = cell->getParam(ID::NPRODUCTS).as_int(); + const Const &product_neg = cell->getParam(ID::PRODUCT_NEGATED); const Const &a_widths = cell->getParam(ID::A_WIDTHS); const Const &b_widths = cell->getParam(ID::B_WIDTHS); const Const &a_signed = cell->getParam(ID::A_SIGNED); const Const &b_signed = cell->getParam(ID::B_SIGNED); - int ai = 0, bi = 0; - for (int i = 0; i < nterms; i++) { + for (int i = 0; i < nproducts; i++) { port_t term; log_assert(a_signed[i] == b_signed[i]); @@ -169,49 +169,78 @@ struct Macc ai += a_width; term.in_b = port_b.extract(bi, b_width); bi += b_width; - term.do_subtract = (neg[i] == State::S1); + term.do_subtract = (product_neg[i] == State::S1); ports.push_back(term); } log_assert(port_a.size() == ai); log_assert(port_b.size() == bi); + + int naddends = cell->getParam(ID::NADDENDS).as_int(); + const Const &addend_neg = cell->getParam(ID::ADDEND_NEGATED); + const Const &c_widths = cell->getParam(ID::C_WIDTHS); + const Const &c_signed = cell->getParam(ID::C_SIGNED); + int ci = 0; + for (int i = 0; i < naddends; i++) { + port_t term; + + term.is_signed = (c_signed[i] == State::S1); + int c_width = c_widths.extract(16 * i, 16).as_int(false); + + term.in_a = port_c.extract(ci, c_width); + ci += c_width; + term.do_subtract = (addend_neg[i] == State::S1); + + ports.push_back(term); + } + log_assert(port_c.size() == ci); } void to_cell(RTLIL::Cell *cell) { cell->type = ID($macc_v2); - int nterms = ports.size(); - const auto Sx = State::Sx; - Const a_signed(Sx, nterms), b_signed(Sx, nterms), negated(Sx, nterms); - Const a_widths, b_widths; - SigSpec a, b; + int nproducts = 0, naddends = 0; + Const a_signed, b_signed, a_widths, b_widths, product_negated; + Const c_signed, c_widths, addend_negated; + SigSpec a, b, c; - for (int i = 0; i < nterms; i++) { + for (int i = 0; i < (int) ports.size(); i++) { SigSpec term_a = ports[i].in_a, term_b = ports[i].in_b; - a_widths.append(Const(term_a.size(), 16)); - b_widths.append(Const(term_b.size(), 16)); - - a_signed.bits()[i] = b_signed.bits()[i] = - (ports[i].is_signed ? RTLIL::S1 : RTLIL::S0); - negated.bits()[i] = (ports[i].do_subtract ? RTLIL::S1 : RTLIL::S0); - - a.append(term_a); - b.append(term_b); + if (term_b.empty()) { + // addend + c_widths.append(Const(term_a.size(), 16)); + c_signed.append(ports[i].is_signed ? RTLIL::S1 : RTLIL::S0); + addend_negated.append(ports[i].do_subtract ? RTLIL::S1 : RTLIL::S0); + c.append(term_a); + naddends++; + } else { + // product + a_widths.append(Const(term_a.size(), 16)); + b_widths.append(Const(term_b.size(), 16)); + a_signed.append(ports[i].is_signed ? RTLIL::S1 : RTLIL::S0); + b_signed.append(ports[i].is_signed ? RTLIL::S1 : RTLIL::S0); + product_negated.append(ports[i].do_subtract ? RTLIL::S1 : RTLIL::S0); + a.append(term_a); + b.append(term_b); + nproducts++; + } } - negated.is_fully_def(); - a_signed.is_fully_def(); - b_signed.is_fully_def(); - cell->setParam(ID::NTERMS, nterms); - cell->setParam(ID::TERM_NEGATED, negated); + cell->setParam(ID::NPRODUCTS, nproducts); + cell->setParam(ID::PRODUCT_NEGATED, product_negated); + cell->setParam(ID::NADDENDS, naddends); + cell->setParam(ID::ADDEND_NEGATED, addend_negated); cell->setParam(ID::A_SIGNED, a_signed); cell->setParam(ID::B_SIGNED, b_signed); + cell->setParam(ID::C_SIGNED, c_signed); cell->setParam(ID::A_WIDTHS, a_widths); cell->setParam(ID::B_WIDTHS, b_widths); + cell->setParam(ID::C_WIDTHS, c_widths); cell->setPort(ID::A, a); cell->setPort(ID::B, b); + cell->setPort(ID::C, c); } bool eval(RTLIL::Const &result) const diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ac491f4cd..f2f36ba30 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1468,24 +1468,34 @@ namespace { } if (cell->type == ID($macc_v2)) { - if (param(ID::NTERMS) <= 0) + if (param(ID::NPRODUCTS) <= 0) error(__LINE__); - param_bits(ID::TERM_NEGATED, param(ID::NTERMS)); - param_bits(ID::A_SIGNED, param(ID::NTERMS)); - param_bits(ID::B_SIGNED, param(ID::NTERMS)); + if (param(ID::NADDENDS) <= 0) + error(__LINE__); + param_bits(ID::PRODUCT_NEGATED, param(ID::NPRODUCTS)); + param_bits(ID::ADDEND_NEGATED, param(ID::NADDENDS)); + param_bits(ID::A_SIGNED, param(ID::NPRODUCTS)); + param_bits(ID::B_SIGNED, param(ID::NPRODUCTS)); + param_bits(ID::C_SIGNED, param(ID::NADDENDS)); if (cell->getParam(ID::A_SIGNED) != cell->getParam(ID::B_SIGNED)) error(__LINE__); - param_bits(ID::A_WIDTHS, param(ID::NTERMS) * 16); - param_bits(ID::B_WIDTHS, param(ID::NTERMS) * 16); + param_bits(ID::A_WIDTHS, param(ID::NPRODUCTS) * 16); + param_bits(ID::B_WIDTHS, param(ID::NPRODUCTS) * 16); + param_bits(ID::C_WIDTHS, param(ID::NADDENDS) * 16); const Const &a_width = cell->getParam(ID::A_WIDTHS); const Const &b_width = cell->getParam(ID::B_WIDTHS); - int a_width_sum = 0, b_width_sum = 0; - for (int i = 0; i < param(ID::NTERMS); i++) { + const Const &c_width = cell->getParam(ID::C_WIDTHS); + int a_width_sum = 0, b_width_sum = 0, c_width_sum = 0; + for (int i = 0; i < param(ID::NPRODUCTS); i++) { a_width_sum += a_width.extract(16 * i, 16).as_int(false); b_width_sum += b_width.extract(16 * i, 16).as_int(false); } + for (int i = 0; i < param(ID::NADDENDS); i++) { + c_width_sum += c_width.extract(16 * i, 16).as_int(false); + } port(ID::A, a_width_sum); port(ID::B, b_width_sum); + port(ID::C, c_width_sum); port(ID::Y, param(ID::Y_WIDTH)); check_expected(); return; From 61450e8b6eb246342971fb0460e1d3ce0091c6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 10 Jan 2025 13:42:26 +0100 Subject: [PATCH 009/133] Update codebase for macc_v2 --- docs/source/cell/word_arith.rst | 2 +- docs/source/code_examples/fifo/fifo.ys | 2 +- docs/source/getting_started/example_synth.rst | 2 +- kernel/celledges.cc | 2 +- kernel/celltypes.h | 1 + kernel/consteval.h | 2 +- kernel/rtlil.cc | 16 ++++++++-------- kernel/satgen.cc | 2 +- passes/techmap/booth.cc | 2 +- 9 files changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/source/cell/word_arith.rst b/docs/source/cell/word_arith.rst index 49070814a..8e3daa27f 100644 --- a/docs/source/cell/word_arith.rst +++ b/docs/source/cell/word_arith.rst @@ -1,7 +1,7 @@ Coarse arithmetics ------------------ -.. todo:: Add information about `$alu`, `$fa`, and `$lcu` cells. +.. todo:: Add information about `$alu`, `$fa`, `$macc_v2`, and `$lcu` cells. The `$macc` cell type represents a generalized multiply and accumulate operation. The cell is purely combinational. It outputs the result of summing up diff --git a/docs/source/code_examples/fifo/fifo.ys b/docs/source/code_examples/fifo/fifo.ys index 57a28e63e..e6b9bf69d 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -67,7 +67,7 @@ show -color maroon3 @new_cells -notitle -format dot -prefix rdata_memrdv2 o:rdat # ======================================================== alumacc -select -set new_cells t:$alu t:$macc +select -set new_cells t:$alu t:$macc_v2 show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdata %ci* # ======================================================== diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 189eaddfa..e215586cc 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -523,7 +523,7 @@ That brings us to the fourth and final part for the iCE40 synthesis flow: :name: synth_coarse4 Where before each type of arithmetic operation had its own cell, e.g. `$add`, we -now want to extract these into `$alu` and `$macc` cells which can help identify +now want to extract these into `$alu` and `$macc_v2` cells which can help identify opportunities for reusing logic. We do this by running `alumacc`, which we can see produce the following changes in our example design: diff --git a/kernel/celledges.cc b/kernel/celledges.cc index bad7124d9..95f160612 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -453,7 +453,7 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL } // FIXME: $mul $div $mod $divfloor $modfloor $slice $concat - // FIXME: $lut $sop $alu $lcu $macc $fa + // FIXME: $lut $sop $alu $lcu $macc $macc_v2 $fa // FIXME: $mul $div $mod $divfloor $modfloor $pow $slice $concat $bweqx // FIXME: $lut $sop $alu $lcu $macc $fa $logic_and $logic_or $bwmux diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 3167a9add..0ce5db54d 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -144,6 +144,7 @@ struct CellTypes setup_type(ID($lcu), {ID::P, ID::G, ID::CI}, {ID::CO}, true); setup_type(ID($alu), {ID::A, ID::B, ID::CI, ID::BI}, {ID::X, ID::Y, ID::CO}, true); + setup_type(ID($macc_v2), {ID::A, ID::B, ID::C}, {ID::Y}, true); setup_type(ID($fa), {ID::A, ID::B, ID::C}, {ID::X, ID::Y}, true); } diff --git a/kernel/consteval.h b/kernel/consteval.h index 331d8f128..05e94ab86 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -310,7 +310,7 @@ struct ConstEval } } } - else if (cell->type == ID($macc)) + else if (cell->type.in(ID($macc), ID($macc_v2))) { Macc macc; macc.from_cell(cell); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f2f36ba30..29a7ebf3e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1472,16 +1472,16 @@ namespace { error(__LINE__); if (param(ID::NADDENDS) <= 0) error(__LINE__); - param_bits(ID::PRODUCT_NEGATED, param(ID::NPRODUCTS)); - param_bits(ID::ADDEND_NEGATED, param(ID::NADDENDS)); - param_bits(ID::A_SIGNED, param(ID::NPRODUCTS)); - param_bits(ID::B_SIGNED, param(ID::NPRODUCTS)); - param_bits(ID::C_SIGNED, param(ID::NADDENDS)); + param_bits(ID::PRODUCT_NEGATED, min(param(ID::NPRODUCTS), 1)); + param_bits(ID::ADDEND_NEGATED, min(param(ID::NADDENDS), 1)); + param_bits(ID::A_SIGNED, min(param(ID::NPRODUCTS), 1)); + param_bits(ID::B_SIGNED, min(param(ID::NPRODUCTS), 1)); + param_bits(ID::C_SIGNED, min(param(ID::NADDENDS), 1)); if (cell->getParam(ID::A_SIGNED) != cell->getParam(ID::B_SIGNED)) error(__LINE__); - param_bits(ID::A_WIDTHS, param(ID::NPRODUCTS) * 16); - param_bits(ID::B_WIDTHS, param(ID::NPRODUCTS) * 16); - param_bits(ID::C_WIDTHS, param(ID::NADDENDS) * 16); + param_bits(ID::A_WIDTHS, min(param(ID::NPRODUCTS) * 16, 1)); + param_bits(ID::B_WIDTHS, min(param(ID::NPRODUCTS) * 16, 1)); + param_bits(ID::C_WIDTHS, min(param(ID::NADDENDS) * 16, 1)); const Const &a_width = cell->getParam(ID::A_WIDTHS); const Const &b_width = cell->getParam(ID::B_WIDTHS); const Const &c_width = cell->getParam(ID::C_WIDTHS); diff --git a/kernel/satgen.cc b/kernel/satgen.cc index dd15b51f3..9e5fa9111 100644 --- a/kernel/satgen.cc +++ b/kernel/satgen.cc @@ -740,7 +740,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep) return true; } - if (cell->type == ID($macc)) + if (cell->type.in(ID($macc), ID($macc_v2))) { std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); diff --git a/passes/techmap/booth.cc b/passes/techmap/booth.cc index dce7da486..cd9012e6c 100644 --- a/passes/techmap/booth.cc +++ b/passes/techmap/booth.cc @@ -218,7 +218,7 @@ struct BoothPassWorker { log_assert(cell->getParam(ID::A_SIGNED).as_bool() == cell->getParam(ID::B_SIGNED).as_bool()); is_signed = cell->getParam(ID::A_SIGNED).as_bool(); - } else if (cell->type == ID($macc)) { + } else if (cell->type.in(ID($macc), ID($macc_v2))) { Macc macc; macc.from_cell(cell); From 1e8aa56f7fdcf7510159927bef9b81040354c119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 10 Jan 2025 13:43:54 +0100 Subject: [PATCH 010/133] macc_v2: Init simlib model --- techlibs/common/simlib.v | 105 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index df9e1feb1..248c93513 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1207,6 +1207,111 @@ end endmodule +// -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $macc_v2 (A, B, C, Y) +//* group arith +//- +//- Multiply and add. +//- This cell represents a generic fused multiply-add operation, it supersedes the +//- earlier $macc cell. +//- +module \$macc_v2 (A, B, C, Y); + +parameter NPRODUCTS = 0; +parameter NADDENDS = 0; +parameter A_WIDTHS = 16'h0000; +parameter B_WIDTHS = 16'h0000; +parameter C_WIDTHS = 16'h0000; +parameter Y_WIDTH = 0; + +parameter PRODUCT_NEGATED = 1'bx; +parameter ADDEND_NEGATED = 1'bx; +parameter A_SIGNED = 1'bx; +parameter B_SIGNED = 1'bx; +parameter C_SIGNED = 1'bx; + +function integer sum_widths1; + input [(16*NPRODUCTS)-1:0] widths; + int i; + sum_widths1 = 0; + begin + for (i = 0; i < NPRODUCTS; i++) begin + sum_widths1 += widths[16*i+:16]; + end + end +endfunction + +function integer sum_widths2; + input [(16*NADDENDS)-1:0] widths; + int i; + sum_widths2 = 0; + begin + for (i = 0; i < NADDENDS; i++) begin + sum_widths2 += widths[16*i+:16]; + end + end +endfunction + +input [sum_widths1(A_WIDTHS)-1:0] A; // concatenation of LHS factors +input [sum_widths1(B_WIDTHS)-1:0] B; // concatenation of RHS factors +input [sum_widths2(C_WIDTHS)-1:0] C; // concatenation of summands +output reg [Y_WIDTH-1:0] Y; // output sum + +integer i, j, ai, bi, ci, aw, bw, cw; +reg [Y_WIDTH-1:0] product; +reg signed [Y_WIDTH-1:0] product_signed; +reg [Y_WIDTH-1:0] addend; +reg signed [Y_WIDTH-1:0] addend_signed; + +always @* begin + Y = 0; + ai = 0; + bi = 0; + for (i = 0; i < NPRODUCTS; i = i+1) + begin + aw = A_WIDTHS[16*i+:16]; + bw = B_WIDTHS[16*i+:16]; + + product = A[ai +: aw] * B[bi +: bw]; + product_signed = $signed(A[ai +: aw]) * $signed(B[bi +: bw]); + + // A_SIGNED[i] == B_SIGNED[i] as RTLIL invariant + if (A_SIGNED[i] && B_SIGNED[i]) + product = product_signed; + + if (PRODUCT_NEGATED[i]) + Y = Y - product; + else + Y = Y + product; + + ai += aw; + bi += bw; + end + + ci = 0; + for (i = 0; i < NADDENDS; i = i+1) + begin + cw = C_WIDTHS[16*i+:16]; + + addend = C[ci +: cw]; + addend_signed = $signed(C[ci +: cw]); + + if (C_SIGNED[i]) + addend = addend_signed; + + if (ADDEND_NEGATED[i]) + Y = Y - addend; + else + Y = Y + addend; + + ci += cw; + end +end + +endmodule + // -------------------------------------------------------- //* ver 2 //* title Divider From cb8f855f347da751d65eb002f80247d107b25e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 24 Jan 2025 12:35:23 +0100 Subject: [PATCH 011/133] rtlil: Fix macc_v2 cell check --- kernel/rtlil.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 29a7ebf3e..c10e879c5 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1472,16 +1472,16 @@ namespace { error(__LINE__); if (param(ID::NADDENDS) <= 0) error(__LINE__); - param_bits(ID::PRODUCT_NEGATED, min(param(ID::NPRODUCTS), 1)); - param_bits(ID::ADDEND_NEGATED, min(param(ID::NADDENDS), 1)); - param_bits(ID::A_SIGNED, min(param(ID::NPRODUCTS), 1)); - param_bits(ID::B_SIGNED, min(param(ID::NPRODUCTS), 1)); - param_bits(ID::C_SIGNED, min(param(ID::NADDENDS), 1)); + param_bits(ID::PRODUCT_NEGATED, max(param(ID::NPRODUCTS), 1)); + param_bits(ID::ADDEND_NEGATED, max(param(ID::NADDENDS), 1)); + param_bits(ID::A_SIGNED, max(param(ID::NPRODUCTS), 1)); + param_bits(ID::B_SIGNED, max(param(ID::NPRODUCTS), 1)); + param_bits(ID::C_SIGNED, max(param(ID::NADDENDS), 1)); if (cell->getParam(ID::A_SIGNED) != cell->getParam(ID::B_SIGNED)) error(__LINE__); - param_bits(ID::A_WIDTHS, min(param(ID::NPRODUCTS) * 16, 1)); - param_bits(ID::B_WIDTHS, min(param(ID::NPRODUCTS) * 16, 1)); - param_bits(ID::C_WIDTHS, min(param(ID::NADDENDS) * 16, 1)); + param_bits(ID::A_WIDTHS, max(param(ID::NPRODUCTS) * 16, 1)); + param_bits(ID::B_WIDTHS, max(param(ID::NPRODUCTS) * 16, 1)); + param_bits(ID::C_WIDTHS, max(param(ID::NADDENDS) * 16, 1)); const Const &a_width = cell->getParam(ID::A_WIDTHS); const Const &b_width = cell->getParam(ID::B_WIDTHS); const Const &c_width = cell->getParam(ID::C_WIDTHS); From 3184b335dacc42dc4631931058630a04c4bcf277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 24 Jan 2025 12:35:36 +0100 Subject: [PATCH 012/133] macc_v2: Fix language constructs in simlib model --- techlibs/common/simlib.v | 53 +++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 248c93513..028e4e5a9 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1234,22 +1234,22 @@ parameter C_SIGNED = 1'bx; function integer sum_widths1; input [(16*NPRODUCTS)-1:0] widths; - int i; - sum_widths1 = 0; + integer i; begin + sum_widths1 = 0; for (i = 0; i < NPRODUCTS; i++) begin - sum_widths1 += widths[16*i+:16]; + sum_widths1 = sum_widths1 + widths[16*i+:16]; end end endfunction function integer sum_widths2; input [(16*NADDENDS)-1:0] widths; - int i; - sum_widths2 = 0; + integer i; begin + sum_widths2 = 0; for (i = 0; i < NADDENDS; i++) begin - sum_widths2 += widths[16*i+:16]; + sum_widths2 = sum_widths2 + widths[16*i+:16]; end end endfunction @@ -1261,9 +1261,7 @@ output reg [Y_WIDTH-1:0] Y; // output sum integer i, j, ai, bi, ci, aw, bw, cw; reg [Y_WIDTH-1:0] product; -reg signed [Y_WIDTH-1:0] product_signed; -reg [Y_WIDTH-1:0] addend; -reg signed [Y_WIDTH-1:0] addend_signed; +reg [Y_WIDTH-1:0] addend, oper_a, oper_b; always @* begin Y = 0; @@ -1274,20 +1272,29 @@ always @* begin aw = A_WIDTHS[16*i+:16]; bw = B_WIDTHS[16*i+:16]; - product = A[ai +: aw] * B[bi +: bw]; - product_signed = $signed(A[ai +: aw]) * $signed(B[bi +: bw]); - + oper_a = 0; + oper_b = 0; + for (j = 0; j < Y_WIDTH && j < aw; j = j + 1) + oper_a[j] = A[ai + j]; + for (j = 0; j < Y_WIDTH && j < bw; j = j + 1) + oper_b[j] = B[bi + j]; // A_SIGNED[i] == B_SIGNED[i] as RTLIL invariant - if (A_SIGNED[i] && B_SIGNED[i]) - product = product_signed; + if (A_SIGNED[i] && B_SIGNED[i]) begin + for (j = aw; j > 0 && j < Y_WIDTH; j = j + 1) + oper_a[j] = oper_a[j - 1]; + for (j = bw; j > 0 && j < Y_WIDTH; j = j + 1) + oper_b[j] = oper_b[j - 1]; + end + + product = oper_a * oper_b; if (PRODUCT_NEGATED[i]) Y = Y - product; else Y = Y + product; - ai += aw; - bi += bw; + ai = ai + aw; + bi = bi + bw; end ci = 0; @@ -1295,18 +1302,20 @@ always @* begin begin cw = C_WIDTHS[16*i+:16]; - addend = C[ci +: cw]; - addend_signed = $signed(C[ci +: cw]); - - if (C_SIGNED[i]) - addend = addend_signed; + addend = 0; + for (j = 0; j < Y_WIDTH && j < cw; j = j + 1) + addend[j] = C[ci + j]; + if (C_SIGNED[i]) begin + for (j = cw; j > 0 && j < Y_WIDTH; j = j + 1) + addend[j] = addend[j - 1]; + end if (ADDEND_NEGATED[i]) Y = Y - addend; else Y = Y + addend; - ci += cw; + ci = ci + cw; end end From aabb4ea1df3d5ef216b6fce95caf989333a14e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 27 Jan 2025 13:08:19 +0100 Subject: [PATCH 013/133] macc_v2: Fix checks and parameter padding --- kernel/macc.h | 17 +++++++++++++++++ kernel/rtlil.cc | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/kernel/macc.h b/kernel/macc.h index fdd738d45..5cf8d634d 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -228,6 +228,23 @@ struct Macc } } + if (a_signed.empty()) + a_signed = {RTLIL::Sx}; + if (b_signed.empty()) + a_signed = {RTLIL::Sx}; + if (c_signed.empty()) + c_signed = {RTLIL::Sx}; + if (a_widths.empty()) + a_widths = {RTLIL::Sx}; + if (b_widths.empty()) + b_widths = {RTLIL::Sx}; + if (c_widths.empty()) + c_widths = {RTLIL::Sx}; + if (product_negated.empty()) + product_negated = {RTLIL::Sx}; + if (addend_negated.empty()) + addend_negated = {RTLIL::Sx}; + cell->setParam(ID::NPRODUCTS, nproducts); cell->setParam(ID::PRODUCT_NEGATED, product_negated); cell->setParam(ID::NADDENDS, naddends); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index c10e879c5..d197660bd 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1470,7 +1470,7 @@ namespace { if (cell->type == ID($macc_v2)) { if (param(ID::NPRODUCTS) <= 0) error(__LINE__); - if (param(ID::NADDENDS) <= 0) + if (param(ID::NADDENDS) < 0) error(__LINE__); param_bits(ID::PRODUCT_NEGATED, max(param(ID::NPRODUCTS), 1)); param_bits(ID::ADDEND_NEGATED, max(param(ID::NADDENDS), 1)); From 6c76dcec3ea59d31b4fdda59be50ea87f2d8294d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 27 Jan 2025 13:08:44 +0100 Subject: [PATCH 014/133] macc_v2: Fix v2 omissions --- passes/techmap/techmap.cc | 8 ++++---- techlibs/common/techmap.v | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index b77bab69e..95c733f62 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -554,8 +554,8 @@ struct TechmapWorker if (extmapper_name == "maccmap") { log("Creating %s with maccmap.\n", log_id(extmapper_module)); - if (extmapper_cell->type != ID($macc)) - log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(extmapper_cell->type)); + if (!extmapper_cell->type.in(ID($macc), ID($macc_v2))) + log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", log_id(extmapper_cell->type)); maccmap(extmapper_module, extmapper_cell); extmapper_module->remove(extmapper_cell); } @@ -600,8 +600,8 @@ struct TechmapWorker } if (extmapper_name == "maccmap") { - if (cell->type != ID($macc)) - log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(cell->type)); + if (!cell->type.in(ID($macc), ID($macc_v2))) + log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", log_id(cell->type)); maccmap(module, cell); } diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 119296147..75651bb79 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -290,7 +290,7 @@ module _90_alu (A, B, CI, BI, X, Y, CO); endmodule (* techmap_maccmap *) -(* techmap_celltype = "$macc" *) +(* techmap_celltype = "$macc $macc_v2" *) module _90_macc; endmodule From 916fe998abfca65fabb417fec5737684dd323933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 27 Jan 2025 13:18:35 +0100 Subject: [PATCH 015/133] macc_v2: Add test --- tests/alumacc/basic.ys | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 tests/alumacc/basic.ys diff --git a/tests/alumacc/basic.ys b/tests/alumacc/basic.ys new file mode 100644 index 000000000..cdd20c472 --- /dev/null +++ b/tests/alumacc/basic.ys @@ -0,0 +1,61 @@ +read_verilog < Date: Mon, 27 Jan 2025 15:52:49 +0100 Subject: [PATCH 016/133] macc_v2: Relax and fix cell check --- kernel/macc.h | 2 +- kernel/rtlil.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/macc.h b/kernel/macc.h index 5cf8d634d..5fc6036ed 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -231,7 +231,7 @@ struct Macc if (a_signed.empty()) a_signed = {RTLIL::Sx}; if (b_signed.empty()) - a_signed = {RTLIL::Sx}; + b_signed = {RTLIL::Sx}; if (c_signed.empty()) c_signed = {RTLIL::Sx}; if (a_widths.empty()) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d197660bd..3b9a4a8b1 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1468,7 +1468,7 @@ namespace { } if (cell->type == ID($macc_v2)) { - if (param(ID::NPRODUCTS) <= 0) + if (param(ID::NPRODUCTS) < 0) error(__LINE__); if (param(ID::NADDENDS) < 0) error(__LINE__); From a8052f653a216f9501150abc94a09c14f8459254 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Fri, 14 Feb 2025 01:21:39 +0200 Subject: [PATCH 017/133] write_xaiger: Detect and error on combinatorial loops --- backends/aiger/xaiger.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 3ca8b205a..baf504ba2 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -53,6 +53,8 @@ struct XAigerWriter dict arrival_times; vector> aig_gates; + vector bit2aig_stack; + int next_loop_check = 1024; vector aig_outputs; int aig_m = 0, aig_i = 0, aig_l = 0, aig_o = 0, aig_a = 0; @@ -76,6 +78,24 @@ struct XAigerWriter return it->second; } + if (GetSize(bit2aig_stack)== next_loop_check) { + for (int i = 0; i < next_loop_check; ++i) + { + SigBit report_bit = bit2aig_stack[i]; + if (report_bit != bit) + continue; + for (int j = i; j < next_loop_check; ++j) { + report_bit = bit2aig_stack[j]; + if (report_bit.is_wire() && report_bit.wire->name.isPublic()) + break; + } + log_error("Found combinatorial logic loop while processing signal %s.\n", log_signal(report_bit)); + } + next_loop_check *= 2; + } + + bit2aig_stack.push_back(bit); + // NB: Cannot use iterator returned from aig_map.insert() // since this function is called recursively @@ -93,6 +113,8 @@ struct XAigerWriter a = bit2aig(alias_map.at(bit)); } + bit2aig_stack.pop_back(); + if (bit == State::Sx || bit == State::Sz) { log_debug("Design contains 'x' or 'z' bits. Treating as 1'b0.\n"); a = aig_map.at(State::S0); From cf65cb2cf10c0a2e6902cda325d6e677e63b4b82 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Fri, 14 Feb 2025 10:41:16 -0800 Subject: [PATCH 018/133] Copy abc stuff for pyosys --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 5bb6496c4..7c159e5b7 100644 --- a/Makefile +++ b/Makefile @@ -958,6 +958,10 @@ ifeq ($(ENABLE_LIBYOSYS),1) ifeq ($(ENABLE_PYOSYS),1) $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so + $(INSTALL_SUDO) cp -r share $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/share +ifeq ($(ENABLE_ABC),1) + $(INSTALL_SUDO) cp yosys-abc $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/yosys-abc +endif $(INSTALL_SUDO) cp misc/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/ endif endif From 8968986b543a6d3b42408ec5d3eb5996210ad209 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 14 Feb 2025 18:57:36 +0100 Subject: [PATCH 019/133] share: add -pattern-limit to set analysis effort on branch-unbranch mux regions --- passes/opt/share.cc | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 6081d140e..bf583dd32 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -23,6 +23,7 @@ #include "kernel/modtools.h" #include "kernel/utils.h" #include "kernel/macc.h" +#include USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -33,6 +34,7 @@ typedef std::pair ssc_pair_t; struct ShareWorkerConfig { int limit; + size_t pattern_limit; bool opt_force; bool opt_aggressive; bool opt_fast; @@ -853,6 +855,21 @@ struct ShareWorker optimize_activation_patterns(patterns); } + template + void insert_capped(pool& cache, Iterator begin_pattern, Iterator end_pattern) + { + if (cache.size() + std::distance(begin_pattern, end_pattern) > config.pattern_limit) { + cache.clear(); + cache.insert(ssc_pair_t()); + } else { + cache.insert(begin_pattern, end_pattern); + } + } + void insert_capped(pool& cache, ssc_pair_t pattern) + { + insert_capped(cache, &pattern, &pattern + 1); + } + const pool &find_cell_activation_patterns(RTLIL::Cell *cell, const char *indent) { if (recursion_state.count(cell)) { @@ -909,20 +926,20 @@ struct ShareWorker for (int i = 0; i < GetSize(sig_s); i++) p.first.append(sig_s[i]), p.second.bits().push_back(RTLIL::State::S0); if (sort_check_activation_pattern(p)) - activation_patterns_cache[cell].insert(p); + insert_capped(activation_patterns_cache[cell], p); } for (int idx : used_in_b_parts) for (auto p : c_patterns) { p.first.append(sig_s[idx]), p.second.bits().push_back(RTLIL::State::S1); if (sort_check_activation_pattern(p)) - activation_patterns_cache[cell].insert(p); + insert_capped(activation_patterns_cache[cell], p); } } for (auto c : driven_cells) { const pool &c_patterns = find_cell_activation_patterns(c, indent); - activation_patterns_cache[cell].insert(c_patterns.begin(), c_patterns.end()); + insert_capped(activation_patterns_cache[cell], c_patterns.begin(), c_patterns.end()); } log_assert(recursion_state.count(cell) != 0); @@ -1437,6 +1454,10 @@ struct SharePass : public Pass { log("\n"); log(" -limit N\n"); log(" Only perform the first N merges, then stop. This is useful for debugging.\n"); + log(" -pattern-limit N\n"); + log(" Only analyze up to N activation patterns per cell, otherwise assume active.\n"); + log(" N is 1000 by default. Higher values may merge more resources at the cost of\n"); + log(" more runtime and memory consumption.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override @@ -1444,6 +1465,7 @@ struct SharePass : public Pass { ShareWorkerConfig config; config.limit = -1; + config.pattern_limit = 1000; config.opt_force = false; config.opt_aggressive = false; config.opt_fast = false; @@ -1508,6 +1530,10 @@ struct SharePass : public Pass { config.limit = atoi(args[++argidx].c_str()); continue; } + if (args[argidx] == "-pattern-limit" && argidx+1 < args.size()) { + config.pattern_limit = atoi(args[++argidx].c_str()); + continue; + } break; } extra_args(args, argidx, design); From 8083d9b9dae601ccc6b00ab0a0d3c745a0e64ea9 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Fri, 14 Feb 2025 16:43:58 -0800 Subject: [PATCH 020/133] Fix share copy --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7c159e5b7..0249038e5 100644 --- a/Makefile +++ b/Makefile @@ -958,7 +958,7 @@ ifeq ($(ENABLE_LIBYOSYS),1) ifeq ($(ENABLE_PYOSYS),1) $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so - $(INSTALL_SUDO) cp -r share $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/share + $(INSTALL_SUDO) cp -r share $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys ifeq ($(ENABLE_ABC),1) $(INSTALL_SUDO) cp yosys-abc $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/yosys-abc endif From 9a14ab8d98cdaaf2a680ad744aeb11db2226c592 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Fri, 28 Feb 2025 13:51:22 +0200 Subject: [PATCH 021/133] splitcells: Fix the assertion bug caused by out-of-bound offset --- passes/cmds/splitcells.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/passes/cmds/splitcells.cc b/passes/cmds/splitcells.cc index 074bf0f64..e3d509564 100644 --- a/passes/cmds/splitcells.cc +++ b/passes/cmds/splitcells.cc @@ -103,8 +103,7 @@ struct SplitcellsWorker auto slice_signal = [&](SigSpec old_sig) -> SigSpec { SigSpec new_sig; - for (int i = 0; i < GetSize(old_sig); i += GetSize(outsig)) { - int offset = i+slice_lsb; + for (int offset = slice_lsb; offset <= GetSize(old_sig); offset += GetSize(outsig)) { int length = std::min(GetSize(old_sig)-offset, slice_msb-slice_lsb+1); new_sig.append(old_sig.extract(offset, length)); } From de032d2e2ac766df596ab4a11ecf14175b9c8fb4 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Fri, 28 Feb 2025 23:16:04 +0200 Subject: [PATCH 022/133] splitcells: change for-loop condition --- passes/cmds/splitcells.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/splitcells.cc b/passes/cmds/splitcells.cc index e3d509564..d2063a0c8 100644 --- a/passes/cmds/splitcells.cc +++ b/passes/cmds/splitcells.cc @@ -103,7 +103,7 @@ struct SplitcellsWorker auto slice_signal = [&](SigSpec old_sig) -> SigSpec { SigSpec new_sig; - for (int offset = slice_lsb; offset <= GetSize(old_sig); offset += GetSize(outsig)) { + for (int offset = slice_lsb; offset < GetSize(old_sig); offset += GetSize(outsig)) { int length = std::min(GetSize(old_sig)-offset, slice_msb-slice_lsb+1); new_sig.append(old_sig.extract(offset, length)); } From 912c93ca0ba75e109c184aae32e10f2df4bc5b4d Mon Sep 17 00:00:00 2001 From: Emil J Date: Mon, 3 Mar 2025 18:52:05 +0100 Subject: [PATCH 023/133] share: help message formatting Co-authored-by: KrystalDelusion <93062060+KrystalDelusion@users.noreply.github.com> --- passes/opt/share.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index bf583dd32..20ec8d358 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -1454,6 +1454,7 @@ struct SharePass : public Pass { log("\n"); log(" -limit N\n"); log(" Only perform the first N merges, then stop. This is useful for debugging.\n"); + log("\n"); log(" -pattern-limit N\n"); log(" Only analyze up to N activation patterns per cell, otherwise assume active.\n"); log(" N is 1000 by default. Higher values may merge more resources at the cost of\n"); From f62a9be15352d000228584bcb1984030dbefe6e4 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Sun, 2 Mar 2025 12:24:57 -0500 Subject: [PATCH 024/133] Initial file list support --- frontends/verilog/verilog_frontend.cc | 76 +++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index d363d71fb..5328ad404 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -26,6 +26,8 @@ * */ +#include + #include "verilog_frontend.h" #include "preproc.h" #include "kernel/yosys.h" @@ -672,6 +674,80 @@ struct VerilogDefines : public Pass { } } VerilogDefines; +struct VerilogFilelist : public Pass { + VerilogFilelist() : Pass("verilog_filelist", "use filelist") {} + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" verilog_filelist [options]\n"); + log("\n"); + log("Load a Verilog file list, and pass list of Verilog files to read_verilog command.\n"); + log("\n"); + log(" -Fflist\n"); + log(" File list file contains list of Verilog to be parsed, any\n"); + log(" ' path is relative to the file list file'\n"); + log("\n"); + log(" -Fflist\n"); + log(" File list file contains list of Verilog to be parsed, any\n"); + log(" ' path is relative to current working directroy'\n"); + log("\n"); + } + + void parse_flist_rel_filelist(const std::string &flist_path, RTLIL::Design *design) + { + std::ifstream ifs(flist_path); + if (!ifs.is_open()) { + log_error("file list file does not exist"); + exit(1); + } + + std::filesystem::path flist_parent_dir = std::filesystem::path(flist_path).parent_path(); + + std::string v_file_name; + while (std::getline(ifs, v_file_name)) { + if (v_file_name.empty()) { + continue; + } + std::string v_file_path = flist_parent_dir.string() + '/' + v_file_name; + log("Verilog file %s\n", v_file_path.c_str()); + + bool is_sv = (std::filesystem::path(v_file_path).extension() == ".sv"); + + std::string command = "read_verilog"; + if (is_sv) { + command += " -sv"; + } + command = command + ' ' + v_file_path; + Pass::call(design, command); + } + } + + void parse_flist_rel_pwd(const std::string &flist_path, RTLIL::Design *design) { log("pwd %s\n", flist_path.c_str()); } + + void execute(std::vector args, RTLIL::Design *design) override + { + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + std::string arg = args[argidx]; + if (arg == "-F" && argidx + 1 < args.size()) { + std::string flist_path = args[++argidx]; + parse_flist_rel_filelist(flist_path, design); + continue; + } + if (arg == "-f" && argidx + 1 < args.size()) { + std::string flist_path = args[++argidx]; + parse_flist_rel_pwd(flist_path, design); + continue; + } + break; + } + + if (args.size() != argidx) + cmd_error(args, argidx, "Extra argument."); + } +} VerilogFilelist; + YOSYS_NAMESPACE_END // the yyerror function used by bison to report parser errors From 8f46f53f183b9e4cb7011b185ba0632efdf95514 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Sun, 2 Mar 2025 12:29:56 -0500 Subject: [PATCH 025/133] Add clangd cache to gitignore file --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5c3d8f4e9..3c209ff4f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ *.gcno *~ __pycache__ +/.cache /.cproject /.project /.settings @@ -52,3 +53,4 @@ __pycache__ /venv /boost /ffi +/compile_commands.json From 0678c4dec97d0ad3d83220c75cee8d65f419a4f1 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Sun, 2 Mar 2025 21:07:00 -0500 Subject: [PATCH 026/133] Coding style update --- frontends/verilog/verilog_frontend.cc | 60 +++++++++++++++------------ 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 5328ad404..d2cea3599 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -674,56 +674,61 @@ struct VerilogDefines : public Pass { } } VerilogDefines; -struct VerilogFilelist : public Pass { - VerilogFilelist() : Pass("verilog_filelist", "use filelist") {} +struct VerilogFileList : public Pass { + VerilogFileList() : Pass("read_verilog_file_list", "Parse a Verilog file list") {} void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" verilog_filelist [options]\n"); + log(" read_verilog_file_list [options]\n"); log("\n"); - log("Load a Verilog file list, and pass list of Verilog files to read_verilog command.\n"); + log("Parse a Verilog file list, and pass the list of Verilog files to read_verilog command.\n"); log("\n"); - log(" -Fflist\n"); - log(" File list file contains list of Verilog to be parsed, any\n"); - log(" ' path is relative to the file list file'\n"); + log(" -F file_list_path\n"); + log(" File list file contains list of Verilog files to be parsed, any\n"); + log(" ' path is treated relative to the file list file'\n"); log("\n"); - log(" -Fflist\n"); - log(" File list file contains list of Verilog to be parsed, any\n"); - log(" ' path is relative to current working directroy'\n"); + log(" -f file_list_path\n"); + log(" File list file contains list of Verilog files to be parsed, any\n"); + log(" ' path is treated relative to current working directroy'\n"); log("\n"); } - void parse_flist_rel_filelist(const std::string &flist_path, RTLIL::Design *design) + void parse_file_list(const std::string &file_list_path, RTLIL::Design *design, bool relative_to_file_list_path) { - std::ifstream ifs(flist_path); - if (!ifs.is_open()) { - log_error("file list file does not exist"); + std::ifstream flist(file_list_path); + if (!flist.is_open()) { + log_error("Verilog file list file does not exist"); exit(1); } - std::filesystem::path flist_parent_dir = std::filesystem::path(flist_path).parent_path(); + std::filesystem::path file_list_parent_dir = std::filesystem::path(file_list_path).parent_path(); std::string v_file_name; - while (std::getline(ifs, v_file_name)) { + while (std::getline(flist, v_file_name)) { if (v_file_name.empty()) { continue; } - std::string v_file_path = flist_parent_dir.string() + '/' + v_file_name; - log("Verilog file %s\n", v_file_path.c_str()); - bool is_sv = (std::filesystem::path(v_file_path).extension() == ".sv"); + std::string verilog_file_path; + if (relative_to_file_list_path) { + verilog_file_path = file_list_parent_dir.string() + '/' + v_file_name; + } else { + verilog_file_path = std::filesystem::current_path().string() + '/' + v_file_name; + } + + bool is_sv = (std::filesystem::path(verilog_file_path).extension() == ".sv"); std::string command = "read_verilog"; if (is_sv) { command += " -sv"; } - command = command + ' ' + v_file_path; + command = command + ' ' + verilog_file_path; Pass::call(design, command); } - } - void parse_flist_rel_pwd(const std::string &flist_path, RTLIL::Design *design) { log("pwd %s\n", flist_path.c_str()); } + flist.close(); + } void execute(std::vector args, RTLIL::Design *design) override { @@ -731,20 +736,21 @@ struct VerilogFilelist : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; if (arg == "-F" && argidx + 1 < args.size()) { - std::string flist_path = args[++argidx]; - parse_flist_rel_filelist(flist_path, design); + std::string file_list_path = args[++argidx]; + parse_file_list(file_list_path, design, true); continue; } if (arg == "-f" && argidx + 1 < args.size()) { - std::string flist_path = args[++argidx]; - parse_flist_rel_pwd(flist_path, design); + std::string file_list_path = args[++argidx]; + parse_file_list(file_list_path, design, false); continue; } break; } - if (args.size() != argidx) + if (args.size() != argidx) { cmd_error(args, argidx, "Extra argument."); + } } } VerilogFilelist; From 8ec96ec8065bb42570ddc5ecd843331a31990032 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Fri, 7 Mar 2025 00:50:28 -0500 Subject: [PATCH 027/133] Address most comments --- .gitignore | 2 +- frontends/verilog/verilog_frontend.cc | 24 +++++++++++------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 3c209ff4f..239ae742b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ __pycache__ /qtcreator.config /qtcreator.creator /qtcreator.creator.user +/compile_commands.json /coverage.info /coverage_html /Makefile.conf @@ -53,4 +54,3 @@ __pycache__ /venv /boost /ffi -/compile_commands.json diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index d2cea3599..fd317bf22 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -686,11 +686,11 @@ struct VerilogFileList : public Pass { log("\n"); log(" -F file_list_path\n"); log(" File list file contains list of Verilog files to be parsed, any\n"); - log(" ' path is treated relative to the file list file'\n"); + log(" path is treated relative to the file list file\n"); log("\n"); log(" -f file_list_path\n"); log(" File list file contains list of Verilog files to be parsed, any\n"); - log(" ' path is treated relative to current working directroy'\n"); + log(" path is treated relative to current working directroy\n"); log("\n"); } @@ -710,21 +710,21 @@ struct VerilogFileList : public Pass { continue; } - std::string verilog_file_path; + std::filesystem::path verilog_file_path; if (relative_to_file_list_path) { - verilog_file_path = file_list_parent_dir.string() + '/' + v_file_name; + verilog_file_path = file_list_parent_dir / v_file_name; } else { - verilog_file_path = std::filesystem::current_path().string() + '/' + v_file_name; + verilog_file_path = std::filesystem::current_path() / v_file_name; } - bool is_sv = (std::filesystem::path(verilog_file_path).extension() == ".sv"); + bool is_sv = (verilog_file_path.extension() == ".sv"); - std::string command = "read_verilog"; + std::vector read_verilog_cmd = {"read_verilog", "-defer"}; if (is_sv) { - command += " -sv"; + read_verilog_cmd.push_back("-sv"); } - command = command + ' ' + verilog_file_path; - Pass::call(design, command); + read_verilog_cmd.push_back(verilog_file_path.string()); + Pass::call(design, read_verilog_cmd); } flist.close(); @@ -748,9 +748,7 @@ struct VerilogFileList : public Pass { break; } - if (args.size() != argidx) { - cmd_error(args, argidx, "Extra argument."); - } + extra_args(args, argidx, design); } } VerilogFilelist; From ac31bad6569306450a28d9cd0bdf52ed51aceb93 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Fri, 7 Mar 2025 00:57:39 -0500 Subject: [PATCH 028/133] Address all comments --- frontends/verilog/verilog_frontend.cc | 72 +++++++++++++-------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index fd317bf22..723f2d589 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -674,6 +674,42 @@ struct VerilogDefines : public Pass { } } VerilogDefines; +static void parse_file_list(const std::string &file_list_path, RTLIL::Design *design, bool relative_to_file_list_path) +{ + std::ifstream flist(file_list_path); + if (!flist.is_open()) { + log_error("Verilog file list file does not exist"); + exit(1); + } + + std::filesystem::path file_list_parent_dir = std::filesystem::path(file_list_path).parent_path(); + + std::string v_file_name; + while (std::getline(flist, v_file_name)) { + if (v_file_name.empty()) { + continue; + } + + std::filesystem::path verilog_file_path; + if (relative_to_file_list_path) { + verilog_file_path = file_list_parent_dir / v_file_name; + } else { + verilog_file_path = std::filesystem::current_path() / v_file_name; + } + + bool is_sv = (verilog_file_path.extension() == ".sv"); + + std::vector read_verilog_cmd = {"read_verilog", "-defer"}; + if (is_sv) { + read_verilog_cmd.push_back("-sv"); + } + read_verilog_cmd.push_back(verilog_file_path.string()); + Pass::call(design, read_verilog_cmd); + } + + flist.close(); +} + struct VerilogFileList : public Pass { VerilogFileList() : Pass("read_verilog_file_list", "Parse a Verilog file list") {} void help() override @@ -694,42 +730,6 @@ struct VerilogFileList : public Pass { log("\n"); } - void parse_file_list(const std::string &file_list_path, RTLIL::Design *design, bool relative_to_file_list_path) - { - std::ifstream flist(file_list_path); - if (!flist.is_open()) { - log_error("Verilog file list file does not exist"); - exit(1); - } - - std::filesystem::path file_list_parent_dir = std::filesystem::path(file_list_path).parent_path(); - - std::string v_file_name; - while (std::getline(flist, v_file_name)) { - if (v_file_name.empty()) { - continue; - } - - std::filesystem::path verilog_file_path; - if (relative_to_file_list_path) { - verilog_file_path = file_list_parent_dir / v_file_name; - } else { - verilog_file_path = std::filesystem::current_path() / v_file_name; - } - - bool is_sv = (verilog_file_path.extension() == ".sv"); - - std::vector read_verilog_cmd = {"read_verilog", "-defer"}; - if (is_sv) { - read_verilog_cmd.push_back("-sv"); - } - read_verilog_cmd.push_back(verilog_file_path.string()); - Pass::call(design, read_verilog_cmd); - } - - flist.close(); - } - void execute(std::vector args, RTLIL::Design *design) override { size_t argidx; From bf1eab565b0f843b9472794f0fbfeabaa49091f7 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:20:27 -0500 Subject: [PATCH 029/133] Fix compile on WASI platform --- frontends/verilog/verilog_frontend.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 723f2d589..737481743 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -26,7 +26,9 @@ * */ +#if !defined(__wasm) #include +#endif #include "verilog_frontend.h" #include "preproc.h" @@ -674,6 +676,8 @@ struct VerilogDefines : public Pass { } } VerilogDefines; +#if !defined(__wasm) + static void parse_file_list(const std::string &file_list_path, RTLIL::Design *design, bool relative_to_file_list_path) { std::ifstream flist(file_list_path); @@ -721,12 +725,10 @@ struct VerilogFileList : public Pass { log("Parse a Verilog file list, and pass the list of Verilog files to read_verilog command.\n"); log("\n"); log(" -F file_list_path\n"); - log(" File list file contains list of Verilog files to be parsed, any\n"); - log(" path is treated relative to the file list file\n"); + log(" File list file contains list of Verilog files to be parsed, any path is treated relative to the file list file\n"); log("\n"); log(" -f file_list_path\n"); - log(" File list file contains list of Verilog files to be parsed, any\n"); - log(" path is treated relative to current working directroy\n"); + log(" File list file contains list of Verilog files to be parsed, any path is treated relative to current working directroy\n"); log("\n"); } @@ -752,6 +754,8 @@ struct VerilogFileList : public Pass { } } VerilogFilelist; +#endif + YOSYS_NAMESPACE_END // the yyerror function used by bison to report parser errors From 98eefc5d1adcf6aec1dce8877c2f4f0780fa085b Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:44:21 -0500 Subject: [PATCH 030/133] Add file list support to read pass --- frontends/verific/verific.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index cdd0ed802..19f17b0ff 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -4298,7 +4298,7 @@ struct ReadPass : public Pass { log("\n"); log(" read {-f|-F} \n"); log("\n"); - log("Load and execute the specified command file. (Requires Verific.)\n"); + log("Load and execute the specified command file.\n"); log("Check verific command for more information about supported commands in file.\n"); log("\n"); log("\n"); @@ -4412,10 +4412,10 @@ struct ReadPass : public Pass { if (args[1] == "-f" || args[1] == "-F") { if (use_verific) { args[0] = "verific"; - Pass::call(design, args); } else { - cmd_error(args, 1, "This version of Yosys is built without Verific support.\n"); + args[0] = "read_verilog_file_list"; } + Pass::call(design, args); return; } From cbb776c62690ddf6fea4e79f48cdc60c11eb3c22 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 18 Oct 2024 16:25:15 +0200 Subject: [PATCH 031/133] opt_merge: avoid hashing strings --- passes/opt/opt_merge.cc | 173 +++++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 83 deletions(-) diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index eb3aa462e..d6ed74433 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -26,6 +26,8 @@ #include #include #include +#include +#include USING_YOSYS_NAMESPACE @@ -42,6 +44,22 @@ struct OptMergeWorker CellTypes ct; int total_count; + static vector> sorted_pmux_in(const dict &conn) + { + SigSpec sig_s = conn.at(ID::S); + SigSpec sig_b = conn.at(ID::B); + + int s_width = GetSize(sig_s); + int width = GetSize(sig_b) / s_width; + + vector> sb_pairs; + for (int i = 0; i < s_width; i++) + sb_pairs.push_back(pair(sig_s[i], sig_b.extract(i*width, width))); + + std::sort(sb_pairs.begin(), sb_pairs.end()); + return sb_pairs; + } + static void sort_pmux_conn(dict &conn) { SigSpec sig_s = conn.at(ID::S); @@ -65,90 +83,74 @@ struct OptMergeWorker } } - std::string int_to_hash_string(unsigned int v) + Hasher hash_cell_inputs(const RTLIL::Cell *cell, Hasher h) { - if (v == 0) - return "0"; - std::string str = ""; - while (v > 0) { - str += 'a' + (v & 15); - v = v >> 4; - } - return str; - } - - uint64_t hash_cell_parameters_and_connections(const RTLIL::Cell *cell) - { - vector hash_conn_strings; - std::string hash_string = cell->type.str() + "\n"; - - const dict *conn = &cell->connections(); - dict alt_conn; - + // TODO: when implemented, use celltypes to match: + // (builtin || stdcell) && (unary || binary) && symmetrical if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($mul), ID($logic_and), ID($logic_or), ID($_AND_), ID($_OR_), ID($_XOR_))) { - alt_conn = *conn; - if (assign_map(alt_conn.at(ID::A)) < assign_map(alt_conn.at(ID::B))) { - alt_conn[ID::A] = conn->at(ID::B); - alt_conn[ID::B] = conn->at(ID::A); + std::array inputs = { + assign_map(cell->getPort(ID::A)), + assign_map(cell->getPort(ID::B)) + }; + std::sort(inputs.begin(), inputs.end()); + h = hash_ops>::hash_acc(inputs, h); + h = assign_map(cell->getPort(ID::Y)).hash_acc(h); + } else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { + SigSpec a = assign_map(cell->getPort(ID::A)); + a.sort(); + h = a.hash_acc(h); + } else if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) { + SigSpec a = assign_map(cell->getPort(ID::A)); + a.sort_and_unify(); + h = a.hash_acc(h); + } else if (cell->type == ID($pmux)) { + dict conn = cell->connections(); + assign_map.apply(conn.at(ID::A)); + assign_map.apply(conn.at(ID::B)); + assign_map.apply(conn.at(ID::S)); + for (const auto& [s_bit, b_chunk] : sorted_pmux_in(conn)) { + h = s_bit.hash_acc(h); + h = b_chunk.hash_acc(h); } - conn = &alt_conn; - } else - if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { - alt_conn = *conn; - assign_map.apply(alt_conn.at(ID::A)); - alt_conn.at(ID::A).sort(); - conn = &alt_conn; - } else - if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) { - alt_conn = *conn; - assign_map.apply(alt_conn.at(ID::A)); - alt_conn.at(ID::A).sort_and_unify(); - conn = &alt_conn; - } else - if (cell->type == ID($pmux)) { - alt_conn = *conn; - assign_map.apply(alt_conn.at(ID::A)); - assign_map.apply(alt_conn.at(ID::B)); - assign_map.apply(alt_conn.at(ID::S)); - sort_pmux_conn(alt_conn); - conn = &alt_conn; - } - - for (auto &it : *conn) { - RTLIL::SigSpec sig; - if (cell->output(it.first)) { - if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) { - // For the 'Q' output of state elements, - // use its (* init *) attribute value - sig = initvals(it.second); + h = assign_map(cell->getPort(ID::A)).hash_acc(h); + } else { + std::vector> conns; + for (const auto& conn : cell->connections()) { + conns.push_back(conn); + } + std::sort(conns.begin(), conns.end()); + for (const auto& [port, sig] : conns) { + if (!cell->output(port)) { + h = port.hash_acc(h); + h = assign_map(sig).hash_acc(h); } - else - continue; } - else - sig = assign_map(it.second); - string s = "C " + it.first.str() + "="; - for (auto &chunk : sig.chunks()) { - if (chunk.wire) - s += "{" + chunk.wire->name.str() + " " + - int_to_hash_string(chunk.offset) + " " + - int_to_hash_string(chunk.width) + "}"; - else - s += RTLIL::Const(chunk.data).as_string(); - } - hash_conn_strings.push_back(s + "\n"); + + if (RTLIL::builtin_ff_cell_types().count(cell->type)) + h = initvals(cell->getPort(ID::Q)).hash_acc(h); + } + return h; + } - for (auto &it : cell->parameters) - hash_conn_strings.push_back("P " + it.first.str() + "=" + it.second.as_string() + "\n"); + static Hasher hash_cell_parameters(const RTLIL::Cell *cell, Hasher h) + { + using Paramvec = std::vector>; + Paramvec params; + for (const auto& param : cell->parameters) { + params.push_back(param); + } + std::sort(params.begin(), params.end()); + return hash_ops::hash_acc(params, h); + } - std::sort(hash_conn_strings.begin(), hash_conn_strings.end()); - - for (auto it : hash_conn_strings) - hash_string += it; - - return std::hash{}(hash_string); + Hasher hash_cell_function(const RTLIL::Cell *cell, Hasher h) + { + h.eat(cell->type); + h = hash_cell_inputs(cell, h); + h = hash_cell_parameters(cell, h); + return h; } bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) @@ -255,18 +257,23 @@ struct OptMergeWorker while (did_something) { std::vector cells; - cells.reserve(module->cells_.size()); - for (auto &it : module->cells_) { - if (!design->selected(module, it.second)) + cells.reserve(module->cells().size()); + for (auto cell : module->cells()) { + if (!design->selected(module, cell)) continue; - if (mode_keepdc && has_dont_care_initval(it.second)) + if (cell->type.in(ID($meminit), ID($meminit_v2), ID($mem), ID($mem_v2))) { + // Ignore those for performance: meminit can have an excessively large port, + // mem can have an excessively large parameter holding the init data continue; - if (ct.cell_known(it.second->type) || (mode_share_all && it.second->known())) - cells.push_back(it.second); + } + if (mode_keepdc && has_dont_care_initval(cell)) + continue; + if (ct.cell_known(cell->type) || (mode_share_all && cell->known())) + cells.push_back(cell); } did_something = false; - dict sharemap; + dict sharemap; for (auto cell : cells) { if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known()) @@ -275,7 +282,7 @@ struct OptMergeWorker if (cell->type == ID($scopeinfo)) continue; - uint64_t hash = hash_cell_parameters_and_connections(cell); + Hasher::hash_t hash = hash_cell_function(cell, Hasher()).yield(); auto r = sharemap.insert(std::make_pair(hash, cell)); if (!r.second) { if (compare_cell_parameters_and_connections(cell, r.first->second)) { From ffc057a89c76f922c4bd5c13383551fc6f9233a3 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 18 Oct 2024 20:39:52 +0200 Subject: [PATCH 032/133] opt_merge: fix the many collisions case --- passes/opt/opt_merge.cc | 45 ++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index d6ed74433..025a6c977 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -254,6 +254,11 @@ struct OptMergeWorker initvals.set(&assign_map, module); bool did_something = true; + bool warned_collisions = false; + // A cell may have to go through a lot of collisions if the hash + // function is performing poorly, but it's a symptom of something bad + // beyond the user's control. + int threshold = 1000; // adjust to taste while (did_something) { std::vector cells; @@ -273,7 +278,10 @@ struct OptMergeWorker } did_something = false; - dict sharemap; + // INVARIANT: All cells associated with the same hash in sharemap + // are distinct as far as compare_cell_parameters_and_connections + // can tell. + std::unordered_multimap sharemap; for (auto cell : cells) { if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known()) @@ -283,21 +291,30 @@ struct OptMergeWorker continue; Hasher::hash_t hash = hash_cell_function(cell, Hasher()).yield(); - auto r = sharemap.insert(std::make_pair(hash, cell)); - if (!r.second) { - if (compare_cell_parameters_and_connections(cell, r.first->second)) { + // Get all cells with matching hashes + auto matching = sharemap.equal_range(hash); + int collisions = 0; + bool found = false; + for (auto it = matching.first; it != matching.second && !found; ++it) { + if (collisions > threshold && !warned_collisions) { + log_warning("High hash collision counts. opt_merge runtime may be excessive.\n" \ + "Please report to maintainers.\n"); + warned_collisions = true; + } + auto other_cell = it->second; + if (compare_cell_parameters_and_connections(cell, other_cell)) { + found = true; if (cell->has_keep_attr()) { - if (r.first->second->has_keep_attr()) + if (other_cell->has_keep_attr()) continue; - std::swap(r.first->second, cell); + std::swap(other_cell, cell); } - did_something = true; - log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), r.first->second->name.c_str()); + log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), other_cell->name.c_str()); for (auto &it : cell->connections()) { if (cell->output(it.first)) { - RTLIL::SigSpec other_sig = r.first->second->getPort(it.first); + RTLIL::SigSpec other_sig = other_cell->getPort(it.first); log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(), log_signal(it.second), log_signal(other_sig)); Const init = initvals(other_sig); @@ -311,8 +328,18 @@ struct OptMergeWorker log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); module->remove(cell); total_count++; + break; + } else { + collisions++; + log_debug(" False hash match: `%s' and `%s'.\n", cell->name.c_str(), other_cell->name.c_str()); } } + if (!did_something) { + // This cell isn't represented yet in the sharemap. + // Either it's the first of its hash, + // or falsely matches all cells in sharemap sharing its hash. + sharemap.insert(std::make_pair(hash, cell)); + } } } From 890374014714532726ceab36d7b4eedb78e119eb Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 12 Nov 2024 14:59:09 +0100 Subject: [PATCH 033/133] opt_merge: switch to unordered_set --- passes/opt/opt_merge.cc | 126 +++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 65 deletions(-) diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 025a6c977..1992aa871 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -83,7 +83,7 @@ struct OptMergeWorker } } - Hasher hash_cell_inputs(const RTLIL::Cell *cell, Hasher h) + Hasher hash_cell_inputs(const RTLIL::Cell *cell, Hasher h) const { // TODO: when implemented, use celltypes to match: // (builtin || stdcell) && (unary || binary) && symmetrical @@ -94,26 +94,26 @@ struct OptMergeWorker assign_map(cell->getPort(ID::B)) }; std::sort(inputs.begin(), inputs.end()); - h = hash_ops>::hash_acc(inputs, h); - h = assign_map(cell->getPort(ID::Y)).hash_acc(h); + h = hash_ops>::hash_into(inputs, h); + h = assign_map(cell->getPort(ID::Y)).hash_into(h); } else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { SigSpec a = assign_map(cell->getPort(ID::A)); a.sort(); - h = a.hash_acc(h); + h = a.hash_into(h); } else if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) { SigSpec a = assign_map(cell->getPort(ID::A)); a.sort_and_unify(); - h = a.hash_acc(h); + h = a.hash_into(h); } else if (cell->type == ID($pmux)) { dict conn = cell->connections(); assign_map.apply(conn.at(ID::A)); assign_map.apply(conn.at(ID::B)); assign_map.apply(conn.at(ID::S)); for (const auto& [s_bit, b_chunk] : sorted_pmux_in(conn)) { - h = s_bit.hash_acc(h); - h = b_chunk.hash_acc(h); + h = s_bit.hash_into(h); + h = b_chunk.hash_into(h); } - h = assign_map(cell->getPort(ID::A)).hash_acc(h); + h = assign_map(cell->getPort(ID::A)).hash_into(h); } else { std::vector> conns; for (const auto& conn : cell->connections()) { @@ -122,13 +122,13 @@ struct OptMergeWorker std::sort(conns.begin(), conns.end()); for (const auto& [port, sig] : conns) { if (!cell->output(port)) { - h = port.hash_acc(h); - h = assign_map(sig).hash_acc(h); + h = port.hash_into(h); + h = assign_map(sig).hash_into(h); } } if (RTLIL::builtin_ff_cell_types().count(cell->type)) - h = initvals(cell->getPort(ID::Q)).hash_acc(h); + h = initvals(cell->getPort(ID::Q)).hash_into(h); } return h; @@ -142,10 +142,10 @@ struct OptMergeWorker params.push_back(param); } std::sort(params.begin(), params.end()); - return hash_ops::hash_acc(params, h); + return hash_ops::hash_into(params, h); } - Hasher hash_cell_function(const RTLIL::Cell *cell, Hasher h) + Hasher hash_cell_function(const RTLIL::Cell *cell, Hasher h) const { h.eat(cell->type); h = hash_cell_inputs(cell, h); @@ -153,7 +153,7 @@ struct OptMergeWorker return h; } - bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) + bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) const { log_assert(cell1 != cell2); if (cell1->type != cell2->type) return false; @@ -254,11 +254,9 @@ struct OptMergeWorker initvals.set(&assign_map, module); bool did_something = true; - bool warned_collisions = false; // A cell may have to go through a lot of collisions if the hash // function is performing poorly, but it's a symptom of something bad // beyond the user's control. - int threshold = 1000; // adjust to taste while (did_something) { std::vector cells; @@ -278,10 +276,29 @@ struct OptMergeWorker } did_something = false; - // INVARIANT: All cells associated with the same hash in sharemap - // are distinct as far as compare_cell_parameters_and_connections - // can tell. - std::unordered_multimap sharemap; + + // We keep a set of known cells. They're hashed with our hash_cell_function + // and compared with our compare_cell_parameters_and_connections. + // Both need to capture OptMergeWorker to access initvals + struct CellPtrHash { + const OptMergeWorker& worker; + CellPtrHash(const OptMergeWorker& w) : worker(w) {} + std::size_t operator()(const Cell* c) const { + return (std::size_t)worker.hash_cell_function(c, Hasher()).yield(); + } + }; + struct CellPtrEqual { + const OptMergeWorker& worker; + CellPtrEqual(const OptMergeWorker& w) : worker(w) {} + bool operator()(const Cell* lhs, const Cell* rhs) const { + return worker.compare_cell_parameters_and_connections(lhs, rhs); + } + }; + std::unordered_set< + RTLIL::Cell*, + CellPtrHash, + CellPtrEqual> known_cells (0, CellPtrHash(*this), CellPtrEqual(*this)); + for (auto cell : cells) { if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known()) @@ -290,55 +307,34 @@ struct OptMergeWorker if (cell->type == ID($scopeinfo)) continue; - Hasher::hash_t hash = hash_cell_function(cell, Hasher()).yield(); - // Get all cells with matching hashes - auto matching = sharemap.equal_range(hash); - int collisions = 0; - bool found = false; - for (auto it = matching.first; it != matching.second && !found; ++it) { - if (collisions > threshold && !warned_collisions) { - log_warning("High hash collision counts. opt_merge runtime may be excessive.\n" \ - "Please report to maintainers.\n"); - warned_collisions = true; + auto [cell_in_map, inserted] = known_cells.insert(cell); + if (!inserted) { + // We've failed to insert since we already have an equivalent cell + Cell* other_cell = *cell_in_map; + if (cell->has_keep_attr()) { + if (other_cell->has_keep_attr()) + continue; + std::swap(other_cell, cell); } - auto other_cell = it->second; - if (compare_cell_parameters_and_connections(cell, other_cell)) { - found = true; - if (cell->has_keep_attr()) { - if (other_cell->has_keep_attr()) - continue; - std::swap(other_cell, cell); - } - did_something = true; - log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), other_cell->name.c_str()); - for (auto &it : cell->connections()) { - if (cell->output(it.first)) { - RTLIL::SigSpec other_sig = other_cell->getPort(it.first); - log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(), - log_signal(it.second), log_signal(other_sig)); - Const init = initvals(other_sig); - initvals.remove_init(it.second); - initvals.remove_init(other_sig); - module->connect(RTLIL::SigSig(it.second, other_sig)); - assign_map.add(it.second, other_sig); - initvals.set_init(other_sig, init); - } + did_something = true; + log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), other_cell->name.c_str()); + for (auto &it : cell->connections()) { + if (cell->output(it.first)) { + RTLIL::SigSpec other_sig = other_cell->getPort(it.first); + log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(), + log_signal(it.second), log_signal(other_sig)); + Const init = initvals(other_sig); + initvals.remove_init(it.second); + initvals.remove_init(other_sig); + module->connect(RTLIL::SigSig(it.second, other_sig)); + assign_map.add(it.second, other_sig); + initvals.set_init(other_sig, init); } - log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); - module->remove(cell); - total_count++; - break; - } else { - collisions++; - log_debug(" False hash match: `%s' and `%s'.\n", cell->name.c_str(), other_cell->name.c_str()); } - } - if (!did_something) { - // This cell isn't represented yet in the sharemap. - // Either it's the first of its hash, - // or falsely matches all cells in sharemap sharing its hash. - sharemap.insert(std::make_pair(hash, cell)); + log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); + module->remove(cell); + total_count++; } } } From 176faae7c94b0dea13052b17d4f210cb19b2d7ba Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Mon, 10 Mar 2025 11:43:13 +0100 Subject: [PATCH 034/133] opt_merge: fix trivial binary regression --- passes/opt/opt_merge.cc | 1 - tests/opt/opt_merge_basic.ys | 13 +++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tests/opt/opt_merge_basic.ys diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 1992aa871..745b27e87 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -95,7 +95,6 @@ struct OptMergeWorker }; std::sort(inputs.begin(), inputs.end()); h = hash_ops>::hash_into(inputs, h); - h = assign_map(cell->getPort(ID::Y)).hash_into(h); } else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { SigSpec a = assign_map(cell->getPort(ID::A)); a.sort(); diff --git a/tests/opt/opt_merge_basic.ys b/tests/opt/opt_merge_basic.ys new file mode 100644 index 000000000..e6336f648 --- /dev/null +++ b/tests/opt/opt_merge_basic.ys @@ -0,0 +1,13 @@ +read_verilog -icells < Date: Mon, 10 Mar 2025 12:30:00 +0100 Subject: [PATCH 035/133] opt_merge: test some unary cells --- tests/opt/opt_merge_basic.ys | 69 +++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/tests/opt/opt_merge_basic.ys b/tests/opt/opt_merge_basic.ys index e6336f648..082fdb0b8 100644 --- a/tests/opt/opt_merge_basic.ys +++ b/tests/opt/opt_merge_basic.ys @@ -1,13 +1,74 @@ -read_verilog -icells < Date: Mon, 10 Mar 2025 12:56:21 +0100 Subject: [PATCH 036/133] opt_merge: test more kinds of cells --- tests/opt/opt_merge_basic.ys | 104 +++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 6 deletions(-) diff --git a/tests/opt/opt_merge_basic.ys b/tests/opt/opt_merge_basic.ys index 082fdb0b8..9de320aaa 100644 --- a/tests/opt/opt_merge_basic.ys +++ b/tests/opt/opt_merge_basic.ys @@ -19,7 +19,7 @@ module top(A, B, C, X, Y); input [7:0] A, B, C; output [7:0] X, Y; assign X = A + B; -assign Y = A + C; +assign Y = A + C; // <- look here endmodule EOT # Reject on a different input @@ -45,10 +45,9 @@ select -assert-count 1 t:$reduce_xor design -reset read_verilog -icells < B; +assign Y = A > B; +endmodule +EOT +# Exercise the general case in hash_cell_inputs - accept +opt_expr +select -assert-count 2 t:$gt +equiv_opt -assert opt_merge +design -load postopt +select -assert-count 1 t:$gt + +design -reset +read_verilog < B; +assign Y = A > C; // <- look here +endmodule +EOT +# Exercise the general case in hash_cell_inputs - reject +opt_expr +select -assert-count 2 t:$gt +opt_merge +select -assert-count 2 t:$gt From 1d773b50a4bc44cd9b431387adf053d1998a4590 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Mon, 10 Mar 2025 13:02:49 +0100 Subject: [PATCH 037/133] opt_merge: fix dangling pointers in known_cells when keep attribute is used --- passes/opt/opt_merge.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 745b27e87..b519d33d6 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -154,7 +154,7 @@ struct OptMergeWorker bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) const { - log_assert(cell1 != cell2); + if (cell1 == cell2) return true; if (cell1->type != cell2->type) return false; if (cell1->parameters != cell2->parameters) @@ -313,6 +313,8 @@ struct OptMergeWorker if (cell->has_keep_attr()) { if (other_cell->has_keep_attr()) continue; + known_cells.erase(other_cell); + known_cells.insert(cell); std::swap(other_cell, cell); } From ca9176cd0f7268fabd5bc9f56a66b4cfc09936d7 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Mon, 10 Mar 2025 17:55:04 +0100 Subject: [PATCH 038/133] share: bail better on too many patterns --- passes/opt/share.cc | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 20ec8d358..7bb48eddc 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -856,18 +856,20 @@ struct ShareWorker } template - void insert_capped(pool& cache, Iterator begin_pattern, Iterator end_pattern) + bool insert_capped(pool& cache, Iterator begin_pattern, Iterator end_pattern) { if (cache.size() + std::distance(begin_pattern, end_pattern) > config.pattern_limit) { cache.clear(); cache.insert(ssc_pair_t()); + return false; } else { cache.insert(begin_pattern, end_pattern); } + return true; } - void insert_capped(pool& cache, ssc_pair_t pattern) + bool insert_capped(pool& cache, ssc_pair_t pattern) { - insert_capped(cache, &pattern, &pattern + 1); + return insert_capped(cache, &pattern, &pattern + 1); } const pool &find_cell_activation_patterns(RTLIL::Cell *cell, const char *indent) @@ -926,20 +928,29 @@ struct ShareWorker for (int i = 0; i < GetSize(sig_s); i++) p.first.append(sig_s[i]), p.second.bits().push_back(RTLIL::State::S0); if (sort_check_activation_pattern(p)) - insert_capped(activation_patterns_cache[cell], p); + if (!insert_capped(activation_patterns_cache[cell], p)) { + recursion_state.erase(cell); + return activation_patterns_cache[cell]; + } } for (int idx : used_in_b_parts) for (auto p : c_patterns) { p.first.append(sig_s[idx]), p.second.bits().push_back(RTLIL::State::S1); if (sort_check_activation_pattern(p)) - insert_capped(activation_patterns_cache[cell], p); + if (!insert_capped(activation_patterns_cache[cell], p)) { + recursion_state.erase(cell); + return activation_patterns_cache[cell]; + } } } for (auto c : driven_cells) { const pool &c_patterns = find_cell_activation_patterns(c, indent); - insert_capped(activation_patterns_cache[cell], c_patterns.begin(), c_patterns.end()); + if (!insert_capped(activation_patterns_cache[cell], c_patterns.begin(), c_patterns.end())) { + recursion_state.erase(cell); + return activation_patterns_cache[cell]; + } } log_assert(recursion_state.count(cell) != 0); From be3dfdc5ad01019d7f843f1acb9a1640316e60ab Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Mon, 10 Mar 2025 19:41:22 +0200 Subject: [PATCH 039/133] splitcells: add tests --- tests/various/bug4909.ys | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/various/bug4909.ys diff --git a/tests/various/bug4909.ys b/tests/various/bug4909.ys new file mode 100644 index 000000000..bf8cfb45b --- /dev/null +++ b/tests/various/bug4909.ys @@ -0,0 +1,44 @@ +read_rtlil << EOF +autoidx 20 +attribute \src "3510.v:2.1-26.10" +attribute \cells_not_processed 1 +attribute \tamara_triplicate 1 +module \top + attribute \src "3510.v:14.3-17.8" + wire width 4 $0\reg5[3:0] + attribute $bugpoint 1 + wire width 4 $auto$bugpoint.cc:258:simplify_something$12 + wire $delete_wire$14 + attribute \src "3510.v:13.19-13.59" + wire width 4 $xnor$3510.v:13$1_Y + attribute \src "3510.v:11.23-11.27" + wire width 4 \reg5 + attribute \src "3510.v:8.24-8.29" + wire width 3 \wire4 + attribute \src "3510.v:3.33-3.34" + wire width 12 output 1 \y + attribute \src "3510.v:13.19-13.59" + cell $xnor $xnor$3510.v:13$1 + parameter \A_SIGNED 0 + parameter \A_WIDTH 3 + parameter \B_SIGNED 0 + parameter \B_WIDTH 4 + parameter \Y_WIDTH 4 + connect \A 3'x + connect \B $auto$bugpoint.cc:258:simplify_something$12 + connect \Y $xnor$3510.v:13$1_Y + end + attribute \src "3510.v:14.3-17.8" + process $proc$3510.v:14$2 + assign $0\reg5[3:0] { \wire4 [2] \wire4 } + sync posedge $delete_wire$14 + update \reg5 $0\reg5[3:0] + end + connect \y [4:0] { \reg5 1'0 } + connect \wire4 $xnor$3510.v:13$1_Y [2:0] +end +EOF + +prep +splitcells + From 6c9857403cb112fc36db73a9eece2fcf34637518 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 11 Mar 2025 14:57:00 +0100 Subject: [PATCH 040/133] share: use share.pattern_limit from scratchpad --- passes/opt/share.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 7bb48eddc..cb1377626 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -1477,7 +1477,7 @@ struct SharePass : public Pass { ShareWorkerConfig config; config.limit = -1; - config.pattern_limit = 1000; + config.pattern_limit = design->scratchpad_get_int("share.pattern_limit", 1000); config.opt_force = false; config.opt_aggressive = false; config.opt_fast = false; From a5f34d04f8f3f9305c18bdfb79e13e59ac15ac39 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Tue, 11 Mar 2025 18:50:44 -0400 Subject: [PATCH 041/133] Address comments --- frontends/verific/verific.cc | 4 ++++ frontends/verilog/verilog_frontend.cc | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 19f17b0ff..a320a6efd 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -4413,7 +4413,11 @@ struct ReadPass : public Pass { if (use_verific) { args[0] = "verific"; } else { +#if !defined(__wasm) args[0] = "read_verilog_file_list"; +#else + cmd_error(args, 1, "Command files are not supported on this platform.\n"); +#endif } Pass::call(design, args); return; diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 737481743..e4e705c39 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -722,13 +722,16 @@ struct VerilogFileList : public Pass { log("\n"); log(" read_verilog_file_list [options]\n"); log("\n"); - log("Parse a Verilog file list, and pass the list of Verilog files to read_verilog command.\n"); + log("Parse a Verilog file list, and pass the list of Verilog files to read_verilog\n"); + log("command\n"); log("\n"); log(" -F file_list_path\n"); - log(" File list file contains list of Verilog files to be parsed, any path is treated relative to the file list file\n"); + log(" File list file contains list of Verilog files to be parsed, any path is\n"); + log(" treated relative to the file list file\n"); log("\n"); log(" -f file_list_path\n"); - log(" File list file contains list of Verilog files to be parsed, any path is treated relative to current working directroy\n"); + log(" File list file contains list of Verilog files to be parsed, any path is\n"); + log(" treated relative to current working directroy\n"); log("\n"); } From e44d1d404a2ff2e042c36300f986bd0fa0b8d643 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 00:22:18 +0000 Subject: [PATCH 042/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8f0355c8e..89ffaef66 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+0 +YOSYS_VER := 0.51+17 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 398afd102e036000d9a7b19b08d4f474cb85bba1 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:05:39 +1300 Subject: [PATCH 043/133] Refactor full_selection The `Design::selected_*()` methods no longer unconditionally skip boxed modules. Instead, selections are now box and design aware. The selection constructor now optionally takes a design pointer, and has a new `selects_boxes` flag. If the selection has an assigned design, then `Selection::selected_*()` will only return true for boxed modules if the selects_boxes flag is set. A warning is raised if a selection is checked and no design is set. Selections can change design via the `Selection::optimize()` method. Most places that iterate over `Design::modules()` and check `Selection::selected_module()` should instead use `Design::selected_modules()`. Since boxed modules should only ever be selected explicitly, and `full_selection` (now) refers to all non-boxed modules, `Selection::optimize()` will clear the `full_selection` flag if the `selects_boxes` flag is enabled, and instead explicitly selects all modules (including boxed modules). This also means that `full_selection` will only get automatically applied to a design without any boxed modules. These changes necessitated a number of changes to `select.cc` in order to support this functionality when operating on selections, in particular when combining selections (e.g. by union or difference). To minimize redundancy, a number of places that previously iterated over `design->modules()` now push the current selection to the design, use `design->selected_modules()`, and then pop the selection when done. Introduce `RTLIL::NamedObject`, to allow for iterating over all members of a module with a single iterator instead of needing to iterate over wires, cells, memories, and processes separately. Also implement `Module::selected_{memories, processes, members}()` to match wires and cells methods. The `selected_members()` method combines each of the other `selected_*()` methods into a single list. --- kernel/rtlil.cc | 90 +++++++++++++++++--- kernel/rtlil.h | 29 ++++--- passes/cmds/select.cc | 192 ++++++++++++++++++++++-------------------- 3 files changed, 197 insertions(+), 114 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3b9a4a8b1..8c40e83d3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -766,8 +766,21 @@ vector RTLIL::AttrObject::get_intvec_attribute(const RTLIL::IdString &id) c return data; } +bool RTLIL::Selection::boxed_module(const RTLIL::IdString &mod_name) const +{ + if (current_design != nullptr) { + auto module = current_design->module(mod_name); + return module && module->get_blackbox_attribute(); + } else { + log_warning("Unable to check if module is boxed for null design.\n"); + return false; + } +} + bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const { + if (!selects_boxes && boxed_module(mod_name)) + return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -779,6 +792,8 @@ bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) const { + if (!selects_boxes && boxed_module(mod_name)) + return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -788,6 +803,8 @@ bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) co bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const { + if (!selects_boxes && boxed_module(mod_name)) + return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -800,6 +817,19 @@ bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RT void RTLIL::Selection::optimize(RTLIL::Design *design) { + if (design != current_design) { + current_design = design; + } + + if (selects_boxes && full_selection) { + selected_modules.clear(); + selected_members.clear(); + full_selection = false; + for (auto mod : current_design->modules()) { + selected_modules.insert(mod->name); + } + return; + } if (full_selection) { selected_modules.clear(); selected_members.clear(); @@ -810,7 +840,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto mod_name : selected_modules) { - if (design->modules_.count(mod_name) == 0) + if (current_design->modules_.count(mod_name) == 0) del_list.push_back(mod_name); selected_members.erase(mod_name); } @@ -819,7 +849,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto &it : selected_members) - if (design->modules_.count(it.first) == 0) + if (current_design->modules_.count(it.first) == 0) del_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -827,7 +857,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) { del_list.clear(); for (auto memb_name : it.second) - if (design->modules_[it.first]->count_id(memb_name) == 0) + if (current_design->modules_[it.first]->count_id(memb_name) == 0) del_list.push_back(memb_name); for (auto memb_name : del_list) it.second.erase(memb_name); @@ -838,8 +868,8 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) if (it.second.size() == 0) del_list.push_back(it.first); - else if (it.second.size() == design->modules_[it.first]->wires_.size() + design->modules_[it.first]->memories.size() + - design->modules_[it.first]->cells_.size() + design->modules_[it.first]->processes.size()) + else if (it.second.size() == current_design->modules_[it.first]->wires_.size() + current_design->modules_[it.first]->memories.size() + + current_design->modules_[it.first]->cells_.size() + current_design->modules_[it.first]->processes.size()) add_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -848,7 +878,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) selected_modules.insert(mod_name); } - if (selected_modules.size() == design->modules_.size()) { + if (!selects_boxes && selected_modules.size() == current_design->modules_.size()) { full_selection = true; selected_modules.clear(); selected_members.clear(); @@ -863,7 +893,7 @@ RTLIL::Design::Design() hashidx_ = hashidx_count; refcount_modules_ = 0; - selection_stack.push_back(RTLIL::Selection()); + selection_stack.push_back(RTLIL::Selection(true, false, this)); #ifdef WITH_PYTHON RTLIL::Design::get_all_designs()->insert(std::pair(hashidx_, this)); @@ -1127,7 +1157,7 @@ std::vector RTLIL::Design::selected_modules() const std::vector result; result.reserve(modules_.size()); for (auto &it : modules_) - if (selected_module(it.first) && !it.second->get_blackbox_attribute()) + if (selected_module(it.first)) result.push_back(it.second); return result; } @@ -1137,7 +1167,7 @@ std::vector RTLIL::Design::selected_whole_modules() const std::vector result; result.reserve(modules_.size()); for (auto &it : modules_) - if (selected_whole_module(it.first) && !it.second->get_blackbox_attribute()) + if (selected_whole_module(it.first)) result.push_back(it.second); return result; } @@ -1146,13 +1176,13 @@ std::vector RTLIL::Design::selected_whole_modules_warn(bool incl { std::vector result; result.reserve(modules_.size()); - for (auto &it : modules_) - if (it.second->get_blackbox_attribute(include_wb)) - continue; - else if (selected_whole_module(it.first)) + for (auto &it : modules_) { + log_assert(selection_stack.size() > 0 || !it.second->get_blackbox_attribute(include_wb)); + if (selected_whole_module(it.first)) result.push_back(it.second); else if (selected_module(it.first)) log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); + } return result; } @@ -2431,6 +2461,40 @@ std::vector RTLIL::Module::selected_cells() const return result; } +std::vector RTLIL::Module::selected_memories() const +{ + std::vector result; + result.reserve(memories.size()); + for (auto &it : memories) + if (design->selected(this, it.second)) + result.push_back(it.second); + return result; +} + +std::vector RTLIL::Module::selected_processes() const +{ + std::vector result; + result.reserve(processes.size()); + for (auto &it : processes) + if (design->selected(this, it.second)) + result.push_back(it.second); + return result; +} + +std::vector RTLIL::Module::selected_members() const +{ + std::vector result; + auto cells = selected_cells(); + auto memories = selected_memories(); + auto wires = selected_wires(); + auto processes = selected_processes(); + result.insert(result.end(), cells.begin(), cells.end()); + result.insert(result.end(), memories.begin(), memories.end()); + result.insert(result.end(), wires.begin(), wires.end()); + result.insert(result.end(), processes.begin(), processes.end()); + return result; +} + void RTLIL::Module::add(RTLIL::Wire *wire) { log_assert(!wire->name.empty()); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f1bd96be7..ee75237f3 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -58,6 +58,7 @@ namespace RTLIL struct Const; struct AttrObject; + struct NamedObject; struct Selection; struct Monitor; struct Design; @@ -869,6 +870,11 @@ struct RTLIL::AttrObject vector get_intvec_attribute(const RTLIL::IdString &id) const; }; +struct RTLIL::NamedObject : public RTLIL::AttrObject +{ + RTLIL::IdString name; +}; + struct RTLIL::SigChunk { RTLIL::Wire *wire; @@ -1135,11 +1141,14 @@ public: struct RTLIL::Selection { bool full_selection; + bool selects_boxes; pool selected_modules; dict> selected_members; + RTLIL::Design *current_design; - Selection(bool full = true) : full_selection(full) { } + Selection(bool full = true, bool boxes = false, RTLIL::Design *design = nullptr) : full_selection(full), selects_boxes(boxes), current_design(design) { } + bool boxed_module(const RTLIL::IdString &mod_name) const; bool selected_module(const RTLIL::IdString &mod_name) const; bool selected_whole_module(const RTLIL::IdString &mod_name) const; bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; @@ -1290,7 +1299,7 @@ struct RTLIL::Design #endif }; -struct RTLIL::Module : public RTLIL::AttrObject +struct RTLIL::Module : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1313,7 +1322,6 @@ public: std::vector connections_; std::vector bindings_; - RTLIL::IdString name; idict avail_parameters; dict parameter_default_values; dict memories; @@ -1360,6 +1368,9 @@ public: std::vector selected_wires() const; std::vector selected_cells() const; + std::vector selected_memories() const; + std::vector selected_processes() const; + std::vector selected_members() const; template bool selected(T *member) const { return design->selected_member(name, member->name); @@ -1645,7 +1656,7 @@ namespace RTLIL_BACKEND { void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); } -struct RTLIL::Wire : public RTLIL::AttrObject +struct RTLIL::Wire : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1668,7 +1679,6 @@ public: void operator=(RTLIL::Wire &other) = delete; RTLIL::Module *module; - RTLIL::IdString name; int width, start_offset, port_id; bool port_input, port_output, upto, is_signed; @@ -1697,14 +1707,13 @@ inline int GetSize(RTLIL::Wire *wire) { return wire->width; } -struct RTLIL::Memory : public RTLIL::AttrObject +struct RTLIL::Memory : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } Memory(); - RTLIL::IdString name; int width, start_offset, size; #ifdef WITH_PYTHON ~Memory(); @@ -1712,7 +1721,7 @@ struct RTLIL::Memory : public RTLIL::AttrObject #endif }; -struct RTLIL::Cell : public RTLIL::AttrObject +struct RTLIL::Cell : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1729,7 +1738,6 @@ public: void operator=(RTLIL::Cell &other) = delete; RTLIL::Module *module; - RTLIL::IdString name; RTLIL::IdString type; dict connections_; dict parameters; @@ -1822,7 +1830,7 @@ struct RTLIL::SyncRule RTLIL::SyncRule *clone() const; }; -struct RTLIL::Process : public RTLIL::AttrObject +struct RTLIL::Process : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1834,7 +1842,6 @@ protected: ~Process(); public: - RTLIL::IdString name; RTLIL::Module *module; RTLIL::CaseRule root_case; std::vector syncs; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index aec4c964b..1b1b7ca43 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -141,6 +141,20 @@ static bool match_attr(const dict &attributes, co return match_attr(attributes, match_expr, std::string(), 0); } +static void full_select_no_box(RTLIL::Design *design, RTLIL::Selection &lhs) +{ + if (!lhs.full_selection) + return; + + lhs.current_design = design; + lhs.selected_modules.clear(); + for (auto mod : design->modules()) { + if (mod->get_blackbox_attribute()) + continue; + lhs.selected_modules.insert(mod->name); + } +} + static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) { if (lhs.full_selection) { @@ -150,7 +164,7 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) return; } - if (lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { + if (!lhs.selects_boxes && lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { lhs.full_selection = true; return; } @@ -159,6 +173,8 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) for (auto mod : design->modules()) { + if (!lhs.selects_boxes && mod->get_blackbox_attribute()) + continue; if (lhs.selected_whole_module(mod->name)) continue; if (!lhs.selected_module(mod->name)) { @@ -212,7 +228,7 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c } } - lhs = RTLIL::Selection(false); + lhs = RTLIL::Selection(false, false, design); while (!objects.empty() && count-- > 0) { @@ -243,7 +259,7 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection &lhs) { - RTLIL::Selection new_sel(false); + RTLIL::Selection new_sel(false, lhs.selects_boxes, design); for (auto mod : design->modules()) if (lhs.selected_module(mod->name)) for (auto cell : mod->cells()) @@ -254,7 +270,7 @@ static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection & static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &lhs) { - RTLIL::Selection new_sel(false); + RTLIL::Selection new_sel(false, lhs.selects_boxes, design); for (auto mod : design->modules()) for (auto cell : mod->cells()) if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type)) @@ -274,6 +290,8 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) { for (auto mod : design->modules()) { + if (!lhs.selects_boxes && mod->get_blackbox_attribute()) + continue; if (lhs.selected_whole_module(mod->name)) continue; if (!lhs.selected_module(mod->name)) @@ -292,18 +310,32 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) } } -static void select_op_union(RTLIL::Design*, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) +static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { + if (rhs.selects_boxes) { + if (lhs.full_selection) { + full_select_no_box(design, lhs); + lhs.full_selection = false; + } + lhs.selects_boxes = true; + } + else if (lhs.full_selection) + return; + if (rhs.full_selection) { - lhs.full_selection = true; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); + if (lhs.selects_boxes) { + auto new_rhs = RTLIL::Selection(rhs); + full_select_no_box(design, new_rhs); + for (auto mod : new_rhs.selected_modules) + lhs.selected_modules.insert(mod); + } else { + lhs.full_selection = true; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); + } return; } - if (lhs.full_selection) - return; - for (auto &it : rhs.selected_members) for (auto &it2 : it.second) lhs.selected_members[it.first].insert(it2); @@ -317,18 +349,26 @@ static void select_op_union(RTLIL::Design*, RTLIL::Selection &lhs, const RTLIL:: static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { if (rhs.full_selection) { - lhs.full_selection = false; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); + if (lhs.selects_boxes) { + auto new_rhs = RTLIL::Selection(rhs); + full_select_no_box(design, new_rhs); + for (auto mod : new_rhs.selected_modules) { + lhs.selected_modules.erase(mod); + lhs.selected_members.erase(mod); + } + } else { + lhs.full_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); + } return; } if (lhs.full_selection) { - if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0) + if (rhs.empty()) return; + full_select_no_box(design, lhs); lhs.full_selection = false; - for (auto mod : design->modules()) - lhs.selected_modules.insert(mod->name); } for (auto &it : rhs.selected_modules) { @@ -366,7 +406,7 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { - if (rhs.full_selection) + if (rhs.full_selection && !lhs.selects_boxes) return; if (lhs.full_selection) { @@ -377,27 +417,28 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co std::vector del_list; - for (auto &it : lhs.selected_modules) - if (rhs.selected_modules.count(it) == 0) { - if (rhs.selected_members.count(it) > 0) - for (auto &it2 : rhs.selected_members.at(it)) - lhs.selected_members[it].insert(it2); - del_list.push_back(it); - } + for (auto mod_name : lhs.selected_modules) { + if (rhs.selected_whole_module(mod_name)) + continue; + if (rhs.selected_module(mod_name)) + for (auto memb_name : rhs.selected_members.at(mod_name)) + lhs.selected_members[mod_name].insert(memb_name); + del_list.push_back(mod_name); + } for (auto &it : del_list) lhs.selected_modules.erase(it); del_list.clear(); for (auto &it : lhs.selected_members) { - if (rhs.selected_modules.count(it.first) > 0) + if (rhs.selected_whole_module(it.first)) continue; - if (rhs.selected_members.count(it.first) == 0) { + if (!rhs.selected_module(it.first)) { del_list.push_back(it.first); continue; } std::vector del_list2; for (auto &it2 : it.second) - if (rhs.selected_members.at(it.first).count(it2) == 0) + if (!rhs.selected_member(it.first, it2)) del_list2.push_back(it2); for (auto &it2 : del_list2) it.second.erase(it2); @@ -796,15 +837,16 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp } } - work_stack.push_back(RTLIL::Selection()); + bool full_selection = (arg == "*" && arg_mod == "*"); + work_stack.push_back(RTLIL::Selection(full_selection, select_blackboxes, design)); RTLIL::Selection &sel = work_stack.back(); - if (arg == "*" && arg_mod == "*" && select_blackboxes) { + if (sel.full_selection) { + if (sel.selects_boxes) sel.optimize(design); select_filter_active_mod(design, work_stack.back()); return; } - sel.full_selection = false; for (auto mod : design->modules()) { if (!select_blackboxes && mod->get_blackbox_attribute()) @@ -958,24 +1000,12 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel, bool whole_modules = false) { std::string desc = "Selection contains:\n"; - for (auto mod : design->modules()) + for (auto mod : design->selected_modules()) { - if (sel->selected_module(mod->name)) { - if (whole_modules && sel->selected_whole_module(mod->name)) - desc += stringf("%s\n", id2cstr(mod->name)); - for (auto wire : mod->wires()) - if (sel->selected_member(mod->name, wire->name)) - desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)); - for (auto &it : mod->memories) - if (sel->selected_member(mod->name, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); - for (auto cell : mod->cells()) - if (sel->selected_member(mod->name, cell->name)) - desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)); - for (auto &it : mod->processes) - if (sel->selected_member(mod->name, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); - } + if (whole_modules && sel->selected_whole_module(mod->name)) + desc += stringf("%s\n", id2cstr(mod->name)); + for (auto it : mod->selected_members()) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)); } return desc; } @@ -1001,7 +1031,7 @@ void handle_extra_select_args(Pass *pass, const vector &args, size_t arg work_stack.pop_back(); } if (work_stack.empty()) - design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.push_back(RTLIL::Selection(false, false, design)); else design->selection_stack.push_back(work_stack.back()); } @@ -1017,7 +1047,7 @@ RTLIL::Selection eval_select_args(const vector &args, RTLIL::Design *des work_stack.pop_back(); } if (work_stack.empty()) - return RTLIL::Selection(false); + return RTLIL::Selection(false, false, design); return work_stack.back(); } @@ -1444,13 +1474,13 @@ struct SelectPass : public Pass { log_assert(design->selection_stack.size() > 0); if (clear_mode) { - design->selection_stack.back() = RTLIL::Selection(true); + design->selection_stack.back() = RTLIL::Selection(true, false, design); design->selected_active_module = std::string(); return; } if (none_mode) { - design->selection_stack.back() = RTLIL::Selection(false); + design->selection_stack.back() = RTLIL::Selection(false, false, design); return; } @@ -1465,28 +1495,17 @@ struct SelectPass : public Pass { if (f == nullptr) log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno)); } - RTLIL::Selection *sel = &design->selection_stack.back(); if (work_stack.size() > 0) - sel = &work_stack.back(); + design->selection_stack.push_back(work_stack.back()); + RTLIL::Selection *sel = &design->selection_stack.back(); sel->optimize(design); - for (auto mod : design->modules()) + for (auto mod : design->selected_modules()) { if (sel->selected_whole_module(mod->name) && list_mode) log("%s\n", id2cstr(mod->name)); - if (sel->selected_module(mod->name) && !list_mod_mode) { - for (auto wire : mod->wires()) - if (sel->selected_member(mod->name, wire->name)) - LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)) - for (auto &it : mod->memories) - if (sel->selected_member(mod->name, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) - for (auto cell : mod->cells()) - if (sel->selected_member(mod->name, cell->name)) - LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)) - for (auto &it : mod->processes) - if (sel->selected_member(mod->name, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) - } + if (!list_mod_mode) + for (auto it : mod->selected_members()) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)) } if (count_mode) { @@ -1495,6 +1514,8 @@ struct SelectPass : public Pass { } if (f != nullptr) fclose(f); + if (work_stack.size() > 0) + design->selection_stack.pop_back(); #undef LOG_OBJECT return; } @@ -1553,23 +1574,13 @@ struct SelectPass : public Pass { if (work_stack.size() == 0) log_cmd_error("No selection to check.\n"); RTLIL::Selection *sel = &work_stack.back(); + design->selection_stack.push_back(*sel); sel->optimize(design); - for (auto mod : design->modules()) - if (sel->selected_module(mod->name)) { - module_count++; - for (auto wire : mod->wires()) - if (sel->selected_member(mod->name, wire->name)) - total_count++; - for (auto &it : mod->memories) - if (sel->selected_member(mod->name, it.first)) - total_count++; - for (auto cell : mod->cells()) - if (sel->selected_member(mod->name, cell->name)) - total_count++; - for (auto &it : mod->processes) - if (sel->selected_member(mod->name, it.first)) - total_count++; - } + for (auto mod : design->selected_modules()) { + module_count++; + for ([[maybe_unused]] auto member_name : mod->selected_members()) + total_count++; + } if (assert_modcount >= 0 && assert_modcount != module_count) { log_error("Assertion failed: selection contains %d modules instead of the asserted %d:%s\n", @@ -1593,13 +1604,14 @@ struct SelectPass : public Pass { log_error("Assertion failed: selection contains %d elements, less than the minimum number %d:%s\n%s", total_count, assert_min, sel_str.c_str(), desc.c_str()); } + design->selection_stack.pop_back(); return; } if (!set_name.empty()) { if (work_stack.size() == 0) - design->selection_vars[set_name] = RTLIL::Selection(false); + design->selection_vars[set_name] = RTLIL::Selection(false, false, design); else design->selection_vars[set_name] = work_stack.back(); return; @@ -1665,7 +1677,7 @@ struct CdPass : public Pass { log_cmd_error("Invalid number of arguments.\n"); if (args.size() == 1 || args[1] == "/") { - design->selection_stack.back() = RTLIL::Selection(true); + design->selection_stack.back() = RTLIL::Selection(true, false, design); design->selected_active_module = std::string(); return; } @@ -1674,7 +1686,7 @@ struct CdPass : public Pass { { string modname = design->selected_active_module; - design->selection_stack.back() = RTLIL::Selection(true); + design->selection_stack.back() = RTLIL::Selection(true, false, design); design->selected_active_module = std::string(); while (1) @@ -1691,7 +1703,7 @@ struct CdPass : public Pass { continue; design->selected_active_module = modname; - design->selection_stack.back() = RTLIL::Selection(); + design->selection_stack.back() = RTLIL::Selection(true, false, design); select_filter_active_mod(design, design->selection_stack.back()); design->selection_stack.back().optimize(design); return; @@ -1710,7 +1722,7 @@ struct CdPass : public Pass { if (design->module(modname) != nullptr) { design->selected_active_module = modname; - design->selection_stack.back() = RTLIL::Selection(); + design->selection_stack.back() = RTLIL::Selection(true, false, design); select_filter_active_mod(design, design->selection_stack.back()); design->selection_stack.back().optimize(design); return; From 061c234559fa5351345c13be061cdde4f12335fd Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:05:40 +1300 Subject: [PATCH 044/133] tests/select: Add tests for selections with boxes --- tests/select/{blackboxes.ys => boxes.v} | 12 -------- tests/select/boxes_dummy.ys | 13 +++++++++ tests/select/boxes_equals_clean.ys | 7 +++++ tests/select/boxes_equals_name.ys | 7 +++++ tests/select/boxes_equals_operators.ys | 38 +++++++++++++++++++++++++ tests/select/boxes_equals_pattern.ys | 7 +++++ tests/select/boxes_equals_wildcard.ys | 6 ++++ tests/select/boxes_no_equals.ys | 7 +++++ tests/select/boxes_no_equals_clean.ys | 18 ++++++++++++ 9 files changed, 103 insertions(+), 12 deletions(-) rename tests/select/{blackboxes.ys => boxes.v} (51%) create mode 100644 tests/select/boxes_dummy.ys create mode 100644 tests/select/boxes_equals_clean.ys create mode 100644 tests/select/boxes_equals_name.ys create mode 100644 tests/select/boxes_equals_operators.ys create mode 100644 tests/select/boxes_equals_pattern.ys create mode 100644 tests/select/boxes_equals_wildcard.ys create mode 100644 tests/select/boxes_no_equals.ys create mode 100644 tests/select/boxes_no_equals_clean.ys diff --git a/tests/select/blackboxes.ys b/tests/select/boxes.v similarity index 51% rename from tests/select/blackboxes.ys rename to tests/select/boxes.v index 9bfe92c6b..696b26523 100644 --- a/tests/select/blackboxes.ys +++ b/tests/select/boxes.v @@ -1,4 +1,3 @@ -read_verilog -specify < Date: Fri, 14 Mar 2025 14:05:40 +1300 Subject: [PATCH 045/133] Unify Design::selected_modules variants Now uses two enums, one to control whether or not to include partially selected modules (and what to do if they are encountered), and one to control whether or not to include boxed modules (and what to do if they are encountered). Mark Design::selected{modules, whole_modules}() deprecated and make them provide warnings on boxes. There are a lot of places that use them and I can't always tell which ones support boxed modules and which don't. --- kernel/rtlil.cc | 75 +++++++++++++++++++++++++++++++------------------ kernel/rtlil.h | 41 +++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 30 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8c40e83d3..946556b04 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1152,37 +1152,58 @@ bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const return selected_whole_module(mod->name); } -std::vector RTLIL::Design::selected_modules() const + +std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const { + bool include_partials = partials == RTLIL::SELECT_ALL; + bool exclude_boxes = (partials & RTLIL::SB_UNBOXED_ONLY) == 0; + bool ignore_wb = (partials & RTLIL::SB_INCL_WB) != 0; std::vector result; result.reserve(modules_.size()); for (auto &it : modules_) - if (selected_module(it.first)) - result.push_back(it.second); - return result; -} - -std::vector RTLIL::Design::selected_whole_modules() const -{ - std::vector result; - result.reserve(modules_.size()); - for (auto &it : modules_) - if (selected_whole_module(it.first)) - result.push_back(it.second); - return result; -} - -std::vector RTLIL::Design::selected_whole_modules_warn(bool include_wb) const -{ - std::vector result; - result.reserve(modules_.size()); - for (auto &it : modules_) { - log_assert(selection_stack.size() > 0 || !it.second->get_blackbox_attribute(include_wb)); - if (selected_whole_module(it.first)) - result.push_back(it.second); - else if (selected_module(it.first)) - log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); - } + if (selected_whole_module(it.first) || (include_partials && selected_module(it.first))) { + if (!(exclude_boxes && it.second->get_blackbox_attribute(ignore_wb))) + result.push_back(it.second); + else + switch (boxes) + { + case RTLIL::SB_UNBOXED_WARN: + log_warning("Ignoring boxed module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_EXCL_BB_WARN: + log_warning("Ignoring blackbox module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_UNBOXED_ERR: + log_error("Unsupported boxed module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_EXCL_BB_ERR: + log_error("Unsupported blackbox module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_UNBOXED_CMDERR: + log_cmd_error("Unsupported boxed module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_EXCL_BB_CMDERR: + log_cmd_error("Unsupported blackbox module %s.\n", log_id(it.first)); + break; + default: + break; + } + } else if (!include_partials && selected_module(it.first)) { + switch(partials) + { + case RTLIL::SELECT_WHOLE_WARN: + log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); + break; + case RTLIL::SELECT_WHOLE_ERR: + log_error("Unsupported partially selected module %s.\n", log_id(it.first)); + break; + case RTLIL::SELECT_WHOLE_CMDERR: + log_cmd_error("Unsupported partially selected module %s.\n", log_id(it.first)); + break; + default: + break; + } + } return result; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index ee75237f3..9c9103bb6 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -56,6 +56,30 @@ namespace RTLIL CONST_FLAG_REAL = 4 // only used for parameters }; + enum SelectPartials : unsigned char { + SELECT_ALL = 0, // include partial modules + SELECT_WHOLE_ONLY = 1, // ignore partial modules + SELECT_WHOLE_WARN = 2, // call log_warning on partial module + SELECT_WHOLE_ERR = 3, // call log_error on partial module + SELECT_WHOLE_CMDERR = 4 // call log_cmd_error on partial module + }; + + enum SelectBoxes : unsigned char { + SB_ALL = 0, // include boxed modules + SB_WARN = 1, // helper for log_warning + SB_ERR = 2, // helper for log_error + SB_CMDERR = 3, // helper for log_cmd_error + SB_UNBOXED_ONLY = 4, // ignore boxed modules + SB_UNBOXED_WARN = 5, // call log_warning on boxed module + SB_UNBOXED_ERR = 6, // call log_error on boxed module + SB_UNBOXED_CMDERR = 7, // call log_cmd_error on boxed module + SB_INCL_WB = 8, // helper for white boxes + SB_EXCL_BB_ONLY = 12, // ignore black boxes, but not white boxes + SB_EXCL_BB_WARN = 13, // call log_warning on black boxed module + SB_EXCL_BB_ERR = 14, // call log_error on black boxed module + SB_EXCL_BB_CMDERR = 15 // call log_cmd_error on black boxed module + }; + struct Const; struct AttrObject; struct NamedObject; @@ -1291,9 +1315,20 @@ struct RTLIL::Design } - std::vector selected_modules() const; - std::vector selected_whole_modules() const; - std::vector selected_whole_modules_warn(bool include_wb = false) const; + std::vector selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes = SB_ALL) const; + + [[deprecated("Use selected_unboxed_modules() to maintain prior behaviour, or consider one of the other selected module helpers.")]] + std::vector selected_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } + std::vector all_selected_modules() const { return selected_modules(SELECT_ALL, SB_ALL); } + std::vector selected_unboxed_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_ONLY); } + std::vector selected_unboxed_modules_warn() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } + + [[deprecated("Use select_unboxed_whole_modules() to maintain prior behaviour, or consider one of the other selected whole module helpers.")]] + std::vector selected_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_UNBOXED_WARN); } + std::vector all_selected_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_ALL); } + std::vector selected_whole_modules_warn(bool include_wb = false) const { return selected_modules(SELECT_WHOLE_WARN, include_wb ? SB_EXCL_BB_WARN : SB_UNBOXED_WARN); } + std::vector selected_unboxed_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_UNBOXED_ONLY); } + std::vector selected_unboxed_whole_modules_warn() const { return selected_modules(SELECT_WHOLE_WARN, SB_UNBOXED_WARN); } #ifdef WITH_PYTHON static std::map *get_all_designs(void); #endif From 3b1b09baf690f449c23309eac7707a00cfb8351c Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:05:40 +1300 Subject: [PATCH 046/133] Can clean boxed modules If a selection contains a boxed module, but does not select boxes, it should be removed from the selection. --- kernel/rtlil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 946556b04..c3a415f36 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -840,7 +840,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto mod_name : selected_modules) { - if (current_design->modules_.count(mod_name) == 0) + if (current_design->modules_.count(mod_name) == 0 || (!selects_boxes && boxed_module(mod_name))) del_list.push_back(mod_name); selected_members.erase(mod_name); } @@ -849,7 +849,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto &it : selected_members) - if (current_design->modules_.count(it.first) == 0) + if (current_design->modules_.count(it.first) == 0 || (!selects_boxes && boxed_module(it.first))) del_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); From a67b57bd6456ff61f3c90b5e8e449989a43161ec Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:05:40 +1300 Subject: [PATCH 047/133] rtlil: Add selection helpers New methods on Design to push/pop selection instead of accessing the selection stack directly. Includes methods for pushing a full/complete/empty selection. Also helper methods on modules to check `is_selected` and `is_selected_whole`. --- kernel/rtlil.cc | 39 +++++++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 9 +++++++++ 2 files changed, 48 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index c3a415f36..378c976ef 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1152,6 +1152,35 @@ bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const return selected_whole_module(mod->name); } +void RTLIL::Design::push_selection(RTLIL::Selection sel) +{ + sel.current_design = this; + selection_stack.push_back(sel); +} + +void RTLIL::Design::push_empty_selection() +{ + RTLIL::Selection sel(false, false, this); + push_selection(sel); +} + +void RTLIL::Design::push_full_selection() +{ + RTLIL::Selection sel(true, false, this); + push_selection(sel); +} + +void RTLIL::Design::push_complete_selection() +{ + RTLIL::Selection sel(true, true, this); + sel.optimize(this); + push_selection(sel); +} + +void RTLIL::Design::pop_selection() +{ + selection_stack.pop_back(); +} std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const { @@ -2462,6 +2491,16 @@ bool RTLIL::Module::has_processes_warn() const return !processes.empty(); } +bool RTLIL::Module::is_selected() const +{ + return design->selected_module(this->name); +} + +bool RTLIL::Module::is_selected_whole() const +{ + return design->selected_whole_module(this->name); +} + std::vector RTLIL::Module::selected_wires() const { std::vector result; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 9c9103bb6..57030d133 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1280,6 +1280,12 @@ struct RTLIL::Design bool selected_module(RTLIL::Module *mod) const; bool selected_whole_module(RTLIL::Module *mod) const; + void push_selection(RTLIL::Selection sel); + void push_empty_selection(); + void push_full_selection(); + void push_complete_selection(); + void pop_selection(); + RTLIL::Selection &selection() { return selection_stack.back(); } @@ -1401,6 +1407,9 @@ public: bool has_memories_warn() const; bool has_processes_warn() const; + bool is_selected() const; + bool is_selected_whole() const; + std::vector selected_wires() const; std::vector selected_cells() const; std::vector selected_memories() const; From dac2bb7d4d6d0bfd18d61316696f5422e1508e8f Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:13 +1300 Subject: [PATCH 048/133] Use selection helpers Catch more uses of selection constructor without assigning a design. --- backends/rtlil/rtlil_backend.cc | 4 +- .../source/code_examples/extensions/my_cmd.cc | 4 +- .../extending_yosys/extensions.rst | 2 +- kernel/driver.cc | 2 +- kernel/register.cc | 24 ++++---- kernel/rtlil.cc | 8 +-- kernel/rtlil.h | 6 +- kernel/tclapi.cc | 2 +- kernel/yosys.cc | 8 +-- passes/cmds/add.cc | 2 +- passes/cmds/design.cc | 6 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 60 ++++++++++--------- passes/cmds/show.cc | 8 +-- passes/cmds/stat.cc | 2 +- passes/cmds/viz.cc | 4 +- passes/hierarchy/submod.cc | 2 +- passes/sat/cutpoint.cc | 2 +- passes/techmap/abc9.cc | 4 +- passes/techmap/abc9_ops.cc | 2 +- passes/techmap/abc_new.cc | 4 +- passes/techmap/aigmap.cc | 2 +- passes/techmap/nlutmap.cc | 2 +- 23 files changed, 84 insertions(+), 78 deletions(-) diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index 113f1a615..ae60ee6c7 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -304,8 +304,8 @@ void RTLIL_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL:: void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { - bool print_header = flag_m || design->selected_whole_module(module->name); - bool print_body = !flag_n || !design->selected_whole_module(module->name); + bool print_header = flag_m || module->is_selected_whole(); + bool print_body = !flag_n || !module->is_selected_whole(); if (print_header) { diff --git a/docs/source/code_examples/extensions/my_cmd.cc b/docs/source/code_examples/extensions/my_cmd.cc index 36ddbe175..e6660469c 100644 --- a/docs/source/code_examples/extensions/my_cmd.cc +++ b/docs/source/code_examples/extensions/my_cmd.cc @@ -51,10 +51,10 @@ struct Test2Pass : public Pass { Test2Pass() : Pass("test2", "demonstrating sigmap on test module") { } void execute(std::vector, RTLIL::Design *design) override { - if (design->selection_stack.back().empty()) + if (design->selection().empty()) log_cmd_error("This command can't operator on an empty selection!\n"); - RTLIL::Module *module = design->modules_.at("\\test"); + RTLIL::Module *module = design->module("\\test"); RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")), y(module->wire("\\y")); log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index b02c4cd99..d30dd2bae 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -237,7 +237,7 @@ Use ``log_cmd_error()`` to report a recoverable error: .. code:: C++ - if (design->selection_stack.back().empty()) + if (design->selection().empty()) log_cmd_error("This command can't operator on an empty selection!\n"); Use ``log_assert()`` and ``log_abort()`` instead of ``assert()`` and ``abort()``. diff --git a/kernel/driver.cc b/kernel/driver.cc index a3d85bd90..eb1326ce0 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -111,7 +111,7 @@ void run(const char *command) log_last_error = ""; } catch (...) { while (GetSize(yosys_get_design()->selection_stack) > selSize) - yosys_get_design()->selection_stack.pop_back(); + yosys_get_design()->pop_selection(); throw; } } diff --git a/kernel/register.cc b/kernel/register.cc index 11cf5b0e4..f0a5ddc06 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -318,18 +318,18 @@ void Pass::call(RTLIL::Design *design, std::vector args) pass_register[args[0]]->execute(args, design); pass_register[args[0]]->post_execute(state); while (design->selection_stack.size() > orig_sel_stack_pos) - design->selection_stack.pop_back(); + design->pop_selection(); } void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command) { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->selection_stack.push_back(selection); + design->push_selection(selection); Pass::call(design, command); - design->selection_stack.pop_back(); + design->pop_selection(); design->selected_active_module = backup_selected_active_module; } @@ -337,11 +337,11 @@ void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &sele { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->selection_stack.push_back(selection); + design->push_selection(selection); Pass::call(design, args); - design->selection_stack.pop_back(); + design->pop_selection(); design->selected_active_module = backup_selected_active_module; } @@ -349,12 +349,12 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::str { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module = module->name.str(); - design->selection_stack.push_back(RTLIL::Selection(false)); - design->selection_stack.back().select(module); + design->push_empty_selection(); + design->select(module); Pass::call(design, command); - design->selection_stack.pop_back(); + design->pop_selection(); design->selected_active_module = backup_selected_active_module; } @@ -362,12 +362,12 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vec { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module = module->name.str(); - design->selection_stack.push_back(RTLIL::Selection(false)); - design->selection_stack.back().select(module); + design->push_empty_selection(); + design->select(module); Pass::call(design, args); - design->selection_stack.pop_back(); + design->pop_selection(); design->selected_active_module = backup_selected_active_module; } @@ -745,7 +745,7 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f } while (design->selection_stack.size() > orig_sel_stack_pos) - design->selection_stack.pop_back(); + design->pop_selection(); } struct SimHelper { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 378c976ef..fa7712ee0 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -893,7 +893,7 @@ RTLIL::Design::Design() hashidx_ = hashidx_count; refcount_modules_ = 0; - selection_stack.push_back(RTLIL::Selection(true, false, this)); + push_full_selection(); #ifdef WITH_PYTHON RTLIL::Design::get_all_designs()->insert(std::pair(hashidx_, this)); @@ -1121,7 +1121,7 @@ bool RTLIL::Design::selected_module(const RTLIL::IdString& mod_name) const return false; if (selection_stack.size() == 0) return true; - return selection_stack.back().selected_module(mod_name); + return selection().selected_module(mod_name); } bool RTLIL::Design::selected_whole_module(const RTLIL::IdString& mod_name) const @@ -1130,7 +1130,7 @@ bool RTLIL::Design::selected_whole_module(const RTLIL::IdString& mod_name) const return false; if (selection_stack.size() == 0) return true; - return selection_stack.back().selected_whole_module(mod_name); + return selection().selected_whole_module(mod_name); } bool RTLIL::Design::selected_member(const RTLIL::IdString& mod_name, const RTLIL::IdString& memb_name) const @@ -1139,7 +1139,7 @@ bool RTLIL::Design::selected_member(const RTLIL::IdString& mod_name, const RTLIL return false; if (selection_stack.size() == 0) return true; - return selection_stack.back().selected_member(mod_name, memb_name); + return selection().selected_member(mod_name, memb_name); } bool RTLIL::Design::selected_module(RTLIL::Module *mod) const diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 57030d133..52b63141b 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1295,7 +1295,7 @@ struct RTLIL::Design } bool full_selection() const { - return selection_stack.back().full_selection; + return selection().full_selection; } template bool selected(T1 *module) const { @@ -1308,14 +1308,14 @@ struct RTLIL::Design template void select(T1 *module) { if (selection_stack.size() > 0) { - RTLIL::Selection &sel = selection_stack.back(); + RTLIL::Selection &sel = selection(); sel.select(module); } } template void select(T1 *module, T2 *member) { if (selection_stack.size() > 0) { - RTLIL::Selection &sel = selection_stack.back(); + RTLIL::Selection &sel = selection(); sel.select(module, member); } } diff --git a/kernel/tclapi.cc b/kernel/tclapi.cc index be39ca4a0..e970779d7 100644 --- a/kernel/tclapi.cc +++ b/kernel/tclapi.cc @@ -114,7 +114,7 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a if (in_repl) { auto design = yosys_get_design(); while (design->selection_stack.size() > 1) - design->selection_stack.pop_back(); + design->pop_selection(); log_reset_stack(); } Tcl_SetResult(interp, (char *)"Yosys command produced an error", TCL_STATIC); diff --git a/kernel/yosys.cc b/kernel/yosys.cc index d39acf9d9..85354c163 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -679,11 +679,11 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter) str += "yosys"; if (!design->selected_active_module.empty()) str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module).c_str()); - if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { + if (!design->selection_stack.empty() && !design->full_selection()) { if (design->selected_active_module.empty()) str += "*"; - else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || - design->selection_stack.back().selected_modules.count(design->selected_active_module) == 0) + else if (design->selection().selected_modules.size() != 1 || design->selection().selected_members.size() != 0 || + design->selection().selected_modules.count(design->selected_active_module) == 0) str += "*"; } snprintf(buffer, 100, "%s> ", str.c_str()); @@ -1346,7 +1346,7 @@ void shell(RTLIL::Design *design) Pass::call(design, command); } catch (log_cmd_error_exception) { while (design->selection_stack.size() > 1) - design->selection_stack.pop_back(); + design->pop_selection(); log_reset_stack(); } design->check(); diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index c09517254..833d6006d 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -102,7 +102,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n RTLIL::Module *mod = design->module(cell->type); if (mod == nullptr) continue; - if (!design->selected_whole_module(mod->name)) + if (!mod->is_selected_whole()) continue; if (mod->get_blackbox_attribute()) continue; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 168d38563..910c9e366 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -216,8 +216,8 @@ struct DesignPass : public Pass { RTLIL::Selection sel; if (argidx != args.size()) { handle_extra_select_args(this, args, argidx, args.size(), copy_from_design); - sel = copy_from_design->selection_stack.back(); - copy_from_design->selection_stack.pop_back(); + sel = copy_from_design->selection(); + copy_from_design->pop_selection(); argidx = args.size(); } @@ -368,7 +368,7 @@ struct DesignPass : public Pass { design->selection_vars.clear(); design->selected_active_module.clear(); - design->selection_stack.push_back(RTLIL::Selection()); + design->push_full_selection(); } if (reset_mode || reset_vlog_mode || !load_name.empty() || push_mode || pop_mode) diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 197bd9319..ddd72bb45 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -340,7 +340,7 @@ struct SccPass : public Pass { int origSelectPos = design->selection_stack.size() - 1; extra_args(args, argidx, design); - RTLIL::Selection newSelection(false); + RTLIL::Selection newSelection(false, false, design); int scc_counter = 0; for (auto mod : design->selected_modules()) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 1b1b7ca43..4db1c2f28 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -687,7 +687,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp if (arg[0] == '%') { if (arg == "%") { if (design->selection_stack.size() > 0) - work_stack.push_back(design->selection_stack.back()); + work_stack.push_back(design->selection()); } else if (arg == "%%") { while (work_stack.size() > 1) { @@ -1031,9 +1031,9 @@ void handle_extra_select_args(Pass *pass, const vector &args, size_t arg work_stack.pop_back(); } if (work_stack.empty()) - design->selection_stack.push_back(RTLIL::Selection(false, false, design)); + design->push_empty_selection(); else - design->selection_stack.push_back(work_stack.back()); + design->push_selection(work_stack.back()); } // extern decl. in register.h @@ -1420,7 +1420,7 @@ struct SelectPass : public Pass { if (f.fail()) log_error("Can't open '%s' for reading: %s\n", read_file.c_str(), strerror(errno)); - RTLIL::Selection sel(false); + RTLIL::Selection sel(false, false, design); string line; while (std::getline(f, line)) { @@ -1461,7 +1461,7 @@ struct SelectPass : public Pass { log_cmd_error("Option -unset can not be combined with -list, -write, -count, -set, %s.\n", common_flagset); if (work_stack.size() == 0 && got_module) { - RTLIL::Selection sel; + RTLIL::Selection sel(true, false, design); select_filter_active_mod(design, sel); work_stack.push_back(sel); } @@ -1474,13 +1474,15 @@ struct SelectPass : public Pass { log_assert(design->selection_stack.size() > 0); if (clear_mode) { - design->selection_stack.back() = RTLIL::Selection(true, false, design); + design->pop_selection(); + design->push_full_selection(); design->selected_active_module = std::string(); return; } if (none_mode) { - design->selection_stack.back() = RTLIL::Selection(false, false, design); + design->pop_selection(); + design->push_empty_selection(); return; } @@ -1496,8 +1498,8 @@ struct SelectPass : public Pass { log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno)); } if (work_stack.size() > 0) - design->selection_stack.push_back(work_stack.back()); - RTLIL::Selection *sel = &design->selection_stack.back(); + design->push_selection(work_stack.back()); + RTLIL::Selection *sel = &design->selection(); sel->optimize(design); for (auto mod : design->selected_modules()) { @@ -1515,7 +1517,7 @@ struct SelectPass : public Pass { if (f != nullptr) fclose(f); if (work_stack.size() > 0) - design->selection_stack.pop_back(); + design->pop_selection(); #undef LOG_OBJECT return; } @@ -1524,8 +1526,8 @@ struct SelectPass : public Pass { { if (work_stack.size() == 0) log_cmd_error("Nothing to add to selection.\n"); - select_op_union(design, design->selection_stack.back(), work_stack.back()); - design->selection_stack.back().optimize(design); + select_op_union(design, design->selection(), work_stack.back()); + design->selection().optimize(design); return; } @@ -1533,8 +1535,8 @@ struct SelectPass : public Pass { { if (work_stack.size() == 0) log_cmd_error("Nothing to delete from selection.\n"); - select_op_diff(design, design->selection_stack.back(), work_stack.back()); - design->selection_stack.back().optimize(design); + select_op_diff(design, design->selection(), work_stack.back()); + design->selection().optimize(design); return; } @@ -1574,7 +1576,7 @@ struct SelectPass : public Pass { if (work_stack.size() == 0) log_cmd_error("No selection to check.\n"); RTLIL::Selection *sel = &work_stack.back(); - design->selection_stack.push_back(*sel); + design->push_selection(*sel); sel->optimize(design); for (auto mod : design->selected_modules()) { module_count++; @@ -1604,7 +1606,7 @@ struct SelectPass : public Pass { log_error("Assertion failed: selection contains %d elements, less than the minimum number %d:%s\n%s", total_count, assert_min, sel_str.c_str(), desc.c_str()); } - design->selection_stack.pop_back(); + design->pop_selection(); return; } @@ -1625,7 +1627,7 @@ struct SelectPass : public Pass { } if (work_stack.size() == 0) { - RTLIL::Selection &sel = design->selection_stack.back(); + RTLIL::Selection &sel = design->selection(); if (sel.full_selection) log("*\n"); for (auto &it : sel.selected_modules) @@ -1636,8 +1638,8 @@ struct SelectPass : public Pass { return; } - design->selection_stack.back() = work_stack.back(); - design->selection_stack.back().optimize(design); + design->selection() = work_stack.back(); + design->selection().optimize(design); } } SelectPass; @@ -1677,7 +1679,8 @@ struct CdPass : public Pass { log_cmd_error("Invalid number of arguments.\n"); if (args.size() == 1 || args[1] == "/") { - design->selection_stack.back() = RTLIL::Selection(true, false, design); + design->pop_selection(); + design->push_full_selection(); design->selected_active_module = std::string(); return; } @@ -1686,7 +1689,8 @@ struct CdPass : public Pass { { string modname = design->selected_active_module; - design->selection_stack.back() = RTLIL::Selection(true, false, design); + design->pop_selection(); + design->push_full_selection(); design->selected_active_module = std::string(); while (1) @@ -1703,9 +1707,10 @@ struct CdPass : public Pass { continue; design->selected_active_module = modname; - design->selection_stack.back() = RTLIL::Selection(true, false, design); - select_filter_active_mod(design, design->selection_stack.back()); - design->selection_stack.back().optimize(design); + design->pop_selection(); + design->push_full_selection(); + select_filter_active_mod(design, design->selection()); + design->selection().optimize(design); return; } @@ -1722,9 +1727,10 @@ struct CdPass : public Pass { if (design->module(modname) != nullptr) { design->selected_active_module = modname; - design->selection_stack.back() = RTLIL::Selection(true, false, design); - select_filter_active_mod(design, design->selection_stack.back()); - design->selection_stack.back().optimize(design); + design->pop_selection(); + design->push_full_selection(); + select_filter_active_mod(design, design->selection()); + design->selection().optimize(design); return; } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 82b5c6bcf..8a1bd58c4 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -802,8 +802,8 @@ struct ShowPass : public Pass { std::pair data; data.first = args[++argidx], argidx++; handle_extra_select_args(this, args, argidx, argidx+1, design); - data.second = design->selection_stack.back(); - design->selection_stack.pop_back(); + data.second = design->selection(); + design->pop_selection(); color_selections.push_back(data); continue; } @@ -811,8 +811,8 @@ struct ShowPass : public Pass { std::pair data; data.first = args[++argidx], argidx++; handle_extra_select_args(this, args, argidx, argidx+1, design); - data.second = design->selection_stack.back(); - design->selection_stack.pop_back(); + data.second = design->selection(); + design->pop_selection(); label_selections.push_back(data); continue; } diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 5bbbb2789..97a2886d4 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -468,7 +468,7 @@ struct StatPass : public Pass { first_module = false; } else { log("\n"); - log("=== %s%s ===\n", log_id(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)"); + log("=== %s%s ===\n", log_id(mod->name), mod->is_selected_whole() ? "" : " (partially selected)"); log("\n"); data.log_data(mod->name, false); } diff --git a/passes/cmds/viz.cc b/passes/cmds/viz.cc index 9dd68bd00..131e799ab 100644 --- a/passes/cmds/viz.cc +++ b/passes/cmds/viz.cc @@ -950,8 +950,8 @@ struct VizPass : public Pass { auto type = arg == "-g" || arg == "-G" ? VizConfig::TYPE_G : arg == "-u" || arg == "-U" ? VizConfig::TYPE_U : arg == "-x" || arg == "-X" ? VizConfig::TYPE_X : VizConfig::TYPE_S; - config.groups.push_back({type, design->selection_stack.back()}); - design->selection_stack.pop_back(); + config.groups.push_back({type, design->selection()}); + design->pop_selection(); continue; } if (arg == "-0" || arg == "-1" || arg == "-2" || arg == "-3" || arg == "-4" || diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 52fd59cf8..facc5d173 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -246,7 +246,7 @@ struct SubmodWorker SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, bool hidden_mode = false, std::string opt_name = std::string()) : design(design), module(module), sigmap(module), copy_mode(copy_mode), hidden_mode(hidden_mode), opt_name(opt_name) { - if (!design->selected_whole_module(module->name) && opt_name.empty()) + if (!module->is_selected_whole() && opt_name.empty()) return; if (module->processes.size() > 0) { diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index bca6a5ec6..e86b964e5 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -57,7 +57,7 @@ struct CutpointPass : public Pass { for (auto module : design->selected_modules()) { - if (design->selected_whole_module(module->name)) { + if (module->is_selected_whole()) { log("Making all outputs of module %s cut points, removing module contents.\n", log_id(module)); module->new_connections(std::vector()); for (auto cell : vector(module->cells())) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index a96a82659..56fa4b011 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -400,7 +400,7 @@ struct Abc9Pass : public ScriptPass } log_push(); - active_design->selection().select(mod); + active_design->select(mod); if (!active_design->selected_whole_module(mod)) log_error("Can't handle partially selected module %s!\n", log_id(mod)); @@ -452,7 +452,7 @@ struct Abc9Pass : public ScriptPass log_pop(); } - active_design->selection_stack.pop_back(); + active_design->pop_selection(); } } diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 4c7667a43..0d28b8f4a 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -454,7 +454,7 @@ void prep_bypass(RTLIL::Design *design) void prep_dff(RTLIL::Design *design) { - auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection(false))); + auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection(false, false, design))); auto &modules_sel = r.first->second; for (auto module : design->selected_modules()) diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index 5be823916..23670394b 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -157,7 +157,7 @@ struct AbcNewPass : public ScriptPass { exe_options = abc_exe_options; log_header(active_design, "Mapping module '%s'.\n", log_id(mod)); log_push(); - active_design->selection().select(mod); + active_design->select(mod); } std::string script_save; @@ -194,7 +194,7 @@ struct AbcNewPass : public ScriptPass { } if (!help_mode) { - active_design->selection_stack.pop_back(); + active_design->pop_selection(); } } } diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 4836ebe34..b51ad912e 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -172,7 +172,7 @@ struct AigmapPass : public Pass { if (select_mode) { log_assert(!design->selection_stack.empty()); - RTLIL::Selection& sel = design->selection_stack.back(); + RTLIL::Selection& sel = design->selection(); sel.selected_members[module->name] = std::move(new_sel); } diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index 016789157..098c227f6 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -42,7 +42,7 @@ struct NlutmapWorker RTLIL::Selection get_selection() { - RTLIL::Selection sel(false); + RTLIL::Selection sel(false, false, module->design); for (auto cell : module->cells()) if (!mapped_cells.count(cell)) sel.select(module, cell); From 091e9488feb9888006e407e60cf9957bcfbbcaf4 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:14 +1300 Subject: [PATCH 049/133] rtlil: Design::top_module() can be const Since it doesn't change anything and is just a lookup. --- kernel/rtlil.cc | 2 +- kernel/rtlil.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index fa7712ee0..8205165f5 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -938,7 +938,7 @@ const RTLIL::Module *RTLIL::Design::module(const RTLIL::IdString& name) const return modules_.count(name) ? modules_.at(name) : NULL; } -RTLIL::Module *RTLIL::Design::top_module() +RTLIL::Module *RTLIL::Design::top_module() const { RTLIL::Module *module = nullptr; int module_count = 0; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 52b63141b..b754b4717 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1246,7 +1246,7 @@ struct RTLIL::Design RTLIL::ObjRange modules(); RTLIL::Module *module(const RTLIL::IdString &name); const RTLIL::Module *module(const RTLIL::IdString &name) const; - RTLIL::Module *top_module(); + RTLIL::Module *top_module() const; bool has(const RTLIL::IdString &id) const { return modules_.count(id) != 0; From d09ae42951c58599b334b667455826e06d892d10 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:14 +1300 Subject: [PATCH 050/133] Fixing selections --- kernel/rtlil.cc | 2 +- passes/cmds/select.cc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8205165f5..a48a37834 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1185,7 +1185,7 @@ void RTLIL::Design::pop_selection() std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const { bool include_partials = partials == RTLIL::SELECT_ALL; - bool exclude_boxes = (partials & RTLIL::SB_UNBOXED_ONLY) == 0; + bool exclude_boxes = (partials & RTLIL::SB_UNBOXED_ONLY) != 0; bool ignore_wb = (partials & RTLIL::SB_INCL_WB) != 0; std::vector result; result.reserve(modules_.size()); diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 4db1c2f28..1eed7c818 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1000,7 +1000,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel, bool whole_modules = false) { std::string desc = "Selection contains:\n"; - for (auto mod : design->selected_modules()) + for (auto mod : design->all_selected_modules()) { if (whole_modules && sel->selected_whole_module(mod->name)) desc += stringf("%s\n", id2cstr(mod->name)); @@ -1501,7 +1501,7 @@ struct SelectPass : public Pass { design->push_selection(work_stack.back()); RTLIL::Selection *sel = &design->selection(); sel->optimize(design); - for (auto mod : design->selected_modules()) + for (auto mod : design->all_selected_modules()) { if (sel->selected_whole_module(mod->name) && list_mode) log("%s\n", id2cstr(mod->name)); @@ -1578,7 +1578,7 @@ struct SelectPass : public Pass { RTLIL::Selection *sel = &work_stack.back(); design->push_selection(*sel); sel->optimize(design); - for (auto mod : design->selected_modules()) { + for (auto mod : design->all_selected_modules()) { module_count++; for ([[maybe_unused]] auto member_name : mod->selected_members()) total_count++; @@ -1777,7 +1777,7 @@ struct LsPass : public Pass { { std::vector matches; - for (auto mod : design->selected_modules()) + for (auto mod : design->all_selected_modules()) matches.push_back(mod->name); if (!matches.empty()) { From 59802584b0ad9a9731769d1086b278421e1eca6a Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:14 +1300 Subject: [PATCH 051/133] Fix describe_selection_for_assert If the current selection is not the provided selection, push the provided selection. --- passes/cmds/select.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 1eed7c818..54b6f0a42 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -999,6 +999,8 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel, bool whole_modules = false) { + bool push_selection = &design->selection() != sel; + if (push_selection) design->push_selection(*sel); std::string desc = "Selection contains:\n"; for (auto mod : design->all_selected_modules()) { @@ -1007,6 +1009,7 @@ static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::S for (auto it : mod->selected_members()) desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)); } + if (push_selection) design->pop_selection(); return desc; } From f15cd73419eb735210bbb09cd03d654faf111a43 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:14 +1300 Subject: [PATCH 052/133] Fix select_op_random ignoring boxes --- passes/cmds/select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 54b6f0a42..8579c6111 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -228,7 +228,7 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c } } - lhs = RTLIL::Selection(false, false, design); + lhs = RTLIL::Selection(false, lhs.selects_boxes, design); while (!objects.empty() && count-- > 0) { From b296a970d260b9709ed52a296fae2a4ed1e534e7 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:14 +1300 Subject: [PATCH 053/133] abc9: Use push_empty_selection() --- passes/techmap/abc9.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 56fa4b011..1313fbd73 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -391,7 +391,7 @@ struct Abc9Pass : public ScriptPass } else { auto selected_modules = active_design->selected_modules(); - active_design->selection_stack.emplace_back(false); + active_design->push_empty_selection(); for (auto mod : selected_modules) { if (mod->processes.size() > 0) { @@ -402,6 +402,7 @@ struct Abc9Pass : public ScriptPass log_push(); active_design->select(mod); + // this check does nothing because the above line adds the whole module to the selection if (!active_design->selected_whole_module(mod)) log_error("Can't handle partially selected module %s!\n", log_id(mod)); From 9a9cd05f6c195f00e64ed39a3a414d2aa3e64bee Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:15 +1300 Subject: [PATCH 054/133] tests: Fixes for boxes cxxrtl `test_unconnected_output` and simple_abc9 `abc9.v` both expect boxed modules in the outputs, so make sure they work as expected. --- tests/cxxrtl/run-test.sh | 2 +- tests/simple_abc9/run-test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cxxrtl/run-test.sh b/tests/cxxrtl/run-test.sh index fd11a3783..ee299fc82 100755 --- a/tests/cxxrtl/run-test.sh +++ b/tests/cxxrtl/run-test.sh @@ -13,5 +13,5 @@ run_subtest value run_subtest value_fuzz # Compile-only test. -../../yosys -p "read_verilog test_unconnected_output.v; proc; clean; write_cxxrtl cxxrtl-test-unconnected_output.cc" +../../yosys -p "read_verilog test_unconnected_output.v; select =*; proc; clean; write_cxxrtl cxxrtl-test-unconnected_output.cc" ${CC:-gcc} -std=c++11 -c -o cxxrtl-test-unconnected_output -I../../backends/cxxrtl/runtime cxxrtl-test-unconnected_output.cc diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh index b75e54dd3..5669321ac 100755 --- a/tests/simple_abc9/run-test.sh +++ b/tests/simple_abc9/run-test.sh @@ -49,6 +49,6 @@ exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v *.sv EXTRA_FLAGS="-f \"veri clean; \ check -assert * abc9_test037 %d; \ select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%; \ - setattr -mod -unset blackbox -unset whitebox'" + setattr -mod -unset blackbox -unset whitebox =*'" # NOTE: Skip 'check -assert' on abc9_test037 because it intentionally has a combinatorial loop From a30bacfcb142a40ed6465c23af89d6978f3001f2 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:15 +1300 Subject: [PATCH 055/133] Add Selection::complete_selection Used to select all modules including boxes, set when both `full` and `boxes` are true in the constructor, pulling down `full_selection`. Add `Selection::selects_all()` method as short hand for `full_selection || complete_selection`. Update selection operations to account for complete selections. Add static methods to `Selection` for creating a new empty/full/complete selection to make it clearer to users when doing so. Use said static methods to replace most instances of the `Selection` constructor. Update `Selection::optimize` to use --- kernel/rtlil.cc | 36 +++++++++--------- kernel/rtlil.h | 22 ++++++++--- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 75 ++++++++++++++++++++++++-------------- passes/techmap/abc9_ops.cc | 2 +- passes/techmap/nlutmap.cc | 2 +- 6 files changed, 86 insertions(+), 53 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a48a37834..f9f4cca4a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -779,6 +779,8 @@ bool RTLIL::Selection::boxed_module(const RTLIL::IdString &mod_name) const bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const { + if (complete_selection) + return true; if (!selects_boxes && boxed_module(mod_name)) return false; if (full_selection) @@ -792,6 +794,8 @@ bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) const { + if (complete_selection) + return true; if (!selects_boxes && boxed_module(mod_name)) return false; if (full_selection) @@ -803,6 +807,8 @@ bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) co bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const { + if (complete_selection) + return true; if (!selects_boxes && boxed_module(mod_name)) return false; if (full_selection) @@ -821,16 +827,13 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) current_design = design; } - if (selects_boxes && full_selection) { - selected_modules.clear(); - selected_members.clear(); + if (selects_boxes && full_selection) + complete_selection = true; + if (complete_selection) { full_selection = false; - for (auto mod : current_design->modules()) { - selected_modules.insert(mod->name); - } - return; + selects_boxes = true; } - if (full_selection) { + if (selects_all()) { selected_modules.clear(); selected_members.clear(); return; @@ -878,10 +881,13 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) selected_modules.insert(mod_name); } - if (!selects_boxes && selected_modules.size() == current_design->modules_.size()) { - full_selection = true; + if (selected_modules.size() == current_design->modules_.size()) { selected_modules.clear(); selected_members.clear(); + if (selects_boxes) + complete_selection = true; + else + full_selection = true; } } @@ -1160,21 +1166,17 @@ void RTLIL::Design::push_selection(RTLIL::Selection sel) void RTLIL::Design::push_empty_selection() { - RTLIL::Selection sel(false, false, this); - push_selection(sel); + push_selection(RTLIL::Selection::EmptySelection(this)); } void RTLIL::Design::push_full_selection() { - RTLIL::Selection sel(true, false, this); - push_selection(sel); + push_selection(RTLIL::Selection::FullSelection(this)); } void RTLIL::Design::push_complete_selection() { - RTLIL::Selection sel(true, true, this); - sel.optimize(this); - push_selection(sel); + push_selection(RTLIL::Selection::CompleteSelection(this)); } void RTLIL::Design::pop_selection() diff --git a/kernel/rtlil.h b/kernel/rtlil.h index b754b4717..56f00fdf6 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1166,11 +1166,13 @@ struct RTLIL::Selection { bool full_selection; bool selects_boxes; + bool complete_selection; pool selected_modules; dict> selected_members; RTLIL::Design *current_design; - Selection(bool full = true, bool boxes = false, RTLIL::Design *design = nullptr) : full_selection(full), selects_boxes(boxes), current_design(design) { } + Selection(bool full = true, bool boxes = false, RTLIL::Design *design = nullptr) : + full_selection(full && !boxes), selects_boxes(boxes), complete_selection(full && boxes), current_design(design) { } bool boxed_module(const RTLIL::IdString &mod_name) const; bool selected_module(const RTLIL::IdString &mod_name) const; @@ -1178,21 +1180,29 @@ struct RTLIL::Selection bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; void optimize(RTLIL::Design *design); + bool selects_all() const { + return full_selection || complete_selection; + } + template void select(T1 *module) { - if (!full_selection && selected_modules.count(module->name) == 0) { + if (!selects_all() && selected_modules.count(module->name) == 0) { selected_modules.insert(module->name); selected_members.erase(module->name); } } template void select(T1 *module, T2 *member) { - if (!full_selection && selected_modules.count(module->name) == 0) + if (!selects_all() && selected_modules.count(module->name) == 0) selected_members[module->name].insert(member->name); } bool empty() const { - return !full_selection && selected_modules.empty() && selected_members.empty(); + return !selects_all() && selected_modules.empty() && selected_members.empty(); } + + static Selection EmptySelection(RTLIL::Design *design = nullptr) { return Selection(false, false, design); }; + static Selection FullSelection(RTLIL::Design *design = nullptr) { return Selection(true, false, design); }; + static Selection CompleteSelection(RTLIL::Design *design = nullptr) { return Selection(true, true, design); }; }; struct RTLIL::Monitor @@ -1282,8 +1292,8 @@ struct RTLIL::Design void push_selection(RTLIL::Selection sel); void push_empty_selection(); - void push_full_selection(); - void push_complete_selection(); + void push_full_selection(); // all modules excluding boxes + void push_complete_selection(); // all modules including boxes void pop_selection(); RTLIL::Selection &selection() { diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index ddd72bb45..0f988e57a 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -340,7 +340,7 @@ struct SccPass : public Pass { int origSelectPos = design->selection_stack.size() - 1; extra_args(args, argidx, design); - RTLIL::Selection newSelection(false, false, design); + auto newSelection = RTLIL::Selection::EmptySelection(design); int scc_counter = 0; for (auto mod : design->selected_modules()) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 8579c6111..7517af80a 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -141,35 +141,40 @@ static bool match_attr(const dict &attributes, co return match_attr(attributes, match_expr, std::string(), 0); } -static void full_select_no_box(RTLIL::Design *design, RTLIL::Selection &lhs) +static void select_all(RTLIL::Design *design, RTLIL::Selection &lhs) { - if (!lhs.full_selection) + if (!lhs.selects_all()) return; - lhs.current_design = design; lhs.selected_modules.clear(); for (auto mod : design->modules()) { - if (mod->get_blackbox_attribute()) + if (!lhs.selects_boxes && mod->get_blackbox_attribute()) continue; lhs.selected_modules.insert(mod->name); } + lhs.full_selection = false; + lhs.complete_selection = false; } static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) { - if (lhs.full_selection) { + if (lhs.selects_all()) { lhs.full_selection = false; + lhs.complete_selection = false; lhs.selected_modules.clear(); lhs.selected_members.clear(); return; } - if (!lhs.selects_boxes && lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { - lhs.full_selection = true; + if (lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { + if (lhs.selects_boxes) + lhs.complete_selection = true; + else + lhs.full_selection = true; return; } - RTLIL::Selection new_sel(false); + auto new_sel = RTLIL::Selection::EmptySelection(); for (auto mod : design->modules()) { @@ -312,10 +317,17 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { + if (lhs.complete_selection) + return; + else if (rhs.complete_selection) { + lhs.complete_selection = true; + lhs.optimize(design); + return; + } + if (rhs.selects_boxes) { if (lhs.full_selection) { - full_select_no_box(design, lhs); - lhs.full_selection = false; + select_all(design, lhs); } lhs.selects_boxes = true; } @@ -325,7 +337,7 @@ static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const if (rhs.full_selection) { if (lhs.selects_boxes) { auto new_rhs = RTLIL::Selection(rhs); - full_select_no_box(design, new_rhs); + select_all(design, new_rhs); for (auto mod : new_rhs.selected_modules) lhs.selected_modules.insert(mod); } else { @@ -348,10 +360,19 @@ static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { + if (rhs.complete_selection) { + lhs.full_selection = false; + lhs.complete_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); + return; + } + if (rhs.full_selection) { if (lhs.selects_boxes) { auto new_rhs = RTLIL::Selection(rhs); - full_select_no_box(design, new_rhs); + select_all(design, new_rhs); + select_all(design, lhs); for (auto mod : new_rhs.selected_modules) { lhs.selected_modules.erase(mod); lhs.selected_members.erase(mod); @@ -364,12 +385,10 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R return; } - if (lhs.full_selection) { - if (rhs.empty()) - return; - full_select_no_box(design, lhs); - lhs.full_selection = false; - } + if (rhs.empty() || lhs.empty()) + return; + + select_all(design, lhs); for (auto &it : rhs.selected_modules) { lhs.selected_modules.erase(it); @@ -406,14 +425,16 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { + if (rhs.complete_selection) + return; + if (rhs.full_selection && !lhs.selects_boxes) return; - if (lhs.full_selection) { - lhs.full_selection = false; - for (auto mod : design->modules()) - lhs.selected_modules.insert(mod->name); - } + if (lhs.empty() || rhs.empty()) + return; + + select_all(design, lhs); std::vector del_list; @@ -1050,7 +1071,7 @@ RTLIL::Selection eval_select_args(const vector &args, RTLIL::Design *des work_stack.pop_back(); } if (work_stack.empty()) - return RTLIL::Selection(false, false, design); + return RTLIL::Selection::EmptySelection(design); return work_stack.back(); } @@ -1423,7 +1444,7 @@ struct SelectPass : public Pass { if (f.fail()) log_error("Can't open '%s' for reading: %s\n", read_file.c_str(), strerror(errno)); - RTLIL::Selection sel(false, false, design); + auto sel = RTLIL::Selection::EmptySelection(design); string line; while (std::getline(f, line)) { @@ -1464,7 +1485,7 @@ struct SelectPass : public Pass { log_cmd_error("Option -unset can not be combined with -list, -write, -count, -set, %s.\n", common_flagset); if (work_stack.size() == 0 && got_module) { - RTLIL::Selection sel(true, false, design); + auto sel = RTLIL::Selection::FullSelection(design); select_filter_active_mod(design, sel); work_stack.push_back(sel); } @@ -1616,7 +1637,7 @@ struct SelectPass : public Pass { if (!set_name.empty()) { if (work_stack.size() == 0) - design->selection_vars[set_name] = RTLIL::Selection(false, false, design); + design->selection_vars[set_name] = RTLIL::Selection::EmptySelection(design); else design->selection_vars[set_name] = work_stack.back(); return; diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 0d28b8f4a..6cb569b5a 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -454,7 +454,7 @@ void prep_bypass(RTLIL::Design *design) void prep_dff(RTLIL::Design *design) { - auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection(false, false, design))); + auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection::EmptySelection(design))); auto &modules_sel = r.first->second; for (auto module : design->selected_modules()) diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index 098c227f6..c823f10fe 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -42,7 +42,7 @@ struct NlutmapWorker RTLIL::Selection get_selection() { - RTLIL::Selection sel(false, false, module->design); + auto sel = RTLIL::Selection::EmptySelection(module->design); for (auto cell : module->cells()) if (!mapped_cells.count(cell)) sel.select(module, cell); From 824f7146aab8302510b3e205877971a597f9a753 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:15 +1300 Subject: [PATCH 056/133] Selecting a blackbox sets selects_boxes --- kernel/rtlil.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 56f00fdf6..d7c860b39 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1188,12 +1188,17 @@ struct RTLIL::Selection if (!selects_all() && selected_modules.count(module->name) == 0) { selected_modules.insert(module->name); selected_members.erase(module->name); + if (module->get_blackbox_attribute()) + selects_boxes = true; } } template void select(T1 *module, T2 *member) { - if (!selects_all() && selected_modules.count(module->name) == 0) + if (!selects_all() && selected_modules.count(module->name) == 0) { selected_members[module->name].insert(member->name); + if (module->get_blackbox_attribute()) + selects_boxes = true; + } } bool empty() const { From cacea737bcc3f6aa826891ea8f9f17a550771c3f Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:15 +1300 Subject: [PATCH 057/133] select.cc: Re-add '=' to empty selection warning --- passes/cmds/select.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 7517af80a..c42c0ead2 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1008,12 +1008,16 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp for (auto &it : arg_mod_found) { if (it.second == false && !disable_empty_warning) { - log_warning("Selection \"%s\" did not match any module.\n", it.first.c_str()); + std::string selection_str = select_blackboxes ? "=" : ""; + selection_str += it.first; + log_warning("Selection \"%s\" did not match any module.\n", selection_str.c_str()); } } for (auto &it : arg_memb_found) { if (it.second == false && !disable_empty_warning) { - log_warning("Selection \"%s\" did not match any object.\n", it.first.c_str()); + std::string selection_str = select_blackboxes ? "=" : ""; + selection_str += it.first; + log_warning("Selection \"%s\" did not match any object.\n", selection_str.c_str()); } } } From 2dec493054aede44642f7af993ca9c4be97ba479 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:15 +1300 Subject: [PATCH 058/133] abc9.cc: Call select =* Or rather, say we're calling `select =*`, but actually bypass the select command to avoid the warning that can pop up if there is nothing to select. --- passes/techmap/abc9.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 1313fbd73..3a79c0dbf 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -306,6 +306,8 @@ struct Abc9Pass : public ScriptPass } run("design -stash $abc9"); run("design -load $abc9_map"); + if (help_mode) run("select =*"); + else active_design->push_complete_selection(); run("proc"); run("wbflip"); run("techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); @@ -369,6 +371,8 @@ struct Abc9Pass : public ScriptPass if (saved_designs.count("$abc9_holes") || help_mode) { run("design -stash $abc9"); run("design -load $abc9_holes"); + if (help_mode) run("select =*"); + else active_design->push_complete_selection(); run("techmap -wb -map %$abc9 -map +/techmap.v"); run("opt -purge"); run("aigmap"); From 38293d3bdf3d07be14b531dcbffa56c9d61edb51 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:16 +1300 Subject: [PATCH 059/133] select.cc: Fix %i when rhs is empty --- passes/cmds/select.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index c42c0ead2..bb1055c67 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -431,9 +431,17 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co if (rhs.full_selection && !lhs.selects_boxes) return; - if (lhs.empty() || rhs.empty()) + if (lhs.empty()) return; + if (rhs.empty()) { + lhs.full_selection = false; + lhs.complete_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); + return; + } + select_all(design, lhs); std::vector del_list; From 7eaf33e4da19142cfa127d09660a3a2e8a55fced Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:16 +1300 Subject: [PATCH 060/133] abc9: Use techmap -autoproc Fixes quicklogic/pp3 problem with `dffepc` including processes. Also means the preceding `proc` is safe to remove (and may result in some small speedup by doing so). --- passes/techmap/abc9.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 3a79c0dbf..fe5cc7af1 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -308,9 +308,8 @@ struct Abc9Pass : public ScriptPass run("design -load $abc9_map"); if (help_mode) run("select =*"); else active_design->push_complete_selection(); - run("proc"); run("wbflip"); - run("techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); + run("techmap -autoproc -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); run("opt -nodffe -nosdff"); if (dff_mode || help_mode) { if (!help_mode) From add5eba9b2070cbaa3ab937bde27fc94f274519b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:16 +1300 Subject: [PATCH 061/133] Design::selection_stack should never be empty Add a `log_assert` for it in `Design::check()`. Remove unneeded checks in other places. --- kernel/rtlil.cc | 14 ++++++++------ kernel/rtlil.h | 12 ++++-------- kernel/yosys.cc | 2 +- passes/cmds/select.cc | 5 ++--- passes/techmap/aigmap.cc | 1 - 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f9f4cca4a..6a29c42e7 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1102,6 +1102,7 @@ void RTLIL::Design::sort() void RTLIL::Design::check() { #ifndef NDEBUG + log_assert(!selection_stack.empty()); for (auto &it : modules_) { log_assert(this == it.second->design); log_assert(it.first == it.second->name); @@ -1125,8 +1126,6 @@ bool RTLIL::Design::selected_module(const RTLIL::IdString& mod_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - if (selection_stack.size() == 0) - return true; return selection().selected_module(mod_name); } @@ -1134,8 +1133,6 @@ bool RTLIL::Design::selected_whole_module(const RTLIL::IdString& mod_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - if (selection_stack.size() == 0) - return true; return selection().selected_whole_module(mod_name); } @@ -1143,8 +1140,6 @@ bool RTLIL::Design::selected_member(const RTLIL::IdString& mod_name, const RTLIL { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - if (selection_stack.size() == 0) - return true; return selection().selected_member(mod_name, memb_name); } @@ -1182,6 +1177,9 @@ void RTLIL::Design::push_complete_selection() void RTLIL::Design::pop_selection() { selection_stack.pop_back(); + // Default to a full_selection if we ran out of stack + if (selection_stack.empty()) + push_full_selection(); } std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const @@ -2366,6 +2364,10 @@ void RTLIL::Module::check() log_assert(!packed_memids.count(memid)); packed_memids.insert(memid); } + auto cell_mod = design->module(it.first); + if (cell_mod != nullptr) { + log_assert(!it.second->get_blackbox_attribute()); + } } for (auto &it : processes) { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d7c860b39..1c7eaec39 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1322,17 +1322,13 @@ struct RTLIL::Design } template void select(T1 *module) { - if (selection_stack.size() > 0) { - RTLIL::Selection &sel = selection(); - sel.select(module); - } + RTLIL::Selection &sel = selection(); + sel.select(module); } template void select(T1 *module, T2 *member) { - if (selection_stack.size() > 0) { - RTLIL::Selection &sel = selection(); - sel.select(module, member); - } + RTLIL::Selection &sel = selection(); + sel.select(module, member); } diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 85354c163..37e820060 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -679,7 +679,7 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter) str += "yosys"; if (!design->selected_active_module.empty()) str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module).c_str()); - if (!design->selection_stack.empty() && !design->full_selection()) { + if (!design->full_selection()) { if (design->selected_active_module.empty()) str += "*"; else if (design->selection().selected_modules.size() != 1 || design->selection().selected_members.size() != 0 || diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index bb1055c67..1ed1987c8 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -715,8 +715,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp if (arg[0] == '%') { if (arg == "%") { - if (design->selection_stack.size() > 0) - work_stack.push_back(design->selection()); + work_stack.push_back(design->selection()); } else if (arg == "%%") { while (work_stack.size() > 1) { @@ -1507,7 +1506,7 @@ struct SelectPass : public Pass { work_stack.pop_back(); } - log_assert(design->selection_stack.size() > 0); + log_assert(!design->selection_stack.empty()); if (clear_mode) { design->pop_selection(); diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index b51ad912e..19e568a61 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -171,7 +171,6 @@ struct AigmapPass : public Pass { module->remove(cell); if (select_mode) { - log_assert(!design->selection_stack.empty()); RTLIL::Selection& sel = design->selection(); sel.selected_members[module->name] = std::move(new_sel); } From 732c82f8514c0d4963c604f00503d59dc1c080e2 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:56 +1300 Subject: [PATCH 062/133] abc_new: Use push_empty_selection() --- passes/techmap/abc_new.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index 23670394b..dfa2e2f71 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -139,7 +139,7 @@ struct AbcNewPass : public ScriptPass { if (!help_mode) { selected_modules = order_modules(active_design, active_design->selected_whole_modules_warn()); - active_design->selection_stack.emplace_back(false); + active_design->push_empty_selection(); } else { selected_modules = {nullptr}; run("foreach module in selection"); From 46a311acb2089ce65ae361d45e39910821559f96 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:56 +1300 Subject: [PATCH 063/133] firrtl: Drop full_selection check Change `top` pointer default to `nullptr` to avoid issues with `Design->top_module()` only operating on the current selection. Calls to other passes (`bmuxmap` etc) will only operate on the current selection, and may cause problems when those cells are unprocessed, but this is consistent with the other backends that only operate on the full designs and will hopefully be fixed in another PR soon :) --- backends/firrtl/firrtl.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index eac0c9719..ceb805dcb 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -1215,9 +1215,6 @@ struct FirrtlBackend : public Backend { } extra_args(f, filename, args, argidx); - if (!design->full_selection()) - log_cmd_error("This command only operates on fully selected designs!\n"); - log_header(design, "Executing FIRRTL backend.\n"); log_push(); @@ -1230,7 +1227,7 @@ struct FirrtlBackend : public Backend { autoid_counter = 0; // Get the top module, or a reasonable facsimile - we need something for the circuit name. - Module *top = design->top_module(); + Module *top = nullptr; Module *last = nullptr; // Generate module and wire names. for (auto module : design->modules()) { From a3968d43f0e9895a9f00b88ba2bfd5b284f0c648 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:56 +1300 Subject: [PATCH 064/133] Drop deprecation on Design::selected_modules() Instead, change the default `Design::selected_modules()` to match the behaviour (i.e. `selected_unboxed_modules_warn()`) because it's a lot of files to touch and they don't really _need_ to be updated. Also change `Design::selected_whole_modules()` users over to `Design::selected_unboxed_whole_modules()`, except `attrmap` because I'm not convinced it should be ignoring boxes. So instead, leave the deprecation warning for that one use and come back to the pass another time. --- kernel/rtlil.h | 4 +--- passes/opt/opt_clean.cc | 2 +- passes/sat/sim.cc | 4 ++-- passes/techmap/clockgate.cc | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 1c7eaec39..c81990f43 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1332,10 +1332,8 @@ struct RTLIL::Design } - std::vector selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes = SB_ALL) const; + std::vector selected_modules(RTLIL::SelectPartials partials = SELECT_ALL, RTLIL::SelectBoxes boxes = SB_UNBOXED_WARN) const; - [[deprecated("Use selected_unboxed_modules() to maintain prior behaviour, or consider one of the other selected module helpers.")]] - std::vector selected_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } std::vector all_selected_modules() const { return selected_modules(SELECT_ALL, SB_ALL); } std::vector selected_unboxed_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_ONLY); } std::vector selected_unboxed_modules_warn() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index c37c03607..620b38813 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -734,7 +734,7 @@ struct CleanPass : public Pass { count_rm_cells = 0; count_rm_wires = 0; - for (auto module : design->selected_whole_modules()) { + for (auto module : design->selected_unboxed_whole_modules()) { if (module->has_processes()) continue; rmunused_module(module, purge_mode, ys_debug(), true); diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 8fac93b98..dd2f1d255 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2887,7 +2887,7 @@ struct SimPass : public Pass { if (!top_mod) log_cmd_error("Design has no top module, use the 'hierarchy' command to specify one.\n"); } else { - auto mods = design->selected_whole_modules(); + auto mods = design->selected_unboxed_whole_modules(); if (GetSize(mods) != 1) log_cmd_error("Only one top module must be selected.\n"); top_mod = mods.front(); @@ -3016,7 +3016,7 @@ struct Fst2TbPass : public Pass { if (!top_mod) log_cmd_error("Design has no top module, use the 'hierarchy' command to specify one.\n"); } else { - auto mods = design->selected_whole_modules(); + auto mods = design->selected_unboxed_whole_modules(); if (GetSize(mods) != 1) log_cmd_error("Only one top module must be selected.\n"); top_mod = mods.front(); diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index 52851d922..3a3d24c0f 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -333,7 +333,7 @@ struct ClockgatePass : public Pass { dict clk_nets; int gated_flop_count = 0; - for (auto module : design->selected_whole_modules()) { + for (auto module : design->selected_unboxed_whole_modules()) { for (auto cell : module->cells()) { if (!RTLIL::builtin_ff_cell_types().count(cell->type)) continue; From 68adac691d0a5fcb257169b5b6ff4171e2292d24 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:40:06 +1300 Subject: [PATCH 065/133] rtlil.cc: Add comment to log_assert Because the use of `RTLIL::AttrObject::get_blackbox_attribute()` is deprecated, but the assert is needed in case users are doing weird things. --- kernel/rtlil.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 6a29c42e7..c9d2f6760 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2366,6 +2366,9 @@ void RTLIL::Module::check() } auto cell_mod = design->module(it.first); if (cell_mod != nullptr) { + // assertion check below to make sure that there are no + // cases where a cell has a blackbox attribute since + // that is deprecated log_assert(!it.second->get_blackbox_attribute()); } } From 8405b3b72308d2b393e4ab3a14f00850b9a6d662 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 16:32:00 +1300 Subject: [PATCH 066/133] select: Fix -none and -clear If the selection stack only has one element (which it normally does), then `design->pop_selection()` automatically resets to the default full selection. This is a problem for `select [-none | -clear]` which were trying to replace the current selection, but because the pop added an extra element when the `execute` returned, the extra selection (the one we actually wanted) gets popped too. So instead, reassign `design->selection()` in the same way as if we called `select [selection]`. Also adds selection stack tests, and removes the accidentally-committed `boxes_dummy.ys`. --- passes/cmds/select.cc | 6 ++---- tests/select/boxes_dummy.ys | 13 ------------- tests/select/boxes_stack.ys | 29 +++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 17 deletions(-) delete mode 100644 tests/select/boxes_dummy.ys create mode 100644 tests/select/boxes_stack.ys diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 1ed1987c8..c34cf43c6 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1509,15 +1509,13 @@ struct SelectPass : public Pass { log_assert(!design->selection_stack.empty()); if (clear_mode) { - design->pop_selection(); - design->push_full_selection(); + design->selection() = RTLIL::Selection::FullSelection(design); design->selected_active_module = std::string(); return; } if (none_mode) { - design->pop_selection(); - design->push_empty_selection(); + design->selection() = RTLIL::Selection::EmptySelection(design); return; } diff --git a/tests/select/boxes_dummy.ys b/tests/select/boxes_dummy.ys deleted file mode 100644 index 67d59bdf1..000000000 --- a/tests/select/boxes_dummy.ys +++ /dev/null @@ -1,13 +0,0 @@ -read_verilog -specify boxes.v -clean - -echo on -select -list -select -count -select -count * -select -count top -select -count top/w:* -select -list =* -select -count =* -select -clear -select -assert-count 9 =?b diff --git a/tests/select/boxes_stack.ys b/tests/select/boxes_stack.ys new file mode 100644 index 000000000..8c2eb7526 --- /dev/null +++ b/tests/select/boxes_stack.ys @@ -0,0 +1,29 @@ +read_verilog -specify boxes.v +clean + +# default selection == select * +select -assert-count 4 * +select -assert-count 4 % + +# -none replaces default selection +select -none +select -assert-none % +select -assert-count 13 =* + +# select replaces current selection +select =* +select -assert-count 13 % + +# -module changes module +select -module wb +select -assert-none % +select -assert-count 5 =* + +# -none maintains module +select -none +select -assert-count 5 =* + +# -clear clears current selection and module +select -clear +select -assert-count 4 % +select -assert-count 13 =* From d8af6b06168b025ea4b7165dfaf6fb3cad8ba3b8 Mon Sep 17 00:00:00 2001 From: Scott Ashcroft Date: Fri, 14 Mar 2025 21:47:26 +0100 Subject: [PATCH 067/133] docs: Add latex magic to make PDFs reproducible again --- docs/source/conf.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/source/conf.py b/docs/source/conf.py index 607e088da..6a0e92167 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -93,6 +93,9 @@ bibtex_bibfiles = ['literature.bib'] latex_elements = { 'releasename': 'Version', 'preamble': r''' +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} \usepackage{lmodern} \usepackage{comment} From 8877817fa915897e168f604f4c4d40c16d570063 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 15 Mar 2025 12:14:09 +1300 Subject: [PATCH 068/133] Fix Docs issues for offline pdf builds #4777 Drop svg badges. Even though they were only appearing in the html version, the latexpdf target was still trying to download them, leading to warnings-as-errors in offline builds. --- docs/source/getting_started/installation.rst | 27 +++++-------------- .../extending_yosys/test_suites.rst | 18 +++---------- 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 4f31af966..fe96b2314 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -34,31 +34,18 @@ Targeted architectures The `OSS CAD Suite`_ releases `nightly builds`_ for the following architectures: -.. only:: html +- **linux-x64** - Most personal Linux based computers +- **darwin-x64** - macOS 12 or later with Intel CPU +- **darwin-arm64** - macOS 12 or later with M1/M2 CPU +- **windows-x64** - Targeted for Windows 10 and 11 +- **linux-arm64** - Devices such as Raspberry Pi with 64bit OS - - linux-x64 |linux-x64| - - Most personal Linux based computers - - - darwin-x64 |darwin-x64| - - macOS 12 or later with Intel CPU - - - darwin-arm64 |darwin-arm64| - - macOS 12 or later with M1/M2 CPU - - - windows-x64 |windows-x64| - - Targeted for Windows 10 and 11 - - - linux-arm64 |linux-arm64| +For more information about the targeted architectures, and the current build +status, check the `OSS CAD Suite`_ git repository. .. _OSS CAD Suite: https://github.com/YosysHQ/oss-cad-suite-build .. _nightly builds: https://github.com/YosysHQ/oss-cad-suite-build/releases/latest -.. |linux-x64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-x64.yml/badge.svg -.. |darwin-x64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/darwin-x64.yml/badge.svg -.. |darwin-arm64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/darwin-arm64.yml/badge.svg -.. |windows-x64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/windows-x64.yml/badge.svg -.. |linux-arm64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-arm64.yml/badge.svg - Building from source ~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals/extending_yosys/test_suites.rst b/docs/source/yosys_internals/extending_yosys/test_suites.rst index 264b97ce1..3e5f45b94 100644 --- a/docs/source/yosys_internals/extending_yosys/test_suites.rst +++ b/docs/source/yosys_internals/extending_yosys/test_suites.rst @@ -6,22 +6,12 @@ Testing Yosys Automatic testing ----------------- -.. only:: html - - The `Yosys Git repo`_ has automatic testing of builds and running of the - included test suite on the following platforms: - - - Ubuntu |test-linux| - - macOS |test-macos| +The `Yosys Git repo`_ has automatic testing of builds and running of the +included test suite on both Ubuntu and macOS, as well as across range of +compiler versions. For up to date information, including OS versions, refer to +`the git actions page`_. .. _Yosys Git repo: https://github.com/YosysHQ/yosys - -.. |test-linux| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-linux.yml/badge.svg?branch=main -.. |test-macos| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-macos.yml/badge.svg?branch=main - -For up to date information, including OS versions, refer to `the git actions -page`_. - .. _the git actions page: https://github.com/YosysHQ/yosys/actions .. todo:: are unit tests currently working From 725c489c7e1daa928030d8be6842892db1c0f175 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Sat, 15 Mar 2025 17:11:32 +0200 Subject: [PATCH 069/133] ice40_dsp: fix log_assert issue --- techlibs/ice40/ice40_dsp.pmg | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/techlibs/ice40/ice40_dsp.pmg b/techlibs/ice40/ice40_dsp.pmg index 9099dd3c4..285e3ceee 100644 --- a/techlibs/ice40/ice40_dsp.pmg +++ b/techlibs/ice40/ice40_dsp.pmg @@ -46,17 +46,19 @@ code sigA sigB sigH // Only care about those bits that are used int i; - for (i = 0; i < GetSize(O); i++) { - if (nusers(O[i]) <= 1) - break; - sigH.append(O[i]); - } + for (i = GetSize(O) - 1; i > 0 && nusers(O[i]) <= 1; i--) + ; // This sigM could have no users if downstream sinks (e.g. $add) is // narrower than $mul result, for example if (i == 0) reject; - log_assert(nusers(O.extract_end(i)) <= 1); + for (int j = 0; j <= i; j++) + if (nusers(O[j]) == 0) + sigH.append(module->addWire(NEW_ID)); + else + sigH.append(O[j]); + endcode code argQ ffA sigA clock clock_pol From 5ae32efca5a2018ce8ef41fa1cb30590b0a8aed5 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Sat, 15 Mar 2025 20:05:57 +0200 Subject: [PATCH 070/133] ice40_dsp: add test --- tests/various/bug4865.ys | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 tests/various/bug4865.ys diff --git a/tests/various/bug4865.ys b/tests/various/bug4865.ys new file mode 100644 index 000000000..ac5a459d8 --- /dev/null +++ b/tests/various/bug4865.ys @@ -0,0 +1,67 @@ +read_rtlil << EOF + +autoidx 524 + +attribute \top 1 +attribute \library "work" +attribute \hdlname "main" +module \main + + attribute \force_downto 1 + wire width 18 $verific$mult_4$garbage/usb.v:12$388.etc.blk.partial[0] + + wire width 14 $delete_wire$514 + + attribute \module_not_derived 1 + cell \SB_MAC16 $verific$mult_4$garbage/usb.v:12$388.etc.sliceB[0].mul + parameter \A_REG 1'0 + parameter \A_SIGNED 0 + parameter \BOTADDSUB_CARRYSELECT 2'00 + parameter \BOTADDSUB_LOWERINPUT 2'00 + parameter \BOTADDSUB_UPPERINPUT 1'0 + parameter \BOTOUTPUT_SELECT 2'11 + parameter \BOT_8x8_MULT_REG 1'0 + parameter \B_REG 1'0 + parameter signed \B_SIGNED 0 + parameter \C_REG 1'0 + parameter \D_REG 1'0 + parameter \MODE_8x8 1'0 + parameter \NEG_TRIGGER 1'0 + parameter \PIPELINE_16x16_MULT_REG1 1'0 + parameter \PIPELINE_16x16_MULT_REG2 1'0 + parameter \TOPADDSUB_CARRYSELECT 2'00 + parameter \TOPADDSUB_LOWERINPUT 2'00 + parameter \TOPADDSUB_UPPERINPUT 1'0 + parameter \TOPOUTPUT_SELECT 2'11 + parameter \TOP_8x8_MULT_REG 1'0 + connect \A 16'x + connect \B 16'x + connect \O { $delete_wire$514 $verific$mult_4$garbage/usb.v:12$388.etc.blk.partial[0] [17:2] 2'x} + end + + cell $add $techmap$verific$mult_4$garbage/usb.v:12$388.etc.sliceA.last.$add$/home/emil/pulls/yosys/share/mul2dsp.v:216$483 + parameter \A_SIGNED 0 + parameter \A_WIDTH 18 + parameter \B_SIGNED 0 + parameter \B_WIDTH 2 + parameter \Y_WIDTH 19 + connect \A 18'x + connect \B $verific$mult_4$garbage/usb.v:12$388.etc.blk.partial[0] [17:16] + connect \Y 19'x + end + + cell $add $techmap$verific$mult_4$garbage/usb.v:12$388.$add$/home/emil/pulls/yosys/share/mul2dsp.v:173$480 + parameter \A_SIGNED 0 + parameter \A_WIDTH 14 + parameter \B_SIGNED 0 + parameter \B_WIDTH 2 + parameter \Y_WIDTH 2 + connect \A $delete_wire$514 + connect \B 2'x + connect \Y 2'x + end + +end +EOF + +ice40_dsp From de11624f42f982810ef9c2f4923e611274aace96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gr=C3=B6ber?= Date: Fri, 14 Mar 2025 21:25:14 +0100 Subject: [PATCH 071/133] mk: Avoid broken rebuild if program --help fails Make will happily consider a target available if it's zero sized. When writing output files with shell redirections for commands that usually succeed we can apply the `|| rm $@` pattern. For commands where --help exits with failure we always rerun the recipe instead. --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 89ffaef66..646fb64fc 100644 --- a/Makefile +++ b/Makefile @@ -1038,7 +1038,7 @@ docs/source/generated: # some commands return an error and print the usage text to stderr define DOC_USAGE_STDERR -docs/source/generated/$(1): $(TARGETS) docs/source/generated +docs/source/generated/$(1): $(TARGETS) docs/source/generated FORCE -$(Q) ./$(PROGRAM_PREFIX)$(1) --help 2> $$@ endef DOCS_USAGE_STDERR := yosys-config yosys-filterlib @@ -1053,7 +1053,7 @@ $(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage)))) # others print to stdout define DOC_USAGE_STDOUT docs/source/generated/$(1): $(TARGETS) docs/source/generated - $(Q) ./$(PROGRAM_PREFIX)$(1) --help > $$@ + $(Q) ./$(PROGRAM_PREFIX)$(1) --help > $$@ || rm $$@ endef DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness $(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage)))) @@ -1190,5 +1190,7 @@ echo-cxx: -include kernel/*.d -include techlibs/*/*.d +FORCE: + .PHONY: all top-all abc test install install-abc docs clean mrproper qtcreator coverage vcxsrc .PHONY: config-clean config-clang config-gcc config-gcc-static config-gprof config-sudo From a9d765e11ef04fda65de4027f1d4b5fa87370f0f Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Sun, 16 Mar 2025 15:11:45 +0200 Subject: [PATCH 072/133] ice40_dsp: group empty wires --- techlibs/ice40/ice40_dsp.pmg | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/techlibs/ice40/ice40_dsp.pmg b/techlibs/ice40/ice40_dsp.pmg index 285e3ceee..63bc8de4b 100644 --- a/techlibs/ice40/ice40_dsp.pmg +++ b/techlibs/ice40/ice40_dsp.pmg @@ -53,11 +53,16 @@ code sigA sigB sigH if (i == 0) reject; - for (int j = 0; j <= i; j++) + for (int j = 0, wire_width = 0; j <= i; j++) if (nusers(O[j]) == 0) - sigH.append(module->addWire(NEW_ID)); - else + wire_width++; + else { + if (wire_width) { // add empty wires for bit offset if needed + sigH.append(module->addWire(NEW_ID, wire_width)); + wire_width = 0; + } sigH.append(O[j]); + } endcode From 39a1623ac01f5c3d73d26fd1967d00d8ebe23b8a Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 18 Mar 2025 03:57:17 +1300 Subject: [PATCH 073/133] Docs: Don't READTHEDOCS on local builds --- docs/source/conf.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 607e088da..d97fb99a7 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,15 +16,17 @@ html_theme_options: dict[str] = { "source_branch": "main", "source_directory": "docs/source/", } +html_context: dict[str] = {} # try to fix the readthedocs detection -html_context: dict[str] = { - "READTHEDOCS": True, - "display_github": True, - "github_user": "YosysHQ", - "github_repo": "yosys", - "slug": "yosys", -} +if os.getenv("READTHEDOCS"): + html_context.update({ + "READTHEDOCS": True, + "display_github": True, + "github_user": "YosysHQ", + "github_repo": "yosys", + "slug": "yosys", + }) # override source_branch if not main git_slug = os.getenv("READTHEDOCS_VERSION_NAME") From 0c689091e2a0959b1a6173de1bd7bd679b6120b2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 00:21:58 +0000 Subject: [PATCH 074/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 89ffaef66..76c7cffbb 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+17 +YOSYS_VER := 0.51+41 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 9c5bffcf93183df0756e01f3c4774d2f83688b8e Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 17 Mar 2025 17:56:02 -0700 Subject: [PATCH 075/133] Use wheel --- .gitignore | 1 + Makefile | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 239ae742b..7b4a1fb1e 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ __pycache__ /venv /boost /ffi +/*.whl diff --git a/Makefile b/Makefile index 820ab83c7..fc07374ea 100644 --- a/Makefile +++ b/Makefile @@ -341,6 +341,7 @@ ifeq ($(ENABLE_PYOSYS),1) LINKFLAGS += $(filter-out -l%,$(shell $(PYTHON_CONFIG) --ldflags)) LIBS += $(shell $(PYTHON_CONFIG) --libs) CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON +EXTRA_TARGETS += wheel # Detect name of boost_python library. Some distros use boost_python-py, other boost_python, some only use the major version number, some a concatenation of major and minor version numbers CHECK_BOOST_PYTHON = (echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(LINKFLAGS) $(LIBS) -l$(1) - > /dev/null 2>&1 && echo "-l$(1)") @@ -957,6 +958,12 @@ unit-test: libyosys.so clean-unit-test: @$(MAKE) -C $(UNITESTPATH) clean +wheel: $(TARGETS) + python$(PYTHON_VERSION) -m pip wheel . + +install-wheel: wheel + python$(PYTHON_VERSION) -m pip install pyosys-$(YOSYS_MAJOR).$(YOSYS_MINOR).$(YOSYS_COMMIT)-*.whl --force-reinstall + install: $(TARGETS) $(EXTRA_TARGETS) $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR) $(INSTALL_SUDO) cp $(filter-out libyosys.so,$(TARGETS)) $(DESTDIR)$(BINDIR) @@ -976,9 +983,7 @@ ifeq ($(ENABLE_LIBYOSYS),1) $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(LIBDIR)/ $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so ifeq ($(ENABLE_PYOSYS),1) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys - $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so - $(INSTALL_SUDO) cp -r share $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys + $(INSTALL_SUDO) @$(MAKE) install-wheel ifeq ($(ENABLE_ABC),1) $(INSTALL_SUDO) cp yosys-abc $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/yosys-abc endif @@ -998,9 +1003,7 @@ uninstall: ifeq ($(ENABLE_LIBYOSYS),1) $(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.so ifeq ($(ENABLE_PYOSYS),1) - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py - $(INSTALL_SUDO) rmdir $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys + $(INSTALL_SUDO) python$(PYTHON_VERSION) -m pip uninstall -y pyosys endif endif From 061cf5c6c41c6d2e4c7460453d466dd2ab15ce53 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Wed, 19 Mar 2025 10:27:23 +0100 Subject: [PATCH 076/133] share: re-add SAT solver cell count to log message --- passes/opt/share.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 40d6d1d20..1a4e2b31c 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -1297,8 +1297,8 @@ struct ShareWorker qcsat.ez->assume(qcsat.ez->AND(sub1, sub2)); - log(" Size of SAT problem: %d variables, %d clauses\n", - qcsat.ez->numCnfVariables(), qcsat.ez->numCnfClauses()); + log(" Size of SAT problem: %zu cells, %d variables, %d clauses\n", + qcsat.imported_cells.size(), qcsat.ez->numCnfVariables(), qcsat.ez->numCnfClauses()); if (qcsat.ez->solve(sat_model, sat_model_values)) { log(" According to the SAT solver this pair of cells can not be shared.\n"); From 613a17b4a8c2f370a26a788fd0ab7ae4fbad2503 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Wed, 19 Mar 2025 10:33:28 +0100 Subject: [PATCH 077/133] ezsat: fix incorrect logging references to function names --- libs/ezsat/ezsat.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index 3b089ccca..20a210abe 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -676,10 +676,10 @@ void ezSAT::preSolverCallback() bool ezSAT::solver(const std::vector&, std::vector&, const std::vector&) { preSolverCallback(); - fprintf(stderr, "************************************************************************\n"); - fprintf(stderr, "ERROR: You are trying to use the solve() method of the ezSAT base class!\n"); + fprintf(stderr, "*************************************************************************\n"); + fprintf(stderr, "ERROR: You are trying to use the solver() method of the ezSAT base class!\n"); fprintf(stderr, "Use a dervied class like ezMiniSAT instead.\n"); - fprintf(stderr, "************************************************************************\n"); + fprintf(stderr, "*************************************************************************\n"); abort(); } @@ -1332,7 +1332,7 @@ void ezSAT::printInternalState(FILE *f) const fprintf(f, "\n"); } if (cnfConsumed) - fprintf(f, " *** more clauses consumed via cnfConsume() ***\n"); + fprintf(f, " *** more clauses consumed via consumeCnf() ***\n"); fprintf(f, "--8<-- snap --8<--\n"); } From 4f3fdc8457acdf7033ed881253b4bb7ef35654d9 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Wed, 11 Dec 2024 15:35:43 +0100 Subject: [PATCH 078/133] io: refactor string and file work into new unit --- Makefile | 5 +- backends/btor/btor.cc | 1 + backends/smt2/smt2.cc | 1 + frontends/ast/simplify.cc | 14 +- frontends/verific/verific.cc | 1 + kernel/io.cc | 460 +++++++++++++++++++++++++++++++++++ kernel/io.h | 100 ++++++++ kernel/register.cc | 91 +------ kernel/utils.h | 14 ++ kernel/yosys.cc | 367 ---------------------------- kernel/yosys_common.h | 58 +---- passes/fsm/fsm_recode.cc | 1 + passes/opt/peepopt.cc | 1 + passes/opt/pmux2shiftx.cc | 1 + passes/opt/wreduce.cc | 1 + passes/pmgen/pmgen.py | 1 + passes/sat/assertpmux.cc | 1 + 17 files changed, 595 insertions(+), 523 deletions(-) create mode 100644 kernel/io.cc create mode 100644 kernel/io.h diff --git a/Makefile b/Makefile index 76c7cffbb..775375533 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,7 @@ YOSYS_SRC := $(dir $(firstword $(MAKEFILE_LIST))) VPATH := $(YOSYS_SRC) CXXSTD ?= c++17 -CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include +CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -Werror=implicit-function-declaration -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include LIBS := $(LIBS) -lstdc++ -lm PLUGIN_LINKFLAGS := PLUGIN_LIBS := @@ -587,6 +587,7 @@ ifeq ($(ENABLE_ZLIB),1) $(eval $(call add_include_file,kernel/fstdata.h)) endif $(eval $(call add_include_file,kernel/hashlib.h)) +$(eval $(call add_include_file,kernel/io.h)) $(eval $(call add_include_file,kernel/json.h)) $(eval $(call add_include_file,kernel/log.h)) $(eval $(call add_include_file,kernel/macc.h)) @@ -617,7 +618,7 @@ $(eval $(call add_include_file,frontends/ast/ast_binding.h)) $(eval $(call add_include_file,frontends/blif/blifparse.h)) $(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) -OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o +OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o OBJS += kernel/binding.o kernel/tclapi.o OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o OBJS += kernel/drivertools.o kernel/functional.o diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 43d189679..fa3cc728e 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -30,6 +30,7 @@ #include "kernel/mem.h" #include "kernel/json.h" #include "kernel/yw.h" +#include "kernel/utils.h" #include USING_YOSYS_NAMESPACE diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index a6e1965ba..02784b975 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -24,6 +24,7 @@ #include "kernel/log.h" #include "kernel/mem.h" #include "libs/json11/json11.hpp" +#include "kernel/utils.h" #include USING_YOSYS_NAMESPACE diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d35756d4e..ae49ae9ba 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2777,13 +2777,13 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin mux_input = new AstNode(AST_BIT_NOT, mux_input); } AstNode *node = new AstNode(AST_TERNARY, children_list.at(2)); - if (str == "bufif0") { - node->children.push_back(AstNode::mkconst_bits(z_const, false)); - node->children.push_back(mux_input); - } else { - node->children.push_back(mux_input); - node->children.push_back(AstNode::mkconst_bits(z_const, false)); - } + // if (str == "bufif0") { + // node->children.push_back(AstNode::mkconst_bits(z_const, false)); + // node->children.push_back(mux_input); + // } else { + // node->children.push_back(mux_input); + // node->children.push_back(AstNode::mkconst_bits(z_const, false)); + // } str.clear(); type = AST_ASSIGN; diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index a320a6efd..4221419af 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -21,6 +21,7 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" #include "kernel/log.h" +#include "kernel/utils.h" #include "libs/sha1/sha1.h" #include #include diff --git a/kernel/io.cc b/kernel/io.cc new file mode 100644 index 000000000..2b09eb69b --- /dev/null +++ b/kernel/io.cc @@ -0,0 +1,460 @@ +#include "kernel/yosys_common.h" +#include "kernel/log.h" +#include +#include +#include +#include +#include + +YOSYS_NAMESPACE_BEGIN + +// Set of utilities for handling files + +int readsome(std::istream &f, char *s, int n) +{ + int rc = int(f.readsome(s, n)); + + // f.readsome() sometimes returns 0 on a non-empty stream.. + if (rc == 0) { + int c = f.get(); + if (c != EOF) { + *s = c; + rc = 1; + } + } + + return rc; +} + +std::string next_token(std::string &text, const char *sep, bool long_strings) +{ + size_t pos_begin = text.find_first_not_of(sep); + + if (pos_begin == std::string::npos) + pos_begin = text.size(); + + if (long_strings && pos_begin != text.size() && text[pos_begin] == '"') { + std::string sep_string = sep; + for (size_t i = pos_begin+1; i < text.size(); i++) { + if (text[i] == '"' && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) { + std::string token = text.substr(pos_begin, i-pos_begin+1); + text = text.substr(i+1); + return token; + } + if (i+1 < text.size() && text[i] == '"' && text[i+1] == ';' && (i+2 == text.size() || sep_string.find(text[i+2]) != std::string::npos)) { + std::string token = text.substr(pos_begin, i-pos_begin+1); + text = text.substr(i+2); + return token + ";"; + } + } + } + + size_t pos_end = text.find_first_of(sep, pos_begin); + + if (pos_end == std::string::npos) + pos_end = text.size(); + + std::string token = text.substr(pos_begin, pos_end-pos_begin); + text = text.substr(pos_end); + return token; +} + +std::vector split_tokens(const std::string &text, const char *sep) +{ + std::vector tokens; + std::string current_token; + for (char c : text) { + if (strchr(sep, c)) { + if (!current_token.empty()) { + tokens.push_back(current_token); + current_token.clear(); + } + } else + current_token += c; + } + if (!current_token.empty()) { + tokens.push_back(current_token); + current_token.clear(); + } + return tokens; +} + +// this is very similar to fnmatch(). the exact rules used by this +// function are: +// +// ? matches any character except +// * matches any sequence of characters +// [...] matches any of the characters in the list +// [!..] matches any of the characters not in the list +// +// a backslash may be used to escape the next characters in the +// pattern. each special character can also simply match itself. +// +bool patmatch(const char *pattern, const char *string) +{ + if (*pattern == 0) + return *string == 0; + + if (*pattern == '\\') { + if (pattern[1] == string[0] && patmatch(pattern+2, string+1)) + return true; + } + + if (*pattern == '?') { + if (*string == 0) + return false; + return patmatch(pattern+1, string+1); + } + + if (*pattern == '*') { + while (*string) { + if (patmatch(pattern+1, string++)) + return true; + } + return pattern[1] == 0; + } + + if (*pattern == '[') { + bool found_match = false; + bool inverted_list = pattern[1] == '!'; + const char *p = pattern + (inverted_list ? 1 : 0); + + while (*++p) { + if (*p == ']') { + if (found_match != inverted_list && patmatch(p+1, string+1)) + return true; + break; + } + + if (*p == '\\') { + if (*++p == *string) + found_match = true; + } else + if (*p == *string) + found_match = true; + } + } + + if (*pattern == *string) + return patmatch(pattern+1, string+1); + + return false; +} + +std::string get_base_tmpdir() +{ + static std::string tmpdir; + + if (!tmpdir.empty()) { + return tmpdir; + } + +#if defined(_WIN32) +# ifdef __MINGW32__ + char longpath[MAX_PATH + 1]; + char shortpath[MAX_PATH + 1]; +# else + WCHAR longpath[MAX_PATH + 1]; + TCHAR shortpath[MAX_PATH + 1]; +# endif + if (!GetTempPath(MAX_PATH+1, longpath)) + log_error("GetTempPath() failed.\n"); + if (!GetShortPathName(longpath, shortpath, MAX_PATH + 1)) + log_error("GetShortPathName() failed.\n"); + for (int i = 0; shortpath[i]; i++) + tmpdir += char(shortpath[i]); +#else + char * var = std::getenv("TMPDIR"); + if (var && strlen(var)!=0) { + tmpdir.assign(var); + // We return the directory name without the trailing '/' + while (!tmpdir.empty() && (tmpdir.back() == '/')) { + tmpdir.pop_back(); + } + } else { + tmpdir.assign("/tmp"); + } +#endif + return tmpdir; +} + +std::string make_temp_file(std::string template_str) +{ + size_t pos = template_str.rfind("XXXXXX"); + log_assert(pos != std::string::npos); +#if defined(__wasm) + static size_t index = 0; + template_str.replace(pos, 6, stringf("%06zu", index++)); +#elif defined(_WIN32) +#ifndef YOSYS_WIN32_UNIX_DIR + std::replace(template_str.begin(), template_str.end(), '/', '\\'); +#endif + while (1) { + for (int i = 0; i < 6; i++) { + static std::string y = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + static uint32_t x = 314159265 ^ uint32_t(time(NULL)); + x ^= x << 13, x ^= x >> 17, x ^= x << 5; + template_str[pos+i] = y[x % y.size()]; + } + if (_access(template_str.c_str(), 0) != 0) + break; + } +#else + int suffixlen = template_str.size() - pos - 6; + + char *p = strdup(template_str.c_str()); + close(mkstemps(p, suffixlen)); + template_str = p; + free(p); +#endif + + return template_str; +} + +std::string make_temp_dir(std::string template_str) +{ +#if defined(_WIN32) + template_str = make_temp_file(template_str); + mkdir(template_str.c_str()); + return template_str; +#elif defined(__wasm) + template_str = make_temp_file(template_str); + mkdir(template_str.c_str(), 0777); + return template_str; +#else +# ifndef NDEBUG + size_t pos = template_str.rfind("XXXXXX"); + log_assert(pos != std::string::npos); + + int suffixlen = template_str.size() - pos - 6; + log_assert(suffixlen == 0); +# endif + + char *p = strdup(template_str.c_str()); + log_assert(p); + char *res = mkdtemp(p); + if (!res) + log_error("mkdtemp failed for '%s': %s [Error %d]\n", + p, strerror(errno), errno); + template_str = p; + free(p); + + return template_str; +#endif +} + +bool check_directory_exists(const std::string& dirname) +{ +#if defined(_WIN32) + struct _stat info; + if (_stat(dirname.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & _S_IFDIR) != 0; +#else + struct stat info; + if (stat(dirname.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & S_IFDIR) != 0; +#endif +} + +#ifdef _WIN32 +bool check_file_exists(std::string filename, bool) +{ + return _access(filename.c_str(), 0) == 0; +} +#else +bool check_file_exists(std::string filename, bool is_exec) +{ + return access(filename.c_str(), is_exec ? X_OK : F_OK) == 0; +} +#endif + +bool is_absolute_path(std::string filename) +{ +#ifdef _WIN32 + return filename[0] == '/' || filename[0] == '\\' || (filename[0] != 0 && filename[1] == ':'); +#else + return filename[0] == '/'; +#endif +} + +void remove_directory(std::string dirname) +{ +#ifdef _WIN32 + run_command(stringf("rmdir /s /q \"%s\"", dirname.c_str())); +#else + struct stat stbuf; + struct dirent **namelist; + int n = scandir(dirname.c_str(), &namelist, nullptr, alphasort); + log_assert(n >= 0); + for (int i = 0; i < n; i++) { + if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) { + std::string buffer = stringf("%s/%s", dirname.c_str(), namelist[i]->d_name); + if (!stat(buffer.c_str(), &stbuf) && S_ISREG(stbuf.st_mode)) { + remove(buffer.c_str()); + } else + remove_directory(buffer); + } + free(namelist[i]); + } + free(namelist); + rmdir(dirname.c_str()); +#endif +} + +bool create_directory(const std::string& dirname) +{ +#if defined(_WIN32) + int ret = _mkdir(dirname.c_str()); +#else + mode_t mode = 0755; + int ret = mkdir(dirname.c_str(), mode); +#endif + if (ret == 0) + return true; + + switch (errno) + { + case ENOENT: + // parent didn't exist, try to create it + { + std::string::size_type pos = dirname.find_last_of('/'); + if (pos == std::string::npos) +#if defined(_WIN32) + pos = dirname.find_last_of('\\'); + if (pos == std::string::npos) +#endif + return false; + if (!create_directory( dirname.substr(0, pos) )) + return false; + } + // now, try to create again +#if defined(_WIN32) + return 0 == _mkdir(dirname.c_str()); +#else + return 0 == mkdir(dirname.c_str(), mode); +#endif + + case EEXIST: + // done! + return check_directory_exists(dirname); + + default: + return false; + } +} + +std::string escape_filename_spaces(const std::string& filename) +{ + std::string out; + out.reserve(filename.size()); + for (auto c : filename) + { + if (c == ' ') + out += "\\ "; + else + out.push_back(c); + } + return out; +} + +#ifdef YOSYS_ENABLE_ZLIB + +PRIVATE_NAMESPACE_BEGIN + +static const size_t GZ_BUFFER_SIZE = 8192; +static void decompress_gzip(const std::string &filename, std::stringstream &out) +{ + char buffer[GZ_BUFFER_SIZE]; + int bytes_read; + gzFile gzf = gzopen(filename.c_str(), "rb"); + while(!gzeof(gzf)) { + bytes_read = gzread(gzf, reinterpret_cast(buffer), GZ_BUFFER_SIZE); + out.write(buffer, bytes_read); + } + gzclose(gzf); +} + +PRIVATE_NAMESPACE_END + +gzip_ostream::gzip_ostream() : std::ostream(nullptr) { + rdbuf(&outbuf); +} + +bool gzip_ostream::open(const std::string &filename) { + return outbuf.open(filename); +} + +gzip_ostream::gzip_streambuf::gzip_streambuf() { + setp(buffer, buffer + buffer_size - 1); +} + +bool gzip_ostream::gzip_streambuf::open(const std::string &filename) { + gzf = gzopen(filename.c_str(), "wb"); + return gzf != nullptr; +} + +int gzip_ostream::gzip_streambuf::sync() { + int num = pptr() - pbase(); + if (num > 0) { + if (gzwrite(gzf, reinterpret_cast(pbase()), num) != num) { + return -1; + } + pbump(-num); + } + return 0; +} + +gzip_ostream::gzip_streambuf::~gzip_streambuf() { + if (gzf) { + sync(); + gzclose(gzf); + } +} + +#endif // YOSYS_ENABLE_ZLIB + + +// Takes a successfully opened ifstream. If it's gzipped, returns an istream +// over a buffer of the file fully decompressed in memory. Otherwise, +// returns the original ifstream, rewound to the start. +std::istream* uncompressed(std::ifstream* f, const std::string filename) { + if (!f) + return nullptr; + // Check for gzip magic + unsigned char magic[3]; + int n = 0; + while (n < 3) + { + int c = f->get(); + if (c != EOF) { + magic[n] = (unsigned char) c; + } + n++; + } + if (n == 3 && magic[0] == 0x1f && magic[1] == 0x8b) { +#ifdef YOSYS_ENABLE_ZLIB + log("Found gzip magic in file `%s', decompressing using zlib.\n", filename.c_str()); + if (magic[2] != 8) + log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n", + filename.c_str(), unsigned(magic[2])); + delete f; + std::stringstream *df = new std::stringstream(); + decompress_gzip(filename, *df); + return df; +#else + log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); +#endif // YOSYS_ENABLE_ZLIB + } else { + f->clear(); + f->seekg(0, std::ios::beg); + return f; + } +} + +YOSYS_NAMESPACE_END diff --git a/kernel/io.h b/kernel/io.h new file mode 100644 index 000000000..99b2dc62a --- /dev/null +++ b/kernel/io.h @@ -0,0 +1,100 @@ +#include "kernel/yosys_common.h" +#include + +#ifndef YOSYS_IO_H +#define YOSYS_IO_H + +#ifdef YOSYS_ENABLE_ZLIB +#include +#endif + +YOSYS_NAMESPACE_BEGIN + +inline std::string vstringf(const char *fmt, va_list ap) +{ + // For the common case of strings shorter than 128, save a heap + // allocation by using a stack allocated buffer. + const int kBufSize = 128; + char buf[kBufSize]; + buf[0] = '\0'; + va_list apc; + va_copy(apc, ap); + int n = vsnprintf(buf, kBufSize, fmt, apc); + va_end(apc); + if (n < kBufSize) + return std::string(buf); + + std::string string; + char *str = NULL; +#if defined(_WIN32) || defined(__CYGWIN__) + int sz = 2 * kBufSize, rc; + while (1) { + va_copy(apc, ap); + str = (char *)realloc(str, sz); + rc = vsnprintf(str, sz, fmt, apc); + va_end(apc); + if (rc >= 0 && rc < sz) + break; + sz *= 2; + } + if (str != NULL) { + string = str; + free(str); + } + return string; +#else + if (vasprintf(&str, fmt, ap) < 0) + str = NULL; + if (str != NULL) { + string = str; + free(str); + } + return string; +#endif +} + +std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); + +inline std::string stringf(const char *fmt, ...) +{ + std::string string; + va_list ap; + + va_start(ap, fmt); + string = vstringf(fmt, ap); + va_end(ap); + + return string; +} + +#ifdef YOSYS_ENABLE_ZLIB +/* +An output stream that uses a stringbuf to buffer data internally, +using zlib to write gzip-compressed data every time the stream is flushed. +*/ +class gzip_ostream : public std::ostream { +public: + gzip_ostream(); + bool open(const std::string &filename); +private: + class gzip_streambuf : public std::stringbuf { + public: + gzip_streambuf(); + bool open(const std::string &filename); + virtual int sync() override; + virtual ~gzip_streambuf(); + private: + static const int buffer_size = 4096; // Size of the internal buffer + char buffer[buffer_size]; // Internal buffer for compressed data + gzFile gzf = nullptr; // Handle to the gzip file + }; + + gzip_streambuf outbuf; // The stream buffer instance +}; +#endif // YOSYS_ENABLE_ZLIB + +std::istream* uncompressed(std::ifstream* f, const std::string filename); + +YOSYS_NAMESPACE_END + +#endif // YOSYS_IO_H diff --git a/kernel/register.cc b/kernel/register.cc index 11cf5b0e4..c919871dc 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -26,65 +26,6 @@ #include #include -#ifdef YOSYS_ENABLE_ZLIB -#include - -PRIVATE_NAMESPACE_BEGIN -#define GZ_BUFFER_SIZE 8192 -void decompress_gzip(const std::string &filename, std::stringstream &out) -{ - char buffer[GZ_BUFFER_SIZE]; - int bytes_read; - gzFile gzf = gzopen(filename.c_str(), "rb"); - while(!gzeof(gzf)) { - bytes_read = gzread(gzf, reinterpret_cast(buffer), GZ_BUFFER_SIZE); - out.write(buffer, bytes_read); - } - gzclose(gzf); -} - -/* -An output stream that uses a stringbuf to buffer data internally, -using zlib to write gzip-compressed data every time the stream is flushed. -*/ -class gzip_ostream : public std::ostream { -public: - gzip_ostream() : std::ostream(nullptr) - { - rdbuf(&outbuf); - } - bool open(const std::string &filename) - { - return outbuf.open(filename); - } -private: - class gzip_streambuf : public std::stringbuf { - public: - gzip_streambuf() { }; - bool open(const std::string &filename) - { - gzf = gzopen(filename.c_str(), "wb"); - return gzf != nullptr; - } - virtual int sync() override - { - gzwrite(gzf, reinterpret_cast(str().c_str()), unsigned(str().size())); - str(""); - return 0; - } - virtual ~gzip_streambuf() - { - sync(); - gzclose(gzf); - } - private: - gzFile gzf = nullptr; - } outbuf; -}; -PRIVATE_NAMESPACE_END - -#endif - YOSYS_NAMESPACE_BEGIN #define MAX_REG_COUNT 1000 @@ -534,37 +475,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vectorget(); - if (c != EOF) { - magic[n] = (unsigned char) c; - } - n++; - } - if (n == 3 && magic[0] == 0x1f && magic[1] == 0x8b) { - #ifdef YOSYS_ENABLE_ZLIB - log("Found gzip magic in file `%s', decompressing using zlib.\n", filename.c_str()); - if (magic[2] != 8) - log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n", - filename.c_str(), unsigned(magic[2])); - delete ff; - std::stringstream *df = new std::stringstream(); - decompress_gzip(filename, *df); - f = df; - #else - log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); - #endif - } else { - ff->clear(); - ff->seekg(0, std::ios::beg); - } - } + f = uncompressed(ff, filename); } if (f == NULL) log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); diff --git a/kernel/utils.h b/kernel/utils.h index 07edad074..6c9fe36a5 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -262,6 +262,20 @@ struct arrow_proxy { T* operator->() { return &v; } }; +inline int ceil_log2(int x) +{ +#if defined(__GNUC__) + return x > 1 ? (8*sizeof(int)) - __builtin_clz(x-1) : 0; +#else + if (x <= 0) + return 0; + for (int i = 0; i < 32; i++) + if (((x-1) >> i) == 0) + return i; + log_abort(); +#endif +} + YOSYS_NAMESPACE_END #endif diff --git a/kernel/yosys.cc b/kernel/yosys.cc index d39acf9d9..a5520e6ef 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -147,151 +147,6 @@ void yosys_banner() log(" %s\n", yosys_version_str); } -int ceil_log2(int x) -{ -#if defined(__GNUC__) - return x > 1 ? (8*sizeof(int)) - __builtin_clz(x-1) : 0; -#else - if (x <= 0) - return 0; - for (int i = 0; i < 32; i++) - if (((x-1) >> i) == 0) - return i; - log_abort(); -#endif -} - -int readsome(std::istream &f, char *s, int n) -{ - int rc = int(f.readsome(s, n)); - - // f.readsome() sometimes returns 0 on a non-empty stream.. - if (rc == 0) { - int c = f.get(); - if (c != EOF) { - *s = c; - rc = 1; - } - } - - return rc; -} - -std::string next_token(std::string &text, const char *sep, bool long_strings) -{ - size_t pos_begin = text.find_first_not_of(sep); - - if (pos_begin == std::string::npos) - pos_begin = text.size(); - - if (long_strings && pos_begin != text.size() && text[pos_begin] == '"') { - string sep_string = sep; - for (size_t i = pos_begin+1; i < text.size(); i++) { - if (text[i] == '"' && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) { - std::string token = text.substr(pos_begin, i-pos_begin+1); - text = text.substr(i+1); - return token; - } - if (i+1 < text.size() && text[i] == '"' && text[i+1] == ';' && (i+2 == text.size() || sep_string.find(text[i+2]) != std::string::npos)) { - std::string token = text.substr(pos_begin, i-pos_begin+1); - text = text.substr(i+2); - return token + ";"; - } - } - } - - size_t pos_end = text.find_first_of(sep, pos_begin); - - if (pos_end == std::string::npos) - pos_end = text.size(); - - std::string token = text.substr(pos_begin, pos_end-pos_begin); - text = text.substr(pos_end); - return token; -} - -std::vector split_tokens(const std::string &text, const char *sep) -{ - std::vector tokens; - std::string current_token; - for (char c : text) { - if (strchr(sep, c)) { - if (!current_token.empty()) { - tokens.push_back(current_token); - current_token.clear(); - } - } else - current_token += c; - } - if (!current_token.empty()) { - tokens.push_back(current_token); - current_token.clear(); - } - return tokens; -} - -// this is very similar to fnmatch(). the exact rules used by this -// function are: -// -// ? matches any character except -// * matches any sequence of characters -// [...] matches any of the characters in the list -// [!..] matches any of the characters not in the list -// -// a backslash may be used to escape the next characters in the -// pattern. each special character can also simply match itself. -// -bool patmatch(const char *pattern, const char *string) -{ - if (*pattern == 0) - return *string == 0; - - if (*pattern == '\\') { - if (pattern[1] == string[0] && patmatch(pattern+2, string+1)) - return true; - } - - if (*pattern == '?') { - if (*string == 0) - return false; - return patmatch(pattern+1, string+1); - } - - if (*pattern == '*') { - while (*string) { - if (patmatch(pattern+1, string++)) - return true; - } - return pattern[1] == 0; - } - - if (*pattern == '[') { - bool found_match = false; - bool inverted_list = pattern[1] == '!'; - const char *p = pattern + (inverted_list ? 1 : 0); - - while (*++p) { - if (*p == ']') { - if (found_match != inverted_list && patmatch(p+1, string+1)) - return true; - break; - } - - if (*p == '\\') { - if (*++p == *string) - found_match = true; - } else - if (*p == *string) - found_match = true; - } - } - - if (*pattern == *string) - return patmatch(pattern+1, string+1); - - return false; -} - #if !defined(YOSYS_DISABLE_SPAWN) int run_command(const std::string &command, std::function process_line) { @@ -323,228 +178,6 @@ int run_command(const std::string &command, std::function> 17, x ^= x << 5; - template_str[pos+i] = y[x % y.size()]; - } - if (_access(template_str.c_str(), 0) != 0) - break; - } -#else - int suffixlen = GetSize(template_str) - pos - 6; - - char *p = strdup(template_str.c_str()); - close(mkstemps(p, suffixlen)); - template_str = p; - free(p); -#endif - - return template_str; -} - -std::string make_temp_dir(std::string template_str) -{ -#if defined(_WIN32) - template_str = make_temp_file(template_str); - mkdir(template_str.c_str()); - return template_str; -#elif defined(__wasm) - template_str = make_temp_file(template_str); - mkdir(template_str.c_str(), 0777); - return template_str; -#else -# ifndef NDEBUG - size_t pos = template_str.rfind("XXXXXX"); - log_assert(pos != std::string::npos); - - int suffixlen = GetSize(template_str) - pos - 6; - log_assert(suffixlen == 0); -# endif - - char *p = strdup(template_str.c_str()); - log_assert(p); - char *res = mkdtemp(p); - if (!res) - log_error("mkdtemp failed for '%s': %s [Error %d]\n", - p, strerror(errno), errno); - template_str = p; - free(p); - - return template_str; -#endif -} - -bool check_directory_exists(const std::string& dirname) -{ -#if defined(_WIN32) - struct _stat info; - if (_stat(dirname.c_str(), &info) != 0) - { - return false; - } - return (info.st_mode & _S_IFDIR) != 0; -#else - struct stat info; - if (stat(dirname.c_str(), &info) != 0) - { - return false; - } - return (info.st_mode & S_IFDIR) != 0; -#endif -} - -#ifdef _WIN32 -bool check_file_exists(std::string filename, bool) -{ - return _access(filename.c_str(), 0) == 0; -} -#else -bool check_file_exists(std::string filename, bool is_exec) -{ - return access(filename.c_str(), is_exec ? X_OK : F_OK) == 0; -} -#endif - -bool is_absolute_path(std::string filename) -{ -#ifdef _WIN32 - return filename[0] == '/' || filename[0] == '\\' || (filename[0] != 0 && filename[1] == ':'); -#else - return filename[0] == '/'; -#endif -} - -void remove_directory(std::string dirname) -{ -#ifdef _WIN32 - run_command(stringf("rmdir /s /q \"%s\"", dirname.c_str())); -#else - struct stat stbuf; - struct dirent **namelist; - int n = scandir(dirname.c_str(), &namelist, nullptr, alphasort); - log_assert(n >= 0); - for (int i = 0; i < n; i++) { - if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) { - std::string buffer = stringf("%s/%s", dirname.c_str(), namelist[i]->d_name); - if (!stat(buffer.c_str(), &stbuf) && S_ISREG(stbuf.st_mode)) { - remove(buffer.c_str()); - } else - remove_directory(buffer); - } - free(namelist[i]); - } - free(namelist); - rmdir(dirname.c_str()); -#endif -} - -bool create_directory(const std::string& dirname) -{ -#if defined(_WIN32) - int ret = _mkdir(dirname.c_str()); -#else - mode_t mode = 0755; - int ret = mkdir(dirname.c_str(), mode); -#endif - if (ret == 0) - return true; - - switch (errno) - { - case ENOENT: - // parent didn't exist, try to create it - { - std::string::size_type pos = dirname.find_last_of('/'); - if (pos == std::string::npos) -#if defined(_WIN32) - pos = dirname.find_last_of('\\'); - if (pos == std::string::npos) -#endif - return false; - if (!create_directory( dirname.substr(0, pos) )) - return false; - } - // now, try to create again -#if defined(_WIN32) - return 0 == _mkdir(dirname.c_str()); -#else - return 0 == mkdir(dirname.c_str(), mode); -#endif - - case EEXIST: - // done! - return check_directory_exists(dirname); - - default: - return false; - } -} - -std::string escape_filename_spaces(const std::string& filename) -{ - std::string out; - out.reserve(filename.size()); - for (auto c : filename) - { - if (c == ' ') - out += "\\ "; - else - out.push_back(c); - } - return out; -} - bool already_setup = false; void yosys_setup() diff --git a/kernel/yosys_common.h b/kernel/yosys_common.h index b1d9ce1e6..a68539ce1 100644 --- a/kernel/yosys_common.h +++ b/kernel/yosys_common.h @@ -128,6 +128,7 @@ # error "C++17 or later compatible compiler is required" #endif +#include "kernel/io.h" YOSYS_NAMESPACE_BEGIN @@ -245,63 +246,6 @@ inline void memhasher() { if (memhasher_active) memhasher_do(); } void yosys_banner(); int ceil_log2(int x) YS_ATTRIBUTE(const); -inline std::string vstringf(const char *fmt, va_list ap) -{ - // For the common case of strings shorter than 128, save a heap - // allocation by using a stack allocated buffer. - const int kBufSize = 128; - char buf[kBufSize]; - buf[0] = '\0'; - va_list apc; - va_copy(apc, ap); - int n = vsnprintf(buf, kBufSize, fmt, apc); - va_end(apc); - if (n < kBufSize) - return std::string(buf); - - std::string string; - char *str = NULL; -#if defined(_WIN32 )|| defined(__CYGWIN__) - int sz = 2 * kBufSize, rc; - while (1) { - va_copy(apc, ap); - str = (char*)realloc(str, sz); - rc = vsnprintf(str, sz, fmt, apc); - va_end(apc); - if (rc >= 0 && rc < sz) - break; - sz *= 2; - } - if (str != NULL) { - string = str; - free(str); - } - return string; -#else - if (vasprintf(&str, fmt, ap) < 0) - str = NULL; - if (str != NULL) { - string = str; - free(str); - } - return string; -#endif -} - -std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); - -inline std::string stringf(const char *fmt, ...) -{ - std::string string; - va_list ap; - - va_start(ap, fmt); - string = vstringf(fmt, ap); - va_end(ap); - - return string; -} - int readsome(std::istream &f, char *s, int n); std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false); std::vector split_tokens(const std::string &text, const char *sep = " \t\r\n"); diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index cf6622d55..bcdea9d87 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -22,6 +22,7 @@ #include "kernel/sigtools.h" #include "kernel/consteval.h" #include "kernel/celltypes.h" +#include "kernel/utils.h" #include "fsmdata.h" #include #include diff --git a/passes/opt/peepopt.cc b/passes/opt/peepopt.cc index b12f4777e..faacfb304 100644 --- a/passes/opt/peepopt.cc +++ b/passes/opt/peepopt.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/utils.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc index 9873f12a5..e512a5be1 100644 --- a/passes/opt/pmux2shiftx.cc +++ b/passes/opt/pmux2shiftx.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/ffinit.h" +#include "kernel/utils.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index be67d3a7f..fb30f0195 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -21,6 +21,7 @@ #include "kernel/sigtools.h" #include "kernel/modtools.h" #include "kernel/ffinit.h" +#include "kernel/utils.h" USING_YOSYS_NAMESPACE diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 6e2fabeeb..97c6f5600 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -354,6 +354,7 @@ with open(outfile, "w") as f: if genhdr: print("#include \"kernel/yosys.h\"", file=f) print("#include \"kernel/sigtools.h\"", file=f) + print("#include \"kernel/utils.h\"", file=f) print("", file=f) print("YOSYS_NAMESPACE_BEGIN", file=f) print("", file=f) diff --git a/passes/sat/assertpmux.cc b/passes/sat/assertpmux.cc index abdcb2240..991977ab9 100644 --- a/passes/sat/assertpmux.cc +++ b/passes/sat/assertpmux.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/utils.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN From 813f909460d642992545179cc6523fbf941b2663 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 20 Dec 2024 12:35:57 +0100 Subject: [PATCH 079/133] gzip: istream --- Makefile | 5 +- frontends/ast/simplify.cc | 14 ++-- kernel/gzip.cc | 132 ++++++++++++++++++++++++++++++++++++++ kernel/gzip.h | 79 +++++++++++++++++++++++ kernel/io.cc | 96 --------------------------- kernel/io.h | 36 +---------- kernel/register.cc | 1 + 7 files changed, 225 insertions(+), 138 deletions(-) create mode 100644 kernel/gzip.cc create mode 100644 kernel/gzip.h diff --git a/Makefile b/Makefile index 775375533..571f1e100 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,7 @@ YOSYS_SRC := $(dir $(firstword $(MAKEFILE_LIST))) VPATH := $(YOSYS_SRC) CXXSTD ?= c++17 -CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -Werror=implicit-function-declaration -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include +CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include LIBS := $(LIBS) -lstdc++ -lm PLUGIN_LINKFLAGS := PLUGIN_LIBS := @@ -586,6 +586,7 @@ $(eval $(call add_include_file,kernel/fmt.h)) ifeq ($(ENABLE_ZLIB),1) $(eval $(call add_include_file,kernel/fstdata.h)) endif +$(eval $(call add_include_file,kernel/gzip.h)) $(eval $(call add_include_file,kernel/hashlib.h)) $(eval $(call add_include_file,kernel/io.h)) $(eval $(call add_include_file,kernel/json.h)) @@ -618,7 +619,7 @@ $(eval $(call add_include_file,frontends/ast/ast_binding.h)) $(eval $(call add_include_file,frontends/blif/blifparse.h)) $(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) -OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o +OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o kernel/gzip.o OBJS += kernel/binding.o kernel/tclapi.o OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o OBJS += kernel/drivertools.o kernel/functional.o diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index ae49ae9ba..d35756d4e 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2777,13 +2777,13 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin mux_input = new AstNode(AST_BIT_NOT, mux_input); } AstNode *node = new AstNode(AST_TERNARY, children_list.at(2)); - // if (str == "bufif0") { - // node->children.push_back(AstNode::mkconst_bits(z_const, false)); - // node->children.push_back(mux_input); - // } else { - // node->children.push_back(mux_input); - // node->children.push_back(AstNode::mkconst_bits(z_const, false)); - // } + if (str == "bufif0") { + node->children.push_back(AstNode::mkconst_bits(z_const, false)); + node->children.push_back(mux_input); + } else { + node->children.push_back(mux_input); + node->children.push_back(AstNode::mkconst_bits(z_const, false)); + } str.clear(); type = AST_ASSIGN; diff --git a/kernel/gzip.cc b/kernel/gzip.cc new file mode 100644 index 000000000..900e33bf4 --- /dev/null +++ b/kernel/gzip.cc @@ -0,0 +1,132 @@ +#include "kernel/yosys_common.h" +#include "kernel/log.h" +#include "kernel/gzip.h" +#include +#include +#include +#include +#include + +YOSYS_NAMESPACE_BEGIN + + +#ifdef YOSYS_ENABLE_ZLIB + +PRIVATE_NAMESPACE_BEGIN + +using namespace Zlib; + +PRIVATE_NAMESPACE_END + +gzip_ostream::obuf::obuf() { + setp(buffer, buffer + buffer_size - 1); +} + +bool gzip_ostream::obuf::open(const std::string &filename) { + gzf = gzopen(filename.c_str(), "wb"); + return gzf != nullptr; +} + +int gzip_ostream::obuf::sync() { + int num = pptr() - pbase(); + if (num > 0) { + if (gzwrite(gzf, reinterpret_cast(pbase()), num) != num) { + return -1; + } + pbump(-num); + } + return 0; +} + +gzip_ostream::obuf::~obuf() { + if (gzf) { + sync(); + gzclose(gzf); + } +} + +bool gzip_istream::ibuf::open(const std::string& filename) { + if (gzf) { + Zlib::gzclose(gzf); + } + gzf = Zlib::gzopen(filename.c_str(), "rb"); + if (!gzf) { + return false; + } + // Empty and point to start + setg(buffer, buffer, buffer); + return true; +} + +// Called when the buffer is empty and more input is needed +std::istream::int_type gzip_istream::ibuf::underflow() { + log_assert(gzf && "No gzfile opened\n"); + int bytes_read = Zlib::gzread(gzf, buffer, buffer_size); + if (bytes_read <= 0) { + if (Zlib::gzeof(gzf)) + return traits_type::eof(); + + int err; + const char* error_msg = Zlib::gzerror(gzf, &err); + if (err != Z_OK) + log_error("%s", error_msg); + else + log_error("Decompression logic failure: "\ + "read <=0 bytes but neither EOF nor error\n"); + } + + // Keep size and point to start + setg(buffer, buffer, buffer + bytes_read); + return traits_type::to_int_type(buffer[0]); +} + +gzip_istream::ibuf::~ibuf() { + if (gzf) { + int err = Zlib::gzclose(gzf); + if (err != Z_OK) { + // OK to overwrite rr it, it doesn't change + const char* error_msg = Zlib::gzerror(gzf, &err); + log_error("%s", error_msg); + } + } +} + +#endif // YOSYS_ENABLE_ZLIB + + +// Takes a successfully opened ifstream. If it's gzipped, returns an istream. Otherwise, +// returns the original ifstream, rewound to the start. +std::istream* uncompressed(std::ifstream* f, const std::string filename) { + if (!f) + return nullptr; + // Check for gzip magic + unsigned char magic[3]; + int n = 0; + while (n < 3) + { + int c = f->get(); + if (c != EOF) { + magic[n] = (unsigned char) c; + } + n++; + } + if (n == 3 && magic[0] == 0x1f && magic[1] == 0x8b) { +#ifdef YOSYS_ENABLE_ZLIB + log("Found gzip magic in file `%s', decompressing using zlib.\n", filename.c_str()); + if (magic[2] != 8) + log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n", + filename.c_str(), unsigned(magic[2])); + delete f; + gzip_istream* s = new gzip_istream(); + return s->open(filename.c_str()) ? s : nullptr; +#else + log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); +#endif // YOSYS_ENABLE_ZLIB + } else { + f->clear(); + f->seekg(0, std::ios::beg); + return f; + } +} + +YOSYS_NAMESPACE_END diff --git a/kernel/gzip.h b/kernel/gzip.h new file mode 100644 index 000000000..22f5093a0 --- /dev/null +++ b/kernel/gzip.h @@ -0,0 +1,79 @@ +#include +#include +#include "kernel/yosys_common.h" + +#ifndef YOSYS_GZIP_H +#define YOSYS_GZIP_H + +YOSYS_NAMESPACE_BEGIN + +#ifdef YOSYS_ENABLE_ZLIB + +namespace Zlib { +#include +} + +/* +An output stream that uses a stringbuf to buffer data internally, +using zlib to write gzip-compressed data every time the stream is flushed. +*/ +class gzip_ostream : public std::ostream { +public: + gzip_ostream(): std::ostream(nullptr) { + rdbuf(&outbuf); + } + bool open(const std::string &filename) { + return outbuf.open(filename); + } +private: + class obuf : public std::stringbuf { + public: + obuf(); + bool open(const std::string &filename); + virtual int sync() override; + virtual ~obuf(); + private: + static const int buffer_size = 4096; + char buffer[buffer_size]; // Internal buffer for compressed data + Zlib::gzFile gzf = nullptr; // Handle to the gzip file + }; + + obuf outbuf; // The stream buffer instance +}; + +/* +An input stream that uses zlib to read gzip-compressed data from a file, +buffering the decompressed data internally using its own buffer. +*/ +class gzip_istream final : public std::istream { +public: + gzip_istream() : std::istream(&inbuf) {} + bool open(const std::string& filename) { + return inbuf.open(filename); + } +private: + class ibuf final : public std::streambuf { + public: + ibuf() : gzf(nullptr) {} + bool open(const std::string& filename); + virtual ~ibuf(); + + protected: + // Called when the buffer is empty and more input is needed + virtual int_type underflow() override; + private: + static const int buffer_size = 8192; + char buffer[buffer_size]; + Zlib::gzFile gzf; + }; + + ibuf inbuf; // The stream buffer instance +}; + +#endif // YOSYS_ENABLE_ZLIB + +std::istream* uncompressed(std::ifstream* f, const std::string filename); + +YOSYS_NAMESPACE_END + +#endif // YOSYS_GZIP_H diff --git a/kernel/io.cc b/kernel/io.cc index 2b09eb69b..579ff9f3d 100644 --- a/kernel/io.cc +++ b/kernel/io.cc @@ -3,8 +3,6 @@ #include #include #include -#include -#include YOSYS_NAMESPACE_BEGIN @@ -363,98 +361,4 @@ std::string escape_filename_spaces(const std::string& filename) return out; } -#ifdef YOSYS_ENABLE_ZLIB - -PRIVATE_NAMESPACE_BEGIN - -static const size_t GZ_BUFFER_SIZE = 8192; -static void decompress_gzip(const std::string &filename, std::stringstream &out) -{ - char buffer[GZ_BUFFER_SIZE]; - int bytes_read; - gzFile gzf = gzopen(filename.c_str(), "rb"); - while(!gzeof(gzf)) { - bytes_read = gzread(gzf, reinterpret_cast(buffer), GZ_BUFFER_SIZE); - out.write(buffer, bytes_read); - } - gzclose(gzf); -} - -PRIVATE_NAMESPACE_END - -gzip_ostream::gzip_ostream() : std::ostream(nullptr) { - rdbuf(&outbuf); -} - -bool gzip_ostream::open(const std::string &filename) { - return outbuf.open(filename); -} - -gzip_ostream::gzip_streambuf::gzip_streambuf() { - setp(buffer, buffer + buffer_size - 1); -} - -bool gzip_ostream::gzip_streambuf::open(const std::string &filename) { - gzf = gzopen(filename.c_str(), "wb"); - return gzf != nullptr; -} - -int gzip_ostream::gzip_streambuf::sync() { - int num = pptr() - pbase(); - if (num > 0) { - if (gzwrite(gzf, reinterpret_cast(pbase()), num) != num) { - return -1; - } - pbump(-num); - } - return 0; -} - -gzip_ostream::gzip_streambuf::~gzip_streambuf() { - if (gzf) { - sync(); - gzclose(gzf); - } -} - -#endif // YOSYS_ENABLE_ZLIB - - -// Takes a successfully opened ifstream. If it's gzipped, returns an istream -// over a buffer of the file fully decompressed in memory. Otherwise, -// returns the original ifstream, rewound to the start. -std::istream* uncompressed(std::ifstream* f, const std::string filename) { - if (!f) - return nullptr; - // Check for gzip magic - unsigned char magic[3]; - int n = 0; - while (n < 3) - { - int c = f->get(); - if (c != EOF) { - magic[n] = (unsigned char) c; - } - n++; - } - if (n == 3 && magic[0] == 0x1f && magic[1] == 0x8b) { -#ifdef YOSYS_ENABLE_ZLIB - log("Found gzip magic in file `%s', decompressing using zlib.\n", filename.c_str()); - if (magic[2] != 8) - log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n", - filename.c_str(), unsigned(magic[2])); - delete f; - std::stringstream *df = new std::stringstream(); - decompress_gzip(filename, *df); - return df; -#else - log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); -#endif // YOSYS_ENABLE_ZLIB - } else { - f->clear(); - f->seekg(0, std::ios::beg); - return f; - } -} - YOSYS_NAMESPACE_END diff --git a/kernel/io.h b/kernel/io.h index 99b2dc62a..1eb3a0fc1 100644 --- a/kernel/io.h +++ b/kernel/io.h @@ -1,13 +1,11 @@ -#include "kernel/yosys_common.h" #include +#include +#include +#include "kernel/yosys_common.h" #ifndef YOSYS_IO_H #define YOSYS_IO_H -#ifdef YOSYS_ENABLE_ZLIB -#include -#endif - YOSYS_NAMESPACE_BEGIN inline std::string vstringf(const char *fmt, va_list ap) @@ -67,34 +65,6 @@ inline std::string stringf(const char *fmt, ...) return string; } -#ifdef YOSYS_ENABLE_ZLIB -/* -An output stream that uses a stringbuf to buffer data internally, -using zlib to write gzip-compressed data every time the stream is flushed. -*/ -class gzip_ostream : public std::ostream { -public: - gzip_ostream(); - bool open(const std::string &filename); -private: - class gzip_streambuf : public std::stringbuf { - public: - gzip_streambuf(); - bool open(const std::string &filename); - virtual int sync() override; - virtual ~gzip_streambuf(); - private: - static const int buffer_size = 4096; // Size of the internal buffer - char buffer[buffer_size]; // Internal buffer for compressed data - gzFile gzf = nullptr; // Handle to the gzip file - }; - - gzip_streambuf outbuf; // The stream buffer instance -}; -#endif // YOSYS_ENABLE_ZLIB - -std::istream* uncompressed(std::ifstream* f, const std::string filename); - YOSYS_NAMESPACE_END #endif // YOSYS_IO_H diff --git a/kernel/register.cc b/kernel/register.cc index c919871dc..9640ff074 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/satgen.h" #include "kernel/json.h" +#include "kernel/gzip.h" #include #include From 218ec3fc056f81802e07492c4411fa6101bd384d Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 3 Jan 2025 17:51:38 +0100 Subject: [PATCH 080/133] dfflibmap: allow gzipped liberty files --- passes/techmap/dfflibmap.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index b475cdd2d..fedcba1e1 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/gzip.h" #include "libparse.h" #include #include @@ -632,11 +633,12 @@ struct DfflibmapPass : public Pass { for (auto path : liberty_files) { std::ifstream f; f.open(path.c_str()); - if (f.fail()) + std::istream* ff = uncompressed(&f, path); + if (ff->fail()) log_cmd_error("Can't open liberty file `%s': %s\n", path.c_str(), strerror(errno)); - LibertyParser p(f); + LibertyParser p(*ff); merged.merge(p); - f.close(); + delete ff; } find_cell(merged.cells, ID($_DFF_N_), false, false, false, false, false, false, dont_use_cells); From d00259081dcbb06f378a670a595fa167e7880753 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 3 Jan 2025 18:40:40 +0100 Subject: [PATCH 081/133] gzip: simplify uncompressed interface --- kernel/gzip.cc | 21 ++++++++++++--------- kernel/gzip.h | 2 +- kernel/register.cc | 8 +------- passes/techmap/dfflibmap.cc | 10 ++++------ 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/kernel/gzip.cc b/kernel/gzip.cc index 900e33bf4..0da53ff68 100644 --- a/kernel/gzip.cc +++ b/kernel/gzip.cc @@ -96,15 +96,17 @@ gzip_istream::ibuf::~ibuf() { // Takes a successfully opened ifstream. If it's gzipped, returns an istream. Otherwise, // returns the original ifstream, rewound to the start. -std::istream* uncompressed(std::ifstream* f, const std::string filename) { - if (!f) - return nullptr; +std::istream& uncompressed(const std::string filename, std::ios_base::openmode mode) { + std::ifstream& f = *new std::ifstream(); + f.open(filename, mode); + if (f.fail()) + return f; // Check for gzip magic unsigned char magic[3]; int n = 0; while (n < 3) { - int c = f->get(); + int c = f.get(); if (c != EOF) { magic[n] = (unsigned char) c; } @@ -116,15 +118,16 @@ std::istream* uncompressed(std::ifstream* f, const std::string filename) { if (magic[2] != 8) log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n", filename.c_str(), unsigned(magic[2])); - delete f; - gzip_istream* s = new gzip_istream(); - return s->open(filename.c_str()) ? s : nullptr; + gzip_istream& s = *new gzip_istream(); + delete &f; + s.open(filename.c_str()); + return s; #else log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); #endif // YOSYS_ENABLE_ZLIB } else { - f->clear(); - f->seekg(0, std::ios::beg); + f.clear(); + f.seekg(0, std::ios::beg); return f; } } diff --git a/kernel/gzip.h b/kernel/gzip.h index 22f5093a0..0201d2340 100644 --- a/kernel/gzip.h +++ b/kernel/gzip.h @@ -72,7 +72,7 @@ private: #endif // YOSYS_ENABLE_ZLIB -std::istream* uncompressed(std::ifstream* f, const std::string filename); +std::istream& uncompressed(const std::string filename, std::ios_base::openmode mode = std::ios_base::in); YOSYS_NAMESPACE_END diff --git a/kernel/register.cc b/kernel/register.cc index 9640ff074..508091974 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -469,14 +469,8 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vectoropen(filename.c_str(), bin_input ? std::ifstream::binary : std::ifstream::in); yosys_input_files.insert(filename); - if (ff->fail()) { - delete ff; - ff = nullptr; - } - f = uncompressed(ff, filename); + f = &uncompressed(filename, bin_input ? std::ifstream::binary : std::ifstream::in); } if (f == NULL) log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index fedcba1e1..df2bfa88f 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -631,14 +631,12 @@ struct DfflibmapPass : public Pass { LibertyMergedCells merged; for (auto path : liberty_files) { - std::ifstream f; - f.open(path.c_str()); - std::istream* ff = uncompressed(&f, path); - if (ff->fail()) + std::istream& f = uncompressed(path); + if (f.fail()) log_cmd_error("Can't open liberty file `%s': %s\n", path.c_str(), strerror(errno)); - LibertyParser p(*ff); + LibertyParser p(f); merged.merge(p); - delete ff; + delete &f; } find_cell(merged.cells, ID($_DFF_N_), false, false, false, false, false, false, dont_use_cells); From ab2ca831c9613fb60eafce33d0b8306d0e8f7e5c Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Sat, 4 Jan 2025 12:18:02 +0100 Subject: [PATCH 082/133] io: remove unused unistd.h to fix windows build --- kernel/io.h | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/io.h b/kernel/io.h index 1eb3a0fc1..b21d4d9c8 100644 --- a/kernel/io.h +++ b/kernel/io.h @@ -1,5 +1,4 @@ #include -#include #include #include "kernel/yosys_common.h" From 0877798e189e69fc1c98f6e7474d37bcc8849e90 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Sat, 4 Jan 2025 12:18:19 +0100 Subject: [PATCH 083/133] dfflibmap: allow gzipped liberty files --- passes/techmap/clockgate.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index 52851d922..0cb9e0910 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -1,5 +1,6 @@ #include "kernel/yosys.h" #include "kernel/ff.h" +#include "kernel/gzip.h" #include "libparse.h" #include @@ -308,13 +309,12 @@ struct ClockgatePass : public Pass { if (!liberty_files.empty()) { LibertyMergedCells merged; for (auto path : liberty_files) { - std::ifstream f; - f.open(path.c_str()); + std::istream& f = uncompressed(path); if (f.fail()) log_cmd_error("Can't open liberty file `%s': %s\n", path.c_str(), strerror(errno)); LibertyParser p(f); merged.merge(p); - f.close(); + delete &f; } std::tie(pos_icg_desc, neg_icg_desc) = find_icgs(merged.cells, dont_use_cells); From ceb7a923dae7b675a4866a0f7e5122109d18de43 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Sun, 5 Jan 2025 23:55:38 +0100 Subject: [PATCH 084/133] io: smooth out non-POSIX function usage across platforms --- kernel/gzip.cc | 8 +++++++- kernel/gzip.h | 1 - kernel/io.cc | 8 +++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/kernel/gzip.cc b/kernel/gzip.cc index 0da53ff68..71a498bb0 100644 --- a/kernel/gzip.cc +++ b/kernel/gzip.cc @@ -2,11 +2,17 @@ #include "kernel/log.h" #include "kernel/gzip.h" #include -#include #include #include #include +#if !defined(WIN32) +#include +#include +#else +#include +#endif + YOSYS_NAMESPACE_BEGIN diff --git a/kernel/gzip.h b/kernel/gzip.h index 0201d2340..57eac73c8 100644 --- a/kernel/gzip.h +++ b/kernel/gzip.h @@ -1,5 +1,4 @@ #include -#include #include "kernel/yosys_common.h" #ifndef YOSYS_GZIP_H diff --git a/kernel/io.cc b/kernel/io.cc index 579ff9f3d..5331e2ed8 100644 --- a/kernel/io.cc +++ b/kernel/io.cc @@ -1,9 +1,15 @@ #include "kernel/yosys_common.h" #include "kernel/log.h" #include -#include #include +#if !defined(WIN32) +#include +#include +#else +#include +#endif + YOSYS_NAMESPACE_BEGIN // Set of utilities for handling files From 79985a2bcaef2f657e80b5e9a3df5a01fd605f99 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 7 Jan 2025 11:19:30 +0100 Subject: [PATCH 085/133] gzip: minor refactor --- kernel/gzip.cc | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/kernel/gzip.cc b/kernel/gzip.cc index 71a498bb0..b1f61ea26 100644 --- a/kernel/gzip.cc +++ b/kernel/gzip.cc @@ -15,28 +15,21 @@ YOSYS_NAMESPACE_BEGIN - #ifdef YOSYS_ENABLE_ZLIB -PRIVATE_NAMESPACE_BEGIN - -using namespace Zlib; - -PRIVATE_NAMESPACE_END - gzip_ostream::obuf::obuf() { setp(buffer, buffer + buffer_size - 1); } bool gzip_ostream::obuf::open(const std::string &filename) { - gzf = gzopen(filename.c_str(), "wb"); + gzf = Zlib::gzopen(filename.c_str(), "wb"); return gzf != nullptr; } int gzip_ostream::obuf::sync() { int num = pptr() - pbase(); if (num > 0) { - if (gzwrite(gzf, reinterpret_cast(pbase()), num) != num) { + if (Zlib::gzwrite(gzf, reinterpret_cast(pbase()), num) != num) { return -1; } pbump(-num); @@ -47,7 +40,7 @@ int gzip_ostream::obuf::sync() { gzip_ostream::obuf::~obuf() { if (gzf) { sync(); - gzclose(gzf); + Zlib::gzclose(gzf); } } From a8a5463f57c5959862fb32cab2dc4cc906408079 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Thu, 9 Jan 2025 13:38:51 +0100 Subject: [PATCH 086/133] gzip: uphold rules for basic_streambuf::underflow overrides --- kernel/gzip.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/gzip.cc b/kernel/gzip.cc index b1f61ea26..f31d535df 100644 --- a/kernel/gzip.cc +++ b/kernel/gzip.cc @@ -62,8 +62,13 @@ std::istream::int_type gzip_istream::ibuf::underflow() { log_assert(gzf && "No gzfile opened\n"); int bytes_read = Zlib::gzread(gzf, buffer, buffer_size); if (bytes_read <= 0) { - if (Zlib::gzeof(gzf)) + if (Zlib::gzeof(gzf)) { + // "On failure, the function ensures that either + // gptr() == nullptr or gptr() == egptr." + // Let's set gptr to egptr + setg(eback(), egptr(), egptr()); return traits_type::eof(); + } int err; const char* error_msg = Zlib::gzerror(gzf, &err); From 7aefd4b22677e9ffa4bf8d8235a0666808fae8c2 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Thu, 9 Jan 2025 16:26:03 +0100 Subject: [PATCH 087/133] gzip: back to pointers --- kernel/gzip.cc | 20 ++++++++++---------- kernel/gzip.h | 2 +- kernel/register.cc | 2 +- passes/techmap/clockgate.cc | 8 ++++---- passes/techmap/dfflibmap.cc | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/kernel/gzip.cc b/kernel/gzip.cc index f31d535df..d44b03517 100644 --- a/kernel/gzip.cc +++ b/kernel/gzip.cc @@ -100,17 +100,17 @@ gzip_istream::ibuf::~ibuf() { // Takes a successfully opened ifstream. If it's gzipped, returns an istream. Otherwise, // returns the original ifstream, rewound to the start. -std::istream& uncompressed(const std::string filename, std::ios_base::openmode mode) { - std::ifstream& f = *new std::ifstream(); - f.open(filename, mode); - if (f.fail()) +std::istream* uncompressed(const std::string filename, std::ios_base::openmode mode) { + std::ifstream* f = new std::ifstream(); + f->open(filename, mode); + if (f->fail()) return f; // Check for gzip magic unsigned char magic[3]; int n = 0; while (n < 3) { - int c = f.get(); + int c = f->get(); if (c != EOF) { magic[n] = (unsigned char) c; } @@ -122,16 +122,16 @@ std::istream& uncompressed(const std::string filename, std::ios_base::openmode m if (magic[2] != 8) log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n", filename.c_str(), unsigned(magic[2])); - gzip_istream& s = *new gzip_istream(); - delete &f; - s.open(filename.c_str()); + gzip_istream* s = new gzip_istream(); + delete f; + s->open(filename.c_str()); return s; #else log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); #endif // YOSYS_ENABLE_ZLIB } else { - f.clear(); - f.seekg(0, std::ios::beg); + f->clear(); + f->seekg(0, std::ios::beg); return f; } } diff --git a/kernel/gzip.h b/kernel/gzip.h index 57eac73c8..aac5340de 100644 --- a/kernel/gzip.h +++ b/kernel/gzip.h @@ -71,7 +71,7 @@ private: #endif // YOSYS_ENABLE_ZLIB -std::istream& uncompressed(const std::string filename, std::ios_base::openmode mode = std::ios_base::in); +std::istream* uncompressed(const std::string filename, std::ios_base::openmode mode = std::ios_base::in); YOSYS_NAMESPACE_END diff --git a/kernel/register.cc b/kernel/register.cc index 508091974..fcb6ca769 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -470,7 +470,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vectorfail()) log_cmd_error("Can't open liberty file `%s': %s\n", path.c_str(), strerror(errno)); - LibertyParser p(f); + LibertyParser p(*f); merged.merge(p); - delete &f; + delete f; } std::tie(pos_icg_desc, neg_icg_desc) = find_icgs(merged.cells, dont_use_cells); diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index df2bfa88f..fe4f8aada 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -631,12 +631,12 @@ struct DfflibmapPass : public Pass { LibertyMergedCells merged; for (auto path : liberty_files) { - std::istream& f = uncompressed(path); - if (f.fail()) + std::istream* f = uncompressed(path); + if (f->fail()) log_cmd_error("Can't open liberty file `%s': %s\n", path.c_str(), strerror(errno)); - LibertyParser p(f); + LibertyParser p(*f); merged.merge(p); - delete &f; + delete f; } find_cell(merged.cells, ID($_DFF_N_), false, false, false, false, false, false, dont_use_cells); From 980a0a15c1b13f7824abc540a986b75729fce723 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Mon, 27 Jan 2025 16:08:47 +0100 Subject: [PATCH 088/133] stat: allow gzipped liberty files --- passes/cmds/stat.cc | 10 +++++----- tests/various/stat.ys | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 tests/various/stat.ys diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 5bbbb2789..7e51b6cb1 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -23,6 +23,7 @@ #include "kernel/celltypes.h" #include "passes/techmap/libparse.h" #include "kernel/cost.h" +#include "kernel/gzip.h" #include "libs/json11/json11.hpp" USING_YOSYS_NAMESPACE @@ -347,13 +348,12 @@ statdata_t hierarchy_worker(std::map &mod_stat, RTL void read_liberty_cellarea(dict &cell_area, string liberty_file) { - std::ifstream f; - f.open(liberty_file.c_str()); + std::istream* f = uncompressed(liberty_file.c_str()); yosys_input_files.insert(liberty_file); - if (f.fail()) + if (f->fail()) log_cmd_error("Can't open liberty file `%s': %s\n", liberty_file.c_str(), strerror(errno)); - LibertyParser libparser(f); - f.close(); + LibertyParser libparser(*f); + delete f; for (auto cell : libparser.ast->children) { diff --git a/tests/various/stat.ys b/tests/various/stat.ys new file mode 100644 index 000000000..ad96fe8d4 --- /dev/null +++ b/tests/various/stat.ys @@ -0,0 +1,14 @@ +read_rtlil << EOF +module \top + wire input 1 \A + wire output 2 \Y + cell \sg13g2_and2_1 \sub + connect \A \A + connect \B 1'0 + connect \Y \Y + end +end +EOF +logger -expect log "Chip area for module '\\top': 9.072000" 1 +logger -expect-no-warnings +stat -liberty ../../tests/liberty/foundry_data/sg13g2_stdcell_typ_1p20V_25C.lib.filtered.gz From 199702a3925c182e2457396b16cf76e9cdc30a3d Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Wed, 19 Mar 2025 18:28:50 +0100 Subject: [PATCH 089/133] dft_tag: fix autoNot not notting --- passes/cmds/dft_tag.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/dft_tag.cc b/passes/cmds/dft_tag.cc index ba7d14323..b6afe6f89 100644 --- a/passes/cmds/dft_tag.cc +++ b/passes/cmds/dft_tag.cc @@ -883,7 +883,7 @@ struct DftTagWorker { { if (sig_a.is_fully_const()) { auto const_val = sig_a.as_const(); - for (auto bit : const_val) + for (State& bit : const_val.bits()) bit = bit == State::S0 ? State::S1 : bit == State::S1 ? State::S0 : bit; return const_val; } From f92ad7d900af8d9095cf91abd5d0dfce8ea42a3d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 00:21:55 +0000 Subject: [PATCH 090/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 76c7cffbb..c58c6f0f3 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+41 +YOSYS_VER := 0.51+46 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 013206de391d548f1889670e35fc9da6890d6469 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 20 Mar 2025 14:23:37 +1300 Subject: [PATCH 091/133] Fix #3898 (again) --- libs/fst/00_PATCH_i386_endian.patch | 14 ++++++++++++++ libs/fst/00_UPDATE.sh | 1 + libs/fst/fstapi.cc | 5 ++++- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 libs/fst/00_PATCH_i386_endian.patch diff --git a/libs/fst/00_PATCH_i386_endian.patch b/libs/fst/00_PATCH_i386_endian.patch new file mode 100644 index 000000000..3857f1fdf --- /dev/null +++ b/libs/fst/00_PATCH_i386_endian.patch @@ -0,0 +1,14 @@ +--- fstapi.cc ++++ fstapi.cc +@@ -4723,7 +4723,10 @@ if(gzread_pass_status) + hdr_incomplete = (xc->start_time == 0) && (xc->end_time == 0); + + fstFread(&dcheck, 8, 1, xc->f); +- xc->double_endian_match = (dcheck == FST_DOUBLE_ENDTEST); ++ /* ++ * Yosys patch: Fix double endian check for i386 targets built in modern gcc ++ */ ++ xc->double_endian_match = (dcheck == (double)FST_DOUBLE_ENDTEST); + if(!xc->double_endian_match) + { + union { diff --git a/libs/fst/00_UPDATE.sh b/libs/fst/00_UPDATE.sh index 66a0fd8df..302e187f2 100755 --- a/libs/fst/00_UPDATE.sh +++ b/libs/fst/00_UPDATE.sh @@ -19,3 +19,4 @@ patch -p0 < 00_PATCH_win_zlib.patch patch -p0 < 00_PATCH_win_io.patch patch -p1 < 00_PATCH_strict_alignment.patch patch -p0 < 00_PATCH_wx_len_overread.patch +patch -p0 < 00_PATCH_i386_endian.patch diff --git a/libs/fst/fstapi.cc b/libs/fst/fstapi.cc index ab3c54469..2463e6f15 100644 --- a/libs/fst/fstapi.cc +++ b/libs/fst/fstapi.cc @@ -4723,7 +4723,10 @@ if(gzread_pass_status) hdr_incomplete = (xc->start_time == 0) && (xc->end_time == 0); fstFread(&dcheck, 8, 1, xc->f); - xc->double_endian_match = (dcheck == FST_DOUBLE_ENDTEST); + /* + * Yosys patch: Fix double endian check for i386 targets built in modern gcc + */ + xc->double_endian_match = (dcheck == (double)FST_DOUBLE_ENDTEST); if(!xc->double_endian_match) { union { From 452dd1b74b5cee91e618043c6211745569adc339 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 20 Mar 2025 17:19:22 +1300 Subject: [PATCH 092/133] abstract: Assign default to value Fix `-Wmaybe-uninitialized` on line 43 and 44. --- passes/cmds/abstract.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/abstract.cc b/passes/cmds/abstract.cc index 1e67dcd88..513cd8ecc 100644 --- a/passes/cmds/abstract.cc +++ b/passes/cmds/abstract.cc @@ -45,7 +45,7 @@ struct Slice { } static int parse_index(const char *begin, const char *end, const std::string &slice) { - int value; + int value = 0; auto result = std::from_chars(begin, end, value, 10); if (result.ptr != end || result.ptr == begin) syntax_error(slice); From d704ca8019455799b2244fa31178439eff02a529 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 20 Mar 2025 17:20:36 +1300 Subject: [PATCH 093/133] abstract: Fix indentation --- passes/cmds/abstract.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/abstract.cc b/passes/cmds/abstract.cc index 513cd8ecc..d4eb22ca5 100644 --- a/passes/cmds/abstract.cc +++ b/passes/cmds/abstract.cc @@ -47,7 +47,7 @@ struct Slice { static int parse_index(const char *begin, const char *end, const std::string &slice) { int value = 0; auto result = std::from_chars(begin, end, value, 10); - if (result.ptr != end || result.ptr == begin) + if (result.ptr != end || result.ptr == begin) syntax_error(slice); return value; } From 2b67ad78bf533eec1134973aef4489823b7738b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gr=C3=B6ber?= Date: Fri, 14 Mar 2025 21:23:33 +0100 Subject: [PATCH 094/133] mk: Fall back to cp if rsync is not available --- Makefile | 10 ++++++++-- docs/source/_images/Makefile | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 89ffaef66..adaf57d0f 100644 --- a/Makefile +++ b/Makefile @@ -114,6 +114,12 @@ BISON ?= bison STRIP ?= strip AWK ?= awk +ifneq ($(shell :; command -v rsync),) +RSYNC_CP ?= rsync -rc +else +RSYNC_CP ?= cp -ru +endif + ifeq ($(OS), Darwin) PLUGIN_LINKFLAGS += -undefined dynamic_lookup LINKFLAGS += -rdynamic @@ -1005,13 +1011,13 @@ docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS) $(Q) mkdir -p docs/source/cmd $(Q) mkdir -p temp/docs/source/cmd $(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-command-reference-manual' - $(Q) rsync -rc temp/docs/source/cmd docs/source + $(Q) $(RSYNC_CP) temp/docs/source/cmd docs/source $(Q) rm -rf temp docs/source/cell/word_add.rst: $(TARGETS) $(EXTRA_TARGETS) $(Q) mkdir -p docs/source/cell $(Q) mkdir -p temp/docs/source/cell $(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-cells-manual' - $(Q) rsync -rc temp/docs/source/cell docs/source + $(Q) $(RSYNC_CP) temp/docs/source/cell docs/source $(Q) rm -rf temp docs/source/generated/cells.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) diff --git a/docs/source/_images/Makefile b/docs/source/_images/Makefile index cc00050f1..71f52c578 100644 --- a/docs/source/_images/Makefile +++ b/docs/source/_images/Makefile @@ -3,6 +3,12 @@ all: examples all_tex # set a fake time in pdf generation to prevent unnecessary differences in output FAKETIME := TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001' +ifneq ($(shell :; command -v rsync),) +RSYNC_CP ?= rsync -t +else +RSYNC_CP ?= cp -a +endif + # find all code example makefiles .PHONY: examples CODE_EXAMPLES := ../code_examples/*/Makefile @@ -19,7 +25,7 @@ FORCE: ../%/Makefile: FORCE @make -C $(@D) dots @mkdir -p $* - @find $(@D) -name *.dot -exec rsync -t {} $* \; + @find $(@D) -name *.dot -exec $(RSYNC_CP) {} $* \; # find and build all tex files .PHONY: all_tex From 59602740eea8662e30e245b267b59e47c158fa48 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 00:23:05 +0000 Subject: [PATCH 095/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index eeb0bf424..f9f09d501 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+46 +YOSYS_VER := 0.51+79 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 04bbd4e7e2833060d6eb13d7749a391ccc799c5d Mon Sep 17 00:00:00 2001 From: Scott Ashcroft Date: Tue, 25 Mar 2025 13:08:49 +0000 Subject: [PATCH 096/133] Make all vector-size related integer params in $print sim model signed This fixes iverilog crashes on 32-bit, similar to 95944eb for $mem. --- techlibs/common/simlib.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 028e4e5a9..6e39aa60a 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -2224,10 +2224,10 @@ module \$print (EN, TRG, ARGS); parameter PRIORITY = 0; parameter FORMAT = ""; -parameter ARGS_WIDTH = 0; +parameter signed ARGS_WIDTH = 0; parameter TRG_ENABLE = 1; -parameter TRG_WIDTH = 0; +parameter signed TRG_WIDTH = 0; parameter TRG_POLARITY = 0; input EN; From 518986d45c507f303c0d7b2230e5cf54ab6be293 Mon Sep 17 00:00:00 2001 From: Scott Ashcroft Date: Tue, 25 Mar 2025 13:12:04 +0000 Subject: [PATCH 097/133] Make cxxrtl tests work on 32-bit by using __builtin_clzll when needed --- tests/cxxrtl/test_value_fuzz.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/cxxrtl/test_value_fuzz.cc b/tests/cxxrtl/test_value_fuzz.cc index 7e8fbb0a9..a77120136 100644 --- a/tests/cxxrtl/test_value_fuzz.cc +++ b/tests/cxxrtl/test_value_fuzz.cc @@ -241,7 +241,10 @@ struct CtlzTest { if (a == 0) return bits; - return __builtin_clzl(a) - (64 - bits); + if (sizeof(long) == 4) + return __builtin_clzll(a) - (64 - bits); + else + return __builtin_clzl(a) - (64 - bits); } template From 4991ed9d4bd610fed7e1a969c3957ea087bb62ba Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 25 Mar 2025 18:10:47 +0100 Subject: [PATCH 098/133] cutpoint: fix typo --- passes/sat/cutpoint.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index bca6a5ec6..88f995dda 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -34,8 +34,8 @@ struct CutpointPass : public Pass { log("This command adds formal cut points to the design.\n"); log("\n"); log(" -undef\n"); - log(" set cupoint nets to undef (x). the default behavior is to create a\n"); - log(" $anyseq cell and drive the cutpoint net from that\n"); + log(" set cutpoint nets to undef (x). the default behavior is to create\n"); + log(" an $anyseq cell and drive the cutpoint net from that\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override From d3aec12fe9d17935170a739a7ac3c18207c5bcc6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 26 Mar 2025 00:22:20 +0000 Subject: [PATCH 099/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f9f09d501..5745d1d0c 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+79 +YOSYS_VER := 0.51+85 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From cb03a1ec2121cde499253c8f3738bac8fdb400b0 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Wed, 26 Mar 2025 15:13:05 +0200 Subject: [PATCH 100/133] ice40_dsp: fix test --- tests/various/bug4865.ys | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/various/bug4865.ys b/tests/various/bug4865.ys index ac5a459d8..b747c59a7 100644 --- a/tests/various/bug4865.ys +++ b/tests/various/bug4865.ys @@ -1,5 +1,6 @@ read_rtlil << EOF + autoidx 524 attribute \top 1 @@ -10,8 +11,10 @@ module \main attribute \force_downto 1 wire width 18 $verific$mult_4$garbage/usb.v:12$388.etc.blk.partial[0] - wire width 14 $delete_wire$514 + wire width 12 $delete_wire$514 + wire width 4 $test + attribute \module_not_derived 1 cell \SB_MAC16 $verific$mult_4$garbage/usb.v:12$388.etc.sliceB[0].mul parameter \A_REG 1'0 @@ -36,7 +39,7 @@ module \main parameter \TOP_8x8_MULT_REG 1'0 connect \A 16'x connect \B 16'x - connect \O { $delete_wire$514 $verific$mult_4$garbage/usb.v:12$388.etc.blk.partial[0] [17:2] 2'x} + connect \O { $test $delete_wire$514 14'x $verific$mult_4$garbage/usb.v:12$388.etc.blk.partial[0] [1:0] } end cell $add $techmap$verific$mult_4$garbage/usb.v:12$388.etc.sliceA.last.$add$/home/emil/pulls/yosys/share/mul2dsp.v:216$483 @@ -46,17 +49,17 @@ module \main parameter \B_WIDTH 2 parameter \Y_WIDTH 19 connect \A 18'x - connect \B $verific$mult_4$garbage/usb.v:12$388.etc.blk.partial[0] [17:16] + connect \B $verific$mult_4$garbage/usb.v:12$388.etc.blk.partial[0] [1:0] connect \Y 19'x end cell $add $techmap$verific$mult_4$garbage/usb.v:12$388.$add$/home/emil/pulls/yosys/share/mul2dsp.v:173$480 parameter \A_SIGNED 0 - parameter \A_WIDTH 14 + parameter \A_WIDTH 2 parameter \B_SIGNED 0 parameter \B_WIDTH 2 parameter \Y_WIDTH 2 - connect \A $delete_wire$514 + connect \A $delete_wire$514 [1:0] connect \B 2'x connect \Y 2'x end From 8a68ae60233677f7e42bf715939b4b6da3632e81 Mon Sep 17 00:00:00 2001 From: KrystalDelusion <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 27 Mar 2025 10:10:49 +1300 Subject: [PATCH 101/133] Update gen-tests-makefile.sh --- tests/gen-tests-makefile.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/gen-tests-makefile.sh b/tests/gen-tests-makefile.sh index 146bb5e81..855ebbd9b 100755 --- a/tests/gen-tests-makefile.sh +++ b/tests/gen-tests-makefile.sh @@ -17,20 +17,20 @@ generate_target() { generate_ys_test() { ys_file=$1 yosys_args_=${2:-} - generate_target "$ys_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${ys_file%.*}.log $yosys_args_ $ys_file" + generate_target "$ys_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${ys_file%.*}.err $yosys_args_ $ys_file && mv ${ys_file%.*}.err ${ys_file%.*}.log" } # $ generate_tcl_test tcl_file [yosys_args] generate_tcl_test() { tcl_file=$1 yosys_args_=${2:-} - generate_target "$tcl_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${tcl_file%.*}.log $yosys_args_ $tcl_file" + generate_target "$tcl_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${tcl_file%.*}.err $yosys_args_ $tcl_file && mv ${tcl_file%.*}.err ${tcl_file%.*}.log" } # $ generate_bash_test bash_file generate_bash_test() { bash_file=$1 - generate_target "$bash_file" "bash -v $bash_file >${bash_file%.*}.log 2>&1" + generate_target "$bash_file" "bash -v $bash_file >${bash_file%.*}.err 2>&1 && mv ${bash_file%.*}.err ${bash_file%.*}.log" } # $ generate_tests [-y|--yosys-scripts] [-s|--prove-sv] [-b|--bash] [-a|--yosys-args yosys_args] From 5b6b3d01bf2fdfed181a30ab685f7bd8d4845a39 Mon Sep 17 00:00:00 2001 From: KrystalDelusion <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 27 Mar 2025 10:33:51 +1300 Subject: [PATCH 102/133] Update gen-tests-makefile.sh Keep file extensions so that e.g. tribuf.ys and tribuf.sh don't try to output to the same log file. --- tests/gen-tests-makefile.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/gen-tests-makefile.sh b/tests/gen-tests-makefile.sh index 855ebbd9b..e3308506b 100755 --- a/tests/gen-tests-makefile.sh +++ b/tests/gen-tests-makefile.sh @@ -17,20 +17,20 @@ generate_target() { generate_ys_test() { ys_file=$1 yosys_args_=${2:-} - generate_target "$ys_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${ys_file%.*}.err $yosys_args_ $ys_file && mv ${ys_file%.*}.err ${ys_file%.*}.log" + generate_target "$ys_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${ys_file}.err $yosys_args_ $ys_file && mv ${ys_file}.err ${ys_file}.log" } # $ generate_tcl_test tcl_file [yosys_args] generate_tcl_test() { tcl_file=$1 yosys_args_=${2:-} - generate_target "$tcl_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${tcl_file%.*}.err $yosys_args_ $tcl_file && mv ${tcl_file%.*}.err ${tcl_file%.*}.log" + generate_target "$tcl_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${tcl_file}.err $yosys_args_ $tcl_file && mv ${tcl_file}.err ${tcl_file}.log" } # $ generate_bash_test bash_file generate_bash_test() { bash_file=$1 - generate_target "$bash_file" "bash -v $bash_file >${bash_file%.*}.err 2>&1 && mv ${bash_file%.*}.err ${bash_file%.*}.log" + generate_target "$bash_file" "bash -v $bash_file >${bash_file}.err 2>&1 && mv ${bash_file}.err ${bash_file}.log" } # $ generate_tests [-y|--yosys-scripts] [-s|--prove-sv] [-b|--bash] [-a|--yosys-args yosys_args] From c37db637c77e696b226cc3cc75e2543276660e0f Mon Sep 17 00:00:00 2001 From: YRabbit Date: Fri, 28 Mar 2025 06:34:26 +1000 Subject: [PATCH 103/133] Gowin. Remove unnecessary modules Primitives that are not planned for implementation for reasons of belonging to old unsupported chips or representing composite complex IPs rather than primitives are removed. Also latches and large MUXes not planned for implementation. Signed-off-by: YRabbit --- techlibs/gowin/cells_xtra.py | 11 +- techlibs/gowin/cells_xtra_gw1n.v | 721 ---------------------------- techlibs/gowin/cells_xtra_gw2a.v | 561 ---------------------- techlibs/gowin/cells_xtra_gw5a.v | 792 ++----------------------------- 4 files changed, 37 insertions(+), 2048 deletions(-) diff --git a/techlibs/gowin/cells_xtra.py b/techlibs/gowin/cells_xtra.py index 418accdfe..be2e0eff3 100644 --- a/techlibs/gowin/cells_xtra.py +++ b/techlibs/gowin/cells_xtra.py @@ -13,7 +13,8 @@ class State(Enum): IN_MODULE = auto() IN_PARAMETER = auto() -_skip = { 'ALU', 'BANDGAP', 'DFF', 'DFFC', 'DFFCE', 'DFFE', 'DFFN', 'DFFNC', 'DFFNCE', +_skip = { # These are already described, no need to extract them from the vendor files + 'ALU', 'BANDGAP', 'DFF', 'DFFC', 'DFFCE', 'DFFE', 'DFFN', 'DFFNC', 'DFFNCE', 'DFFNE', 'DFFNP', 'DFFNPE', 'DFFNR', 'DFFNRE', 'DFFNS', 'DFFNSE', 'DFFP', 'DFFPE', 'DFFR', 'DFFRE', 'DFFS', 'DFFSE', 'DP', 'DPX9', 'ELVDS_OBUF', 'GND', 'GSR', 'IBUF', 'IDDR', 'IDDRC', 'IDES10', @@ -23,7 +24,13 @@ _skip = { 'ALU', 'BANDGAP', 'DFF', 'DFFC', 'DFFCE', 'DFFE', 'DFFN', 'DFFNC', 'DF 'OSCO', 'OSCW', 'OSCZ', 'OSER10', 'OSER16', 'OSER10', 'OSER4', 'OSER8', 'OVIDEO', 'PLLVR', 'RAM16S1', 'RAM16S2', 'RAM16S4', 'RAM16SDP1', 'RAM16SDP2', 'RAM16SDP4', 'rPLL', 'SDP', - 'SDPX9', 'SP', 'SPX9', 'TBUF', 'TLVDS_OBUF', 'VCC', 'DCS', 'EMCU' + 'SDPX9', 'SP', 'SPX9', 'TBUF', 'TLVDS_OBUF', 'VCC', 'DCS', 'EMCU', + # These are not planned for implementation + 'MUX2_MUX8', 'MUX2_MUX16', 'MUX2_MUX32', 'MUX4', 'MUX8', 'MUX16', + 'MUX32', 'DL', 'DLE', 'DLC', 'DLCE', 'DLP', 'DLPE', 'DLN', 'DLNE', + 'DLNC', 'DLNCE', 'DLNP', 'DLNPE', 'rSDP', 'rSDPX9', 'rROM', 'rROMX9', + 'TLVDS_OEN_BK', 'DLL', 'DCC', 'I3C', 'IODELAYA', 'IODELAYC', 'IODELAYB', + 'SPMI', 'PLLO', 'DCCG', 'MIPI_DPHY_RX', 'CLKDIVG', 'PWRGRD', 'FLASH96KA', } def xtract_cells_decl(dir, fout): fname = os.path.join(dir, 'prim_sim.v') diff --git a/techlibs/gowin/cells_xtra_gw1n.v b/techlibs/gowin/cells_xtra_gw1n.v index ca6afd2e2..abf2c0493 100644 --- a/techlibs/gowin/cells_xtra_gw1n.v +++ b/techlibs/gowin/cells_xtra_gw1n.v @@ -1,53 +1,6 @@ // Created by cells_xtra.py -module MUX2_MUX8 (...); -input I0,I1; -input S0; -output O; -endmodule - - -module MUX2_MUX16 (...); -input I0,I1; -input S0; -output O; -endmodule - - -module MUX2_MUX32 (...); -input I0,I1; -input S0; -output O; -endmodule - - -module MUX4 (...); -input I0, I1, I2, I3; -input S0, S1; -output O; -endmodule - - -module MUX8 (...); -input I0, I1, I2, I3, I4, I5, I6, I7; -input S0, S1, S2; -output O; -endmodule - - -module MUX16 (...); -input I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15; -input S0, S1, S2, S3; -output O; -endmodule - -module MUX32 (...); -input I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31; -input S0, S1, S2, S3, S4; -output O; -endmodule - module LUT5 (...); parameter INIT = 32'h00000000; input I0, I1, I2, I3, I4; @@ -76,90 +29,6 @@ output F; endmodule -module DL (...); -input D, G; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLE (...); -input D, G, CE; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLC (...); -input D, G, CLEAR; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLCE (...); -input D, G, CLEAR, CE; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLP (...); -input D, G, PRESET; -output Q; -parameter INIT = 1'b1; -endmodule - - -module DLPE (...); -input D, G, PRESET, CE; -output Q; -parameter INIT = 1'b1; -endmodule - - -module DLN (...); -input D, G; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLNE (...); -input D, G, CE; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLNC (...); -input D, G, CLEAR; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLNCE (...); -input D, G, CLEAR, CE; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLNP (...); -input D, G, PRESET; -output Q; -parameter INIT = 1'b1; -endmodule - - -module DLNPE (...); -input D, G, PRESET, CE; -output Q; -parameter INIT = 1'b1; -endmodule - - module INV (...); input I; output O; @@ -351,322 +220,6 @@ output [35:0] DO; endmodule -module rSDP (...); -parameter READ_MODE = 1'b0; -parameter BIT_WIDTH_0 = 32; -parameter BIT_WIDTH_1 = 32; -parameter BLK_SEL = 3'b000; -parameter RESET_MODE = "SYNC"; -parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -input CLKA, CEA, CLKB, CEB; -input OCE; -input RESETA, RESETB; -input [13:0] ADA, ADB; -input [31:0] DI; -input [2:0] BLKSEL; -output [31:0] DO; -endmodule - - -module rSDPX9 (...); -parameter READ_MODE = 1'b0; -parameter BIT_WIDTH_0 = 36; -parameter BIT_WIDTH_1 = 36; -parameter BLK_SEL = 3'b000; -parameter RESET_MODE = "SYNC"; -parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -input CLKA, CEA, CLKB, CEB; -input OCE; -input RESETA, RESETB; -input [13:0] ADA, ADB; -input [2:0] BLKSEL; -input [35:0] DI; -output [35:0] DO; -endmodule - - -module rROM (...); -parameter READ_MODE = 1'b0; -parameter BIT_WIDTH = 32; -parameter BLK_SEL = 3'b000; -parameter RESET_MODE = "SYNC"; -parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -input CLK, CE; -input OCE; -input RESET; -input [13:0] AD; -input [2:0] BLKSEL; -output [31:0] DO; -endmodule - - -module rROMX9 (...); -parameter READ_MODE = 1'b0; -parameter BIT_WIDTH = 36; -parameter BLK_SEL = 3'b000; -parameter RESET_MODE = "SYNC"; -parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -input CLK, CE; -input OCE; -input RESET; -input [13:0] AD; -input [2:0] BLKSEL; -output [35:0] DO; -endmodule - - module pROM (...); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 32; @@ -1476,11 +1029,6 @@ inout IO; input I, MODESEL; endmodule -module TLVDS_OEN_BK (...); -input OEN; -parameter OEN_BANK = "0"; -endmodule - module CLKDIV (...); input HCLKIN; input RESETN; @@ -1495,19 +1043,6 @@ input CLKIN,CE; output CLKOUT; endmodule -module DLL (...); -input CLKIN; -input STOP; -input UPDNCNTL; -input RESET; -output [7:0]STEP; -output LOCK; -parameter DLL_FORCE = 0; -parameter CODESCAL="000"; -parameter SCAL_EN="true"; -parameter DIV_SEL = 1'b0; -endmodule - module DLLDLY (...); input CLKIN; input [7:0] DLLSTEP; @@ -1586,13 +1121,6 @@ input HCLKIN, RESETN; output CLKOUT; endmodule -module DCC (...); -output CLKOUT; -input CLKIN; -parameter DCC_EN = 1'b1; -parameter FCLKIN = 50.0; -endmodule - module DHCENC (...); input CLKIN, CE; output CLKOUT, CLKOUTN; @@ -1642,252 +1170,3 @@ parameter IDLE = 4'd0, RD_S1 = 4'd11, RD_S2 = 4'd12; endmodule - -module I3C (...); -parameter ADDRESS = 7'b0000000; -input LGYS, CMS, ACS, AAS, STOPS, STRTS; -output LGYO, CMO, ACO, AAO, SIO, STOPO, STRTO; -input LGYC, CMC, ACC, AAC, SIC, STOPC, STRTC; -input STRTHDS, SENDAHS, SENDALS, ACKHS; -input ACKLS, STOPSUS, STOPHDS, SENDDHS; -input SENDDLS, RECVDHS, RECVDLS, ADDRS; -output PARITYERROR; -input [7:0] DI; -output [7:0] DOBUF; -output [7:0] DO; -output [7:0] STATE; -input SDAI, SCLI; -output SDAO, SCLO; -output SDAOEN, SCLOEN; -output SDAPULLO, SCLPULLO; -output SDAPULLOEN, SCLPULLOEN; -input CE, RESET, CLK; -endmodule - -module IODELAYA (...); -parameter C_STATIC_DLY = 0; -input DI; -input SDTAP; -input SETN; -input VALUE; -output DF; -output DO; -endmodule - -module IODELAYC (...); -parameter C_STATIC_DLY = 0; -parameter DYN_DA_SEL = "false"; -parameter DA_SEL = 2'b00; -input DI; -input SDTAP; -input SETN; -input VALUE; -input [1:0] DASEL; -input [1:0] DAADJ; -output DF; -output DO; -output DAO; -endmodule - - -module SPMI (...); -parameter FUNCTION_CTRL = 7'b0000000; -parameter MSID_CLKSEL = 7'b0000000; -parameter RESPOND_DELAY = 4'b0000; -parameter SCLK_NORMAL_PERIOD = 7'b0000000; -parameter SCLK_LOW_PERIOD = 7'b0000000; -parameter CLK_FREQ = 7'b0000000; -parameter SHUTDOWN_BY_ENABLE = 1'b0; -input CLKEXT, ENEXT; -inout SDATA, SCLK; -input CLK, CE, RESETN, LOCRESET; -input PA, SA, CA; -input [3:0] ADDRI; -input [7:0] DATAI; -output [3:0] ADDRO; -output [7:0] DATAO; -output [15:0] STATE; -output [3:0] CMD; -endmodule - -module IODELAYB (...); -parameter C_STATIC_DLY = 0; -parameter DELAY_MUX = 2'b00; -parameter DA_SEL = 2'b00; -input DI; -input SDTAP; -input SETN; -input VALUE; -input [1:0] DAADJ; -output DF; -output DO; -output DAO; -endmodule - - -module PLLO (...); -input CLKIN; -input CLKFB; -input RESET; -input RESET_P; -input RESET_I; -input RESET_S; -input [5:0] FBDSEL; -input [5:0] IDSEL; -input [6:0] ODSELA; -input [6:0] ODSELB; -input [6:0] ODSELC; -input [6:0] ODSELD; -input [3:0] DTA; -input [3:0] DTB; -input [4:0] ICPSEL; -input [2:0] LPFRES; -input [1:0] PSSEL; -input PSDIR; -input PSPULSE; -input ENCLKA; -input ENCLKB; -input ENCLKC; -input ENCLKD; -output LOCK; -output CLKOUTA; -output CLKOUTB; -output CLKOUTC; -output CLKOUTD; -parameter FCLKIN = "100.0"; -parameter DYN_IDIV_SEL= "FALSE"; -parameter IDIV_SEL = 0; -parameter DYN_FBDIV_SEL= "FALSE"; -parameter FBDIV_SEL = 0; -parameter DYN_ODIVA_SEL= "FALSE"; -parameter ODIVA_SEL = 6; -parameter DYN_ODIVB_SEL= "FALSE"; -parameter ODIVB_SEL = 6; -parameter DYN_ODIVC_SEL= "FALSE"; -parameter ODIVC_SEL = 6; -parameter DYN_ODIVD_SEL= "FALSE"; -parameter ODIVD_SEL = 6; -parameter CLKOUTA_EN = "TRUE"; -parameter CLKOUTB_EN = "TRUE"; -parameter CLKOUTC_EN = "TRUE"; -parameter CLKOUTD_EN = "TRUE"; -parameter DYN_DTA_SEL = "FALSE"; -parameter DYN_DTB_SEL = "FALSE"; -parameter CLKOUTA_DT_DIR = 1'b1; -parameter CLKOUTB_DT_DIR = 1'b1; -parameter CLKOUTA_DT_STEP = 0; -parameter CLKOUTB_DT_STEP = 0; -parameter CLKA_IN_SEL = 2'b00; -parameter CLKA_OUT_SEL = 1'b0; -parameter CLKB_IN_SEL = 2'b00; -parameter CLKB_OUT_SEL = 1'b0; -parameter CLKC_IN_SEL = 2'b00; -parameter CLKC_OUT_SEL = 1'b0; -parameter CLKD_IN_SEL = 2'b00; -parameter CLKD_OUT_SEL = 1'b0; -parameter CLKFB_SEL = "INTERNAL"; -parameter DYN_DPA_EN = "FALSE"; -parameter DYN_PSB_SEL = "FALSE"; -parameter DYN_PSC_SEL = "FALSE"; -parameter DYN_PSD_SEL = "FALSE"; -parameter PSB_COARSE = 1; -parameter PSB_FINE = 0; -parameter PSC_COARSE = 1; -parameter PSC_FINE = 0; -parameter PSD_COARSE = 1; -parameter PSD_FINE = 0; -parameter DTMS_ENB = "FALSE"; -parameter DTMS_ENC = "FALSE"; -parameter DTMS_END = "FALSE"; -parameter RESET_I_EN = "FALSE"; -parameter RESET_S_EN = "FALSE"; -parameter DYN_ICP_SEL= "FALSE"; -parameter ICP_SEL = 5'bXXXXX; -parameter DYN_RES_SEL= "FALSE"; -parameter LPR_REF = 7'bXXXXXXX; -endmodule - -module DCCG (...); -output CLKOUT; -input CLKIN; -parameter DCC_MODE = 2'b00; -parameter FCLKIN = 50.0; -endmodule - -module FLASH96KA (...); -input[5:0]XADR; -input[5:0]YADR; -input XE,YE,SE; -input ERASE,PROG,NVSTR; -input [31:0] DIN; -input SLEEP; -output reg [31:0] DOUT; -parameter IDLE = 4'd0, - ERA_S1 = 4'd1, - ERA_S2 = 4'd2, - ERA_S3 = 4'd3, - ERA_S4 = 4'd4, - ERA_S5 = 4'd5, - PRO_S1 = 4'd6, - PRO_S2 = 4'd7, - PRO_S3 = 4'd8, - PRO_S4 = 4'd9, - PRO_S5 = 4'd10, - RD_S1 = 4'd11, - RD_S2 = 4'd12; -endmodule - -module MIPI_DPHY_RX (...); -output [15:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD; -output D0LN_HSRXD_VLD,D1LN_HSRXD_VLD,D2LN_HSRXD_VLD,D3LN_HSRXD_VLD; -output DI_LPRX0_N, DI_LPRX0_P, DI_LPRX1_N, DI_LPRX1_P, DI_LPRX2_N, DI_LPRX2_P, DI_LPRX3_N, DI_LPRX3_P; -output DI_LPRXCK_N, DI_LPRXCK_P; -output RX_CLK_O; -output DESKEW_ERROR; -inout CK_N, CK_P, RX0_N, RX0_P, RX1_N, RX1_P, RX2_N, RX2_P, RX3_N, RX3_P; -input LPRX_EN_CK, LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2, LPRX_EN_D3; -input HSRX_ODTEN_CK, HSRX_ODTEN_D0, HSRX_ODTEN_D1, HSRX_ODTEN_D2, HSRX_ODTEN_D3; -input D0LN_HSRX_DREN, D1LN_HSRX_DREN, D2LN_HSRX_DREN, D3LN_HSRX_DREN; -input HSRX_EN_CK; -input HS_8BIT_MODE; -input RX_CLK_1X; -input RX_INVERT; -input LALIGN_EN; -input WALIGN_BY; -input DO_LPTX0_N, DO_LPTX0_P, DO_LPTX1_N, DO_LPTX1_P, DO_LPTX2_N, DO_LPTX2_P, DO_LPTX3_N, DO_LPTX3_P; -input DO_LPTXCK_N, DO_LPTXCK_P; -input LPTX_EN_CK, LPTX_EN_D0, LPTX_EN_D1, LPTX_EN_D2, LPTX_EN_D3; -input BYTE_LENDIAN; -input HSRX_STOP; -input LPRX_ULP_LN0, LPRX_ULP_LN1, LPRX_ULP_LN2, LPRX_ULP_LN3, LPRX_ULP_CK; -input PWRON; -input RESET; -input [2:0] DESKEW_LNSEL; -input [7:0] DESKEW_MTH; -input [6:0] DESKEW_OWVAL; -input DESKEW_REQ; -input DRST_N; -input ONE_BYTE0_MATCH; -input WORD_LENDIAN; -input [2:0] FIFO_RD_STD; -parameter ALIGN_BYTE = 8'b10111000; -parameter MIPI_LANE0_EN = 1'b0; -parameter MIPI_LANE1_EN = 1'b0; -parameter MIPI_LANE2_EN = 1'b0; -parameter MIPI_LANE3_EN = 1'b0; -parameter MIPI_CK_EN = 1'b1; -parameter SYNC_CLK_SEL = 1'b0; -endmodule - -module CLKDIVG (...); -input CLKIN; -input RESETN; -input CALIB; -output CLKOUT; -parameter DIV_MODE = "2"; -parameter GSREN = "false"; -endmodule - -module PWRGRD (...); -input PDEN; -endmodule diff --git a/techlibs/gowin/cells_xtra_gw2a.v b/techlibs/gowin/cells_xtra_gw2a.v index 84c08c6cb..5c365f8da 100644 --- a/techlibs/gowin/cells_xtra_gw2a.v +++ b/techlibs/gowin/cells_xtra_gw2a.v @@ -1,53 +1,6 @@ // Created by cells_xtra.py -module MUX2_MUX8 (...); -input I0,I1; -input S0; -output O; -endmodule - - -module MUX2_MUX16 (...); -input I0,I1; -input S0; -output O; -endmodule - - -module MUX2_MUX32 (...); -input I0,I1; -input S0; -output O; -endmodule - - -module MUX4 (...); -input I0, I1, I2, I3; -input S0, S1; -output O; -endmodule - - -module MUX8 (...); -input I0, I1, I2, I3, I4, I5, I6, I7; -input S0, S1, S2; -output O; -endmodule - - -module MUX16 (...); -input I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15; -input S0, S1, S2, S3; -output O; -endmodule - -module MUX32 (...); -input I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31; -input S0, S1, S2, S3, S4; -output O; -endmodule - module LUT5 (...); parameter INIT = 32'h00000000; input I0, I1, I2, I3, I4; @@ -76,90 +29,6 @@ output F; endmodule -module DL (...); -input D, G; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLE (...); -input D, G, CE; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLC (...); -input D, G, CLEAR; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLCE (...); -input D, G, CLEAR, CE; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLP (...); -input D, G, PRESET; -output Q; -parameter INIT = 1'b1; -endmodule - - -module DLPE (...); -input D, G, PRESET, CE; -output Q; -parameter INIT = 1'b1; -endmodule - - -module DLN (...); -input D, G; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLNE (...); -input D, G, CE; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLNC (...); -input D, G, CLEAR; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLNCE (...); -input D, G, CLEAR, CE; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLNP (...); -input D, G, PRESET; -output Q; -parameter INIT = 1'b1; -endmodule - - -module DLNPE (...); -input D, G, PRESET, CE; -output Q; -parameter INIT = 1'b1; -endmodule - - module INV (...); input I; output O; @@ -421,322 +290,6 @@ output [35:0] DO; endmodule -module rSDP (...); -parameter READ_MODE = 1'b0; -parameter BIT_WIDTH_0 = 32; -parameter BIT_WIDTH_1 = 32; -parameter BLK_SEL = 3'b000; -parameter RESET_MODE = "SYNC"; -parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -input CLKA, CEA, CLKB, CEB; -input OCE; -input RESETA, RESETB; -input [13:0] ADA, ADB; -input [31:0] DI; -input [2:0] BLKSEL; -output [31:0] DO; -endmodule - - -module rSDPX9 (...); -parameter READ_MODE = 1'b0; -parameter BIT_WIDTH_0 = 36; -parameter BIT_WIDTH_1 = 36; -parameter BLK_SEL = 3'b000; -parameter RESET_MODE = "SYNC"; -parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -input CLKA, CEA, CLKB, CEB; -input OCE; -input RESETA, RESETB; -input [13:0] ADA, ADB; -input [2:0] BLKSEL; -input [35:0] DI; -output [35:0] DO; -endmodule - - -module rROM (...); -parameter READ_MODE = 1'b0; -parameter BIT_WIDTH = 32; -parameter BLK_SEL = 3'b000; -parameter RESET_MODE = "SYNC"; -parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -input CLK, CE; -input OCE; -input RESET; -input [13:0] AD; -input [2:0] BLKSEL; -output [31:0] DO; -endmodule - - -module rROMX9 (...); -parameter READ_MODE = 1'b0; -parameter BIT_WIDTH = 36; -parameter BLK_SEL = 3'b000; -parameter RESET_MODE = "SYNC"; -parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; -input CLK, CE; -input OCE; -input RESET; -input [13:0] AD; -input [2:0] BLKSEL; -output [35:0] DO; -endmodule - - module pROM (...); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 32; @@ -1505,19 +1058,6 @@ inout IO, IOB; input I, OEN; endmodule -module DLL (...); -input CLKIN; -input STOP; -input UPDNCNTL; -input RESET; -output [7:0]STEP; -output LOCK; -parameter DLL_FORCE = 0; -parameter CODESCAL="000"; -parameter SCAL_EN="true"; -parameter DIV_SEL = 1'b0; -endmodule - module CLKDIV (...); input HCLKIN; input RESETN; @@ -1567,16 +1107,6 @@ input HCLKIN, RESETN; output CLKOUT; endmodule -module IODELAYA (...); -parameter C_STATIC_DLY = 0; -input DI; -input SDTAP; -input SETN; -input VALUE; -output DF; -output DO; -endmodule - module IBUF_R (...); input I; input RTEN; @@ -1613,97 +1143,6 @@ input [23:0] SPIAD; input LOADN_SPIAD; endmodule -module CLKDIVG (...); -input CLKIN; -input RESETN; -input CALIB; -output CLKOUT; -parameter DIV_MODE = "2"; -parameter GSREN = "false"; -endmodule - -module PLLO (...); -input CLKIN; -input CLKFB; -input RESET; -input RESET_P; -input RESET_I; -input RESET_S; -input [5:0] FBDSEL; -input [5:0] IDSEL; -input [6:0] ODSELA; -input [6:0] ODSELB; -input [6:0] ODSELC; -input [6:0] ODSELD; -input [3:0] DTA; -input [3:0] DTB; -input [4:0] ICPSEL; -input [2:0] LPFRES; -input [1:0] PSSEL; -input PSDIR; -input PSPULSE; -input ENCLKA; -input ENCLKB; -input ENCLKC; -input ENCLKD; -output LOCK; -output CLKOUTA; -output CLKOUTB; -output CLKOUTC; -output CLKOUTD; -parameter FCLKIN = "100.0"; -parameter DYN_IDIV_SEL= "FALSE"; -parameter IDIV_SEL = 0; -parameter DYN_FBDIV_SEL= "FALSE"; -parameter FBDIV_SEL = 0; -parameter DYN_ODIVA_SEL= "FALSE"; -parameter ODIVA_SEL = 6; -parameter DYN_ODIVB_SEL= "FALSE"; -parameter ODIVB_SEL = 6; -parameter DYN_ODIVC_SEL= "FALSE"; -parameter ODIVC_SEL = 6; -parameter DYN_ODIVD_SEL= "FALSE"; -parameter ODIVD_SEL = 6; -parameter CLKOUTA_EN = "TRUE"; -parameter CLKOUTB_EN = "TRUE"; -parameter CLKOUTC_EN = "TRUE"; -parameter CLKOUTD_EN = "TRUE"; -parameter DYN_DTA_SEL = "FALSE"; -parameter DYN_DTB_SEL = "FALSE"; -parameter CLKOUTA_DT_DIR = 1'b1; -parameter CLKOUTB_DT_DIR = 1'b1; -parameter CLKOUTA_DT_STEP = 0; -parameter CLKOUTB_DT_STEP = 0; -parameter CLKA_IN_SEL = 2'b00; -parameter CLKA_OUT_SEL = 1'b0; -parameter CLKB_IN_SEL = 2'b00; -parameter CLKB_OUT_SEL = 1'b0; -parameter CLKC_IN_SEL = 2'b00; -parameter CLKC_OUT_SEL = 1'b0; -parameter CLKD_IN_SEL = 2'b00; -parameter CLKD_OUT_SEL = 1'b0; -parameter CLKFB_SEL = "INTERNAL"; -parameter DYN_DPA_EN = "FALSE"; -parameter DYN_PSB_SEL = "FALSE"; -parameter DYN_PSC_SEL = "FALSE"; -parameter DYN_PSD_SEL = "FALSE"; -parameter PSB_COARSE = 1; -parameter PSB_FINE = 0; -parameter PSC_COARSE = 1; -parameter PSC_FINE = 0; -parameter PSD_COARSE = 1; -parameter PSD_FINE = 0; -parameter DTMS_ENB = "FALSE"; -parameter DTMS_ENC = "FALSE"; -parameter DTMS_END = "FALSE"; -parameter RESET_I_EN = "FALSE"; -parameter RESET_S_EN = "FALSE"; -parameter DYN_ICP_SEL= "FALSE"; -parameter ICP_SEL = 5'bXXXXX; -parameter DYN_RES_SEL= "FALSE"; -parameter LPR_REF = 7'bXXXXXXX; -endmodule - module ELVDS_IBUF_MIPI (...); output OH, OL; input I, IB; diff --git a/techlibs/gowin/cells_xtra_gw5a.v b/techlibs/gowin/cells_xtra_gw5a.v index 3a9766a93..d19435f85 100644 --- a/techlibs/gowin/cells_xtra_gw5a.v +++ b/techlibs/gowin/cells_xtra_gw5a.v @@ -1,53 +1,6 @@ // Created by cells_xtra.py -module MUX2_MUX8 (...); -input I0,I1; -input S0; -output O; -endmodule - - -module MUX2_MUX16 (...); -input I0,I1; -input S0; -output O; -endmodule - - -module MUX2_MUX32 (...); -input I0,I1; -input S0; -output O; -endmodule - - -module MUX4 (...); -input I0, I1, I2, I3; -input S0, S1; -output O; -endmodule - - -module MUX8 (...); -input I0, I1, I2, I3, I4, I5, I6, I7; -input S0, S1, S2; -output O; -endmodule - - -module MUX16 (...); -input I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15; -input S0, S1, S2, S3; -output O; -endmodule - -module MUX32 (...); -input I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31; -input S0, S1, S2, S3, S4; -output O; -endmodule - module LUT5 (...); parameter INIT = 32'h00000000; input I0, I1, I2, I3, I4; @@ -76,20 +29,6 @@ output F; endmodule -module DLCE (...); -input D, G, CLEAR, GE; -output Q; -parameter INIT = 1'b0; -endmodule - - -module DLPE (...); -input D, G, PRESET, GE; -output Q; -parameter INIT = 1'b1; -endmodule - - module ROM16 (...); parameter INIT_0 = 16'h0000; input [3:0] AD; @@ -141,8 +80,19 @@ endmodule module MIPI_OBUF_A (...); output O, OB; input I, IB, IL, MODESEL; -inout IO, IOB; -input OEN, OENB; +endmodule + +module IBUF_R (...); +input I; +input RTEN; +output O; +endmodule + +module IOBUF_R (...); +input I,OEN; +input RTEN; +output O; +inout IO; endmodule module ELVDS_IOBUF_R (...); @@ -163,21 +113,6 @@ input I, IB; input ADCEN; endmodule -module MIPI_CPHY_IBUF (...); -output OH0, OL0, OB0, OH1, OL1, OB1, OH2, OL2, OB2; -inout IO0, IOB0, IO1, IOB1, IO2, IOB2; -input I0, IB0, I1, IB1, I2, IB2; -input OEN, OENB; -input HSEN; -endmodule - -module MIPI_CPHY_OBUF (...); -output O0, OB0, O1, OB1, O2, OB2; -input I0, IB0, IL0, I1, IB1, IL1, I2, IB2, IL2; -inout IO0, IOB0, IO1, IOB1, IO2, IOB2; -input OEN, OENB, MODESEL, VCOME; -endmodule - module SDPB (...); parameter READ_MODE = 1'b0; parameter BIT_WIDTH_0 = 32; @@ -663,8 +598,8 @@ endmodule module SDP36KE (...); -parameter ECC_WRITE_EN="TRUE"; -parameter ECC_READ_EN="TRUE"; +parameter ECC_WRITE_EN="FALSE"; +parameter ECC_READ_EN="FALSE"; parameter READ_MODE = 1'b0; parameter BLK_SEL_A = 3'b000; parameter BLK_SEL_B = 3'b000; @@ -829,14 +764,6 @@ output [7:0] ECCP; endmodule -module SDP136K (...); -input CLKA, CLKB; -input WE, RE; -input [10:0] ADA, ADB; -input [67:0] DI; -output [67:0] DO; -endmodule - module MULTADDALU12X12 (...); parameter A0REG_CLK = "BYPASS"; parameter A0REG_CE = "CE0"; @@ -1053,24 +980,6 @@ input PSEL; input PADDSUB; endmodule -module MULTACC (...); -output [23:0] DATAO, CASO; -input CE, CLK; -input [5:0] COFFIN0, COFFIN1, COFFIN2; -input [9:0] DATAIN0, DATAIN1; -input [9:0] DATAIN2; -input RSTN; -input [23:0] CASI; -parameter COFFIN_WIDTH = 4; -parameter DATAIN_WIDTH = 8; -parameter IREG = 1'b0; -parameter OREG = 1'b0; -parameter PREG = 1'b0; -parameter ACC_EN = "FALSE"; -parameter CASI_EN = "FALSE"; -parameter CASO_EN = "FALSE"; -endmodule - module IDDR_MEM (...); input D, ICLK, PCLK; input [2:0] WADDR; @@ -1157,39 +1066,13 @@ output [31:0] Q; input D; input PCLK, FCLKP, FCLKN, FCLKQP, FCLKQN; input RESET; -output DF0, DF1; -input SDTAP0, SDTAP1; -input VALUE0,VALUE1; -input [7:0] DLYSTEP0,DLYSTEP1; -parameter C_STATIC_DLY_0 = 0; -parameter DYN_DLY_EN_0 = "FALSE"; -parameter ADAPT_EN_0 = "FALSE"; -parameter C_STATIC_DLY_1 = 0; -parameter DYN_DLY_EN_1 = "FALSE"; -parameter ADAPT_EN_1 = "FALSE"; -endmodule - -module OSIDES64 (...); -output [63:0] Q; -input D; -input PCLK, FCLKP, FCLKN, FCLKQP, FCLKQN; -input RESET; -output DF0, DF1, DF2, DF3; -input SDTAP0, SDTAP1, SDTAP2, SDTAP3; -input VALUE0, VALUE1, VALUE2, VALUE3; -input [7:0] DLYSTEP0, DLYSTEP1, DLYSTEP2, DLYSTEP3; -parameter C_STATIC_DLY_0 = 0; -parameter DYN_DLY_EN_0 = "FALSE"; -parameter ADAPT_EN_0 = "FALSE"; -parameter C_STATIC_DLY_1 = 0; -parameter DYN_DLY_EN_1 = "FALSE"; -parameter ADAPT_EN_1 = "FALSE"; -parameter C_STATIC_DLY_2 = 0; -parameter DYN_DLY_EN_2 = "FALSE"; -parameter ADAPT_EN_2 = "FALSE"; -parameter C_STATIC_DLY_3 = 0; -parameter DYN_DLY_EN_3 = "FALSE"; -parameter ADAPT_EN_3 = "FALSE"; +output DF; +input SDTAP; +input VALUE; +input [7:0] DLYSTEP; +parameter C_STATIC_DLY = 0; +parameter DYN_DLY_EN = "FALSE"; +parameter ADAPT_EN = "FALSE"; endmodule module DCE (...); @@ -1249,17 +1132,6 @@ output OSCOUT; input OSCEN; endmodule -module OSCB (...); -parameter FREQ_MODE = "25"; -parameter FREQ_DIV = 10; -parameter DYN_TRIM_EN = "FALSE"; -output OSCOUT; -output OSCREF; -input OSCEN, FMODE; -input [7:0] RTRIM; -input [5:0] RTCTRIM; -endmodule - module PLL (...); input CLKIN; input CLKFB; @@ -1699,8 +1571,8 @@ input ADWSEL; endmodule module OTP (...); -parameter MODE = 2'b01; -input CLK, READ, SHIFT; +parameter MODE = 1'b0; +input READ, SHIFT; output DOUT; endmodule @@ -1743,31 +1615,6 @@ input ERR0INJECT,ERR1INJECT; input [6:0] ERRINJ0LOC,ERRINJ1LOC; endmodule -module CMSERB (...); -output RUNNING; -output CRCERR; -output CRCDONE; -output ECCCORR; -output ECCUNCORR; -output [12:0] ERRLOC; -output ECCDEC; -output DSRRD; -output DSRWR; -output ASRRESET; -output ASRINC; -output REFCLK; -input CLK; -input [2:0] SEREN; -input ERR0INJECT,ERR1INJECT; -input [6:0] ERRINJ0LOC,ERRINJ1LOC; -endmodule - -module SAMBA (...); -parameter MODE = 2'b00; -input SPIAD; -input LOAD; -endmodule - module ADCLRC (...); endmodule @@ -1777,150 +1624,6 @@ endmodule module ADC (...); endmodule -module MIPI_DPHY_RX (...); -output D0LN_DESKEW_DONE,D1LN_DESKEW_DONE,D2LN_DESKEW_DONE,D3LN_DESKEW_DONE; -output [15:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD; -output D0LN_HSRXD_VLD,D1LN_HSRXD_VLD,D2LN_HSRXD_VLD,D3LN_HSRXD_VLD; -output DI_LPRX0_N, DI_LPRX0_P, DI_LPRX1_N, DI_LPRX1_P, DI_LPRX2_N, DI_LPRX2_P, DI_LPRX3_N, DI_LPRX3_P; -output DI_LPRXCK_N, DI_LPRXCK_P; -output RX_CLK_O; -output DESKEW_ERROR; -inout CK_N, CK_P, RX0_N, RX0_P, RX1_N, RX1_P, RX2_N, RX2_P, RX3_N, RX3_P; -input BYTE_LENDIAN; -input [2:0] FIFO_RD_STD; -input HSRX_STOP; -input PWRON; -input RESET; -input D0LN_HSRX_DREN, D1LN_HSRX_DREN, D2LN_HSRX_DREN, D3LN_HSRX_DREN; -input DESKEW_BY,DESKEW_EN_OEDGE; -input [5:0] DESKEW_HALF_OPENING; -input [2:0] DESKEW_LNSEL; -input [1:0] DESKEW_LSB_MODE; -input [2:0] DESKEW_M; -input [12:0] DESKEW_MTH; -input [6:0] DESKEW_MSET; -input DESKEW_OCLKEDG_EN; -input [6:0] DESKEW_OWVAL; -input DESKEW_REQ; -input DO_LPTX0_N, DO_LPTX0_P, DO_LPTX1_N, DO_LPTX1_P, DO_LPTX2_N, DO_LPTX2_P, DO_LPTX3_N, DO_LPTX3_P; -input DO_LPTXCK_N, DO_LPTXCK_P; -input DRST_N; -input [2:0] EQCS_LANE0,EQCS_LANE1,EQCS_LANE2,EQCS_LANE3,EQCS_CK; -input [2:0] EQRS_LANE0,EQRS_LANE1,EQRS_LANE2,EQRS_LANE3,EQRS_CK; -input HS_8BIT_MODE; -input HSRX_DLYDIR_LANE0, HSRX_DLYDIR_LANE1,HSRX_DLYDIR_LANE2,HSRX_DLYDIR_LANE3,HSRX_DLYDIR_CK; -input HSRX_DLYLDN_LANE0, HSRX_DLYLDN_LANE1,HSRX_DLYLDN_LANE2,HSRX_DLYLDN_LANE3,HSRX_DLYLDN_CK; -input HSRX_DLYMV_LANE0, HSRX_DLYMV_LANE1,HSRX_DLYMV_LANE2,HSRX_DLYMV_LANE3,HSRX_DLYMV_CK; -input HSRX_EN_CK; -input HSRX_ODTEN_CK, HSRX_ODTEN_D0, HSRX_ODTEN_D1, HSRX_ODTEN_D2, HSRX_ODTEN_D3; -input LALIGN_EN; -input LPRX_EN_CK, LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2, LPRX_EN_D3; -input LPTX_EN_CK, LPTX_EN_D0, LPTX_EN_D1, LPTX_EN_D2, LPTX_EN_D3; -input ONE_BYTE0_MATCH; -input RX_CLK_1X; -input RX_INVERT; -input WALIGN_BY; -input WALIGN_DVLD; -input WORD_LENDIAN; -parameter ALIGN_BYTE = 8'b10111000; -parameter EN_CLKB1X = 1'b1; -parameter EQ_ADPSEL_LANE0 = 1'b0; -parameter EQ_ADPSEL_LANE1 = 1'b0; -parameter EQ_ADPSEL_LANE2 = 1'b0; -parameter EQ_ADPSEL_LANE3 = 1'b0; -parameter EQ_ADPSEL_CK = 1'b0; -parameter EQ_CS_LANE0 = 3'b100; -parameter EQ_CS_LANE1 = 3'b100; -parameter EQ_CS_LANE2 = 3'b100; -parameter EQ_CS_LANE3 = 3'b100; -parameter EQ_CS_CK = 3'b100; -parameter EQ_PBIAS_LANE0 = 4'b0100; -parameter EQ_PBIAS_LANE1 = 4'b0100; -parameter EQ_PBIAS_LANE2 = 4'b0100; -parameter EQ_PBIAS_LANE3 = 4'b0100; -parameter EQ_PBIAS_CK = 4'b0100; -parameter EQ_RS_LANE0 = 3'b100; -parameter EQ_RS_LANE1 = 3'b100; -parameter EQ_RS_LANE2 = 3'b100; -parameter EQ_RS_LANE3 = 3'b100; -parameter EQ_RS_CK = 3'b100; -parameter EQ_ZLD_LANE0 = 4'b1000; -parameter EQ_ZLD_LANE1 = 4'b1000; -parameter EQ_ZLD_LANE2 = 4'b1000; -parameter EQ_ZLD_LANE3 = 4'b1000; -parameter EQ_ZLD_CK = 4'b1000; -parameter HIGH_BW_LANE0 = 1'b1; -parameter HIGH_BW_LANE1 = 1'b1; -parameter HIGH_BW_LANE2 = 1'b1; -parameter HIGH_BW_LANE3 = 1'b1; -parameter HIGH_BW_CK = 1'b1; -parameter HSRX_DLYCTL_CK = 7'b0000000; -parameter HSRX_DLYCTL_LANE0 = 7'b0000000; -parameter HSRX_DLYCTL_LANE1 = 7'b0000000; -parameter HSRX_DLYCTL_LANE2 = 7'b0000000; -parameter HSRX_DLYCTL_LANE3 = 7'b0000000; -parameter HSRX_DLY_SEL = 1'b0; -parameter HSRX_DUTY_LANE0 = 4'b1000; -parameter HSRX_DUTY_LANE1 = 4'b1000; -parameter HSRX_DUTY_LANE2 = 4'b1000; -parameter HSRX_DUTY_LANE3 = 4'b1000; -parameter HSRX_DUTY_CK = 4'b1000; -parameter HSRX_EN = 1'b1; -parameter HSRX_EQ_EN_LANE0 = 1'b1; -parameter HSRX_EQ_EN_LANE1 = 1'b1; -parameter HSRX_EQ_EN_LANE2 = 1'b1; -parameter HSRX_EQ_EN_LANE3 = 1'b1; -parameter HSRX_EQ_EN_CK = 1'b1; -parameter HSRX_IBIAS = 4'b0011; -parameter HSRX_IMARG_EN = 1'b1; -parameter MIPI_LANE0_EN = 1'b0; -parameter MIPI_LANE1_EN = 1'b0; -parameter MIPI_LANE2_EN = 1'b0; -parameter MIPI_LANE3_EN = 1'b0; -parameter MIPI_CK_EN = 1'b1; -parameter HSRX_ODT_EN = 1'b1; -parameter HSRX_ODT_TST = 4'b0000; -parameter HSRX_ODT_TST_CK = 1'b0; -parameter HSRX_STOP_EN = 1'b0; -parameter HSRX_TST = 4'b0000; -parameter HSRX_TST_CK = 1'b0; -parameter HSRX_WAIT4EDGE = 1'b0; -parameter HYST_NCTL = 2'b01; -parameter HYST_PCTL = 2'b01; -parameter LOW_LPRX_VTH = 1'b0; -parameter LPRX_EN = 1'b1; -parameter LPRX_TST = 4'b0000; -parameter LPRX_TST_CK = 1'b0; -parameter LPTX_EN = 1'b1; -parameter LPTX_SW_LANE0 = 3'b100; -parameter LPTX_SW_LANE1 = 3'b100; -parameter LPTX_SW_LANE2 = 3'b100; -parameter LPTX_SW_LANE3 = 3'b100; -parameter LPTX_SW_CK = 3'b100; -parameter LPTX_TST = 4'b0000; -parameter LPTX_TST_CK = 1'b0; -parameter MIPI_DIS_N = 1'b1; -parameter PGA_BIAS_LANE0 = 4'b1000; -parameter PGA_BIAS_LANE1 = 4'b1000; -parameter PGA_BIAS_LANE2 = 4'b1000; -parameter PGA_BIAS_LANE3 = 4'b1000; -parameter PGA_BIAS_CK = 4'b1000; -parameter PGA_GAIN_LANE0 = 4'b1000; -parameter PGA_GAIN_LANE1 = 4'b1000; -parameter PGA_GAIN_LANE2 = 4'b1000; -parameter PGA_GAIN_LANE3 = 4'b1000; -parameter PGA_GAIN_CK = 4'b1000; -parameter RX_CLK1X_SYNC_SEL = 1'b0; -parameter RX_ODT_TRIM_LANE0 = 4'b0111; -parameter RX_ODT_TRIM_LANE1 = 4'b0111; -parameter RX_ODT_TRIM_LANE2 = 4'b0111; -parameter RX_ODT_TRIM_LANE3 = 4'b0111; -parameter RX_ODT_TRIM_CK = 4'b0111; -parameter STP_UNIT = 2'b00; -parameter SYNC_CLK_SEL = 1'b1; -parameter WALIGN_DVLD_SRC_SEL = 1'b0; -endmodule - module MIPI_DPHY (...); output RX_CLK_O, TX_CLK_O; output [15:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD; @@ -1928,14 +1631,14 @@ output D0LN_HSRXD_VLD,D1LN_HSRXD_VLD,D2LN_HSRXD_VLD,D3LN_HSRXD_VLD; input D0LN_HSRX_DREN, D1LN_HSRX_DREN, D2LN_HSRX_DREN, D3LN_HSRX_DREN; output DI_LPRX0_N, DI_LPRX0_P, DI_LPRX1_N, DI_LPRX1_P, DI_LPRX2_N, DI_LPRX2_P, DI_LPRX3_N, DI_LPRX3_P, DI_LPRXCK_N, DI_LPRXCK_P; inout CK_N, CK_P, D0_N, D0_P, D1_N, D1_P, D2_N, D2_P, D3_N, D3_P; -input HSRX_STOP, HSTXEN_LN0, HSTXEN_LN1, HSTXEN_LN2, HSTXEN_LN3, HSTXEN_LNCK; +input HSRX_STOP, HSTXEN_LN0, HSTXEN_LN1, HSTXEN_LN2, HSTXEN_LN3, HSTXEN_LNCK, input PWRON_RX, PWRON_TX, RESET, RX_CLK_1X, TX_CLK_1X; input TXDPEN_LN0, TXDPEN_LN1, TXDPEN_LN2, TXDPEN_LN3, TXDPEN_LNCK, TXHCLK_EN; input [15:0] CKLN_HSTXD,D0LN_HSTXD,D1LN_HSTXD,D2LN_HSTXD,D3LN_HSTXD; input HSTXD_VLD; input CK0, CK90, CK180, CK270; input DO_LPTX0_N, DO_LPTX1_N, DO_LPTX2_N, DO_LPTX3_N, DO_LPTXCK_N, DO_LPTX0_P, DO_LPTX1_P, DO_LPTX2_P, DO_LPTX3_P, DO_LPTXCK_P; -input HSRX_EN_CK, HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2, HSRX_EN_D3, HSRX_ODTEN_CK; +input HSRX_EN_CK, HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2, HSRX_EN_D3, HSRX_ODTEN_CK, input RX_DRST_N, TX_DRST_N, WALIGN_DVLD; output [7:0] MRDATA; input MA_INC, MCLK; @@ -2011,7 +1714,7 @@ parameter RX_RD_START_DEPTH = 5'b00001; parameter RX_SYNC_MODE = 1'b0 ; parameter RX_WORD_ALIGN_BYPASS = 1'b0 ; parameter RX_WORD_ALIGN_DATA_VLD_SRC_SEL = 1'b0 ; -parameter RX_WORD_LITTLE_ENDIAN = 1'b1 ; +parameter RX_WORD_LITTLE_ENDIAN = 1'b0 ; parameter TX_BYPASS_MODE = 1'b0 ; parameter TX_BYTECLK_SYNC_MODE = 1'b0 ; parameter TX_OCLK_USE_CIBCLK = 1'b0 ; @@ -2214,434 +1917,6 @@ parameter TEST_P_IMP_LN3 = 1'b0 ; parameter TEST_P_IMP_LNCK = 1'b0 ; endmodule -module MIPI_DPHYA (...); -output RX_CLK_O, TX_CLK_O; -output [15:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD; -output D0LN_HSRXD_VLD,D1LN_HSRXD_VLD,D2LN_HSRXD_VLD,D3LN_HSRXD_VLD; -input D0LN_HSRX_DREN, D1LN_HSRX_DREN, D2LN_HSRX_DREN, D3LN_HSRX_DREN; -output DI_LPRX0_N, DI_LPRX0_P, DI_LPRX1_N, DI_LPRX1_P, DI_LPRX2_N, DI_LPRX2_P, DI_LPRX3_N, DI_LPRX3_P, DI_LPRXCK_N, DI_LPRXCK_P; -inout CK_N, CK_P, D0_N, D0_P, D1_N, D1_P, D2_N, D2_P, D3_N, D3_P; -input HSRX_STOP, HSTXEN_LN0, HSTXEN_LN1, HSTXEN_LN2, HSTXEN_LN3, HSTXEN_LNCK; -input PWRON_RX, PWRON_TX, RESET, RX_CLK_1X, TX_CLK_1X; -input TXDPEN_LN0, TXDPEN_LN1, TXDPEN_LN2, TXDPEN_LN3, TXDPEN_LNCK, TXHCLK_EN; -input [15:0] CKLN_HSTXD,D0LN_HSTXD,D1LN_HSTXD,D2LN_HSTXD,D3LN_HSTXD; -input HSTXD_VLD; -input CK0, CK90, CK180, CK270; -input DO_LPTX0_N, DO_LPTX1_N, DO_LPTX2_N, DO_LPTX3_N, DO_LPTXCK_N, DO_LPTX0_P, DO_LPTX1_P, DO_LPTX2_P, DO_LPTX3_P, DO_LPTXCK_P; -input HSRX_EN_CK, HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2, HSRX_EN_D3, HSRX_ODTEN_CK; -input RX_DRST_N, TX_DRST_N, WALIGN_DVLD; -output [7:0] MRDATA; -input MA_INC, MCLK; -input [1:0] MOPCODE; -input [7:0] MWDATA; -input SPLL_CKN, SPLL_CKP; -output ALPEDO_LANE0, ALPEDO_LANE1, ALPEDO_LANE2, ALPEDO_LANE3, ALPEDO_LANECK; -output D1LN_DESKEW_DONE,D2LN_DESKEW_DONE,D3LN_DESKEW_DONE,D0LN_DESKEW_DONE; -output D1LN_DESKEW_ERROR, D2LN_DESKEW_ERROR, D3LN_DESKEW_ERROR, D0LN_DESKEW_ERROR; -input D0LN_DESKEW_REQ, D1LN_DESKEW_REQ, D2LN_DESKEW_REQ, D3LN_DESKEW_REQ; -input HSRX_DLYDIR_LANE0, HSRX_DLYDIR_LANE1, HSRX_DLYDIR_LANE2, HSRX_DLYDIR_LANE3, HSRX_DLYDIR_LANECK; -input HSRX_DLYLDN_LANE0, HSRX_DLYLDN_LANE1, HSRX_DLYLDN_LANE2, HSRX_DLYLDN_LANE3, HSRX_DLYLDN_LANECK; -input HSRX_DLYMV_LANE0, HSRX_DLYMV_LANE1, HSRX_DLYMV_LANE2, HSRX_DLYMV_LANE3, HSRX_DLYMV_LANECK; -input ALP_EDEN_LANE0, ALP_EDEN_LANE1, ALP_EDEN_LANE2, ALP_EDEN_LANE3, ALP_EDEN_LANECK, ALPEN_LN0, ALPEN_LN1, ALPEN_LN2, ALPEN_LN3, ALPEN_LNCK; -parameter TX_PLLCLK = "NONE"; -parameter RX_ALIGN_BYTE = 8'b10111000 ; -parameter RX_HS_8BIT_MODE = 1'b0 ; -parameter RX_LANE_ALIGN_EN = 1'b0 ; -parameter TX_HS_8BIT_MODE = 1'b0 ; -parameter HSREG_EN_LN0 = 1'b0; -parameter HSREG_EN_LN1 = 1'b0; -parameter HSREG_EN_LN2 = 1'b0; -parameter HSREG_EN_LN3 = 1'b0; -parameter HSREG_EN_LNCK = 1'b0; -parameter LANE_DIV_SEL = 2'b00; -parameter HSRX_EN = 1'b1 ; -parameter HSRX_LANESEL = 4'b1111 ; -parameter HSRX_LANESEL_CK = 1'b1 ; -parameter HSTX_EN_LN0 = 1'b0 ; -parameter HSTX_EN_LN1 = 1'b0 ; -parameter HSTX_EN_LN2 = 1'b0 ; -parameter HSTX_EN_LN3 = 1'b0 ; -parameter HSTX_EN_LNCK = 1'b0 ; -parameter LPTX_EN_LN0 = 1'b1 ; -parameter LPTX_EN_LN1 = 1'b1 ; -parameter LPTX_EN_LN2 = 1'b1 ; -parameter LPTX_EN_LN3 = 1'b1 ; -parameter LPTX_EN_LNCK = 1'b1 ; -parameter TXDP_EN_LN0 = 1'b0 ; -parameter TXDP_EN_LN1 = 1'b0 ; -parameter TXDP_EN_LN2 = 1'b0 ; -parameter TXDP_EN_LN3 = 1'b0 ; -parameter TXDP_EN_LNCK = 1'b0 ; -parameter SPLL_DIV_SEL = 2'b00; -parameter DPHY_CK_SEL = 2'b01; -parameter CKLN_DELAY_EN = 1'b0; -parameter CKLN_DELAY_OVR_VAL = 7'b0000000; -parameter D0LN_DELAY_EN = 1'b0; -parameter D0LN_DELAY_OVR_VAL = 7'b0000000; -parameter D0LN_DESKEW_BYPASS = 1'b0; -parameter D1LN_DELAY_EN = 1'b0; -parameter D1LN_DELAY_OVR_VAL = 7'b0000000; -parameter D1LN_DESKEW_BYPASS = 1'b0; -parameter D2LN_DELAY_EN = 1'b0; -parameter D2LN_DELAY_OVR_VAL = 7'b0000000; -parameter D2LN_DESKEW_BYPASS = 1'b0; -parameter D3LN_DELAY_EN = 1'b0; -parameter D3LN_DELAY_OVR_VAL = 7'b0000000; -parameter D3LN_DESKEW_BYPASS = 1'b0; -parameter DESKEW_EN_LOW_DELAY = 1'b0; -parameter DESKEW_EN_ONE_EDGE = 1'b0; -parameter DESKEW_FAST_LOOP_TIME = 4'b0000; -parameter DESKEW_FAST_MODE = 1'b0; -parameter DESKEW_HALF_OPENING = 6'b010110; -parameter DESKEW_LSB_MODE = 2'b00; -parameter DESKEW_M = 3'b011; -parameter DESKEW_M_TH = 13'b0000110100110; -parameter DESKEW_MAX_SETTING = 7'b0100001; -parameter DESKEW_ONE_CLK_EDGE_EN = 1'b0 ; -parameter DESKEW_RST_BYPASS = 1'b0 ; -parameter RX_BYTE_LITTLE_ENDIAN = 1'b1 ; -parameter RX_CLK_1X_SYNC_SEL = 1'b0 ; -parameter RX_INVERT = 1'b0 ; -parameter RX_ONE_BYTE0_MATCH = 1'b0 ; -parameter RX_RD_START_DEPTH = 5'b00001; -parameter RX_SYNC_MODE = 1'b0 ; -parameter RX_WORD_ALIGN_BYPASS = 1'b0 ; -parameter RX_WORD_ALIGN_DATA_VLD_SRC_SEL = 1'b0 ; -parameter RX_WORD_LITTLE_ENDIAN = 1'b1 ; -parameter TX_BYPASS_MODE = 1'b0 ; -parameter TX_BYTECLK_SYNC_MODE = 1'b0 ; -parameter TX_OCLK_USE_CIBCLK = 1'b0 ; -parameter TX_RD_START_DEPTH = 5'b00001; -parameter TX_SYNC_MODE = 1'b0 ; -parameter TX_WORD_LITTLE_ENDIAN = 1'b1 ; -parameter EQ_CS_LANE0 = 3'b100; -parameter EQ_CS_LANE1 = 3'b100; -parameter EQ_CS_LANE2 = 3'b100; -parameter EQ_CS_LANE3 = 3'b100; -parameter EQ_CS_LANECK = 3'b100; -parameter EQ_RS_LANE0 = 3'b100; -parameter EQ_RS_LANE1 = 3'b100; -parameter EQ_RS_LANE2 = 3'b100; -parameter EQ_RS_LANE3 = 3'b100; -parameter EQ_RS_LANECK = 3'b100; -parameter HSCLK_LANE_LN0 = 1'b0; -parameter HSCLK_LANE_LN1 = 1'b0; -parameter HSCLK_LANE_LN2 = 1'b0; -parameter HSCLK_LANE_LN3 = 1'b0; -parameter HSCLK_LANE_LNCK = 1'b1; -parameter ALP_ED_EN_LANE0 = 1'b1 ; -parameter ALP_ED_EN_LANE1 = 1'b1 ; -parameter ALP_ED_EN_LANE2 = 1'b1 ; -parameter ALP_ED_EN_LANE3 = 1'b1 ; -parameter ALP_ED_EN_LANECK = 1'b1 ; -parameter ALP_ED_TST_LANE0 = 1'b0 ; -parameter ALP_ED_TST_LANE1 = 1'b0 ; -parameter ALP_ED_TST_LANE2 = 1'b0 ; -parameter ALP_ED_TST_LANE3 = 1'b0 ; -parameter ALP_ED_TST_LANECK = 1'b0 ; -parameter ALP_EN_LN0 = 1'b0 ; -parameter ALP_EN_LN1 = 1'b0 ; -parameter ALP_EN_LN2 = 1'b0 ; -parameter ALP_EN_LN3 = 1'b0 ; -parameter ALP_EN_LNCK = 1'b0 ; -parameter ALP_HYS_EN_LANE0 = 1'b1 ; -parameter ALP_HYS_EN_LANE1 = 1'b1 ; -parameter ALP_HYS_EN_LANE2 = 1'b1 ; -parameter ALP_HYS_EN_LANE3 = 1'b1 ; -parameter ALP_HYS_EN_LANECK = 1'b1 ; -parameter ALP_TH_LANE0 = 4'b1000 ; -parameter ALP_TH_LANE1 = 4'b1000 ; -parameter ALP_TH_LANE2 = 4'b1000 ; -parameter ALP_TH_LANE3 = 4'b1000 ; -parameter ALP_TH_LANECK = 4'b1000 ; -parameter ANA_BYTECLK_PH = 2'b00 ; -parameter BIT_REVERSE_LN0 = 1'b0 ; -parameter BIT_REVERSE_LN1 = 1'b0 ; -parameter BIT_REVERSE_LN2 = 1'b0 ; -parameter BIT_REVERSE_LN3 = 1'b0 ; -parameter BIT_REVERSE_LNCK = 1'b0 ; -parameter BYPASS_TXHCLKEN = 1'b1 ; -parameter BYPASS_TXHCLKEN_SYNC = 1'b0 ; -parameter BYTE_CLK_POLAR = 1'b0 ; -parameter BYTE_REVERSE_LN0 = 1'b0 ; -parameter BYTE_REVERSE_LN1 = 1'b0 ; -parameter BYTE_REVERSE_LN2 = 1'b0 ; -parameter BYTE_REVERSE_LN3 = 1'b0 ; -parameter BYTE_REVERSE_LNCK = 1'b0 ; -parameter EN_CLKB1X = 1'b1 ; -parameter EQ_PBIAS_LANE0 = 4'b1000 ; -parameter EQ_PBIAS_LANE1 = 4'b1000 ; -parameter EQ_PBIAS_LANE2 = 4'b1000 ; -parameter EQ_PBIAS_LANE3 = 4'b1000 ; -parameter EQ_PBIAS_LANECK = 4'b1000 ; -parameter EQ_ZLD_LANE0 = 4'b1000 ; -parameter EQ_ZLD_LANE1 = 4'b1000 ; -parameter EQ_ZLD_LANE2 = 4'b1000 ; -parameter EQ_ZLD_LANE3 = 4'b1000 ; -parameter EQ_ZLD_LANECK = 4'b1000 ; -parameter HIGH_BW_LANE0 = 1'b1 ; -parameter HIGH_BW_LANE1 = 1'b1 ; -parameter HIGH_BW_LANE2 = 1'b1 ; -parameter HIGH_BW_LANE3 = 1'b1 ; -parameter HIGH_BW_LANECK = 1'b1 ; -parameter HSREG_VREF_CTL = 3'b100 ; -parameter HSREG_VREF_EN = 1'b1 ; -parameter HSRX_DLY_CTL_CK = 7'b0000000 ; -parameter HSRX_DLY_CTL_LANE0 = 7'b0000000 ; -parameter HSRX_DLY_CTL_LANE1 = 7'b0000000 ; -parameter HSRX_DLY_CTL_LANE2 = 7'b0000000 ; -parameter HSRX_DLY_CTL_LANE3 = 7'b0000000 ; -parameter HSRX_DLY_SEL_LANE0 = 1'b0 ; -parameter HSRX_DLY_SEL_LANE1 = 1'b0 ; -parameter HSRX_DLY_SEL_LANE2 = 1'b0 ; -parameter HSRX_DLY_SEL_LANE3 = 1'b0 ; -parameter HSRX_DLY_SEL_LANECK = 1'b0 ; -parameter HSRX_DUTY_LANE0 = 4'b1000 ; -parameter HSRX_DUTY_LANE1 = 4'b1000 ; -parameter HSRX_DUTY_LANE2 = 4'b1000 ; -parameter HSRX_DUTY_LANE3 = 4'b1000 ; -parameter HSRX_DUTY_LANECK = 4'b1000 ; -parameter HSRX_EQ_EN_LANE0 = 1'b1 ; -parameter HSRX_EQ_EN_LANE1 = 1'b1 ; -parameter HSRX_EQ_EN_LANE2 = 1'b1 ; -parameter HSRX_EQ_EN_LANE3 = 1'b1 ; -parameter HSRX_EQ_EN_LANECK = 1'b1 ; -parameter HSRX_IBIAS = 4'b0011 ; -parameter HSRX_IBIAS_TEST_EN = 1'b0 ; -parameter HSRX_IMARG_EN = 1'b0 ; -parameter HSRX_ODT_EN = 1'b1 ; -parameter HSRX_ODT_TST = 4'b0000 ; -parameter HSRX_ODT_TST_CK = 1'b0 ; -parameter HSRX_SEL = 4'b0000 ; -parameter HSRX_STOP_EN = 1'b0 ; -parameter HSRX_TST = 4'b0000 ; -parameter HSRX_TST_CK = 1'b0 ; -parameter HSRX_WAIT4EDGE = 1'b1 ; -parameter HYST_NCTL = 2'b01 ; -parameter HYST_PCTL = 2'b01 ; -parameter IBIAS_TEST_EN = 1'b0 ; -parameter LB_CH_SEL = 1'b0 ; -parameter LB_EN_LN0 = 1'b0 ; -parameter LB_EN_LN1 = 1'b0 ; -parameter LB_EN_LN2 = 1'b0 ; -parameter LB_EN_LN3 = 1'b0 ; -parameter LB_EN_LNCK = 1'b0 ; -parameter LB_POLAR_LN0 = 1'b0 ; -parameter LB_POLAR_LN1 = 1'b0 ; -parameter LB_POLAR_LN2 = 1'b0 ; -parameter LB_POLAR_LN3 = 1'b0 ; -parameter LB_POLAR_LNCK = 1'b0 ; -parameter LOW_LPRX_VTH = 1'b0 ; -parameter LPBK_DATA2TO1 = 4'b0000; -parameter LPBK_DATA2TO1_CK = 1'b0 ; -parameter LPBK_EN = 1'b0 ; -parameter LPBK_SEL = 4'b0000; -parameter LPBKTST_EN = 4'b0000; -parameter LPBKTST_EN_CK = 1'b0 ; -parameter LPRX_EN = 1'b1 ; -parameter LPRX_TST = 4'b0000; -parameter LPRX_TST_CK = 1'b0 ; -parameter LPTX_DAT_POLAR_LN0 = 1'b0 ; -parameter LPTX_DAT_POLAR_LN1 = 1'b0 ; -parameter LPTX_DAT_POLAR_LN2 = 1'b0 ; -parameter LPTX_DAT_POLAR_LN3 = 1'b0 ; -parameter LPTX_DAT_POLAR_LNCK = 1'b0 ; -parameter LPTX_NIMP_LN0 = 3'b100 ; -parameter LPTX_NIMP_LN1 = 3'b100 ; -parameter LPTX_NIMP_LN2 = 3'b100 ; -parameter LPTX_NIMP_LN3 = 3'b100 ; -parameter LPTX_NIMP_LNCK = 3'b100 ; -parameter LPTX_PIMP_LN0 = 3'b100 ; -parameter LPTX_PIMP_LN1 = 3'b100 ; -parameter LPTX_PIMP_LN2 = 3'b100 ; -parameter LPTX_PIMP_LN3 = 3'b100 ; -parameter LPTX_PIMP_LNCK = 3'b100 ; -parameter MIPI_PMA_DIS_N = 1'b1 ; -parameter PGA_BIAS_LANE0 = 4'b1000 ; -parameter PGA_BIAS_LANE1 = 4'b1000 ; -parameter PGA_BIAS_LANE2 = 4'b1000 ; -parameter PGA_BIAS_LANE3 = 4'b1000 ; -parameter PGA_BIAS_LANECK = 4'b1000 ; -parameter PGA_GAIN_LANE0 = 4'b1000 ; -parameter PGA_GAIN_LANE1 = 4'b1000 ; -parameter PGA_GAIN_LANE2 = 4'b1000 ; -parameter PGA_GAIN_LANE3 = 4'b1000 ; -parameter PGA_GAIN_LANECK = 4'b1000 ; -parameter RX_ODT_TRIM_LANE0 = 4'b1000 ; -parameter RX_ODT_TRIM_LANE1 = 4'b1000 ; -parameter RX_ODT_TRIM_LANE2 = 4'b1000 ; -parameter RX_ODT_TRIM_LANE3 = 4'b1000 ; -parameter RX_ODT_TRIM_LANECK = 4'b1000 ; -parameter SLEWN_CTL_LN0 = 4'b1111 ; -parameter SLEWN_CTL_LN1 = 4'b1111 ; -parameter SLEWN_CTL_LN2 = 4'b1111 ; -parameter SLEWN_CTL_LN3 = 4'b1111 ; -parameter SLEWN_CTL_LNCK = 4'b1111 ; -parameter SLEWP_CTL_LN0 = 4'b1111 ; -parameter SLEWP_CTL_LN1 = 4'b1111 ; -parameter SLEWP_CTL_LN2 = 4'b1111 ; -parameter SLEWP_CTL_LN3 = 4'b1111 ; -parameter SLEWP_CTL_LNCK = 4'b1111 ; -parameter STP_UNIT = 2'b01 ; -parameter TERMN_CTL_LN0 = 4'b1000 ; -parameter TERMN_CTL_LN1 = 4'b1000 ; -parameter TERMN_CTL_LN2 = 4'b1000 ; -parameter TERMN_CTL_LN3 = 4'b1000 ; -parameter TERMN_CTL_LNCK = 4'b1000 ; -parameter TERMP_CTL_LN0 = 4'b1000 ; -parameter TERMP_CTL_LN1 = 4'b1000 ; -parameter TERMP_CTL_LN2 = 4'b1000 ; -parameter TERMP_CTL_LN3 = 4'b1000 ; -parameter TERMP_CTL_LNCK = 4'b1000 ; -parameter TEST_EN_LN0 = 1'b0 ; -parameter TEST_EN_LN1 = 1'b0 ; -parameter TEST_EN_LN2 = 1'b0 ; -parameter TEST_EN_LN3 = 1'b0 ; -parameter TEST_EN_LNCK = 1'b0 ; -parameter TEST_N_IMP_LN0 = 1'b0 ; -parameter TEST_N_IMP_LN1 = 1'b0 ; -parameter TEST_N_IMP_LN2 = 1'b0 ; -parameter TEST_N_IMP_LN3 = 1'b0 ; -parameter TEST_N_IMP_LNCK = 1'b0 ; -parameter TEST_P_IMP_LN0 = 1'b0 ; -parameter TEST_P_IMP_LN1 = 1'b0 ; -parameter TEST_P_IMP_LN2 = 1'b0 ; -parameter TEST_P_IMP_LN3 = 1'b0 ; -parameter TEST_P_IMP_LNCK = 1'b0 ; -endmodule - -module MIPI_CPHY (...); -output [41:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD; -output D0LN_HSRXD_VLD, D1LN_HSRXD_VLD, D2LN_HSRXD_VLD; -output [1:0] D0LN_HSRX_DEMAP_INVLD, D1LN_HSRX_DEMAP_INVLD, D2LN_HSRX_DEMAP_INVLD; -output D0LN_HSRX_FIFO_RDE_ERR, D0LN_HSRX_FIFO_WRF_ERR, D1LN_HSRX_FIFO_RDE_ERR, D1LN_HSRX_FIFO_WRF_ERR, D2LN_HSRX_FIFO_RDE_ERR, D2LN_HSRX_FIFO_WRF_ERR; -output [1:0] D0LN_HSRX_WA, D1LN_HSRX_WA, D2LN_HSRX_WA; -output D0LN_RX_CLK_1X_O, D1LN_RX_CLK_1X_O, D2LN_RX_CLK_1X_O; -output HSTX_FIFO_AE, HSTX_FIFO_AF; -output HSTX_FIFO_RDE_ERR, HSTX_FIFO_WRF_ERR; -output RX_CLK_MUXED; -output TX_CLK_1X_O; -output DI_LPRX0_A, DI_LPRX0_B, DI_LPRX0_C, DI_LPRX1_A, DI_LPRX1_B, DI_LPRX1_C, DI_LPRX2_A, DI_LPRX2_B, DI_LPRX2_C; -output [7:0] MDRP_RDATA; -inout D0A, D0B, D0C, D1A, D1B, D1C, D2A, D2B, D2C; -input D0LN_HSRX_EN, D0LN_HSTX_EN, D1LN_HSRX_EN, D1LN_HSTX_EN, D2LN_HSRX_EN, D2LN_HSTX_EN; -input [41:0] D0LN_HSTX_DATA,D1LN_HSTX_DATA, D2LN_HSTX_DATA; -input D0LN_HSTX_DATA_VLD, D1LN_HSTX_DATA_VLD, D2LN_HSTX_DATA_VLD; -input [1:0] D0LN_HSTX_MAP_DIS, D1LN_HSTX_MAP_DIS, D2LN_HSTX_MAP_DIS; -input D0LN_RX_CLK_1X_I,D1LN_RX_CLK_1X_I, D2LN_RX_CLK_1X_I; -input D0LN_RX_DRST_N, D0LN_TX_DRST_N, D1LN_RX_DRST_N, D1LN_TX_DRST_N, D2LN_RX_DRST_N, D2LN_TX_DRST_N; -input HSTX_ENLN0, HSTX_ENLN1, HSTX_ENLN2, LPTX_ENLN0, LPTX_ENLN1, LPTX_ENLN2; -input [7:0] MDRP_A_D_I; -input MDRP_A_INC_I; -input MDRP_CLK_I; -input [1:0] MDRP_OPCODE_I; -input PWRON_RX_LN0, PWRON_RX_LN1, PWRON_RX_LN2, PWRON_TX; -input ARST_RXLN0, ARST_RXLN1, ARST_RXLN2; -input ARSTN_TX; -input RX_CLK_EN_LN0, RX_CLK_EN_LN1, RX_CLK_EN_LN2; -input TX_CLK_1X_I; -input TXDP_ENLN0, TXDP_ENLN1, TXDP_ENLN2; -input TXHCLK_EN; -input DO_LPTX_A_LN0, DO_LPTX_A_LN1, DO_LPTX_A_LN2, DO_LPTX_B_LN0, DO_LPTX_B_LN1, DO_LPTX_B_LN2, DO_LPTX_C_LN0, DO_LPTX_C_LN1, DO_LPTX_C_LN2; -input GPLL_CK0,GPLL_CK90, GPLL_CK180, GPLL_CK270; -input HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2; -input HSRX_ODT_EN_D0, HSRX_ODT_EN_D1, HSRX_ODT_EN_D2; -input LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2; -input SPLL0_CKN, SPLL0_CKP, SPLL1_CKN, SPLL1_CKP; -parameter TX_PLLCLK = "NONE"; -parameter D0LN_HS_TX_EN = 1'b1; -parameter D1LN_HS_TX_EN = 1'b1; -parameter D2LN_HS_TX_EN = 1'b1; -parameter D0LN_HS_RX_EN = 1'b1; -parameter D1LN_HS_RX_EN = 1'b1; -parameter D2LN_HS_RX_EN = 1'b1; -parameter TX_HS_21BIT_MODE = 1'b0; -parameter RX_OUTCLK_SEL = 2'b00; -parameter TX_W_LENDIAN = 1'b1; -parameter CLK_SEL = 2'b00; -parameter LNDIV_RATIO = 4'b0000; -parameter LNDIV_EN = 1'b0; -parameter D0LN_TX_REASGN_A = 2'b00; -parameter D0LN_TX_REASGN_B = 2'b01; -parameter D0LN_TX_REASGN_C = 2'b10; -parameter D0LN_RX_HS_21BIT_MODE = 1'b0; -parameter D0LN_RX_WA_SYNC_PAT0_EN = 1'b1; -parameter D0LN_RX_WA_SYNC_PAT0_H = 7'b1001001; -parameter D0LN_RX_WA_SYNC_PAT0_L = 8'b00100100; -parameter D0LN_RX_WA_SYNC_PAT1_EN = 1'b1; -parameter D0LN_RX_WA_SYNC_PAT1_H = 7'b0101001; -parameter D0LN_RX_WA_SYNC_PAT1_L = 8'b00100100; -parameter D0LN_RX_WA_SYNC_PAT2_EN = 1'b1; -parameter D0LN_RX_WA_SYNC_PAT2_H = 7'b0011001; -parameter D0LN_RX_WA_SYNC_PAT2_L = 8'b00100100; -parameter D0LN_RX_WA_SYNC_PAT3_EN = 1'b0; -parameter D0LN_RX_WA_SYNC_PAT3_H = 7'b0001001; -parameter D0LN_RX_WA_SYNC_PAT3_L = 8'b00100100; -parameter D0LN_RX_W_LENDIAN = 1'b1; -parameter D0LN_RX_REASGN_A = 2'b00; -parameter D0LN_RX_REASGN_B = 2'b01; -parameter D0LN_RX_REASGN_C = 2'b10; -parameter HSRX_LNSEL = 3'b111; -parameter EQ_RS_LN0 = 3'b001; -parameter EQ_CS_LN0 = 3'b101; -parameter PGA_GAIN_LN0 = 4'b0110; -parameter PGA_BIAS_LN0 = 4'b1000; -parameter EQ_PBIAS_LN0 = 4'b0100; -parameter EQ_ZLD_LN0 = 4'b1000; -parameter D1LN_TX_REASGN_A = 2'b00; -parameter D1LN_TX_REASGN_B = 2'b01; -parameter D1LN_TX_REASGN_C = 2'b10; -parameter D1LN_RX_HS_21BIT_MODE = 1'b0; -parameter D1LN_RX_WA_SYNC_PAT0_EN = 1'b1; -parameter D1LN_RX_WA_SYNC_PAT0_H = 7'b1001001; -parameter D1LN_RX_WA_SYNC_PAT0_L = 8'b00100100; -parameter D1LN_RX_WA_SYNC_PAT1_EN = 1'b1; -parameter D1LN_RX_WA_SYNC_PAT1_H = 7'b0101001; -parameter D1LN_RX_WA_SYNC_PAT1_L = 8'b00100100; -parameter D1LN_RX_WA_SYNC_PAT2_EN = 1'b1; -parameter D1LN_RX_WA_SYNC_PAT2_H = 7'b0011001; -parameter D1LN_RX_WA_SYNC_PAT2_L = 8'b00100100; -parameter D1LN_RX_WA_SYNC_PAT3_EN = 1'b0; -parameter D1LN_RX_WA_SYNC_PAT3_H = 7'b0001001; -parameter D1LN_RX_WA_SYNC_PAT3_L = 8'b00100100; -parameter D1LN_RX_W_LENDIAN = 1'b1; -parameter D1LN_RX_REASGN_A = 2'b00; -parameter D1LN_RX_REASGN_B = 2'b01; -parameter D1LN_RX_REASGN_C = 2'b10; -parameter EQ_RS_LN1 = 3'b001; -parameter EQ_CS_LN1 = 3'b101; -parameter PGA_GAIN_LN1 = 4'b0110; -parameter PGA_BIAS_LN1 = 4'b1000; -parameter EQ_PBIAS_LN1 = 4'b0100; -parameter EQ_ZLD_LN1 = 4'b1000; -parameter D2LN_TX_REASGN_A = 2'b00; -parameter D2LN_TX_REASGN_B = 2'b01; -parameter D2LN_TX_REASGN_C = 2'b10; -parameter D2LN_RX_HS_21BIT_MODE = 1'b0; -parameter D2LN_RX_WA_SYNC_PAT0_EN = 1'b1; -parameter D2LN_RX_WA_SYNC_PAT0_H = 7'b1001001; -parameter D2LN_RX_WA_SYNC_PAT0_L = 8'b00100100; -parameter D2LN_RX_WA_SYNC_PAT1_EN = 1'b1; -parameter D2LN_RX_WA_SYNC_PAT1_H = 7'b0101001; -parameter D2LN_RX_WA_SYNC_PAT1_L = 8'b00100100; -parameter D2LN_RX_WA_SYNC_PAT2_EN = 1'b1; -parameter D2LN_RX_WA_SYNC_PAT2_H = 7'b0011001; -parameter D2LN_RX_WA_SYNC_PAT2_L = 8'b00100100; -parameter D2LN_RX_WA_SYNC_PAT3_EN = 1'b0; -parameter D2LN_RX_WA_SYNC_PAT3_H = 7'b0001001; -parameter D2LN_RX_WA_SYNC_PAT3_L = 8'b00100100; -parameter D2LN_RX_W_LENDIAN = 1'b1; -parameter D2LN_RX_REASGN_A = 2'b00; -parameter D2LN_RX_REASGN_B = 2'b01; -parameter D2LN_RX_REASGN_C = 2'b10; -parameter EQ_RS_LN2 = 3'b001; -parameter EQ_CS_LN2 = 3'b101; -parameter PGA_GAIN_LN2 = 4'b0110; -parameter PGA_BIAS_LN2 = 4'b1000; -parameter EQ_PBIAS_LN2 = 4'b0100; -parameter EQ_ZLD_LN2 = 4'b1000; -endmodule - module GTR12_QUAD (...); endmodule @@ -2651,18 +1926,6 @@ endmodule module GTR12_PMAC (...); endmodule -module GTR12_QUADA (...); -endmodule - -module GTR12_UPARA (...); -endmodule - -module GTR12_PMACA (...); -endmodule - -module GTR12_QUADB (...); -endmodule - module DQS (...); input DQSIN,PCLK,FCLK,RESET; input [3:0] READ; @@ -2678,3 +1941,4 @@ parameter RD_PNTR = 3'b000; parameter DQS_MODE = "X1"; parameter HWL = "false"; endmodule + From ca57e1481986638339e801c040557c4cb3e6138c Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Thu, 27 Mar 2025 15:53:50 -0700 Subject: [PATCH 104/133] Address review feedback --- Makefile | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index fc07374ea..01cf5f8f1 100644 --- a/Makefile +++ b/Makefile @@ -360,7 +360,7 @@ LIBS += $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem PY_WRAPPER_FILE = kernel/python_wrappers OBJS += $(PY_WRAPPER_FILE).o PY_GEN_SCRIPT= py_wrap_generator -PY_WRAP_INCLUDES := $(shell python$(PYTHON_VERSION) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).print_includes()") +PY_WRAP_INCLUDES := $(shell $(PYTHON_EXECUTABLE) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).print_includes()") endif # ENABLE_PYOSYS ifeq ($(ENABLE_READLINE),1) @@ -747,7 +747,7 @@ endif ifeq ($(ENABLE_PYOSYS),1) $(PY_WRAPPER_FILE).cc: misc/$(PY_GEN_SCRIPT).py $(PY_WRAP_INCLUDES) $(Q) mkdir -p $(dir $@) - $(P) python$(PYTHON_VERSION) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).gen_wrappers(\"$(PY_WRAPPER_FILE).cc\")" + $(P) $(PYTHON_EXECUTABLE) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).gen_wrappers(\"$(PY_WRAPPER_FILE).cc\")" endif %.o: %.cpp @@ -959,10 +959,10 @@ clean-unit-test: @$(MAKE) -C $(UNITESTPATH) clean wheel: $(TARGETS) - python$(PYTHON_VERSION) -m pip wheel . + $(PYTHON_EXECUTABLE) -m pip wheel . install-wheel: wheel - python$(PYTHON_VERSION) -m pip install pyosys-$(YOSYS_MAJOR).$(YOSYS_MINOR).$(YOSYS_COMMIT)-*.whl --force-reinstall + $(PYTHON_EXECUTABLE) -m pip install pyosys-$(YOSYS_MAJOR).$(YOSYS_MINOR).$(YOSYS_COMMIT)-*.whl --force-reinstall install: $(TARGETS) $(EXTRA_TARGETS) $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR) @@ -984,10 +984,6 @@ ifeq ($(ENABLE_LIBYOSYS),1) $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so ifeq ($(ENABLE_PYOSYS),1) $(INSTALL_SUDO) @$(MAKE) install-wheel -ifeq ($(ENABLE_ABC),1) - $(INSTALL_SUDO) cp yosys-abc $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/yosys-abc -endif - $(INSTALL_SUDO) cp misc/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/ endif endif ifeq ($(ENABLE_PLUGINS),1) @@ -1003,7 +999,7 @@ uninstall: ifeq ($(ENABLE_LIBYOSYS),1) $(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.so ifeq ($(ENABLE_PYOSYS),1) - $(INSTALL_SUDO) python$(PYTHON_VERSION) -m pip uninstall -y pyosys + $(INSTALL_SUDO) $(PYTHON_EXECUTABLE) -m pip uninstall -y pyosys endif endif From 314842d2a0a9901f4839a20360f3b35ae6736e63 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 29 Mar 2025 00:22:03 +0000 Subject: [PATCH 105/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5745d1d0c..74128b41d 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+85 +YOSYS_VER := 0.51+101 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 83b095ab6ca294cb8ccd8504e5dcdae54841199a Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Sun, 30 Mar 2025 15:43:41 +0300 Subject: [PATCH 106/133] opt_expr: optimize pow of 2 cells --- passes/opt/opt_expr.cc | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 62a0ffc48..5089959ae 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -1690,7 +1690,43 @@ skip_identity: else if (inA == inB) ACTION_DO(ID::Y, cell->getPort(ID::A)); } + if (cell->type == ID($pow) && cell->getPort(ID::A).is_fully_const() && !cell->parameters[ID::B_SIGNED].as_bool()) { + SigSpec sig_a = assign_map(cell->getPort(ID::A)); + SigSpec sig_y = assign_map(cell->getPort(ID::Y)); + int y_size = GetSize(sig_y); + unsigned int bits = unsigned(sig_a.as_int()); + int bit_count = 0; + for (; bits; bits >>= 1) + bit_count += (bits & 1); + + if (bit_count == 1) { + if (sig_a.as_int() == 2) { + log_debug("Replacing pow cell `%s' in module `%s' with left-shift\n", + cell->name.c_str(), module->name.c_str()); + cell->type = ID($shl); + cell->parameters[ID::A_WIDTH] = 1; + cell->setPort(ID::A, Const(1, 1)); + } + else { + log_debug("Replacing pow cell `%s' in module `%s' with multiply and left-shift\n", + cell->name.c_str(), module->name.c_str()); + cell->type = ID($mul); + cell->parameters[ID::A_SIGNED] = 0; + + int left_shift; + sig_a.is_onehot(&left_shift); + cell->setPort(ID::A, Const(left_shift, cell->parameters[ID::A_WIDTH].as_int())); + + SigSpec y_wire = module->addWire(NEW_ID, y_size); + cell->setPort(ID::Y, y_wire); + + module->addShl(NEW_ID, Const(1, 1), y_wire, sig_y); + } + did_something = true; + goto next_cell; + } + } if (!keepdc && cell->type == ID($mul)) { bool a_signed = cell->parameters[ID::A_SIGNED].as_bool(); From 58a515d57f137b0dab9708eebaffaff6d101c98b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 31 Mar 2025 16:19:45 +0200 Subject: [PATCH 107/133] yosys-config: Propagate exit code for help command --- misc/yosys-config.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/yosys-config.in b/misc/yosys-config.in index 2d9c35e4d..34cf3b53b 100755 --- a/misc/yosys-config.in +++ b/misc/yosys-config.in @@ -37,11 +37,11 @@ help() { echo " $0 --datdir/simlib.v" echo "" } >&2 - exit 1 + exit $1 } if [ $# -eq 0 ]; then - help + help 1 fi if [ "$1" = "--build" ]; then @@ -83,7 +83,7 @@ for opt; do tokens=( "${tokens[@]}" '@DATDIR@'"${opt#${prefix}datdir}" ) ;; --help|-\?|-h) if [ ${#tokens[@]} -eq 0 ]; then - help + help 0 else tokens=( "${tokens[@]}" "$opt" ) fi ;; From 6194eb939dd51529b27591b7fc3fc0bc7ef06d05 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Mon, 31 Mar 2025 19:31:53 +0200 Subject: [PATCH 108/133] opt_expr: expand test coverage --- tests/opt/opt_expr_more.ys | 177 +++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 tests/opt/opt_expr_more.ys diff --git a/tests/opt/opt_expr_more.ys b/tests/opt/opt_expr_more.ys new file mode 100644 index 000000000..795ae89c4 --- /dev/null +++ b/tests/opt/opt_expr_more.ys @@ -0,0 +1,177 @@ +design -reset +read_verilog < Date: Tue, 1 Apr 2025 00:26:08 +0000 Subject: [PATCH 109/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 74128b41d..fd3f8c20c 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+101 +YOSYS_VER := 0.51+104 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 66d7ffb2c55f8e1606b20ec13f7ea566438cf017 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 1 Apr 2025 08:39:11 +0200 Subject: [PATCH 110/133] yosys-config: redirect to stderr/stdout depending of exit code --- Makefile | 4 ++-- misc/yosys-config.in | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 74128b41d..2efe23eea 100644 --- a/Makefile +++ b/Makefile @@ -1049,7 +1049,7 @@ define DOC_USAGE_STDERR docs/source/generated/$(1): $(TARGETS) docs/source/generated FORCE -$(Q) ./$(PROGRAM_PREFIX)$(1) --help 2> $$@ endef -DOCS_USAGE_STDERR := yosys-config yosys-filterlib +DOCS_USAGE_STDERR := yosys-filterlib # The in-tree ABC (yosys-abc) is only built when ABCEXTERNAL is not set. ifeq ($(ABCEXTERNAL),) @@ -1063,7 +1063,7 @@ define DOC_USAGE_STDOUT docs/source/generated/$(1): $(TARGETS) docs/source/generated $(Q) ./$(PROGRAM_PREFIX)$(1) --help > $$@ || rm $$@ endef -DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness +DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness yosys-config $(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage)))) docs/usage: $(addprefix docs/source/generated/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE_STDERR)) diff --git a/misc/yosys-config.in b/misc/yosys-config.in index 34cf3b53b..758ba79a9 100755 --- a/misc/yosys-config.in +++ b/misc/yosys-config.in @@ -36,7 +36,7 @@ help() { echo "" echo " $0 --datdir/simlib.v" echo "" - } >&2 + } >&$(( $1 + 1)) exit $1 } From 119e998f120832ca7e5d61f434cc5efd37fa5197 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 1 Apr 2025 13:48:44 +0200 Subject: [PATCH 111/133] read_liberty: Faster input handling for the liberty lexer The lexer for liberty files was using istream's `get` and `unget` which are notorious for bad performance and that showed up during profiling. This replaces the direct `istream` use with a custom LibertyInputStream that does its own buffering to provide `get` and `unget` that behave the same way but are implemented with a fast path that is easy to inline and optimize. --- kernel/yosys_common.h | 6 +++++ passes/techmap/libparse.cc | 45 ++++++++++++++++++++++++++++++++++++++ passes/techmap/libparse.h | 33 +++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/kernel/yosys_common.h b/kernel/yosys_common.h index a68539ce1..6fadf788f 100644 --- a/kernel/yosys_common.h +++ b/kernel/yosys_common.h @@ -128,6 +128,12 @@ # error "C++17 or later compatible compiler is required" #endif +#if defined(__has_cpp_attribute) && __has_cpp_attribute(gnu::cold) +# define YS_COLD [[gnu::cold]] +#else +# define YS_COLD +#endif + #include "kernel/io.h" YOSYS_NAMESPACE_BEGIN diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index 06dd6288e..dbf191080 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -32,6 +32,51 @@ using namespace Yosys; +bool LibertyInputStream::extend_buffer_once() +{ + if (eof) + return false; + + // To support unget we leave the last already read character in the buffer + if (buf_pos > 1) { + size_t move_pos = buf_pos - 1; + memmove(buffer.data(), buffer.data() + move_pos, buf_end - move_pos); + buf_pos -= move_pos; + buf_end -= move_pos; + } + + const size_t chunk_size = 4096; + if (buffer.size() < buf_end + chunk_size) { + buffer.resize(buf_end + chunk_size); + } + + size_t read_size = f.rdbuf()->sgetn(buffer.data() + buf_end, chunk_size); + buf_end += read_size; + if (read_size < chunk_size) + eof = true; + return read_size != 0; +} + +bool LibertyInputStream::extend_buffer_at_least(size_t size) { + while (buffered_size() < size) { + if (!extend_buffer_once()) + return false; + } + return true; +} + +int LibertyInputStream::get_cold() +{ + if (buf_pos == buf_end) { + if (!extend_buffer_at_least()) + return EOF; + } + + int c = buffer[buf_pos]; + buf_pos += 1; + return c; +} + LibertyAst::~LibertyAst() { for (auto child : children) diff --git a/passes/techmap/libparse.h b/passes/techmap/libparse.h index 16808fc58..eb73e296d 100644 --- a/passes/techmap/libparse.h +++ b/passes/techmap/libparse.h @@ -90,12 +90,43 @@ namespace Yosys bool eval(dict& values); }; + class LibertyInputStream { + std::istream &f; + std::vector buffer; + size_t buf_pos = 0; + size_t buf_end = 0; + bool eof = false; + + bool extend_buffer_once(); + bool extend_buffer_at_least(size_t size = 1); + + YS_COLD int get_cold(); + + public: + LibertyInputStream(std::istream &f) : f(f) {} + + size_t buffered_size() { return buf_end - buf_pos; } + const char *buffered_data() { return buffer.data() + buf_pos; } + + int get() { + if (buf_pos == buf_end) + return get_cold(); + int c = buffer[buf_pos]; + buf_pos += 1; + return c; + } + + void unget() { + buf_pos -= 1; + } + }; + class LibertyMergedCells; class LibertyParser { friend class LibertyMergedCells; private: - std::istream &f; + LibertyInputStream f; int line; /* lexer return values: From bc01468c7545b2362a52b48f11fa0e5cccb4e75a Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 1 Apr 2025 13:50:29 +0200 Subject: [PATCH 112/133] read_liberty: Faster std::string construction in the liberty lexer This extends the `LibertyInputStream` added in the previous commit to allow arbitrary lookahead. Then this uses the lookahead to find the total length of the token within the input buffer, instead of consuming the token byte by byte while appending to a std::string. Constructing the std::string with the total length is known avoids any reallocations from growing std::string's buffer. --- passes/techmap/libparse.cc | 55 ++++++++++++++++++++++++-------------- passes/techmap/libparse.h | 11 ++++++++ 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index dbf191080..d3d5b7d57 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -77,6 +77,16 @@ int LibertyInputStream::get_cold() return c; } +int LibertyInputStream::peek_cold(size_t offset) +{ + if (buf_pos + offset >= buf_end) { + if (!extend_buffer_at_least(offset + 1)) + return EOF; + } + + return buffer[buf_pos + offset]; +} + LibertyAst::~LibertyAst() { for (auto child : children) @@ -282,15 +292,19 @@ int LibertyParser::lexer(std::string &str) // search for identifiers, numbers, plus or minus. if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.') { - str = static_cast(c); - while (1) { - c = f.get(); + f.unget(); + size_t i = 1; + while (true) { + c = f.peek(i); if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.') - str += c; + i += 1; else break; } - f.unget(); + str.clear(); + str.append(f.buffered_data(), f.buffered_data() + i); + f.consume(i); + if (str == "+" || str == "-") { /* Single operator is not an identifier */ // fprintf(stderr, "LEX: char >>%s<<\n", str.c_str()); @@ -305,23 +319,24 @@ int LibertyParser::lexer(std::string &str) // if it wasn't an identifer, number of array range, // maybe it's a string? if (c == '"') { - str = ""; -#ifdef FILTERLIB - str += c; -#endif - while (1) { - c = f.get(); - if (c == '\n') - line++; - if (c == '"') { -#ifdef FILTERLIB - str += c; -#endif + size_t i = 0; + while (true) { + c = f.peek(i); + line += (c == '\n'); + if (c != '"') + i += 1; + else break; - } - str += c; } - // fprintf(stderr, "LEX: string >>%s<<\n", str.c_str()); + str.clear(); +#ifdef FILTERLIB + f.unget(); + str.append(f.buffered_data(), f.buffered_data() + i + 2); + f.consume(i + 2); +#else + str.append(f.buffered_data(), f.buffered_data() + i); + f.consume(i + 1); +#endif return 'v'; } diff --git a/passes/techmap/libparse.h b/passes/techmap/libparse.h index eb73e296d..1fcaaebee 100644 --- a/passes/techmap/libparse.h +++ b/passes/techmap/libparse.h @@ -101,6 +101,7 @@ namespace Yosys bool extend_buffer_at_least(size_t size = 1); YS_COLD int get_cold(); + YS_COLD int peek_cold(size_t offset); public: LibertyInputStream(std::istream &f) : f(f) {} @@ -116,6 +117,16 @@ namespace Yosys return c; } + int peek(size_t offset = 0) { + if (buf_pos + offset >= buf_end) + return peek_cold(offset); + return buffer[buf_pos + offset]; + } + + void consume(size_t n = 1) { + buf_pos += n; + } + void unget() { buf_pos -= 1; } From 72f2185a94965fb11ece7e2495b12e4f0c98451f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 1 Apr 2025 17:35:59 +0200 Subject: [PATCH 113/133] verific: fix restoring msg state after blackbox import --- frontends/verific/verific.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 4221419af..3418ebe50 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -3403,6 +3403,7 @@ struct VerificPass : public Pass { veri_module->SetCompileAsBlackbox(); } } + restore_blackbox_msg_state(); } #endif From 6b5507139ecc8b0d5e71bf81ae077ff3f5258210 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Tue, 1 Apr 2025 20:37:22 +0300 Subject: [PATCH 114/133] opt_expr: requsted changes --- passes/opt/opt_expr.cc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 5089959ae..9967c7753 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -1695,33 +1695,28 @@ skip_identity: SigSpec sig_y = assign_map(cell->getPort(ID::Y)); int y_size = GetSize(sig_y); - unsigned int bits = unsigned(sig_a.as_int()); - int bit_count = 0; - for (; bits; bits >>= 1) - bit_count += (bits & 1); + int bit_idx; + const auto onehot = sig_a.is_onehot(&bit_idx); - if (bit_count == 1) { - if (sig_a.as_int() == 2) { + if (onehot) { + if (bit_idx == 1) { log_debug("Replacing pow cell `%s' in module `%s' with left-shift\n", cell->name.c_str(), module->name.c_str()); cell->type = ID($shl); cell->parameters[ID::A_WIDTH] = 1; - cell->setPort(ID::A, Const(1, 1)); + cell->setPort(ID::A, Const(State::S1, 1)); } else { log_debug("Replacing pow cell `%s' in module `%s' with multiply and left-shift\n", cell->name.c_str(), module->name.c_str()); cell->type = ID($mul); cell->parameters[ID::A_SIGNED] = 0; - - int left_shift; - sig_a.is_onehot(&left_shift); - cell->setPort(ID::A, Const(left_shift, cell->parameters[ID::A_WIDTH].as_int())); + cell->setPort(ID::A, Const(bit_idx, cell->parameters[ID::A_WIDTH].as_int())); SigSpec y_wire = module->addWire(NEW_ID, y_size); cell->setPort(ID::Y, y_wire); - module->addShl(NEW_ID, Const(1, 1), y_wire, sig_y); + module->addShl(NEW_ID, Const(State::S1, 1), y_wire, sig_y); } did_something = true; goto next_cell; From c57cbfa8f9525ac230815ca9fffe751f0e63f2e7 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Tue, 1 Apr 2025 21:54:46 +0300 Subject: [PATCH 115/133] opt_expr: add test --- tests/opt/opt_pow.ys | 89 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 tests/opt/opt_pow.ys diff --git a/tests/opt/opt_pow.ys b/tests/opt/opt_pow.ys new file mode 100644 index 000000000..0fa2f88c7 --- /dev/null +++ b/tests/opt/opt_pow.ys @@ -0,0 +1,89 @@ +# Default power of two + +design -reset + +read_rtlil << EOT +autoidx 3 +attribute \cells_not_processed 1 +attribute \src ":1.1-3.10" +module \top + attribute \src ":2.17-2.20" + wire width 32 $add$:2$1_Y + attribute \src ":2.12-2.21" + wire width 32 signed $pow$:2$2_Y + attribute \src ":1.29-1.30" + wire width 15 input 1 \a + attribute \src ":1.51-1.52" + wire width 32 output 2 \b + attribute \src ":2.17-2.20" + cell $add $add$:2$1 + parameter \A_SIGNED 0 + parameter \A_WIDTH 15 + parameter \B_SIGNED 0 + parameter \B_WIDTH 32 + parameter \Y_WIDTH 32 + connect \A \a + connect \B 2 + connect \Y $add$:2$1_Y + end + attribute \src ":2.12-2.21" + cell $pow $pow$:2$2 + parameter \A_SIGNED 0 + parameter \A_WIDTH 32 + parameter \B_SIGNED 0 + parameter \B_WIDTH 32 + parameter \Y_WIDTH 32 + connect \A 2 + connect \B $add$:2$1_Y + connect \Y $pow$:2$2_Y + end + connect \b $pow$:2$2_Y +end +EOT + +select -assert-count 1 t:$pow +select -assert-none t:$shl +opt_expr +select -assert-none t:$pow +select -assert-count 1 t:$shl + +read_verilog << EOT +module ref(input wire [14:0] a, output wire [31:0] b); +assign b = 1 << (a+2); +endmodule +EOT + +equiv_make top ref equiv +select -assert-any -module equiv t:$equiv +equiv_induct +equiv_status -assert + +# Other power of 2 value + +design -reset + +read_verilog < Date: Wed, 2 Apr 2025 00:23:07 +0000 Subject: [PATCH 116/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fd3f8c20c..3bd037075 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+104 +YOSYS_VER := 0.51+107 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 0f13b551731766214ba6bb839c2dbddfec0c7c8c Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Thu, 3 Apr 2025 13:11:48 +0200 Subject: [PATCH 117/133] Liberty file caching with new `libcache` command This adds optional in-memory caching of parsed liberty files to speed up flows that repeatedly parse the same liberty files. To avoid increasing the memory overhead by default, the caching is disabled by default. The caching can be controlled globally or on a per path basis using the new `libcache` command, which also allows purging cached data. --- frontends/liberty/liberty.cc | 2 +- passes/cmds/stat.cc | 2 +- passes/techmap/Makefile.inc | 1 + passes/techmap/clockgate.cc | 2 +- passes/techmap/dfflibmap.cc | 2 +- passes/techmap/libcache.cc | 130 +++++++++++++++++++++++++++++++++++ passes/techmap/libparse.cc | 25 +++++++ passes/techmap/libparse.h | 48 +++++++++---- tests/liberty/libcache.ys | 58 ++++++++++++++++ 9 files changed, 253 insertions(+), 17 deletions(-) create mode 100644 passes/techmap/libcache.cc create mode 100644 tests/liberty/libcache.ys diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index cda13ff8b..3228f02fb 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -539,7 +539,7 @@ struct LibertyFrontend : public Frontend { log_header(design, "Executing Liberty frontend: %s\n", filename.c_str()); - LibertyParser parser(*f); + LibertyParser parser(*f, filename); int cell_count = 0; std::map> global_type_map; diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 7e51b6cb1..23583a8a8 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -352,7 +352,7 @@ void read_liberty_cellarea(dict &cell_area, string libert yosys_input_files.insert(liberty_file); if (f->fail()) log_cmd_error("Can't open liberty file `%s': %s\n", liberty_file.c_str(), strerror(errno)); - LibertyParser libparser(*f); + LibertyParser libparser(*f, liberty_file); delete f; for (auto cell : libparser.ast->children) diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 4e1d16744..e6a910a0d 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -6,6 +6,7 @@ OBJS += passes/techmap/dfflibmap.o OBJS += passes/techmap/maccmap.o OBJS += passes/techmap/booth.o OBJS += passes/techmap/libparse.o +OBJS += passes/techmap/libcache.o ifeq ($(ENABLE_ABC),1) OBJS += passes/techmap/abc.o diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index 363f998db..b34ad1769 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -312,7 +312,7 @@ struct ClockgatePass : public Pass { std::istream* f = uncompressed(path); if (f->fail()) log_cmd_error("Can't open liberty file `%s': %s\n", path.c_str(), strerror(errno)); - LibertyParser p(*f); + LibertyParser p(*f, path); merged.merge(p); delete f; } diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index fe4f8aada..84db7f157 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -634,7 +634,7 @@ struct DfflibmapPass : public Pass { std::istream* f = uncompressed(path); if (f->fail()) log_cmd_error("Can't open liberty file `%s': %s\n", path.c_str(), strerror(errno)); - LibertyParser p(*f); + LibertyParser p(*f, path); merged.merge(p); delete f; } diff --git a/passes/techmap/libcache.cc b/passes/techmap/libcache.cc new file mode 100644 index 000000000..19f1fa87d --- /dev/null +++ b/passes/techmap/libcache.cc @@ -0,0 +1,130 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2025 Jannis Harder + * + * 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 "passes/techmap/libparse.h" + + USING_YOSYS_NAMESPACE + PRIVATE_NAMESPACE_BEGIN + + struct LibcachePass : public Pass { + LibcachePass() : Pass("libcache", "control caching of technology library data parsed from liberty files") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" libcache {-enable|-disable|-purge} { -all | [path]... }\n"); + log("\n"); + log("Controls the default and per path caching of liberty file data.\n"); + log("\n"); + log(" -enable Enable caching.\n"); + log(" -disable Disable caching.\n"); + log(" -purge Reset cache setting and forget cached data.\n"); + log("\n"); + log("This mode takes a list of paths as argument. If no paths are provided, this\n"); + log("command does nothing. The -all option can be used to change the default cache\n"); + log("setting for -enable/-disable or to reset and forget about all paths.\n"); + log("\n"); + log("By default caching is disabled.\n"); + log("\n"); + log(" libcache -list\n"); + log("\n"); + log("Displays the current cache settings and cached paths.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *) override + { + bool enable = false; + bool disable = false; + bool purge = false; + bool all = false; + bool list = false; + std::vector paths; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-enable") { + enable = true; + continue; + } + if (args[argidx] == "-disable") { + enable = true; + continue; + } + if (args[argidx] == "-purge") { + purge = true; + continue; + } + if (args[argidx] == "-all") { + all = true; + continue; + } + if (args[argidx] == "-list") { + list = true; + continue; + } + std::string fname = args[argidx]; + rewrite_filename(fname); + paths.push_back(fname); + break; + } + int modes = enable + disable + purge + list; + if (modes == 0) + log_cmd_error("At least one of -enable, -disable, -purge or -list is required.\n"); + if (modes > 1) + log_cmd_error("Only one of -enable, -disable, -purge or -list may be present.\n"); + + if (all && !paths.empty()) + log_cmd_error("The -all option cannot be combined with a list of paths.\n"); + if (list && (all || !paths.empty())) + log_cmd_error("The -list mode takes no further options.\n"); + if (!list && !all && paths.empty()) + log("No paths specified, use -all to %s\n", purge ? "purge all paths" : "change the default setting"); + + if (list) { + log("Caching is %s by default.\n", LibertyAstCache::instance.cache_by_default ? "enabled" : "disabled"); + for (auto const &entry : LibertyAstCache::instance.cache_path) + log("Caching is %s for `%s'.\n", entry.second ? "enabled" : "disabled", entry.first.c_str()); + for (auto const &entry : LibertyAstCache::instance.cached) + log("Data for `%s' is currently cached.\n", entry.first.c_str()); + } else if (enable || disable) { + if (all) { + LibertyAstCache::instance.cache_by_default = enable; + } else { + for (auto const &path : paths) { + LibertyAstCache::instance.cache_path[path] = enable; + } + } + } else if (purge) { + if (all) { + LibertyAstCache::instance.cached.clear(); + LibertyAstCache::instance.cache_path.clear(); + } else { + for (auto const &path : paths) { + LibertyAstCache::instance.cached.erase(path); + LibertyAstCache::instance.cache_path.erase(path); + } + } + } else { + log_assert(false); + } + } +} LibcachePass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index d3d5b7d57..d7a952603 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -32,6 +32,31 @@ using namespace Yosys; +#ifndef FILTERLIB + +LibertyAstCache LibertyAstCache::instance; + +std::shared_ptr LibertyAstCache::cached_ast(const std::string &fname) +{ + auto it = cached.find(fname); + if (it == cached.end()) + return nullptr; + log("Using cached data for liberty file `%s'\n", fname.c_str()); + return it->second; +} + +void LibertyAstCache::parsed_ast(const std::string &fname, const std::shared_ptr &ast) +{ + auto it = cache_path.find(fname); + bool should_cache = it == cache_path.end() ? cache_by_default : it->second; + if (!should_cache) + return; + log("Caching data for liberty file `%s'\n", fname.c_str()); + cached.emplace(fname, ast); +} + +#endif + bool LibertyInputStream::extend_buffer_once() { if (eof) diff --git a/passes/techmap/libparse.h b/passes/techmap/libparse.h index 1fcaaebee..9332afebd 100644 --- a/passes/techmap/libparse.h +++ b/passes/techmap/libparse.h @@ -132,6 +132,22 @@ namespace Yosys } }; +#ifndef FILTERLIB + class LibertyAstCache { + LibertyAstCache() {}; + ~LibertyAstCache() {}; + public: + dict> cached; + + bool cache_by_default = false; + dict cache_path; + + std::shared_ptr cached_ast(const std::string &fname); + void parsed_ast(const std::string &fname, const std::shared_ptr &ast); + static LibertyAstCache instance; + }; +#endif + class LibertyMergedCells; class LibertyParser { @@ -152,15 +168,29 @@ namespace Yosys void error(const std::string &str) const; public: - const LibertyAst *ast; + std::shared_ptr shared_ast; + const LibertyAst *ast = nullptr; - LibertyParser(std::istream &f) : f(f), line(1), ast(parse()) {} - ~LibertyParser() { if (ast) delete ast; } + LibertyParser(std::istream &f) : f(f), line(1) { + shared_ast.reset(parse()); + ast = shared_ast.get(); + } + +#ifndef FILTERLIB + LibertyParser(std::istream &f, const std::string &fname) : f(f), line(1) { + shared_ast = LibertyAstCache::instance.cached_ast(fname); + if (!shared_ast) { + shared_ast.reset(parse()); + LibertyAstCache::instance.parsed_ast(fname, shared_ast); + } + ast = shared_ast.get(); + } +#endif }; class LibertyMergedCells { - std::vector asts; + std::vector> asts; public: std::vector cells; @@ -168,10 +198,7 @@ namespace Yosys { if (parser.ast) { const LibertyAst *ast = parser.ast; - asts.push_back(ast); - // The parser no longer owns its top level ast, but we do. - // sketchy zone - parser.ast = nullptr; + asts.push_back(parser.shared_ast); if (ast->id != "library") parser.error("Top level entity isn't \"library\".\n"); for (const LibertyAst *cell : ast->children) @@ -179,11 +206,6 @@ namespace Yosys cells.push_back(cell); } } - ~LibertyMergedCells() - { - for (auto ast : asts) - delete ast; - } }; } diff --git a/tests/liberty/libcache.ys b/tests/liberty/libcache.ys new file mode 100644 index 000000000..a741a9df1 --- /dev/null +++ b/tests/liberty/libcache.ys @@ -0,0 +1,58 @@ +libcache -enable busdef.lib + +logger -expect log "Caching is disabled by default." 1 +logger -expect log "Caching is enabled for `busdef.lib'." 1 +libcache -list +logger -check-expected + +logger -expect log "Caching data" 1 +log Caching data +read_liberty normal.lib; design -reset +logger -check-expected + +logger -expect log "Caching data" 1 +read_liberty -lib busdef.lib; design -reset +logger -check-expected + +logger -expect log "Using caching data" 1 +log Using caching data +read_liberty normal.lib; design -reset +logger -check-expected + +logger -expect log "Using cached data" 1 +read_liberty -lib busdef.lib; design -reset +logger -check-expected + +libcache -purge busdef.lib + +logger -expect log "Caching is disabled by default." 1 +logger -expect log "Caching is enabled for `busdef.lib'." 1 +log Caching is enabled for `busdef.lib'. +libcache -list +logger -check-expected + +libcache -enable -all + +logger -expect log "Caching is enabled by default." 1 +libcache -list +logger -check-expected + +logger -expect log "Caching data" 1 +read_liberty normal.lib; design -reset +logger -check-expected + +logger -expect log "Caching data" 1 +read_liberty -lib busdef.lib; design -reset +logger -check-expected + +logger -expect log "Using cached data" 1 +read_liberty -lib busdef.lib; design -reset +logger -check-expected + +logger -expect log "Using cached data" 1 +read_liberty normal.lib; design -reset +logger -check-expected + +logger -expect log "Using cached data" 1 +dfflibmap -liberty normal.lib +logger -check-expected From 406b400458619e1491b2fd0b97b625fba6f80021 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 4 Apr 2025 12:25:31 +1300 Subject: [PATCH 118/133] opt_expr: Fix #4590 If all the (non-select) inputs of a `$_MUX{4,8,16}_` are undefined, replace it, just like we do for `$mux` and `$_MUX_`. Add `tests/opt/opt_expr_mux_undef.ys` to verify this. This doesn't do any const folding on the wide muxes, or shrinking to less wide muxes. It only handles the case where all inputs are 'x and the mux can be completely removed. --- passes/opt/opt_expr.cc | 14 ++ tests/opt/opt_expr_mux_undef.ys | 290 ++++++++++++++++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 tests/opt/opt_expr_mux_undef.ys diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 9967c7753..df969daf0 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -1573,6 +1573,20 @@ skip_identity: } } + if (mux_undef && cell->type.in(ID($_MUX4_), ID($_MUX8_), ID($_MUX16_))) { + int num_inputs = 4; + if (cell->type == ID($_MUX8_)) num_inputs = 8; + if (cell->type == ID($_MUX16_)) num_inputs = 16; + int undef_inputs = 0; + for (auto &conn : cell->connections()) + if (!conn.first.in(ID::S, ID::T, ID::U, ID::V, ID::Y)) + undef_inputs += conn.second.is_fully_undef(); + if (undef_inputs == num_inputs) { + replace_cell(assign_map, module, cell, "mux_undef", ID::Y, cell->getPort(ID::A)); + goto next_cell; + } + } + #define FOLD_1ARG_CELL(_t) \ if (cell->type == ID($##_t)) { \ RTLIL::SigSpec a = cell->getPort(ID::A); \ diff --git a/tests/opt/opt_expr_mux_undef.ys b/tests/opt/opt_expr_mux_undef.ys new file mode 100644 index 000000000..83c29e07b --- /dev/null +++ b/tests/opt/opt_expr_mux_undef.ys @@ -0,0 +1,290 @@ + +read_rtlil < Date: Thu, 3 Apr 2025 17:47:48 -0700 Subject: [PATCH 119/133] Updates --- Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Makefile b/Makefile index 01cf5f8f1..302678185 100644 --- a/Makefile +++ b/Makefile @@ -958,11 +958,19 @@ unit-test: libyosys.so clean-unit-test: @$(MAKE) -C $(UNITESTPATH) clean +ifeq ($(ENABLE_PYOSYS),1) wheel: $(TARGETS) $(PYTHON_EXECUTABLE) -m pip wheel . install-wheel: wheel $(PYTHON_EXECUTABLE) -m pip install pyosys-$(YOSYS_MAJOR).$(YOSYS_MINOR).$(YOSYS_COMMIT)-*.whl --force-reinstall +else +wheel: + $(error Pyosys is not enabled. Set ENABLE_PYOSYS=1 to enable it.) + +install-wheel: + $(error Pyosys is not enabled. Set ENABLE_PYOSYS=1 to enable it.) +endif install: $(TARGETS) $(EXTRA_TARGETS) $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR) @@ -1078,6 +1086,7 @@ clean: rm -rf kernel/*.pyh rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES) $(PY_WRAPPER_FILE).cc rm -f kernel/version_*.o kernel/version_*.cc + rm -f kernel/python_wrappers.o rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d rm -rf tests/asicworld/*.out tests/asicworld/*.log rm -rf tests/hana/*.out tests/hana/*.log @@ -1091,6 +1100,8 @@ clean: rm -f $(addsuffix /run-test.mk,$(MK_TEST_DIRS)) -$(MAKE) -C docs clean rm -rf docs/source/cmd docs/util/__pycache__ + rm -f *.whl + rm -f libyosys.so clean-abc: $(MAKE) -C abc DEP= clean From dab67f84dae6bc5240fd492a627f3ba2eedf8bd1 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 5 Apr 2025 10:40:19 +1300 Subject: [PATCH 120/133] rtlil.h: Document selections --- kernel/rtlil.h | 103 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 6 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c81990f43..97160e1d9 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1164,26 +1164,60 @@ public: struct RTLIL::Selection { - bool full_selection; + // selection includes boxed modules bool selects_boxes; + // selection covers full design, including boxed modules bool complete_selection; + // selection covers full design, not including boxed modules + bool full_selection; pool selected_modules; dict> selected_members; RTLIL::Design *current_design; - Selection(bool full = true, bool boxes = false, RTLIL::Design *design = nullptr) : + // create a new selection + Selection( + // should the selection cover the full design + bool full = true, + // should the selection include boxed modules + bool boxes = false, + // the design to select from + RTLIL::Design *design = nullptr + ) : full_selection(full && !boxes), selects_boxes(boxes), complete_selection(full && boxes), current_design(design) { } + // checks if the given module exists in the current design and is a + // boxed module, warning the user if the current design is not set bool boxed_module(const RTLIL::IdString &mod_name) const; + + // checks if the given module is included in this selection bool selected_module(const RTLIL::IdString &mod_name) const; + + // checks if the given module is wholly included in this selection, + // i.e. not partially selected bool selected_whole_module(const RTLIL::IdString &mod_name) const; + + // checks if the given member from the given module is included in this + // selection bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; + + // optimizes this selection for the given design by: + // - removing non-existent modules and members, any boxed modules and + // their members (if selection does not include boxes), and any + // partially selected modules with no selected members; + // - marking partially selected modules as wholly selected if all + // members of that module are selected; and + // - marking selection as a complete_selection if all modules in the + // given design are selected, or a full_selection if it does not + // include boxes. void optimize(RTLIL::Design *design); + // checks if selection covers full design (may or may not include + // boxed-modules) bool selects_all() const { return full_selection || complete_selection; } + // add whole module to this selection template void select(T1 *module) { if (!selects_all() && selected_modules.count(module->name) == 0) { selected_modules.insert(module->name); @@ -1193,6 +1227,7 @@ struct RTLIL::Selection } } + // add member of module to this selection template void select(T1 *module, T2 *member) { if (!selects_all() && selected_modules.count(module->name) == 0) { selected_members[module->name].insert(member->name); @@ -1201,12 +1236,18 @@ struct RTLIL::Selection } } + // checks if selection is empty bool empty() const { return !selects_all() && selected_modules.empty() && selected_members.empty(); } + // create a new selection which is empty static Selection EmptySelection(RTLIL::Design *design = nullptr) { return Selection(false, false, design); }; + + // create a new selection with all non-boxed modules static Selection FullSelection(RTLIL::Design *design = nullptr) { return Selection(true, false, design); }; + + // create a new selection with all modules, including boxes static Selection CompleteSelection(RTLIL::Design *design = nullptr) { return Selection(true, true, design); }; }; @@ -1288,61 +1329,111 @@ struct RTLIL::Design void check(); void optimize(); + // checks if the given module is included in the current selection bool selected_module(const RTLIL::IdString &mod_name) const; + + // checks if the given module is wholly included in the current + // selection, i.e. not partially selected bool selected_whole_module(const RTLIL::IdString &mod_name) const; + + // checks if the given member from the given module is included in the + // current selection bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; + // checks if the given module is included in the current selection bool selected_module(RTLIL::Module *mod) const; + + // checks if the given module is wholly included in the current + // selection, i.e. not partially selected bool selected_whole_module(RTLIL::Module *mod) const; + // push the given selection to the selection stack void push_selection(RTLIL::Selection sel); + // push a new selection to the selection stack, with nothing selected void push_empty_selection(); - void push_full_selection(); // all modules excluding boxes - void push_complete_selection(); // all modules including boxes + // push a new selection to the selection stack, with all non-boxed + // modules selected + void push_full_selection(); + // push a new selection to the selection stack, with all modules + // selected including boxes + void push_complete_selection(); + // pop the current selection from the stack, returning to a full + // selection (no boxes) if the stack is empty void pop_selection(); + // get the current selection RTLIL::Selection &selection() { return selection_stack.back(); } + // get the current selection const RTLIL::Selection &selection() const { return selection_stack.back(); } + // is the current selection a full selection (no boxes) bool full_selection() const { return selection().full_selection; } + // is the given module in the current selection template bool selected(T1 *module) const { return selected_module(module->name); } + // is the given member of the given module in the current selection template bool selected(T1 *module, T2 *member) const { return selected_member(module->name, member->name); } + // add whole module to the current selection template void select(T1 *module) { RTLIL::Selection &sel = selection(); sel.select(module); } + // add member of module to the current selection template void select(T1 *module, T2 *member) { RTLIL::Selection &sel = selection(); sel.select(module, member); } - std::vector selected_modules(RTLIL::SelectPartials partials = SELECT_ALL, RTLIL::SelectBoxes boxes = SB_UNBOXED_WARN) const; + // returns all selected modules + std::vector selected_modules( + // controls if partially selected modules are included + RTLIL::SelectPartials partials = SELECT_ALL, + // controls if boxed modules are included + RTLIL::SelectBoxes boxes = SB_UNBOXED_WARN + ) const; + // returns all selected modules, and may include boxes std::vector all_selected_modules() const { return selected_modules(SELECT_ALL, SB_ALL); } + // returns all selected unboxed modules, silently ignoring any boxed + // modules in the selection std::vector selected_unboxed_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_ONLY); } + // returns all selected unboxed modules, warning the user if any boxed + // modules have been ignored std::vector selected_unboxed_modules_warn() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } [[deprecated("Use select_unboxed_whole_modules() to maintain prior behaviour, or consider one of the other selected whole module helpers.")]] std::vector selected_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_UNBOXED_WARN); } + // returns all selected whole modules, silently ignoring partially + // selected modules, and may include boxes std::vector all_selected_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_ALL); } - std::vector selected_whole_modules_warn(bool include_wb = false) const { return selected_modules(SELECT_WHOLE_WARN, include_wb ? SB_EXCL_BB_WARN : SB_UNBOXED_WARN); } + // returns all selected whole modules, warning the user if any partially + // selected or boxed modules have been ignored; optionally includes + // selected whole modules with the 'whitebox' attribute + std::vector selected_whole_modules_warn( + // should whole modules with the 'whitebox' attribute be + // included + bool include_wb = false + ) const { return selected_modules(SELECT_WHOLE_WARN, include_wb ? SB_EXCL_BB_WARN : SB_UNBOXED_WARN); } + // returns all selected unboxed whole modules, silently ignoring + // partially selected or boxed modules std::vector selected_unboxed_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_UNBOXED_ONLY); } + // returns all selected unboxed whole modules, warning the user if any + // partially selected or boxed modules have been ignored std::vector selected_unboxed_whole_modules_warn() const { return selected_modules(SELECT_WHOLE_WARN, SB_UNBOXED_WARN); } #ifdef WITH_PYTHON static std::map *get_all_designs(void); From d8a9ad686009f1f09b2c6f6d73f98a4db54d7f78 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 5 Apr 2025 10:56:01 +1300 Subject: [PATCH 121/133] Add Selection::clear() method Use method in `select.cc` to reduce code duplication. --- kernel/rtlil.cc | 8 ++++++++ kernel/rtlil.h | 3 +++ passes/cmds/select.cc | 26 ++++++-------------------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index c9d2f6760..637cc9be3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -891,6 +891,14 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) } } +void RTLIL::Selection::clear() +{ + full_selection = false; + complete_selection = false; + selected_modules.clear(); + selected_members.clear(); +} + RTLIL::Design::Design() : verilog_defines (new define_map_t) { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 97160e1d9..52e7a17e7 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1241,6 +1241,9 @@ struct RTLIL::Selection return !selects_all() && selected_modules.empty() && selected_members.empty(); } + // clear this selection, leaving it empty + void clear(); + // create a new selection which is empty static Selection EmptySelection(RTLIL::Design *design = nullptr) { return Selection(false, false, design); }; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index c34cf43c6..1d75091af 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -159,10 +159,7 @@ static void select_all(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) { if (lhs.selects_all()) { - lhs.full_selection = false; - lhs.complete_selection = false; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); + lhs.clear(); return; } @@ -341,9 +338,8 @@ static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const for (auto mod : new_rhs.selected_modules) lhs.selected_modules.insert(mod); } else { + lhs.clear(); lhs.full_selection = true; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); } return; } @@ -361,10 +357,7 @@ static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { if (rhs.complete_selection) { - lhs.full_selection = false; - lhs.complete_selection = false; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); + lhs.clear(); return; } @@ -378,9 +371,7 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R lhs.selected_members.erase(mod); } } else { - lhs.full_selection = false; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); + lhs.clear(); } return; } @@ -435,10 +426,7 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co return; if (rhs.empty()) { - lhs.full_selection = false; - lhs.complete_selection = false; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); + lhs.clear(); return; } @@ -680,9 +668,7 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se return; if (sel.full_selection) { - sel.full_selection = false; - sel.selected_modules.clear(); - sel.selected_members.clear(); + sel.clear(); sel.selected_modules.insert(design->selected_active_module); return; } From 331952f78dd6c2d0ac6c3036bea6a58f63c7969a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 00:22:08 +0000 Subject: [PATCH 122/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 286e3d48a..249d29f85 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+107 +YOSYS_VER := 0.51+125 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 7a1729e60916a6dfd5a2a1c8e155ab36a50d1732 Mon Sep 17 00:00:00 2001 From: Adrien Prost-Boucle Date: Sun, 6 Apr 2025 11:43:17 +0200 Subject: [PATCH 123/133] Fix mux xilinx mapping when all inputs are x --- techlibs/xilinx/cells_map.v | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 2b8eade2f..846f03bb9 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -184,10 +184,17 @@ module \$__XILINX_SHIFTX (A, B, Y); assign A_i[i] = A[i*2]; \$__XILINX_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH((A_WIDTH+1'd1)/2'd2), .B_WIDTH(B_WIDTH-1'd1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_i), .B(B[B_WIDTH-1:1]), .Y(Y)); end - // Trim off any leading 1'bx -es in A + // Handle presence of leading 1'bx -es in A else if (_TECHMAP_CONSTMSK_A_[A_WIDTH-1] && _TECHMAP_CONSTVAL_A_[A_WIDTH-1] === 1'bx) begin - localparam A_WIDTH_new = A_WIDTH_trimmed(A_WIDTH-1); - \$__XILINX_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH_new), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A[A_WIDTH_new-1:0]), .B(B), .Y(Y)); + // Replace by 1'bx if A is only 'x + if (A_WIDTH_trimmed(A_WIDTH-1) == 0) begin + assign Y = 1'bx; + end + // Trim off any leading 1'bx -es in A + else begin + localparam A_WIDTH_new = A_WIDTH_trimmed(A_WIDTH-1); + \$__XILINX_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH_new), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A[A_WIDTH_new-1:0]), .B(B), .Y(Y)); + end end else if (A_WIDTH < `MIN_MUX_INPUTS) begin wire _TECHMAP_FAIL_ = 1; From 3911a627a889e9303ecbe47ffd10d11510355508 Mon Sep 17 00:00:00 2001 From: Adrien Prost-Boucle Date: Mon, 7 Apr 2025 07:55:30 +0200 Subject: [PATCH 124/133] Clearer diff for the all-x corner case --- techlibs/xilinx/cells_map.v | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 846f03bb9..c1b911b0b 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -184,17 +184,13 @@ module \$__XILINX_SHIFTX (A, B, Y); assign A_i[i] = A[i*2]; \$__XILINX_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH((A_WIDTH+1'd1)/2'd2), .B_WIDTH(B_WIDTH-1'd1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_i), .B(B[B_WIDTH-1:1]), .Y(Y)); end - // Handle presence of leading 1'bx -es in A + // Trim off any leading 1'bx -es in A else if (_TECHMAP_CONSTMSK_A_[A_WIDTH-1] && _TECHMAP_CONSTVAL_A_[A_WIDTH-1] === 1'bx) begin - // Replace by 1'bx if A is only 'x - if (A_WIDTH_trimmed(A_WIDTH-1) == 0) begin + localparam A_WIDTH_new = A_WIDTH_trimmed(A_WIDTH-1); + if (A_WIDTH_new == 0) assign Y = 1'bx; - end - // Trim off any leading 1'bx -es in A - else begin - localparam A_WIDTH_new = A_WIDTH_trimmed(A_WIDTH-1); + else \$__XILINX_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH_new), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A[A_WIDTH_new-1:0]), .B(B), .Y(Y)); - end end else if (A_WIDTH < `MIN_MUX_INPUTS) begin wire _TECHMAP_FAIL_ = 1; From d49364d96fac7d62b12243601534e9593e1bf3f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Milanovi=C4=87?= Date: Mon, 7 Apr 2025 12:11:55 +0200 Subject: [PATCH 125/133] Revert "Refactor full_selection" --- backends/firrtl/firrtl.cc | 5 +- backends/rtlil/rtlil_backend.cc | 4 +- .../source/code_examples/extensions/my_cmd.cc | 4 +- .../extending_yosys/extensions.rst | 2 +- kernel/driver.cc | 2 +- kernel/register.cc | 24 +- kernel/rtlil.cc | 231 +++----------- kernel/rtlil.h | 208 ++----------- kernel/tclapi.cc | 2 +- kernel/yosys.cc | 8 +- passes/cmds/add.cc | 2 +- passes/cmds/design.cc | 6 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 289 ++++++++---------- passes/cmds/show.cc | 8 +- passes/cmds/stat.cc | 2 +- passes/cmds/viz.cc | 4 +- passes/hierarchy/submod.cc | 2 +- passes/opt/opt_clean.cc | 2 +- passes/sat/cutpoint.cc | 2 +- passes/sat/sim.cc | 4 +- passes/techmap/abc9.cc | 14 +- passes/techmap/abc9_ops.cc | 2 +- passes/techmap/abc_new.cc | 6 +- passes/techmap/aigmap.cc | 3 +- passes/techmap/clockgate.cc | 2 +- passes/techmap/nlutmap.cc | 2 +- tests/cxxrtl/run-test.sh | 2 +- tests/select/{boxes.v => blackboxes.ys} | 12 + tests/select/boxes_equals_clean.ys | 7 - tests/select/boxes_equals_name.ys | 7 - tests/select/boxes_equals_operators.ys | 38 --- tests/select/boxes_equals_pattern.ys | 7 - tests/select/boxes_equals_wildcard.ys | 6 - tests/select/boxes_no_equals.ys | 7 - tests/select/boxes_no_equals_clean.ys | 18 -- tests/select/boxes_stack.ys | 29 -- tests/simple_abc9/run-test.sh | 2 +- 38 files changed, 270 insertions(+), 707 deletions(-) rename tests/select/{boxes.v => blackboxes.ys} (51%) delete mode 100644 tests/select/boxes_equals_clean.ys delete mode 100644 tests/select/boxes_equals_name.ys delete mode 100644 tests/select/boxes_equals_operators.ys delete mode 100644 tests/select/boxes_equals_pattern.ys delete mode 100644 tests/select/boxes_equals_wildcard.ys delete mode 100644 tests/select/boxes_no_equals.ys delete mode 100644 tests/select/boxes_no_equals_clean.ys delete mode 100644 tests/select/boxes_stack.ys diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index ceb805dcb..eac0c9719 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -1215,6 +1215,9 @@ struct FirrtlBackend : public Backend { } extra_args(f, filename, args, argidx); + if (!design->full_selection()) + log_cmd_error("This command only operates on fully selected designs!\n"); + log_header(design, "Executing FIRRTL backend.\n"); log_push(); @@ -1227,7 +1230,7 @@ struct FirrtlBackend : public Backend { autoid_counter = 0; // Get the top module, or a reasonable facsimile - we need something for the circuit name. - Module *top = nullptr; + Module *top = design->top_module(); Module *last = nullptr; // Generate module and wire names. for (auto module : design->modules()) { diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index ae60ee6c7..113f1a615 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -304,8 +304,8 @@ void RTLIL_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL:: void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { - bool print_header = flag_m || module->is_selected_whole(); - bool print_body = !flag_n || !module->is_selected_whole(); + bool print_header = flag_m || design->selected_whole_module(module->name); + bool print_body = !flag_n || !design->selected_whole_module(module->name); if (print_header) { diff --git a/docs/source/code_examples/extensions/my_cmd.cc b/docs/source/code_examples/extensions/my_cmd.cc index e6660469c..36ddbe175 100644 --- a/docs/source/code_examples/extensions/my_cmd.cc +++ b/docs/source/code_examples/extensions/my_cmd.cc @@ -51,10 +51,10 @@ struct Test2Pass : public Pass { Test2Pass() : Pass("test2", "demonstrating sigmap on test module") { } void execute(std::vector, RTLIL::Design *design) override { - if (design->selection().empty()) + if (design->selection_stack.back().empty()) log_cmd_error("This command can't operator on an empty selection!\n"); - RTLIL::Module *module = design->module("\\test"); + RTLIL::Module *module = design->modules_.at("\\test"); RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")), y(module->wire("\\y")); log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index d30dd2bae..b02c4cd99 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -237,7 +237,7 @@ Use ``log_cmd_error()`` to report a recoverable error: .. code:: C++ - if (design->selection().empty()) + if (design->selection_stack.back().empty()) log_cmd_error("This command can't operator on an empty selection!\n"); Use ``log_assert()`` and ``log_abort()`` instead of ``assert()`` and ``abort()``. diff --git a/kernel/driver.cc b/kernel/driver.cc index eb1326ce0..a3d85bd90 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -111,7 +111,7 @@ void run(const char *command) log_last_error = ""; } catch (...) { while (GetSize(yosys_get_design()->selection_stack) > selSize) - yosys_get_design()->pop_selection(); + yosys_get_design()->selection_stack.pop_back(); throw; } } diff --git a/kernel/register.cc b/kernel/register.cc index c52bfb5b8..fcb6ca769 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -260,18 +260,18 @@ void Pass::call(RTLIL::Design *design, std::vector args) pass_register[args[0]]->execute(args, design); pass_register[args[0]]->post_execute(state); while (design->selection_stack.size() > orig_sel_stack_pos) - design->pop_selection(); + design->selection_stack.pop_back(); } void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command) { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->push_selection(selection); + design->selection_stack.push_back(selection); Pass::call(design, command); - design->pop_selection(); + design->selection_stack.pop_back(); design->selected_active_module = backup_selected_active_module; } @@ -279,11 +279,11 @@ void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &sele { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->push_selection(selection); + design->selection_stack.push_back(selection); Pass::call(design, args); - design->pop_selection(); + design->selection_stack.pop_back(); design->selected_active_module = backup_selected_active_module; } @@ -291,12 +291,12 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::str { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module = module->name.str(); - design->push_empty_selection(); - design->select(module); + design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.back().select(module); Pass::call(design, command); - design->pop_selection(); + design->selection_stack.pop_back(); design->selected_active_module = backup_selected_active_module; } @@ -304,12 +304,12 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vec { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module = module->name.str(); - design->push_empty_selection(); - design->select(module); + design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.back().select(module); Pass::call(design, args); - design->pop_selection(); + design->selection_stack.pop_back(); design->selected_active_module = backup_selected_active_module; } @@ -651,7 +651,7 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f } while (design->selection_stack.size() > orig_sel_stack_pos) - design->pop_selection(); + design->selection_stack.pop_back(); } struct SimHelper { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 637cc9be3..3b9a4a8b1 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -766,23 +766,8 @@ vector RTLIL::AttrObject::get_intvec_attribute(const RTLIL::IdString &id) c return data; } -bool RTLIL::Selection::boxed_module(const RTLIL::IdString &mod_name) const -{ - if (current_design != nullptr) { - auto module = current_design->module(mod_name); - return module && module->get_blackbox_attribute(); - } else { - log_warning("Unable to check if module is boxed for null design.\n"); - return false; - } -} - bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const { - if (complete_selection) - return true; - if (!selects_boxes && boxed_module(mod_name)) - return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -794,10 +779,6 @@ bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) const { - if (complete_selection) - return true; - if (!selects_boxes && boxed_module(mod_name)) - return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -807,10 +788,6 @@ bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) co bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const { - if (complete_selection) - return true; - if (!selects_boxes && boxed_module(mod_name)) - return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -823,17 +800,7 @@ bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RT void RTLIL::Selection::optimize(RTLIL::Design *design) { - if (design != current_design) { - current_design = design; - } - - if (selects_boxes && full_selection) - complete_selection = true; - if (complete_selection) { - full_selection = false; - selects_boxes = true; - } - if (selects_all()) { + if (full_selection) { selected_modules.clear(); selected_members.clear(); return; @@ -843,7 +810,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto mod_name : selected_modules) { - if (current_design->modules_.count(mod_name) == 0 || (!selects_boxes && boxed_module(mod_name))) + if (design->modules_.count(mod_name) == 0) del_list.push_back(mod_name); selected_members.erase(mod_name); } @@ -852,7 +819,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto &it : selected_members) - if (current_design->modules_.count(it.first) == 0 || (!selects_boxes && boxed_module(it.first))) + if (design->modules_.count(it.first) == 0) del_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -860,7 +827,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) { del_list.clear(); for (auto memb_name : it.second) - if (current_design->modules_[it.first]->count_id(memb_name) == 0) + if (design->modules_[it.first]->count_id(memb_name) == 0) del_list.push_back(memb_name); for (auto memb_name : del_list) it.second.erase(memb_name); @@ -871,8 +838,8 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) if (it.second.size() == 0) del_list.push_back(it.first); - else if (it.second.size() == current_design->modules_[it.first]->wires_.size() + current_design->modules_[it.first]->memories.size() + - current_design->modules_[it.first]->cells_.size() + current_design->modules_[it.first]->processes.size()) + else if (it.second.size() == design->modules_[it.first]->wires_.size() + design->modules_[it.first]->memories.size() + + design->modules_[it.first]->cells_.size() + design->modules_[it.first]->processes.size()) add_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -881,24 +848,13 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) selected_modules.insert(mod_name); } - if (selected_modules.size() == current_design->modules_.size()) { + if (selected_modules.size() == design->modules_.size()) { + full_selection = true; selected_modules.clear(); selected_members.clear(); - if (selects_boxes) - complete_selection = true; - else - full_selection = true; } } -void RTLIL::Selection::clear() -{ - full_selection = false; - complete_selection = false; - selected_modules.clear(); - selected_members.clear(); -} - RTLIL::Design::Design() : verilog_defines (new define_map_t) { @@ -907,7 +863,7 @@ RTLIL::Design::Design() hashidx_ = hashidx_count; refcount_modules_ = 0; - push_full_selection(); + selection_stack.push_back(RTLIL::Selection()); #ifdef WITH_PYTHON RTLIL::Design::get_all_designs()->insert(std::pair(hashidx_, this)); @@ -952,7 +908,7 @@ const RTLIL::Module *RTLIL::Design::module(const RTLIL::IdString& name) const return modules_.count(name) ? modules_.at(name) : NULL; } -RTLIL::Module *RTLIL::Design::top_module() const +RTLIL::Module *RTLIL::Design::top_module() { RTLIL::Module *module = nullptr; int module_count = 0; @@ -1110,7 +1066,6 @@ void RTLIL::Design::sort() void RTLIL::Design::check() { #ifndef NDEBUG - log_assert(!selection_stack.empty()); for (auto &it : modules_) { log_assert(this == it.second->design); log_assert(it.first == it.second->name); @@ -1134,21 +1089,27 @@ bool RTLIL::Design::selected_module(const RTLIL::IdString& mod_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - return selection().selected_module(mod_name); + if (selection_stack.size() == 0) + return true; + return selection_stack.back().selected_module(mod_name); } bool RTLIL::Design::selected_whole_module(const RTLIL::IdString& mod_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - return selection().selected_whole_module(mod_name); + if (selection_stack.size() == 0) + return true; + return selection_stack.back().selected_whole_module(mod_name); } bool RTLIL::Design::selected_member(const RTLIL::IdString& mod_name, const RTLIL::IdString& memb_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - return selection().selected_member(mod_name, memb_name); + if (selection_stack.size() == 0) + return true; + return selection_stack.back().selected_member(mod_name, memb_name); } bool RTLIL::Design::selected_module(RTLIL::Module *mod) const @@ -1161,86 +1122,37 @@ bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const return selected_whole_module(mod->name); } -void RTLIL::Design::push_selection(RTLIL::Selection sel) +std::vector RTLIL::Design::selected_modules() const { - sel.current_design = this; - selection_stack.push_back(sel); -} - -void RTLIL::Design::push_empty_selection() -{ - push_selection(RTLIL::Selection::EmptySelection(this)); -} - -void RTLIL::Design::push_full_selection() -{ - push_selection(RTLIL::Selection::FullSelection(this)); -} - -void RTLIL::Design::push_complete_selection() -{ - push_selection(RTLIL::Selection::CompleteSelection(this)); -} - -void RTLIL::Design::pop_selection() -{ - selection_stack.pop_back(); - // Default to a full_selection if we ran out of stack - if (selection_stack.empty()) - push_full_selection(); -} - -std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const -{ - bool include_partials = partials == RTLIL::SELECT_ALL; - bool exclude_boxes = (partials & RTLIL::SB_UNBOXED_ONLY) != 0; - bool ignore_wb = (partials & RTLIL::SB_INCL_WB) != 0; std::vector result; result.reserve(modules_.size()); for (auto &it : modules_) - if (selected_whole_module(it.first) || (include_partials && selected_module(it.first))) { - if (!(exclude_boxes && it.second->get_blackbox_attribute(ignore_wb))) - result.push_back(it.second); - else - switch (boxes) - { - case RTLIL::SB_UNBOXED_WARN: - log_warning("Ignoring boxed module %s.\n", log_id(it.first)); - break; - case RTLIL::SB_EXCL_BB_WARN: - log_warning("Ignoring blackbox module %s.\n", log_id(it.first)); - break; - case RTLIL::SB_UNBOXED_ERR: - log_error("Unsupported boxed module %s.\n", log_id(it.first)); - break; - case RTLIL::SB_EXCL_BB_ERR: - log_error("Unsupported blackbox module %s.\n", log_id(it.first)); - break; - case RTLIL::SB_UNBOXED_CMDERR: - log_cmd_error("Unsupported boxed module %s.\n", log_id(it.first)); - break; - case RTLIL::SB_EXCL_BB_CMDERR: - log_cmd_error("Unsupported blackbox module %s.\n", log_id(it.first)); - break; - default: - break; - } - } else if (!include_partials && selected_module(it.first)) { - switch(partials) - { - case RTLIL::SELECT_WHOLE_WARN: - log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); - break; - case RTLIL::SELECT_WHOLE_ERR: - log_error("Unsupported partially selected module %s.\n", log_id(it.first)); - break; - case RTLIL::SELECT_WHOLE_CMDERR: - log_cmd_error("Unsupported partially selected module %s.\n", log_id(it.first)); - break; - default: - break; - } - } + if (selected_module(it.first) && !it.second->get_blackbox_attribute()) + result.push_back(it.second); + return result; +} + +std::vector RTLIL::Design::selected_whole_modules() const +{ + std::vector result; + result.reserve(modules_.size()); + for (auto &it : modules_) + if (selected_whole_module(it.first) && !it.second->get_blackbox_attribute()) + result.push_back(it.second); + return result; +} + +std::vector RTLIL::Design::selected_whole_modules_warn(bool include_wb) const +{ + std::vector result; + result.reserve(modules_.size()); + for (auto &it : modules_) + if (it.second->get_blackbox_attribute(include_wb)) + continue; + else if (selected_whole_module(it.first)) + result.push_back(it.second); + else if (selected_module(it.first)) + log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); return result; } @@ -2372,13 +2284,6 @@ void RTLIL::Module::check() log_assert(!packed_memids.count(memid)); packed_memids.insert(memid); } - auto cell_mod = design->module(it.first); - if (cell_mod != nullptr) { - // assertion check below to make sure that there are no - // cases where a cell has a blackbox attribute since - // that is deprecated - log_assert(!it.second->get_blackbox_attribute()); - } } for (auto &it : processes) { @@ -2506,16 +2411,6 @@ bool RTLIL::Module::has_processes_warn() const return !processes.empty(); } -bool RTLIL::Module::is_selected() const -{ - return design->selected_module(this->name); -} - -bool RTLIL::Module::is_selected_whole() const -{ - return design->selected_whole_module(this->name); -} - std::vector RTLIL::Module::selected_wires() const { std::vector result; @@ -2536,40 +2431,6 @@ std::vector RTLIL::Module::selected_cells() const return result; } -std::vector RTLIL::Module::selected_memories() const -{ - std::vector result; - result.reserve(memories.size()); - for (auto &it : memories) - if (design->selected(this, it.second)) - result.push_back(it.second); - return result; -} - -std::vector RTLIL::Module::selected_processes() const -{ - std::vector result; - result.reserve(processes.size()); - for (auto &it : processes) - if (design->selected(this, it.second)) - result.push_back(it.second); - return result; -} - -std::vector RTLIL::Module::selected_members() const -{ - std::vector result; - auto cells = selected_cells(); - auto memories = selected_memories(); - auto wires = selected_wires(); - auto processes = selected_processes(); - result.insert(result.end(), cells.begin(), cells.end()); - result.insert(result.end(), memories.begin(), memories.end()); - result.insert(result.end(), wires.begin(), wires.end()); - result.insert(result.end(), processes.begin(), processes.end()); - return result; -} - void RTLIL::Module::add(RTLIL::Wire *wire) { log_assert(!wire->name.empty()); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 52e7a17e7..f1bd96be7 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -56,33 +56,8 @@ namespace RTLIL CONST_FLAG_REAL = 4 // only used for parameters }; - enum SelectPartials : unsigned char { - SELECT_ALL = 0, // include partial modules - SELECT_WHOLE_ONLY = 1, // ignore partial modules - SELECT_WHOLE_WARN = 2, // call log_warning on partial module - SELECT_WHOLE_ERR = 3, // call log_error on partial module - SELECT_WHOLE_CMDERR = 4 // call log_cmd_error on partial module - }; - - enum SelectBoxes : unsigned char { - SB_ALL = 0, // include boxed modules - SB_WARN = 1, // helper for log_warning - SB_ERR = 2, // helper for log_error - SB_CMDERR = 3, // helper for log_cmd_error - SB_UNBOXED_ONLY = 4, // ignore boxed modules - SB_UNBOXED_WARN = 5, // call log_warning on boxed module - SB_UNBOXED_ERR = 6, // call log_error on boxed module - SB_UNBOXED_CMDERR = 7, // call log_cmd_error on boxed module - SB_INCL_WB = 8, // helper for white boxes - SB_EXCL_BB_ONLY = 12, // ignore black boxes, but not white boxes - SB_EXCL_BB_WARN = 13, // call log_warning on black boxed module - SB_EXCL_BB_ERR = 14, // call log_error on black boxed module - SB_EXCL_BB_CMDERR = 15 // call log_cmd_error on black boxed module - }; - struct Const; struct AttrObject; - struct NamedObject; struct Selection; struct Monitor; struct Design; @@ -894,11 +869,6 @@ struct RTLIL::AttrObject vector get_intvec_attribute(const RTLIL::IdString &id) const; }; -struct RTLIL::NamedObject : public RTLIL::AttrObject -{ - RTLIL::IdString name; -}; - struct RTLIL::SigChunk { RTLIL::Wire *wire; @@ -1164,94 +1134,32 @@ public: struct RTLIL::Selection { - // selection includes boxed modules - bool selects_boxes; - // selection covers full design, including boxed modules - bool complete_selection; - // selection covers full design, not including boxed modules bool full_selection; pool selected_modules; dict> selected_members; - RTLIL::Design *current_design; - // create a new selection - Selection( - // should the selection cover the full design - bool full = true, - // should the selection include boxed modules - bool boxes = false, - // the design to select from - RTLIL::Design *design = nullptr - ) : - full_selection(full && !boxes), selects_boxes(boxes), complete_selection(full && boxes), current_design(design) { } + Selection(bool full = true) : full_selection(full) { } - // checks if the given module exists in the current design and is a - // boxed module, warning the user if the current design is not set - bool boxed_module(const RTLIL::IdString &mod_name) const; - - // checks if the given module is included in this selection bool selected_module(const RTLIL::IdString &mod_name) const; - - // checks if the given module is wholly included in this selection, - // i.e. not partially selected bool selected_whole_module(const RTLIL::IdString &mod_name) const; - - // checks if the given member from the given module is included in this - // selection bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; - - // optimizes this selection for the given design by: - // - removing non-existent modules and members, any boxed modules and - // their members (if selection does not include boxes), and any - // partially selected modules with no selected members; - // - marking partially selected modules as wholly selected if all - // members of that module are selected; and - // - marking selection as a complete_selection if all modules in the - // given design are selected, or a full_selection if it does not - // include boxes. void optimize(RTLIL::Design *design); - // checks if selection covers full design (may or may not include - // boxed-modules) - bool selects_all() const { - return full_selection || complete_selection; - } - - // add whole module to this selection template void select(T1 *module) { - if (!selects_all() && selected_modules.count(module->name) == 0) { + if (!full_selection && selected_modules.count(module->name) == 0) { selected_modules.insert(module->name); selected_members.erase(module->name); - if (module->get_blackbox_attribute()) - selects_boxes = true; } } - // add member of module to this selection template void select(T1 *module, T2 *member) { - if (!selects_all() && selected_modules.count(module->name) == 0) { + if (!full_selection && selected_modules.count(module->name) == 0) selected_members[module->name].insert(member->name); - if (module->get_blackbox_attribute()) - selects_boxes = true; - } } - // checks if selection is empty bool empty() const { - return !selects_all() && selected_modules.empty() && selected_members.empty(); + return !full_selection && selected_modules.empty() && selected_members.empty(); } - - // clear this selection, leaving it empty - void clear(); - - // create a new selection which is empty - static Selection EmptySelection(RTLIL::Design *design = nullptr) { return Selection(false, false, design); }; - - // create a new selection with all non-boxed modules - static Selection FullSelection(RTLIL::Design *design = nullptr) { return Selection(true, false, design); }; - - // create a new selection with all modules, including boxes - static Selection CompleteSelection(RTLIL::Design *design = nullptr) { return Selection(true, true, design); }; }; struct RTLIL::Monitor @@ -1305,7 +1213,7 @@ struct RTLIL::Design RTLIL::ObjRange modules(); RTLIL::Module *module(const RTLIL::IdString &name); const RTLIL::Module *module(const RTLIL::IdString &name) const; - RTLIL::Module *top_module() const; + RTLIL::Module *top_module(); bool has(const RTLIL::IdString &id) const { return modules_.count(id) != 0; @@ -1332,118 +1240,57 @@ struct RTLIL::Design void check(); void optimize(); - // checks if the given module is included in the current selection bool selected_module(const RTLIL::IdString &mod_name) const; - - // checks if the given module is wholly included in the current - // selection, i.e. not partially selected bool selected_whole_module(const RTLIL::IdString &mod_name) const; - - // checks if the given member from the given module is included in the - // current selection bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; - // checks if the given module is included in the current selection bool selected_module(RTLIL::Module *mod) const; - - // checks if the given module is wholly included in the current - // selection, i.e. not partially selected bool selected_whole_module(RTLIL::Module *mod) const; - // push the given selection to the selection stack - void push_selection(RTLIL::Selection sel); - // push a new selection to the selection stack, with nothing selected - void push_empty_selection(); - // push a new selection to the selection stack, with all non-boxed - // modules selected - void push_full_selection(); - // push a new selection to the selection stack, with all modules - // selected including boxes - void push_complete_selection(); - // pop the current selection from the stack, returning to a full - // selection (no boxes) if the stack is empty - void pop_selection(); - - // get the current selection RTLIL::Selection &selection() { return selection_stack.back(); } - // get the current selection const RTLIL::Selection &selection() const { return selection_stack.back(); } - // is the current selection a full selection (no boxes) bool full_selection() const { - return selection().full_selection; + return selection_stack.back().full_selection; } - // is the given module in the current selection template bool selected(T1 *module) const { return selected_module(module->name); } - // is the given member of the given module in the current selection template bool selected(T1 *module, T2 *member) const { return selected_member(module->name, member->name); } - // add whole module to the current selection template void select(T1 *module) { - RTLIL::Selection &sel = selection(); - sel.select(module); + if (selection_stack.size() > 0) { + RTLIL::Selection &sel = selection_stack.back(); + sel.select(module); + } } - // add member of module to the current selection template void select(T1 *module, T2 *member) { - RTLIL::Selection &sel = selection(); - sel.select(module, member); + if (selection_stack.size() > 0) { + RTLIL::Selection &sel = selection_stack.back(); + sel.select(module, member); + } } - // returns all selected modules - std::vector selected_modules( - // controls if partially selected modules are included - RTLIL::SelectPartials partials = SELECT_ALL, - // controls if boxed modules are included - RTLIL::SelectBoxes boxes = SB_UNBOXED_WARN - ) const; - - // returns all selected modules, and may include boxes - std::vector all_selected_modules() const { return selected_modules(SELECT_ALL, SB_ALL); } - // returns all selected unboxed modules, silently ignoring any boxed - // modules in the selection - std::vector selected_unboxed_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_ONLY); } - // returns all selected unboxed modules, warning the user if any boxed - // modules have been ignored - std::vector selected_unboxed_modules_warn() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } - - [[deprecated("Use select_unboxed_whole_modules() to maintain prior behaviour, or consider one of the other selected whole module helpers.")]] - std::vector selected_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_UNBOXED_WARN); } - // returns all selected whole modules, silently ignoring partially - // selected modules, and may include boxes - std::vector all_selected_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_ALL); } - // returns all selected whole modules, warning the user if any partially - // selected or boxed modules have been ignored; optionally includes - // selected whole modules with the 'whitebox' attribute - std::vector selected_whole_modules_warn( - // should whole modules with the 'whitebox' attribute be - // included - bool include_wb = false - ) const { return selected_modules(SELECT_WHOLE_WARN, include_wb ? SB_EXCL_BB_WARN : SB_UNBOXED_WARN); } - // returns all selected unboxed whole modules, silently ignoring - // partially selected or boxed modules - std::vector selected_unboxed_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_UNBOXED_ONLY); } - // returns all selected unboxed whole modules, warning the user if any - // partially selected or boxed modules have been ignored - std::vector selected_unboxed_whole_modules_warn() const { return selected_modules(SELECT_WHOLE_WARN, SB_UNBOXED_WARN); } + std::vector selected_modules() const; + std::vector selected_whole_modules() const; + std::vector selected_whole_modules_warn(bool include_wb = false) const; #ifdef WITH_PYTHON static std::map *get_all_designs(void); #endif }; -struct RTLIL::Module : public RTLIL::NamedObject +struct RTLIL::Module : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1466,6 +1313,7 @@ public: std::vector connections_; std::vector bindings_; + RTLIL::IdString name; idict avail_parameters; dict parameter_default_values; dict memories; @@ -1510,14 +1358,8 @@ public: bool has_memories_warn() const; bool has_processes_warn() const; - bool is_selected() const; - bool is_selected_whole() const; - std::vector selected_wires() const; std::vector selected_cells() const; - std::vector selected_memories() const; - std::vector selected_processes() const; - std::vector selected_members() const; template bool selected(T *member) const { return design->selected_member(name, member->name); @@ -1803,7 +1645,7 @@ namespace RTLIL_BACKEND { void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); } -struct RTLIL::Wire : public RTLIL::NamedObject +struct RTLIL::Wire : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1826,6 +1668,7 @@ public: void operator=(RTLIL::Wire &other) = delete; RTLIL::Module *module; + RTLIL::IdString name; int width, start_offset, port_id; bool port_input, port_output, upto, is_signed; @@ -1854,13 +1697,14 @@ inline int GetSize(RTLIL::Wire *wire) { return wire->width; } -struct RTLIL::Memory : public RTLIL::NamedObject +struct RTLIL::Memory : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } Memory(); + RTLIL::IdString name; int width, start_offset, size; #ifdef WITH_PYTHON ~Memory(); @@ -1868,7 +1712,7 @@ struct RTLIL::Memory : public RTLIL::NamedObject #endif }; -struct RTLIL::Cell : public RTLIL::NamedObject +struct RTLIL::Cell : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1885,6 +1729,7 @@ public: void operator=(RTLIL::Cell &other) = delete; RTLIL::Module *module; + RTLIL::IdString name; RTLIL::IdString type; dict connections_; dict parameters; @@ -1977,7 +1822,7 @@ struct RTLIL::SyncRule RTLIL::SyncRule *clone() const; }; -struct RTLIL::Process : public RTLIL::NamedObject +struct RTLIL::Process : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1989,6 +1834,7 @@ protected: ~Process(); public: + RTLIL::IdString name; RTLIL::Module *module; RTLIL::CaseRule root_case; std::vector syncs; diff --git a/kernel/tclapi.cc b/kernel/tclapi.cc index e970779d7..be39ca4a0 100644 --- a/kernel/tclapi.cc +++ b/kernel/tclapi.cc @@ -114,7 +114,7 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a if (in_repl) { auto design = yosys_get_design(); while (design->selection_stack.size() > 1) - design->pop_selection(); + design->selection_stack.pop_back(); log_reset_stack(); } Tcl_SetResult(interp, (char *)"Yosys command produced an error", TCL_STATIC); diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 9b0bc92ce..a5520e6ef 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -312,11 +312,11 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter) str += "yosys"; if (!design->selected_active_module.empty()) str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module).c_str()); - if (!design->full_selection()) { + if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { if (design->selected_active_module.empty()) str += "*"; - else if (design->selection().selected_modules.size() != 1 || design->selection().selected_members.size() != 0 || - design->selection().selected_modules.count(design->selected_active_module) == 0) + else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || + design->selection_stack.back().selected_modules.count(design->selected_active_module) == 0) str += "*"; } snprintf(buffer, 100, "%s> ", str.c_str()); @@ -979,7 +979,7 @@ void shell(RTLIL::Design *design) Pass::call(design, command); } catch (log_cmd_error_exception) { while (design->selection_stack.size() > 1) - design->pop_selection(); + design->selection_stack.pop_back(); log_reset_stack(); } design->check(); diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 833d6006d..c09517254 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -102,7 +102,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n RTLIL::Module *mod = design->module(cell->type); if (mod == nullptr) continue; - if (!mod->is_selected_whole()) + if (!design->selected_whole_module(mod->name)) continue; if (mod->get_blackbox_attribute()) continue; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 910c9e366..168d38563 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -216,8 +216,8 @@ struct DesignPass : public Pass { RTLIL::Selection sel; if (argidx != args.size()) { handle_extra_select_args(this, args, argidx, args.size(), copy_from_design); - sel = copy_from_design->selection(); - copy_from_design->pop_selection(); + sel = copy_from_design->selection_stack.back(); + copy_from_design->selection_stack.pop_back(); argidx = args.size(); } @@ -368,7 +368,7 @@ struct DesignPass : public Pass { design->selection_vars.clear(); design->selected_active_module.clear(); - design->push_full_selection(); + design->selection_stack.push_back(RTLIL::Selection()); } if (reset_mode || reset_vlog_mode || !load_name.empty() || push_mode || pop_mode) diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 0f988e57a..197bd9319 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -340,7 +340,7 @@ struct SccPass : public Pass { int origSelectPos = design->selection_stack.size() - 1; extra_args(args, argidx, design); - auto newSelection = RTLIL::Selection::EmptySelection(design); + RTLIL::Selection newSelection(false); int scc_counter = 0; for (auto mod : design->selected_modules()) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 1d75091af..aec4c964b 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -141,42 +141,24 @@ static bool match_attr(const dict &attributes, co return match_attr(attributes, match_expr, std::string(), 0); } -static void select_all(RTLIL::Design *design, RTLIL::Selection &lhs) -{ - if (!lhs.selects_all()) - return; - lhs.current_design = design; - lhs.selected_modules.clear(); - for (auto mod : design->modules()) { - if (!lhs.selects_boxes && mod->get_blackbox_attribute()) - continue; - lhs.selected_modules.insert(mod->name); - } - lhs.full_selection = false; - lhs.complete_selection = false; -} - static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) { - if (lhs.selects_all()) { - lhs.clear(); + if (lhs.full_selection) { + lhs.full_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); return; } if (lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { - if (lhs.selects_boxes) - lhs.complete_selection = true; - else - lhs.full_selection = true; + lhs.full_selection = true; return; } - auto new_sel = RTLIL::Selection::EmptySelection(); + RTLIL::Selection new_sel(false); for (auto mod : design->modules()) { - if (!lhs.selects_boxes && mod->get_blackbox_attribute()) - continue; if (lhs.selected_whole_module(mod->name)) continue; if (!lhs.selected_module(mod->name)) { @@ -230,7 +212,7 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c } } - lhs = RTLIL::Selection(false, lhs.selects_boxes, design); + lhs = RTLIL::Selection(false); while (!objects.empty() && count-- > 0) { @@ -261,7 +243,7 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection &lhs) { - RTLIL::Selection new_sel(false, lhs.selects_boxes, design); + RTLIL::Selection new_sel(false); for (auto mod : design->modules()) if (lhs.selected_module(mod->name)) for (auto cell : mod->cells()) @@ -272,7 +254,7 @@ static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection & static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &lhs) { - RTLIL::Selection new_sel(false, lhs.selects_boxes, design); + RTLIL::Selection new_sel(false); for (auto mod : design->modules()) for (auto cell : mod->cells()) if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type)) @@ -292,8 +274,6 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) { for (auto mod : design->modules()) { - if (!lhs.selects_boxes && mod->get_blackbox_attribute()) - continue; if (lhs.selected_whole_module(mod->name)) continue; if (!lhs.selected_module(mod->name)) @@ -312,38 +292,18 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) } } -static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) +static void select_op_union(RTLIL::Design*, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { - if (lhs.complete_selection) - return; - else if (rhs.complete_selection) { - lhs.complete_selection = true; - lhs.optimize(design); - return; - } - - if (rhs.selects_boxes) { - if (lhs.full_selection) { - select_all(design, lhs); - } - lhs.selects_boxes = true; - } - else if (lhs.full_selection) - return; - if (rhs.full_selection) { - if (lhs.selects_boxes) { - auto new_rhs = RTLIL::Selection(rhs); - select_all(design, new_rhs); - for (auto mod : new_rhs.selected_modules) - lhs.selected_modules.insert(mod); - } else { - lhs.clear(); - lhs.full_selection = true; - } + lhs.full_selection = true; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); return; } + if (lhs.full_selection) + return; + for (auto &it : rhs.selected_members) for (auto &it2 : it.second) lhs.selected_members[it.first].insert(it2); @@ -356,30 +316,20 @@ static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { - if (rhs.complete_selection) { - lhs.clear(); - return; - } - if (rhs.full_selection) { - if (lhs.selects_boxes) { - auto new_rhs = RTLIL::Selection(rhs); - select_all(design, new_rhs); - select_all(design, lhs); - for (auto mod : new_rhs.selected_modules) { - lhs.selected_modules.erase(mod); - lhs.selected_members.erase(mod); - } - } else { - lhs.clear(); - } + lhs.full_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); return; } - if (rhs.empty() || lhs.empty()) - return; - - select_all(design, lhs); + if (lhs.full_selection) { + if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0) + return; + lhs.full_selection = false; + for (auto mod : design->modules()) + lhs.selected_modules.insert(mod->name); + } for (auto &it : rhs.selected_modules) { lhs.selected_modules.erase(it); @@ -416,46 +366,38 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { - if (rhs.complete_selection) + if (rhs.full_selection) return; - if (rhs.full_selection && !lhs.selects_boxes) - return; - - if (lhs.empty()) - return; - - if (rhs.empty()) { - lhs.clear(); - return; + if (lhs.full_selection) { + lhs.full_selection = false; + for (auto mod : design->modules()) + lhs.selected_modules.insert(mod->name); } - select_all(design, lhs); - std::vector del_list; - for (auto mod_name : lhs.selected_modules) { - if (rhs.selected_whole_module(mod_name)) - continue; - if (rhs.selected_module(mod_name)) - for (auto memb_name : rhs.selected_members.at(mod_name)) - lhs.selected_members[mod_name].insert(memb_name); - del_list.push_back(mod_name); - } + for (auto &it : lhs.selected_modules) + if (rhs.selected_modules.count(it) == 0) { + if (rhs.selected_members.count(it) > 0) + for (auto &it2 : rhs.selected_members.at(it)) + lhs.selected_members[it].insert(it2); + del_list.push_back(it); + } for (auto &it : del_list) lhs.selected_modules.erase(it); del_list.clear(); for (auto &it : lhs.selected_members) { - if (rhs.selected_whole_module(it.first)) + if (rhs.selected_modules.count(it.first) > 0) continue; - if (!rhs.selected_module(it.first)) { + if (rhs.selected_members.count(it.first) == 0) { del_list.push_back(it.first); continue; } std::vector del_list2; for (auto &it2 : it.second) - if (!rhs.selected_member(it.first, it2)) + if (rhs.selected_members.at(it.first).count(it2) == 0) del_list2.push_back(it2); for (auto &it2 : del_list2) it.second.erase(it2); @@ -668,7 +610,9 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se return; if (sel.full_selection) { - sel.clear(); + sel.full_selection = false; + sel.selected_modules.clear(); + sel.selected_members.clear(); sel.selected_modules.insert(design->selected_active_module); return; } @@ -701,7 +645,8 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp if (arg[0] == '%') { if (arg == "%") { - work_stack.push_back(design->selection()); + if (design->selection_stack.size() > 0) + work_stack.push_back(design->selection_stack.back()); } else if (arg == "%%") { while (work_stack.size() > 1) { @@ -851,16 +796,15 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp } } - bool full_selection = (arg == "*" && arg_mod == "*"); - work_stack.push_back(RTLIL::Selection(full_selection, select_blackboxes, design)); + work_stack.push_back(RTLIL::Selection()); RTLIL::Selection &sel = work_stack.back(); - if (sel.full_selection) { - if (sel.selects_boxes) sel.optimize(design); + if (arg == "*" && arg_mod == "*" && select_blackboxes) { select_filter_active_mod(design, work_stack.back()); return; } + sel.full_selection = false; for (auto mod : design->modules()) { if (!select_blackboxes && mod->get_blackbox_attribute()) @@ -1001,33 +945,38 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp for (auto &it : arg_mod_found) { if (it.second == false && !disable_empty_warning) { - std::string selection_str = select_blackboxes ? "=" : ""; - selection_str += it.first; - log_warning("Selection \"%s\" did not match any module.\n", selection_str.c_str()); + log_warning("Selection \"%s\" did not match any module.\n", it.first.c_str()); } } for (auto &it : arg_memb_found) { if (it.second == false && !disable_empty_warning) { - std::string selection_str = select_blackboxes ? "=" : ""; - selection_str += it.first; - log_warning("Selection \"%s\" did not match any object.\n", selection_str.c_str()); + log_warning("Selection \"%s\" did not match any object.\n", it.first.c_str()); } } } static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel, bool whole_modules = false) { - bool push_selection = &design->selection() != sel; - if (push_selection) design->push_selection(*sel); std::string desc = "Selection contains:\n"; - for (auto mod : design->all_selected_modules()) + for (auto mod : design->modules()) { - if (whole_modules && sel->selected_whole_module(mod->name)) - desc += stringf("%s\n", id2cstr(mod->name)); - for (auto it : mod->selected_members()) - desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)); + if (sel->selected_module(mod->name)) { + if (whole_modules && sel->selected_whole_module(mod->name)) + desc += stringf("%s\n", id2cstr(mod->name)); + for (auto wire : mod->wires()) + if (sel->selected_member(mod->name, wire->name)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)); + for (auto &it : mod->memories) + if (sel->selected_member(mod->name, it.first)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); + for (auto cell : mod->cells()) + if (sel->selected_member(mod->name, cell->name)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)); + for (auto &it : mod->processes) + if (sel->selected_member(mod->name, it.first)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); + } } - if (push_selection) design->pop_selection(); return desc; } @@ -1052,9 +1001,9 @@ void handle_extra_select_args(Pass *pass, const vector &args, size_t arg work_stack.pop_back(); } if (work_stack.empty()) - design->push_empty_selection(); + design->selection_stack.push_back(RTLIL::Selection(false)); else - design->push_selection(work_stack.back()); + design->selection_stack.push_back(work_stack.back()); } // extern decl. in register.h @@ -1068,7 +1017,7 @@ RTLIL::Selection eval_select_args(const vector &args, RTLIL::Design *des work_stack.pop_back(); } if (work_stack.empty()) - return RTLIL::Selection::EmptySelection(design); + return RTLIL::Selection(false); return work_stack.back(); } @@ -1441,7 +1390,7 @@ struct SelectPass : public Pass { if (f.fail()) log_error("Can't open '%s' for reading: %s\n", read_file.c_str(), strerror(errno)); - auto sel = RTLIL::Selection::EmptySelection(design); + RTLIL::Selection sel(false); string line; while (std::getline(f, line)) { @@ -1482,7 +1431,7 @@ struct SelectPass : public Pass { log_cmd_error("Option -unset can not be combined with -list, -write, -count, -set, %s.\n", common_flagset); if (work_stack.size() == 0 && got_module) { - auto sel = RTLIL::Selection::FullSelection(design); + RTLIL::Selection sel; select_filter_active_mod(design, sel); work_stack.push_back(sel); } @@ -1492,16 +1441,16 @@ struct SelectPass : public Pass { work_stack.pop_back(); } - log_assert(!design->selection_stack.empty()); + log_assert(design->selection_stack.size() > 0); if (clear_mode) { - design->selection() = RTLIL::Selection::FullSelection(design); + design->selection_stack.back() = RTLIL::Selection(true); design->selected_active_module = std::string(); return; } if (none_mode) { - design->selection() = RTLIL::Selection::EmptySelection(design); + design->selection_stack.back() = RTLIL::Selection(false); return; } @@ -1516,17 +1465,28 @@ struct SelectPass : public Pass { if (f == nullptr) log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno)); } + RTLIL::Selection *sel = &design->selection_stack.back(); if (work_stack.size() > 0) - design->push_selection(work_stack.back()); - RTLIL::Selection *sel = &design->selection(); + sel = &work_stack.back(); sel->optimize(design); - for (auto mod : design->all_selected_modules()) + for (auto mod : design->modules()) { if (sel->selected_whole_module(mod->name) && list_mode) log("%s\n", id2cstr(mod->name)); - if (!list_mod_mode) - for (auto it : mod->selected_members()) - LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)) + if (sel->selected_module(mod->name) && !list_mod_mode) { + for (auto wire : mod->wires()) + if (sel->selected_member(mod->name, wire->name)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)) + for (auto &it : mod->memories) + if (sel->selected_member(mod->name, it.first)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) + for (auto cell : mod->cells()) + if (sel->selected_member(mod->name, cell->name)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)) + for (auto &it : mod->processes) + if (sel->selected_member(mod->name, it.first)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) + } } if (count_mode) { @@ -1535,8 +1495,6 @@ struct SelectPass : public Pass { } if (f != nullptr) fclose(f); - if (work_stack.size() > 0) - design->pop_selection(); #undef LOG_OBJECT return; } @@ -1545,8 +1503,8 @@ struct SelectPass : public Pass { { if (work_stack.size() == 0) log_cmd_error("Nothing to add to selection.\n"); - select_op_union(design, design->selection(), work_stack.back()); - design->selection().optimize(design); + select_op_union(design, design->selection_stack.back(), work_stack.back()); + design->selection_stack.back().optimize(design); return; } @@ -1554,8 +1512,8 @@ struct SelectPass : public Pass { { if (work_stack.size() == 0) log_cmd_error("Nothing to delete from selection.\n"); - select_op_diff(design, design->selection(), work_stack.back()); - design->selection().optimize(design); + select_op_diff(design, design->selection_stack.back(), work_stack.back()); + design->selection_stack.back().optimize(design); return; } @@ -1595,13 +1553,23 @@ struct SelectPass : public Pass { if (work_stack.size() == 0) log_cmd_error("No selection to check.\n"); RTLIL::Selection *sel = &work_stack.back(); - design->push_selection(*sel); sel->optimize(design); - for (auto mod : design->all_selected_modules()) { - module_count++; - for ([[maybe_unused]] auto member_name : mod->selected_members()) - total_count++; - } + for (auto mod : design->modules()) + if (sel->selected_module(mod->name)) { + module_count++; + for (auto wire : mod->wires()) + if (sel->selected_member(mod->name, wire->name)) + total_count++; + for (auto &it : mod->memories) + if (sel->selected_member(mod->name, it.first)) + total_count++; + for (auto cell : mod->cells()) + if (sel->selected_member(mod->name, cell->name)) + total_count++; + for (auto &it : mod->processes) + if (sel->selected_member(mod->name, it.first)) + total_count++; + } if (assert_modcount >= 0 && assert_modcount != module_count) { log_error("Assertion failed: selection contains %d modules instead of the asserted %d:%s\n", @@ -1625,14 +1593,13 @@ struct SelectPass : public Pass { log_error("Assertion failed: selection contains %d elements, less than the minimum number %d:%s\n%s", total_count, assert_min, sel_str.c_str(), desc.c_str()); } - design->pop_selection(); return; } if (!set_name.empty()) { if (work_stack.size() == 0) - design->selection_vars[set_name] = RTLIL::Selection::EmptySelection(design); + design->selection_vars[set_name] = RTLIL::Selection(false); else design->selection_vars[set_name] = work_stack.back(); return; @@ -1646,7 +1613,7 @@ struct SelectPass : public Pass { } if (work_stack.size() == 0) { - RTLIL::Selection &sel = design->selection(); + RTLIL::Selection &sel = design->selection_stack.back(); if (sel.full_selection) log("*\n"); for (auto &it : sel.selected_modules) @@ -1657,8 +1624,8 @@ struct SelectPass : public Pass { return; } - design->selection() = work_stack.back(); - design->selection().optimize(design); + design->selection_stack.back() = work_stack.back(); + design->selection_stack.back().optimize(design); } } SelectPass; @@ -1698,8 +1665,7 @@ struct CdPass : public Pass { log_cmd_error("Invalid number of arguments.\n"); if (args.size() == 1 || args[1] == "/") { - design->pop_selection(); - design->push_full_selection(); + design->selection_stack.back() = RTLIL::Selection(true); design->selected_active_module = std::string(); return; } @@ -1708,8 +1674,7 @@ struct CdPass : public Pass { { string modname = design->selected_active_module; - design->pop_selection(); - design->push_full_selection(); + design->selection_stack.back() = RTLIL::Selection(true); design->selected_active_module = std::string(); while (1) @@ -1726,10 +1691,9 @@ struct CdPass : public Pass { continue; design->selected_active_module = modname; - design->pop_selection(); - design->push_full_selection(); - select_filter_active_mod(design, design->selection()); - design->selection().optimize(design); + design->selection_stack.back() = RTLIL::Selection(); + select_filter_active_mod(design, design->selection_stack.back()); + design->selection_stack.back().optimize(design); return; } @@ -1746,10 +1710,9 @@ struct CdPass : public Pass { if (design->module(modname) != nullptr) { design->selected_active_module = modname; - design->pop_selection(); - design->push_full_selection(); - select_filter_active_mod(design, design->selection()); - design->selection().optimize(design); + design->selection_stack.back() = RTLIL::Selection(); + select_filter_active_mod(design, design->selection_stack.back()); + design->selection_stack.back().optimize(design); return; } @@ -1796,7 +1759,7 @@ struct LsPass : public Pass { { std::vector matches; - for (auto mod : design->all_selected_modules()) + for (auto mod : design->selected_modules()) matches.push_back(mod->name); if (!matches.empty()) { diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 8a1bd58c4..82b5c6bcf 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -802,8 +802,8 @@ struct ShowPass : public Pass { std::pair data; data.first = args[++argidx], argidx++; handle_extra_select_args(this, args, argidx, argidx+1, design); - data.second = design->selection(); - design->pop_selection(); + data.second = design->selection_stack.back(); + design->selection_stack.pop_back(); color_selections.push_back(data); continue; } @@ -811,8 +811,8 @@ struct ShowPass : public Pass { std::pair data; data.first = args[++argidx], argidx++; handle_extra_select_args(this, args, argidx, argidx+1, design); - data.second = design->selection(); - design->pop_selection(); + data.second = design->selection_stack.back(); + design->selection_stack.pop_back(); label_selections.push_back(data); continue; } diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 7e25615bb..7e51b6cb1 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -468,7 +468,7 @@ struct StatPass : public Pass { first_module = false; } else { log("\n"); - log("=== %s%s ===\n", log_id(mod->name), mod->is_selected_whole() ? "" : " (partially selected)"); + log("=== %s%s ===\n", log_id(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)"); log("\n"); data.log_data(mod->name, false); } diff --git a/passes/cmds/viz.cc b/passes/cmds/viz.cc index 131e799ab..9dd68bd00 100644 --- a/passes/cmds/viz.cc +++ b/passes/cmds/viz.cc @@ -950,8 +950,8 @@ struct VizPass : public Pass { auto type = arg == "-g" || arg == "-G" ? VizConfig::TYPE_G : arg == "-u" || arg == "-U" ? VizConfig::TYPE_U : arg == "-x" || arg == "-X" ? VizConfig::TYPE_X : VizConfig::TYPE_S; - config.groups.push_back({type, design->selection()}); - design->pop_selection(); + config.groups.push_back({type, design->selection_stack.back()}); + design->selection_stack.pop_back(); continue; } if (arg == "-0" || arg == "-1" || arg == "-2" || arg == "-3" || arg == "-4" || diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index facc5d173..52fd59cf8 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -246,7 +246,7 @@ struct SubmodWorker SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, bool hidden_mode = false, std::string opt_name = std::string()) : design(design), module(module), sigmap(module), copy_mode(copy_mode), hidden_mode(hidden_mode), opt_name(opt_name) { - if (!module->is_selected_whole() && opt_name.empty()) + if (!design->selected_whole_module(module->name) && opt_name.empty()) return; if (module->processes.size() > 0) { diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 620b38813..c37c03607 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -734,7 +734,7 @@ struct CleanPass : public Pass { count_rm_cells = 0; count_rm_wires = 0; - for (auto module : design->selected_unboxed_whole_modules()) { + for (auto module : design->selected_whole_modules()) { if (module->has_processes()) continue; rmunused_module(module, purge_mode, ys_debug(), true); diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index 263a3a4c8..88f995dda 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -57,7 +57,7 @@ struct CutpointPass : public Pass { for (auto module : design->selected_modules()) { - if (module->is_selected_whole()) { + if (design->selected_whole_module(module->name)) { log("Making all outputs of module %s cut points, removing module contents.\n", log_id(module)); module->new_connections(std::vector()); for (auto cell : vector(module->cells())) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index dd2f1d255..8fac93b98 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2887,7 +2887,7 @@ struct SimPass : public Pass { if (!top_mod) log_cmd_error("Design has no top module, use the 'hierarchy' command to specify one.\n"); } else { - auto mods = design->selected_unboxed_whole_modules(); + auto mods = design->selected_whole_modules(); if (GetSize(mods) != 1) log_cmd_error("Only one top module must be selected.\n"); top_mod = mods.front(); @@ -3016,7 +3016,7 @@ struct Fst2TbPass : public Pass { if (!top_mod) log_cmd_error("Design has no top module, use the 'hierarchy' command to specify one.\n"); } else { - auto mods = design->selected_unboxed_whole_modules(); + auto mods = design->selected_whole_modules(); if (GetSize(mods) != 1) log_cmd_error("Only one top module must be selected.\n"); top_mod = mods.front(); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index fe5cc7af1..a96a82659 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -306,10 +306,9 @@ struct Abc9Pass : public ScriptPass } run("design -stash $abc9"); run("design -load $abc9_map"); - if (help_mode) run("select =*"); - else active_design->push_complete_selection(); + run("proc"); run("wbflip"); - run("techmap -autoproc -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); + run("techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); run("opt -nodffe -nosdff"); if (dff_mode || help_mode) { if (!help_mode) @@ -370,8 +369,6 @@ struct Abc9Pass : public ScriptPass if (saved_designs.count("$abc9_holes") || help_mode) { run("design -stash $abc9"); run("design -load $abc9_holes"); - if (help_mode) run("select =*"); - else active_design->push_complete_selection(); run("techmap -wb -map %$abc9 -map +/techmap.v"); run("opt -purge"); run("aigmap"); @@ -394,7 +391,7 @@ struct Abc9Pass : public ScriptPass } else { auto selected_modules = active_design->selected_modules(); - active_design->push_empty_selection(); + active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { if (mod->processes.size() > 0) { @@ -403,9 +400,8 @@ struct Abc9Pass : public ScriptPass } log_push(); - active_design->select(mod); + active_design->selection().select(mod); - // this check does nothing because the above line adds the whole module to the selection if (!active_design->selected_whole_module(mod)) log_error("Can't handle partially selected module %s!\n", log_id(mod)); @@ -456,7 +452,7 @@ struct Abc9Pass : public ScriptPass log_pop(); } - active_design->pop_selection(); + active_design->selection_stack.pop_back(); } } diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 6cb569b5a..4c7667a43 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -454,7 +454,7 @@ void prep_bypass(RTLIL::Design *design) void prep_dff(RTLIL::Design *design) { - auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection::EmptySelection(design))); + auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection(false))); auto &modules_sel = r.first->second; for (auto module : design->selected_modules()) diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index dfa2e2f71..5be823916 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -139,7 +139,7 @@ struct AbcNewPass : public ScriptPass { if (!help_mode) { selected_modules = order_modules(active_design, active_design->selected_whole_modules_warn()); - active_design->push_empty_selection(); + active_design->selection_stack.emplace_back(false); } else { selected_modules = {nullptr}; run("foreach module in selection"); @@ -157,7 +157,7 @@ struct AbcNewPass : public ScriptPass { exe_options = abc_exe_options; log_header(active_design, "Mapping module '%s'.\n", log_id(mod)); log_push(); - active_design->select(mod); + active_design->selection().select(mod); } std::string script_save; @@ -194,7 +194,7 @@ struct AbcNewPass : public ScriptPass { } if (!help_mode) { - active_design->pop_selection(); + active_design->selection_stack.pop_back(); } } } diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 19e568a61..4836ebe34 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -171,7 +171,8 @@ struct AigmapPass : public Pass { module->remove(cell); if (select_mode) { - RTLIL::Selection& sel = design->selection(); + log_assert(!design->selection_stack.empty()); + RTLIL::Selection& sel = design->selection_stack.back(); sel.selected_members[module->name] = std::move(new_sel); } diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index 6a12e2005..363f998db 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -333,7 +333,7 @@ struct ClockgatePass : public Pass { dict clk_nets; int gated_flop_count = 0; - for (auto module : design->selected_unboxed_whole_modules()) { + for (auto module : design->selected_whole_modules()) { for (auto cell : module->cells()) { if (!RTLIL::builtin_ff_cell_types().count(cell->type)) continue; diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index c823f10fe..016789157 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -42,7 +42,7 @@ struct NlutmapWorker RTLIL::Selection get_selection() { - auto sel = RTLIL::Selection::EmptySelection(module->design); + RTLIL::Selection sel(false); for (auto cell : module->cells()) if (!mapped_cells.count(cell)) sel.select(module, cell); diff --git a/tests/cxxrtl/run-test.sh b/tests/cxxrtl/run-test.sh index ee299fc82..fd11a3783 100755 --- a/tests/cxxrtl/run-test.sh +++ b/tests/cxxrtl/run-test.sh @@ -13,5 +13,5 @@ run_subtest value run_subtest value_fuzz # Compile-only test. -../../yosys -p "read_verilog test_unconnected_output.v; select =*; proc; clean; write_cxxrtl cxxrtl-test-unconnected_output.cc" +../../yosys -p "read_verilog test_unconnected_output.v; proc; clean; write_cxxrtl cxxrtl-test-unconnected_output.cc" ${CC:-gcc} -std=c++11 -c -o cxxrtl-test-unconnected_output -I../../backends/cxxrtl/runtime cxxrtl-test-unconnected_output.cc diff --git a/tests/select/boxes.v b/tests/select/blackboxes.ys similarity index 51% rename from tests/select/boxes.v rename to tests/select/blackboxes.ys index 696b26523..9bfe92c6b 100644 --- a/tests/select/boxes.v +++ b/tests/select/blackboxes.ys @@ -1,3 +1,4 @@ +read_verilog -specify < Date: Tue, 8 Apr 2025 00:22:31 +0000 Subject: [PATCH 126/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 249d29f85..340a232c8 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+125 +YOSYS_VER := 0.51+162 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 406ee4c8d3a9c594ddcb11069f84158b1713a5de Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 8 Apr 2025 13:20:16 +0200 Subject: [PATCH 127/133] read_verilog_file_list: change short help message to start with lower case --- frontends/verilog/verilog_frontend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index e4e705c39..14a0f16c0 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -715,7 +715,7 @@ static void parse_file_list(const std::string &file_list_path, RTLIL::Design *de } struct VerilogFileList : public Pass { - VerilogFileList() : Pass("read_verilog_file_list", "Parse a Verilog file list") {} + VerilogFileList() : Pass("read_verilog_file_list", "parse a Verilog file list") {} void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| From a9656455b19655eed4c1ed31b5109c586f17e8c8 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 8 Apr 2025 17:39:41 +0200 Subject: [PATCH 128/133] Update to latest ABC --- Makefile | 4 ++-- abc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 340a232c8..8de3d234c 100644 --- a/Makefile +++ b/Makefile @@ -309,7 +309,7 @@ CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -s LIBS := $(filter-out -lrt,$(LIBS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DHAVE_STRUCT_TIMESPEC -fpermissive -w" +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DWIN32 -DHAVE_STRUCT_TIMESPEC -fpermissive -w" ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="i686-w64-mingw32-gcc" CXX="$(CXX)" EXE = .exe @@ -319,7 +319,7 @@ CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -s LIBS := $(filter-out -lrt,$(LIBS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DHAVE_STRUCT_TIMESPEC -fpermissive -w" +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DWIN32 -DHAVE_STRUCT_TIMESPEC -fpermissive -w" ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="x86_64-w64-mingw32-gcc" CXX="$(CXX)" EXE = .exe diff --git a/abc b/abc index f2d68d590..e55d316cc 160000 --- a/abc +++ b/abc @@ -1 +1 @@ -Subproject commit f2d68d590fa6f8fc32295a2edd79afc0d14a1414 +Subproject commit e55d316cc9a7f72a84a76eda555aa6ec083c9d0d From f602248a2eff6f43dc8486cf10a830739d3dd96a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 00:22:49 +0000 Subject: [PATCH 129/133] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8de3d234c..aafc2ceb2 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+162 +YOSYS_VER := 0.51+166 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From fee39a3284c90249e1d9684cf6944ffbbcbb8f90 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 9 Apr 2025 07:38:42 +0200 Subject: [PATCH 130/133] Release version 0.52 --- CHANGELOG | 13 ++++++++++++- Makefile | 4 ++-- docs/source/conf.py | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 716939992..0bbe3b179 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,19 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.51 .. Yosys 0.52-dev +Yosys 0.51 .. Yosys 0.52 -------------------------- + * New commands and options + - Added "-pattern-limit" option to "share" pass to limit analysis effort. + - Added "libcache" pass to control caching of technology library + data parsed from liberty files. + - Added "read_verilog_file_list" to parse verilog file list. + + * Various + - Added $macc_v2 cell. + - Improve lexer performance and zlib support for "read_liberty". + - opt_expr: optimize pow of 2 cells. + Yosys 0.50 .. Yosys 0.51 -------------------------- diff --git a/Makefile b/Makefile index aafc2ceb2..15ff178ad 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.51+166 +YOSYS_VER := 0.52 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) @@ -182,7 +182,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline c4b5190.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline c4b5190.. | wc -l`/;" Makefile ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) diff --git a/docs/source/conf.py b/docs/source/conf.py index dc7cbfe60..74ebe16e0 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -6,7 +6,7 @@ import os project = 'YosysHQ Yosys' author = 'YosysHQ GmbH' copyright ='2025 YosysHQ GmbH' -yosys_ver = "0.51" +yosys_ver = "0.52" # select HTML theme html_theme = 'furo-ys' From a2c08476678ba2c7e0a49028775ab8295b1f04bc Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 9 Apr 2025 08:21:08 +0200 Subject: [PATCH 131/133] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0bbe3b179..413a3236c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.52 .. Yosys 0.53-dev +-------------------------- + Yosys 0.51 .. Yosys 0.52 -------------------------- * New commands and options diff --git a/Makefile b/Makefile index 15ff178ad..89723e99d 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.52 +YOSYS_VER := 0.52+0 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) @@ -182,7 +182,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline c4b5190.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline fee39a3.. | wc -l`/;" Makefile ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From 2443facc462355c5ad9819d2da88f04995394ab3 Mon Sep 17 00:00:00 2001 From: Emily Schmidt Date: Wed, 9 Apr 2025 10:18:25 +0100 Subject: [PATCH 132/133] add dft_tag documentation --- .../more_scripting/data_flow_tracking.rst | 71 +++++++++++++++++++ .../using_yosys/more_scripting/index.rst | 1 + 2 files changed, 72 insertions(+) create mode 100644 docs/source/using_yosys/more_scripting/data_flow_tracking.rst diff --git a/docs/source/using_yosys/more_scripting/data_flow_tracking.rst b/docs/source/using_yosys/more_scripting/data_flow_tracking.rst new file mode 100644 index 000000000..e13dfac7d --- /dev/null +++ b/docs/source/using_yosys/more_scripting/data_flow_tracking.rst @@ -0,0 +1,71 @@ +Dataflow tracking +------------------- +Yosys can be used to answer questions such as "can this signal affect this other signal?" via its *dataflow tracking* support. +For this, four special cells, ``$get_tag``, ``$set_tag``, ``$overwrite_tag`` and ``$original_tag`` are inserted into the design and then the ``dft_tag`` is run, which converts these cells into ordinary logic. +Typically, one would then use ``sby`` to prove assertions involving these cells. + +Ordinarily in Yosys, the state of a bit is simply ``0`` or ``1`` (or one of the special values, ``z`` and ``x``). +During dataflow tracking they are augmented with a set of tags. +For example, the state of a bit could be ``0`` and the set of tags ``"KEY"`` and ``"OVERFLOW"``. + +In addition to their usual operations on the logical bits, Yosys operations must now also process the status of the tags. +For this, tags are simply *forwarded* or *propagated* (i.e. copied) from inputs to outputs, according to the following general rule: + + A tag is forwarded from an input to an output if the input can affect the output, for that particular state of all other inputs. + +For example, XOR, AND and OR cells propagate tags as follows: + +#. XOR simply forwards all tags from its inputs to its output, because inputs to XOR can always affect the output. +#. AND forwards tags only if the other input is ``1``. Because if one input is ``0``, the other input can never affect the output. +#. Similarly, OR forwards tags only if the other input is ``0``. + +There are two exceptions to this rule: +#. In general, propagation is only determined approximately. + For example, unless the ``dft_tag`` code knows about a cell, it simply assumes the worst-case behaviour that all inputs can affect all outputs. + It also does not try to determine whether the effect of a signal is cancelled out, for example ``A ^ A`` or ``A ^ (B ^ A)`` is independent of ``A``, but its tags would be propagated nonetheless. +#. If tag groups are used, the rules are modified (see below). + +Because of this propagation behaviour, we can answer questions about what signals are affected by a certain signal, by injecting a tag at that point in the circuit, and observing where the tag is visible. + +Example use cases +~~~~~~~~~~~~~~~~~~ +As an example use case, consider a cryptographic processor which is not supposed to expose its secret keys to the outside world. +We can tag all key bits with the ``"KEY"`` tag and use ``sby`` to formally verify that no external signal ever carries the ``"KEY"`` tag, meaning that key information is not visible to the outside. +As a caveat, we have to manually clear the ``"KEY"`` tag during cryptographic operations, as proving that the cryptographic operations themselves do not leak key information is beyond the ability of Yosys. +However we can still easily detect, if e.g. an engineer forgot to remove debugging code that allows reading back key data. + +As a different use case, we can modify all adders in the design to set the ``"OVERFLOW"`` tag on their output bits, if the addition overflowed, and then add asserts to all flip-flop inputs and output signals that they do not carry the ``"OVERFLOW"`` tag, i.e. that the results of overflowed additions never affect system state. +Note that in this particular example we use the ability of tag insertion to be conditional on logic, in this case the overflow condition of an adder. + +Semantics of dataflow tracking cells +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``$set_tag`` has inputs ``A``, ``SET``, ``CLR``, an output ``Y`` and a string parameter ``TAG``. +The logic value of ``A`` and all tags other than the one named by the ``TAG`` parameter are simply copied to ``Y``. +If ``SET`` is ``1``, then the named tag is added to ``Y``. +Otherwise, if ``CLR`` is ``1``, then the named tag is removed. +Otherwise, the tag is unchanged, i.e. it is present in ``Y`` if it is present in ``A``. + +``$get_tag`` has an input ``A`` and an output ``Y`` and a string parameter ``TAG``. +``$get_tag`` inspects ``A`` for the presence or absence of a tag of the given name and sets ``Y`` to ``1`` if the tag is present. +The logical value of ``A`` is completely ignored. + +``$overwrite_tag`` functions like ``$set_tag``, but lacks the ``Y`` output. +Instead of providing a modified version of the input signal, it modifies the signal ``A`` "in-place", i.e. if a signal is input to ``$overwrite_tag``, that is equivalent to interposing a ``$set_tag`` between its driver and all cells it is connected to. +The main purpose of ``$overwrite_tag`` is adding tags to signals produced within a module that cannot or should not be modified itself. + +``$original_tag`` functions identically to ``$get_tag``, but ignores ``$overwrite_tag``, i.e. when converting the ``$overwrite_tag`` to ``$set_tag`` as described above, it is equivalent to inserting the ``$get_tag`` *before* the ``$set_tag``. + +Tag groups +~~~~~~~~~~~~~~ +Tag groups are an advanced feature that modify the propagation rule discussed above. +To use tag groups, simply name tags according to the schema ``"group:name"``. +For example, ``"key:0"``, ``"key:a"``, ``"key:b"`` would be three tags in the ``"key"`` group. + +The propagation rule is then amended by + + Inputs cannot block the propagation of each other's tags for tags of the same group. + +For example, an AND gate will propagate a given tag on one input, if the other input is either 1 or carries a tag of the same group. +So if one input is ``0, "key:a"`` and the other is ``0, "key:b"`` the result would be ``0, "key:a", "key:b"``, rather than simply ``0``. +Note that if we add an unrelated ``"overflow"`` tag to the first input, it would still not be propagated. \ No newline at end of file diff --git a/docs/source/using_yosys/more_scripting/index.rst b/docs/source/using_yosys/more_scripting/index.rst index 090b9e0b9..6265e5d0e 100644 --- a/docs/source/using_yosys/more_scripting/index.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -12,5 +12,6 @@ More scripting selections interactive_investigation model_checking + data_flow_tracking .. troubleshooting From 32ec5a9ccd4e41f774e8bcae5fff70a568b2a36c Mon Sep 17 00:00:00 2001 From: Emily Schmidt Date: Wed, 9 Apr 2025 10:34:11 +0100 Subject: [PATCH 133/133] Revert "add dft_tag documentation" This reverts commit 2443facc462355c5ad9819d2da88f04995394ab3. --- .../more_scripting/data_flow_tracking.rst | 71 ------------------- .../using_yosys/more_scripting/index.rst | 1 - 2 files changed, 72 deletions(-) delete mode 100644 docs/source/using_yosys/more_scripting/data_flow_tracking.rst diff --git a/docs/source/using_yosys/more_scripting/data_flow_tracking.rst b/docs/source/using_yosys/more_scripting/data_flow_tracking.rst deleted file mode 100644 index e13dfac7d..000000000 --- a/docs/source/using_yosys/more_scripting/data_flow_tracking.rst +++ /dev/null @@ -1,71 +0,0 @@ -Dataflow tracking -------------------- -Yosys can be used to answer questions such as "can this signal affect this other signal?" via its *dataflow tracking* support. -For this, four special cells, ``$get_tag``, ``$set_tag``, ``$overwrite_tag`` and ``$original_tag`` are inserted into the design and then the ``dft_tag`` is run, which converts these cells into ordinary logic. -Typically, one would then use ``sby`` to prove assertions involving these cells. - -Ordinarily in Yosys, the state of a bit is simply ``0`` or ``1`` (or one of the special values, ``z`` and ``x``). -During dataflow tracking they are augmented with a set of tags. -For example, the state of a bit could be ``0`` and the set of tags ``"KEY"`` and ``"OVERFLOW"``. - -In addition to their usual operations on the logical bits, Yosys operations must now also process the status of the tags. -For this, tags are simply *forwarded* or *propagated* (i.e. copied) from inputs to outputs, according to the following general rule: - - A tag is forwarded from an input to an output if the input can affect the output, for that particular state of all other inputs. - -For example, XOR, AND and OR cells propagate tags as follows: - -#. XOR simply forwards all tags from its inputs to its output, because inputs to XOR can always affect the output. -#. AND forwards tags only if the other input is ``1``. Because if one input is ``0``, the other input can never affect the output. -#. Similarly, OR forwards tags only if the other input is ``0``. - -There are two exceptions to this rule: -#. In general, propagation is only determined approximately. - For example, unless the ``dft_tag`` code knows about a cell, it simply assumes the worst-case behaviour that all inputs can affect all outputs. - It also does not try to determine whether the effect of a signal is cancelled out, for example ``A ^ A`` or ``A ^ (B ^ A)`` is independent of ``A``, but its tags would be propagated nonetheless. -#. If tag groups are used, the rules are modified (see below). - -Because of this propagation behaviour, we can answer questions about what signals are affected by a certain signal, by injecting a tag at that point in the circuit, and observing where the tag is visible. - -Example use cases -~~~~~~~~~~~~~~~~~~ -As an example use case, consider a cryptographic processor which is not supposed to expose its secret keys to the outside world. -We can tag all key bits with the ``"KEY"`` tag and use ``sby`` to formally verify that no external signal ever carries the ``"KEY"`` tag, meaning that key information is not visible to the outside. -As a caveat, we have to manually clear the ``"KEY"`` tag during cryptographic operations, as proving that the cryptographic operations themselves do not leak key information is beyond the ability of Yosys. -However we can still easily detect, if e.g. an engineer forgot to remove debugging code that allows reading back key data. - -As a different use case, we can modify all adders in the design to set the ``"OVERFLOW"`` tag on their output bits, if the addition overflowed, and then add asserts to all flip-flop inputs and output signals that they do not carry the ``"OVERFLOW"`` tag, i.e. that the results of overflowed additions never affect system state. -Note that in this particular example we use the ability of tag insertion to be conditional on logic, in this case the overflow condition of an adder. - -Semantics of dataflow tracking cells -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``$set_tag`` has inputs ``A``, ``SET``, ``CLR``, an output ``Y`` and a string parameter ``TAG``. -The logic value of ``A`` and all tags other than the one named by the ``TAG`` parameter are simply copied to ``Y``. -If ``SET`` is ``1``, then the named tag is added to ``Y``. -Otherwise, if ``CLR`` is ``1``, then the named tag is removed. -Otherwise, the tag is unchanged, i.e. it is present in ``Y`` if it is present in ``A``. - -``$get_tag`` has an input ``A`` and an output ``Y`` and a string parameter ``TAG``. -``$get_tag`` inspects ``A`` for the presence or absence of a tag of the given name and sets ``Y`` to ``1`` if the tag is present. -The logical value of ``A`` is completely ignored. - -``$overwrite_tag`` functions like ``$set_tag``, but lacks the ``Y`` output. -Instead of providing a modified version of the input signal, it modifies the signal ``A`` "in-place", i.e. if a signal is input to ``$overwrite_tag``, that is equivalent to interposing a ``$set_tag`` between its driver and all cells it is connected to. -The main purpose of ``$overwrite_tag`` is adding tags to signals produced within a module that cannot or should not be modified itself. - -``$original_tag`` functions identically to ``$get_tag``, but ignores ``$overwrite_tag``, i.e. when converting the ``$overwrite_tag`` to ``$set_tag`` as described above, it is equivalent to inserting the ``$get_tag`` *before* the ``$set_tag``. - -Tag groups -~~~~~~~~~~~~~~ -Tag groups are an advanced feature that modify the propagation rule discussed above. -To use tag groups, simply name tags according to the schema ``"group:name"``. -For example, ``"key:0"``, ``"key:a"``, ``"key:b"`` would be three tags in the ``"key"`` group. - -The propagation rule is then amended by - - Inputs cannot block the propagation of each other's tags for tags of the same group. - -For example, an AND gate will propagate a given tag on one input, if the other input is either 1 or carries a tag of the same group. -So if one input is ``0, "key:a"`` and the other is ``0, "key:b"`` the result would be ``0, "key:a", "key:b"``, rather than simply ``0``. -Note that if we add an unrelated ``"overflow"`` tag to the first input, it would still not be propagated. \ No newline at end of file diff --git a/docs/source/using_yosys/more_scripting/index.rst b/docs/source/using_yosys/more_scripting/index.rst index 6265e5d0e..090b9e0b9 100644 --- a/docs/source/using_yosys/more_scripting/index.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -12,6 +12,5 @@ More scripting selections interactive_investigation model_checking - data_flow_tracking .. troubleshooting