From 4f4e9d7902ae68712d7d2d0fcb10bc2393396761 Mon Sep 17 00:00:00 2001 From: dan <17553473+poname@users.noreply.github.com> Date: Fri, 9 Jun 2023 13:44:12 -0300 Subject: [PATCH] Squashed 'yosys/' changes from b96eb888cc..f7a8284c7b f7a8284c7b Release version 0.30 73badeccef Bump version 8cb3bab479 Merge pull request #3792 from pu-cc/gatemate-bram-updates 61387d78b7 gatemate: Prevent implicit declaration of `ram_{we,en}` 62fc118548 Merge pull request #3790 from zeldin/makefile-posix-test 7c606bd5a3 Merge pull request #3791 from nakengelhardt/nak/show_attr_wires 6f5d984bdb Merge pull request #3778 from jix/yw_clk2fflogic 88c849d112 Bump version d7f25165a5 Add ninitff line to aiger .aim files 0707b911c7 show: add -viewer none option 4b986c9c65 fix wire color after BUF 2004a9ff4a gatemate: Add CC_FIFO_40K simulation model c244a7161b gatemate: Fix SDP read behavior 43b807fe6f Bump version 1cd1e57e3c Fix use of non-POSIX test expressions in Makefile fb7af093a8 intel_alm: re-enable 8x40-bit M10K support 26555a998d show -colorattr: extend colors to arrows when wires have attribute 8596c5ce49 Bump version cac1bc6fbe intel_alm: enable M10K initialisation ec8d7b1c68 abc9_ops -prep_hier to unmap entire module 862631d657 Add ABC9 DSP cascade test 00b0e850db intel_alm: re-enable carry chains for ABC9 e36c71b5b7 Use clk2fflogic attr on cells to track original FF names in witnesses 7caeb922a0 sim: Run level triggered async updates to fixpoint during initialization 52c8c28d2c Add recover_names pass to recover names post-mapping 57c9eb70fe Bump version 5e36effe3c Merge pull request #3777 from YosysHQ/micko/vhdl_verific ecd289c100 Fix importing parametrized VHDL entity 4f3d1be96a Merge pull request #3767 from YosysHQ/krys/yw_fix 5fb1223861 Merge pull request #3733 from AdamHillier/aiger-inputs 890849447f Merge pull request #3716 from antmicro/kr/brackets cdeef5481c Bump version e7156c644d Standard compliance for tests/verilog/block_labels.ys ad2b04d63a sim: Fix cosimulation with nested modules having unconnected inputs e6f3914800 smt2: Use smt bv offset for `$any*`'s smtoffset 147cceb516 Bump version 52ad7a47f3 Assign wires an smtoffset c2285b3460 fix file rights 07e76fcaca Merge pull request #3751 from RTLWorks/main/issue2525 693c609eec Merge branch 'YosysHQ:master' into main/issue2525 665e0f6131 remove new line per maintainer request acfdc5cc42 Merge pull request #3755 from RTLWorks/muthu/issue3498 6b3e6d96a3 Fix missing brackets around else d82bae32be Bump version c855502bd5 Update passes/techmap/libparse.cc 7aab324e85 Merge pull request #3737 from yrabbit/all-primitives-script 5c7cc6ff06 Merge pull request #3745 from rfuest/gowin_alu 226a224640 Merge pull request #3749 from lethalbit/aki/plugin-stuff f790e00478 Next dev cycle 9c5a60eb20 Release version 0.29 0469405abf Bump version 266036c6f9 Merge pull request #3756 from YosysHQ/krys/sim_writeback 0aeb6105eb Merge pull request #3736 from jix/conc_assertion_in_unclocked_proc_ctx ec56e625f4 Merge pull request #3742 from jix/fix_rename_witness_cell_renames 5a4e72f57a Fix sim writeback check for yw_cosim 17cfc969dd [YOSYS] Issue #3498 - Fix Synopsys style unquoted Liberty style function body parsing with unittest 8341fd450e Merge branch 'master' into all-primitives-script 4251d37f4f Merge pull request #3610 from YosysHQ/synthprop d2f3251528 adding unittest 81e089cb60 [YOSYS-2525] fix read_liberty newline handling #2525 - newlines can be allowed in function parsing 4f6a66e257 Merge branch 'master' into all-primitives-script f93671eb85 Bump version 32f5fca2aa Merge pull request #3694 from daglem/struct-attributes fb7f3bb290 Cleaner tests for RTLIL cells in struct_dynamic_range.sv ad437c178d Handling of attributes for struct / union variables bb240665b7 plugin: shuffled the `#ifdef WITH_PYTHON`'s around to un-tangle the code and pulled out the check for the `.py` extension so it will complain if you try to load a python extension without python support 572c8df9a8 plugin: Re-vamped how plugin lookup was done to make it more consistent with the rest of yosys, and prevented a case where you could end up with `.so.so` on the end 30f1d10948 gowin: Fix X output of $alu techmap 2bab787729 Merge branch 'master' into all-primitives-script 7bff8b63b3 rename: Fix renaming cells in -witness mode cee3cb31b9 Merge pull request #3734 from jix/fix_unbased_unsized_const 51dd029024 Bump version 8611429237 ABC9: Cell Port Bug Patch (#3670) a1dd794ff8 gowin: Add all the primitives. 3cbca5064c verific: Handle non-seq properties with VerificClocking conditions ec47bf1745 verific: Handle conditions when using sva_at_only in VerificClocking 985f4926b7 verilog: Fix const eval of unbased unsized constants 3861cc31f0 Add outputs before inputs to the sigmap in the AIGER backend. 7efc50367e Bump version 88ae463ffe Merge pull request #3732 from hzeller/20230417-remote-statement-no-effect a3a8f7be38 Remove a statement without effect. a9c792dcee Bump version d0855576ae Next dev cycle 0d6f4b0683 Release version 0.28 b377a39b73 Merge pull request #3727 from YosysHQ/micko/pll_bram a2655a4b70 Bump version e56dad56c4 fabulous: Add support for LUT6s f9a6c0fcbd gowin: Add serialization/deserialization primitives ee3162c58d Add PLL and EBR related primitives 101075611f Bump version 266f81816b ecp5: Remove TRELLIS_SLICE and add TRELLIS_COMB model 0f5e7c244d add additional dff and lutram tests 54d313efc3 add test for CCU2D 9e9fae1966 Add more DFF types d5a405d3b4 Added proper simulation model for CCU2D 6e4c1675e7 Generate TRELLIS_DPR16X4 for lutram 6e12da3956 machxo2: Initial support for carry chains (CCU2D) 53c0a6b780 Bump version f35bdaa527 Update Xilinx cell definitions, fixes #3699 23826e5152 Bump version dc0a799c06 Merge pull request #3708 from jix/void_func fb1c2be76b verilog: Support void functions 61da330a38 Update tests ff9f1fb86e Start unification effort for machxo2 and ecp5 4d7e9e2e5d Add additional iopad_external_pin attributes db367bd69e Add iopad_external_pin to some basic io primitives 10589c57bf insert IO buffers for ECP5, off by default ceef00c35e Bump version 57fb1f51b2 Merge pull request #3704 from jix/enum_values 390d1c583a verific: Fix enum_values support and signed attribute values 101d19bb6a Bump version c50f641812 Merge pull request #3682 from daglem/struct-member-out-of-bounds baa3659ea5 ice40: Fix path delay definitions 1af7d6121f Added test for dynamic indexing within struct members b58664d441 Bump version 7c5ae560a8 Merge pull request #3684 from YosysHQ/fix-GIT_REV 368f2984cd Next dev cycle 5f88c218b5 Release version 0.27 0d3423ddea Index struct/union members within corresponding wire chunks 9747e55d95 Bump version 3f173c2180 Makefile: fix GIT_REV extraction if Yosys is built as submodule. 981c934b5b Merge pull request #3690 from whitequark/smtbmc-help-opt 25ebefc2a6 Merge pull request #3692 from nakengelhardt/stat_q_fix 1a3ff0d926 Merge pull request #3688 from pu-cc/gatemate-reginit 57897927ff stat: pass down quiet arg bb28e48136 Merge pull request #3663 from uis246/master 4ff9063145 Merge pull request #3652 from martell/elvds 71c59d9fab Bump version 4bb173e256 yosys-smtbmc: support -h/--help (and exit with code 0). 21e87f7986 Merge pull request #3646 from YosysHQ/lofty/fix-3591 842cdad575 Merge pull request #3674 from YosysHQ/fix_wide_case 2ab3747cc9 fabulous: Add support for mapping carry chains 28c4aac234 run verific tests in test target d8cefec169 Added ranged case check 53a4f0fb56 Add test example a30894e5fa Handle more wide case selector types 8216b23fb7 Bump version ef8ed21a2e Merge pull request #3685 from YosysHQ/update-abc 5d9bd0af92 Update abc. 0f2d226ae9 Bump version c8966722d2 Merge pull request #3403 from KrystalDelusion/mem-tests f80920bd9f Genericising bug1836.ys 445a801a85 bug3205.ys removed 51c2d476c2 Removing extra `default_nettype` lines 8f6a06951c Fix for sync_ram_sdp not being final module 7f033d3c1f More tests in memlib/generate.py af1b9c9e07 Tests for ram_style = "huge" de2f140c09 Testing TDP synth mapping 48f4e09202 Asymmetric port ram tests with Xilinx ac5fa9a838 Addings tests for #1836 and #3205 79043cb849 Out of bounds checking for struct/union members f0116330bc Bump version f30b539cc2 Merge pull request #3681 from keszocze/keszocze-patch-dsp48e1-init-dreg fc56978703 Check DREG attribute 1cfedc90ce Bump version 25e7cb3bbb fabulous: Add CLK to BRAM interface primitives a20804c6ed Bump version 2c7ba0e752 gatemate: Enable register initialization 1c667fab2b Merge pull request #3672 from jix/yw-cosim-hierarchy-fixes 1cedad7a68 Merge pull request #3675 from daglem/struct-item-queries 68480dfa19 Merge pull request #3671 from zachjs/master f8219289b2 Corrected tests for data and array queries on struct/union item expressions c1e12877f0 Support for data and array queries on struct/union item expressions 53bda9de54 Merge pull request #3661 from daglem/struct-array-range-offset 59de4a0e7f Bump version ec94703619 Merge pull request #2995 from georgerennie/cover_precond 85f611fb23 Merge pull request #3126 from georgerennie/equiv_make_assertions b636af9751 chformal: Note about using -coverenable with the Verific frontend f37073050b gatemate: Update CC_PLL parameters 6a7d5257cd gatemate: Add CC_USR_RSTN primitive 4cb27b1a3a gatemate: Ensure compatibility of LVDS ports with VHDL e0bc25f1af Bump version d2032ac6fd Merge pull request #3669 from jix/fix-xprop-tests-yosys-call 550a5b7b6b Update license 713b7d3e26 added support for latched output reset 131b557727 Initial implementation of synthesizable assertions 55ad3fe6c7 xprop tests: Make iverilog invocation more portable 2a68eee5f1 xprop: Test fixes and abort on test failure 9f20beb7df xprop: Smaller subset of tests to run by default 160eeab2bb verilog_backend: Do not run bwmuxmap even if in expr mode 1698202ccc sim: For yw cosim, drive parent module's signals for input ports 4c334b905f Bump version 615adc4253 Resolve package types in interfaces (#3658) 26a6c60478 Add test for typenames using constants shadowed later on 5ea2c290a5 Bump version 6d021f04d4 tests: Fix path of yosys invocation in xprop tests f3c4e93d24 Merge pull request #3667 from jix/xprop-test-make-fix d31d5da69f tests: in xprop tests, use MAKE variable if set b1a011138c Bump version a7099b0a72 Next dev cycle 7e588664e7 Release version 0.26 ddb2bd85c8 Merge pull request #3662 from YosysHQ/micko/wide_case_select_box 5f33c0e0b2 Updated changelog 109b88c379 For case select values use Sa instead of Sx and Sz ea6f562d49 gowin: Add new types of oscillator 417fadbefd Merge pull request #3625 from povik/show_cleanup e7e37df91b Add verific import support for OPER_WIDE_CASE_SELECT_BOX 777c589e85 Handle range offsets in packed arrays within packed structs 45edc8eb98 Bump version 5fa96ccdee Merge pull request #3659 from whitequark/update-abc 3af3cc15b5 Bump ABCREV to fix WASM build. 54bf15a5b8 Bump version a90f940615 backends/firrtl: Ensure `modInstance` is valid 221036c5b6 Bump version 0f2cb80a26 Merge pull request #3655 from jix/smt2_fix_b_op_width 5e82638408 smt2: Fix operation width computation for boolean producing cells f7c1e4aadf Bump version c235802f4a Merge pull request #3650 from jix/rtlil_roundtrip_z_bits 419f91a2b9 add option to fsm_detect to ignore self-resetting ecfa7e9fbc add pmux option to bmuxmap for better fsm detection with verific frontend dbc8b77222 gowin: Add support for emulated differential output d11cb6901f Bump version 26db5a11d3 Resolve struct member package types db13c6df2b Handle struct members of union type (#3641) b08a880704 backends/rtlil: Do not shorten a value with z bits to 'x 822c7b0341 muxcover: do not add decode muxes with x inputs 541fdffff2 Bump version b9155a574e Merge pull request #3647 from jix/formalff-hierarchy-fix afac3f2c76 formalff: Fix crash with _NOT_ gates in -hierarchy mode 755b753e1a Bump version 8180cc4325 Merge pull request #3624 from jix/sim_yw 245884a101 Merge pull request #3629 from YosysHQ/micko/clang_fixes 9bc9121b9e Merge pull request #3636 from YosysHQ/log_plugin bfacaddca8 show: Remove left-in debug log_warning 200ffdccc5 Call yosys_shutdown to properly cleanup plugins and tcl when expecting error 611f71c670 Merge pull request #3630 from yrabbit/gw1n4c-pll 29e7756b0c Bump version bfc3c20cfb Improve splitcells pass 6574553189 Fixes for some of clang scan-build detected issues f9e30ee5e0 passes: show: s/pos/bitpos/ for readability 314b864205 passes: show: Reuse string parts in generation of portboxes 61abca10a3 passes: show: Touch chunk iteration in gen_portbox 60318a5cd8 passes: show: Label no_signode flag 8b1f5fba62 passes: show: Simplify wire bit range logic ad149cc42a passes: show: Factor out 'join_label_pieces' 5848790835 passes: show: Label signed_suffix flag 13700e12e5 passes: show: s/idx/dot_idx/ for readability e3709ce776 passes: show: Fix portbox bit ranges in case of driven signals 956c4e485a Bump version 692a0fa33b print filename in liberty log_header d6c7aa0e3d sim/formalff: Clock handling for yw cosim 7ddec5093f sim: Improvements and fixes for yw cosim 636b9f2705 Support for BTOR witness to Yosys witness conversion 3e25e61778 aiger: Use new JSON code for writing aiger witness map files 29461ade17 Add json.{h,cc} for pretty printing JSON dda972a148 sim: New -append option for Yosys witness cosim 2dd5652215 sim: Add Yosys witness (.yw) cosimulation 1494cfff00 New kernel/yw.{h,cc} to support reading Yosys witness files f6458bab70 sim: Only check formal cells during gclk simulation updates 9c6198a827 sim: Internal API to set $initstate 44b26d5c6d sim: Emit used memory addresses as signals to output traces 5042600c0d xprop, setundef: Mark xprop decoding bwmuxes, exclude them from setundef 673ad561b8 smt2: Treat bweqx as xnor 62afe61779 smt2: Directly implement bwmux instead of using bwmuxmap 4173daa708 Merge pull request #3605 from gadfort/stat-json-area 2e3c08adc4 Merge pull request #3570 from YosysHQ/claire/eqystuff 843f329b96 Merge branch 'master' into claire/eqystuff 5abaa59080 Merge pull request #3537 from jix/xprop d742d063d4 remove template declaration that stops function from being used 41ce00e82a Merge pull request #3620 from YosysHQ/gcc48_remove 4fc5207b1e Add deprecation info to changelog 5801152779 Deprecate gcc-4.8 6d56d4ecfc Merge branch 'master' of github.com:YosysHQ/yosys into claire/eqystuff d6a1e022e1 gowin: add a new type of PLL - PLLVR 7b476996df Bump version 2677569d48 Merge pull request #3616 from YosysHQ/register_error 2b622258a2 Merge pull request #3615 from YosysHQ/qbfsat_cvc5 40282576b0 Display error instead of assertion when pass exists e3c0fd8b10 qbfsat support for cvc5, fixes #3608 f2c689403a Bump version 7bac1920b2 nexus: Fix BRAM write enable in PDP mode d3216593da Bump version c34d308bbd Next dev cycle e02b7f64bc Release version 0.25 a27a297ebc Bump version 7971154e72 Merge branch 'master' into stat-json-area 583ab81670 Merge pull request #3606 from YosysHQ/fix_vs a935752df6 Remove cache fcd1c68ab7 add note to help about how to chain commands 257b41cd1f Merge pull request #3577 from KrystalDelusion/deprecate_manual 58cca9592d stat: ensure area is included in json output 029b0aac7f Merge branch 'claire/eqystuff' of github.com:YosysHQ/yosys into claire/eqystuff 1bc832a8e1 Allow non-unique modules without state in sim writeback-mode a9072dc23c Small bugfix in uniquify pass 3ebc50dee4 Merge pull request #3467 from jix/fix_cellarray_simplify f2a4e5f1a0 Fixing other references to the manual f33a21eea4 Removed manual from make clean aeb40d4ddf Remove make targets for manual 69cbef9666 Bump version 76de4455e6 Merge pull request #3588 from YosysHQ/noblackbox b867dee241 respect noblackbox attribute in verific 5d893c4b03 Bump version 4a0ed35aab xprop: Improve signal splitting code 2093cf07e4 Merge pull request #3581 from jix/formalff-error 6a6e1d8424 Improvements in "viz" pass 967529abb1 formalff: Proper error messages on async inputs for the -clk2ff mode dc14def5f3 Add gold-x handing to miter cross port handling 3454bddbe2 Merge branch 'claire/eqystuff' of github.com:YosysHQ/yosys into claire/eqystuff 4f36a86fff Merge pull request #3579 from jix/split_public_untested 172a8e79f0 xprop: Add -split-public option 7ad7b550cb Merge pull request #3573 from daglem/struct-array-multidimensional cf3570abde simplify: regression test for AST_CELLARRAY simplification issue dd8b412833 simplify: Do not recursively simplify AST_CELL within AST_CELLARRAY 11fe4d0862 Remove help outputs for tex a955c42d6c And appnotes 1eec255e60 Removing manual files 4b95fac139 Removing old manual from README.md 068031d2aa Improvements in "viz" command aeba966475 Improvements in "viz" pass c679b408cb Various improvements in "viz" command 2895a66784 Bugfix in splitcells pass 1f6ac926a4 Bump version f1da4b0204 Next dev cycle 313b7997b5 Release version 0.24 2dac9be3cd Update manual b60baad662 Merge pull request #3572 from jix/tcl-recover 6589accfa9 tcl: Update help message to mention 'tee -s' 9362fdb4c6 Merge pull request #3568 from YosysHQ/verific_msg 26aaf7683f Merge pull request #3569 from YosysHQ/ver_no_rewriters a43356cb04 tcl: Unset both result.json and result.string only before calling pass e151e44caa Improvements in "viz" command c9f4b06cb2 Add "viz" pass for visualizing big-picture data flow in larger designs 22090011ab Made make_struct_member_range side-effect-free again 92fc6cd4a9 Add splitcells pass 8895b51dbb Merge branch 'master' of github.com:YosysHQ/yosys into claire/eqystuff f94eec952f Support for packed multidimensional arrays within packed structs 34a64aa322 set VERI-1063 explicitly 0f7b8b8d23 tcl: Don't exit repl on recoverable command errors 5524d5185d tcl: Return scratchpad result.json and result.string as tcl objects 7036a312bf stat: Fix JSON output for empty designs ed02d52f30 tee: Allow logging command output to a given scratchpad value a64ed824ed Merge pull request #3567 from YosysHQ/tcl_fix_crash 956b7f5fd1 Merge branch 'xprop' of github.com:jix/yosys into claire/eqystuff fbf8bcf38f Add insbuf -chain mode dcc1cb7ddd Bump version 4a2b7287ca Merge pull request #3551 from daglem/struct-array-swapped-range 64f88eb7f1 Added asserts for current limitation of array dimensions in packed structs 15c8e74329 Check for all cases of currently unsupported array dimensions in packed structs eb0039848b miter: Add -make_cover option to cover each output pair difference 551ca7f97f formalff: Fix -ff2anyinit assertion error for fine FFs ce708122a5 New xprop pass to encode 3-valued x-propagation using 2-valued logic 5ff69a0fe2 sim: Improved global clock handling 3ecf85e32c opt_expr: Optimizations for `$bweqx` and `$bwmux` be752a20dc Add bwmuxmap pass 7203ba7bc1 Add bitwise `$bweqx` and `$bwmux` cells f2c531e65f verilog_backend: Do not run bmuxmap or demuxmap in -noexpr mode. 82b630a246 verilog_backend: Correctly sign extend output of signed `$modfloor` 5cb7d0fe9d verilog_backend: Add -noparallelcase option 99163fb822 simlib: Use optional SIMLIB_GLOBAL_CLOCK to define a global clock signal 605d127517 simlib: Silence iverilog warning for `$lut` 39ac113402 simlib: Fix wide $bmux and avoid iverilog warnings b982ab4f59 satgen, simlib: Consistent x-propagation for `$pmux` cells 1e67c3a3c2 opt_expr: Fix shift/shiftx optimizations 2dd55d73a0 reset elaboration error after rewriter bfd79845b6 Set all verific messages of certain type to other b0469b3863 Fix tcl crash in case of error executing command fd56d1f79e opt_expr: Constant fold mux, pmux, bmux, demux, eqx, nex cells c08242ba41 opt_expr: Optimize bitwise logic ops with one fully const input 661fa5ff92 simplemap: Map `$xnor` to `$_XNOR_` cells f9db7c0599 Bump version 10e22608c0 Merge pull request #3565 from jix/sat-def-formal ed0e14820e sat: Add -set-def-formal option to force defined $any* outputs 23e26ff661 Bump version fd01d9eb8b Merge pull request #3561 from YosysHQ/tcl_shell 448a796e15 Merge pull request #3560 from YosysHQ/verific_conf 2450e6be22 Add TCL interactive shell mode f764cd1655 update documentation b0be19c126 Support importing verilog configurations using Verific c55c514cdb Bump version b9b5899cce Remove docs dependency on yosys repo (#3558) a460e0b31c Tests for unpacked arrays in packed structs are for the Yosys frontend only ddb12148e7 Support for swapped ranges in second array dimension fc2f622a27 Merge pull request #3552 from daglem/fix-sv-c-array-dimensions 13e4f343b9 Bump version 239ecf9185 Merge branch 'zachjs-master' b64141f48b mention prerequisites in fsm_detect and fsm help e56c689962 Bump version b6467f0801 fabulous: Allow adding extra custom prims and map rules f111bbdf40 fabulous: improvements to the pass e3f9ff2679 fabulous: Unify and update primitives 12c22045b7 Introduce RegFile mappings 2b07e01ea4 Replace synth call with components, reintroduce flags and correct vpr flag implementation df56178567 Reorder operations to load in primitive library before hierarchy pass da32f21b59 Add plib flag to specify custom primitive library path 950dde3081 Remove flattening from FABulous pass 8fdf4948a8 Remove ALL currently unused flags (some to be reintroduced later and passed through to synth) 2e9480be24 Add synth_fabulous ScriptPass 0516fd751c Bump version 48659ee2bb Slowing down clock to have same metadata 388611aac4 Bump version 7de226878d faketime to make PDFs unique a14dec79eb Rst docs conversion (#3496) 853f4bb3c6 Merge pull request #3547 from YosysHQ/update_abc a862642fac Correct interpretation of SystemVerilog C-style array dimensions bab88630c2 Support for arrays with swapped ranges within structs 553eb6ac1e Bump version c75f12a989 Add missing memory width assert preventing division by zero (#3546) 6403bfbd9f Update ABC faa1c2e7fe Bump version cb7299c3dc Next dev cycle 7ce5011c24 Release version 0.23 6758b7babc Update manual 2cdbb85da6 Bump version 4cb923a4f5 Merge pull request #3544 from jix/cosim-ffinit 9b4fba3870 sim: Run a comb-only update step to set past values during FST cosim cff42f0af5 Update CHANGELOG 96df99dafa Merge pull request #3536 from YosysHQ/claire/vcdend bc0e69f5c8 Merge pull request #3543 from jix/fstdata-fixes 68d52cb1b1 fstdata: Update past_data before end_time callback 3477f2d00b fstdata: Handle square/angle bracket replacemnt, change memory handling 9470ef9efe Update CHANGELOG 14aa485176 Bump version 310281a96c Separate deprecated compilers on CI a4eb7e41c0 Add extra time at the end of a sat VCD trace d8ea5ef6e2 Bump version 8d69220be7 Merge pull request #3533 from YosysHQ/micko/liberty 59b6ac47c9 Add additional help info 499390e9ce Merge pull request #3534 from mmicko/win32_plugins 6fb80bce15 Enable importing blackbox modules only e702f2894a Support for reading liberty files using verific d1b3a250db Windows plugin build support 5f209f8be5 Bump version fe438ca1ab Add missing log_dump_val_worker forward declarations c0ad6b3bc6 Bump version 71e7e09092 verilog: Support module-scoped task/function calls 31c15e5fa6 Merge pull request #3530 from jix/simlib-mux-fix aa7e7df19f simlib: Simplify recently changed $mux model 05218ec900 Add dlfcn library for win32 518194fac1 Bump version fdce6c5868 Merge pull request #3528 from YosysHQ/claire/crossbits d04c17fd58 Add miter -cross option 408fc60c95 Merge pull request #3526 from jix/mux-simlib-eval 3a37597e9f Merge pull request #3518 from jix/smtmap 9f76ff0b6a Merge pull request #3517 from jix/smtbmc-witness-no-assume-skipped 61440a42d1 Merge pull request #3523 from lparkes/basename c77b7343d0 Consistent $mux undef handling c0e4d01aa7 Merge pull request #3512 from lparkes/fstapi 7fcc39abe3 Update CodeQL action 49945ab1c2 Replace GNU specific invocation of basename(1) with the equivalent POSIX one. The tests now complete on BSD as well as GNU/Linux. 713d42d25d Bump version 32808b26c6 Merge pull request #3521 from YosysHQ/ci_upgrade 61dfc26d74 Update versions of CI actions used 4f4cff0080 Bump version 0f96ae5990 Add smtmap.v describing the smt2 backend's behavior for undef bits be1a12595a Add missing log_dump handler for std::vector<> 96029400cb smtbmc: Do not assume skipped assertions when loading a witness trace 6781746872 Bump version 8859d801c8 Temporal induction counterexample loop detection (#3504) f4ede15d68 Merge pull request #3514 from jix/smtbmc-kind-witness-fix 8838b1eaa4 smtbmc: Fix witness handling for k-induction failures 7dcc9c664e And another place we need to lseek() after dup(). 635aa2a3fc Forcibly set the current seek location of gz files that we are accessing via dup(fileno());gzdopen() because stdio might have buffered data from the underlying file meaning that the underlying seek position isn't what we think it is. d02ae8f2fc Bump version fc53a0a5c2 Merge pull request #3511 from YosysHQ/improve_edif 48628fbf5a Skip verific primitives and operators import by default 922f8b614a Add option to import all cells from all libraries 2e837956dc Bump version 33a2773de0 Merge pull request #3510 from jix/ff_witness_fixes 4d334fd3e3 smt2/smtbmc: Fix FF witness data for fine grained or multi chunk FFs f35c062354 github: issues: added an OS dropdown to the issue template fcf742837e Merge pull request #3502 from jix/equiv_opt_fixes 5c7a1eda92 Bump version 00bef0b534 Merge pull request #3508 from YosysHQ/aki/rm_protobuf 7a73133c9f backends: protobuf: removed protobuf backend 03df1ac72b fix whitespace e8ce9442a6 Merge pull request #3452 from ALGCDG/master d68013811f Merge pull request #3507 from YosysHQ/claire/verificlibopt 090228a6a1 Fix handling of verific -L options, add implicit "-L work" 0e13d7e4c7 Bump version ae1a24d0c4 Merge pull request #3503 from jix/abort_on_log_error 0113f44faa Reenable existing equiv_opt tests 81906aa627 Fix tests for check in equiv_opt 0516307637 Add "check -assert" to equiv_opt f0478c520d Re-enable opt_dff_sr equiv_opt checks afa5e6bb53 Exclude primary inputs from quiv_make rewiring 381ce66f58 Revert "Merge pull request #641 from tklam/master" 925f92918a clk2fflogic: Always correctly handle simultaneously changing signals ac906d15ce Add YOSYS_ABORT_ON_LOG_ERROR environment variable for debugging. c4a52b1b02 Bump version a5172df9e9 Next dev cycle f109fa3d4c Release version 0.22 7db26a8e59 Update CHANGELOG 11203815a8 Merge pull request #3500 from nakengelhardt/mutate_warn_not_enough 47e73826e0 mutate: warn if less mutations possible than number requested b5d3920bf5 Merge pull request #3499 from YosysHQ/micko/verific_edif 620af8b663 Bump version 1a6f10e8ba Add support for EDIF file reading using Verific f5e2c0a498 Merge pull request #3494 from YosysHQ/micko/verific_attributes d29606532a Changing error reason string to be based on lut input plane limit constant. 43267dec99 support file content redirection for verific frontened b45517f7b7 Add comment for future self f54ac8a6d6 Handle attributes imported from verific a9795c4fce Bump version b2ddd0d42d Merge pull request #3489 from hzeller/20220924-fix-hardcoded-bin-bash f09bf58b6e Fix hard-coded path to /bin/bash -> /usr/bin/env bash fcd1be1422 Merge pull request #3486 from daglem/fix-flowmap-crash 0ab726e204 Bump version 69787f1906 remove extra space in formating bc1e579483 stat: add tech tech-specific utilizations to json 50e267eace Bump version 5580185228 Merge pull request #3488 from YosysHQ/micko/test_fix b2eb331b83 Merge pull request #3487 from YosysHQ/micko/verific_mem_fix 8fb498744f Import memory attributes 1ecf6aee9b Test fixes for latest iverilog c4c68e8d86 Fix crash in flowmap a217450524 Bump version da614fe13a Fix tmpdir naming when passing -nocleanup option to abc(9) on systems where base_tmpdir isn't /tmp/ dd4a0c3034 Add CodeQL d98738db5c Bump version 5ccc941f25 Update to latest ABC changes 406e12d859 Bump version b7bf685010 Update to latest abc 3f94f9313a verific: better fix for read callback 06a9c7499a verific: fix crash when using prep right after read 4fa4161aa6 Bump version 07d9924a1b Next dev cycle e6d2a900a9 Release version 0.21 0ff129c10b Update Changelog 6d5adb6a65 Update documentation 9313549cdd Bump version 3f04931adb Replaced old markdown Issue template with new GitHub forms templates (#3468) 1bc6ea2366 Merge pull request #3470 from jix/smtbmc-faster-parse 1d40f5e8fa smtbmc: Avoid unnecessary string copies when parsing solver output 6e907acf86 Bump version d8a383b555 Merge pull request #3087 from tgingold-cern/sf2 d829d7fe00 Merge pull request #3458 from QuantamHD/abc_faster 1e0e3bd48e sf2: add NOTES about using yosys for smartfusion2 and igloo2 0f6cf8b8e4 sf2: add a test for $alu gate c25f3ff3df sf2: suport $alu gate and ARI1 implementation 13ccdd032d synth_sf2: purge on last clean 39993a92d7 sf2/cells_sim.v: add XTLOSC, SYSRESET cells 1c0119aa90 sf2/cells_sim.v: add IOSTD parameter to I/O cells 4543751a77 synth_sf2: add -discard-ffinit option to discard ff initial value 7117817dbe Bump version a8506c1c76 Merge pull request #3463 from YosysHQ/micko/hierarchy_fix 5b5fe76966 Add test for bug 3462 883831bd24 Fix mingw build 4bc1e1d1f1 Makes sure to set initial_top when change, fixes #3462 060cbd3e9e Bump version 0d8ee63d03 Merge pull request #3461 from YosysHQ/aki/hashlib_assert 6717e02023 kernel: hashlib: cleaned up message about table size in cases where `sizeof(int) == 4`, (closes #3440) 7d35003c16 Merge pull request #3449 from YosysHQ/aki/show_pathrw e3eb114e75 use inttypes format specifiers 7e92e80741 dump runtime information for passes to json 8e640663d6 Merge pull request #3457 from KrystalDelusion/docs_width 114253cd54 Improves ABC command runtime by 10-100x 9465b2af95 Fitting help messages to 80 character width 1433a63165 yosys: passes: cmds: show: added filename re-writing to `show -lib` 15a0697c70 Adding check for BLIF names command input plane size. db73f3c26b Merge branch 'master' of https://github.com/ALGCDG/yosys 029c2785e8 Bump version f1c9399b66 Merge pull request #3450 from jix/write_aiger_nonff 5142fb3b5c write_aiger: Fix non-$_FF_ FFs 1c36f4cc2c Bump version 556d008ed3 Merge pull request #3434 from jix/witness_flow f7023d06a2 sim: -hdlname option to preserve flattened hierarchy in sim output 66f761a8c5 smtbmc: Set step range for --yw and dont skip steps for --check-witness 927af914f1 Update CEX minimization patches for abc 4ad13c647e clk2fflogic: Generate less unused logic when using verific 65145db7e7 rename: Add -witness mode b156fe903f yosys-witness: Add stats command 475267ac25 smtbmc: Add --check-witness mode efd5b86eb9 aiger: Add yosys-witness support f041e36c6e smtbmc: Add native json based witness format + smt2 backend support 96a1173598 btor: Support $anyinit cells 5893cae647 aiger: Support $anyinit cells 021c3c8da5 smt2: Support $anyinit cells a2f9ebe43a memory_map: Add -formal option 0cdb14df41 setundef: Do not add anyseq / anyconst to unused memory port clocks 428ad5b9fd wreduce: Keep more x-bits with -keepdc 95db5a9d38 formalff: New -setundef option a5e1d3b997 formalff: Set new replaced_by_gclk attribute on removed dff's clks c0063288d6 Add the $anyinit cell and the formalff pass c26b2bf543 Bump version 6f439dc59a Merge pull request #3425 from YosysHQ/lofty/stat-json 59facfa98c stat: add option for machine-readable json output 63fca0dbc2 Merge pull request #3277 from YosysHQ/lofty/rename-scramble_name 91010449ff Bump version 0b0e01e211 Merge pull request #3443 from YosysHQ/micko/resetall_undefineall b76c72056b set default_nettype to wire for resetall 545a3417c8 resetall does not affect text defines, but undefineall does 51f67e55f2 Merge pull request #3322 from Forty-Bot/default_assignment_first 8c05f14b58 Order ports with default assignments first 035d99f3a8 Bump version 8fab6ec023 nexus: Fix BRAM mapping. 594cfd1d4d Merge pull request #3441 from YosysHQ/micko/smtio-utf-8 4444d5cf68 Switched to utf-8 in smtio.py 99f1c71582 properly encode string in rtlil d2b4246a6d Bump version 6b4dbf6c36 Merge pull request #3439 from YosysHQ/micko/filepath_improve f4a1906721 support file locations containing spaces a48dcd1d40 rename: add -scramble-name option to randomly rename selections 6c65ca4e50 Encode filename unprintable chars 2b1aeb44d9 verific - make filepath handling compatible with verilog frontend 60a787fa50 Bump version 733902c81e Next dev cycle 4fcb95ed08 Release version 0.20 a07b06d5e7 Update Changelog 3f7042d114 update manual to latest 3705d8414e Merge pull request #3432 from YosysHQ/aki/jny_updates 6a1d98b816 Update manual and changelog e989313317 Bump version b8316b2f13 Merge pull request #3433 from jix/fix_smt_shift 6af5e74f95 smt2: Fix $shift/$shiftx with negative shift ammounts e3074c044a misc: Added JNY schema definition 4f0ee383c9 backend: jny: updated the `JnyWriter` to emite a new "invocation" entry as well as a "$schema" entry to point to the location the schema will be at 7d4f87d69f Bump version 15393442d6 Merge pull request #3089 from YosysHQ/gatecat/liberty_wb a207fd4b33 Merge pull request #3429 from YosysHQ/micko/verific_upto 6f792e2223 Update documentation 52a4a89265 Setting wire upto in verific import 30a4218f53 Bump version d19f9d0b66 Update README 23a39d707e Bump version a681904237 Assorted microoptimization speedups in core data structures. 6ba48515b5 macos 10.15 deprecated by gh actions 29a5947bf8 Make all compile under OpenBSD (#3423) bc012995b4 Support using ABC source tarball distribution d4875ceae6 Merge pull request #3406 from josuah/master 358e656e21 Bump version f679b756d8 opt_reduce: Fix use-after-free. 7e02b6a70b Bump version 12b0ce9721 Merge pull request #3419 from jix/sim_nested_anyseq 14ba50908b sim: Fix $anyseq in nested modules 58fddf61cc reduce the Makefile TCL compatibility code 6eba56fcf0 include changes to support OpenBSD and prepare NetBSD support 793b9ade56 extends the list of platforms without a82eff2e20 Bump version d25f349f4d Update to latest abc 08c319fc35 Bump version f086da8bdf Merge pull request #3392 from rockybulwinkle/rockybulwinkle-patch-1 58c51b9a0b Remove empty lines 2326b9f90a Bump version 933f110bf7 Merge pull request #3404 from YosysHQ/fix-build-after-pr-3399 502b96fe53 Fix external ABC build after commit 0ca0932b5. 43d86f2c26 Fix WASI build after commit 0ca0932b5. 09c6fc68c7 Bump version 0098b32c6c using more portable formatting 0cd20693c2 Merge pull request #3399 from YosysHQ/abc_cpp 4c5152bf26 Merge pull request #3402 from C-Elegans/modfloor_support 86a4ba1758 Merge pull request #3397 from pepijndevos/patch-2 24b895778a Add support for GHDL modfloor operator 086c2f3224 Bump version 4db820e9d4 Fix static initialization, fixes mingw build 0ca0932b52 Update abc and build as C++ da0682b99a Next dev cycle a45c131b37 Release version 0.19 0b44bff182 Merge pull request #3398 from jix/mention_smtlib2_module 5343911263 Mention smtlib2_module in README.md and CHANGELOG 59b96bb1f8 Upadte documentation and changelog de07eb11c1 Apicula now supports lutram c39bade1a7 Bump version 4a1e54bf70 Merge pull request #3395 from jix/opt_dff_keepdc_initival 876ef59f4f Merge pull request #3396 from jix/async2sync_const_clocks fda3a537e1 Update abc 0182b26aba Merge pull request #3391 from programmerjake/simcheck-allow-smtlib2-blackboxes 42721b6a12 Bump version 5db542742b async2sync: turn FFs with const clks into gclk FFs with feedback b80976b543 Update to new verific extensions inteface 9d63a90e0e Bump version 0d2377c8a6 Merge pull request #3394 from jix/memory_map_rom_keepdc 930bcf0e75 smt2, btor: Revert calling memory_map -rom-only a47254bd10 opt_dff: With -keepdc, never turn undef init vals into const drivers a6b440b5c9 memory_map: avoid undriven unused FF inputs for -keepdc 869e6a1b6d Bump version d78d807a7f memory_map: -keepdc option for formal 48efc9b75c gatemate: Add test for LUT tree mapping 38a24ec5cc gatemate: Add LUT tree library script 7c756c9959 gatemate: Add preliminary sim models for LUT tree structures fbf5d89587 equiv_make: Add -make_assert option ec2f8796bd Update tcl doc, yosys does not return data to tcl c16c028831 add hierarchy -smtcheck b2408df313 Bump version f69c2c802c Adding expected error message. c8cd4f468a Adding testcase for issue 3374 7eeb656e2a Add check for BLIF with no model name 1fdbb42fdd Revert "use new verific extensions library" a30b38910c Merge pull request #3387 from ekiwi/btor-pos-cell 0b486c56e8 Bump version de5c4bf523 btor: add support for $pos cell e7e8e3b0f6 Adding expected error message. 34804f3fb6 codeowners: adopt ABC9 and update intel_alm username 5dfad5101d chformal: Rename -coverprecond to -coverenable e39c422734 chformal: Test -coverprecond and reuse the src attribute c659bd1878 chformal: Add -coverprecond option 90147f5fbf Bump version 4542d51791 Adding testcase for issue 3374 e6a5d84149 Merge pull request #3383 from jix/write_formal_map_roms 4adef63cd4 smt2, btor: Use memory_map -rom-only to make ROMs usable for k-induction ab3a9325c3 memory_map: Add -rom-only option. c23139fd98 Merge pull request #3382 from YosysHQ/micko/verific_extensions 607e957657 use new verific extensions library 01daa077a2 memory_map: Use const drivers instead of FFs for ROMs. bb634d39ef Bump version d69091806a memory_libmap: Fix wrprio handling. 25a4cd7020 memory_libmap: Fix params emitted for unused ports for consistency. b604c97b33 Add check for BLIF with no model name 3046a06490 Bump version 6b7efe12b7 Add a check for packed memory MEMID uniqueness 3eaa9e38e0 Merge pull request #3196 from bfg86/bfg86/rename 1ff0e1a58a opt_ffinv: Fix use after free. ddc8044655 removed deprecated features code aedd3b7999 Updating help-text with nakengelhardts suggestion. b15a46c2c0 Bump version 53b205c41d Merge pull request #3368 from jix/smtbmc-unroll-noincr-traces-fix 4b423dcfb4 Next dev cycle 19ce3b45d6 Release version 0.18 d1cd24a457 Update manual 1940bf647f Updated CHANGELOG 47a99092af Bump version b8ede6162b Merge pull request #3349 from nakengelhardt/select_count_scratchpad 871b277d35 Merge pull request #3359 from jix/fmcombine-memid 9c41b43191 Use compiler-generated default constructor for RTLIL::Const::Const 9d41aa8e28 Avoid unnecessary copy of a potential large constant value. 6e8e4b4550 verific: Added "-vlog-libext" option to specify search extension for libraries d1b2beab12 Bump version 47efc04a7d wreduce: Introduce -mux_undef option (aligned with opt_expr). 0c5f62f6ff smtbmc: noincr: keep solver running for post check-sat unrolling 6db2948938 Merge pull request #3357 from jix/smtbmc-cvc5 a0172e68c5 More updates on CHANGELOG 096f3d2aa4 Update changelog and manual aae2c01326 sta: warn on unrecognised cells only once 4afb951283 Bump version d9bb10ba5f Merge pull request #3367 from jix/smtlib2-module-fixes ac22f1764d smt2: emit smtlib2_comb_expr outputs after all inputs 5f9a97d234 Merge pull request #3319 from programmerjake/smtlib2-expr-support fe048a48b3 Merge pull request #3358 from jix/smtbmc-yices-forall d07828b409 opt_ffinv: Harden against simple ff/inv loop. 9e8a2ac051 iopadmap: Fix z assignment removal. aa0b47c74a Bump version e35a166353 verific: proper file location for readmem commands 8d0f71b256 Bump version 459941c8ff fmcombine: Add _gold/_gate suffix to memids ab9e887dee smtbmc: Force nonincremental mode when yices is used with forall 0207d7b0cf smtbmc: recognize cvc5 and fix unrolling for cvc4/cvc5 0b0123e003 don't use sed -i because it won't work on macos d88a5d26b7 Fix preventing show crashing with newer graphviz b7c19b1c88 smtlib2_module: try to fix test on macos cd57c5adb3 smt2: Add smtlib2_comb_expr attribute to allow user-selected smtlib2 expressions 1eb1bc441b Bump version 71dfbf33b2 Add -no-rw-check option to memory_dff + memory + synth_{ice40,ecp5,gowin}. 3a0aa9c663 memory_dff: Add support for no_rw_check attribute. 61b05051e1 also make 'stat' save counts to scratchpad a55c3db384 have 'select -count' save the count to scratchpad entry 'select.count' 01cb02c81d Merge pull request #3348 from zachjs/func-tern-hint a79a228c2b Bump version a650d9079f verilog: fix width/sign detection for functions cea7e85d60 Merge pull request #3347 from DanielHuisman/fix-3053 6809ee8de0 Fix typo in emcc flags (typo introduced by #3053) 4bfaaea0d5 verilog: fix size and signedness of array querying functions ce24208a8b Bump version 5d08688054 gatemate: Fix minor issues with `memory_libmap` (#3343) 197c9e04e8 Merge pull request #3333 from mohamed/feature/tmpdir 08275a1569 Cleanup, and fix windows 1822be8792 Observe $TMPDIR variable when creating tmp files bf78041e89 Merge pull request #3341 from mmicko/unused_vars f9b6fe521d Upload emscripten artifact 4316cdb603 Remove set but unused variable 5490f94e82 Add emcc build (stuck if all cpus used on GH) 0d31aa6008 Proper std::move 7ee570a75e Use proper operator b0c71ed594 Merge pull request #3053 from DanielHuisman/pr-2 f698a0514d Bump version b75fa62e9b verilog: fix $past's signedness 63c9c9be5c Merge pull request #3011 from DanielHuisman/pr-1 8e9471c695 Merge pull request #3335 from programmerjake/divfloor-in-write_smt2 904e2efe11 Merge pull request #3138 from DanielG/fix-git-rev 222e7a2da3 Make GIT_REV logic work in release tarballs cffec1f95f verilog: fix signedness when removing unreachable cases d53479a0d6 add $divfloor support to write_smt2 c525b5f919 Bump version 335b4888ce Merge pull request #3332 from YosysHQ/verific_f fdb393b6ce fix text to fit 80 columns 4a5790d404 Update verific command file documentation a6ec5754c6 Use analysis mode if set in file e47cfe277e Merge pull request #3331 from YosysHQ/git_rev_fix 87149b3f8e Change way to get commit sha 166a175983 abc9_ops: Don't leave unused derived modules lying around 0b1a1a576b Bump version 795c445159 Merge pull request #3324 from jix/confusing-select-errors fc65ea47df select: Fix -assert-none and -assert-any error output and docs 015ca4ddac Bump version 606f1637ae Add memory_bmux2rom pass. 982a11c709 Add memory_libmap tests. 2a2dc12eb6 gatemate: Use `memory_libmap` pass. 2dcb0797f0 machxo2: Use `memory_libmap` pass. 9d11575856 efinix: Use `memory_libmap` pass. f4d1426229 anlogic: Use `memory_libmap` pass. d7dc2313b9 ice40: Use `memory_libmap` pass. 3b2f95953c xilinx: Use `memory_libmap` pass. e4d811561c gowin: Use `memory_libmap` pass. 0a8eaca322 nexus: Use `memory_libmap` pass. a04b025abf ecp5: Use `memory_libmap` pass. 7c5dba8b77 Add memory_libmap pass. 9450f308f0 proc_rom: Add special handling of const-0 address bits. 06ef3f264a Bump version 7c64c70727 Merge pull request #3310 from robinsonb5-PRs/master 98c7804b89 opt_ffinv: Use ModIndex instead of ModWalker. 6c6017c973 Use log_warning when Tcl_Init fails, report error with Tcl_ErrnoMsg. 2864f2826a Merge pull request #3314 from jix/sva_value_change_logic_wide 3f8fb28cd2 Bump version 2858bb03cd Add opt_ffinv pass. f56a3bd48f Bump version 990c9b8e11 Add proc_rom pass. fada77b8cf verific: Use new value change logic also for $stable of wide signals. 83dbea1689 Now calls Tcl_Init after creating the interp, fixes clock format. c862b1dbfb Bump version 587e09d551 Merge pull request #3305 from jix/sva_value_change_logic 5ca2ee0c31 Merge pull request #3297 from jix/sva_nested_clk_else a855d62b42 verific: Improve logic generated for SVA value change expressions d562bfd165 Next dev cycle 6f9602b4cf Release version 0.17 72d2efeb32 Update CHANGELOG 65f70b9d50 Update manual 58b23954e8 Merge pull request #3299 from YosysHQ/mmicko/sim_memory 600079e281 Fix running sva tests 9c69e9f8a6 Bump version 77b1dfd8c3 opt_mem: Remove constant-value bit lanes. 048170d376 Bump version 37b6614718 include latest abc changes 7fcf976f9e include latest abc changes 384d2120ee Merge pull request #3300 from imhcyx/master 52d8ddee0c Include abc change to fix FreeBSD build d8adbff72f Handle possible non-memory indexed data 71166eeecf memory_share: fix wrong argidx in extra_args a8cc0c3930 Bump version 18a48b1337 abc: Use dict/pool instead of std::map/std::set 8b3657454b map memory location to wire value, if memory is converted to FFs 8e02b3ca30 fix crash when no fst input ad48639cdd Start restoring memory state from VCD/FST 3fb32540ea Add propagated clock signals into btor info file 96f64f4788 verific: Fix conditions of SVAs with explicit clocks within procedures 11e75bc27c Bump version 3730db4b98 AIM file could have gaps in or between inputs and inits c785cb7fe3 Bump version 7bdf7365e7 Merge pull request #3294 from YosysHQ/micko/verific_merge_past_ff 422db937d4 Ignore merging past ffs that we are not properly merging b30d90a14a Bump version 414dc25a96 Add missing parameters for ecp5 6ae0b51c76 Merge pull request #3287 from jix/smt2-conditional-store e0e31bfc5c Merge pull request #3257 from jix/tribuf-formal 3c0f3504c6 Merge pull request #3290 from mpasternacki/bugfix/freebsd-build a511c27eb7 Merge pull request #3289 from YosysHQ/micko/sim_improve 0302e97ebc Fix build on FreeBSD, which has no alloca.h bbfdea2f8a Match $anyseq input if connected to public wire 4d80bc24c7 Treat $anyseq as input from FST 9c7deabf94 Ignore change on last edge 33f4009bb5 Last sample from input does not represent change 83cad82b29 latches are always set to zero c989adcc2d If not multiclock, output only on clock edges 75032a565d Set init state for all wires from FST and set past 8fa2f3b260 Fix multiclock for btor2 witness c7ef0f2932 smt2: Make write port array stores conditional on nonzero write mask 29c0a59589 Bump version c3a3f68b4d Merge pull request #3280 from YosysHQ/micko/fix_readaiw 2610b04033 Update abc 1cc281ca6f verific: allow memories to be inferred in loops (vhdl) d23260d381 Merge pull request #3282 from nakengelhardt/verific_loop_rams 36b5caf821 Bump version 25ff83f0b5 memory_share: Fix up mismatched address widths. 48eea3efcf opt_dff: Fix behavior on $ff with D == Q. 57bc29c64a verific: allow memories to be inferred in loops 9508bb2330 Fix reading aiw from other solvers bc48500548 tribuf: `-formal` option: convert all to logic and detect conflicts c1646a00ac Bump version 4772bc70d0 Merge pull request #3275 from YosysHQ/micko/clk2fflogic_fix 868409361c Use wrap_async_control_gate if ff is fine bd7ee79486 Merge pull request #3273 from modwizcode/fix-build 1f1a403cce pass jny: flipped the defaults for the inclusion of various bits of metadata 6053856f91 pass jny: ensured the cell collection is cleared between modules 5a016713cc pass jny: fixed missing quotes around the type value for the cell sort 2e792857e9 pass jny: fixed the backslash escape for strings cae5ea8337 pass jny: removed the invalid json escapes dccc89e8b3 pass jny: added some todo comments about things that need to be done before a proper merge, but it should be enough for the PoC at the moment 1be9bef28b pass jny: changed the constructor initializers to use parens rather than curly-braces to hopefully make GCC 4.8 happy 43b2fc5566 pass jny: fixed the string escape method to be less jank and more proper 52ea944012 pass jny: fixed the signed output for param value output 58e2870261 pass jny: added connection output 167206f2f5 pass jny: added filter options for including connections, attributes, and properties 587f31b9a3 pass jny: large chunk of refactoring to make the JSON output more pretty and the internals less of a spaghetti nightmare 0e20619189 metadata -> jny: migrated to the proper name for the pass bdf14557ca pass metadata: added the machinery to write param and attributes 1876ed21e7 pass metadata: removed superfluous `stringf` calls ca03fbdc6d pass metadata: some more rough work on dumping the parameters and attributes 6a90b42c48 pass metadata: fixed the MetadataWriter object initializer so GCC 4.8 is happy 7a275567df pass metadata: added the output of parameters, d8b85e1247 pass metadata: fixed some of the output formatting f6bb238051 pass metadata: initial commit of the metadata pass for exporting design metadata for yosys assisted tooling ccc6060f52 Makefile: properly conditionalize features requiring compression. e0ba324236 Bump version 8a1d531b25 Merge pull request #3269 from YosysHQ/micko/fix_autotop 376d8cb26f abc: Add support for FFs with reset in -dff 4da3f2878b Bump version bf15dbd0f7 sv: fix always_comb auto nosync for nested and function blocks 977002b1d2 Reorder steps in -auto-top to fix synth command, fixes #3261 957fdb328a Next dev cycle b63e0a0cae Release version 0.16 580800eb0d Bump version 0aec79a0da show: Fix width labels. 0d3bf9e725 Update CHANGELOG and manual 75f4847689 Merge pull request #3265 from YosysHQ/micko/sim_improvements 6020ba67ac past_ad initial value setting 2c96ecc5f7 setInitState can be only one altering values b54aecd80a Set past_d value for init state 8ca9737180 Merge pull request #3264 from jix/invalid_ff_dcinit_merge 5ac5c57c73 Bump version ca5b910296 opt_merge: Add `-keepdc` option required for formal verification 2a76af9eb6 Merge pull request #3263 from YosysHQ/micko/clk2ff_init 86ce441af6 Set init values for wrapped async control signals 2ec4af56e6 Merge pull request #3262 from YosysHQ/micko/verific_hiernet 1a1f529099 Preserve internal wires for external nets 2b115d858d Bump version ed83f0dea8 Merge pull request #3256 from YosysHQ/micko/aiw_multiclock c95b9b4ba5 Support memories in aiw and multiclock fc2af4e32d Bump version 18fb73fd89 Merge pull request #3259 from YosysHQ/micko/verific_valgrind bbf65702a1 Fix valgrind tests when using verific 0921e5b9a4 Merge pull request #3260 from YosysHQ/micko/proper_scopename 2e47b61cc6 Proper scope naming from FST 72e5498bdf Merge pull request #3250 from YosysHQ/micko/verific_consistent c662fcbc5c Bump version d44f618de5 Merge pull request #3258 from jix/fix-no-assertions 8b15f3a548 smtbmc: fix bmc with no assertions 48d7a6c477 Bump version 3bebe17e5d kernel/mem: Only use FF init in read-first emu for mem with init 8cc8c5efde Merge pull request #3253 from jix/smtbmc-nodeepcopy 17e2a3048c Merge pull request #3247 from jix/smtbmc-keepgoing c1057cb3e0 Merge pull request #3194 from Ravenslofty/abc9-flow3mfs 421192f1cb Merge pull request #3246 from YosysHQ/gatecat/timing-derive-fix 30bc0d26ea gowin: Add oscillator primitives d25daa6203 smtbmc: Avoid unnecessary deep copies during unrolling 62b89bb0d4 Update URL to zlib 703769e494 Properly mark modules imported 207417617d Bump version 349c0ff0a7 Add some more reserve calls to RTLIL::Const a7e7a9f485 Merge pull request #3249 from YosysHQ/micko/no_startoffset 245ecb0529 Import verific netlist in consistent order 4fd8b38d7a Add -no-startoffset option to write_aiger afe258e6f8 Bump version 89dcd7c31e Merge pull request #3243 from nakengelhardt/fix_aiw_comment 5e4d804e53 yosys-smtbmc: Option to keep going after failed assertions in BMC mode e43ebf8527 yosys-smtbmc: Fix typo in help text, remove trailing whitespace 8b64dc1dce abc9_ops: Also derive blackboxes with timing info a7ee01065a ignore # comment lines 6318db6152 Bump version 15c7205908 Update abc with latest fix 322ab1cd54 Proper SigBit forming in sim ff3b0c2c46 Proper SigBit forming in sim f45b290820 Bump version be9595e18f xilinx: Add RAMB4* blackboxes 3bf1070245 Bump version 55eed8df57 More verbose warnings 0c5279b73d Merge pull request #3236 from YosysHQ/micko/tb_initial e1d4863a19 Bump version 1f3423cd7d Recognize registers and set initial state for them in tb e217e3017a Update sim help message. 66914b6eb3 Bump version 19b7633aca gowin: add support for Double Data Rate primitives 25d6fdfea7 Merge pull request #3232 from YosysHQ/micko/fst2tb f5c20b8286 Added fst2tb pass for generating testbench 5e2992dae2 Merge pull request #3213 from antonblanchard/abc-typo 27c5bafc95 Proper example code a502570c25 Bump version cbece4af0c Merge pull request #3229 from YosysHQ/micko/sim_date 532343dcfa Merge pull request #3222 from zachjs/prune-linux-ci 04de9bb655 Merge pull request #3228 from YosysHQ/micko/disable_tests e21badd4b3 Add "sim -q" option 37de369ba7 Add date parameter to enable full date/time and version info be32de1caa Small fix in "sim" help message 2f44683f4f Merge pull request #3226 from YosysHQ/micko/btor2witness 5204694123 FstData already do conversion to VCD b72c779204 Support cell name in btor witness file d340f302f6 Fix handling of some formal cells in btor back-end ebe2ee431e handle state names of $anyconst and $anyseq 5e7ea57d8e Prune Linux CI builds 357336339a Proper write of memory data 75c0391f06 Disable tests on most of platforms eb8c61f033 Bump version 9f7a55c99f intel_alm: M10K write-enable is negative-true 295b0d1899 Start work on memory init f37ac5d934 Fixes and error check ede348cdc2 cleanup 1b1ecd4ab0 Error checks for aiger witness b6aca1d743 btor2 witness co-simulation 4ccc2adbda Merge pull request #3210 from rqou/json-signed 7ba636cb32 Bump version a95e5d505b Merge pull request #3186 from nakengelhardt/smtbmc_sby_print_id 13655ddccf Merge pull request #3206 from YosysHQ/micko/quote_remove c3124023e4 Merge pull request #3207 from nakengelhardt/json_escape_quotes 7be7f5e02e Next dev cycle 07a43689d8 Release version 0.15 66ba5ed7a5 Update ABC a7090e9711 Update documentation 9581b9adac Merge pull request #3219 from YosysHQ/micko/quick_vcd d1fbe738a7 Merge pull request #3220 from YosysHQ/claire/simstuff e768f7552c Bump version 59983eda17 Add option to ignore X only signals in output 48b56a4f7f Write simulation files after simulation is performed 3818e1160d Update CHANGELOG 2ca69e1b88 Merge pull request #3224 from YosysHQ/micko/refactor 28bc88a57e Cleanup 4a38d15f0d Bump version 94505395a9 Refactor sim output writers dfd4c81eac Quick fix 56b968f61c Add writing of aiw files to "sim" command 1fd3a642c9 Hotfix in AIGER witness reader state machine 8be09b5b24 VCD reader support by using external tool ec4af6af2f Merge pull request #3216 from YosysHQ/claire/simstuff 9571acc0bf Support extended aiw format fca168797e Fix for last clock edge data ca261d3c28 Experimental sim changes 08c771078f Bump version 22d9bbb308 gowin: Remove unnecessary attributes 9b3cd4f0d8 gowin: Add support for true differential output 89300b2dca abc: Fix {I} and {P} substitution dc739362c7 print cell name for properties in yosys-smtbmc a41c1df76f Merge pull request #3211 from YosysHQ/micko/witness ac294ed419 Merge pull request #3197 from YosysHQ/claire/smtbmcfix 2d3a337795 json: Add help message for `signed` field 286caa09bd Bump version d0b72e75d9 Merge pull request #3203 from YosysHQ/micko/sim_ff d0f4d0b153 ecp5: Do not use specify in generate in cells_sim.v. fd3f08753a Fix handling of ce_over_srst 8fd1b06249 fix handling of escaped chars in json backend and frontend 1aa9ad25d0 Fix cycle 0 in aiger witness co-simulation 5f918803de Changed error message 41754b4207 Added AIGER witness file co simulation 13a5c28459 simplify logic of handling flip-flops and latches 61752b255f Review cleanup 29293a57bb Remove quotes if any from attribute 21baf48e04 test dlatchsr and adlatch 271ac28b41 Added test cases fb22d7cdc4 Add support for various ff/latch cells simulation 1586000048 Bump version c9a32c0d92 Merge pull request #3204 from YosysHQ/claire/update-abc 3bae2705fc Bump ABC version 426f89fc6f Bump version 15a4e900b2 verilog: support for time scale delay values 68c67c40ec Fix access to whole sub-structs (#3086) 59738c09be Bump version 3a62fa0c97 gowin: Add remaining block RAM blackboxes. 1772a1e98e Bump version 15eb66b99d verilog: fix dynamic dynamic range asgn elab 90bb47d181 verilog: fix const func eval with upto variables ca876e7c12 Merge pull request #2376 from nmoroze/clk2ff-better-names 30eb7f8665 Add a bit of flexibilty re trace length when processing aiger witnesses in smtbmc.py fc7d78f071 Merge pull request #3164 from zachjs/fix-ast-warn 49545c73f7 Merge branch 'master' into clk2ff-better-names e016518866 Merge pull request #2019 from boqwxp/glift 7ac98d1c87 Add -suffix option to rename -wire. 5ac32ea68c abc9: add flow3mfs script c8903e7053 Bump version a08fff9c0f Merge pull request #3193 from YosysHQ/micko/verific_f 2cef48bf2c Add ability to override verilog mode for verific -f command f61f2a4078 gowin: Fix LUT RAM inference, add more models. ac2bb70b52 ecp5: Fix DPR16X4 sim model. 23d062fea3 Bump version 818060880d Next dev cycle a4522d6282 Release version 0.14 9647f6326f Update CHANGELOG and manual d7f7227ce8 Merge pull request #3185 from YosysHQ/micko/co_sim 9c93668954 Bump version 958c3a46ad nexus: Fix arith_map CO signal. c0a156bcb4 Error detection for co-simulation 6db23de7b1 bug fix and cleanups 675a7bd22c Bump version 2d98fe870c Merge pull request #3183 from YosysHQ/micko/nto1mux 0b633b6c2e Use bmux for NTO1MUX 7ef6da4c7d Add test cases for co-simulation 518521c72e Merge pull request #3182 from yrabbit/wip-doc2 f5609d52c4 Correct a typo in the manual 4a30c9cb94 Fix Visual Studio build 990aee5531 respect hide_internal flag 169ffcd2fb unify cycles counting and cleanup 820b2fdd65 added stimulus mode and param check 0a6e2bd5d5 Update comment e04ac4e9e9 Fix unextend method for signed constants 8ba2000a50 error when no signal found bf85dfee5e Merge pull request #3176 from higuoxing/fix-ref-manual 1b5ff92e62 Cleanup eabd0ff115 Compare bits when not all are defined 26de52fa09 Cleanup 6513300db7 message update 543feb75cb Display simulation time data a6959d30df Use edges when explicit cbadfa0268 Updating initial state and checks 190e44f0da Fix scope fc40df0916 Bump version 56e7791760 verilog backend: Emit a `wire` for ports as well. 0520e99968 Fix the help message of synth_quicklogic. 07a657fb0c opt_reduce: Add $bmux and $demux optimization patterns. 772d137bfa Bump version 93508d58da Add $bmux and $demux cells. f04d1398e5 check if stop before start ecbba625c4 set initial state, only flip-flops cb12b7c4d8 ignore not found private signals f0f3c81c56 preserve VCD mangled names 72acce0c82 detect edges even when x 81b76155d6 recursive check a8d03df173 cleanup 4f75a2ca1b Do actual compare 7101df62f8 Fix for limit_range_end when not writing vcd 3e35de2be1 Add more options and time handling db33b1e535 opt_dff: Don't mutate muxes while ModWalker is active. bac750fb99 kernel/mem: Add read-first semantic emulation code. 9a2294f285 Bump version 0e97c3fd74 manual: Fix a custom pass example. 1759c80a3f memory_bram: Make use of new mem emulation functions to map more RAMs. 5e4c6915c9 kernel/mem: Add functions to emulate read port enable/init/reset signals. 84f0df1c95 Bump version 76f7b030ae change to windows-2019 ccc3e3d13a update version 40018e191b Display values of outputs 226dc659f0 Fix tabs/spaces be7be63fec Check if stimulated 9a8939f0a4 Read fst and use data to set inputs 8a02616465 Add fstdata helper class c811a71301 Cleanup of config to support platforms ccfc00705a Add ability to write to FST file 9e9083bbe9 Add FST library bc027b2cae Bump version f699c4ba58 nexus: Fix BB sim model 36482680d5 Removed dbits 8 since 9 will always be picked 4525e419f6 Merge pull request #3120 from Icenowy/anlogic-bram 342927732e fix dumpAst() compilation warning 59382945a9 Bump version 55924de708 Merge pull request #3162 from YosysHQ/mmicko/windows_guidelines 703306c119 Update guidelines/Windows 891eec2882 Merge pull request #3145 from nakengelhardt/advertise_suite_in_readme 15b4d05805 mention distributions' package manager 41e215219b Add info about VS build 61324cf55f Bump version b91533d9f2 Forgot one 883b4fb7e6 Change url to https c428a894c0 Next dev cycle 8b1eafc3ad Release version 0.13 64972360a8 Update CHANGELOG 0feba821a8 Bump version aa35f24290 sv: auto add nosync to certain always_comb local vars 828e85068f sv: fix size cast internal expression extension 59a7150344 Bump version 66447e8faf logger: fix unmatched expected warnings and errors b022fe61a7 opt_dff: fix sequence point copy paste bug 6483e691bc mention tabby+oss cad suite in readme 493b5e03e7 manual: Fix cell-stmt order 361916ad3e Bump version e0e4dfb55e fix iverilog compatibility for new case expr tests 207af4196b fixup verilog doubleslash test 8c509a5659 sv: fix size cast clipping expression width cb17eeaf50 Update manual cfe940a98b Bump version ebe396a2ab Merge pull request #3127 from whitequark/cxxrtl-no-reset-elided fc049e84a9 cxxrtl: don't reset elided wires with \init attribute. 7407a7f3ef Bump version d015c2b48a intel_alm: disable 256x40 M10K mode 229980d663 Bump version f84c9d8e17 memory_share: Fix SAT-based sharing for wide ports. f599c148c5 Bump version 7608985d2c fix width detection of array querying function in case and case item expressions c2b7ad3b28 anlogic: support BRAM mapping 60c3ea367c Bump version ed4642e18e Merge pull request #3115 from whitequark/issue-3112 73eea51613 Merge pull request #3114 from whitequark/issue-3113 4cd2f03e36 preprocessor: do not destroy double slash escaped identifiers 7f2ea7d222 cxxrtl: demote wires not inlinable only in debug_eval to locals. 4f1d62d9b2 bugpoint: avoid infinite loop between -connections and -wires. 477eeefd9b Bump version 5dadcc85b7 Merge pull request #3111 from whitequark/issue-3110 e1c7a9a647 Hotfix for run_shell auto-detection 48ed6d998b Fix null pointer dereference after failing to extract DFF from memory. b07ca8756a Bump version 5e5c8a54ce Merge pull request #3108 from YosysHQ/claire/verificdefs 313340aed5 Add YOSYS to the implicitly defined verilog macros in verific 19a38222e7 Bump version 0aad88a2fb Add clean_zerowidth pass, use it for Verilog output. bdc6ba019c Merge pull request #3105 from whitequark/cxxrtl-reset-memories-2 6a7253b46e Bump version 26f0f6bb0b Fix unused param warning with ENABLE_NDEBUG. d019b4e681 rtlil: Dump empty connections when whole module is selected. 55c9fb3b18 cxxrtl: preserve interior memory pointers across reset. 21fbdb6638 Merge pull request #3103 from whitequark/write_verilog-more-zero-width-values 7c9e498662 cxxrtl: use unique_ptr[]> to store memory contents. 86f2804dc3 write_verilog: dump zero width sigspecs correctly. 8e91857fab Bump version 2412497c26 Merge pull request #3102 from YosysHQ/claire/enumxz 2da214d721 Fix verific import of enum values with x and/or z f8978f9e0a Merge pull request #3097 from YosysHQ/modport 19773d093f Update verific.cc ce82afe44f Merge pull request #3099 from YosysHQ/claire/readargs d6e4d3f1ba Fix the tests we just broke ce08046f44 Added "yosys -r " 0cbdb42dcd Use "read" command to parse HDL files from Yosys command-line cdb5711875 Bump version 1184a7f3b4 opt_mem_priority: Fix non-ascii char in help message. b06f547993 If direction NONE use that from first bit d186ea7a2d Bump version c23cd00f30 Next dev cycle 2156e20db5 Release version 0.12 71e762d68c Update manual d65942b9ac Add gitignore for gatemate 3ebfa3fb84 Make sure cell names are unique for wide operators 2be110cb0b Bump version 4792d925fc Update CHANGELOG and CODEOWNERS 707d98b06c Bump version b506f398dd Add read_liberty -wb a31c8a82be intel_alm: preliminary Arria V support 77327b2544 sta: very crude static timing analysis pass 113c943841 Bump version d0fda4c0ef Merge pull request #3080 from YosysHQ/micko/init_wire c081c683a4 Give initial wire unique ID, fixes #2914 07dde32bf1 Bump version fdb19a5b3a Support parameters using struct as a wiretype (#3050) 06bddb5e49 Bump version cb41209095 synth_gatemate Revert cascade A/B port mixup decdc743db synth_gatemate: Remove iob_map invokation 0d871b6c49 synth_gatemate: Add block RAM cascade support 285ec0547b synth_gatemate: Remove obsolete iob_map 81964d6d6f synth_gatemate: Update pass 74aee88e81 synth_gatemate: Remove specify blocks 05f24adca9 synth_gatemate: Remove gatemate_bramopt pass 97d03c2b3b synth_gatemate: Apply new test practice with assert-max 76bf96d310 synth_gatemate: Fix fsm test 4bee908ae8 synth_gatemate: Revise block RAM read modes and initialization 3f4ccdf2f5 synth_gatemate: Remove unsupported FF initialization d592bd93b8 synth_gatemate: Rename multiplier factor parameters 6825de6343 synth_gatemate: Registers are uninitialized acb993b27b Allow initial blocks to be disabled during tests 0a72952d5f synth_gatemate: Apply review remarks cfcc38582a synth_gatemate: Apply review remarks 240d289fff synth_gatemate: Initial implementation b3e2001e1f Bump version 107aad2cd2 show: Fix wire bit indexing. 48a628522b update abc b4f68e3cca Update abc 1df8ac58fe Bump version a6c90c9772 Merge pull request #3075 from YosysHQ/micko/verific_mem_size 4699ddcc1b Merge pull request #3077 from YosysHQ/claire/genlib c77d5a2aac Spelling fix in abc.cc 093e287a1e Add genlib support to ABC command 506acd52de iopadmap: Fix ebmarassing typo 15a35f5584 No need to alocate more memory than used 224c6f8664 Bump version f4f5acf396 genrtlil: Fix displaying debug info in packages 15b0d717ed iopadmap: Add native support for negative-polarity output enable. 4871d8f199 Bump version cd71d260ea Update CODEOWNERS cd3f3d5df0 Limit macOS GH actions d39d4e11d2 Bump version 4bf8deacbb synth_gowin: move splitnets to after iopadmap (#2435) 9a413803eb manual: fix pdflatex inputenc undefined char error a3eec687e0 Remove noalu from synth_gowin json output as Apicula now supports it 781cf13abd Bump version 0c7461fe5e gowin: widelut support (#3042) 8f08908d8d Bump version a28ee81be0 Next dev cycle 360fed8e4d Release version 0.11 18bcf820b3 Must use latest flex to generate c++17 compatible code d5de2a0cdb Make it work on all cbb6887ac8 Correct way of setting maybe_unsused on labels 051b234df6 Add missing changelog item 598f51c6a1 Update command reference 5a5244a12e Merge pull request #3067 from YosysHQ/aki/ci_update d67eb0eb1c Removed semicolon from macro 11e58d5415 Bump version f346868ccc flatten: Keep sigmap around between flatten_cell invocations. 9cb5092ad1 Bump version 5b834d3aff Merge pull request #3068 from YosysHQ/claire/verific_cfg 2ea757da51 Add "verific -cfg" command 97fce665c7 Bump version e1cfd37384 ci: removed the old `test.yml` workflow, as it was replaced by `test-linux.yml` and `test-macos.yml` 1e7ba922e5 ci: expanded the macOS tests suite to cover more compilers and C++ versions ff31af6d72 ci: expanded the Linux test suite to cover more compilers and C++ versions ad81cff823 Changed the Makefile to have an explicit `CXXSTD` parameter which allows for the setting of other C++ standards, the default is `c++11` dd06d23649 Merge pull request #3066 from YosysHQ/claire/verific_gclk 83118bfb9e Fix verific gclk handling for async-load FFs dcb7096b5a Bump version c0edfa8788 Add missing items in CHANGELOG 55f07fe56f Update command reference part of manual 5f00bf2d7d Bump version 19c2d6e15d Merge pull request #3063 from YosysHQ/micko/verific_aldff e14302a3ea ecp5: Add support for mapping aldff. f7cc388bb5 Enable async load dff emit by default in Verific 32673edfea Revert "Compile option for enabling async load verific support" 8d881826eb proc_dff: Emit $aldff. 0b31cb598e dfflegalize: Add tests for aldff lowering. 54c79af64f dfflegalize: Add tests targetting aldff. 0a0df8d38c dfflegalize: Refactor, add aldff support. bdf153d06c Bump version e833c6a418 verilog: use derived module info to elaborate cell connections bd16d01c0e Split out logic for reprocessing an AstModule ee230f2bb9 Bump version b8624ad2ae Compile option for enabling async load verific support 52ba31b1c0 Bump version 5cebf6a8ef Change implicit conversions from bool to Sig* to explicit. 51d42cc917 Merge pull request #3057 from YosysHQ/claire/verific_latches 90b440f870 Fix verific.cc PRIM_DLATCH handling 16a177560f Initial Verific impoter support for {PRIM,WIDE_OPER}_DLATCH{,RS} e64456f920 extract_reduce: Refactor and fix input signal construction. a0e9d9fef9 Bump version 25c4ed3beb Fix emcc warnings for WebAssembly build bf79ff5927 If verific have vhdl lib it is required by other libs 150ce305f9 Forgot to remove from main list 17269ae59b Option to disable verific VHDL support 69b2b13ddd Bump version fe9689c136 Fixed Verific parser error in ice40 cell library affed103e0 Merge pull request #3045 from galibert/master 83887495b8 Fixes in vcdcd.pl for newer Perl versions a15b01a777 Bump version 3efc14f5ad dfflegalize: remove redundant check for initialized dlatch 6e78a80ff9 CycloneV: Add (passthrough) support for cyclonev_oscillator 6253d4ec9e CycloneV: Add (passthrough) support for cyclonev_hps_interface_mpu_general_purpose 0dd42d406d Bump version 92ecfb2b36 Merge pull request #3044 from YosysHQ/micko/verific_bufif1 1aa6896966 Support PRIM_BUFIF1 primitive a0f5ba8501 Bump version 2d3c79458d Merge pull request #3039 from YosysHQ/claire/verific_aldff c8074769b0 Add Verific adffe/dffsre/aldffe FIXMEs d5cc3a1c72 Merge pull request #3040 from YosysHQ/micko/split_module_ports c15b99c0de Merge pull request #3041 from YosysHQ/mmicko/module_attr 93fbc9fba4 Import module attributes from Verific ff8e999a71 Split module ports, 20 per line d8f6d7b18d Bump version 34f1df8435 Fixes and add comments for open FIXME items 1602a03864 Add support for $aldff flip-flops to verific importer dc8da76282 Fix a regression from #3035. 772b9a108a Bump version 4e70c30775 FfData: some refactoring. 356ec7bb39 Bump version abc5700628 verific set db_infer_set_reset_registers f3ef579ac4 Bump version e7d89e653c Hook up $aldff support in various passes. ba0723cad7 zinit: Refactor to use FfData. 63b9df8693 kernel/ff: Refactor FfData to enable FFs with async load. ec2b5548fe Add $aldff and $aldffe: flip-flops with async load. fbd70f28f0 Specify minimum bison version 3.0+ f9aad606ca simplemap: refactor to use FfData. 62739f7bf7 Merge pull request #3017 from YosysHQ/claire/short_rtlil_x_const 7a7df9a3b4 Bump version 070cad5f4b Prepare for next release cycle 89df26e4bc Add optimization to rtlil back-end for all-x parameter values 1cac671c70 Bump version 0146d83ed8 Merge pull request #3014 from YosysHQ/claire/fix-vgtest 9658d2e337 Fix TOK_ID memory leak in for_initialization 15fb0107dc Fix "make vgtest" so it runs to the end (but now it fails ;) 9432400ec8 Bump version d6fe6d4fb6 sv: support wand and wor of data types 6b7267b849 verilog: fix multiple AST_PREFIX scope resolution issues 3931b3a03f Bump version 1362ad0bf8 Update WaveDrom script URLs e6766b950c Merge pull request #3010 from the6p4c/master c25122e339 Fix protobuf backend build dependencies c88eaea6e0 Bump version 551ef85cd7 verilog: Squash flex-triggered warning. 1d52c07e9b Updates for CHANGELOG (#2997) f44110c625 Bump version 396918cc30 Merge pull request #3001 from YosysHQ/claire/sigcheck 4708907be8 Add additional check to SigSpec 33749f1e3a yosys-smtbmc: Fix reused loop variable. 1d61a911b7 Bump version 96b6410dcb abc9: make re-entrant (#2993) 65316ec926 abc9: holes module to instantiate cells with NEW_ID (#2992) f03e2c30aa abc9: replace cell type/parameters if derived type already processed (#2991) 50be8fd0c2 Bump version c3d4bb4cc9 update required verific version fe9da25c40 Bump version b2e9717419 sv: support declaration in generate for initialization b20bb653ce Bump version f0a52e3dd2 sv: support declaration in procedural for initialization 1dbf91a8ef Bump version 6de500ec08 [ECP5] fix wrong link for syn_* attributes description (#2984) 591fe72203 Bump version dfc453b246 Add DLLDELD 9cbff3a4a9 opt_merge: Remove and reinsert init when connecting nets. 62d41d4639 opt_clean: Make the init attribute follow the FF's Q. 21e710eb55 Bump version c2d358484f Gowin: deal with active-low tristate (#2971) c2866780d2 Merge pull request #2973 from YosysHQ/micko/optional_extensions b59c427348 Make Verific extensions optional 75a4cdfc8a Bump version 3806b07303 ice40: Fix typo in SB_CARRY specify for LP/UltraPlus e6dd4db0af Bump version 10f8b75dca kernel/mem: Remove old parameter when upgrading $mem to $mem_v2. 83c0f82dc8 Bump version faacc7ad89 proc_prune: Make assign removal and promotion per-bit, remember promoted bits. 539d4ee907 Bump version ee2b5b7ed1 Generate an RTLIL representation of bind constructs f791328506 Add opt_mem_widen pass. 1f74ec3535 memory_share: Add -nosat and -nowiden options. 9fdedf4d1c memory_dff: Recognize soft transparency logic. 616ace2d92 Add new opt_mem_priority pass. 30927df881 Merge pull request #2932 from YosysHQ/mwk/logger-check-expected 979053855c sv: improve support for wire and var with user-defined types c8023e37d8 Bump version d0d9aca2c3 memory_share: Pass addresses through sigmap_xmux everywhere. c58ac63c97 logger: Add -check-expected subcommand. bfcd08a323 Bump version b98376884e test/arch/{ecp5,ice40}/memories.ys: Use read_verilog -defer. 72d86c327e memory_dff: Recognize read ports with reset / initial value. 24027b5446 proc_memwr: Use the v2 memwr cell. fd79217763 Add v2 memory cells. 90b40aa51f clk2fflogic: nice names for autogenerated signals bbfa2d65fa glift: Use ID() rather than string literals. eda1af73c4 glift: Use worker pattern. 3eb2593876 glift: Add support for $_NAND_ and $_NOR_ cells. 8cb1a86c23 glift: Add support for $_MUX_ and $_NMUX_ cells. 23defc6fe9 glift: Add support for $_XOR_ and $_XNOR_ cells. 209a123b97 glift: Add initial hierarchy support. 20ad371724 glift: Replace `YS_OVERRIDE` with `override`. 8ec5929f97 glift: Add CODEOWNERS entry. 91c20fca72 glift: Add `-simple-cost-model` option c26a8d1ee0 glift: Use `qbfsat -O2` instead of manually calling `abc`. 26bd686259 glift: Add `-instrument-more` option to add 4 more versions of taint tracking logic. Also refactor a bit and update help text. bc207d5426 glift: Change command names to better represent their functions. ddfb9f08e2 glift: Add `-create-imprecise` command, rename other commands, and re-work the help text. ca3844d44e glift: Add examples, including a number of benchmarks used in some academic works. 72cebef279 glift: Add replacement scoring and area minimization option. c36440a7ee glift: Remove outputs by default; add `-keep-outputs` option; properly reset internal state between calls. 19dafcd4f1 glift: Initial implementation of the `-sketchify` option. 09848b3b9f glift: Initial implementation of GLIFT model construction. 5f45fe51ea glift: Add skeleton for `glift` command. git-subtree-dir: yosys git-subtree-split: f7a8284c7b095bca4bc2c65032144c4e3264ee4d --- .gitattributes | 1 + .gitcommit | 1 + .github/ISSUE_TEMPLATE/bug_report.yml | 75 + .github/ISSUE_TEMPLATE/config.yml | 11 + .github/ISSUE_TEMPLATE/feature_request.yml | 26 + .github/issue_template.md | 24 - .github/workflows/codeql.yml | 29 + .github/workflows/emcc.yml | 18 + .github/workflows/test-linux.yml | 116 + .github/workflows/test-macos.yml | 73 + .github/workflows/test.yml | 91 - .github/workflows/version.yml | 6 +- .github/workflows/vs.yml | 14 +- .gitignore | 3 + CHANGELOG | 542 +- CODEOWNERS | 7 +- Makefile | 230 +- README.md | 75 +- backends/aiger/aiger.cc | 208 +- backends/aiger/xaiger.cc | 35 +- backends/blif/blif.cc | 4 +- backends/btor/btor.cc | 212 +- backends/cxxrtl/cxxrtl.h | 107 +- backends/cxxrtl/cxxrtl_backend.cc | 184 +- backends/edif/edif.cc | 4 +- backends/firrtl/firrtl.cc | 24 +- backends/jny/Makefile.inc | 2 + backends/jny/jny.cc | 578 ++ backends/json/json.cc | 32 +- backends/protobuf/.gitignore | 2 - backends/protobuf/Makefile.inc | 8 - backends/protobuf/protobuf.cc | 371 - backends/rtlil/rtlil_backend.cc | 33 +- backends/smt2/Makefile.inc | 16 +- backends/smt2/smt2.cc | 299 +- backends/smt2/smtbmc.py | 691 +- backends/smt2/smtio.py | 149 +- backends/smt2/witness.py | 410 + backends/smt2/ywio.py | 393 + backends/smv/smv.cc | 8 +- backends/verilog/verilog_backend.cc | 183 +- docs/.gitignore | 11 + docs/Makefile | 226 + docs/images/011/example_out.tex | 18 + docs/images/011/select_prod.tex | 19 + docs/images/011/splitnets_libfile.tex | 15 + docs/images/011/submod_dots.tex | 27 + docs/images/Makefile | 44 + docs/images/approach_flow.png | Bin 0 -> 9709 bytes docs/images/approach_flow.tex | 38 + docs/images/basics_abstractions.png | Bin 0 -> 29158 bytes docs/images/basics_abstractions.tex | 41 + docs/images/basics_ast.png | Bin 0 -> 9478 bytes docs/images/basics_ast.tex | 30 + docs/images/basics_flow.png | Bin 0 -> 12540 bytes docs/images/basics_flow.tex | 44 + docs/images/basics_parsetree.png | Bin 0 -> 23196 bytes docs/images/basics_parsetree.tex | 44 + docs/images/overview_flow.png | Bin 0 -> 17668 bytes docs/images/overview_flow.tex | 37 + docs/images/overview_rtlil.png | Bin 0 -> 16034 bytes docs/images/overview_rtlil.tex | 27 + docs/images/verilog_flow.png | Bin 0 -> 15934 bytes docs/images/verilog_flow.tex | 67 + .../APPNOTE_011_Design_Investigation/cmos.v | 0 .../cmos_00.dot | 0 .../cmos_01.dot | 0 .../example.v | 0 .../example.ys | 0 .../example_00.dot | 0 .../example_01.dot | 0 .../example_02.dot | 0 .../example_03.dot | 0 .../foobaraddsub.v | 0 .../APPNOTE_011_Design_Investigation/make.sh | 0 .../memdemo.v | 0 .../memdemo_00.dot | 0 .../memdemo_01.dot | 0 .../primetest.v | 0 .../splice.dot | 0 .../APPNOTE_011_Design_Investigation/splice.v | 0 .../submod.ys | 0 .../submod_00.dot | 0 .../submod_01.dot | 0 .../submod_02.dot | 0 .../submod_03.dot | 0 .../sumprod.v | 0 .../sumprod_00.dot | 0 .../sumprod_01.dot | 0 .../sumprod_02.dot | 0 .../sumprod_03.dot | 0 .../sumprod_04.dot | 0 .../sumprod_05.dot | 0 docs/source/CHAPTER_Approach.rst | 141 + docs/source/CHAPTER_Basics.rst | 776 ++ docs/source/CHAPTER_CellLib.rst | 1020 +++ docs/source/CHAPTER_Eval.rst | 233 + docs/source/CHAPTER_Intro.rst | 96 + docs/source/CHAPTER_Optimize.rst | 330 + docs/source/CHAPTER_Overview.rst | 571 ++ docs/source/CHAPTER_Prog.rst | 46 + .../source}/CHAPTER_Prog/.gitignore | 0 {manual => docs/source}/CHAPTER_Prog/Makefile | 0 .../source}/CHAPTER_Prog/stubnets.cc | 0 {manual => docs/source}/CHAPTER_Prog/test.v | 0 docs/source/CHAPTER_Techmap.rst | 105 + docs/source/CHAPTER_Verilog.rst | 666 ++ .../appendix/APPNOTE_010_Verilog_to_BLIF.rst | 336 + .../APPNOTE_011_Design_Investigation.rst | 965 +++ .../appendix/APPNOTE_012_Verilog_to_BTOR.rst | 333 + docs/source/appendix/CHAPTER_Auxlibs.rst | 42 + docs/source/appendix/CHAPTER_Auxprogs.rst | 29 + .../source/appendix/CHAPTER_StateOfTheArt.rst | 410 + docs/source/appendix/CHAPTER_TextRtlil.rst | 298 + docs/source/bib.rst | 9 + docs/source/cmd_ref.rst | 11 + docs/source/conf.py | 62 + docs/source/index.rst | 72 + docs/source/literature.bib | 202 + docs/source/requirements.txt | 2 + docs/static/custom.css | 1 + docs/static/favico.png | Bin 0 -> 33435 bytes docs/static/logo.png | Bin 0 -> 15938 bytes docs/static/yosyshq.css | 78 + docs/util/RtlilLexer.py | 45 + docs/util/YoscryptLexer.py | 73 + examples/smtbmc/Makefile | 6 +- examples/smtbmc/glift/C7552.v | 4194 +++++++++ examples/smtbmc/glift/C7552.ys | 41 + examples/smtbmc/glift/C880.v | 451 + examples/smtbmc/glift/C880.ys | 41 + examples/smtbmc/glift/alu2.v | 400 + examples/smtbmc/glift/alu2.ys | 41 + examples/smtbmc/glift/alu4.v | 802 ++ examples/smtbmc/glift/alu4.ys | 41 + examples/smtbmc/glift/mux2.ys | 40 + examples/smtbmc/glift/t481.v | 83 + examples/smtbmc/glift/t481.ys | 41 + examples/smtbmc/glift/too_large.v | 345 + examples/smtbmc/glift/too_large.ys | 41 + examples/smtbmc/glift/ttt2.v | 220 + examples/smtbmc/glift/ttt2.ys | 41 + examples/smtbmc/glift/x1.v | 380 + examples/smtbmc/glift/x1.ys | 41 + frontends/ast/Makefile.inc | 1 + frontends/ast/ast.cc | 156 +- frontends/ast/ast.h | 35 +- frontends/ast/ast_binding.cc | 49 + frontends/ast/ast_binding.h | 58 + frontends/ast/genrtlil.cc | 207 +- frontends/ast/simplify.cc | 838 +- frontends/blif/blifparse.cc | 14 +- frontends/json/jsonparse.cc | 34 +- frontends/liberty/liberty.cc | 18 +- frontends/rpc/rpc_frontend.cc | 12 +- frontends/rtlil/rtlil_parser.y | 2 + frontends/verific/Makefile.inc | 2 + frontends/verific/README | 2 +- frontends/verific/verific.cc | 1463 +++- frontends/verific/verific.h | 7 +- frontends/verific/verificsva.cc | 33 +- frontends/verilog/preproc.cc | 15 + frontends/verilog/verilog_lexer.l | 18 +- frontends/verilog/verilog_parser.y | 269 +- guidelines/Checklists | 16 +- guidelines/CodingStyle | 3 +- guidelines/GettingStarted | 2 +- guidelines/Windows | 23 + kernel/binding.cc | 29 + kernel/binding.h | 60 + kernel/calc.cc | 104 + kernel/celledges.cc | 40 + kernel/celltypes.h | 75 +- kernel/consteval.h | 39 +- kernel/constids.inc | 39 + kernel/driver.cc | 111 +- kernel/ff.cc | 773 ++ kernel/ff.h | 542 +- kernel/ffmerge.cc | 71 +- kernel/fstdata.cc | 264 + kernel/fstdata.h | 84 + kernel/hashlib.h | 8 +- kernel/json.cc | 172 + kernel/json.h | 104 + kernel/log.cc | 48 +- kernel/log.h | 79 +- kernel/mem.cc | 702 +- kernel/mem.h | 32 +- kernel/modtools.h | 4 - kernel/qcsat.cc | 2 +- kernel/register.cc | 187 +- kernel/rtlil.cc | 562 +- kernel/rtlil.h | 187 +- kernel/satgen.cc | 208 +- kernel/satgen.h | 1 + kernel/timinginfo.h | 48 +- kernel/yosys.cc | 264 +- kernel/yosys.h | 20 +- kernel/yw.cc | 207 + kernel/yw.h | 182 + libs/dlfcn-win32/dlfcn.cc | 820 ++ libs/dlfcn-win32/dlfcn.h | 94 + libs/fst/block_format.txt | 130 + libs/fst/config.h | 30 + libs/fst/fastlz.cc | 528 ++ libs/fst/fastlz.h | 109 + libs/fst/fstapi.cc | 6548 ++++++++++++++ libs/fst/fstapi.h | 500 ++ libs/fst/lz4.cc | 1615 ++++ libs/fst/lz4.h | 367 + libs/json11/json11.cpp | 16 +- manual/APPNOTE_010_Verilog_to_BLIF.tex | 466 - manual/APPNOTE_011_Design_Investigation.tex | 1070 --- manual/APPNOTE_012_Verilog_to_BTOR.tex | 435 - manual/CHAPTER_Appnotes.tex | 29 - manual/CHAPTER_Approach.tex | 145 - manual/CHAPTER_Auxlibs.tex | 35 - manual/CHAPTER_Auxprogs.tex | 26 - manual/CHAPTER_Basics.tex | 839 -- manual/CHAPTER_CellLib.tex | 924 -- manual/CHAPTER_Eval.tex | 209 - manual/CHAPTER_Eval/grep-it.sh | 84 - manual/CHAPTER_Eval/openmsp430.prj | 14 - manual/CHAPTER_Eval/openmsp430_ys.prj | 1 - manual/CHAPTER_Eval/or1200.prj | 37 - manual/CHAPTER_Eval/or1200_ys.prj | 1 - manual/CHAPTER_Eval/run-it.sh | 74 - manual/CHAPTER_Eval/settings.xst | 2 - manual/CHAPTER_Intro.tex | 98 - manual/CHAPTER_Optimize.tex | 324 - manual/CHAPTER_Overview.tex | 560 -- manual/CHAPTER_Prog.tex | 27 - manual/CHAPTER_StateOfTheArt.tex | 289 - manual/CHAPTER_StateOfTheArt/always01.v | 12 - manual/CHAPTER_StateOfTheArt/always01_pub.v | 14 - manual/CHAPTER_StateOfTheArt/always02.v | 15 - manual/CHAPTER_StateOfTheArt/always02_pub.v | 14 - manual/CHAPTER_StateOfTheArt/always03.v | 23 - manual/CHAPTER_StateOfTheArt/arrays01.v | 16 - manual/CHAPTER_StateOfTheArt/cmp_tbdata.c | 67 - manual/CHAPTER_StateOfTheArt/forgen01.v | 20 - manual/CHAPTER_StateOfTheArt/forgen02.v | 30 - .../iverilog-0.8.7-buildfixes.patch | 20 - .../mvsis-1.3.6-buildfixes.patch | 36 - manual/CHAPTER_StateOfTheArt/simlib_hana.v | 1139 --- manual/CHAPTER_StateOfTheArt/simlib_icarus.v | 224 - manual/CHAPTER_StateOfTheArt/simlib_yosys.v | 166 - .../sis-1.3.6-buildfixes.patch | 113 - manual/CHAPTER_StateOfTheArt/synth.sh | 64 - manual/CHAPTER_StateOfTheArt/validate_tb.sh | 55 - manual/CHAPTER_Techmap.tex | 102 - manual/CHAPTER_TextRtlil.tex | 299 - manual/CHAPTER_Verilog.tex | 854 -- manual/PRESENTATION_Prog/Makefile | 2 +- manual/appnotes.sh | 22 - manual/command-reference-manual.tex | 7631 ----------------- manual/literature.bib | 163 - manual/manual.sh | 59 - manual/manual.tex | 230 - manual/weblinks.bib | 134 - misc/create_vcxsrc.sh | 11 +- misc/jny.schema.json | 193 + misc/yosys-config.in | 2 +- misc/yosys.proto | 175 - misc/yosysjs/demo03.html | 4 +- passes/cmds/Makefile.inc | 6 + passes/cmds/bugpoint.cc | 11 +- passes/cmds/chformal.cc | 23 +- passes/cmds/clean_zerowidth.cc | 210 + passes/cmds/design.cc | 5 +- passes/cmds/exec.cc | 12 +- passes/cmds/glift.cc | 603 ++ passes/cmds/logcmd.cc | 5 +- passes/cmds/logger.cc | 17 +- passes/cmds/plugin.cc | 83 +- passes/cmds/rename.cc | 168 +- passes/cmds/scratchpad.cc | 3 +- passes/cmds/select.cc | 25 +- passes/cmds/setundef.cc | 34 +- passes/cmds/show.cc | 281 +- passes/cmds/splitcells.cc | 267 + passes/cmds/sta.cc | 315 + passes/cmds/stat.cc | 299 +- passes/cmds/tee.cc | 13 + passes/cmds/torder.cc | 2 +- passes/cmds/viz.cc | 1081 +++ passes/cmds/xprop.cc | 1234 +++ passes/equiv/equiv_make.cc | 185 +- passes/equiv/equiv_opt.cc | 14 +- passes/fsm/fsm.cc | 9 + passes/fsm/fsm_detect.cc | 35 +- passes/fsm/fsmdata.h | 4 +- passes/hierarchy/hierarchy.cc | 58 +- passes/hierarchy/submod.cc | 5 +- passes/hierarchy/uniquify.cc | 1 + passes/memory/Makefile.inc | 3 + passes/memory/memlib.cc | 1101 +++ passes/memory/memlib.h | 171 + passes/memory/memlib.md | 505 ++ passes/memory/memory.cc | 40 +- passes/memory/memory_bmux2rom.cc | 87 + passes/memory/memory_bram.cc | 31 +- passes/memory/memory_dff.cc | 510 +- passes/memory/memory_libmap.cc | 2097 +++++ passes/memory/memory_map.cc | 225 +- passes/memory/memory_share.cc | 101 +- passes/opt/Makefile.inc | 3 + passes/opt/opt.cc | 1 + passes/opt/opt_clean.cc | 36 +- passes/opt/opt_dff.cc | 420 +- passes/opt/opt_expr.cc | 199 +- passes/opt/opt_ffinv.cc | 268 + passes/opt/opt_lut_ins.cc | 10 +- passes/opt/opt_mem.cc | 156 +- passes/opt/opt_mem_priority.cc | 109 + passes/opt/opt_mem_widen.cc | 107 + passes/opt/opt_merge.cc | 29 +- passes/opt/opt_reduce.cc | 399 +- passes/opt/share.cc | 9 +- passes/opt/wreduce.cc | 20 +- passes/pmgen/ice40_dsp.pmg | 5 +- passes/pmgen/xilinx_srl.cc | 6 +- passes/proc/Makefile.inc | 1 + passes/proc/proc.cc | 11 + passes/proc/proc_dff.cc | 41 +- passes/proc/proc_memwr.cc | 28 +- passes/proc/proc_prune.cc | 65 +- passes/proc/proc_rom.cc | 252 + passes/sat/Makefile.inc | 5 + passes/sat/async2sync.cc | 73 +- passes/sat/clk2fflogic.cc | 219 +- passes/sat/fmcombine.cc | 3 + passes/sat/formalff.cc | 766 ++ passes/sat/miter.cc | 58 +- passes/sat/mutate.cc | 2 + passes/sat/qbfsat.cc | 65 +- passes/sat/qbfsat.h | 50 +- passes/sat/recover_names.cc | 730 ++ passes/sat/sat.cc | 29 +- passes/sat/sim.cc | 2232 ++++- passes/sat/synthprop.cc | 269 + passes/techmap/Makefile.inc | 3 + passes/techmap/abc.cc | 452 +- passes/techmap/abc9.cc | 28 +- passes/techmap/abc9_exe.cc | 16 +- passes/techmap/abc9_ops.cc | 178 +- passes/techmap/bmuxmap.cc | 103 + passes/techmap/bwmuxmap.cc | 70 + passes/techmap/demuxmap.cc | 80 + passes/techmap/dfflegalize.cc | 1904 ++-- passes/techmap/dfflibmap.cc | 2 +- passes/techmap/dffunmap.cc | 17 +- passes/techmap/extract.cc | 1 + passes/techmap/extract_reduce.cc | 107 +- passes/techmap/flatten.cc | 7 +- passes/techmap/flowmap.cc | 3 +- passes/techmap/insbuf.cc | 40 +- passes/techmap/iopadmap.cc | 59 +- passes/techmap/libparse.cc | 11 +- passes/techmap/muxcover.cc | 5 +- passes/techmap/simplemap.cc | 379 +- passes/techmap/simplemap.h | 8 +- passes/techmap/techmap.cc | 22 +- passes/techmap/tribuf.cc | 49 +- passes/techmap/zinit.cc | 123 +- passes/tests/test_cell.cc | 46 +- techlibs/achronix/speedster22i/cells_sim.v | 3 +- techlibs/anlogic/Makefile.inc | 3 +- techlibs/anlogic/brams.txt | 69 + techlibs/anlogic/brams_map.v | 474 + techlibs/anlogic/lutram_init_16x4.vh | 16 - techlibs/anlogic/lutrams.txt | 28 +- techlibs/anlogic/lutrams_map.v | 40 +- techlibs/anlogic/synth_anlogic.cc | 24 +- techlibs/common/Makefile.inc | 1 + techlibs/common/gen_fine_ffs.py | 49 + techlibs/common/simcells.v | 284 + techlibs/common/simlib.v | 376 +- techlibs/common/smtmap.v | 28 + techlibs/common/synth.cc | 9 + techlibs/common/techmap.v | 41 +- techlibs/ecp5/.gitignore | 10 - techlibs/ecp5/Makefile.inc | 43 - techlibs/ecp5/brams.txt | 166 +- techlibs/ecp5/brams_connect.py | 66 - techlibs/ecp5/brams_init.py | 22 - techlibs/ecp5/brams_map.v | 636 +- techlibs/ecp5/cells_bb.v | 37 +- techlibs/ecp5/cells_io.vh | 24 +- techlibs/ecp5/cells_map.v | 13 +- techlibs/ecp5/cells_sim.v | 237 +- techlibs/ecp5/lutrams.txt | 38 +- techlibs/ecp5/lutrams_map.v | 46 +- techlibs/ecp5/synth_ecp5.cc | 71 +- techlibs/efinix/brams.txt | 51 +- techlibs/efinix/brams_map.v | 194 +- techlibs/efinix/synth_efinix.cc | 8 +- techlibs/fabulous/Makefile.inc | 11 + techlibs/fabulous/arith_map.v | 65 + techlibs/fabulous/cells_map.v | 34 + techlibs/fabulous/ff_map.v | 9 + techlibs/fabulous/io_map.v | 8 + techlibs/fabulous/latches_map.v | 11 + techlibs/fabulous/prims.v | 463 + techlibs/fabulous/ram_regfile.txt | 46 + techlibs/fabulous/regfile_map.v | 42 + techlibs/fabulous/synth_fabulous.cc | 407 + techlibs/gatemate/.gitignore | 4 + techlibs/gatemate/Makefile.inc | 30 + techlibs/gatemate/arith_map.v | 69 + techlibs/gatemate/brams.txt | 80 + techlibs/gatemate/brams_init_20.vh | 64 + techlibs/gatemate/brams_init_40.vh | 260 + techlibs/gatemate/brams_map.v | 882 ++ techlibs/gatemate/cells_bb.v | 133 + techlibs/gatemate/cells_sim.v | 1842 ++++ techlibs/gatemate/gatemate_foldinv.cc | 219 + techlibs/gatemate/inv_map.v | 4 + techlibs/gatemate/lut_map.v | 45 + techlibs/gatemate/make_lut_tree_lib.py | 323 + techlibs/gatemate/mul_map.v | 77 + techlibs/gatemate/mux_map.v | 56 + techlibs/gatemate/reg_map.v | 51 + techlibs/gatemate/synth_gatemate.cc | 366 + techlibs/gowin/.gitignore | 2 - techlibs/gowin/Makefile.inc | 16 +- techlibs/gowin/arith_map.v | 2 +- techlibs/gowin/brams.txt | 110 +- techlibs/gowin/brams_init.py | 8 - techlibs/gowin/brams_init3.vh | 12 - techlibs/gowin/brams_map.v | 550 +- techlibs/gowin/cells_map.v | 1 - techlibs/gowin/cells_sim.v | 1265 ++- techlibs/gowin/cells_xtra.py | 76 + techlibs/gowin/cells_xtra.v | 2003 +++++ techlibs/gowin/lutrams.txt | 30 +- techlibs/gowin/lutrams_map.v | 94 +- techlibs/gowin/synth_gowin.cc | 55 +- techlibs/ice40/.gitignore | 4 - techlibs/ice40/Makefile.inc | 23 +- techlibs/ice40/brams.txt | 123 +- techlibs/ice40/brams_init.py | 14 - techlibs/ice40/brams_map.v | 524 +- techlibs/ice40/cells_sim.v | 164 +- techlibs/ice40/spram.txt | 12 + techlibs/ice40/spram_map.v | 24 + techlibs/ice40/synth_ice40.cc | 51 +- techlibs/intel/synth_intel.cc | 13 +- techlibs/intel_alm/Makefile.inc | 1 + techlibs/intel_alm/common/alm_sim.v | 78 +- techlibs/intel_alm/common/bram_m10k.txt | 18 +- techlibs/intel_alm/common/bram_m10k_map.v | 26 + techlibs/intel_alm/common/dff_sim.v | 15 + techlibs/intel_alm/common/dsp_sim.v | 47 + techlibs/intel_alm/common/megafunction_bb.v | 18 + techlibs/intel_alm/common/mem_sim.v | 60 +- techlibs/intel_alm/common/quartus_rename.v | 22 +- techlibs/intel_alm/synth_intel_alm.cc | 25 +- techlibs/machxo2/Makefile.inc | 9 + techlibs/machxo2/arith_map.v | 90 + techlibs/machxo2/brams.txt | 50 + techlibs/machxo2/brams_map.v | 337 + techlibs/machxo2/cells_bb.v | 227 + techlibs/machxo2/cells_map.v | 99 +- techlibs/machxo2/cells_sim.v | 251 +- techlibs/machxo2/synth_machxo2.cc | 68 +- techlibs/nexus/Makefile.inc | 2 - techlibs/nexus/arith_map.v | 2 +- techlibs/nexus/brams.txt | 108 +- techlibs/nexus/brams_init.vh | 64 - techlibs/nexus/brams_map.v | 531 +- techlibs/nexus/cells_map.v | 8 - techlibs/nexus/cells_sim.v | 4 +- techlibs/nexus/lrams.txt | 43 +- techlibs/nexus/lrams_init.vh | 128 - techlibs/nexus/lrams_map.v | 246 +- techlibs/nexus/lutrams.txt | 38 +- techlibs/nexus/lutrams_map.v | 39 +- techlibs/nexus/synth_nexus.cc | 35 +- techlibs/quicklogic/synth_quicklogic.cc | 8 +- techlibs/sf2/NOTES.txt | 84 + techlibs/sf2/arith_map.v | 50 +- techlibs/sf2/cells_sim.v | 139 +- techlibs/sf2/synth_sf2.cc | 20 +- techlibs/sf2/tests/test_arith.ys | 22 + techlibs/xilinx/.gitignore | 2 - techlibs/xilinx/Makefile.inc | 70 +- techlibs/xilinx/brams_defs.vh | 561 ++ techlibs/xilinx/brams_init.py | 50 - techlibs/xilinx/brams_xc2v.txt | 33 + techlibs/xilinx/brams_xc2v_map.v | 532 ++ techlibs/xilinx/brams_xc3sda.txt | 120 + techlibs/xilinx/brams_xc3sda_map.v | 224 + techlibs/xilinx/brams_xc4v.txt | 169 + techlibs/xilinx/brams_xc4v_map.v | 149 + techlibs/xilinx/brams_xc5v_map.v | 255 + techlibs/xilinx/brams_xc6v_map.v | 284 + techlibs/xilinx/brams_xcu_map.v | 225 + techlibs/xilinx/brams_xcv.txt | 17 + techlibs/xilinx/brams_xcv_map.v | 257 + techlibs/xilinx/cells_map.v | 8 - techlibs/xilinx/cells_sim.v | 13 +- techlibs/xilinx/cells_xtra.py | 23 +- techlibs/xilinx/cells_xtra.v | 684 +- techlibs/xilinx/lut4_lutrams.txt | 19 - techlibs/xilinx/lut6_lutrams.txt | 143 - techlibs/xilinx/lutrams_map.v | 279 - techlibs/xilinx/lutrams_xc5v.txt | 100 + techlibs/xilinx/lutrams_xc5v_map.v | 901 ++ techlibs/xilinx/lutrams_xcu.txt | 162 + techlibs/xilinx/lutrams_xcv.txt | 59 + techlibs/xilinx/lutrams_xcv_map.v | 177 + techlibs/xilinx/synth_xilinx.cc | 139 +- techlibs/xilinx/urams.txt | 37 + techlibs/xilinx/urams_map.v | 152 + techlibs/xilinx/xc2v_brams.txt | 31 - techlibs/xilinx/xc2v_brams_map.v | 266 - techlibs/xilinx/xc3sa_brams.txt | 51 - techlibs/xilinx/xc3sda_brams.txt | 33 - techlibs/xilinx/xc6s_brams.txt | 85 - techlibs/xilinx/xc6s_brams_map.v | 258 - techlibs/xilinx/xc7_brams_map.v | 363 - techlibs/xilinx/xc7_xcu_brams.txt | 151 - techlibs/xilinx/xcu_brams_map.v | 386 - techlibs/xilinx/xcup_urams.txt | 19 - techlibs/xilinx/xcup_urams_map.v | 47 - tests/arch/anlogic/blockram.ys | 13 + tests/arch/anlogic/lutram.ys | 2 +- tests/arch/common/adffs.v | 8 + tests/arch/common/blockram.v | 31 +- tests/arch/common/dffs.v | 2 + tests/arch/common/shifter.v | 8 +- tests/arch/ecp5/bug1836.mem | 32 + tests/arch/ecp5/bug1836.ys | 23 + tests/arch/ecp5/bug2731.ys | 7 + tests/arch/ecp5/memories.ys | 244 +- tests/arch/efinix/lutram.ys | 13 +- tests/arch/fabulous/.gitignore | 4 + tests/arch/fabulous/carry.ys | 9 + tests/arch/fabulous/complexflop.ys | 37 + tests/arch/fabulous/counter.ys | 26 + tests/arch/fabulous/custom_map.v | 3 + tests/arch/fabulous/custom_prims.v | 8 + tests/arch/fabulous/customisation.ys | 10 + tests/arch/fabulous/fsm.ys | 19 + tests/arch/fabulous/logic.ys | 10 + tests/arch/fabulous/regfile.ys | 33 + tests/arch/fabulous/tribuf.ys | 12 + tests/arch/gatemate/.gitignore | 4 + tests/arch/gatemate/add_sub.ys | 9 + tests/arch/gatemate/adffs.ys | 43 + tests/arch/gatemate/counter.ys | 12 + tests/arch/gatemate/dffs.ys | 21 + tests/arch/gatemate/fsm.ys | 20 + tests/arch/gatemate/gen_luttrees.py | 48 + tests/arch/gatemate/latches.ys | 29 + tests/arch/gatemate/logic.ys | 10 + tests/arch/gatemate/luttrees.v | 752 ++ tests/arch/gatemate/luttrees.ys | 13 + tests/arch/gatemate/memory.ys | 42 + tests/arch/gatemate/mul.v | 79 + tests/arch/gatemate/mul.ys | 33 + tests/arch/gatemate/mux.ys | 24 + tests/arch/gatemate/run-test.sh | 4 + tests/arch/gatemate/shifter.ys | 10 + tests/arch/gatemate/tribuf.ys | 13 + tests/arch/gowin/compare.v | 20 + tests/arch/gowin/compare.ys | 9 + tests/arch/gowin/lutram.ys | 5 +- tests/arch/gowin/tribuf.ys | 3 +- tests/arch/ice40/.gitignore | 1 + tests/arch/ice40/bug1597.ys | 5 +- tests/arch/ice40/ice40_opt.ys | 1 + tests/arch/ice40/memories.ys | 105 +- tests/arch/ice40/spram.v | 22 + tests/arch/ice40/spram.ys | 15 + tests/arch/intel_alm/blockram.ys | 5 +- tests/arch/intel_alm/counter.ys | 8 +- tests/arch/machxo2/add_sub.ys | 2 +- tests/arch/machxo2/adffs.ys | 40 + tests/arch/machxo2/counter.ys | 10 + tests/arch/machxo2/dffs.ys | 8 +- tests/arch/machxo2/fsm.ys | 4 +- tests/arch/machxo2/logic.ys | 2 +- tests/arch/machxo2/lutram.ys | 17 + tests/arch/machxo2/mux.ys | 10 +- tests/arch/machxo2/shifter.ys | 4 +- tests/arch/machxo2/tribuf.ys | 6 +- tests/arch/nexus/blockram.ys | 4 +- tests/arch/xilinx/abc9_dff.ys | 7 + tests/arch/xilinx/asym_ram_sdp.ys | 50 + tests/arch/xilinx/asym_ram_sdp_read_wider.v | 72 + tests/arch/xilinx/asym_ram_sdp_write_wider.v | 71 + tests/arch/xilinx/attributes_test.ys | 12 +- tests/arch/xilinx/blockram.ys | 32 +- tests/arch/xilinx/bug3670.v | 13 + tests/arch/xilinx/bug3670.ys | 3 + tests/arch/xilinx/dsp_abc9.ys | 17 + tests/arch/xilinx/fsm.ys | 5 +- tests/arch/xilinx/lutram.ys | 17 +- tests/arch/xilinx/opt_lut_ins.ys | 1 + tests/arch/xilinx/priority_memory.v | 122 + tests/arch/xilinx/priority_memory.ys | 60 + tests/arch/xilinx/tribuf.sh | 4 +- tests/arch/xilinx/xilinx_dffopt.ys | 12 +- tests/blif/bug3374.ys | 4 + tests/blif/bug3385.ys | 9 + tests/bram/run-single.sh | 2 +- tests/gen-tests-makefile.sh | 4 +- tests/liberty/XNOR2X1.lib | 337 + tests/liberty/issue3498_bad.lib | 8 + tests/memlib/.gitignore | 5 + tests/memlib/generate.py | 1557 ++++ tests/memlib/memlib_9b1B.txt | 31 + tests/memlib/memlib_9b1B.v | 68 + tests/memlib/memlib_block_sdp.txt | 12 + tests/memlib/memlib_block_sdp.v | 26 + tests/memlib/memlib_block_sdp_1clk.txt | 22 + tests/memlib/memlib_block_sdp_1clk.v | 36 + tests/memlib/memlib_block_sp.txt | 95 + tests/memlib/memlib_block_sp.v | 81 + tests/memlib/memlib_block_sp_full.txt | 61 + tests/memlib/memlib_block_sp_full.v | 82 + tests/memlib/memlib_block_tdp.txt | 10 + tests/memlib/memlib_block_tdp.v | 38 + tests/memlib/memlib_clock_sdp.txt | 76 + tests/memlib/memlib_clock_sdp.v | 36 + tests/memlib/memlib_lut.txt | 28 + tests/memlib/memlib_lut.v | 37 + tests/memlib/memlib_multilut.txt | 19 + tests/memlib/memlib_multilut.v | 45 + tests/memlib/memlib_wide_read.txt | 12 + tests/memlib/memlib_wide_read.v | 25 + tests/memlib/memlib_wide_sdp.txt | 17 + tests/memlib/memlib_wide_sdp.v | 45 + tests/memlib/memlib_wide_sp.txt | 22 + tests/memlib/memlib_wide_sp.v | 54 + tests/memlib/memlib_wide_write.txt | 13 + tests/memlib/memlib_wide_write.v | 29 + tests/memlib/memlib_wren.txt | 37 + tests/memlib/memlib_wren.v | 33 + tests/memlib/run-test.sh | 15 + tests/memories/read_arst.v | 27 + tests/memories/read_two_mux.v | 5 +- tests/memories/run-test.sh | 34 +- tests/memories/trans_addr_enable.v | 21 + tests/memories/trans_sdp.v | 21 + tests/memories/trans_sp.v | 21 + tests/memories/wide_all.v | 36 + tests/memories/wide_read_async.v | 27 + tests/memories/wide_read_mixed.v | 46 + tests/memories/wide_read_sync.v | 32 + tests/memories/wide_read_trans.v | 40 + tests/memories/wide_thru_priority.v | 29 + tests/memories/wide_write.v | 29 + tests/opt/bug2765.ys | 4 +- tests/opt/bug3047.ys | 12 + tests/opt/bug3117.ys | 34 + tests/opt/memory_bmux2rom.ys | 27 + tests/opt/memory_dff_trans.ys | 874 ++ tests/opt/opt_clean_mem.ys | 8 +- tests/opt/opt_dff_en.ys | 2 +- tests/opt/opt_dff_mux.ys | 2 +- tests/opt/opt_dff_qd.ys | 2 +- tests/opt/opt_dff_sr.ys | 25 +- tests/opt/opt_expr_xnor.ys | 2 +- tests/opt/opt_expr_xor.ys | 15 +- tests/opt/opt_mem_feedback.ys | 4 +- tests/opt/opt_mem_priority.ys | 209 + tests/opt/opt_merge_init.ys | 50 + tests/opt/opt_reduce_bmux.ys | 117 + tests/opt/opt_reduce_demux.ys | 91 + tests/proc/bug2962.ys | 22 + tests/proc/proc_rom.ys | 189 + tests/sat/.gitignore | 2 + tests/sat/alu.v | 79 + tests/sat/grom.ys | 9 + tests/sat/grom_computer.v | 31 + tests/sat/grom_cpu.v | 747 ++ tests/sat/ram_memory.v | 39 + tests/sat/sim_counter.ys | 48 + tests/sim/.gitignore | 6 + tests/sim/adff.v | 7 + tests/sim/adffe.v | 8 + tests/sim/adlatch.v | 8 + tests/sim/aldff.v | 7 + tests/sim/aldffe.v | 8 + tests/sim/dff.v | 4 + tests/sim/dffe.v | 5 + tests/sim/dffsr.v | 9 + tests/sim/dlatch.v | 6 + tests/sim/dlatchsr.v | 11 + tests/sim/run-test.sh | 12 + tests/sim/sdff.v | 7 + tests/sim/sdffce.v | 8 + tests/sim/sdffe.v | 8 + tests/sim/sim_adff.ys | 6 + tests/sim/sim_adffe.ys | 6 + tests/sim/sim_adlatch.ys | 10 + tests/sim/sim_aldff.ys | 6 + tests/sim/sim_aldffe.ys | 6 + tests/sim/sim_dff.ys | 6 + tests/sim/sim_dffe.ys | 6 + tests/sim/sim_dffsr.ys | 6 + tests/sim/sim_dlatch.ys | 6 + tests/sim/sim_dlatchsr.ys | 10 + tests/sim/sim_sdff.ys | 6 + tests/sim/sim_sdffce.ys | 6 + tests/sim/sim_sdffe.ys | 6 + tests/sim/tb/tb_adff.v | 40 + tests/sim/tb/tb_adffe.v | 58 + tests/sim/tb/tb_adlatch.v | 70 + tests/sim/tb/tb_aldff.v | 73 + tests/sim/tb/tb_aldffe.v | 75 + tests/sim/tb/tb_dff.v | 47 + tests/sim/tb/tb_dffe.v | 42 + tests/sim/tb/tb_dffsr.v | 69 + tests/sim/tb/tb_dlatch.v | 50 + tests/sim/tb/tb_dlatchsr.v | 65 + tests/sim/tb/tb_sdff.v | 48 + tests/sim/tb/tb_sdffce.v | 79 + tests/sim/tb/tb_sdffe.v | 70 + tests/simple/attrib01_module.v | 6 +- tests/simple/attrib02_port_decl.v | 6 +- tests/simple/attrib03_parameter.v | 6 +- tests/simple/attrib04_net_var.v | 6 +- tests/simple/attrib05_port_conn.v.DISABLED | 6 +- tests/simple/attrib06_operator_suffix.v | 6 +- tests/simple/attrib07_func_call.v.DISABLED | 6 +- tests/simple/attrib08_mod_inst.v | 6 +- tests/simple/attrib09_case.v | 6 +- tests/simple/case_expr_const.v | 2 +- tests/simple/case_expr_extend.sv | 11 + tests/simple/case_expr_non_const.v | 2 +- tests/simple/case_expr_query.sv | 32 + tests/simple/case_large.v | 2 +- tests/simple/const_branch_finish.v | 2 +- tests/simple/const_fold_func.v | 2 +- tests/simple/const_func_shadow.v | 2 +- tests/simple/defvalue.sv | 2 +- tests/simple/func_block.v | 2 +- tests/simple/func_recurse.v | 2 +- tests/simple/func_width_scope.v | 2 +- tests/simple/genblk_collide.v | 4 +- tests/simple/genblk_dive.v | 2 +- tests/simple/genblk_order.v | 2 +- tests/simple/genblk_port_shadow.v | 2 +- tests/simple/hierarchy.v | 2 +- tests/simple/hierdefparam.v | 6 +- tests/simple/ifdef_1.v | 2 +- tests/simple/ifdef_2.v | 2 +- .../{implicit_ports.v => implicit_ports.sv} | 0 tests/simple/lesser_size_cast.sv | 7 + tests/simple/local_loop_var.sv | 2 +- tests/simple/loop_prefix_case.v | 2 +- tests/simple/loop_var_shadow.v | 2 +- tests/simple/macro_arg_spaces.sv | 2 +- tests/simple/macro_arg_surrounding_spaces.v | 2 +- tests/simple/matching_end_labels.sv | 2 +- tests/simple/mem2reg_bounds_tern.v | 2 +- tests/simple/memory.v | 14 +- tests/simple/memwr_port_connection.sv | 13 + tests/simple/module_scope.v | 34 +- tests/simple/module_scope_case.v | 8 +- tests/simple/module_scope_func.v | 45 + tests/simple/named_genblk.v | 2 +- tests/simple/nested_genblk_resolve.v | 2 +- tests/simple/signed_full_slice.v | 29 + tests/simple/specify.v | 2 +- tests/simple/string_format.v | 2 +- tests/simple/unnamed_block_decl.sv | 2 +- tests/simple/wandwor.v | 12 +- tests/sva/.gitignore | 1 + tests/sva/Makefile | 1 + tests/sva/nested_clk_else.sv | 11 + tests/sva/runtest.sh | 11 +- tests/sva/sva_value_change_changed.sv | 17 + tests/sva/sva_value_change_changed_wide.sv | 22 + tests/sva/sva_value_change_rose.sv | 20 + tests/sva/sva_value_change_sim.sv | 70 + tests/sva/sva_value_change_sim.ys | 3 + tests/svinterfaces/resolve_types.sv | 24 + tests/svinterfaces/resolve_types.ys | 6 + tests/svinterfaces/run-test.sh | 1 + tests/svtypes/logic_rom.ys | 2 +- tests/svtypes/struct_array.sv | 215 + tests/svtypes/struct_dynamic_range.sv | 67 + tests/svtypes/struct_dynamic_range.ys | 7 + tests/svtypes/struct_sizebits.sv | 112 + tests/svtypes/typedef_initial_and_assign.sv | 94 + tests/svtypes/typedef_initial_and_assign.ys | 14 + tests/svtypes/typedef_memory.ys | 2 +- tests/svtypes/typedef_memory_2.ys | 2 +- tests/svtypes/typedef_struct.sv | 4 + tests/svtypes/union_simple.sv | 16 + tests/techmap/.gitignore | 1 + tests/techmap/adff2dff.ys | 2 +- tests/techmap/bmuxmap_pmux.ys | 45 + tests/techmap/bug2759.ys | 14 + tests/techmap/bug2972.ys | 20 + tests/techmap/dff2ff.ys | 2 +- tests/techmap/dfflegalize_adff.ys | 32 + tests/techmap/dfflegalize_adff_init.ys | 84 +- tests/techmap/dfflegalize_adlatch.ys | 2 +- tests/techmap/dfflegalize_adlatch_init.ys | 6 +- tests/techmap/dfflegalize_aldff.ys | 92 + tests/techmap/dfflegalize_aldff_init.ys | 148 + tests/techmap/dfflegalize_dff.ys | 69 +- tests/techmap/dfflegalize_dff_init.ys | 138 +- tests/techmap/dfflegalize_dffsr_init.ys | 24 +- tests/techmap/dfflegalize_dlatch.ys | 22 + tests/techmap/dfflegalize_dlatch_const.ys | 8 +- tests/techmap/dfflegalize_dlatch_init.ys | 38 + tests/techmap/dfflegalize_dlatchsr_init.ys | 22 +- tests/techmap/dfflegalize_inv.ys | 27 +- tests/techmap/dfflegalize_minsrst.ys | 4 +- tests/techmap/dfflegalize_sr.ys | 2 +- tests/techmap/dfflegalize_sr_init.ys | 34 +- tests/techmap/dfflibmap.ys | 6 +- tests/techmap/dffunmap.ys | 2 +- tests/techmap/iopadmap.ys | 4 +- tests/techmap/mem_simple_4x1_runtest.sh | 16 +- tests/techmap/pmux2mux.ys | 2 +- tests/techmap/recursive_runtest.sh | 2 +- tests/techmap/shiftx2mux.ys | 2 +- tests/techmap/zinit.ys | 21 +- tests/tools/autotest.sh | 16 +- tests/tools/vcdcd.pl | 6 +- tests/various/.gitignore | 3 + tests/various/aiger_dff.ys | 7 + tests/various/async.sh | 8 +- tests/various/bug3462.ys | 12 + tests/various/cellarray_array_connections.ys | 45 + tests/various/chformal_coverenable.ys | 25 + tests/various/equiv_make_make_assert.ys | 32 + tests/various/json_escape_chars.ys | 14 + tests/various/logger_fail.sh | 42 + tests/various/muxcover.ys | 40 + tests/various/param_struct.ys | 50 + tests/various/rename_scramble_name.ys | 31 + tests/various/rtlil_z_bits.ys | 9 + tests/various/smtlib2_module-expected.smt2 | 96 + tests/various/smtlib2_module.sh | 5 + tests/various/smtlib2_module.v | 33 + tests/various/sta.ys | 81 + tests/various/struct_access.sv | 43 + tests/various/struct_access.ys | 5 + tests/various/sub.v | 3 + tests/verific/.gitignore | 3 + tests/verific/case.sv | 28 + tests/verific/case.ys | 16 + tests/verific/enum_values.sv | 37 + tests/verific/enum_values.ys | 19 + tests/verific/range_case.sv | 11 + tests/verific/range_case.ys | 16 + tests/verific/run-test.sh | 4 + tests/verilog/.gitignore | 1 + tests/verilog/always_comb_latch_1.ys | 13 + tests/verilog/always_comb_latch_2.ys | 15 + tests/verilog/always_comb_latch_3.ys | 20 + tests/verilog/always_comb_latch_4.ys | 17 + tests/verilog/always_comb_nolatch_1.ys | 16 + tests/verilog/always_comb_nolatch_2.ys | 17 + tests/verilog/always_comb_nolatch_3.ys | 21 + tests/verilog/always_comb_nolatch_4.ys | 16 + tests/verilog/always_comb_nolatch_5.ys | 15 + tests/verilog/always_comb_nolatch_6.ys | 15 + tests/verilog/block_labels.ys | 6 +- tests/verilog/delay_time_scale.ys | 25 + tests/verilog/doubleslash.ys | 21 + tests/verilog/dynamic_range_lhs.sh | 32 + tests/verilog/dynamic_range_lhs.v | 76 + tests/verilog/for_decl_no_init.ys | 9 + tests/verilog/for_decl_no_sv.ys | 9 + tests/verilog/for_decl_shadow.sv | 32 + tests/verilog/for_decl_shadow.ys | 6 + tests/verilog/func_tern_hint.sv | 42 + tests/verilog/func_tern_hint.ys | 4 + tests/verilog/func_upto.sv | 77 + tests/verilog/func_upto.ys | 7 + tests/verilog/genfor_decl_no_init.ys | 7 + tests/verilog/genfor_decl_no_sv.ys | 7 + tests/verilog/genvar_loop_decl_1.sv | 18 + tests/verilog/genvar_loop_decl_1.ys | 14 + tests/verilog/genvar_loop_decl_2.sv | 30 + tests/verilog/genvar_loop_decl_2.ys | 5 + tests/verilog/genvar_loop_decl_3.sv | 28 + tests/verilog/genvar_loop_decl_3.ys | 5 + tests/verilog/net_types.sv | 34 + tests/verilog/net_types.ys | 5 + tests/verilog/past_signedness.ys | 35 + tests/verilog/prefix.sv | 95 + tests/verilog/prefix.ys | 5 + tests/verilog/sign_array_query.ys | 52 + tests/verilog/size_cast.sv | 140 + tests/verilog/size_cast.ys | 5 + tests/verilog/struct_access.sv | 5 +- tests/verilog/typedef_const_shadow.sv | 12 + tests/verilog/typedef_const_shadow.ys | 4 + tests/verilog/unbased_unsized_shift.sv | 28 + tests/verilog/unbased_unsized_shift.ys | 7 + tests/verilog/unbased_unsized_tern.sv | 31 + tests/verilog/unbased_unsized_tern.ys | 6 + tests/verilog/unreachable_case_sign.ys | 33 + tests/verilog/void_func.ys | 37 + tests/xprop/.gitignore | 2 + tests/xprop/generate.py | 287 + tests/xprop/run-test.sh | 5 + tests/xprop/test.py | 516 ++ 909 files changed, 87269 insertions(+), 28694 deletions(-) create mode 100644 .gitcommit create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml delete mode 100644 .github/issue_template.md create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/emcc.yml create mode 100644 .github/workflows/test-linux.yml create mode 100644 .github/workflows/test-macos.yml delete mode 100644 .github/workflows/test.yml create mode 100644 backends/jny/Makefile.inc create mode 100644 backends/jny/jny.cc delete mode 100644 backends/protobuf/.gitignore delete mode 100644 backends/protobuf/Makefile.inc delete mode 100644 backends/protobuf/protobuf.cc create mode 100644 backends/smt2/witness.py create mode 100644 backends/smt2/ywio.py create mode 100644 docs/.gitignore create mode 100644 docs/Makefile create mode 100644 docs/images/011/example_out.tex create mode 100644 docs/images/011/select_prod.tex create mode 100644 docs/images/011/splitnets_libfile.tex create mode 100644 docs/images/011/submod_dots.tex create mode 100644 docs/images/Makefile create mode 100644 docs/images/approach_flow.png create mode 100644 docs/images/approach_flow.tex create mode 100644 docs/images/basics_abstractions.png create mode 100644 docs/images/basics_abstractions.tex create mode 100644 docs/images/basics_ast.png create mode 100644 docs/images/basics_ast.tex create mode 100644 docs/images/basics_flow.png create mode 100644 docs/images/basics_flow.tex create mode 100644 docs/images/basics_parsetree.png create mode 100644 docs/images/basics_parsetree.tex create mode 100644 docs/images/overview_flow.png create mode 100644 docs/images/overview_flow.tex create mode 100644 docs/images/overview_rtlil.png create mode 100644 docs/images/overview_rtlil.tex create mode 100644 docs/images/verilog_flow.png create mode 100644 docs/images/verilog_flow.tex rename {manual => docs/source}/APPNOTE_011_Design_Investigation/cmos.v (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/cmos_00.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/cmos_01.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/example.v (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/example.ys (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/example_00.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/example_01.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/example_02.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/example_03.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/foobaraddsub.v (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/make.sh (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/memdemo.v (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/memdemo_00.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/memdemo_01.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/primetest.v (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/splice.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/splice.v (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/submod.ys (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/submod_00.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/submod_01.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/submod_02.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/submod_03.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/sumprod.v (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/sumprod_00.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/sumprod_01.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/sumprod_02.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/sumprod_03.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/sumprod_04.dot (100%) rename {manual => docs/source}/APPNOTE_011_Design_Investigation/sumprod_05.dot (100%) create mode 100644 docs/source/CHAPTER_Approach.rst create mode 100644 docs/source/CHAPTER_Basics.rst create mode 100644 docs/source/CHAPTER_CellLib.rst create mode 100644 docs/source/CHAPTER_Eval.rst create mode 100644 docs/source/CHAPTER_Intro.rst create mode 100644 docs/source/CHAPTER_Optimize.rst create mode 100644 docs/source/CHAPTER_Overview.rst create mode 100644 docs/source/CHAPTER_Prog.rst rename {manual => docs/source}/CHAPTER_Prog/.gitignore (100%) rename {manual => docs/source}/CHAPTER_Prog/Makefile (100%) rename {manual => docs/source}/CHAPTER_Prog/stubnets.cc (100%) rename {manual => docs/source}/CHAPTER_Prog/test.v (100%) create mode 100644 docs/source/CHAPTER_Techmap.rst create mode 100644 docs/source/CHAPTER_Verilog.rst create mode 100644 docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst create mode 100644 docs/source/appendix/APPNOTE_011_Design_Investigation.rst create mode 100644 docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst create mode 100644 docs/source/appendix/CHAPTER_Auxlibs.rst create mode 100644 docs/source/appendix/CHAPTER_Auxprogs.rst create mode 100644 docs/source/appendix/CHAPTER_StateOfTheArt.rst create mode 100644 docs/source/appendix/CHAPTER_TextRtlil.rst create mode 100644 docs/source/bib.rst create mode 100644 docs/source/cmd_ref.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst create mode 100644 docs/source/literature.bib create mode 100644 docs/source/requirements.txt create mode 100644 docs/static/custom.css create mode 100644 docs/static/favico.png create mode 100644 docs/static/logo.png create mode 100644 docs/static/yosyshq.css create mode 100644 docs/util/RtlilLexer.py create mode 100644 docs/util/YoscryptLexer.py create mode 100755 examples/smtbmc/glift/C7552.v create mode 100644 examples/smtbmc/glift/C7552.ys create mode 100755 examples/smtbmc/glift/C880.v create mode 100644 examples/smtbmc/glift/C880.ys create mode 100755 examples/smtbmc/glift/alu2.v create mode 100644 examples/smtbmc/glift/alu2.ys create mode 100755 examples/smtbmc/glift/alu4.v create mode 100644 examples/smtbmc/glift/alu4.ys create mode 100644 examples/smtbmc/glift/mux2.ys create mode 100755 examples/smtbmc/glift/t481.v create mode 100644 examples/smtbmc/glift/t481.ys create mode 100755 examples/smtbmc/glift/too_large.v create mode 100644 examples/smtbmc/glift/too_large.ys create mode 100755 examples/smtbmc/glift/ttt2.v create mode 100644 examples/smtbmc/glift/ttt2.ys create mode 100755 examples/smtbmc/glift/x1.v create mode 100644 examples/smtbmc/glift/x1.ys create mode 100644 frontends/ast/ast_binding.cc create mode 100644 frontends/ast/ast_binding.h create mode 100644 kernel/binding.cc create mode 100644 kernel/binding.h create mode 100644 kernel/ff.cc create mode 100644 kernel/fstdata.cc create mode 100644 kernel/fstdata.h create mode 100644 kernel/json.cc create mode 100644 kernel/json.h create mode 100644 kernel/yw.cc create mode 100644 kernel/yw.h create mode 100644 libs/dlfcn-win32/dlfcn.cc create mode 100644 libs/dlfcn-win32/dlfcn.h create mode 100644 libs/fst/block_format.txt create mode 100644 libs/fst/config.h create mode 100644 libs/fst/fastlz.cc create mode 100644 libs/fst/fastlz.h create mode 100644 libs/fst/fstapi.cc create mode 100644 libs/fst/fstapi.h create mode 100644 libs/fst/lz4.cc create mode 100644 libs/fst/lz4.h delete mode 100644 manual/APPNOTE_010_Verilog_to_BLIF.tex delete mode 100644 manual/APPNOTE_011_Design_Investigation.tex delete mode 100644 manual/APPNOTE_012_Verilog_to_BTOR.tex delete mode 100644 manual/CHAPTER_Appnotes.tex delete mode 100644 manual/CHAPTER_Approach.tex delete mode 100644 manual/CHAPTER_Auxlibs.tex delete mode 100644 manual/CHAPTER_Auxprogs.tex delete mode 100644 manual/CHAPTER_Basics.tex delete mode 100644 manual/CHAPTER_CellLib.tex delete mode 100644 manual/CHAPTER_Eval.tex delete mode 100644 manual/CHAPTER_Eval/grep-it.sh delete mode 100644 manual/CHAPTER_Eval/openmsp430.prj delete mode 100644 manual/CHAPTER_Eval/openmsp430_ys.prj delete mode 100644 manual/CHAPTER_Eval/or1200.prj delete mode 100644 manual/CHAPTER_Eval/or1200_ys.prj delete mode 100644 manual/CHAPTER_Eval/run-it.sh delete mode 100644 manual/CHAPTER_Eval/settings.xst delete mode 100644 manual/CHAPTER_Intro.tex delete mode 100644 manual/CHAPTER_Optimize.tex delete mode 100644 manual/CHAPTER_Overview.tex delete mode 100644 manual/CHAPTER_Prog.tex delete mode 100644 manual/CHAPTER_StateOfTheArt.tex delete mode 100644 manual/CHAPTER_StateOfTheArt/always01.v delete mode 100644 manual/CHAPTER_StateOfTheArt/always01_pub.v delete mode 100644 manual/CHAPTER_StateOfTheArt/always02.v delete mode 100644 manual/CHAPTER_StateOfTheArt/always02_pub.v delete mode 100644 manual/CHAPTER_StateOfTheArt/always03.v delete mode 100644 manual/CHAPTER_StateOfTheArt/arrays01.v delete mode 100644 manual/CHAPTER_StateOfTheArt/cmp_tbdata.c delete mode 100644 manual/CHAPTER_StateOfTheArt/forgen01.v delete mode 100644 manual/CHAPTER_StateOfTheArt/forgen02.v delete mode 100644 manual/CHAPTER_StateOfTheArt/iverilog-0.8.7-buildfixes.patch delete mode 100644 manual/CHAPTER_StateOfTheArt/mvsis-1.3.6-buildfixes.patch delete mode 100644 manual/CHAPTER_StateOfTheArt/simlib_hana.v delete mode 100644 manual/CHAPTER_StateOfTheArt/simlib_icarus.v delete mode 100644 manual/CHAPTER_StateOfTheArt/simlib_yosys.v delete mode 100644 manual/CHAPTER_StateOfTheArt/sis-1.3.6-buildfixes.patch delete mode 100755 manual/CHAPTER_StateOfTheArt/synth.sh delete mode 100755 manual/CHAPTER_StateOfTheArt/validate_tb.sh delete mode 100644 manual/CHAPTER_Techmap.tex delete mode 100644 manual/CHAPTER_TextRtlil.tex delete mode 100644 manual/CHAPTER_Verilog.tex delete mode 100755 manual/appnotes.sh delete mode 100644 manual/command-reference-manual.tex delete mode 100644 manual/literature.bib delete mode 100755 manual/manual.sh delete mode 100644 manual/manual.tex delete mode 100644 manual/weblinks.bib create mode 100644 misc/jny.schema.json delete mode 100644 misc/yosys.proto create mode 100644 passes/cmds/clean_zerowidth.cc create mode 100644 passes/cmds/glift.cc create mode 100644 passes/cmds/splitcells.cc create mode 100644 passes/cmds/sta.cc create mode 100644 passes/cmds/viz.cc create mode 100644 passes/cmds/xprop.cc create mode 100644 passes/memory/memlib.cc create mode 100644 passes/memory/memlib.h create mode 100644 passes/memory/memlib.md create mode 100644 passes/memory/memory_bmux2rom.cc create mode 100644 passes/memory/memory_libmap.cc create mode 100644 passes/opt/opt_ffinv.cc create mode 100644 passes/opt/opt_mem_priority.cc create mode 100644 passes/opt/opt_mem_widen.cc create mode 100644 passes/proc/proc_rom.cc create mode 100644 passes/sat/formalff.cc create mode 100644 passes/sat/recover_names.cc create mode 100644 passes/sat/synthprop.cc create mode 100644 passes/techmap/bmuxmap.cc create mode 100644 passes/techmap/bwmuxmap.cc create mode 100644 passes/techmap/demuxmap.cc create mode 100644 techlibs/anlogic/brams.txt create mode 100644 techlibs/anlogic/brams_map.v delete mode 100644 techlibs/anlogic/lutram_init_16x4.vh create mode 100644 techlibs/common/smtmap.v delete mode 100644 techlibs/ecp5/.gitignore delete mode 100755 techlibs/ecp5/brams_connect.py delete mode 100755 techlibs/ecp5/brams_init.py create mode 100644 techlibs/fabulous/Makefile.inc create mode 100644 techlibs/fabulous/arith_map.v create mode 100644 techlibs/fabulous/cells_map.v create mode 100644 techlibs/fabulous/ff_map.v create mode 100644 techlibs/fabulous/io_map.v create mode 100644 techlibs/fabulous/latches_map.v create mode 100644 techlibs/fabulous/prims.v create mode 100644 techlibs/fabulous/ram_regfile.txt create mode 100644 techlibs/fabulous/regfile_map.v create mode 100644 techlibs/fabulous/synth_fabulous.cc create mode 100644 techlibs/gatemate/.gitignore create mode 100644 techlibs/gatemate/Makefile.inc create mode 100644 techlibs/gatemate/arith_map.v create mode 100644 techlibs/gatemate/brams.txt create mode 100644 techlibs/gatemate/brams_init_20.vh create mode 100644 techlibs/gatemate/brams_init_40.vh create mode 100644 techlibs/gatemate/brams_map.v create mode 100644 techlibs/gatemate/cells_bb.v create mode 100644 techlibs/gatemate/cells_sim.v create mode 100644 techlibs/gatemate/gatemate_foldinv.cc create mode 100644 techlibs/gatemate/inv_map.v create mode 100644 techlibs/gatemate/lut_map.v create mode 100644 techlibs/gatemate/make_lut_tree_lib.py create mode 100644 techlibs/gatemate/mul_map.v create mode 100644 techlibs/gatemate/mux_map.v create mode 100644 techlibs/gatemate/reg_map.v create mode 100644 techlibs/gatemate/synth_gatemate.cc delete mode 100644 techlibs/gowin/.gitignore delete mode 100755 techlibs/gowin/brams_init.py delete mode 100644 techlibs/gowin/brams_init3.vh create mode 100644 techlibs/gowin/cells_xtra.py create mode 100644 techlibs/gowin/cells_xtra.v delete mode 100644 techlibs/ice40/.gitignore delete mode 100644 techlibs/ice40/brams_init.py create mode 100644 techlibs/ice40/spram.txt create mode 100644 techlibs/ice40/spram_map.v create mode 100644 techlibs/intel_alm/common/bram_m10k_map.v create mode 100644 techlibs/machxo2/arith_map.v create mode 100644 techlibs/machxo2/brams.txt create mode 100644 techlibs/machxo2/brams_map.v create mode 100644 techlibs/machxo2/cells_bb.v delete mode 100644 techlibs/nexus/brams_init.vh delete mode 100644 techlibs/nexus/lrams_init.vh create mode 100644 techlibs/sf2/NOTES.txt create mode 100644 techlibs/sf2/tests/test_arith.ys delete mode 100644 techlibs/xilinx/.gitignore create mode 100644 techlibs/xilinx/brams_defs.vh delete mode 100644 techlibs/xilinx/brams_init.py create mode 100644 techlibs/xilinx/brams_xc2v.txt create mode 100644 techlibs/xilinx/brams_xc2v_map.v create mode 100644 techlibs/xilinx/brams_xc3sda.txt create mode 100644 techlibs/xilinx/brams_xc3sda_map.v create mode 100644 techlibs/xilinx/brams_xc4v.txt create mode 100644 techlibs/xilinx/brams_xc4v_map.v create mode 100644 techlibs/xilinx/brams_xc5v_map.v create mode 100644 techlibs/xilinx/brams_xc6v_map.v create mode 100644 techlibs/xilinx/brams_xcu_map.v create mode 100644 techlibs/xilinx/brams_xcv.txt create mode 100644 techlibs/xilinx/brams_xcv_map.v delete mode 100644 techlibs/xilinx/lut4_lutrams.txt delete mode 100644 techlibs/xilinx/lut6_lutrams.txt delete mode 100644 techlibs/xilinx/lutrams_map.v create mode 100644 techlibs/xilinx/lutrams_xc5v.txt create mode 100644 techlibs/xilinx/lutrams_xc5v_map.v create mode 100644 techlibs/xilinx/lutrams_xcu.txt create mode 100644 techlibs/xilinx/lutrams_xcv.txt create mode 100644 techlibs/xilinx/lutrams_xcv_map.v create mode 100644 techlibs/xilinx/urams.txt create mode 100644 techlibs/xilinx/urams_map.v delete mode 100644 techlibs/xilinx/xc2v_brams.txt delete mode 100644 techlibs/xilinx/xc2v_brams_map.v delete mode 100644 techlibs/xilinx/xc3sa_brams.txt delete mode 100644 techlibs/xilinx/xc3sda_brams.txt delete mode 100644 techlibs/xilinx/xc6s_brams.txt delete mode 100644 techlibs/xilinx/xc6s_brams_map.v delete mode 100644 techlibs/xilinx/xc7_brams_map.v delete mode 100644 techlibs/xilinx/xc7_xcu_brams.txt delete mode 100644 techlibs/xilinx/xcu_brams_map.v delete mode 100644 techlibs/xilinx/xcup_urams.txt delete mode 100644 techlibs/xilinx/xcup_urams_map.v create mode 100644 tests/arch/anlogic/blockram.ys create mode 100644 tests/arch/ecp5/bug1836.mem create mode 100644 tests/arch/ecp5/bug1836.ys create mode 100644 tests/arch/ecp5/bug2731.ys create mode 100644 tests/arch/fabulous/.gitignore create mode 100644 tests/arch/fabulous/carry.ys create mode 100644 tests/arch/fabulous/complexflop.ys create mode 100644 tests/arch/fabulous/counter.ys create mode 100644 tests/arch/fabulous/custom_map.v create mode 100644 tests/arch/fabulous/custom_prims.v create mode 100644 tests/arch/fabulous/customisation.ys create mode 100644 tests/arch/fabulous/fsm.ys create mode 100644 tests/arch/fabulous/logic.ys create mode 100644 tests/arch/fabulous/regfile.ys create mode 100644 tests/arch/fabulous/tribuf.ys create mode 100644 tests/arch/gatemate/.gitignore create mode 100644 tests/arch/gatemate/add_sub.ys create mode 100644 tests/arch/gatemate/adffs.ys create mode 100644 tests/arch/gatemate/counter.ys create mode 100644 tests/arch/gatemate/dffs.ys create mode 100644 tests/arch/gatemate/fsm.ys create mode 100644 tests/arch/gatemate/gen_luttrees.py create mode 100644 tests/arch/gatemate/latches.ys create mode 100644 tests/arch/gatemate/logic.ys create mode 100644 tests/arch/gatemate/luttrees.v create mode 100644 tests/arch/gatemate/luttrees.ys create mode 100644 tests/arch/gatemate/memory.ys create mode 100644 tests/arch/gatemate/mul.v create mode 100644 tests/arch/gatemate/mul.ys create mode 100644 tests/arch/gatemate/mux.ys create mode 100755 tests/arch/gatemate/run-test.sh create mode 100644 tests/arch/gatemate/shifter.ys create mode 100644 tests/arch/gatemate/tribuf.ys create mode 100644 tests/arch/gowin/compare.v create mode 100644 tests/arch/gowin/compare.ys create mode 100644 tests/arch/ice40/spram.v create mode 100644 tests/arch/ice40/spram.ys create mode 100644 tests/arch/machxo2/adffs.ys create mode 100644 tests/arch/machxo2/counter.ys create mode 100644 tests/arch/machxo2/lutram.ys create mode 100644 tests/arch/xilinx/asym_ram_sdp.ys create mode 100644 tests/arch/xilinx/asym_ram_sdp_read_wider.v create mode 100644 tests/arch/xilinx/asym_ram_sdp_write_wider.v create mode 100644 tests/arch/xilinx/bug3670.v create mode 100644 tests/arch/xilinx/bug3670.ys create mode 100644 tests/arch/xilinx/priority_memory.v create mode 100644 tests/arch/xilinx/priority_memory.ys create mode 100644 tests/blif/bug3374.ys create mode 100644 tests/blif/bug3385.ys create mode 100644 tests/liberty/XNOR2X1.lib create mode 100644 tests/liberty/issue3498_bad.lib create mode 100644 tests/memlib/.gitignore create mode 100644 tests/memlib/generate.py create mode 100644 tests/memlib/memlib_9b1B.txt create mode 100644 tests/memlib/memlib_9b1B.v create mode 100644 tests/memlib/memlib_block_sdp.txt create mode 100644 tests/memlib/memlib_block_sdp.v create mode 100644 tests/memlib/memlib_block_sdp_1clk.txt create mode 100644 tests/memlib/memlib_block_sdp_1clk.v create mode 100644 tests/memlib/memlib_block_sp.txt create mode 100644 tests/memlib/memlib_block_sp.v create mode 100644 tests/memlib/memlib_block_sp_full.txt create mode 100644 tests/memlib/memlib_block_sp_full.v create mode 100644 tests/memlib/memlib_block_tdp.txt create mode 100644 tests/memlib/memlib_block_tdp.v create mode 100644 tests/memlib/memlib_clock_sdp.txt create mode 100644 tests/memlib/memlib_clock_sdp.v create mode 100644 tests/memlib/memlib_lut.txt create mode 100644 tests/memlib/memlib_lut.v create mode 100644 tests/memlib/memlib_multilut.txt create mode 100644 tests/memlib/memlib_multilut.v create mode 100644 tests/memlib/memlib_wide_read.txt create mode 100644 tests/memlib/memlib_wide_read.v create mode 100644 tests/memlib/memlib_wide_sdp.txt create mode 100644 tests/memlib/memlib_wide_sdp.v create mode 100644 tests/memlib/memlib_wide_sp.txt create mode 100644 tests/memlib/memlib_wide_sp.v create mode 100644 tests/memlib/memlib_wide_write.txt create mode 100644 tests/memlib/memlib_wide_write.v create mode 100644 tests/memlib/memlib_wren.txt create mode 100644 tests/memlib/memlib_wren.v create mode 100755 tests/memlib/run-test.sh create mode 100644 tests/memories/read_arst.v create mode 100644 tests/memories/trans_addr_enable.v create mode 100644 tests/memories/trans_sdp.v create mode 100644 tests/memories/trans_sp.v create mode 100644 tests/memories/wide_all.v create mode 100644 tests/memories/wide_read_async.v create mode 100644 tests/memories/wide_read_mixed.v create mode 100644 tests/memories/wide_read_sync.v create mode 100644 tests/memories/wide_read_trans.v create mode 100644 tests/memories/wide_thru_priority.v create mode 100644 tests/memories/wide_write.v create mode 100644 tests/opt/bug3047.ys create mode 100644 tests/opt/bug3117.ys create mode 100644 tests/opt/memory_bmux2rom.ys create mode 100644 tests/opt/memory_dff_trans.ys create mode 100644 tests/opt/opt_mem_priority.ys create mode 100644 tests/opt/opt_reduce_bmux.ys create mode 100644 tests/opt/opt_reduce_demux.ys create mode 100644 tests/proc/bug2962.ys create mode 100644 tests/proc/proc_rom.ys create mode 100644 tests/sat/alu.v create mode 100644 tests/sat/grom.ys create mode 100644 tests/sat/grom_computer.v create mode 100644 tests/sat/grom_cpu.v create mode 100644 tests/sat/ram_memory.v create mode 100644 tests/sat/sim_counter.ys create mode 100644 tests/sim/.gitignore create mode 100644 tests/sim/adff.v create mode 100644 tests/sim/adffe.v create mode 100644 tests/sim/adlatch.v create mode 100644 tests/sim/aldff.v create mode 100644 tests/sim/aldffe.v create mode 100644 tests/sim/dff.v create mode 100644 tests/sim/dffe.v create mode 100644 tests/sim/dffsr.v create mode 100644 tests/sim/dlatch.v create mode 100644 tests/sim/dlatchsr.v create mode 100755 tests/sim/run-test.sh create mode 100644 tests/sim/sdff.v create mode 100644 tests/sim/sdffce.v create mode 100644 tests/sim/sdffe.v create mode 100644 tests/sim/sim_adff.ys create mode 100644 tests/sim/sim_adffe.ys create mode 100644 tests/sim/sim_adlatch.ys create mode 100644 tests/sim/sim_aldff.ys create mode 100644 tests/sim/sim_aldffe.ys create mode 100644 tests/sim/sim_dff.ys create mode 100644 tests/sim/sim_dffe.ys create mode 100644 tests/sim/sim_dffsr.ys create mode 100644 tests/sim/sim_dlatch.ys create mode 100644 tests/sim/sim_dlatchsr.ys create mode 100644 tests/sim/sim_sdff.ys create mode 100644 tests/sim/sim_sdffce.ys create mode 100644 tests/sim/sim_sdffe.ys create mode 100755 tests/sim/tb/tb_adff.v create mode 100755 tests/sim/tb/tb_adffe.v create mode 100755 tests/sim/tb/tb_adlatch.v create mode 100755 tests/sim/tb/tb_aldff.v create mode 100755 tests/sim/tb/tb_aldffe.v create mode 100755 tests/sim/tb/tb_dff.v create mode 100755 tests/sim/tb/tb_dffe.v create mode 100755 tests/sim/tb/tb_dffsr.v create mode 100755 tests/sim/tb/tb_dlatch.v create mode 100755 tests/sim/tb/tb_dlatchsr.v create mode 100755 tests/sim/tb/tb_sdff.v create mode 100755 tests/sim/tb/tb_sdffce.v create mode 100755 tests/sim/tb/tb_sdffe.v create mode 100644 tests/simple/case_expr_extend.sv create mode 100644 tests/simple/case_expr_query.sv rename tests/simple/{implicit_ports.v => implicit_ports.sv} (100%) create mode 100644 tests/simple/lesser_size_cast.sv create mode 100644 tests/simple/memwr_port_connection.sv create mode 100644 tests/simple/module_scope_func.v create mode 100644 tests/simple/signed_full_slice.v create mode 100644 tests/sva/nested_clk_else.sv create mode 100644 tests/sva/sva_value_change_changed.sv create mode 100644 tests/sva/sva_value_change_changed_wide.sv create mode 100644 tests/sva/sva_value_change_rose.sv create mode 100644 tests/sva/sva_value_change_sim.sv create mode 100644 tests/sva/sva_value_change_sim.ys create mode 100644 tests/svinterfaces/resolve_types.sv create mode 100644 tests/svinterfaces/resolve_types.ys create mode 100644 tests/svtypes/struct_dynamic_range.sv create mode 100644 tests/svtypes/struct_dynamic_range.ys create mode 100644 tests/svtypes/struct_sizebits.sv create mode 100644 tests/svtypes/typedef_initial_and_assign.sv create mode 100644 tests/svtypes/typedef_initial_and_assign.ys create mode 100644 tests/techmap/bmuxmap_pmux.ys create mode 100644 tests/techmap/bug2759.ys create mode 100644 tests/techmap/bug2972.ys create mode 100644 tests/techmap/dfflegalize_aldff.ys create mode 100644 tests/techmap/dfflegalize_aldff_init.ys create mode 100644 tests/various/aiger_dff.ys create mode 100644 tests/various/bug3462.ys create mode 100644 tests/various/cellarray_array_connections.ys create mode 100644 tests/various/chformal_coverenable.ys create mode 100644 tests/various/equiv_make_make_assert.ys create mode 100644 tests/various/json_escape_chars.ys create mode 100755 tests/various/logger_fail.sh create mode 100644 tests/various/param_struct.ys create mode 100644 tests/various/rename_scramble_name.ys create mode 100644 tests/various/rtlil_z_bits.ys create mode 100644 tests/various/smtlib2_module-expected.smt2 create mode 100755 tests/various/smtlib2_module.sh create mode 100644 tests/various/smtlib2_module.v create mode 100644 tests/various/sta.ys create mode 100644 tests/various/struct_access.sv create mode 100644 tests/various/struct_access.ys create mode 100644 tests/various/sub.v create mode 100644 tests/verific/.gitignore create mode 100644 tests/verific/case.sv create mode 100644 tests/verific/case.ys create mode 100644 tests/verific/enum_values.sv create mode 100644 tests/verific/enum_values.ys create mode 100644 tests/verific/range_case.sv create mode 100644 tests/verific/range_case.ys create mode 100755 tests/verific/run-test.sh create mode 100644 tests/verilog/always_comb_latch_1.ys create mode 100644 tests/verilog/always_comb_latch_2.ys create mode 100644 tests/verilog/always_comb_latch_3.ys create mode 100644 tests/verilog/always_comb_latch_4.ys create mode 100644 tests/verilog/always_comb_nolatch_1.ys create mode 100644 tests/verilog/always_comb_nolatch_2.ys create mode 100644 tests/verilog/always_comb_nolatch_3.ys create mode 100644 tests/verilog/always_comb_nolatch_4.ys create mode 100644 tests/verilog/always_comb_nolatch_5.ys create mode 100644 tests/verilog/always_comb_nolatch_6.ys create mode 100644 tests/verilog/delay_time_scale.ys create mode 100644 tests/verilog/doubleslash.ys create mode 100755 tests/verilog/dynamic_range_lhs.sh create mode 100644 tests/verilog/dynamic_range_lhs.v create mode 100644 tests/verilog/for_decl_no_init.ys create mode 100644 tests/verilog/for_decl_no_sv.ys create mode 100644 tests/verilog/for_decl_shadow.sv create mode 100644 tests/verilog/for_decl_shadow.ys create mode 100644 tests/verilog/func_tern_hint.sv create mode 100644 tests/verilog/func_tern_hint.ys create mode 100644 tests/verilog/func_upto.sv create mode 100644 tests/verilog/func_upto.ys create mode 100644 tests/verilog/genfor_decl_no_init.ys create mode 100644 tests/verilog/genfor_decl_no_sv.ys create mode 100644 tests/verilog/genvar_loop_decl_1.sv create mode 100644 tests/verilog/genvar_loop_decl_1.ys create mode 100644 tests/verilog/genvar_loop_decl_2.sv create mode 100644 tests/verilog/genvar_loop_decl_2.ys create mode 100644 tests/verilog/genvar_loop_decl_3.sv create mode 100644 tests/verilog/genvar_loop_decl_3.ys create mode 100644 tests/verilog/net_types.sv create mode 100644 tests/verilog/net_types.ys create mode 100644 tests/verilog/past_signedness.ys create mode 100644 tests/verilog/prefix.sv create mode 100644 tests/verilog/prefix.ys create mode 100644 tests/verilog/sign_array_query.ys create mode 100644 tests/verilog/size_cast.sv create mode 100644 tests/verilog/size_cast.ys create mode 100644 tests/verilog/typedef_const_shadow.sv create mode 100644 tests/verilog/typedef_const_shadow.ys create mode 100644 tests/verilog/unbased_unsized_shift.sv create mode 100644 tests/verilog/unbased_unsized_shift.ys create mode 100644 tests/verilog/unbased_unsized_tern.sv create mode 100644 tests/verilog/unbased_unsized_tern.ys create mode 100644 tests/verilog/unreachable_case_sign.ys create mode 100644 tests/verilog/void_func.ys create mode 100644 tests/xprop/.gitignore create mode 100644 tests/xprop/generate.py create mode 100755 tests/xprop/run-test.sh create mode 100644 tests/xprop/test.py diff --git a/.gitattributes b/.gitattributes index f85ae06c930..5e568606e6e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ *.v linguist-language=Verilog +/.gitcommit export-subst diff --git a/.gitcommit b/.gitcommit new file mode 100644 index 00000000000..46b7856fbc8 --- /dev/null +++ b/.gitcommit @@ -0,0 +1 @@ +$Format:%h$ diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000..27cfd09b7de --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,75 @@ +name: Bug Report +description: Report an issue or regression with Yosys +labels: ["pending-verification"] +body: + - type: markdown + attributes: + value: > + + If you have a general question, please ask it in the [Discussions](https://github.com/YosysHQ/yosys/discussions) area + or join our [IRC Channel](https://web.libera.chat/#yosys) or [Community Slack](https://join.slack.com/t/yosyshq/shared_invite/zt-1aopkns2q-EiQ97BeQDt_pwvE41sGSuA). + + + If you have a feature request, please fill out the appropriate issue form, this form is for bugs and/or regressions. + + + Please contact [YosysHQ GmbH](https://www.yosyshq.com/) if you need + commercial support for Yosys. + + - type: input + id: yosys_version + attributes: + label: Version + description: "The version of yosys this bug was encountered on." + placeholder: "The output of `yosys --version`" + validations: + required: true + + - type: dropdown + id: os + attributes: + label: On which OS did this happen? + options: + - Linux + - macOS + - Windows + - BSD + multiple: true + validations: + required: true + + - type: markdown + attributes: + value: > + When providing steps to reproduce the issue, please ensure that the issue + is reproducible in the current git master of Yosys. Also ensure to + provide all necessary source files needed. + + + Please see [https://stackoverflow.com/help/mcve](https://stackoverflow.com/help/mcve) + for information on how to create a Minimal, Complete, and Verifiable Example + (MCVE). + + - type: textarea + id: reproduction_steps + attributes: + label: Reproduction Steps + description: "Please provide clear and concise steps to reproduce the issue." + validations: + required: true + + - type: textarea + id: expected_behavior + attributes: + label: Expected Behavior + description: "Please describe the behavior you would have expected from the tool." + validations: + required: true + + - type: textarea + id: actual_behavior + attributes: + label: Actual Behavior + description: "Please describe how the behavior you see differs from the expected behavior." + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..bef410a3c92 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +contact_links: + - name: Discussions + url: https://github.com/YosysHQ/yosys/discussions + about: "Have a question? Ask it on our discussions page!" + - name: Community Slack + url: https://join.slack.com/t/yosyshq/shared_invite/zt-1aopkns2q-EiQ97BeQDt_pwvE41sGSuA + about: "Yosys Community Slack" + - name: IRC Channel + url: https://web.libera.chat/#yosys + about: "#yosys on irc.libera.chat" + diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000000..c521b529631 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,26 @@ +name: Feature Request +description: "Submit a feature request for Yosys" +labels: ["feature-request"] +body: + - type: markdown + attributes: + value: > + + If you have a general question, please ask it in the [Discussions](https://github.com/YosysHQ/yosys/discussions) area + or join our [IRC Channel](https://web.libera.chat/#yosys) or [Community Slack](https://join.slack.com/t/yosyshq/shared_invite/zt-1aopkns2q-EiQ97BeQDt_pwvE41sGSuA). + + + If you have a bug report, please fill out the appropriate issue form, this form is for feature requests. + + + Please contact [YosysHQ GmbH](https://www.yosyshq.com/) if you need + commercial support or work done for Yosys. + + - type: textarea + id: feature_description + attributes: + label: Feature Description + description: "A clear and detailed description of the feature." + validations: + required: true + diff --git a/.github/issue_template.md b/.github/issue_template.md deleted file mode 100644 index c72daae3ec7..00000000000 --- a/.github/issue_template.md +++ /dev/null @@ -1,24 +0,0 @@ -## Steps to reproduce the issue - -*Provide instructions for reproducing the issue. Make sure to include -all necessary source files. (You can simply drag&drop a .zip file into -the issue editor.)* - -Also, make sure that the issue is actually reproducable in current git -master of Yosys. - -See https://stackoverflow.com/help/mcve for some information on how to -create a Minimal, Complete, and Verifiable example (MCVE). - -Please do not waste our time with issues that lack sufficient information -to reproduce the issue easily. We will simply close those issues. - -Contact https://www.yosyshq.com/ if you need commercial support for Yosys. - -## Expected behavior - -*Please describe the behavior you would have expected from the tool.* - -## Actual behavior - -*Please describe how the behavior you see differs from the expected behavior.* diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000000..2a046703bc0 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,29 @@ +name: "CodeQL" + +on: + workflow_dispatch: + schedule: + - cron: '0 3 * * *' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + steps: + - name: Install deps + run: sudo apt-get install bison flex libreadline-dev tcl-dev libffi-dev + + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: cpp + queries: security-extended,security-and-quality + + - name: Build + run: make yosys -j6 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/emcc.yml b/.github/workflows/emcc.yml new file mode 100644 index 00000000000..295d9554b81 --- /dev/null +++ b/.github/workflows/emcc.yml @@ -0,0 +1,18 @@ +name: Emscripten Build + +on: [push, pull_request] + +jobs: + emcc: + runs-on: ubuntu-latest + steps: + - uses: mymindstorm/setup-emsdk@v11 + - uses: actions/checkout@v3 + - name: Build + run: | + make config-emcc + make YOSYS_VER=latest + - uses: actions/upload-artifact@v3 + with: + name: yosysjs + path: yosysjs-latest.zip diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml new file mode 100644 index 00000000000..eee556794af --- /dev/null +++ b/.github/workflows/test-linux.yml @@ -0,0 +1,116 @@ +name: Build and run tests (Linux) + +on: [push, pull_request] + +jobs: + test-linux: + runs-on: ${{ matrix.os.id }} + strategy: + matrix: + os: + - { id: ubuntu-20.04, name: focal } + compiler: + - 'clang-12' + - 'gcc-11' + cpp_std: + - 'c++11' + - 'c++14' + - 'c++17' + - 'c++20' + include: + # Limit the older compilers to C++11 mode + - os: { id: ubuntu-20.04, name: focal } + compiler: 'clang-11' + cpp_std: 'c++11' + - os: { id: ubuntu-20.04, name: focal } + compiler: 'gcc-10' + cpp_std: 'c++11' + fail-fast: false + steps: + - name: Install Dependencies + shell: bash + run: | + sudo apt-get update + sudo apt-get install gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev + + - name: Setup GCC + if: startsWith(matrix.compiler, 'gcc') + shell: bash + run: | + CXX=${CC/#gcc/g++} + sudo apt-add-repository ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get install $CC $CXX + echo "CC=$CC" >> $GITHUB_ENV + echo "CXX=$CXX" >> $GITHUB_ENV + env: + CC: ${{ matrix.compiler }} + + - name: Setup Clang + if: startsWith(matrix.compiler, 'clang') + shell: bash + run: | + wget https://apt.llvm.org/llvm-snapshot.gpg.key + sudo apt-key add llvm-snapshot.gpg.key + rm llvm-snapshot.gpg.key + sudo apt-add-repository "deb https://apt.llvm.org/${{ matrix.os.name }}/ llvm-toolchain-${{ matrix.os.name }} main" + sudo apt-get update + CXX=${CC/#clang/clang++} + sudo apt-get install $CC $CXX + echo "CC=$CC" >> $GITHUB_ENV + echo "CXX=$CXX" >> $GITHUB_ENV + env: + CC: ${{ matrix.compiler }} + + - name: Runtime environment + shell: bash + env: + WORKSPACE: ${{ github.workspace }} + run: | + echo "GITHUB_WORKSPACE=`pwd`" >> $GITHUB_ENV + echo "$GITHUB_WORKSPACE/.local/bin" >> $GITHUB_PATH + echo "procs=$(nproc)" >> $GITHUB_ENV + + - name: Tool versions + shell: bash + run: | + $CC --version + $CXX --version + + - name: Checkout Yosys + uses: actions/checkout@v3 + + - name: Get iverilog + shell: bash + run: | + git clone https://github.com/steveicarus/iverilog.git + + - name: Cache iverilog + id: cache-iverilog + uses: actions/cache@v3 + with: + path: .local/ + key: ${{ matrix.os.id }}-${{ hashFiles('iverilog/.git/refs/heads/master') }} + + - name: Build iverilog + if: steps.cache-iverilog.outputs.cache-hit != 'true' + shell: bash + run: | + mkdir -p $GITHUB_WORKSPACE/.local/ + cd iverilog + autoconf + CC=gcc CXX=g++ ./configure --prefix=$GITHUB_WORKSPACE/.local + make -j${{ env.procs }} + make install + + - name: Build yosys + shell: bash + run: | + make config-${CC%%-*} + make -j${{ env.procs }} CCXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC + + - name: Run tests + if: (matrix.cpp_std == 'c++11') && (matrix.compiler == 'gcc-11') + shell: bash + run: | + make -j${{ env.procs }} test CXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC diff --git a/.github/workflows/test-macos.yml b/.github/workflows/test-macos.yml new file mode 100644 index 00000000000..04845723467 --- /dev/null +++ b/.github/workflows/test-macos.yml @@ -0,0 +1,73 @@ +name: Build and run tests (macOS) + +on: [push, pull_request] + +jobs: + test-macos: + runs-on: ${{ matrix.os.id }} + strategy: + matrix: + os: + - { id: macos-11, name: 'Big Sur' } + cpp_std: + - 'c++11' + - 'c++17' + fail-fast: false + steps: + - name: Install Dependencies + run: | + brew install bison flex gawk libffi pkg-config bash + + - name: Runtime environment + shell: bash + env: + WORKSPACE: ${{ github.workspace }} + run: | + echo "GITHUB_WORKSPACE=`pwd`" >> $GITHUB_ENV + echo "$GITHUB_WORKSPACE/.local/bin" >> $GITHUB_PATH + echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH + echo "$(brew --prefix flex)/bin" >> $GITHUB_PATH + echo "procs=$(sysctl -n hw.ncpu)" >> $GITHUB_ENV + + - name: Tool versions + shell: bash + run: | + cc --version + + - name: Checkout Yosys + uses: actions/checkout@v3 + + - name: Get iverilog + shell: bash + run: | + git clone https://github.com/steveicarus/iverilog.git + + - name: Cache iverilog + id: cache-iverilog + uses: actions/cache@v3 + with: + path: .local/ + key: ${{ matrix.os.id }}-${{ hashFiles('iverilog/.git/refs/heads/master') }} + + - name: Build iverilog + if: steps.cache-iverilog.outputs.cache-hit != 'true' + shell: bash + run: | + mkdir -p $GITHUB_WORKSPACE/.local/ + cd iverilog + autoconf + CC=gcc CXX=g++ ./configure --prefix=$GITHUB_WORKSPACE/.local/ + make -j${{ env.procs }} + make install + + - name: Build yosys + shell: bash + run: | + make config-clang + make -j${{ env.procs }} CXXSTD=${{ matrix.cpp_std }} CC=cc CXX=cc LD=cc + + - name: Run tests + if: matrix.cpp_std == 'c++11' + shell: bash + run: | + make -j${{ env.procs }} test CXXSTD=${{ matrix.cpp_std }} CC=cc CXX=cc LD=cc diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index ee5b5c00ebf..00000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,91 +0,0 @@ -name: Build and run tests - -on: [push, pull_request] - -jobs: - test: - strategy: - matrix: - include: - - runner: ubuntu-20.04 - config: clang - cc: clang - - runner: ubuntu-20.04 - config: gcc - cc: gcc - - runner: ubuntu-18.04 - config: gcc - cc: gcc-4.8 - - runner: ubuntu-18.04 - config: clang - cc: clang-3.9 - - runner: macOS-10.15 - config: clang - cc: clang - runs-on: ${{ matrix.runner }} - steps: - - - uses: actions/checkout@v2 - - - name: Install dependencies (Linux) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install g++ gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev - - - name: Install gcc-4.8 - if: matrix.cc == 'gcc-4.8' - run: | - sudo apt-get install g++-4.8 - - - name: Install clang-3.9 - if: matrix.cc == 'clang-3.9' - run: | - sudo apt-get install clang-3.9 - - - name: Install dependencies (macOS) - if: runner.os == 'macOS' - run: | - brew install bison gawk libffi pkg-config bash - - - name: Setup environment (Linux) - if: runner.os == 'Linux' - run: | - echo "procs=$(nproc)" >> $GITHUB_ENV - - - name: Setup environment (macOS) - if: runner.os == 'macOS' - run: | - echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH - echo "procs=$(sysctl -n hw.ncpu)" >> $GITHUB_ENV - - - name: Get iverilog - run: | - git clone git://github.com/steveicarus/iverilog.git - - - name: Cache iverilog - id: cache-iverilog - uses: actions/cache@v2 - with: - path: iverilog-bin - key: ${{ matrix.runner }}-${{ hashFiles('iverilog/.git/refs/heads/master') }} - - - name: Build iverilog - if: steps.cache-iverilog.outputs.cache-hit != 'true' - run: | - mkdir iverilog-bin - cd iverilog - autoconf - CC=gcc CXX=g++ ./configure --prefix=$PWD/../iverilog-bin - make -j${{ env.procs }} - make install - - - name: Build yosys - run: | - ${{ matrix.cc }} --version - make config-${{ matrix.config }} - make -j${{ env.procs }} CC=${{ matrix.cc }} CXX=${{ matrix.cc }} LD=${{ matrix.cc }} - - - name: Run tests - run: | - PATH=$PWD/iverilog-bin/bin:$PATH make -j${{ env.procs }} test CC=${{ matrix.cc }} CXX=${{ matrix.cc }} LD=${{ matrix.cc }} diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index c6f4da30d25..c2a1756e9c6 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -10,15 +10,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Take last commit id: log - run: echo "::set-output name=message::$(git log --no-merges -1 --oneline)" + run: echo "message=$(git log --no-merges -1 --oneline)" >> $GITHUB_OUTPUT - name: Take repository id: repo - run: echo "::set-output name=message::$GITHUB_REPOSITORY" + run: echo "message=$GITHUB_REPOSITORY" >> $GITHUB_OUTPUT - name: Bump version if: "!contains(steps.log.outputs.message, 'Bump version') && contains(steps.repo.outputs.message, 'YosysHQ/yosys')" run: | diff --git a/.github/workflows/vs.yml b/.github/workflows/vs.yml index a48821cf803..428770e7200 100644 --- a/.github/workflows/vs.yml +++ b/.github/workflows/vs.yml @@ -6,25 +6,19 @@ jobs: yosys-vcxsrc: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Cache sources - id: cache-sources - uses: actions/cache@v2 - with: - path: . - key: cache-yosys + - uses: actions/checkout@v3 - name: Build run: make vcxsrc YOSYS_VER=latest - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: vcxsrc path: yosys-win32-vcxsrc-latest.zip build: - runs-on: windows-latest + runs-on: windows-2019 needs: yosys-vcxsrc steps: - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v3 with: name: vcxsrc path: . diff --git a/.gitignore b/.gitignore index 0460c7c1339..49b886e7e43 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,9 @@ __pycache__ /yosys-smtbmc /yosys-smtbmc.exe /yosys-smtbmc-script.py +/yosys-witness +/yosys-witness.exe +/yosys-witness-script.py /yosys-filterlib /yosys-filterlib.exe /kernel/*.pyh diff --git a/CHANGELOG b/CHANGELOG index 6948ff441aa..a461564081e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,75 +2,529 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.29 .. Yosys 0.30 +-------------------------- + * New commands and options + - Added "recover_names" pass to recover names post-mapping. + + * Gowin support + - Added remaining primitives blackboxes. + + * Various + - "show -colorattr" will now color the cells, wires, and + connection arrows. + - "show -viewer none" will not execute viewer. + +Yosys 0.28 .. Yosys 0.29 +-------------------------- + * New commands and options + - Added "synthprop" pass for synthesizable properties. + + * Verific support + - Handle conditions on clocked concurrent assertions in unclocked + procedural contexts. + + * Verilog + - Fix const eval of unbased unsized constants. + - Handling of attributes for struct / union variables. + +Yosys 0.27 .. Yosys 0.28 +-------------------------- + * Verilog + - Out of bounds checking for struct/union members. + + * Verific support + - Fix enum_values support and signed attribute values. + + * ECP5 support + - Added "synth_ecp5 -iopad" + + * MachXO2 support + - Added "synth_machxo2 -ccu2" + +Yosys 0.26 .. Yosys 0.27 +-------------------------- + * New commands and options + - Added option "-make_assert" to "equiv_make" pass. + - Added option "-coverenable" to "chformal" pass. + + * Verilog + - Resolve package types in interfaces. + - Handle range offsets in packed arrays within packed structs. + - Support for data and array queries on struct/union item expressions. + + * GateMate support + - Enable register initialization. + +Yosys 0.25 .. Yosys 0.26 +-------------------------- + * New commands and options + - Added "bwmuxmap" pass to replace $bwmux cells with equivalent logic. + - Added "xprop" experimental pass for formal x propagation. + - Added "splitcells" pass to split up multi-bit cells. + - Added "viz" pass to visualize data flow graph. + - Added option "-make_cover" to "miter" pass. + - Added option "-noparallelcase" to "write_verilog" pass. + - Added option "-chain" to "insbuf" pass. + - Added options "-hierarchy" and "-assume" to "formalff" pass. + - Added options "-append" and "-summary" to "sim" pass. + - Added option "-ywmap" to "write_btor" pass. + - Added option "-ignore-self-reset" to "fsm_detect" pass. + + * Verilog + - Support for struct members of union type. + - Support for struct member package types. + + * Various + - Added Yosys witness (.yw) cosimulation. + - GCC 4.8 is deprecated, compiler with full C++11 support is required. + +Yosys 0.24 .. Yosys 0.25 +-------------------------- + * Verific support + - Respect "noblackbox" attribute for modules. + + * Various + - Documentation is hosted at https://yosyshq.readthedocs.io/projects/yosys/en/latest/ + +Yosys 0.23 .. Yosys 0.24 +-------------------------- + * New commands and options + - Added option "-set-def-formal" to "sat" pass. + - Added option "-s" to "tee" command. + + * Verilog + - Support for module-scoped identifiers referring to tasks and functions. + - Support for arrays with swapped ranges within structs. + + * Verific support + - Support for importing verilog configurations per name. + - "verific -set-XXXXX" commands are now able to set severity to all messages + of certain type (errors, warnings, infos and comments) + + * Various + - TCL shell support (use "yosys -C") + - Added FABulous eFPGA frontend + +Yosys 0.22 .. Yosys 0.23 +-------------------------- + * New commands and options + - Added option "-cross" to "miter" pass. + - Added option "-nocheck" to "equiv_opt" pass. + + * Formal Verification + - yosys-smtbmc: Added "--detect-loops" option for checking if states are + unique in temporal induction counter examples. + + * Verific support + - Added support for reading Liberty files using Verific library. + (Optinally enabled with ENABLE_VERIFIC_LIBERTY) + - Added option "-cells" to "verific -import" enabling import of + all cells from verific design. + + * Various + - MinGW build (Windows) plugin support. + - Added YOSYS_ABORT_ON_LOG_ERROR environment variable for debugging. + Setting it to 1 causes abort() to be called when Yosys terminates with an + error message. + +Yosys 0.21 .. Yosys 0.22 +-------------------------- + * Verific support + - Added support for here-document for "verific" command (for reading + source files). + - Added support for reading EDIF files using Verific library. + (Optinally enabled with ENABLE_VERIFIC_EDIF) + + * Various + - Added tech specific utilization to "stat" json. + +Yosys 0.20 .. Yosys 0.21 +-------------------------- + * New commands and options + - Added "formalff" pass - transforms FFs for formal verification + - Added option "-formal" to "memory_map" pass + - Added option "-witness" to "rename" - give public names to all signals + present in yosys witness traces + - Added option "-hdlname" to "sim" pass - preserves hiearachy when writing + simulation output for a flattened design + - Addded option "-scramble-name" to "rename" pass + + * Formal Verification + - Added $anyinit cell to directly represent FFs with an unconstrained + initialization value. These can be generated by the new formalff pass. + - New JSON based yosys witness format for formal verification traces. + - yosys-smtbmc: Reading and writing of yosys witness traces. + - write_smt2: Emit inline metadata to support yosys witness trace. + - yosys-witness is a new tool to inspect and convert yosys witness traces. + - write_aiger: Option to write a map file for yosys witness trace + conversion. + - yosys-witness: Conversion from and to AIGER witness traces. + + * Verific support + - Filename re-writing support for "verific" pass. + + * Various + - ABC performance improvements + - Filename re-writing added for "show -lib". + + * SmartFusion2 support + - Added $alu support + - Added SYSRESET and XTLOSC cells + - Compatible now with LiberoSoc flow -Yosys 0.9 .. Yosys 0.9-dev +Yosys 0.19 .. Yosys 0.20 -------------------------- + * New commands and options + - Added option "-wb" to "read_liberty" pass + + * Various + - Added support for $modfloor operator to cxxrtl backend + - Support build on OpenBSD + - Fixed smt2 backend use of $shift/$shiftx with negative shift amounts, + which affects bit/part-select assignments with a dynamic index. Shift + operators were not affected. + + * Verific support + - Proper import of port ranges into Yosys, may result in reversed + bit-order of top-level ports for some synthesis flows. + +Yosys 0.18 .. Yosys 0.19 +-------------------------- + * New commands and options + - Added option "-rom-only" to "memory_libmap" pass + - Added option "-smtcheck" to "hierarchy" pass + - Added option "-keepdc" to "memory_libmap" pass + - Added option "-suffix" to "rename" pass + - Added "gatemate_foldinv" pass + + * Formal Verification + - Added support for $pos cell in btor backend + - Added the "smtlib2_module" and "smtlib2_comb_expr" attributes + + * GateMate support + - Added LUT tree mapping + + * Verific support + - Added option "-pp" to "verific -import" +Yosys 0.17 .. Yosys 0.18 +-------------------------- * Various + - Migrated most flows to use memory_libmap based memory inference + + * New commands and options + - Added "memory_libmap" pass + - Added "memory_bmux2rom" pass - converts muxes to ROMs + - Added "memory_dff -no-rw-check" + - Added "opt_ffinv" pass - push inverters through FFs + - Added "proc_rom" pass - convert switches to ROMs + - Added "proc -norom" option - will omit the proc_rom pass + - Added option "-no-rw-check" to synth passes + - Added "synth_ice40 -spram" option for automatic inference of SB_SPRAM256KA + - Added options "-nobram" and "-nolutram" to synth_machxo2 pass + + * Formal Verification + - Fixed the signedness of $past's return value to be the same as the + argument's instead of always unsigned. + + * Verilog + - Fixed an issue where simplifying case statements by removing unreachable + cases could result in the wrong signedness being used for comparison with + the remaining cases + - Fixed size and signedness computation for expressions containing array + querying functions + - Fixed size and signedness computation of functions used in ternary + expressions or case item expressions + + * Verific support + - Proper file location for readmem commands + - Added "-vlog-libext" option to specify search extension for libraries + +Yosys 0.16 .. Yosys 0.17 +-------------------------- + * New commands and options + - Added "write_jny" ( JSON netlist metadata format ) + - Added "tribuf -formal" + + * SystemVerilog + - Fixed automatic `nosync` inference for local variables in `always_comb` + procedures not applying to nested blocks and blocks in functions + +Yosys 0.15 .. Yosys 0.16 +-------------------------- + * Various + - Added BTOR2 witness file co-simulation. + - Simulation calls external vcd2fst for VCD conversion. + - Added fst2tb pass - generates testbench for the circuit using + the given top-level module and simulus signal from FST file. + - yosys-smtbmc: Option to keep going after failed assertions in BMC mode + + * Verific support + - Import modules in alphabetic (reproducable) order. + +Yosys 0.14 .. Yosys 0.15 +-------------------------- + + * Various + - clk2fflogic: nice names for autogenerated signals + - simulation include support for all flip-flop types. + - Added AIGER witness file co-simulation. + + * Verilog + - Fixed evaluation of constant functions with variables or arguments with + reversed dimensions + - Fixed elaboration of dynamic range assignments where the vector is + reversed or is not zero-indexed + - Added frontend support for time scale delay values (e.g., `#1ns`) + + * SystemVerilog + - Added support for accessing whole sub-structures in expressions + + * New commands and options + - Added glift command, used to create gate-level information flow tracking + (GLIFT) models by the "constructive mapping" approach + + * Verific support + - Ability to override default parser mode for verific -f command. + +Yosys 0.13 .. Yosys 0.14 +-------------------------- + + * Various + - Added $bmux and $demux cells and related optimization patterns. + + * New commands and options + - Added "bmuxmap" and "dmuxmap" passes + - Added "-fst" option to "sim" pass for writing FST files + - Added "-r", "-scope", "-start", "-stop", "-at", "-sim", "-sim-gate", + "-sim-gold" options to "sim" pass for co-simulation + + * Anlogic support + - Added support for BRAMs + +Yosys 0.12 .. Yosys 0.13 +-------------------------- + + * Various + - Use "read" command to parse HDL files from Yosys command-line + - Added "yosys -r " command line option + - write_verilog: dump zero width sigspecs correctly + + * SystemVerilog + - Fixed regression preventing the use array querying functions in case + expressions and case item expressions + - Fixed static size casts inadvertently limiting the result width of binary + operations + - Fixed static size casts ignoring expression signedness + - Fixed static size casts not extending unbased unsized literals + - Added automatic `nosync` inference for local variables in `always_comb` + procedures which are always assigned before they are used to avoid errant + latch inference + + * New commands and options + - Added "clean_zerowidth" pass + + * Verific support + - Add YOSYS to the implicitly defined verilog macros in verific + +Yosys 0.11 .. Yosys 0.12 +-------------------------- + + * Various + - Added iopadmap native support for negative-polarity output enable + - ABC update + + * SystemVerilog + - Support parameters using struct as a wiretype + + * New commands and options + - Added "-genlib" option to "abc" pass + - Added "sta" very crude static timing analysis pass + + * Verific support + - Fixed memory block size in import + + * New back-ends + - Added support for GateMate FPGA from Cologne Chip AG + + * Intel ALM support + - Added preliminary Arria V support + + +Yosys 0.10 .. Yosys 0.11 +-------------------------- + + * Various + - Added $aldff and $aldffe (flip-flops with async load) cells + + * SystemVerilog + - Fixed an issue which prevented writing directly to a memory word via a + connection to an output port + - Fixed an issue which prevented unbased unsized literals (e.g., `'1`) from + filling the width of a cell input + - Fixed an issue where connecting a slice covering the entirety of a signed + signal to a cell input would cause a failed assertion + + * Verific support + - Importer support for {PRIM,WIDE_OPER}_DFF + - Importer support for PRIM_BUFIF1 + - Option to use Verific without VHDL support + - Importer support for {PRIM,WIDE_OPER}_DLATCH{,RS} + - Added -cfg option for getting/setting Verific runtime flags + +Yosys 0.9 .. Yosys 0.10 +-------------------------- + + * Various + - Added automatic gzip decompression for frontends + - Added $_NMUX_ cell type + - Added automatic gzip compression (based on filename extension) for backends + - Improve attribute and parameter encoding in JSON to avoid ambiguities between + bit vectors and strings containing [01xz]* + - Improvements in pmgen: subpattern and recursive matches + - Support explicit FIRRTL properties + - Improvements in pmgen: slices, choices, define, generate + - Added "_TECHMAP_WIREINIT_*_" parameter and "_TECHMAP_REMOVEINIT_*_" wire for "techmap" pass + - Added +/mul2dsp.v for decomposing wide multipliers to custom-sized ones + - Added new frontend: rpc + - Added --version and -version as aliases for -V + - Improve yosys-smtbmc "solver not found" handling + - Improved support of $readmem[hb] Memory Content File inclusion + - Added CXXRTL backend + - Use YosysHQ/abc instead of upstream berkeley-abc/abc + - Added WASI platform support. + - Added extmodule support to firrtl backend + - Added $divfloor and $modfloor cells + - Added $adffe, $dffsre, $sdff, $sdffe, $sdffce, $adlatch cells + - Added "_TECHMAP_CELLNAME_" parameter for "techmap" pass + - Added firrtl backend support for generic parameters in blackbox components + - Added $meminit_v2 cells (with support for write mask) + - Added $mem_v2, $memrd_v2, $memwr_v2, with the following features: + - write priority masks, per write/write port pair + - transparency and undefined collision behavior masks, per read/write port pair + - read port reset and initialization + - wide ports (accessing a naturally aligned power-of-two number of memory cells) + + * New commands and options - Added "write_xaiger" backend + - Added "read_xaiger" - Added "abc9" pass for timing-aware techmapping (experimental, FPGA only) - - Added "synth_xilinx -abc9" (experimental) - - Added "synth_ice40 -abc9" (experimental) - Added "synth -abc9" (experimental) - Added "script -scriptwire" + - Added "clkbufmap" pass + - Added "extractinv" pass and "invertible_pin" attribute + - Added "proc_clean -quiet" + - Added "proc_prune" pass + - Added "stat -tech cmos" + - Added "opt_share" pass, run as part of "opt -full" + - Added "-match-init" option to "dff2dffs" pass + - Added "equiv_opt -multiclock" + - Added "techmap_autopurge" support to techmap + - Added "add -mod " + - Added "paramap" pass + - Added "portlist" command + - Added "check -mapped" + - Added "check -allow-tbuf" + - Added "autoname" pass + - Added "write_verilog -extmem" + - Added "opt_mem" pass + - Added "scratchpad" pass + - Added "fminit" pass + - Added "opt_lut_ins" pass + - Added "logger" pass + - Added "show -nobg" + - Added "exec" command + - Added "design -delete" + - Added "design -push-copy" + - Added "qbfsat" command + - Added "select -unset" + - Added "dfflegalize" pass + - Removed "opt_expr -clkinv" option, made it the default + - Added "proc -nomux + - Merged "dffsr2dff", "opt_rmdff", "dff2dffe", "dff2dffs", "peepopt.dffmux" passes into a new "opt_dff" pass + + * SystemVerilog + - Added checking of always block types (always_comb, always_latch and always_ff) + - Added support for wildcard port connections (.*) + - Added support for enum typedefs + - Added support for structs and packed unions. + - Allow constant function calls in for loops and generate if and case + - Added support for static cast + - Added support for logic typed parameters + - Fixed generate scoping issues + - Added support for real-valued parameters + - Allow localparams in constant functions + - Module name scope support + - Support recursive functions using ternary expressions + - Extended support for integer types + - Support for parameters without default values + - Allow globals in one file to depend on globals in another + - Added support for: *=, /=, %=, <<=, >>=, <<<=, >>>= + - Added support for parsing the 'bind' construct + - support declaration in procedural for initialization + - support declaration in generate for initialization + - Support wand and wor of data types + + * Verific support + - Added "verific -L" + - Add Verific SVA support for "always" properties + - Add Verific support for SVA nexttime properties + - Improve handling of verific primitives in "verific -import -V" mode + - Import attributes for wires + - Support VHDL enums + - Added support for command files + + * New back-ends + - Added initial EFINIX support + - Added Intel ALM: alternative synthesis for Intel FPGAs + - Added initial Nexus support + - Added initial MachXO2 support + - Added initial QuickLogic PolarPro 3 support + + * ECP5 support + - Renamed labels/options in synth_ecp5 (e.g. dram -> map_lutram; -nodram -> -nolutram) + - Added "synth_ecp5 -abc9" (experimental) + - Added "synth_ecp5 -nowidelut" + - "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental) + + * iCE40 support + - Added "synth_ice40 -abc9" (experimental) + - Added "synth_ice40 -device" + - Renamed labels/options in synth_ice40 (e.g. dram -> map_lutram; -nodram -> -nolutram) + - Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping + - Removed "ice40_unlut" + - Added "ice40_dsp" for Lattice iCE40 DSP packing + - "synth_ice40 -dsp" to infer DSP blocks + + * Xilinx support + - Added "synth_xilinx -abc9" (experimental) - Added "synth_xilinx -nocarry" - Added "synth_xilinx -nowidelut" - - Added "synth_ecp5 -nowidelut" - "synth_xilinx" to now infer wide multiplexers (-widemux to enable) - - Renamed labels/options in synth_ice40 (e.g. dram -> map_lutram; -nodram -> -nolutram) - - Renamed labels/options in synth_ecp5 (e.g. dram -> map_lutram; -nodram -> -nolutram) - - Renamed labels in synth_intel (e.g. bram -> map_bram) - Renamed labels/options in synth_xilinx (e.g. dram -> map_lutram; -nodram -> -nolutram) - - Added automatic gzip decompression for frontends - - Added $_NMUX_ cell type - - Added automatic gzip compression (based on filename extension) for backends - - Improve attribute and parameter encoding in JSON to avoid ambiguities between - bit vectors and strings containing [01xz]* - - Added "clkbufmap" pass - - Added "extractinv" pass and "invertible_pin" attribute - Added "synth_xilinx -family xc6s" for Spartan 6 support (experimental) - Added "synth_xilinx -ise" (experimental) - Added "synth_xilinx -iopad" - "synth_xilinx" now automatically inserts clock buffers (add -noclkbuf to disable) - - Improvements in pmgen: subpattern and recursive matches - - Added "opt_share" pass, run as part of "opt -full" - - Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping - - Removed "ice40_unlut" - - Improvements in pmgen: slices, choices, define, generate - Added "xilinx_srl" for Xilinx shift register extraction - Removed "shregmap -tech xilinx" (superseded by "xilinx_srl") - - Added "_TECHMAP_WIREINIT_*_" parameter and "_TECHMAP_REMOVEINIT_*_" wire for "techmap" pass - - Added "-match-init" option to "dff2dffs" pass - - Added "techmap_autopurge" support to techmap - - Added "add -mod " - - Added +/mul2dsp.v for decomposing wide multipliers to custom-sized ones - - Added "ice40_dsp" for Lattice iCE40 DSP packing - Added "xilinx_dsp" for Xilinx DSP packing - "synth_xilinx" to now infer DSP blocks (-nodsp to disable) - - "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental) - - "synth_ice40 -dsp" to infer DSP blocks - Added latch support to synth_xilinx - Added support for flip-flops with synchronous reset to synth_xilinx - Added support for flip-flops with reset and enable to synth_xilinx - - Added "check -mapped" - - Added checking of SystemVerilog always block types (always_comb, - always_latch and always_ff) - - Added support for SystemVerilog wildcard port connections (.*) - Added "xilinx_dffopt" pass - - Added "scratchpad" pass - Added "synth_xilinx -dff" - - Improved support of $readmem[hb] Memory Content File inclusion - - Added "opt_lut_ins" pass - - Added "logger" pass - - Added "design -delete" - - Added "select -unset" - - Use YosysHQ/abc instead of upstream berkeley-abc/abc - - Added $divfloor and $modfloor cells - - Added $adffe, $dffsre, $sdff, $sdffe, $sdffce, $adlatch cells - - Added "dfflegalize" pass - - Added "_TECHMAP_CELLNAME_" parameter for "techmap" pass - - Merged "dffsr2dff", "opt_rmdff", "dff2dffe", "dff2dffs", "peepopt.dffmux" passes into a new "opt_dff" pass - - Added $meminit_v2 cells (with support for write mask) + + * Intel support + - Renamed labels in synth_intel (e.g. bram -> map_bram) + - synth_intel: cyclone10 -> cyclone10lp, a10gx -> arria10gx + - Added "intel_alm -abc9" (experimental) + + * CoolRunner2 support + - Separate and improve buffer cell insertion pass + - Use extract_counter to optimize counters Yosys 0.8 .. Yosys 0.9 ---------------------- diff --git a/CODEOWNERS b/CODEOWNERS index 0c92691f4ae..a33a9a68ccb 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -16,7 +16,7 @@ backends/cxxrtl/ @whitequark passes/cmds/bugpoint.cc @whitequark passes/techmap/flowmap.cc @whitequark passes/opt/opt_lut.cc @whitequark -passes/techmap/abc9*.cc @eddiehung +passes/techmap/abc9*.cc @eddiehung @Ravenslofty backends/aiger/xaiger.cc @eddiehung @@ -30,7 +30,9 @@ backends/aiger/xaiger.cc @eddiehung frontends/verilog/ @zachjs frontends/ast/ @zachjs -techlibs/intel_alm/ @ZirconiumX +techlibs/intel_alm/ @Ravenslofty +techlibs/gowin/ @pepijndevos +techlibs/gatemate/ @pu-cc # pyosys misc/*.py @btut @@ -40,4 +42,5 @@ backends/firrtl @ucbjrl @azidar passes/sat/qbfsat.cc @boqwxp passes/sat/qbfsat.h @boqwxp passes/cmds/exec.cc @boqwxp +passes/cmds/glift.cc @boqwxp passes/cmds/printattrs.cc @boqwxp diff --git a/Makefile b/Makefile index dc66291a45b..3ff983198a8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ CONFIG := clang # CONFIG := gcc -# CONFIG := gcc-4.8 # CONFIG := afl-gcc # CONFIG := emcc # CONFIG := wasi @@ -18,9 +17,12 @@ ENABLE_READLINE := 1 ENABLE_EDITLINE := 0 ENABLE_GHDL := 0 ENABLE_VERIFIC := 0 +ENABLE_VERIFIC_EDIF := 0 +ENABLE_VERIFIC_LIBERTY := 0 +DISABLE_VERIFIC_EXTENSIONS := 0 +DISABLE_VERIFIC_VHDL := 0 ENABLE_COVER := 1 ENABLE_LIBYOSYS := 0 -ENABLE_PROTOBUF := 0 ENABLE_ZLIB := 1 # python wrappers @@ -54,6 +56,9 @@ PROGRAM_PREFIX := OS := $(shell uname -s) PREFIX ?= /usr/local INSTALL_SUDO := +ifneq ($(filter MINGW%,$(OS)),) +OS := MINGW +endif ifneq ($(wildcard Makefile.conf),) include Makefile.conf @@ -85,9 +90,17 @@ all: top-all YOSYS_SRC := $(dir $(firstword $(MAKEFILE_LIST))) VPATH := $(YOSYS_SRC) +CXXSTD ?= c++11 CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include LDLIBS := $(LDLIBS) -lstdc++ -lm PLUGIN_LDFLAGS := +PLUGIN_LDLIBS := +EXE_LDFLAGS := +ifeq ($(OS), MINGW) +EXE_LDFLAGS := -Wl,--export-all-symbols -Wl,--out-implib,libyosys_exe.a +PLUGIN_LDFLAGS += -L"$(LIBDIR)" +PLUGIN_LDLIBS := -lyosys_exe +endif PKG_CONFIG ?= pkg-config SED ?= sed @@ -123,15 +136,28 @@ endif else LDFLAGS += -rdynamic +ifneq ($(OS), OpenBSD) LDLIBS += -lrt endif +endif + +YOSYS_VER := 0.30 + +# Note: We arrange for .gitcommit to contain the (short) commit hash in +# tarballs generated with git-archive(1) using .gitattributes. The git repo +# will have this file in its unexpanded form tough, in which case we fall +# back to calling git directly. +TARBALL_GIT_REV := $(shell cat $(YOSYS_SRC)/.gitcommit) +ifeq ($(TARBALL_GIT_REV),$$Format:%h$$) +GIT_REV := $(shell GIT_DIR=$(YOSYS_SRC)/.git git rev-parse --short=9 HEAD || echo UNKNOWN) +else +GIT_REV := $(TARBALL_GIT_REV) +endif -YOSYS_VER := 0.9+4254 -GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 8a4c6e6.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 9c5a60e.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # @@ -139,10 +165,10 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 4f5f73d +ABCREV = 2c1c83f ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc -ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 VERBOSE=$(Q) +ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) # set ABCEXTERNAL = to use an external ABC instance # Note: The in-tree ABC (yosys-abc) will not be installed when ABCEXTERNAL is set. @@ -183,11 +209,16 @@ endif endif +ABC_ARCHFLAGS = "" +ifeq ($(OS), OpenBSD) +ABC_ARCHFLAGS += "-DABC_NO_RLIMIT" +endif + ifeq ($(CONFIG),clang) CXX = clang LD = clang++ -CXXFLAGS += -std=c++11 -Os -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H" +CXXFLAGS += -std=$(CXXSTD) -Os +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -Wno-c++11-narrowing $(ABC_ARCHFLAGS)" ifneq ($(SANITIZER),) $(info [Clang Sanitizer] $(SANITIZER)) @@ -209,31 +240,25 @@ endif else ifeq ($(CONFIG),gcc) CXX = gcc LD = gcc -CXXFLAGS += -std=c++11 -Os -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H" +CXXFLAGS += -std=$(CXXSTD) -Os +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" else ifeq ($(CONFIG),gcc-static) LD = $(CXX) LDFLAGS := $(filter-out -rdynamic,$(LDFLAGS)) -static LDLIBS := $(filter-out -lrt,$(LDLIBS)) CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) -CXXFLAGS += -std=c++11 -Os +CXXFLAGS += -std=$(CXXSTD) -Os ABCMKARGS = CC="$(CC)" CXX="$(CXX)" LD="$(LD)" ABC_USE_LIBSTDCXX=1 LIBS="-lm -lpthread -static" OPTFLAGS="-O" \ ARCHFLAGS="-DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING=1 -Wno-unused-but-set-variable $(ARCHFLAGS)" ABC_USE_NO_READLINE=1 ifeq ($(DISABLE_ABC_THREADS),1) ABCMKARGS += "ABC_USE_NO_PTHREADS=1" endif -else ifeq ($(CONFIG),gcc-4.8) -CXX = gcc-4.8 -LD = gcc-4.8 -CXXFLAGS += -std=c++11 -Os -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H" - else ifeq ($(CONFIG),afl-gcc) CXX = AFL_QUIET=1 AFL_HARDEN=1 afl-gcc LD = AFL_QUIET=1 AFL_HARDEN=1 afl-gcc -CXXFLAGS += -std=c++11 -Os +CXXFLAGS += -std=$(CXXSTD) -Os ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H" else ifeq ($(CONFIG),cygwin) @@ -245,16 +270,17 @@ ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H" else ifeq ($(CONFIG),emcc) CXX = emcc LD = emcc -CXXFLAGS := -std=c++11 $(filter-out -fPIC -ggdb,$(CXXFLAGS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8" -EMCCFLAGS := -Os -Wno-warn-absolute-paths -EMCCFLAGS += --memory-init-file 0 --embed-file share -s NO_EXIT_RUNTIME=1 -EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg','_memset']" -EMCCFLAGS += -s TOTAL_MEMORY=134217728 -EMCCFLAGS += -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' +CXXFLAGS := -std=$(CXXSTD) $(filter-out -fPIC -ggdb,$(CXXFLAGS)) +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8 -Wno-c++11-narrowing" +EMCC_CXXFLAGS := -Os -Wno-warn-absolute-paths +EMCC_LDFLAGS := --memory-init-file 0 --embed-file share +EMCC_LDFLAGS += -s NO_EXIT_RUNTIME=1 +EMCC_LDFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg','_memset']" +EMCC_LDFLAGS += -s TOTAL_MEMORY=134217728 +EMCC_LDFLAGS += -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' # https://github.com/kripken/emscripten/blob/master/src/settings.js -CXXFLAGS += $(EMCCFLAGS) -LDFLAGS += $(EMCCFLAGS) +CXXFLAGS += $(EMCC_CXXFLAGS) +LDFLAGS += $(EMCC_LDFLAGS) LDLIBS = EXE = .js @@ -272,7 +298,7 @@ viz.js: wget -O viz.js.part https://github.com/mdaines/viz.js/releases/download/0.0.3/viz.js mv viz.js.part viz.js -yosysjs-$(YOSYS_VER).zip: yosys.js yosys.wasm viz.js misc/yosysjs/* +yosysjs-$(YOSYS_VER).zip: yosys.js viz.js misc/yosysjs/* rm -rf yosysjs-$(YOSYS_VER) yosysjs-$(YOSYS_VER).zip mkdir -p yosysjs-$(YOSYS_VER) cp viz.js misc/yosysjs/* yosys.js yosys.wasm yosysjs-$(YOSYS_VER)/ @@ -295,11 +321,11 @@ AR = $(WASI_SDK)/bin/ar RANLIB = $(WASI_SDK)/bin/ranlib WASIFLAGS := --sysroot $(WASI_SDK)/share/wasi-sysroot $(WASIFLAGS) endif -CXXFLAGS := $(WASIFLAGS) -std=c++11 -Os $(filter-out -fPIC,$(CXXFLAGS)) +CXXFLAGS := $(WASIFLAGS) -std=$(CXXSTD) -Os $(filter-out -fPIC,$(CXXFLAGS)) LDFLAGS := $(WASIFLAGS) -Wl,-z,stack-size=1048576 $(filter-out -rdynamic,$(LDFLAGS)) LDLIBS := $(filter-out -lrt,$(LDLIBS)) ABCMKARGS += AR="$(AR)" RANLIB="$(RANLIB)" -ABCMKARGS += ARCHFLAGS="$(WASIFLAGS) -DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING" +ABCMKARGS += ARCHFLAGS="$(WASIFLAGS) -DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING -DABC_NO_RLIMIT -Wno-c++11-narrowing" ABCMKARGS += OPTFLAGS="-Os" EXE = .wasm @@ -314,7 +340,7 @@ else ifeq ($(CONFIG),mxe) PKG_CONFIG = /usr/local/src/mxe/usr/bin/i686-w64-mingw32.static-pkg-config CXX = /usr/local/src/mxe/usr/bin/i686-w64-mingw32.static-g++ LD = /usr/local/src/mxe/usr/bin/i686-w64-mingw32.static-g++ -CXXFLAGS += -std=c++11 -Os -D_POSIX_SOURCE -DYOSYS_MXE_HACKS -Wno-attributes +CXXFLAGS += -std=$(CXXSTD) -Os -D_POSIX_SOURCE -DYOSYS_MXE_HACKS -Wno-attributes CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) LDFLAGS := $(filter-out -rdynamic,$(LDFLAGS)) -s LDLIBS := $(filter-out -lrt,$(LDLIBS)) @@ -326,7 +352,7 @@ EXE = .exe else ifeq ($(CONFIG),msys2-32) CXX = i686-w64-mingw32-g++ LD = i686-w64-mingw32-g++ -CXXFLAGS += -std=c++11 -Os -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR +CXXFLAGS += -std=$(CXXSTD) -Os -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) LDFLAGS := $(filter-out -rdynamic,$(LDFLAGS)) -s LDLIBS := $(filter-out -lrt,$(LDLIBS)) @@ -337,7 +363,7 @@ EXE = .exe else ifeq ($(CONFIG),msys2-64) CXX = x86_64-w64-mingw32-g++ LD = x86_64-w64-mingw32-g++ -CXXFLAGS += -std=c++11 -Os -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR +CXXFLAGS += -std=$(CXXSTD) -Os -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) LDFLAGS := $(filter-out -rdynamic,$(LDFLAGS)) -s LDLIBS := $(filter-out -lrt,$(LDLIBS)) @@ -346,7 +372,7 @@ ABCMKARGS += LIBS="-lpthread -s" ABC_USE_NO_READLINE=0 CC="x86_64-w64-mingw32-gc EXE = .exe else ifneq ($(CONFIG),none) -$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, gcc-4.8, emcc, mxe, msys2-32, msys2-64) +$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, emcc, mxe, msys2-32, msys2-64) endif ifeq ($(ENABLE_LIBYOSYS),1) @@ -380,7 +406,7 @@ endif # ENABLE_PYOSYS ifeq ($(ENABLE_READLINE),1) CXXFLAGS += -DYOSYS_ENABLE_READLINE -ifeq ($(OS), FreeBSD) +ifeq ($(OS), $(filter $(OS),FreeBSD OpenBSD NetBSD)) CXXFLAGS += -I/usr/local/include endif LDLIBS += -lreadline @@ -414,8 +440,11 @@ endif ifeq ($(ENABLE_PLUGINS),1) CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags libffi) -DYOSYS_ENABLE_PLUGINS +ifeq ($(OS), MINGW) +CXXFLAGS += -Ilibs/dlfcn-win32 +endif LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs libffi || echo -lffi) -ifneq ($(OS), FreeBSD) +ifneq ($(OS), $(filter $(OS),FreeBSD OpenBSD NetBSD MINGW)) LDLIBS += -ldl endif endif @@ -432,10 +461,13 @@ endif ifeq ($(ENABLE_TCL),1) TCL_VERSION ?= tcl$(shell bash -c "tclsh <(echo 'puts [info tclversion]')") -ifeq ($(OS), FreeBSD) +ifeq ($(OS), $(filter $(OS),FreeBSD OpenBSD NetBSD)) +# BSDs usually use tcl8.6, but the lib is named "libtcl86" TCL_INCLUDE ?= /usr/local/include/$(TCL_VERSION) +TCL_LIBS ?= -l$(subst .,,$(TCL_VERSION)) else TCL_INCLUDE ?= /usr/include/$(TCL_VERSION) +TCL_LIBS ?= -l$(TCL_VERSION) endif ifeq ($(CONFIG),mxe) @@ -443,12 +475,7 @@ CXXFLAGS += -DYOSYS_ENABLE_TCL LDLIBS += -ltcl86 -lwsock32 -lws2_32 -lnetapi32 -lz -luserenv else CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags tcl || echo -I$(TCL_INCLUDE)) -DYOSYS_ENABLE_TCL -ifeq ($(OS), FreeBSD) -# FreeBSD uses tcl8.6, but lib is named "libtcl86" -LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs tcl || echo -l$(TCL_VERSION) | tr -d '.') -else -LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs tcl || echo -l$(TCL_VERSION)) -endif +LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs tcl || echo $(TCL_LIBS)) endif endif @@ -498,7 +525,27 @@ endif ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib -VERIFIC_COMPONENTS ?= verilog vhdl database util containers hier_tree extensions +VERIFIC_COMPONENTS ?= verilog database util containers hier_tree +ifneq ($(DISABLE_VERIFIC_VHDL),1) +VERIFIC_COMPONENTS += vhdl +CXXFLAGS += -DVERIFIC_VHDL_SUPPORT +else +ifneq ($(wildcard $(VERIFIC_DIR)/vhdl),) +VERIFIC_COMPONENTS += vhdl +endif +endif +ifeq ($(ENABLE_VERIFIC_EDIF),1) +VERIFIC_COMPONENTS += edif +CXXFLAGS += -DVERIFIC_EDIF_SUPPORT +endif +ifeq ($(ENABLE_VERIFIC_LIBERTY),1) +VERIFIC_COMPONENTS += synlib +CXXFLAGS += -DVERIFIC_LIBERTY_SUPPORT +endif +ifneq ($(DISABLE_VERIFIC_EXTENSIONS),1) +VERIFIC_COMPONENTS += extensions +CXXFLAGS += -DYOSYSHQ_VERIFIC_EXTENSIONS +endif CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -DYOSYS_ENABLE_VERIFIC ifeq ($(OS), Darwin) LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-mac.a,$(VERIFIC_COMPONENTS)) -lz @@ -507,9 +554,6 @@ LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) -lz endif endif -ifeq ($(ENABLE_PROTOBUF),1) -LDLIBS += $(shell pkg-config --cflags --libs protobuf) -endif ifeq ($(ENABLE_COVER),1) CXXFLAGS += -DYOSYS_ENABLE_COVER @@ -565,6 +609,7 @@ $(eval $(call add_include_file,kernel/yosys.h)) $(eval $(call add_include_file,kernel/hashlib.h)) $(eval $(call add_include_file,kernel/log.h)) $(eval $(call add_include_file,kernel/rtlil.h)) +$(eval $(call add_include_file,kernel/binding.h)) $(eval $(call add_include_file,kernel/register.h)) $(eval $(call add_include_file,kernel/celltypes.h)) $(eval $(call add_include_file,kernel/celledges.h)) @@ -578,13 +623,20 @@ $(eval $(call add_include_file,kernel/satgen.h)) $(eval $(call add_include_file,kernel/qcsat.h)) $(eval $(call add_include_file,kernel/ff.h)) $(eval $(call add_include_file,kernel/ffinit.h)) +ifeq ($(ENABLE_ZLIB),1) +$(eval $(call add_include_file,kernel/fstdata.h)) +endif $(eval $(call add_include_file,kernel/mem.h)) $(eval $(call add_include_file,libs/ezsat/ezsat.h)) $(eval $(call add_include_file,libs/ezsat/ezminisat.h)) +ifeq ($(ENABLE_ZLIB),1) +$(eval $(call add_include_file,libs/fst/fstapi.h)) +endif $(eval $(call add_include_file,libs/sha1/sha1.h)) $(eval $(call add_include_file,libs/json11/json11.hpp)) $(eval $(call add_include_file,passes/fsm/fsmdata.h)) $(eval $(call add_include_file,frontends/ast/ast.h)) +$(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)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl.h)) @@ -595,12 +647,21 @@ $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.cc)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.h)) OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o +OBJS += kernel/binding.o ifeq ($(ENABLE_ABC),1) ifneq ($(ABCEXTERNAL),) kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' endif endif -OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o +OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o +ifeq ($(ENABLE_ZLIB),1) +OBJS += kernel/fstdata.o +endif +ifeq ($(ENABLE_PLUGINS),1) +ifeq ($(OS), MINGW) +OBJS += libs/dlfcn-win32/dlfcn.o +endif +endif kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"' @@ -624,6 +685,12 @@ OBJS += libs/minisat/SimpSolver.o OBJS += libs/minisat/Solver.o OBJS += libs/minisat/System.o +ifeq ($(ENABLE_ZLIB),1) +OBJS += libs/fst/fstapi.o +OBJS += libs/fst/fastlz.o +OBJS += libs/fst/lz4.o +endif + include $(YOSYS_SRC)/frontends/*/Makefile.inc include $(YOSYS_SRC)/passes/*/Makefile.inc include $(YOSYS_SRC)/backends/*/Makefile.inc @@ -673,7 +740,7 @@ yosys.js: $(filter-out yosysjs-$(YOSYS_VER).zip,$(EXTRA_TARGETS)) endif $(PROGRAM_PREFIX)yosys$(EXE): $(OBJS) - $(P) $(LD) -o $(PROGRAM_PREFIX)yosys$(EXE) $(LDFLAGS) $(OBJS) $(LDLIBS) + $(P) $(LD) -o $(PROGRAM_PREFIX)yosys$(EXE) $(EXE_LDFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) libyosys.so: $(filter-out kernel/driver.o,$(OBJS)) ifeq ($(OS), Darwin) @@ -716,8 +783,8 @@ LDLIBS_NOVERIFIC = $(LDLIBS) endif $(PROGRAM_PREFIX)yosys-config: misc/yosys-config.in - $(P) $(SED) -e 's#@CXXFLAGS@#$(subst -I. -I"$(YOSYS_SRC)",-I"$(DATDIR)/include",$(strip $(CXXFLAGS_NOVERIFIC)))#;' \ - -e 's#@CXX@#$(strip $(CXX))#;' -e 's#@LDFLAGS@#$(strip $(LDFLAGS) $(PLUGIN_LDFLAGS))#;' -e 's#@LDLIBS@#$(strip $(LDLIBS_NOVERIFIC))#;' \ + $(P) $(SED) -e 's#@CXXFLAGS@#$(subst -Ilibs/dlfcn-win32,,$(subst -I. -I"$(YOSYS_SRC)",-I"$(DATDIR)/include",$(strip $(CXXFLAGS_NOVERIFIC))))#;' \ + -e 's#@CXX@#$(strip $(CXX))#;' -e 's#@LDFLAGS@#$(strip $(LDFLAGS) $(PLUGIN_LDFLAGS))#;' -e 's#@LDLIBS@#$(strip $(LDLIBS_NOVERIFIC) $(PLUGIN_LDLIBS))#;' \ -e 's#@BINDIR@#$(strip $(BINDIR))#;' -e 's#@DATDIR@#$(strip $(DATDIR))#;' < $< > $(PROGRAM_PREFIX)yosys-config $(Q) chmod +x $(PROGRAM_PREFIX)yosys-config @@ -727,11 +794,16 @@ ifneq ($(ABCREV),default) $(Q) if test -d abc/.hg; then \ echo 'REEBE: NOP qverpgbel vf n ut jbexvat pbcl! Erzbir nop/ naq er-eha "znxr".' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; false; \ fi - $(Q) if test -d abc && ! git -C abc diff-index --quiet HEAD; then \ + $(Q) if test -d abc && test -d abc/.git && ! git -C abc diff-index --quiet HEAD; then \ echo 'REEBE: NOP pbagnvaf ybpny zbqvsvpngvbaf! Frg NOPERI=qrsnhyg va Lbflf Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; false; \ fi + $(Q) if test -d abc && ! test -d abc/.git && ! test "`cat abc/.gitcommit | cut -c1-7`" = "$(ABCREV)"; then \ + echo 'REEBE: Qbjaybnqrq NOP irefvbaf qbrf abg zngpu! Qbjaybnq sebz:' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; echo $(ABCURL)/archive/$(ABCREV).tar.gz; false; \ + fi # set a variable so the test fails if git fails to run - when comparing outputs directly, empty string would match empty string - $(Q) if ! (cd abc 2> /dev/null && rev="`git rev-parse $(ABCREV)`" && test "`git rev-parse HEAD`" == "$$rev"); then \ + $(Q) if test -d abc && ! test -d abc/.git && test "`cat abc/.gitcommit | cut -c1-7`" = "$(ABCREV)"; then \ + echo "Compiling local copy of ABC"; \ + elif ! (cd abc 2> /dev/null && rev="`git rev-parse $(ABCREV)`" && test "`git rev-parse HEAD`" = "$$rev"); then \ test $(ABCPULL) -ne 0 || { echo 'REEBE: NOP abg hc gb qngr naq NOPCHYY frg gb 0 va Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; exit 1; }; \ echo "Pulling ABC from $(ABCURL):"; set -x; \ test -d abc || git clone $(ABCURL) abc; \ @@ -765,6 +837,9 @@ ABCOPT="" endif test: $(TARGETS) $(EXTRA_TARGETS) +ifeq ($(ENABLE_VERIFIC),1) + +cd tests/verific && bash run-test.sh $(SEEDOPT) +endif +cd tests/simple && bash run-test.sh $(SEEDOPT) +cd tests/simple_abc9 && bash run-test.sh $(SEEDOPT) +cd tests/hana && bash run-test.sh $(SEEDOPT) @@ -775,10 +850,12 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/fsm && bash run-test.sh $(SEEDOPT) +cd tests/techmap && bash run-test.sh +cd tests/memories && bash run-test.sh $(ABCOPT) $(SEEDOPT) + +cd tests/memlib && bash run-test.sh $(SEEDOPT) +cd tests/bram && bash run-test.sh $(SEEDOPT) +cd tests/various && bash run-test.sh +cd tests/select && bash run-test.sh +cd tests/sat && bash run-test.sh + +cd tests/sim && bash run-test.sh +cd tests/svinterfaces && bash run-test.sh $(SEEDOPT) +cd tests/svtypes && bash run-test.sh $(SEEDOPT) +cd tests/proc && bash run-test.sh @@ -796,9 +873,11 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/arch/intel_alm && bash run-test.sh $(SEEDOPT) +cd tests/arch/nexus && bash run-test.sh $(SEEDOPT) +cd tests/arch/quicklogic && bash run-test.sh $(SEEDOPT) + +cd tests/arch/gatemate && bash run-test.sh $(SEEDOPT) +cd tests/rpc && bash run-test.sh +cd tests/memfile && bash run-test.sh +cd tests/verilog && bash run-test.sh + +cd tests/xprop && bash run-test.sh $(SEEDOPT) @echo "" @echo " Passed \"make test\"." @echo "" @@ -857,6 +936,12 @@ ifeq ($(ENABLE_PYOSYS),1) $(INSTALL_SUDO) cp misc/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/ endif endif +ifeq ($(ENABLE_PLUGINS),1) +ifeq ($(OS), MINGW) + $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(LIBDIR) + $(INSTALL_SUDO) cp libyosys_exe.a $(DESTDIR)$(LIBDIR)/ +endif +endif uninstall: $(INSTALL_SUDO) rm -vf $(addprefix $(DESTDIR)$(BINDIR)/,$(notdir $(TARGETS))) @@ -870,18 +955,27 @@ ifeq ($(ENABLE_PYOSYS),1) endif endif -update-manual: $(TARGETS) $(EXTRA_TARGETS) - cd manual && ../$(PROGRAM_PREFIX)yosys -p 'help -write-tex-command-reference-manual' +# also others, but so long as it doesn't fail this is enough to know we tried +docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS) + mkdir -p docs/source/cmd + ./$(PROGRAM_PREFIX)yosys -p 'help -write-rst-command-reference-manual' -manual: $(TARGETS) $(EXTRA_TARGETS) - cd manual && bash appnotes.sh - cd manual && bash presentation.sh - cd manual && bash manual.sh +PHONY: docs/gen_images docs/guidelines +docs/gen_images: + $(Q) $(MAKE) -C docs/images all + +DOCS_GUIDELINE_FILES := GettingStarted CodingStyle +docs/guidelines: + $(Q) mkdir -p docs/source/temp + $(Q) cp -f $(addprefix guidelines/,$(DOCS_GUIDELINE_FILES)) docs/source/temp + +DOC_TARGET ?= html +docs: docs/source/cmd/abc.rst docs/gen_images docs/guidelines + $(Q) $(MAKE) -C docs $(DOC_TARGET) clean: rm -rf share rm -rf kernel/*.pyh - if test -d manual; then cd manual && sh clean.sh; fi 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 libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d @@ -890,10 +984,13 @@ clean: rm -rf tests/simple/*.out tests/simple/*.log rm -rf tests/memories/*.out tests/memories/*.log tests/memories/*.dmp rm -rf tests/sat/*.log tests/techmap/*.log tests/various/*.log - rm -rf tests/bram/temp tests/fsm/temp tests/realmath/temp tests/share/temp tests/smv/temp + rm -rf tests/bram/temp tests/fsm/temp tests/realmath/temp tests/share/temp tests/smv/temp tests/various/temp rm -rf vloghtb/Makefile vloghtb/refdat vloghtb/rtl vloghtb/scripts vloghtb/spec vloghtb/check_yosys vloghtb/vloghammer_tb.tar.bz2 vloghtb/temp vloghtb/log_test_* rm -f tests/svinterfaces/*.log_stdout tests/svinterfaces/*.log_stderr tests/svinterfaces/dut_result.txt tests/svinterfaces/reference_result.txt tests/svinterfaces/a.out tests/svinterfaces/*_syn.v tests/svinterfaces/*.diff rm -f tests/tools/cmp_tbdata + $(MAKE) -C docs clean + $(MAKE) -C docs/images clean + rm -rf docs/source/cmd docs/util/__pycache__ clean-abc: $(MAKE) -C abc DEP= clean @@ -953,9 +1050,6 @@ config-gcc-static: clean echo 'ENABLE_READLINE := 0' >> Makefile.conf echo 'ENABLE_TCL := 0' >> Makefile.conf -config-gcc-4.8: clean - echo 'CONFIG := gcc-4.8' > Makefile.conf - config-afl-gcc: clean echo 'CONFIG := afl-gcc' > Makefile.conf @@ -981,12 +1075,10 @@ config-mxe: clean config-msys2-32: clean echo 'CONFIG := msys2-32' > Makefile.conf - echo 'ENABLE_PLUGINS := 0' >> Makefile.conf echo "PREFIX := $(MINGW_PREFIX)" >> Makefile.conf config-msys2-64: clean echo 'CONFIG := msys2-64' > Makefile.conf - echo 'ENABLE_PLUGINS := 0' >> Makefile.conf echo "PREFIX := $(MINGW_PREFIX)" >> Makefile.conf config-cygwin: clean @@ -1020,5 +1112,5 @@ echo-abc-rev: -include kernel/*.d -include techlibs/*/*.d -.PHONY: all top-all abc test install install-abc manual clean mrproper qtcreator coverage vcxsrc mxebin -.PHONY: config-clean config-clang config-gcc config-gcc-static config-gcc-4.8 config-afl-gcc config-gprof config-sudo +.PHONY: all top-all abc test install install-abc docs clean mrproper qtcreator coverage vcxsrc mxebin +.PHONY: config-clean config-clang config-gcc config-gcc-static config-afl-gcc config-gprof config-sudo diff --git a/README.md b/README.md index ab656352a9e..f3a63cbec39 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,23 @@ front-end for Yosys, SymbiYosys: - https://github.com/YosysHQ/SymbiYosys -Setup -====== +Installation +============ + +Yosys is part of the [Tabby CAD Suite](https://www.yosyshq.com/tabby-cad-datasheet) and the [OSS CAD Suite](https://github.com/YosysHQ/oss-cad-suite-build)! The easiest way to use yosys is to install the binary software suite, which contains all required dependencies and related tools. + +* [Contact YosysHQ](https://www.yosyshq.com/contact) for a [Tabby CAD Suite](https://www.yosyshq.com/tabby-cad-datasheet) Evaluation License and download link +* OR go to https://github.com/YosysHQ/oss-cad-suite-build/releases to download the free OSS CAD Suite +* Follow the [Install Instructions on GitHub](https://github.com/YosysHQ/oss-cad-suite-build#installation) + +Make sure to get a Tabby CAD Suite Evaluation License if you need features such as industry-grade SystemVerilog and VHDL parsers! + +For more information about the difference between Tabby CAD Suite and the OSS CAD Suite, please visit https://www.yosyshq.com/tabby-cad-datasheet + +Many Linux distributions also provide Yosys binaries, some more up to date than others. Check with your package manager! + +Building from Source +==================== You need a C++ compiler with C++11 support (up-to-date CLANG or GCC is recommended) and some standard tools such as GNU Flex, GNU Bison, and GNU Make. @@ -90,10 +105,6 @@ For Cygwin use the following command to install all prerequisites, or select the setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,make,pkg-config,python3,tcl-devel,boost-build,zlib-devel -There are also pre-compiled Yosys binary packages for Ubuntu and Win32 as well -as a source distribution for Visual Studio. Visit the Yosys download page for -more information: https://yosyshq.net/yosys/download.html - To configure the build system to use a specific compiler, use one of $ make config-clang @@ -489,6 +500,23 @@ Verilog Attributes and non-standard features for use in blackboxes and whiteboxes. Use ``read_verilog -specify`` to enable this functionality. (By default these blocks are ignored.) +- The ``reprocess_after`` internal attribute is used by the Verilog frontend to + mark cells with bindings which might depend on the specified instantiated + module. Modules with such cells will be reprocessed during the ``hierarchy`` + pass once the referenced module definition(s) become available. + +- The ``smtlib2_module`` attribute can be set on a blackbox module to specify a + formal model directly using SMT-LIB 2. For such a module, the + ``smtlib2_comb_expr`` attribute can be used on output ports to define their + value using an SMT-LIB 2 expression. For example: + + (* blackbox *) + (* smtlib2_module *) + module submod(a, b); + input [7:0] a; + (* smtlib2_comb_expr = "(bvnot a)" *) + output [7:0] b; + endmodule Non-standard or SystemVerilog features for formal verification ============================================================== @@ -568,31 +596,22 @@ Building the documentation ========================== Note that there is no need to build the manual if you just want to read it. -Simply download the PDF from https://yosyshq.net/yosys/documentation.html -instead. - -On Ubuntu, texlive needs these packages to be able to build the manual: - - sudo apt-get install texlive-binaries - sudo apt-get install texlive-science # install algorithm2e.sty - sudo apt-get install texlive-bibtex-extra # gets multibib.sty - sudo apt-get install texlive-fonts-extra # gets skull.sty and dsfont.sty - sudo apt-get install texlive-publishers # IEEEtran.cls +Simply visit https://yosys.readthedocs.io/en/latest/ instead. -Also the non-free font luximono should be installed, there is unfortunately -no Ubuntu package for this so it should be installed separately using -`getnonfreefonts`: +In addition to those packages listed above for building Yosys from source, the +following are used for building the website: - wget https://tug.org/fonts/getnonfreefonts/install-getnonfreefonts - sudo texlua install-getnonfreefonts # will install to /usr/local by default, can be changed by editing BINDIR at MANDIR at the top of the script - getnonfreefonts luximono # installs to /home/user/texmf + $ sudo apt-get install pdf2svg faketime -Then execute, from the root of the repository: +PDFLaTeX, included with most LaTeX distributions, is also needed during the +build process for the website. - make manual +The Python package, Sphinx, is needed along with those listed in +`docs/source/requirements.txt`: -Notes: + $ pip install -U sphinx -r docs/source/requirements.txt -- To run `make manual` you need to have installed Yosys with `make install`, - otherwise it will fail on finding `kernel/yosys.h` while building - `PRESENTATION_Prog`. +From the root of the repository, run `make docs`. This will build/rebuild yosys +as necessary before generating the website documentation from the yosys help +commands. To build for pdf instead of html, call +`make docs DOC_TARGET=latexpdf`. diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 35935b847e0..bb804f230fb 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -19,6 +19,9 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/json.h" +#include "kernel/yw.h" +#include "libs/json11/json11.hpp" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -61,6 +64,8 @@ struct AigerWriter dict init_inputs; int initstate_ff = 0; + dict ywmap_clocks; + int mkgate(int a0, int a1) { aig_m++, aig_a++; @@ -114,14 +119,14 @@ struct AigerWriter if (wire->name.isPublic()) sigmap.add(wire); - // promote input wires + // promote output wires for (auto wire : module->wires()) - if (wire->port_input) + if (wire->port_output) sigmap.add(wire); - // promote output wires + // promote input wires for (auto wire : module->wires()) - if (wire->port_output) + if (wire->port_input) sigmap.add(wire); for (auto wire : module->wires()) @@ -159,6 +164,17 @@ struct AigerWriter output_bits.insert(wirebit); } } + + if (wire->width == 1) { + auto gclk_attr = wire->attributes.find(ID::replaced_by_gclk); + if (gclk_attr != wire->attributes.end()) { + SigBit bit = sigmap(wire); + if (gclk_attr->second == State::S1) + ywmap_clocks[bit] |= 1; + else if (gclk_attr->second == State::S0) + ywmap_clocks[bit] |= 2; + } + } } for (auto bit : input_bits) @@ -186,6 +202,22 @@ struct AigerWriter unused_bits.erase(D); undriven_bits.erase(Q); ff_map[Q] = D; + + if (cell->type != ID($_FF_)) { + auto sig_clk = sigmap(cell->getPort(ID::C).as_bit()); + ywmap_clocks[sig_clk] |= cell->type == ID($_DFF_N_) ? 2 : 1; + } + continue; + } + + if (cell->type == ID($anyinit)) + { + auto sig_d = sigmap(cell->getPort(ID::D)); + auto sig_q = sigmap(cell->getPort(ID::Q)); + for (int i = 0; i < sig_d.size(); i++) { + undriven_bits.erase(sig_q[i]); + ff_map[sig_q[i]] = sig_d[i]; + } continue; } @@ -606,7 +638,7 @@ struct AigerWriter f << stringf("c\nGenerated by %s\n", yosys_version_str); } - void write_map(std::ostream &f, bool verbose_map) + void write_map(std::ostream &f, bool verbose_map, bool no_startoffset) { dict input_lines; dict init_lines; @@ -627,32 +659,33 @@ struct AigerWriter continue; int a = aig_map.at(sig[i]); + int index = no_startoffset ? i : (wire->start_offset+i); if (verbose_map) - wire_lines[a] += stringf("wire %d %d %s\n", a, wire->start_offset+i, log_id(wire)); + wire_lines[a] += stringf("wire %d %d %s\n", a, index, log_id(wire)); if (wire->port_input) { log_assert((a & 1) == 0); - input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, wire->start_offset+i, log_id(wire)); + input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, index, log_id(wire)); } if (wire->port_output) { int o = ordered_outputs.at(sig[i]); - output_lines[o] += stringf("output %d %d %s\n", o, wire->start_offset+i, log_id(wire)); + output_lines[o] += stringf("output %d %d %s\n", o, index, log_id(wire)); } if (init_inputs.count(sig[i])) { int a = init_inputs.at(sig[i]); log_assert((a & 1) == 0); - init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, wire->start_offset+i, log_id(wire)); + init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, index, log_id(wire)); } if (ordered_latches.count(sig[i])) { int l = ordered_latches.at(sig[i]); if (zinit_mode && (aig_latchinit.at(l) == 1)) - latch_lines[l] += stringf("invlatch %d %d %s\n", l, wire->start_offset+i, log_id(wire)); + latch_lines[l] += stringf("invlatch %d %d %s\n", l, index, log_id(wire)); else - latch_lines[l] += stringf("latch %d %d %s\n", l, wire->start_offset+i, log_id(wire)); + latch_lines[l] += stringf("latch %d %d %s\n", l, index, log_id(wire)); } } } @@ -673,10 +706,131 @@ struct AigerWriter for (auto &it : latch_lines) f << it.second; + if (initstate_ff) + f << stringf("ninitff %d\n", ((initstate_ff >> 1)-1-aig_i)); + wire_lines.sort(); for (auto &it : wire_lines) f << it.second; } + + void write_ywmap(PrettyJson &json) + { + json.begin_object(); + json.entry("version", "Yosys Witness Aiger map"); + json.entry("gennerator", yosys_version_str); + + json.entry("latch_count", aig_l); + json.entry("input_count", aig_i); + + dict clock_lines; + dict input_lines; + dict init_lines; + dict seq_lines; + + for (auto cell : module->cells()) + { + if (cell->type.in(ID($_FF_), ID($_DFF_N_), ID($_DFF_P_), ID($anyinit), ID($anyconst), ID($anyseq))) + { + // Use sig_q to get the FF output name, but sig to lookup aiger bits + auto sig_qy = cell->getPort(cell->type.in(ID($anyconst), ID($anyseq)) ? ID::Y : ID::Q); + SigSpec sig = sigmap(sig_qy); + + if (cell->get_bool_attribute(ID(clk2fflogic))) + sig_qy = cell->getPort(ID::D); // For a clk2fflogic $_FF_ the named signal is the D input not the Q output + + for (int i = 0; i < GetSize(sig_qy); i++) { + if (sig_qy[i].wire == nullptr || sig[i].wire == nullptr) + continue; + + auto wire = sig_qy[i].wire; + + if (init_inputs.count(sig[i])) { + int a = init_inputs.at(sig[i]); + log_assert((a & 1) == 0); + init_lines[a] = json11::Json(json11::Json::object { + { "path", witness_path(wire) }, + { "input", (a >> 1) - 1 }, + { "offset", sig_qy[i].offset }, + }); + } + + if (input_bits.count(sig[i])) { + int a = aig_map.at(sig[i]); + log_assert((a & 1) == 0); + seq_lines[a] = json11::Json(json11::Json::object { + { "path", witness_path(wire) }, + { "input", (a >> 1) - 1 }, + { "offset", sig_qy[i].offset }, + }); + } + } + } + } + + for (auto wire : module->wires()) + { + SigSpec sig = sigmap(wire); + if (wire->port_input) + { + auto path = witness_path(wire); + for (int i = 0; i < GetSize(wire); i++) { + if (aig_map.count(sig[i]) == 0 || sig[i].wire == nullptr) + continue; + + int a = aig_map.at(sig[i]); + log_assert((a & 1) == 0); + input_lines[a] = json11::Json(json11::Json::object { + { "path", path }, + { "input", (a >> 1) - 1 }, + { "offset", i }, + }); + + if (ywmap_clocks.count(sig[i])) { + int clock_mode = ywmap_clocks[sig[i]]; + if (clock_mode != 3) { + clock_lines[a] = json11::Json(json11::Json::object { + { "path", path }, + { "input", (a >> 1) - 1 }, + { "offset", i }, + { "edge", clock_mode == 1 ? "posedge" : "negedge" }, + }); + } + } + } + } + } + + json.name("clocks"); + json.begin_array(); + clock_lines.sort(); + for (auto &it : clock_lines) + json.value(it.second); + json.end_array(); + + json.name("inputs"); + json.begin_array(); + input_lines.sort(); + for (auto &it : input_lines) + json.value(it.second); + json.end_array(); + + json.name("seqs"); + json.begin_array(); + input_lines.sort(); + for (auto &it : seq_lines) + json.value(it.second); + json.end_array(); + + json.name("inits"); + json.begin_array(); + input_lines.sort(); + for (auto &it : init_lines) + json.value(it.second); + json.end_array(); + json.end_object(); + } + }; struct AigerBackend : public Backend { @@ -713,6 +867,12 @@ struct AigerBackend : public Backend { log(" -vmap \n"); log(" like -map, but more verbose\n"); log("\n"); + log(" -no-startoffset\n"); + log(" make indexes zero based, enable using map files with smt solvers.\n"); + log("\n"); + log(" -ywmap \n"); + log(" write a map file for conversion to and from yosys witness traces.\n"); + log("\n"); log(" -I, -O, -B, -L\n"); log(" If the design contains no input/output/assert/flip-flop then create one\n"); log(" dummy input/output/bad_state-pin or latch to make the tools reading the\n"); @@ -730,7 +890,9 @@ struct AigerBackend : public Backend { bool omode = false; bool bmode = false; bool lmode = false; + bool no_startoffset = false; std::string map_filename; + std::string yw_map_filename; log_header(design, "Executing AIGER backend.\n"); @@ -762,6 +924,14 @@ struct AigerBackend : public Backend { verbose_map = true; continue; } + if (yw_map_filename.empty() && args[argidx] == "-ywmap" && argidx+1 < args.size()) { + yw_map_filename = args[++argidx]; + continue; + } + if (args[argidx] == "-no-startoffset") { + no_startoffset = true; + continue; + } if (args[argidx] == "-I") { imode = true; continue; @@ -782,6 +952,9 @@ struct AigerBackend : public Backend { } extra_args(f, filename, args, argidx, !ascii_mode); + if (!yw_map_filename.empty() && !zinit_mode) + log_error("Currently -ywmap requires -zinit.\n"); + Module *top_module = design->top_module(); if (top_module == nullptr) @@ -804,7 +977,18 @@ struct AigerBackend : public Backend { mapf.open(map_filename.c_str(), std::ofstream::trunc); if (mapf.fail()) log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno)); - writer.write_map(mapf, verbose_map); + writer.write_map(mapf, verbose_map, no_startoffset); + } + + if (!yw_map_filename.empty()) { + std::ofstream mapf; + mapf.open(yw_map_filename.c_str(), std::ofstream::trunc); + + PrettyJson json; + + if (!json.write_to_file(yw_map_filename)) + log_error("Can't open file `%s' for writing: %s\n", yw_map_filename.c_str(), strerror(errno)); + writer.write_ywmap(json); } } } AigerBackend; diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 66955d88e9d..68c2ff52f55 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -261,26 +261,31 @@ struct XAigerWriter if (!timing.count(inst_module->name)) timing.setup_module(inst_module); - auto &t = timing.at(inst_module->name).arrival; - for (const auto &conn : cell->connections()) { - auto port_wire = inst_module->wire(conn.first); - if (!port_wire->port_output) + + for (auto &i : timing.at(inst_module->name).arrival) { + if (!cell->hasPort(i.first.name)) continue; - for (int i = 0; i < GetSize(conn.second); i++) { - auto d = t.at(TimingInfo::NameBit(conn.first,i), 0); - if (d == 0) - continue; + auto port_wire = inst_module->wire(i.first.name); + log_assert(port_wire->port_output); + + auto d = i.second.first; + if (d == 0) + continue; + auto offset = i.first.offset; + + auto rhs = cell->getPort(i.first.name); + if (offset >= rhs.size()) + continue; #ifndef NDEBUG - if (ys_debug(1)) { - static std::set> seen; - if (seen.emplace(inst_module->name, conn.first, i).second) log("%s.%s[%d] abc9_arrival = %d\n", - log_id(cell->type), log_id(conn.first), i, d); - } -#endif - arrival_times[conn.second[i]] = d; + if (ys_debug(1)) { + static pool> seen; + if (seen.emplace(inst_module->name, i.first).second) log("%s.%s[%d] abc9_arrival = %d\n", + log_id(cell->type), log_id(i.first.name), offset, d); } +#endif + arrival_times[rhs[offset]] = d; } if (abc9_flop) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index ba29d90907f..23d1d58fc20 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -512,8 +512,8 @@ struct BlifBackend : public Backend { log(" suppresses the generation of this nets without fanout.\n"); log("\n"); log("The following options can be useful when the generated file is not going to be\n"); - log("read by a BLIF parser but a custom tool. It is recommended to not name the output\n"); - log("file *.blif when any of this options is used.\n"); + log("read by a BLIF parser but a custom tool. It is recommended to not name the\n"); + log("output file *.blif when any of this options is used.\n"); log("\n"); log(" -icells\n"); log(" do not translate Yosys's internal gates to generic BLIF logic\n"); diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 6370b53bd2c..9cfd967e581 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -28,6 +28,8 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include "kernel/mem.h" +#include "kernel/json.h" +#include "kernel/yw.h" #include USING_YOSYS_NAMESPACE @@ -83,6 +85,22 @@ struct BtorWorker vector info_lines; dict info_clocks; + struct ywmap_btor_sig { + SigSpec sig; + Cell *cell = nullptr; + + ywmap_btor_sig(const SigSpec &sig) : sig(sig) {} + ywmap_btor_sig(Cell *cell) : cell(cell) {} + }; + + vector ywmap_inputs; + vector ywmap_states; + dict ywmap_clock_bits; + dict ywmap_clock_inputs; + + + PrettyJson ywmap_json; + void btorf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 2, 3)) { va_list ap; @@ -126,6 +144,50 @@ struct BtorWorker return " " + infostr; } + void ywmap_state(const SigSpec &sig) { + if (ywmap_json.active()) + ywmap_states.emplace_back(sig); + } + + void ywmap_state(Cell *cell) { + if (ywmap_json.active()) + ywmap_states.emplace_back(cell); + } + + void ywmap_input(const SigSpec &sig) { + if (ywmap_json.active()) + ywmap_inputs.emplace_back(sig); + } + + void emit_ywmap_btor_sig(const ywmap_btor_sig &btor_sig) { + if (btor_sig.cell == nullptr) { + if (btor_sig.sig.empty()) { + ywmap_json.value(nullptr); + return; + } + ywmap_json.begin_array(); + ywmap_json.compact(); + for (auto &chunk : btor_sig.sig.chunks()) { + log_assert(chunk.is_wire()); + + ywmap_json.begin_object(); + ywmap_json.entry("path", witness_path(chunk.wire)); + ywmap_json.entry("width", chunk.width); + ywmap_json.entry("offset", chunk.offset); + ywmap_json.end_object(); + } + ywmap_json.end_array(); + } else { + ywmap_json.begin_object(); + ywmap_json.compact(); + ywmap_json.entry("path", witness_path(btor_sig.cell)); + Mem *mem = mem_cells[btor_sig.cell]; + ywmap_json.entry("width", mem->width); + ywmap_json.entry("size", mem->size); + ywmap_json.end_object(); + } + } + void btorf_push(const string &id) { if (verbose) { @@ -446,25 +508,28 @@ struct BtorWorker goto okay; } - if (cell->type.in(ID($not), ID($neg), ID($_NOT_))) + if (cell->type.in(ID($not), ID($neg), ID($_NOT_), ID($pos))) { string btor_op; if (cell->type.in(ID($not), ID($_NOT_))) btor_op = "not"; if (cell->type == ID($neg)) btor_op = "neg"; - log_assert(!btor_op.empty()); int width = std::max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::Y))); bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false; - - int sid = get_bv_sid(width); int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed); - - int nid = next_nid++; - btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str()); - SigSpec sig = sigmap(cell->getPort(ID::Y)); + // the $pos cell just passes through, all other cells need an actual operation applied + int nid = nid_a; + if (cell->type != ID($pos)) + { + log_assert(!btor_op.empty()); + int sid = get_bv_sid(width); + nid = next_nid++; + btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str()); + } + if (GetSize(sig) < width) { int sid = get_bv_sid(GetSize(sig)); int nid2 = next_nid++; @@ -609,12 +674,12 @@ struct BtorWorker goto okay; } - if (cell->type.in(ID($dff), ID($ff), ID($_DFF_P_), ID($_DFF_N), ID($_FF_))) + if (cell->type.in(ID($dff), ID($ff), ID($anyinit), ID($_DFF_P_), ID($_DFF_N), ID($_FF_))) { SigSpec sig_d = sigmap(cell->getPort(ID::D)); SigSpec sig_q = sigmap(cell->getPort(ID::Q)); - if (!info_filename.empty() && cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_))) + if ((!info_filename.empty() || ywmap_json.active()) && cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_))) { SigSpec sig_c = sigmap(cell->getPort(cell->type == ID($dff) ? ID::CLK : ID::C)); int nid = get_sig_nid(sig_c); @@ -626,7 +691,11 @@ struct BtorWorker if (cell->type == ID($dff) && !cell->getParam(ID::CLK_POLARITY).as_bool()) negedge = true; - info_clocks[nid] |= negedge ? 2 : 1; + if (!info_filename.empty()) + info_clocks[nid] |= negedge ? 2 : 1; + + if (ywmap_json.active()) + ywmap_clock_bits[sig_c] |= negedge ? 2 : 1; } IdString symbol; @@ -659,6 +728,11 @@ struct BtorWorker else btorf("%d state %d %s\n", nid, sid, log_id(symbol)); + if (cell->get_bool_attribute(ID(clk2fflogic))) + ywmap_state(cell->getPort(ID::D)); // For a clk2fflogic FF the named signal is the D input not the Q output + else + ywmap_state(sig_q); + if (nid_init_val >= 0) { int nid_init = next_nid++; if (verbose) @@ -678,7 +752,9 @@ struct BtorWorker int sid = get_bv_sid(GetSize(sig_y)); int nid = next_nid++; - btorf("%d state %d\n", nid, sid); + btorf("%d state %d%s\n", nid, sid, getinfo(cell).c_str()); + + ywmap_state(sig_y); if (cell->type == ID($anyconst)) { int nid2 = next_nid++; @@ -699,9 +775,11 @@ struct BtorWorker int one_nid = get_sig_nid(State::S1); int zero_nid = get_sig_nid(State::S0); initstate_nid = next_nid++; - btorf("%d state %d\n", initstate_nid, sid); + btorf("%d state %d%s\n", initstate_nid, sid, getinfo(cell).c_str()); btorf("%d init %d %d %d\n", next_nid++, sid, initstate_nid, one_nid); btorf("%d next %d %d %d\n", next_nid++, sid, initstate_nid, zero_nid); + + ywmap_state(sig_y); } add_nid_sig(initstate_nid, sig_y); @@ -765,6 +843,8 @@ struct BtorWorker nid_init_val = next_nid++; btorf("%d state %d\n", nid_init_val, sid); + ywmap_state(nullptr); + for (int i = 0; i < mem->size; i++) { Const thisword = initdata.extract(i*mem->width, mem->width); if (thisword.is_fully_undef()) @@ -790,6 +870,8 @@ struct BtorWorker else btorf("%d state %d %s\n", nid, sid, log_id(mem->memid)); + ywmap_state(cell); + if (nid_init_val >= 0) { int nid_init = next_nid++; @@ -865,7 +947,7 @@ struct BtorWorker log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_btor`.\n", log_id(cell->type), log_id(module), log_id(cell)); } - if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") { + if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_btor`.\n", log_id(cell->type), log_id(module), log_id(cell)); } @@ -912,10 +994,13 @@ struct BtorWorker int sid = get_bv_sid(GetSize(sig)); int nid_input = next_nid++; - if (is_init) + if (is_init) { btorf("%d state %d\n", nid_input, sid); - else + ywmap_state(sig); + } else { btorf("%d input %d\n", nid_input, sid); + ywmap_input(sig); + } int nid_masked_input; if (sig_mask_undef.is_fully_ones()) { @@ -990,6 +1075,7 @@ struct BtorWorker int sid = get_bv_sid(GetSize(s)); int nid = next_nid++; btorf("%d input %d\n", nid, sid); + ywmap_input(s); nid_width[nid] = GetSize(s); for (int j = 0; j < GetSize(s); j++) @@ -1072,12 +1158,15 @@ struct BtorWorker return nid; } - BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad, bool cover_mode, bool print_internal_names, string info_filename) : + BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad, bool cover_mode, bool print_internal_names, string info_filename, string ywmap_filename) : f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad), cover_mode(cover_mode), print_internal_names(print_internal_names), info_filename(info_filename) { if (!info_filename.empty()) infof("name %s\n", log_id(module)); + if (!ywmap_filename.empty()) + ywmap_json.write_to_file(ywmap_filename); + memories = Mem::get_all_memories(module); dict mem_dict; @@ -1091,6 +1180,20 @@ struct BtorWorker btorf_push("inputs"); + if (ywmap_json.active()) { + for (auto wire : module->wires()) + { + auto gclk_attr = wire->attributes.find(ID::replaced_by_gclk); + if (gclk_attr == wire->attributes.end()) + continue; + SigSpec sig = sigmap(wire); + if (gclk_attr->second == State::S1) + ywmap_clock_bits[sig] |= 1; + else if (gclk_attr->second == State::S0) + ywmap_clock_bits[sig] |= 2; + } + } + for (auto wire : module->wires()) { if (wire->attributes.count(ID::init)) { @@ -1108,7 +1211,28 @@ struct BtorWorker int nid = next_nid++; btorf("%d input %d%s\n", nid, sid, getinfo(wire).c_str()); + ywmap_input(wire); add_nid_sig(nid, sig); + + if (!info_filename.empty()) { + auto gclk_attr = wire->attributes.find(ID::replaced_by_gclk); + if (gclk_attr != wire->attributes.end()) { + if (gclk_attr->second == State::S1) + info_clocks[nid] |= 1; + else if (gclk_attr->second == State::S0) + info_clocks[nid] |= 2; + } + } + + if (ywmap_json.active()) { + for (int i = 0; i < GetSize(sig); i++) { + auto input_bit = SigBit(wire, i); + auto bit = sigmap(input_bit); + if (!ywmap_clock_bits.count(bit)) + continue; + ywmap_clock_inputs[input_bit] = ywmap_clock_bits[bit]; + } + } } btorf_pop("inputs"); @@ -1220,6 +1344,8 @@ struct BtorWorker int this_nid = next_nid++; btorf("%d uext %d %d %d%s\n", this_nid, sid, nid, 0, getinfo(wire).c_str()); + if (info_clocks.count(nid)) + info_clocks[this_nid] |= info_clocks[nid]; btorf_pop(stringf("wire %s", log_id(wire))); continue; @@ -1363,6 +1489,42 @@ struct BtorWorker f << it; f.close(); } + + if (ywmap_json.active()) + { + ywmap_json.begin_object(); + ywmap_json.entry("version", "Yosys Witness BTOR map"); + ywmap_json.entry("generator", yosys_version_str); + + ywmap_json.name("clocks"); + ywmap_json.begin_array(); + for (auto &entry : ywmap_clock_inputs) { + if (entry.second != 1 && entry.second != 2) + continue; + log_assert(entry.first.is_wire()); + ywmap_json.begin_object(); + ywmap_json.compact(); + ywmap_json.entry("path", witness_path(entry.first.wire)); + ywmap_json.entry("offset", entry.first.offset); + ywmap_json.entry("edge", entry.second == 1 ? "posedge" : "negedge"); + ywmap_json.end_object(); + } + ywmap_json.end_array(); + + ywmap_json.name("inputs"); + ywmap_json.begin_array(); + for (auto &entry : ywmap_inputs) + emit_ywmap_btor_sig(entry); + ywmap_json.end_array(); + + ywmap_json.name("states"); + ywmap_json.begin_array(); + for (auto &entry : ywmap_states) + emit_ywmap_btor_sig(entry); + ywmap_json.end_array(); + + ywmap_json.end_object(); + } } }; @@ -1391,14 +1553,24 @@ struct BtorBackend : public Backend { log(" -x\n"); log(" Output symbols for internal netnames (starting with '$')\n"); log("\n"); + log(" -ywmap \n"); + log(" Create a map file for conversion to and from Yosys witness traces\n"); + log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) override { bool verbose = false, single_bad = false, cover_mode = false, print_internal_names = false; string info_filename; + string ywmap_filename; log_header(design, "Executing BTOR backend.\n"); + log_push(); + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); + Pass::call(design, "bwmuxmap"); + log_pop(); + size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -1422,6 +1594,10 @@ struct BtorBackend : public Backend { print_internal_names = true; continue; } + if (args[argidx] == "-ywmap" && argidx+1 < args.size()) { + ywmap_filename = args[++argidx]; + continue; + } break; } extra_args(f, filename, args, argidx); @@ -1434,7 +1610,7 @@ struct BtorBackend : public Backend { *f << stringf("; BTOR description generated by %s for module %s.\n", yosys_version_str, log_id(topmod)); - BtorWorker(*f, topmod, verbose, single_bad, cover_mode, print_internal_names, info_filename); + BtorWorker(*f, topmod, verbose, single_bad, cover_mode, print_internal_names, info_filename, ywmap_filename); *f << stringf("; end of yosys output\n"); } diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 4552a01254d..073921cc49e 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -457,6 +457,42 @@ struct value : public expr_base> { return shr(amount); } + template + value bmux(const value &sel) const { + static_assert(ResultBits << SelBits == Bits, "invalid sizes used in bmux()"); + size_t amount = sel.data[0] * ResultBits; + size_t shift_chunks = amount / chunk::bits; + size_t shift_bits = amount % chunk::bits; + value result; + chunk::type carry = 0; + if (ResultBits % chunk::bits + shift_bits > chunk::bits) + carry = data[result.chunks + shift_chunks] << (chunk::bits - shift_bits); + for (size_t n = 0; n < result.chunks; n++) { + result.data[result.chunks - 1 - n] = carry | (data[result.chunks + shift_chunks - 1 - n] >> shift_bits); + carry = (shift_bits == 0) ? 0 + : data[result.chunks + shift_chunks - 1 - n] << (chunk::bits - shift_bits); + } + return result; + } + + template + value demux(const value &sel) const { + static_assert(Bits << SelBits == ResultBits, "invalid sizes used in demux()"); + size_t amount = sel.data[0] * Bits; + size_t shift_chunks = amount / chunk::bits; + size_t shift_bits = amount % chunk::bits; + value result; + chunk::type carry = 0; + for (size_t n = 0; n < chunks; n++) { + result.data[shift_chunks + n] = (data[n] << shift_bits) | carry; + carry = (shift_bits == 0) ? 0 + : data[n] >> (chunk::bits - shift_bits); + } + if (Bits % chunk::bits + shift_bits > chunk::bits) + result.data[shift_chunks + chunks] = carry; + return result; + } + size_t ctpop() const { size_t count = 0; for (size_t n = 0; n < chunks; n++) { @@ -722,50 +758,32 @@ std::ostream &operator<<(std::ostream &os, const wire &val) { template struct memory { - std::vector> data; + const size_t depth; + std::unique_ptr[]> data; - size_t depth() const { - return data.size(); - } - - memory() = delete; - explicit memory(size_t depth) : data(depth) {} + explicit memory(size_t depth) : depth(depth), data(new value[depth]) {} memory(const memory &) = delete; memory &operator=(const memory &) = delete; memory(memory &&) = default; - memory &operator=(memory &&) = default; - - // The only way to get the compiler to put the initializer in .rodata and do not copy it on stack is to stuff it - // into a plain array. You'd think an std::initializer_list would work here, but it doesn't, because you can't - // construct an initializer_list in a constexpr (or something) and so if you try to do that the whole thing is - // first copied on the stack (probably overflowing it) and then again into `data`. - template - struct init { - size_t offset; - value data[Size]; - }; - - template - explicit memory(size_t depth, const init &...init) : data(depth) { - data.resize(depth); - // This utterly reprehensible construct is the most reasonable way to apply a function to every element - // of a parameter pack, if the elements all have different types and so cannot be cast to an initializer list. - auto _ = {std::move(std::begin(init.data), std::end(init.data), data.begin() + init.offset)...}; - (void)_; + memory &operator=(memory &&other) { + assert(depth == other.depth); + data = std::move(other.data); + write_queue = std::move(other.write_queue); + return *this; } // An operator for direct memory reads. May be used at any time during the simulation. const value &operator [](size_t index) const { - assert(index < data.size()); + assert(index < depth); return data[index]; } // An operator for direct memory writes. May only be used before the simulation is started. If used // after the simulation is started, the design may malfunction. value &operator [](size_t index) { - assert(index < data.size()); + assert(index < depth); return data[index]; } @@ -790,7 +808,7 @@ struct memory { std::vector write_queue; void update(size_t index, const value &val, const value &mask, int priority = 0) { - assert(index < data.size()); + assert(index < depth); // Queue up the write while keeping the queue sorted by priority. write_queue.insert( std::upper_bound(write_queue.begin(), write_queue.end(), priority, @@ -947,9 +965,9 @@ struct debug_item : ::cxxrtl_object { flags = 0; width = Width; lsb_at = 0; - depth = item.data.size(); + depth = item.depth; zero_at = zero_offset; - curr = item.data.empty() ? nullptr : item.data[0].data; + curr = item.data ? item.data[0].data : nullptr; next = nullptr; outline = nullptr; } @@ -1051,9 +1069,9 @@ struct debug_items { } }; -// Tag class to disambiguate module move constructor and module constructor that takes black boxes -// out of another instance of the module. -struct adopt {}; +// Tag class to disambiguate the default constructor used by the toplevel module that calls reset(), +// and the constructor of interior modules that should not call it. +struct interior {}; struct module { module() {} @@ -1557,6 +1575,27 @@ value mod_ss(const value &a, const value &b) { return divmod_ss(a, b).second; } +template +CXXRTL_ALWAYS_INLINE +value modfloor_uu(const value &a, const value &b) { + return divmod_uu(a, b).second; +} + +// GHDL Modfloor operator. Returns r=a mod b, such that r has the same sign as b and +// a=b*N+r where N is some integer +// In practical terms, when a and b have different signs and the remainder returned by divmod_ss is not 0 +// then return the remainder + b +template +CXXRTL_ALWAYS_INLINE +value modfloor_ss(const value &a, const value &b) { + value r; + r = divmod_ss(a, b).second; + if((b.is_neg() != a.is_neg()) && !r.is_zero()) + return add_ss(b, r); + return r; +} + + // Memory helper struct memory_index { bool valid; diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 40e61e5af6e..62768bd3395 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -185,7 +185,7 @@ bool is_binary_cell(RTLIL::IdString type) ID($and), ID($or), ID($xor), ID($xnor), ID($logic_and), ID($logic_or), ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx), ID($eq), ID($ne), ID($eqx), ID($nex), ID($gt), ID($ge), ID($lt), ID($le), - ID($add), ID($sub), ID($mul), ID($div), ID($mod)); + ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($modfloor)); } bool is_extending_cell(RTLIL::IdString type) @@ -198,7 +198,7 @@ bool is_extending_cell(RTLIL::IdString type) bool is_inlinable_cell(RTLIL::IdString type) { return is_unary_cell(type) || is_binary_cell(type) || type.in( - ID($mux), ID($concat), ID($slice), ID($pmux)); + ID($mux), ID($concat), ID($slice), ID($pmux), ID($bmux), ID($demux)); } bool is_ff_cell(RTLIL::IdString type) @@ -206,6 +206,7 @@ bool is_ff_cell(RTLIL::IdString type) return type.in( ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), + ID($aldff), ID($aldffe), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr)); } @@ -933,11 +934,6 @@ struct CxxrtlWorker { f << "}"; } - void dump_const_init(const RTLIL::Const &data) - { - dump_const_init(data, data.size()); - } - void dump_const(const RTLIL::Const &data, int width, int offset = 0, bool fixed_width = false) { f << "value<" << width << ">"; @@ -1158,6 +1154,22 @@ struct CxxrtlWorker { for (int part = 0; part < s_width; part++) { f << ")"; } + // Big muxes + } else if (cell->type == ID($bmux)) { + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); + f << ".bmux<"; + f << cell->getParam(ID::WIDTH).as_int(); + f << ">("; + dump_sigspec_rhs(cell->getPort(ID::S), for_debug); + f << ").val()"; + // Demuxes + } else if (cell->type == ID($demux)) { + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); + f << ".demux<"; + f << GetSize(cell->getPort(ID::Y)); + f << ">("; + dump_sigspec_rhs(cell->getPort(ID::S), for_debug); + f << ").val()"; // Concats } else if (cell->type == ID($concat)) { dump_sigspec_rhs(cell->getPort(ID::B), for_debug); @@ -1267,6 +1279,20 @@ struct CxxrtlWorker { dec_indent(); f << indent << "}\n"; } + if (cell->hasPort(ID::ALOAD)) { + // Asynchronous load + f << indent << "if ("; + dump_sigspec_rhs(cell->getPort(ID::ALOAD)); + f << " == value<1> {" << cell->getParam(ID::ALOAD_POLARITY).as_bool() << "u}) {\n"; + inc_indent(); + f << indent; + dump_sigspec_lhs(cell->getPort(ID::Q)); + f << " = "; + dump_sigspec_rhs(cell->getPort(ID::AD)); + f << ";\n"; + dec_indent(); + f << indent << "}\n"; + } if (cell->hasPort(ID::SET)) { // Asynchronous set (for individual bits) f << indent; @@ -1770,20 +1796,10 @@ struct CxxrtlWorker { } else { f << "<" << wire->width << ">"; } - f << " " << mangle(wire); - if (wire_init.count(wire)) { - f << " "; - dump_const_init(wire_init.at(wire)); - } - f << ";\n"; + f << " " << mangle(wire) << ";\n"; if (edge_wires[wire]) { if (!wire_type.is_buffered()) { - f << indent << "value<" << wire->width << "> prev_" << mangle(wire); - if (wire_init.count(wire)) { - f << " "; - dump_const_init(wire_init.at(wire)); - } - f << ";\n"; + f << indent << "value<" << wire->width << "> prev_" << mangle(wire) << ";\n"; } for (auto edge_type : edge_types) { if (edge_type.first.wire == wire) { @@ -1833,38 +1849,67 @@ struct CxxrtlWorker { f << "value<" << wire->width << "> " << mangle(wire) << ";\n"; } - void dump_memory(Mem *mem) + void dump_reset_method(RTLIL::Module *module) { - dump_attrs(mem); - f << indent << "memory<" << mem->width << "> " << mangle(mem) - << " { " << mem->size << "u"; - if (!GetSize(mem->inits)) { - f << " };\n"; - } else { - f << ",\n"; - inc_indent(); - for (auto &init : mem->inits) { + int mem_init_idx = 0; + inc_indent(); + for (auto wire : module->wires()) { + const auto &wire_type = wire_types[wire]; + if (!wire_type.is_named() || wire_type.is_local()) continue; + if (!wire_init.count(wire)) continue; + + f << indent << mangle(wire) << " = "; + if (wire_types[wire].is_buffered()) { + f << "wire<" << wire->width << ">"; + } else { + f << "value<" << wire->width << ">"; + } + dump_const_init(wire_init.at(wire), wire->width); + f << ";\n"; + + if (edge_wires[wire] && !wire_types[wire].is_buffered()) { + f << indent << "prev_" << mangle(wire) << " = "; + dump_const(wire_init.at(wire), wire->width); + f << ";\n"; + } + } + for (auto &mem : mod_memories[module]) { + for (auto &init : mem.inits) { if (init.removed) continue; dump_attrs(&init); - int words = GetSize(init.data) / mem->width; - f << indent << "memory<" << mem->width << ">::init<" << words << "> { " - << stringf("%#x", init.addr.as_int()) << ", {"; + int words = GetSize(init.data) / mem.width; + f << indent << "static const value<" << mem.width << "> "; + f << "mem_init_" << ++mem_init_idx << "[" << words << "] {"; inc_indent(); for (int n = 0; n < words; n++) { if (n % 4 == 0) f << "\n" << indent; else f << " "; - dump_const(init.data, mem->width, n * mem->width, /*fixed_width=*/true); + dump_const(init.data, mem.width, n * mem.width, /*fixed_width=*/true); f << ","; } dec_indent(); - f << "\n" << indent << "}},\n"; + f << "\n"; + f << indent << "};\n"; + f << indent << "std::copy(std::begin(mem_init_" << mem_init_idx << "), "; + f << "std::end(mem_init_" << mem_init_idx << "), "; + f << "&" << mangle(&mem) << ".data[" << stringf("%#x", init.addr.as_int()) << "]);\n"; } - dec_indent(); - f << indent << "};\n"; - } + } + for (auto cell : module->cells()) { + if (is_internal_cell(cell->type)) + continue; + f << indent << mangle(cell); + RTLIL::Module *cell_module = module->design->module(cell->type); + if (cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) { + f << "->reset();\n"; + } else { + f << ".reset();\n"; + } + } + dec_indent(); } void dump_eval_method(RTLIL::Module *module) @@ -2185,6 +2230,10 @@ struct CxxrtlWorker { dump_wire(wire, /*is_local=*/false); } f << "\n"; + f << indent << "void reset() override {\n"; + dump_reset_method(module); + f << indent << "}\n"; + f << "\n"; f << indent << "bool eval() override {\n"; dump_eval_method(module); f << indent << "}\n"; @@ -2233,7 +2282,9 @@ struct CxxrtlWorker { dump_debug_wire(wire, /*is_local=*/false); bool has_memories = false; for (auto &mem : mod_memories[module]) { - dump_memory(&mem); + dump_attrs(&mem); + f << indent << "memory<" << mem.width << "> " << mangle(&mem) + << " { " << mem.size << "u };\n"; has_memories = true; } if (has_memories) @@ -2254,52 +2305,20 @@ struct CxxrtlWorker { dump_metadata_map(cell->attributes); f << ");\n"; } else { - f << indent << mangle(cell_module) << " " << mangle(cell) << ";\n"; + f << indent << mangle(cell_module) << " " << mangle(cell) << " {interior()};\n"; } has_cells = true; } if (has_cells) f << "\n"; - f << indent << mangle(module) << "() {}\n"; - if (has_cells) { - f << indent << mangle(module) << "(adopt, " << mangle(module) << " other) :\n"; - bool first = true; - for (auto cell : module->cells()) { - if (is_internal_cell(cell->type)) - continue; - if (first) { - first = false; - } else { - f << ",\n"; - } - RTLIL::Module *cell_module = module->design->module(cell->type); - if (cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) { - f << indent << " " << mangle(cell) << "(std::move(other." << mangle(cell) << "))"; - } else { - f << indent << " " << mangle(cell) << "(adopt {}, std::move(other." << mangle(cell) << "))"; - } - } - f << " {\n"; - inc_indent(); - for (auto cell : module->cells()) { - if (is_internal_cell(cell->type)) - continue; - RTLIL::Module *cell_module = module->design->module(cell->type); - if (cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) - f << indent << mangle(cell) << "->reset();\n"; - } - dec_indent(); - f << indent << "}\n"; - } else { - f << indent << mangle(module) << "(adopt, " << mangle(module) << " other) {}\n"; - } - f << "\n"; - f << indent << "void reset() override {\n"; + f << indent << mangle(module) << "(interior) {}\n"; + f << indent << mangle(module) << "() {\n"; inc_indent(); - f << indent << "*this = " << mangle(module) << "(adopt {}, std::move(*this));\n"; + f << indent << "reset();\n"; dec_indent(); - f << indent << "}\n"; + f << indent << "};\n"; f << "\n"; + f << indent << "void reset() override;\n"; f << indent << "bool eval() override;\n"; f << indent << "bool commit() override;\n"; if (debug_info) { @@ -2326,6 +2345,10 @@ struct CxxrtlWorker { { if (module->get_bool_attribute(ID(cxxrtl_blackbox))) return; + f << indent << "void " << mangle(module) << "::reset() {\n"; + dump_reset_method(module); + f << indent << "}\n"; + f << "\n"; f << indent << "bool " << mangle(module) << "::eval() {\n"; dump_eval_method(module); f << indent << "}\n"; @@ -2573,7 +2596,7 @@ struct CxxrtlWorker { flow.add_node(cell); // Various DFF cells are treated like posedge/negedge processes, see above for details. - if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) { + if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) { if (is_valid_clock(cell->getPort(ID::CLK))) register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); @@ -2883,15 +2906,16 @@ struct CxxrtlWorker { debug_wire_type = {WireType::INLINE, node->cell}; // wire replaced with cell break; case FlowGraph::Node::Type::CONNECT: - debug_wire_type = {WireType::INLINE, node->connect.second}; // wire replaced with sig + debug_wire_type = {WireType::INLINE, node->connect.second}; // wire replaced with sig break; default: continue; } debug_live_nodes.erase(node); - } else if (wire_type.is_member() || wire_type.is_local()) { + } else if (wire_type.is_member() || wire_type.type == WireType::LOCAL) { debug_wire_type = wire_type; // wire not inlinable } else { - log_assert(wire_type.type == WireType::UNUSED); + log_assert(wire_type.type == WireType::INLINE || + wire_type.type == WireType::UNUSED); if (flow.wire_comb_defs[wire].size() == 0) { if (wire_init.count(wire)) { // wire never modified debug_wire_type = {WireType::CONST, wire_init.at(wire)}; diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 37010844432..7722d0c3394 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -107,8 +107,8 @@ struct EdifBackend : public Backend { log(" constant drivers first)\n"); log("\n"); log(" -gndvccy\n"); - log(" create \"GND\" and \"VCC\" cells with \"Y\" outputs. (the default is \"G\"\n"); - log(" for \"GND\" and \"P\" for \"VCC\".)\n"); + log(" create \"GND\" and \"VCC\" cells with \"Y\" outputs. (the default is\n"); + log(" \"G\" for \"GND\" and \"P\" for \"VCC\".)\n"); log("\n"); log(" -attrprop\n"); log(" create EDIF properties for cell attributes\n"); diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 7abe584c9cc..eb30ab4b948 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -346,6 +346,12 @@ void emit_elaborated_extmodules(RTLIL::Design *design, std::ostream &f) { // Find the module corresponding to this instance. auto modInstance = design->module(cell->type); + // Ensure that we actually have a module instance + if (modInstance == nullptr) { + log_error("Unknown cell type %s\n", cell->type.c_str()); + return; + } + bool modIsBlackbox = modInstance->get_blackbox_attribute(); if (modIsBlackbox) @@ -729,12 +735,12 @@ struct FirrtlWorker always_uint = true; firrtl_width = max(a_width, b_width); } - else if ((cell->type == ID($eq)) | (cell->type == ID($eqx))) { + else if ((cell->type == ID($eq)) || (cell->type == ID($eqx))) { primop = "eq"; always_uint = true; firrtl_width = 1; } - else if ((cell->type == ID($ne)) | (cell->type == ID($nex))) { + else if ((cell->type == ID($ne)) || (cell->type == ID($nex))) { primop = "neq"; always_uint = true; firrtl_width = 1; @@ -759,7 +765,7 @@ struct FirrtlWorker always_uint = true; firrtl_width = 1; } - else if ((cell->type == ID($shl)) | (cell->type == ID($sshl))) { + else if ((cell->type == ID($shl)) || (cell->type == ID($sshl))) { // FIRRTL will widen the result (y) by the amount of the shift. // We'll need to offset this by extracting the un-widened portion as Verilog would do. extract_y_bits = true; @@ -777,7 +783,7 @@ struct FirrtlWorker firrtl_width = a_width + (1 << b_width) - 1; } } - else if ((cell->type == ID($shr)) | (cell->type == ID($sshr))) { + else if ((cell->type == ID($shr)) || (cell->type == ID($sshr))) { // We don't need to extract a specific range of bits. extract_y_bits = false; // Is the shift amount constant? @@ -1188,6 +1194,8 @@ struct FirrtlBackend : public Backend { log("Write a FIRRTL netlist of the current design.\n"); log("The following commands are executed by this command:\n"); log(" pmuxtree\n"); + log(" bmuxmap\n"); + log(" demuxmap\n"); log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) override @@ -1210,7 +1218,10 @@ struct FirrtlBackend : public Backend { log_header(design, "Executing FIRRTL backend.\n"); log_push(); - Pass::call(design, stringf("pmuxtree")); + Pass::call(design, "pmuxtree"); + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); + Pass::call(design, "bwmuxmap"); namecache.clear(); autoid_counter = 0; @@ -1233,6 +1244,9 @@ struct FirrtlBackend : public Backend { if (top == nullptr) top = last; + if (!top) + log_cmd_error("There is no top module in this design!\n"); + std::string circuitFileinfo = getFileinfo(top); *f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo.c_str()); diff --git a/backends/jny/Makefile.inc b/backends/jny/Makefile.inc new file mode 100644 index 00000000000..5e417128ed9 --- /dev/null +++ b/backends/jny/Makefile.inc @@ -0,0 +1,2 @@ + +OBJS += backends/jny/jny.o diff --git a/backends/jny/jny.cc b/backends/jny/jny.cc new file mode 100644 index 00000000000..0be11a52cca --- /dev/null +++ b/backends/jny/jny.cc @@ -0,0 +1,578 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Aki "lethalbit" Van Ness + * + * 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/rtlil.h" +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/celltypes.h" +#include "kernel/cellaigs.h" +#include "kernel/log.h" +#include +#include +#include +#include +#include +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + + +struct JnyWriter +{ + private: + std::ostream &f; + bool _use_selection; + + // XXX(aki): TODO: this needs to be updated to us + // dict and then coalesce_cells needs to be updated + // but for now for the PoC this looks to be sufficient + std::unordered_map> _cells{}; + + bool _include_connections; + bool _include_attributes; + bool _include_properties; + + string escape_string(string str) { + std::string newstr; + + auto itr = str.begin(); + + for(; itr != str.end(); ++itr) { + switch (*itr) { + case '\\': { + newstr += "\\\\"; + break; + } case '\n': { + newstr += "\\n"; + break; + } case '\f': { + newstr += "\\f"; + break; + } case '\t': { + newstr += "\\t"; + break; + } case '\r': { + newstr += "\\r"; + break; + } case '\"': { + newstr += "\\\""; + break; + } case '\b': { + newstr += "\\b"; + break; + } default: { + newstr += *itr; + } + } + } + + return newstr; + } + + // XXX(aki): I know this is far from ideal but i'm out of spoons and cant focus so + // it'll have to do for now, + void coalesce_cells(Module* mod) + { + _cells.clear(); + for (auto cell : mod->cells()) { + const auto cell_type = escape_string(RTLIL::unescape_id(cell->type)); + + if (_cells.find(cell_type) == _cells.end()) + _cells.emplace(cell_type, std::vector()); + + _cells.at(cell_type).push_back(cell); + } + } + + // XXX(aki): this is a lazy way to do this i know,,, + std::string gen_indent(const uint16_t level) + { + std::stringstream s; + for (uint16_t i = 0; i <= level; ++i) + { + s << " "; + } + return s.str(); + } + + public: + JnyWriter(std::ostream &f, bool use_selection, bool connections, bool attributes, bool properties) noexcept: + f(f), _use_selection(use_selection), + _include_connections(connections), _include_attributes(attributes), _include_properties(properties) + { } + + void write_metadata(Design *design, uint16_t indent_level = 0, std::string invk = "") + { + log_assert(design != nullptr); + + design->sort(); + + f << "{\n"; + f << " \"$schema\": \"https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json\",\n"; + f << stringf(" \"generator\": \"%s\",\n", escape_string(yosys_version_str).c_str()); + f << " \"version\": \"0.0.1\",\n"; + f << " \"invocation\": \"" << escape_string(invk) << "\",\n"; + f << " \"features\": ["; + + size_t fnum{0}; + if (_include_connections) { + ++fnum; + f << "\"connections\""; + } + + if (_include_attributes) { + if (fnum > 0) + f << ", "; + ++fnum; + f << "\"attributes\""; + } + + if (_include_properties) { + if (fnum > 0) + f << ", "; + ++fnum; + f << "\"properties\""; + } + + f << "],\n"; + + f << " \"modules\": [\n"; + + bool first{true}; + for (auto mod : _use_selection ? design->selected_modules() : design->modules()) { + if (!first) + f << ",\n"; + write_module(mod, indent_level + 2); + first = false; + } + + f << "\n"; + f << " ]\n"; + f << "}\n"; + } + + void write_sigspec(const RTLIL::SigSpec& sig, uint16_t indent_level = 0) { + const auto _indent = gen_indent(indent_level); + + f << _indent << " {\n"; + f << _indent << " \"width\": \"" << sig.size() << "\",\n"; + f << _indent << " \"type\": \""; + + if (sig.is_wire()) { + f << "wire"; + } else if (sig.is_chunk()) { + f << "chunk"; + } else if (sig.is_bit()) { + f << "bit"; + } else { + f << "unknown"; + } + f << "\",\n"; + + f << _indent << " \"const\": "; + if (sig.has_const()) { + f << "true"; + } else { + f << "false"; + } + + f << "\n"; + + f << _indent << " }"; + } + + void write_mod_conn(const std::pair& conn, uint16_t indent_level = 0) { + const auto _indent = gen_indent(indent_level); + f << _indent << " {\n"; + f << _indent << " \"signals\": [\n"; + + write_sigspec(conn.first, indent_level + 2); + f << ",\n"; + write_sigspec(conn.second, indent_level + 2); + f << "\n"; + + f << _indent << " ]\n"; + f << _indent << " }"; + } + + void write_cell_conn(const std::pair& sig, uint16_t indent_level = 0) { + const auto _indent = gen_indent(indent_level); + f << _indent << " {\n"; + f << _indent << " \"name\": \"" << escape_string(RTLIL::unescape_id(sig.first)) << "\",\n"; + f << _indent << " \"signals\": [\n"; + + write_sigspec(sig.second, indent_level + 2); + f << "\n"; + + f << _indent << " ]\n"; + f << _indent << " }"; + } + + void write_module(Module* mod, uint16_t indent_level = 0) { + log_assert(mod != nullptr); + + coalesce_cells(mod); + + const auto _indent = gen_indent(indent_level); + + f << _indent << "{\n"; + f << stringf(" %s\"name\": \"%s\",\n", _indent.c_str(), escape_string(RTLIL::unescape_id(mod->name)).c_str()); + f << _indent << " \"cell_sorts\": [\n"; + + bool first_sort{true}; + for (auto& sort : _cells) { + if (!first_sort) + f << ",\n"; + write_cell_sort(sort, indent_level + 2); + first_sort = false; + } + f << "\n"; + + f << _indent << " ]"; + if (_include_connections) { + f << ",\n" << _indent << " \"connections\": [\n"; + + bool first_conn{true}; + for (const auto& conn : mod->connections()) { + if (!first_conn) + f << ",\n"; + + write_mod_conn(conn, indent_level + 2); + + first_conn = false; + } + + f << _indent << " ]"; + } + if (_include_attributes) { + f << ",\n" << _indent << " \"attributes\": {\n"; + + write_prams(mod->attributes, indent_level + 2); + + f << "\n"; + f << _indent << " }"; + } + f << "\n" << _indent << "}"; + } + + void write_cell_ports(RTLIL::Cell* port_cell, uint64_t indent_level = 0) { + const auto _indent = gen_indent(indent_level); + + bool first_port{true}; + for (auto con : port_cell->connections()) { + if (!first_port) + f << ",\n"; + + f << _indent << " {\n"; + f << stringf(" %s\"name\": \"%s\",\n", _indent.c_str(), escape_string(RTLIL::unescape_id(con.first)).c_str()); + f << _indent << " \"direction\": \""; + if (port_cell->input(con.first)) + f << "i"; + if (port_cell->input(con.first)) + f << "o"; + f << "\",\n"; + if (con.second.size() == 1) + f << _indent << " \"range\": [0, 0]\n"; + else + f << stringf(" %s\"range\": [%d, %d]\n", _indent.c_str(), con.second.size(), 0); + f << _indent << " }"; + + first_port = false; + } + f << "\n"; + } + + + void write_cell_sort(std::pair>& sort, uint16_t indent_level = 0) { + const auto port_cell = sort.second.front(); + const auto _indent = gen_indent(indent_level); + + f << _indent << "{\n"; + f << stringf(" %s\"type\": \"%s\",\n", _indent.c_str(), sort.first.c_str()); + f << _indent << " \"ports\": [\n"; + + write_cell_ports(port_cell, indent_level + 2); + + f << _indent << " ],\n" << _indent << " \"cells\": [\n"; + + bool first_cell{true}; + for (auto& cell : sort.second) { + if (!first_cell) + f << ",\n"; + + write_cell(cell, indent_level + 2); + + first_cell = false; + } + + f << "\n"; + f << _indent << " ]\n"; + f << _indent << "}"; + } + + void write_param_val(const Const& v) { + if ((v.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) == RTLIL::ConstFlags::CONST_FLAG_STRING) { + const auto str = v.decode_string(); + + // XXX(aki): TODO, uh, yeah + + f << "\"" << escape_string(str) << "\""; + } else if ((v.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) == RTLIL::ConstFlags::CONST_FLAG_SIGNED) { + f << stringf("\"%dsd %d\"", v.size(), v.as_int(true)); + } else if ((v.flags & RTLIL::ConstFlags::CONST_FLAG_REAL) == RTLIL::ConstFlags::CONST_FLAG_REAL) { + + } else { + f << "\"" << escape_string(v.as_string()) << "\""; + } + } + + void write_prams(dict& params, uint16_t indent_level = 0) { + const auto _indent = gen_indent(indent_level); + + bool first_param{true}; + for (auto& param : params) { + if (!first_param) + f << stringf(",\n"); + const auto param_val = param.second; + if (!param_val.empty()) { + f << stringf(" %s\"%s\": ", _indent.c_str(), escape_string(RTLIL::unescape_id(param.first)).c_str()); + write_param_val(param_val); + } else { + f << stringf(" %s\"%s\": true", _indent.c_str(), escape_string(RTLIL::unescape_id(param.first)).c_str()); + } + + first_param = false; + } + } + + void write_cell(Cell* cell, uint16_t indent_level = 0) { + const auto _indent = gen_indent(indent_level); + log_assert(cell != nullptr); + + f << _indent << " {\n"; + f << stringf(" %s\"name\": \"%s\"", _indent.c_str(), escape_string(RTLIL::unescape_id(cell->name)).c_str()); + + if (_include_connections) { + f << ",\n" << _indent << " \"connections\": [\n"; + + bool first_conn{true}; + for (const auto& conn : cell->connections()) { + if (!first_conn) + f << ",\n"; + + write_cell_conn(conn, indent_level + 2); + + first_conn = false; + } + + f << "\n"; + f << _indent << " ]"; + } + + if (_include_attributes) { + f << ",\n" << _indent << " \"attributes\": {\n"; + + write_prams(cell->attributes, indent_level + 2); + + f << "\n"; + f << _indent << " }"; + } + + if (_include_properties) { + f << ",\n" << _indent << " \"parameters\": {\n"; + + write_prams(cell->parameters, indent_level + 2); + + f << "\n"; + f << _indent << " }"; + } + + f << "\n" << _indent << " }"; + } +}; + +struct JnyBackend : public Backend { + JnyBackend() : Backend("jny", "generate design metadata") { } + void help() override { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" jny [options] [selection]\n"); + log("\n"); + log("Write JSON netlist metadata for the current design\n"); + log("\n"); + log(" -no-connections\n"); + log(" Don't include connection information in the netlist output.\n"); + log("\n"); + log(" -no-attributes\n"); + log(" Don't include attributed information in the netlist output.\n"); + log("\n"); + log(" -no-properties\n"); + log(" Don't include property information in the netlist output.\n"); + log("\n"); + log("The JSON schema for JNY output files is located in the \"jny.schema.json\" file\n"); + log("which is located at \"https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json\"\n"); + log("\n"); + } + + void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) override { + + bool connections{true}; + bool attributes{true}; + bool properties{true}; + + size_t argidx{1}; + for (; argidx < args.size(); argidx++) { + if (args[argidx] == "-no-connections") { + connections = false; + continue; + } + + if (args[argidx] == "-no-attributes") { + attributes = false; + continue; + } + + if (args[argidx] == "-no-properties") { + properties = false; + continue; + } + + break; + } + + // Compose invocation line + std::ostringstream invk; + if (!args.empty()) { + std::copy(args.begin(), args.end(), + std::ostream_iterator(invk, " ") + ); + } + invk << filename; + + extra_args(f, filename, args, argidx); + + log_header(design, "Executing jny backend.\n"); + + JnyWriter jny_writer(*f, false, connections, attributes, properties); + jny_writer.write_metadata(design, 0, invk.str()); + } + +} JnyBackend; + + +struct JnyPass : public Pass { + JnyPass() : Pass("jny", "write design and metadata") { } + + void help() override { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" jny [options] [selection]\n"); + log("\n"); + log("Write JSON netlist metadata for the current design\n"); + log("\n"); + log(" -o \n"); + log(" write to the specified file.\n"); + log("\n"); + log(" -no-connections\n"); + log(" Don't include connection information in the netlist output.\n"); + log("\n"); + log(" -no-attributes\n"); + log(" Don't include attributed information in the netlist output.\n"); + log("\n"); + log(" -no-properties\n"); + log(" Don't include property information in the netlist output.\n"); + log("\n"); + log("See 'help write_jny' for a description of the JSON format used.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override { + std::string filename{}; + + bool connections{true}; + bool attributes{true}; + bool properties{true}; + + size_t argidx{1}; + for (; argidx < args.size(); argidx++) { + if (args[argidx] == "-o" && argidx+1 < args.size()) { + filename = args[++argidx]; + continue; + } + + if (args[argidx] == "-no-connections") { + connections = false; + continue; + } + + if (args[argidx] == "-no-attributes") { + attributes = false; + continue; + } + + if (args[argidx] == "-no-properties") { + properties = false; + continue; + } + + break; + } + + // Compose invocation line + std::ostringstream invk; + if (!args.empty()) { + std::copy(args.begin(), args.end(), + std::ostream_iterator(invk, " ") + ); + } + + extra_args(args, argidx, design); + + std::ostream *f; + std::stringstream buf; + bool empty = filename.empty(); + + if (!empty) { + rewrite_filename(filename); + std::ofstream *ff = new std::ofstream; + ff->open(filename.c_str(), std::ofstream::trunc); + if (ff->fail()) { + delete ff; + log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + } + f = ff; + invk << filename; + } else { + f = &buf; + } + + + JnyWriter jny_writer(*f, false, connections, attributes, properties); + jny_writer.write_metadata(design, 0, invk.str()); + + if (!empty) { + delete f; + } else { + log("%s", buf.str().c_str()); + } + } + +} JnyPass; + +PRIVATE_NAMESPACE_END diff --git a/backends/json/json.cc b/backends/json/json.cc index 4aa8046d602..fd2c922fd5d 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -52,8 +52,23 @@ struct JsonWriter string newstr = "\""; for (char c : str) { if (c == '\\') + newstr += "\\\\"; + else if (c == '"') + newstr += "\\\""; + else if (c == '\b') + newstr += "\\b"; + else if (c == '\f') + newstr += "\\f"; + else if (c == '\n') + newstr += "\\n"; + else if (c == '\r') + newstr += "\\r"; + else if (c == '\t') + newstr += "\\t"; + else if (c < 0x20) + newstr += stringf("\\u%04X", c); + else newstr += c; - newstr += c; } return newstr + "\""; } @@ -379,10 +394,11 @@ struct JsonBackend : public Backend { log(" \"bits\": \n"); log(" \"offset\": \n"); log(" \"upto\": <1 if the port bit indexing is MSB-first>\n"); + log(" \"signed\": <1 if the port is signed>\n"); log(" }\n"); log("\n"); - log("The \"offset\" and \"upto\" fields are skipped if their value would be 0."); - log("They don't affect connection semantics, and are only used to preserve original"); + log("The \"offset\" and \"upto\" fields are skipped if their value would be 0.\n"); + log("They don't affect connection semantics, and are only used to preserve original\n"); log("HDL bit indexing."); log("And is:\n"); log("\n"); @@ -428,6 +444,7 @@ struct JsonBackend : public Backend { log(" \"bits\": \n"); log(" \"offset\": \n"); log(" \"upto\": <1 if the port bit indexing is MSB-first>\n"); + log(" \"signed\": <1 if the port is signed>\n"); log(" }\n"); log("\n"); log("The \"hide_name\" fields are set to 1 when the name of this cell or net is\n"); @@ -442,8 +459,8 @@ struct JsonBackend : public Backend { log("connected to a constant driver are denoted as string \"0\", \"1\", \"x\", or\n"); log("\"z\" instead of a number.\n"); log("\n"); - log("Bit vectors (including integers) are written as string holding the binary"); - log("representation of the value. Strings are written as strings, with an appended"); + log("Bit vectors (including integers) are written as string holding the binary\n"); + log("representation of the value. Strings are written as strings, with an appended\n"); log("blank in cases of strings of the form /[01xz]* */.\n"); log("\n"); log("For example the following Verilog code:\n"); @@ -649,8 +666,9 @@ struct JsonPass : public Pass { std::ostream *f; std::stringstream buf; + bool empty = filename.empty(); - if (!filename.empty()) { + if (!empty) { rewrite_filename(filename); std::ofstream *ff = new std::ofstream; ff->open(filename.c_str(), std::ofstream::trunc); @@ -666,7 +684,7 @@ struct JsonPass : public Pass { JsonWriter json_writer(*f, true, aig_mode, compat_int_mode); json_writer.write_design(design); - if (!filename.empty()) { + if (!empty) { delete f; } else { log("%s", buf.str().c_str()); diff --git a/backends/protobuf/.gitignore b/backends/protobuf/.gitignore deleted file mode 100644 index 849b38d45aa..00000000000 --- a/backends/protobuf/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -yosys.pb.cc -yosys.pb.h diff --git a/backends/protobuf/Makefile.inc b/backends/protobuf/Makefile.inc deleted file mode 100644 index 834cad42cde..00000000000 --- a/backends/protobuf/Makefile.inc +++ /dev/null @@ -1,8 +0,0 @@ -ifeq ($(ENABLE_PROTOBUF),1) - -backends/protobuf/yosys.pb.cc backends/protobuf/yosys.pb.h: misc/yosys.proto - $(Q) cd misc && protoc --cpp_out "../backends/protobuf" yosys.proto - -OBJS += backends/protobuf/protobuf.o backends/protobuf/yosys.pb.o - -endif diff --git a/backends/protobuf/protobuf.cc b/backends/protobuf/protobuf.cc deleted file mode 100644 index 384ce2e8e10..00000000000 --- a/backends/protobuf/protobuf.cc +++ /dev/null @@ -1,371 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Claire Xenia Wolf - * Copyright (C) 2018 Serge Bazanski - * - * 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 - -#include "kernel/rtlil.h" -#include "kernel/register.h" -#include "kernel/sigtools.h" -#include "kernel/celltypes.h" -#include "kernel/cellaigs.h" -#include "kernel/log.h" -#include "yosys.pb.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct ProtobufDesignSerializer -{ - bool aig_mode_; - bool use_selection_; - yosys::pb::Design *pb_; - - Design *design_; - Module *module_; - - SigMap sigmap_; - int sigidcounter_; - dict sigids_; - pool aig_models_; - - - ProtobufDesignSerializer(bool use_selection, bool aig_mode) : - aig_mode_(aig_mode), use_selection_(use_selection) { } - - string get_name(IdString name) - { - return RTLIL::unescape_id(name); - } - - - void serialize_parameters(google::protobuf::Map *out, - const dict ¶meters) - { - for (auto ¶m : parameters) { - std::string key = get_name(param.first); - - - yosys::pb::Parameter pb_param; - - if ((param.second.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) != 0) { - pb_param.set_str(param.second.decode_string()); - } else if (GetSize(param.second.bits) > 64) { - pb_param.set_str(param.second.as_string()); - } else { - pb_param.set_int_(param.second.as_int()); - } - - (*out)[key] = pb_param; - } - } - - void get_bits(yosys::pb::BitVector *out, SigSpec sig) - { - for (auto bit : sigmap_(sig)) { - auto sig = out->add_signal(); - - // Constant driver. - if (bit.wire == nullptr) { - if (bit == State::S0) sig->set_constant(sig->CONSTANT_DRIVER_LOW); - else if (bit == State::S1) sig->set_constant(sig->CONSTANT_DRIVER_HIGH); - else if (bit == State::Sz) sig->set_constant(sig->CONSTANT_DRIVER_Z); - else sig->set_constant(sig->CONSTANT_DRIVER_X); - continue; - } - - // Signal - give it a unique identifier. - if (sigids_.count(bit) == 0) { - sigids_[bit] = sigidcounter_++; - } - sig->set_id(sigids_[bit]); - } - } - - void serialize_module(yosys::pb::Module* out, Module *module) - { - module_ = module; - log_assert(module_->design == design_); - sigmap_.set(module_); - sigids_.clear(); - sigidcounter_ = 0; - - serialize_parameters(out->mutable_attribute(), module_->attributes); - - for (auto n : module_->ports) { - Wire *w = module->wire(n); - if (use_selection_ && !module_->selected(w)) - continue; - - yosys::pb::Module::Port pb_port; - pb_port.set_direction(w->port_input ? w->port_output ? - yosys::pb::DIRECTION_INOUT : yosys::pb::DIRECTION_INPUT : yosys::pb::DIRECTION_OUTPUT); - get_bits(pb_port.mutable_bits(), w); - (*out->mutable_port())[get_name(n)] = pb_port; - } - - for (auto c : module_->cells()) { - if (use_selection_ && !module_->selected(c)) - continue; - - yosys::pb::Module::Cell pb_cell; - pb_cell.set_hide_name(c->name[0] == '$'); - pb_cell.set_type(get_name(c->type)); - - if (aig_mode_) { - Aig aig(c); - if (aig.name.empty()) - continue; - pb_cell.set_model(aig.name); - aig_models_.insert(aig); - } - serialize_parameters(pb_cell.mutable_parameter(), c->parameters); - serialize_parameters(pb_cell.mutable_attribute(), c->attributes); - - if (c->known()) { - for (auto &conn : c->connections()) { - yosys::pb::Direction direction = yosys::pb::DIRECTION_OUTPUT; - if (c->input(conn.first)) - direction = c->output(conn.first) ? yosys::pb::DIRECTION_INOUT : yosys::pb::DIRECTION_INPUT; - (*pb_cell.mutable_port_direction())[get_name(conn.first)] = direction; - } - } - for (auto &conn : c->connections()) { - yosys::pb::BitVector vec; - get_bits(&vec, conn.second); - (*pb_cell.mutable_connection())[get_name(conn.first)] = vec; - } - - (*out->mutable_cell())[get_name(c->name)] = pb_cell; - } - - for (auto w : module_->wires()) { - if (use_selection_ && !module_->selected(w)) - continue; - - auto netname = out->add_netname(); - netname->set_hide_name(w->name[0] == '$'); - get_bits(netname->mutable_bits(), w); - serialize_parameters(netname->mutable_attributes(), w->attributes); - } - } - - - void serialize_models(google::protobuf::Map *models) - { - for (auto &aig : aig_models_) { - yosys::pb::Model pb_model; - for (auto &node : aig.nodes) { - auto pb_node = pb_model.add_node(); - if (node.portbit >= 0) { - if (node.inverter) { - pb_node->set_type(pb_node->TYPE_NPORT); - } else { - pb_node->set_type(pb_node->TYPE_PORT); - } - auto port = pb_node->mutable_port(); - port->set_portname(log_id(node.portname)); - port->set_bitindex(node.portbit); - } else if (node.left_parent < 0 && node.right_parent < 0) { - if (node.inverter) { - pb_node->set_type(pb_node->TYPE_TRUE); - } else { - pb_node->set_type(pb_node->TYPE_FALSE); - } - } else { - if (node.inverter) { - pb_node->set_type(pb_node->TYPE_NAND); - } else { - pb_node->set_type(pb_node->TYPE_AND); - } - auto gate = pb_node->mutable_gate(); - gate->set_left(node.left_parent); - gate->set_right(node.right_parent); - } - for (auto &op : node.outports) { - auto pb_op = pb_node->add_out_port(); - pb_op->set_name(log_id(op.first)); - pb_op->set_bit_index(op.second); - } - } - (*models)[aig.name] = pb_model; - } - } - - void serialize_design(yosys::pb::Design *pb, Design *design) - { - GOOGLE_PROTOBUF_VERIFY_VERSION; - pb_ = pb; - pb_->Clear(); - pb_->set_creator(yosys_version_str); - - design_ = design; - design_->sort(); - - auto modules = use_selection_ ? design_->selected_modules() : design_->modules(); - for (auto mod : modules) { - yosys::pb::Module pb_mod; - serialize_module(&pb_mod, mod); - (*pb->mutable_modules())[mod->name.str()] = pb_mod; - } - - serialize_models(pb_->mutable_models()); - } -}; - -struct ProtobufBackend : public Backend { - ProtobufBackend(): Backend("protobuf", "write design to a Protocol Buffer file") { } - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" write_protobuf [options] [filename]\n"); - log("\n"); - log("Write a JSON netlist of the current design.\n"); - log("\n"); - log(" -aig\n"); - log(" include AIG models for the different gate types\n"); - log("\n"); - log(" -text\n"); - log(" output protobuf in Text/ASCII representation\n"); - log("\n"); - log("The schema of the output Protocol Buffer is defined in misc/yosys.pb in the\n"); - log("Yosys source code distribution.\n"); - log("\n"); - } - void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) override - { - bool aig_mode = false; - bool text_mode = false; - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-aig") { - aig_mode = true; - continue; - } - if (args[argidx] == "-text") { - text_mode = true; - continue; - } - break; - } - extra_args(f, filename, args, argidx, !text_mode); - - log_header(design, "Executing Protobuf backend.\n"); - - yosys::pb::Design pb; - ProtobufDesignSerializer serializer(false, aig_mode); - serializer.serialize_design(&pb, design); - - if (text_mode) { - string out; - google::protobuf::TextFormat::PrintToString(pb, &out); - *f << out; - } else { - pb.SerializeToOstream(f); - } - } -} ProtobufBackend; - -struct ProtobufPass : public Pass { - ProtobufPass() : Pass("protobuf", "write design in Protobuf format") { } - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" protobuf [options] [selection]\n"); - log("\n"); - log("Write a JSON netlist of all selected objects.\n"); - log("\n"); - log(" -o \n"); - log(" write to the specified file.\n"); - log("\n"); - log(" -aig\n"); - log(" include AIG models for the different gate types\n"); - log("\n"); - log(" -text\n"); - log(" output protobuf in Text/ASCII representation\n"); - log("\n"); - log("The schema of the output Protocol Buffer is defined in misc/yosys.pb in the\n"); - log("Yosys source code distribution.\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) override - { - std::string filename; - bool aig_mode = false; - bool text_mode = false; - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-o" && argidx+1 < args.size()) { - filename = args[++argidx]; - continue; - } - if (args[argidx] == "-aig") { - aig_mode = true; - continue; - } - if (args[argidx] == "-text") { - text_mode = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - std::ostream *f; - std::stringstream buf; - - if (!filename.empty()) { - rewrite_filename(filename); - std::ofstream *ff = new std::ofstream; - ff->open(filename.c_str(), text_mode ? std::ofstream::trunc : (std::ofstream::trunc | std::ofstream::binary)); - if (ff->fail()) { - delete ff; - log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); - } - f = ff; - } else { - f = &buf; - } - - yosys::pb::Design pb; - ProtobufDesignSerializer serializer(true, aig_mode); - serializer.serialize_design(&pb, design); - - if (text_mode) { - string out; - google::protobuf::TextFormat::PrintToString(pb, &out); - *f << out; - } else { - pb.SerializeToOstream(f); - } - - if (!filename.empty()) { - delete f; - } else { - log("%s", buf.str().c_str()); - } - } -} ProtobufPass; - -PRIVATE_NAMESPACE_END; diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index a6e45b2f2e9..574eb3aaad1 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -51,15 +51,19 @@ void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi } } f << stringf("%d'", width); - for (int i = offset+width-1; i >= offset; i--) { - log_assert(i < (int)data.bits.size()); - switch (data.bits[i]) { - case State::S0: f << stringf("0"); break; - case State::S1: f << stringf("1"); break; - case RTLIL::Sx: f << stringf("x"); break; - case RTLIL::Sz: f << stringf("z"); break; - case RTLIL::Sa: f << stringf("-"); break; - case RTLIL::Sm: f << stringf("m"); break; + if (data.is_fully_undef_x_only()) { + f << "x"; + } else { + for (int i = offset+width-1; i >= offset; i--) { + log_assert(i < (int)data.bits.size()); + switch (data.bits[i]) { + case State::S0: f << stringf("0"); break; + case State::S1: f << stringf("1"); break; + case RTLIL::Sx: f << stringf("x"); break; + case RTLIL::Sz: f << stringf("z"); break; + case RTLIL::Sa: f << stringf("-"); break; + case RTLIL::Sm: f << stringf("m"); break; + } } } } else { @@ -71,7 +75,7 @@ void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi else if (str[i] == '\t') f << stringf("\\t"); else if (str[i] < 32) - f << stringf("\\%03o", str[i]); + f << stringf("\\%03o", (unsigned char)str[i]); else if (str[i] == '"') f << stringf("\\\""); else if (str[i] == '\\') @@ -354,8 +358,8 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu bool first_conn_line = true; for (auto it = module->connections().begin(); it != module->connections().end(); ++it) { - bool show_conn = !only_selected; - if (only_selected) { + bool show_conn = !only_selected || design->selected_whole_module(module->name); + if (!show_conn) { RTLIL::SigSpec sigs = it->first; sigs.append(it->second); for (auto &c : sigs.chunks()) { @@ -526,8 +530,9 @@ struct DumpPass : public Pass { std::ostream *f; std::stringstream buf; + bool empty = filename.empty(); - if (!filename.empty()) { + if (!empty) { rewrite_filename(filename); std::ofstream *ff = new std::ofstream; ff->open(filename.c_str(), append ? std::ofstream::app : std::ofstream::trunc); @@ -542,7 +547,7 @@ struct DumpPass : public Pass { RTLIL_BACKEND::dump_design(*f, design, true, flag_m, flag_n); - if (!filename.empty()) { + if (!empty) { delete f; } else { log("%s", buf.str().c_str()); diff --git a/backends/smt2/Makefile.inc b/backends/smt2/Makefile.inc index fb01308bd8a..3afe990e769 100644 --- a/backends/smt2/Makefile.inc +++ b/backends/smt2/Makefile.inc @@ -7,6 +7,7 @@ ifneq ($(CONFIG),emcc) # MSYS targets support yosys-smtbmc, but require a launcher script ifeq ($(CONFIG),$(filter $(CONFIG),msys2 msys2-64)) TARGETS += $(PROGRAM_PREFIX)yosys-smtbmc.exe $(PROGRAM_PREFIX)yosys-smtbmc-script.py +TARGETS += $(PROGRAM_PREFIX)yosys-witness.exe $(PROGRAM_PREFIX)yosys-witness-script.py # Needed to find the Python interpreter for yosys-smtbmc scripts. # Override if necessary, it is only used for msys2 targets. PYTHON := $(shell cygpath -w -m $(PREFIX)/bin/python3) @@ -15,18 +16,31 @@ $(PROGRAM_PREFIX)yosys-smtbmc-script.py: backends/smt2/smtbmc.py $(P) sed -e 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' \ -e "s|#!/usr/bin/env python3|#!$(PYTHON)|" < $< > $@ +$(PROGRAM_PREFIX)yosys-witness-script.py: backends/smt2/witness.py + $(P) sed -e 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' \ + -e "s|#!/usr/bin/env python3|#!$(PYTHON)|" < $< > $@ + $(PROGRAM_PREFIX)yosys-smtbmc.exe: misc/launcher.c $(PROGRAM_PREFIX)yosys-smtbmc-script.py $(P) $(CXX) -DGUI=0 -O -s -o $@ $< + +$(PROGRAM_PREFIX)yosys-witness.exe: misc/launcher.c $(PROGRAM_PREFIX)yosys-witness-script.py + $(P) $(CXX) -DGUI=0 -O -s -o $@ $< # Other targets else -TARGETS += $(PROGRAM_PREFIX)yosys-smtbmc +TARGETS += $(PROGRAM_PREFIX)yosys-smtbmc $(PROGRAM_PREFIX)yosys-witness $(PROGRAM_PREFIX)yosys-smtbmc: backends/smt2/smtbmc.py $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' < $< > $@.new $(Q) chmod +x $@.new $(Q) mv $@.new $@ + +$(PROGRAM_PREFIX)yosys-witness: backends/smt2/witness.py + $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' < $< > $@.new + $(Q) chmod +x $@.new + $(Q) mv $@.new $@ endif $(eval $(call add_share_file,share/python3,backends/smt2/smtio.py)) +$(eval $(call add_share_file,share/python3,backends/smt2/ywio.py)) endif endif diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index f4482794279..7b48be29902 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -23,6 +23,7 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include "kernel/mem.h" +#include "libs/json11/json11.hpp" #include USING_YOSYS_NAMESPACE @@ -53,6 +54,8 @@ struct Smt2Worker std::map bvsizes; dict ids; + bool is_smtlib2_module; + const char *get_id(IdString n) { if (ids.count(n) == 0) { @@ -112,9 +115,10 @@ struct Smt2Worker } Smt2Worker(RTLIL::Module *module, bool bvmode, bool memmode, bool wiresmode, bool verbose, bool statebv, bool statedt, bool forallmode, - dict &mod_stbv_width, dict>> &mod_clk_cache) : - ct(module->design), sigmap(module), module(module), bvmode(bvmode), memmode(memmode), wiresmode(wiresmode), - verbose(verbose), statebv(statebv), statedt(statedt), forallmode(forallmode), mod_stbv_width(mod_stbv_width) + dict &mod_stbv_width, dict>> &mod_clk_cache) + : ct(module->design), sigmap(module), module(module), bvmode(bvmode), memmode(memmode), wiresmode(wiresmode), verbose(verbose), + statebv(statebv), statedt(statedt), forallmode(forallmode), mod_stbv_width(mod_stbv_width), + is_smtlib2_module(module->has_attribute(ID::smtlib2_module)) { pool noclock; @@ -124,6 +128,9 @@ struct Smt2Worker memories = Mem::get_all_memories(module); for (auto &mem : memories) { + if (is_smtlib2_module) + log_error("Memory %s.%s not allowed in module with smtlib2_module attribute", get_id(module), mem.memid.c_str()); + mem.narrow(); mem_dict[mem.memid] = &mem; for (auto &port : mem.wr_ports) @@ -233,6 +240,17 @@ struct Smt2Worker clock_negedge.erase(bit); } + for (auto wire : module->wires()) + { + auto gclk_attr = wire->attributes.find(ID::replaced_by_gclk); + if (gclk_attr != wire->attributes.end()) { + if (gclk_attr->second == State::S1) + clock_posedge.insert(sigmap(wire)); + else if (gclk_attr->second == State::S0) + clock_negedge.insert(sigmap(wire)); + } + } + for (auto wire : module->wires()) { if (!wire->port_input || GetSize(wire) != 1) @@ -440,11 +458,14 @@ struct Smt2Worker { RTLIL::SigSpec sig_a, sig_b; RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y)); - bool is_signed = cell->getParam(ID::A_SIGNED).as_bool(); + bool is_signed = type == 'U' ? false : cell->getParam(ID::A_SIGNED).as_bool(); int width = GetSize(sig_y); - if (type == 's' || type == 'd' || type == 'b') { - width = max(width, GetSize(cell->getPort(ID::A))); + if (type == 's' || type == 'S' || type == 'd' || type == 'b') { + if (type == 'b') + width = GetSize(cell->getPort(ID::A)); + else + width = max(width, GetSize(cell->getPort(ID::A))); if (cell->hasPort(ID::B)) width = max(width, GetSize(cell->getPort(ID::B))); } @@ -456,7 +477,7 @@ struct Smt2Worker if (cell->hasPort(ID::B)) { sig_b = cell->getPort(ID::B); - sig_b.extend_u0(width, is_signed && !(type == 's')); + sig_b.extend_u0(width, (type == 'S') || (is_signed && !(type == 's'))); } std::string processed_expr; @@ -465,6 +486,7 @@ struct Smt2Worker if (ch == 'A') processed_expr += get_bv(sig_a); else if (ch == 'B') processed_expr += get_bv(sig_b); else if (ch == 'P') processed_expr += get_bv(cell->getPort(ID::B)); + else if (ch == 'S') processed_expr += get_bv(cell->getPort(ID::S)); else if (ch == 'L') processed_expr += is_signed ? "a" : "l"; else if (ch == 'U') processed_expr += is_signed ? "s" : "u"; else processed_expr += ch; @@ -541,6 +563,9 @@ struct Smt2Worker if (cell->type.in(ID($_FF_), ID($_DFF_P_), ID($_DFF_N_))) { registers.insert(cell); + SigBit q_bit = cell->getPort(ID::Q); + if (q_bit.is_wire()) + decls.push_back(witness_signal("reg", 1, 0, "", idcounter, q_bit.wire)); makebits(stringf("%s#%d", get_id(module), idcounter), 0, log_signal(cell->getPort(ID::Q))); register_bool(cell->getPort(ID::Q), idcounter++); recursive_cells.erase(cell); @@ -571,31 +596,48 @@ struct Smt2Worker if (cell->type.in(ID($ff), ID($dff))) { registers.insert(cell); + int smtoffset = 0; + for (auto chunk : cell->getPort(ID::Q).chunks()) { + if (chunk.is_wire()) + decls.push_back(witness_signal("reg", chunk.width, chunk.offset, "", idcounter, chunk.wire, smtoffset)); + smtoffset += chunk.width; + } makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(ID::Q)), log_signal(cell->getPort(ID::Q))); register_bv(cell->getPort(ID::Q), idcounter++); recursive_cells.erase(cell); return; } - if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) + if (cell->type.in(ID($anyconst), ID($anyseq), ID($anyinit), ID($allconst), ID($allseq))) { + auto QY = cell->type == ID($anyinit) ? ID::Q : ID::Y; registers.insert(cell); string infostr = cell->attributes.count(ID::src) ? cell->attributes.at(ID::src).decode_string().c_str() : get_id(cell); if (cell->attributes.count(ID::reg)) infostr += " " + cell->attributes.at(ID::reg).decode_string(); - decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort(ID::Y)), infostr.c_str())); - if (cell->getPort(ID::Y).is_wire() && cell->getPort(ID::Y).as_wire()->get_bool_attribute(ID::maximize)){ + decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort(QY)), infostr.c_str())); + if (cell->getPort(QY).is_wire() && cell->getPort(QY).as_wire()->get_bool_attribute(ID::maximize)){ decls.push_back(stringf("; yosys-smt2-maximize %s#%d\n", get_id(module), idcounter)); - log("Wire %s is maximized\n", cell->getPort(ID::Y).as_wire()->name.str().c_str()); + log("Wire %s is maximized\n", cell->getPort(QY).as_wire()->name.str().c_str()); } - else if (cell->getPort(ID::Y).is_wire() && cell->getPort(ID::Y).as_wire()->get_bool_attribute(ID::minimize)){ + else if (cell->getPort(QY).is_wire() && cell->getPort(QY).as_wire()->get_bool_attribute(ID::minimize)){ decls.push_back(stringf("; yosys-smt2-minimize %s#%d\n", get_id(module), idcounter)); - log("Wire %s is minimized\n", cell->getPort(ID::Y).as_wire()->name.str().c_str()); + log("Wire %s is minimized\n", cell->getPort(QY).as_wire()->name.str().c_str()); + } + + bool init_only = cell->type.in(ID($anyconst), ID($anyinit), ID($allconst)); + bool clk2fflogic = cell->type == ID($anyinit) && cell->get_bool_attribute(ID(clk2fflogic)); + int smtoffset = 0; + for (auto chunk : cell->getPort(clk2fflogic ? ID::D : QY).chunks()) { + if (chunk.is_wire()) + decls.push_back(witness_signal(init_only ? "init" : "seq", chunk.width, chunk.offset, "", idcounter, chunk.wire, smtoffset)); + smtoffset += chunk.width; } - makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(ID::Y)), log_signal(cell->getPort(ID::Y))); + + makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(QY)), log_signal(cell->getPort(QY))); if (cell->type == ID($anyseq)) ex_input_eq.push_back(stringf(" (= (|%s#%d| state) (|%s#%d| other_state))", get_id(module), idcounter, get_id(module), idcounter)); - register_bv(cell->getPort(ID::Y), idcounter++); + register_bv(cell->getPort(QY), idcounter++); recursive_cells.erase(cell); return; } @@ -605,6 +647,9 @@ struct Smt2Worker if (cell->type == ID($xor)) return export_bvop(cell, "(bvxor A B)"); if (cell->type == ID($xnor)) return export_bvop(cell, "(bvxnor A B)"); + if (cell->type == ID($bweqx)) return export_bvop(cell, "(bvxnor A B)", 'U'); + if (cell->type == ID($bwmux)) return export_bvop(cell, "(bvor (bvand A (bvnot S)) (bvand B S))", 'U'); + if (cell->type == ID($shl)) return export_bvop(cell, "(bvshl A B)", 's'); if (cell->type == ID($shr)) return export_bvop(cell, "(bvlshr A B)", 's'); if (cell->type == ID($sshl)) return export_bvop(cell, "(bvshl A B)", 's'); @@ -613,8 +658,8 @@ struct Smt2Worker if (cell->type.in(ID($shift), ID($shiftx))) { if (cell->getParam(ID::B_SIGNED).as_bool()) { return export_bvop(cell, stringf("(ite (bvsge P #b%0*d) " - "(bvlshr A B) (bvlshr A (bvneg B)))", - GetSize(cell->getPort(ID::B)), 0), 's'); + "(bvlshr A B) (bvshl A (bvneg B)))", + GetSize(cell->getPort(ID::B)), 0), 'S'); // type 'S' sign extends B } else { return export_bvop(cell, "(bvlshr A B)", 's'); } @@ -649,6 +694,27 @@ struct Smt2Worker return export_bvop(cell, "(bvurem A B)", 'd'); } } + // "div" = flooring division + if (cell->type == ID($divfloor)) { + if (cell->getParam(ID::A_SIGNED).as_bool()) { + // bvsdiv is truncating division, so we can't use it here. + int width = max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B))); + width = max(width, GetSize(cell->getPort(ID::Y))); + auto expr = stringf("(let (" + "(a_neg (bvslt A #b%0*d)) " + "(b_neg (bvslt B #b%0*d))) " + "(let ((abs_a (ite a_neg (bvneg A) A)) " + "(abs_b (ite b_neg (bvneg B) B))) " + "(let ((u (bvudiv abs_a abs_b)) " + "(adj (ite (= #b%0*d (bvurem abs_a abs_b)) #b%0*d #b%0*d))) " + "(ite (= a_neg b_neg) u " + "(bvneg (bvadd u adj))))))", + width, 0, width, 0, width, 0, width, 0, width, 1); + return export_bvop(cell, expr, 'd'); + } else { + return export_bvop(cell, "(bvudiv A B)", 'd'); + } + } if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool)) && 2*GetSize(cell->getPort(ID::A).chunks()) < GetSize(cell->getPort(ID::A))) { @@ -721,6 +787,7 @@ struct Smt2Worker log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module)); decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", get_id(mem->memid), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync")); + decls.push_back(witness_memory(get_id(mem->memid), cell, mem)); string memstate; if (has_async_wr) { @@ -813,6 +880,7 @@ struct Smt2Worker if (m != nullptr) { decls.push_back(stringf("; yosys-smt2-cell %s %s\n", get_id(cell->type), get_id(cell->name))); + decls.push_back(witness_cell(get_id(cell->name), cell)); string cell_state = stringf("(|%s_h %s| state)", get_id(module), get_id(cell->name)); for (auto &conn : cell->connections()) @@ -860,7 +928,7 @@ struct Smt2Worker log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smt2`.\n", log_id(cell->type), log_id(module), log_id(cell)); } - if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") { + if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smt2`.\n", log_id(cell->type), log_id(module), log_id(cell)); } @@ -872,24 +940,58 @@ struct Smt2Worker log_id(cell->type), log_id(module), log_id(cell)); } + void verify_smtlib2_module() + { + if (!module->get_blackbox_attribute()) + log_error("Module %s with smtlib2_module attribute must also have blackbox attribute.\n", log_id(module)); + if (module->cells().size() > 0) + log_error("Module %s with smtlib2_module attribute must not have any cells inside it.\n", log_id(module)); + for (auto wire : module->wires()) + if (!wire->port_id) + log_error("Wire %s.%s must be input or output since module has smtlib2_module attribute.\n", log_id(module), + log_id(wire)); + } + void run() { if (verbose) log("=> export logic driving outputs\n"); + if (is_smtlib2_module) + verify_smtlib2_module(); + pool reg_bits; for (auto cell : module->cells()) - if (cell->type.in(ID($ff), ID($dff), ID($_FF_), ID($_DFF_P_), ID($_DFF_N_))) { + if (cell->type.in(ID($ff), ID($dff), ID($_FF_), ID($_DFF_P_), ID($_DFF_N_), ID($anyinit))) { // not using sigmap -- we want the net directly at the dff output for (auto bit : cell->getPort(ID::Q)) reg_bits.insert(bit); } + std::string smtlib2_inputs; + std::vector smtlib2_decls; + if (is_smtlib2_module) { + for (auto wire : module->wires()) { + if (!wire->port_input) + continue; + smtlib2_inputs += stringf("(|%s| (|%s_n %s| state))\n", get_id(wire), get_id(module), get_id(wire)); + } + } + for (auto wire : module->wires()) { bool is_register = false; - for (auto bit : SigSpec(wire)) + bool contains_clock = false; + for (auto bit : SigSpec(wire)) { if (reg_bits.count(bit)) is_register = true; - if (wire->port_id || is_register || wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name.isPublic())) { + auto sig_bit = sigmap(bit); + if (clock_posedge.count(sig_bit) || clock_negedge.count(sig_bit)) + contains_clock = true; + } + bool is_smtlib2_comb_expr = wire->has_attribute(ID::smtlib2_comb_expr); + if (is_smtlib2_comb_expr && !is_smtlib2_module) + log_error("smtlib2_comb_expr is only valid in a module with the smtlib2_module attribute: wire %s.%s", log_id(module), + log_id(wire)); + if (wire->port_id || is_register || contains_clock || wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name.isPublic())) { RTLIL::SigSpec sig = sigmap(wire); std::vector comments; if (wire->port_input) @@ -900,14 +1002,38 @@ struct Smt2Worker comments.push_back(stringf("; yosys-smt2-register %s %d\n", get_id(wire), wire->width)); if (wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name.isPublic())) comments.push_back(stringf("; yosys-smt2-wire %s %d\n", get_id(wire), wire->width)); - if (GetSize(wire) == 1 && (clock_posedge.count(sig) || clock_negedge.count(sig))) + if (contains_clock && GetSize(wire) == 1 && (clock_posedge.count(sig) || clock_negedge.count(sig))) comments.push_back(stringf("; yosys-smt2-clock %s%s%s\n", get_id(wire), clock_posedge.count(sig) ? " posedge" : "", clock_negedge.count(sig) ? " negedge" : "")); + if (wire->port_input && contains_clock) { + for (int i = 0; i < GetSize(sig); i++) { + bool is_posedge = clock_posedge.count(sig[i]); + bool is_negedge = clock_negedge.count(sig[i]); + if (is_posedge != is_negedge) + comments.push_back(witness_signal( + is_posedge ? "posedge" : "negedge", 1, i, get_id(wire), -1, wire)); + } + } + if (wire->port_input) + comments.push_back(witness_signal("input", wire->width, 0, get_id(wire), -1, wire)); + std::string smtlib2_comb_expr; + if (is_smtlib2_comb_expr) { + smtlib2_comb_expr = + "(let (\n" + smtlib2_inputs + ")\n" + wire->get_string_attribute(ID::smtlib2_comb_expr) + "\n)"; + if (wire->port_input || !wire->port_output) + log_error("smtlib2_comb_expr is only valid on output: wire %s.%s", log_id(module), log_id(wire)); + if (!bvmode && GetSize(sig) > 1) + log_error("smtlib2_comb_expr is unsupported on multi-bit wires when -nobv is specified: wire %s.%s", + log_id(module), log_id(wire)); + + comments.push_back(witness_signal("blackbox", wire->width, 0, get_id(wire), -1, wire)); + } + auto &out_decls = is_smtlib2_comb_expr ? smtlib2_decls : decls; if (bvmode && GetSize(sig) > 1) { - std::string sig_bv = get_bv(sig); + std::string sig_bv = is_smtlib2_comb_expr ? smtlib2_comb_expr : get_bv(sig); if (!comments.empty()) - decls.insert(decls.end(), comments.begin(), comments.end()); - decls.push_back(stringf("(define-fun |%s_n %s| ((state |%s_s|)) (_ BitVec %d) %s)\n", + out_decls.insert(out_decls.end(), comments.begin(), comments.end()); + out_decls.push_back(stringf("(define-fun |%s_n %s| ((state |%s_s|)) (_ BitVec %d) %s)\n", get_id(module), get_id(wire), get_id(module), GetSize(sig), sig_bv.c_str())); if (wire->port_input) ex_input_eq.push_back(stringf(" (= (|%s_n %s| state) (|%s_n %s| other_state))", @@ -915,19 +1041,19 @@ struct Smt2Worker } else { std::vector sig_bool; for (int i = 0; i < GetSize(sig); i++) { - sig_bool.push_back(get_bool(sig[i])); + sig_bool.push_back(is_smtlib2_comb_expr ? smtlib2_comb_expr : get_bool(sig[i])); } if (!comments.empty()) - decls.insert(decls.end(), comments.begin(), comments.end()); + out_decls.insert(out_decls.end(), comments.begin(), comments.end()); for (int i = 0; i < GetSize(sig); i++) { if (GetSize(sig) > 1) { - decls.push_back(stringf("(define-fun |%s_n %s %d| ((state |%s_s|)) Bool %s)\n", + out_decls.push_back(stringf("(define-fun |%s_n %s %d| ((state |%s_s|)) Bool %s)\n", get_id(module), get_id(wire), i, get_id(module), sig_bool[i].c_str())); if (wire->port_input) ex_input_eq.push_back(stringf(" (= (|%s_n %s %d| state) (|%s_n %s %d| other_state))", get_id(module), get_id(wire), i, get_id(module), get_id(wire), i)); } else { - decls.push_back(stringf("(define-fun |%s_n %s| ((state |%s_s|)) Bool %s)\n", + out_decls.push_back(stringf("(define-fun |%s_n %s| ((state |%s_s|)) Bool %s)\n", get_id(module), get_id(wire), get_id(module), sig_bool[i].c_str())); if (wire->port_input) ex_input_eq.push_back(stringf(" (= (|%s_n %s| state) (|%s_n %s| other_state))", @@ -938,11 +1064,17 @@ struct Smt2Worker } } + decls.insert(decls.end(), smtlib2_decls.begin(), smtlib2_decls.end()); + if (verbose) log("=> export logic associated with the initial state\n"); vector init_list; for (auto wire : module->wires()) if (wire->attributes.count(ID::init)) { + if (is_smtlib2_module) + log_error("init attribute not allowed on wires in module with smtlib2_module attribute: wire %s.%s", + log_id(module), log_id(wire)); + RTLIL::SigSpec sig = sigmap(wire); Const val = wire->attributes.at(ID::init); val.bits.resize(GetSize(sig), State::Sx); @@ -985,8 +1117,10 @@ struct Smt2Worker string name_a = get_bool(cell->getPort(ID::A)); string name_en = get_bool(cell->getPort(ID::EN)); - string infostr = (cell->name[0] == '$' && cell->attributes.count(ID::src)) ? cell->attributes.at(ID::src).decode_string() : get_id(cell); - decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, infostr.c_str())); + if (cell->name[0] == '$' && cell->attributes.count(ID::src)) + decls.push_back(stringf("; yosys-smt2-%s %d %s %s\n", cell->type.c_str() + 1, id, get_id(cell), cell->attributes.at(ID::src).decode_string().c_str())); + else + decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, get_id(cell))); if (cell->type == ID($cover)) decls.push_back(stringf("(define-fun |%s_%c %d| ((state |%s_s|)) Bool (and %s %s)) ; %s\n", @@ -1061,7 +1195,7 @@ struct Smt2Worker ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort(ID::Q)).c_str(), get_bool(cell->getPort(ID::Q), "other_state").c_str())); } - if (cell->type.in(ID($ff), ID($dff))) + if (cell->type.in(ID($ff), ID($dff), ID($anyinit))) { std::string expr_d = get_bv(cell->getPort(ID::D)); std::string expr_q = get_bv(cell->getPort(ID::Q), "next_state"); @@ -1183,10 +1317,12 @@ struct Smt2Worker data = stringf("(bvor (bvand %s %s) (bvand (select (|%s#%d#%d| state) %s) (bvnot %s)))", data.c_str(), mask.c_str(), get_id(module), arrayid, i, addr.c_str(), mask.c_str()); + string empty_mask(mem->width, '0'); + decls.push_back(stringf("(define-fun |%s#%d#%d| ((state |%s_s|)) (Array (_ BitVec %d) (_ BitVec %d)) " - "(store (|%s#%d#%d| state) %s %s)) ; %s\n", + "(ite (= %s #b%s) (|%s#%d#%d| state) (store (|%s#%d#%d| state) %s %s))) ; %s\n", get_id(module), arrayid, i+1, get_id(module), abits, mem->width, - get_id(module), arrayid, i, addr.c_str(), data.c_str(), get_id(mem->memid))); + mask.c_str(), empty_mask.c_str(), get_id(module), arrayid, i, get_id(module), arrayid, i, addr.c_str(), data.c_str(), get_id(mem->memid))); } } @@ -1358,6 +1494,91 @@ struct Smt2Worker f << "true)"; f << stringf(" ; end of module %s\n", get_id(module)); } + + template static std::vector witness_path(T *obj) { + std::vector path; + if (obj->name.isPublic()) { + auto hdlname = obj->get_string_attribute(ID::hdlname); + for (auto token : split_tokens(hdlname)) + path.push_back("\\" + token); + } + if (path.empty()) + path.push_back(obj->name.str()); + return path; + } + + std::string witness_signal(const char *type, int width, int offset, const std::string &smtname, int smtid, RTLIL::Wire *wire, int smtoffset = 0) + { + std::vector hiername; + const char *wire_name = wire->name.c_str(); + if (wire_name[0] == '\\') { + auto hdlname = wire->get_string_attribute(ID::hdlname); + for (auto token : split_tokens(hdlname)) + hiername.push_back("\\" + token); + } + if (hiername.empty()) + hiername.push_back(wire->name.str()); + + std::string line = "; yosys-smt2-witness "; + (json11::Json { json11::Json::object { + { "type", type }, + { "offset", offset }, + { "width", width }, + { "smtname", smtname.empty() ? json11::Json(smtid) : json11::Json(smtname) }, + { "smtoffset", smtoffset }, + { "path", witness_path(wire) }, + }}).dump(line); + line += "\n"; + return line; + } + + std::string witness_cell(const char *smtname, RTLIL::Cell *cell) + { + std::string line = "; yosys-smt2-witness "; + (json11::Json {json11::Json::object { + { "type", "cell" }, + { "smtname", smtname }, + { "path", witness_path(cell) }, + }}).dump(line); + line += "\n"; + return line; + } + + std::string witness_memory(const char *smtname, RTLIL::Cell *cell, Mem *mem) + { + json11::Json::array uninitialized; + auto init_data = mem->get_init_data(); + + int cursor = 0; + + while (cursor < init_data.size()) { + while (cursor < init_data.size() && init_data[cursor] != State::Sx) + cursor++; + int offset = cursor; + while (cursor < init_data.size() && init_data[cursor] == State::Sx) + cursor++; + int width = cursor - offset; + if (width) + uninitialized.push_back(json11::Json::object { + {"width", width}, + {"offset", offset}, + }); + } + + std::string line = "; yosys-smt2-witness "; + (json11::Json { json11::Json::object { + { "type", "mem" }, + { "width", mem->width }, + { "size", mem->size }, + { "rom", mem->wr_ports.empty() }, + { "statebv", statebv }, + { "smtname", smtname }, + { "uninitialized", uninitialized }, + { "path", witness_path(cell) }, + }}).dump(line); + line += "\n"; + return line; + } }; struct Smt2Backend : public Backend { @@ -1531,6 +1752,11 @@ struct Smt2Backend : public Backend { log_header(design, "Executing SMT2 backend.\n"); + log_push(); + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); + log_pop(); + size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -1657,7 +1883,10 @@ struct Smt2Backend : public Backend { for (auto module : sorted_modules) { - if (module->get_blackbox_attribute() || module->has_processes_warn()) + if (module->get_blackbox_attribute() && !module->has_attribute(ID::smtlib2_module)) + continue; + + if (module->has_processes_warn()) continue; log("Creating SMT-LIBv2 representation of module %s.\n", log_id(module)); diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py index be27a3d097c..6b81740a272 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -17,9 +17,10 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # -import os, sys, getopt, re +import os, sys, getopt, re, bisect ##yosys-sys-path## from smtio import SmtIo, SmtOpts, MkVcd +from ywio import ReadWitness, WriteWitness, WitnessValues from collections import defaultdict got_topt = False @@ -28,6 +29,8 @@ num_steps = 20 append_steps = 0 vcdfile = None +inywfile = None +outywfile = None cexfile = None aimfile = None aiwfile = None @@ -50,12 +53,18 @@ smtctop = None noinit = False binarymode = False +keep_going = False +check_witness = False +detect_loops = False so = SmtOpts() -def usage(): +def help(): print(os.path.basename(sys.argv[0]) + """ [options] + -h, --help + show this message + -t -t : -t :: @@ -93,6 +102,9 @@ def usage(): the AIGER witness file does not include the status and properties lines. + --yw + read a Yosys witness. + --btorwit read a BTOR witness. @@ -120,6 +132,9 @@ def usage(): (hint: use 'write_smt2 -wires' for maximum coverage of signals in generated VCD file) + --dump-yw + write trace as a Yosys witness trace + --dump-vlogtb write trace as Verilog test bench @@ -143,7 +158,7 @@ def usage(): --dump-all when using -g or -i, create a dump file for each - step. The character '%' is replaces in all dump + step. The character '%' is replaced in all dump filenames with the step number. --append @@ -153,20 +168,41 @@ def usage(): --binary dump anyconst values as raw bit strings + + --keep-going + continue BMC after the first failed assertion and report + further failed assertions. To output multiple traces + covering all found failed assertions, the character '%' is + replaced in all dump filenames with an increasing number. + + --check-witness + check that the used witness file contains sufficient + constraints to force an assertion failure. + + --detect-loops + check if states are unique in temporal induction counter examples + (this feature is experimental and incomplete) + """ + so.helpmsg()) + +def usage(): + help() sys.exit(1) try: - opts, args = getopt.getopt(sys.argv[1:], so.shortopts + "t:igcm:", so.longopts + - ["final-only", "assume-skipped=", "smtc=", "cex=", "aig=", "aig-noheader", "btorwit=", "presat", - "dump-vcd=", "dump-vlogtb=", "vlogtb-top=", "dump-smtc=", "dump-all", "noinfo", "append=", - "smtc-init", "smtc-top=", "noinit", "binary"]) + opts, args = getopt.getopt(sys.argv[1:], so.shortopts + "t:higcm:", so.longopts + + ["help", "final-only", "assume-skipped=", "smtc=", "cex=", "aig=", "aig-noheader", "yw=", "btorwit=", "presat", + "dump-vcd=", "dump-yw=", "dump-vlogtb=", "vlogtb-top=", "dump-smtc=", "dump-all", "noinfo", "append=", + "smtc-init", "smtc-top=", "noinit", "binary", "keep-going", "check-witness", "detect-loops"]) except: usage() for o, a in opts: - if o == "-t": + if o in ("-h", "--help"): + help() + sys.exit(0) + elif o == "-t": got_topt = True a = a.split(":") if len(a) == 1: @@ -196,10 +232,14 @@ def usage(): aiwfile = a + ".aiw" elif o == "--aig-noheader": aigheader = False + elif o == "--yw": + inywfile = a elif o == "--btorwit": btorwitfile = a elif o == "--dump-vcd": vcdfile = a + elif o == "--dump-yw": + outywfile = a elif o == "--dump-vlogtb": vlogtbfile = a elif o == "--vlogtb-top": @@ -234,6 +274,12 @@ def usage(): topmod = a elif o == "--binary": binarymode = True + elif o == "--keep-going": + keep_going = True + elif o == "--check-witness": + check_witness = True + elif o == "--detect-loops": + detect_loops = True elif so.handle(o, a): pass else: @@ -341,13 +387,13 @@ def usage(): assert False -def get_constr_expr(db, state, final=False, getvalues=False): +def get_constr_expr(db, state, final=False, getvalues=False, individual=False): if final: if ("final-%d" % state) not in db: - return ([], [], []) if getvalues else "true" + return ([], [], []) if getvalues or individual else "true" else: if state not in db: - return ([], [], []) if getvalues else "true" + return ([], [], []) if getvalues or individual else "true" netref_regex = re.compile(r'(^|[( ])\[(-?[0-9]+:|)([^\]]*|\S*)\](?=[ )]|$)') @@ -368,15 +414,18 @@ def replace_netref(match): expr_list = list() for loc, expr in db[("final-%d" % state) if final else state]: actual_expr = netref_regex.sub(replace_netref, expr) - if getvalues: + if getvalues or individual: expr_list.append((loc, expr, actual_expr)) else: expr_list.append(actual_expr) - if getvalues: - loc_list, expr_list, acual_expr_list = zip(*expr_list) - value_list = smt.get_list(acual_expr_list) - return loc_list, expr_list, value_list + if getvalues or individual: + loc_list, expr_list, actual_expr_list = zip(*expr_list) + if individual: + return loc_list, expr_list, actual_expr_list + else: + value_list = smt.get_list(actual_expr_list) + return loc_list, expr_list, value_list if len(expr_list) == 0: return "true" @@ -413,7 +462,6 @@ def print_msg(msg): if cexfile is not None: if not got_topt: - assume_skipped = 0 skip_steps = 0 num_steps = 0 @@ -449,7 +497,8 @@ def print_msg(msg): constr_assumes[step].append((cexfile, smtexpr)) if not got_topt: - skip_steps = max(skip_steps, step) + if not check_witness: + skip_steps = max(skip_steps, step) num_steps = max(num_steps, step+1) if aimfile is not None: @@ -458,7 +507,6 @@ def print_msg(msg): latch_map = dict() if not got_topt: - assume_skipped = 0 skip_steps = 0 num_steps = 0 @@ -492,7 +540,7 @@ def print_msg(msg): got_state = True for entry in f.read().splitlines(): - if len(entry) == 0 or entry[0] in "bcjfu.": + if len(entry) == 0 or entry[0] in "bcjfu.#": continue if not got_state: @@ -582,10 +630,118 @@ def print_msg(msg): constr_assumes[step].append((cexfile, smtexpr)) if not got_topt: - skip_steps = max(skip_steps, step) - num_steps = max(num_steps, step+1) + if not check_witness: + skip_steps = max(skip_steps, step) + # some solvers optimize the properties so that they fail one cycle early, + # thus we check the properties in the cycle the aiger witness ends, and + # if that doesn't work, we check the cycle after that as well. + num_steps = max(num_steps, step+2) step += 1 +if inywfile is not None: + if not got_topt: + skip_steps = 0 + num_steps = 0 + + with open(inywfile, "r") as f: + inyw = ReadWitness(f) + + inits, seqs, clocks, mems = smt.hierwitness(topmod, allregs=True, blackbox=True) + + smt_wires = defaultdict(list) + smt_mems = defaultdict(list) + + for wire in inits + seqs: + smt_wires[wire["path"]].append(wire) + + for mem in mems: + smt_mems[mem["path"]].append(mem) + + addr_re = re.compile(r'\\\[[0-9]+\]$') + bits_re = re.compile(r'[01?]*$') + + for t, step in inyw.steps(): + present_signals, missing = step.present_signals(inyw.sigmap) + for sig in present_signals: + bits = step[sig] + if not bits_re.match(bits): + raise ValueError("unsupported bit value in Yosys witness file") + + sig_end = sig.offset + len(bits) + if sig.path in smt_wires: + for wire in smt_wires[sig.path]: + width, offset = wire["width"], wire["offset"] + + smt_bool = smt.net_width(topmod, wire["smtpath"]) == 1 + + offset = max(offset, 0) + + end = width + offset + common_offset = max(sig.offset, offset) + common_end = min(sig_end, end) + if common_end <= common_offset: + continue + + smt_expr = smt.witness_net_expr(topmod, f"s{t}", wire) + + if not smt_bool: + slice_high = common_end - offset - 1 + slice_low = common_offset - offset + smt_expr = "((_ extract %d %d) %s)" % (slice_high, slice_low, smt_expr) + + bit_slice = bits[len(bits) - (common_end - sig.offset):len(bits) - (common_offset - sig.offset)] + + if bit_slice.count("?") == len(bit_slice): + continue + + if smt_bool: + assert width == 1 + smt_constr = "(= %s %s)" % (smt_expr, "true" if bit_slice == "1" else "false") + else: + if "?" in bit_slice: + mask = bit_slice.replace("0", "1").replace("?", "0") + bit_slice = bit_slice.replace("?", "0") + smt_expr = "(bvand %s #b%s)" % (smt_expr, mask) + + smt_constr = "(= %s #b%s)" % (smt_expr, bit_slice) + + constr_assumes[t].append((inywfile, smt_constr)) + + if sig.memory_path: + if sig.memory_path in smt_mems: + for mem in smt_mems[sig.memory_path]: + width, size, bv = mem["width"], mem["size"], mem["statebv"] + + smt_expr = smt.net_expr(topmod, f"s{t}", mem["smtpath"]) + + if bv: + word_low = sig.memory_addr * width + word_high = word_low + width - 1 + smt_expr = "((_ extract %d %d) %s)" % (word_high, word_low, smt_expr) + else: + addr_width = (size - 1).bit_length() + addr_bits = f"{sig.memory_addr:0{addr_width}b}" + smt_expr = "(select %s #b%s )" % (smt_expr, addr_bits) + + if len(bits) < width: + slice_high = sig.offset + len(bits) - 1 + smt_expr = "((_ extract %d %d) %s)" % (slice_high, sig.offset, smt_expr) + + bit_slice = bits + + if "?" in bit_slice: + mask = bit_slice.replace("0", "1").replace("?", "0") + bit_slice = bit_slice.replace("?", "0") + smt_expr = "(bvand %s #b%s)" % (smt_expr, mask) + + smt_constr = "(= %s #b%s)" % (smt_expr, bit_slice) + constr_assumes[t].append((inywfile, smt_constr)) + + if not got_topt: + if not check_witness: + skip_steps = max(skip_steps, t) + num_steps = max(num_steps, t+1) + if btorwitfile is not None: with open(btorwitfile, "r") as f: step = None @@ -683,128 +839,137 @@ def print_msg(msg): skip_steps = step num_steps = step+1 -def write_vcd_trace(steps_start, steps_stop, index): - filename = vcdfile.replace("%", index) - print_msg("Writing trace to VCD file: %s" % (filename)) +def collect_mem_trace_data(steps_start, steps_stop, vcd=None): + mem_trace_data = dict() - with open(filename, "w") as vcd_file: - vcd = MkVcd(vcd_file) - path_list = list() - - for netpath in sorted(smt.hiernets(topmod)): - hidden_net = False - for n in netpath: - if n.startswith("$"): - hidden_net = True - if not hidden_net: - edge = smt.net_clock(topmod, netpath) - if edge is None: - vcd.add_net([topmod] + netpath, smt.net_width(topmod, netpath)) - else: - vcd.add_clock([topmod] + netpath, edge) - path_list.append(netpath) + for mempath in sorted(smt.hiermems(topmod)): + abits, width, rports, wports, asyncwr = smt.mem_info(topmod, mempath) - mem_trace_data = dict() - for mempath in sorted(smt.hiermems(topmod)): - abits, width, rports, wports, asyncwr = smt.mem_info(topmod, mempath) + expr_id = list() + expr_list = list() + for i in range(steps_start, steps_stop): + for j in range(rports): + expr_id.append(('R', i-steps_start, j, 'A')) + expr_id.append(('R', i-steps_start, j, 'D')) + expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dA" % j)) + expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dD" % j)) + for j in range(wports): + expr_id.append(('W', i-steps_start, j, 'A')) + expr_id.append(('W', i-steps_start, j, 'D')) + expr_id.append(('W', i-steps_start, j, 'M')) + expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "W%dA" % j)) + expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "W%dD" % j)) + expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "W%dM" % j)) + + rdata = list() + wdata = list() + addrs = set() + + for eid, edat in zip(expr_id, smt.get_list(expr_list)): + t, i, j, f = eid + + if t == 'R': + c = rdata + elif t == 'W': + c = wdata + else: + assert False - expr_id = list() - expr_list = list() - for i in range(steps_start, steps_stop): - for j in range(rports): - expr_id.append(('R', i-steps_start, j, 'A')) - expr_id.append(('R', i-steps_start, j, 'D')) - expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dA" % j)) - expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dD" % j)) - for j in range(wports): - expr_id.append(('W', i-steps_start, j, 'A')) - expr_id.append(('W', i-steps_start, j, 'D')) - expr_id.append(('W', i-steps_start, j, 'M')) - expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "W%dA" % j)) - expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "W%dD" % j)) - expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "W%dM" % j)) - - rdata = list() - wdata = list() - addrs = set() - - for eid, edat in zip(expr_id, smt.get_list(expr_list)): - t, i, j, f = eid - - if t == 'R': - c = rdata - elif t == 'W': - c = wdata - else: - assert False + while len(c) <= i: + c.append(list()) + c = c[i] - while len(c) <= i: - c.append(list()) - c = c[i] + while len(c) <= j: + c.append(dict()) + c = c[j] - while len(c) <= j: - c.append(dict()) - c = c[j] + c[f] = smt.bv2bin(edat) - c[f] = smt.bv2bin(edat) + if f == 'A': + addrs.add(c[f]) - if f == 'A': - addrs.add(c[f]) + for addr in addrs: + tdata = list() + data = ["x"] * width + gotread = False - for addr in addrs: - tdata = list() - data = ["x"] * width - gotread = False + if len(wdata) == 0 and len(rdata) != 0: + wdata = [[]] * len(rdata) - if len(wdata) == 0 and len(rdata) != 0: - wdata = [[]] * len(rdata) + assert len(rdata) == len(wdata) - assert len(rdata) == len(wdata) + for i in range(len(wdata)): + if not gotread: + for j_data in rdata[i]: + if j_data["A"] == addr: + data = list(j_data["D"]) + gotread = True + break - for i in range(len(wdata)): - if not gotread: - for j_data in rdata[i]: - if j_data["A"] == addr: - data = list(j_data["D"]) - gotread = True - break + if gotread: + buf = data[:] + for ii in reversed(range(len(tdata))): + for k in range(width): + if tdata[ii][k] == "x": + tdata[ii][k] = buf[k] + else: + buf[k] = tdata[ii][k] - if gotread: - buf = data[:] - for i in reversed(range(len(tdata))): - for k in range(width): - if tdata[i][k] == "x": - tdata[i][k] = buf[k] - else: - buf[k] = tdata[i][k] + if not asyncwr: + tdata.append(data[:]) - if not asyncwr: - tdata.append(data[:]) + for j_data in wdata[i]: + if j_data["A"] != addr: + continue - for j_data in wdata[i]: - if j_data["A"] != addr: - continue + D = j_data["D"] + M = j_data["M"] - D = j_data["D"] - M = j_data["M"] + for k in range(width): + if M[k] == "1": + data[k] = D[k] - for k in range(width): - if M[k] == "1": - data[k] = D[k] + if asyncwr: + tdata.append(data[:]) - if asyncwr: - tdata.append(data[:]) + assert len(tdata) == len(rdata) - assert len(tdata) == len(rdata) + int_addr = int(addr, 2) - netpath = mempath[:] - netpath[-1] += "<%0*x>" % ((len(addr)+3) // 4, int(addr, 2)) + netpath = mempath[:] + if vcd: + netpath[-1] += "<%0*x>" % ((len(addr)+3) // 4, int_addr) vcd.add_net([topmod] + netpath, width) - for i in range(steps_start, steps_stop): - if i not in mem_trace_data: - mem_trace_data[i] = list() - mem_trace_data[i].append((netpath, "".join(tdata[i-steps_start]))) + for i in range(steps_start, steps_stop): + if i not in mem_trace_data: + mem_trace_data[i] = list() + mem_trace_data[i].append((netpath, int_addr, "".join(tdata[i-steps_start]))) + + return mem_trace_data + +def write_vcd_trace(steps_start, steps_stop, index): + filename = vcdfile.replace("%", index) + print_msg("Writing trace to VCD file: %s" % (filename)) + + with open(filename, "w") as vcd_file: + vcd = MkVcd(vcd_file) + path_list = list() + + for netpath in sorted(smt.hiernets(topmod)): + hidden_net = False + for n in netpath: + if n.startswith("$"): + hidden_net = True + if not hidden_net: + edge = smt.net_clock(topmod, netpath) + if edge is None: + vcd.add_net([topmod] + netpath, smt.net_width(topmod, netpath)) + else: + vcd.add_clock([topmod] + netpath, edge) + path_list.append(netpath) + + mem_trace_data = collect_mem_trace_data(steps_start, steps_stop, vcd) for i in range(steps_start, steps_stop): vcd.set_time(i) @@ -812,11 +977,35 @@ def write_vcd_trace(steps_start, steps_stop, index): for path, value in zip(path_list, value_list): vcd.set_net([topmod] + path, value) if i in mem_trace_data: - for path, value in mem_trace_data[i]: + for path, addr, value in mem_trace_data[i]: vcd.set_net([topmod] + path, value) vcd.set_time(steps_stop) +def detect_state_loop(steps_start, steps_stop): + print_msg(f"Checking for loops in found induction counter example") + print_msg(f"This feature is experimental and incomplete") + + path_list = sorted(smt.hiernets(topmod, regs_only=True)) + + mem_trace_data = collect_mem_trace_data(steps_start, steps_stop) + + # Map state to index of step when it occurred + states = dict() + + for i in range(steps_start, steps_stop): + value_list = smt.get_net_bin_list(topmod, path_list, "s%d" % i) + mem_state = sorted( + [(tuple(path), addr, data) + for path, addr, data in mem_trace_data.get(i, [])]) + state = tuple(value_list), tuple(mem_state) + if state in states: + return (i, states[state]) + else: + states[state] = i + + return None + def char_ok_in_verilog(c,i): if ('A' <= c <= 'Z'): return True if ('a' <= c <= 'z'): return True @@ -826,7 +1015,7 @@ def char_ok_in_verilog(c,i): return False def escape_identifier(identifier): - if type(identifier) is list: + if type(identifier) is list: return map(escape_identifier, identifier) if "." in identifier: return ".".join(escape_identifier(identifier.split("."))) @@ -1056,8 +1245,73 @@ def write_constr_trace(steps_start, steps_stop, index): for name, val in zip(pi_names, pi_values): print("assume (= [%s%s] %s)" % (constr_prefix, ".".join(name), val), file=f) +def write_yw_trace(steps_start, steps_stop, index, allregs=False): + filename = outywfile.replace("%", index) + print_msg("Writing trace to Yosys witness file: %s" % (filename)) + + mem_trace_data = collect_mem_trace_data(steps_start, steps_stop) + + with open(filename, "w") as f: + inits, seqs, clocks, mems = smt.hierwitness(topmod, allregs) + + yw = WriteWitness(f, "smtbmc") -def write_trace(steps_start, steps_stop, index): + for clock in clocks: + yw.add_clock(clock["path"], clock["offset"], clock["type"]) + + for seq in seqs: + seq["sig"] = yw.add_sig(seq["path"], seq["offset"], seq["width"]) + + for init in inits: + init["sig"] = yw.add_sig(init["path"], init["offset"], init["width"], True) + + inits = seqs + inits + + mem_dict = {tuple(mem["smtpath"]): mem for mem in mems} + mem_init_values = [] + + for path, addr, value in mem_trace_data.get(0, ()): + json_mem = mem_dict.get(tuple(path)) + if not json_mem: + continue + + bit_addr = addr * json_mem["width"] + uninit_chunks = [(chunk["width"] + chunk["offset"], chunk["offset"]) for chunk in json_mem["uninitialized"]] + first_chunk_nr = bisect.bisect_left(uninit_chunks, (bit_addr + 1,)) + + for uninit_end, uninit_offset in uninit_chunks[first_chunk_nr:]: + assert uninit_end > bit_addr + if uninit_offset > bit_addr + json_mem["width"]: + break + + word_path = (*json_mem["path"], f"\\[{addr}]") + + overlap_start = max(uninit_offset - bit_addr, 0) + overlap_end = min(uninit_end - bit_addr, json_mem["width"]) + overlap_bits = value[len(value)-overlap_end:len(value)-overlap_start] + + sig = yw.add_sig(word_path, overlap_start, overlap_end - overlap_start, True) + mem_init_values.append((sig, overlap_bits.replace("x", "?"))) + + for k in range(steps_start, steps_stop): + step_values = WitnessValues() + + if k == steps_start: + for sig, value in mem_init_values: + step_values[sig] = value + sigs = inits + seqs + else: + sigs = seqs + + for sig in sigs: + value = smt.bv2bin(smt.get(smt.witness_net_expr(topmod, f"s{k}", sig))) + step_values[sig["sig"]] = value + yw.step(step_values) + + yw.end_trace() + + +def write_trace(steps_start, steps_stop, index, allregs=False): if vcdfile is not None: write_vcd_trace(steps_start, steps_stop, index) @@ -1067,8 +1321,11 @@ def write_trace(steps_start, steps_stop, index): if outconstr is not None: write_constr_trace(steps_start, steps_stop, index) + if outywfile is not None: + write_yw_trace(steps_start, steps_stop, index, allregs) -def print_failed_asserts_worker(mod, state, path, extrainfo): + +def print_failed_asserts_worker(mod, state, path, extrainfo, infomap, infokey=()): assert mod in smt.modinfo found_failed_assert = False @@ -1076,29 +1333,31 @@ def print_failed_asserts_worker(mod, state, path, extrainfo): return for cellname, celltype in smt.modinfo[mod].cells.items(): - if print_failed_asserts_worker(celltype, "(|%s_h %s| %s)" % (mod, cellname, state), path + "." + cellname, extrainfo): + cell_infokey = (mod, cellname, infokey) + if print_failed_asserts_worker(celltype, "(|%s_h %s| %s)" % (mod, cellname, state), path + "." + cellname, extrainfo, infomap, cell_infokey): found_failed_assert = True for assertfun, assertinfo in smt.modinfo[mod].asserts.items(): if smt.get("(|%s| %s)" % (assertfun, state)) in ["false", "#b0"]: - print_msg("Assert failed in %s: %s%s" % (path, assertinfo, extrainfo)) + assert_key = (assertfun, infokey) + print_msg("Assert failed in %s: %s%s%s" % (path, assertinfo, extrainfo, infomap.get(assert_key, ''))) found_failed_assert = True return found_failed_assert -def print_failed_asserts(state, final=False, extrainfo=""): +def print_failed_asserts(state, final=False, extrainfo="", infomap={}): if noinfo: return loc_list, expr_list, value_list = get_constr_expr(constr_asserts, state, final=final, getvalues=True) found_failed_assert = False for loc, expr, value in zip(loc_list, expr_list, value_list): if smt.bv2int(value) == 0: - print_msg("Assert %s failed: %s%s" % (loc, expr, extrainfo)) + print_msg("Assert %s failed: %s%s%s" % (loc, expr, extrainfo, infomap.get(loc, ''))) found_failed_assert = True if not final: - if print_failed_asserts_worker(topmod, "s%d" % state, topmod, extrainfo): + if print_failed_asserts_worker(topmod, "s%d" % state, topmod, extrainfo, infomap): found_failed_assert = True return found_failed_assert @@ -1145,6 +1404,43 @@ def get_cover_list(mod, base): return cover_expr, cover_desc + +def get_assert_map(mod, base, path, key_base=()): + assert mod in smt.modinfo + + assert_map = dict() + + for expr, desc in smt.modinfo[mod].asserts.items(): + assert_map[(expr, key_base)] = ("(|%s| %s)" % (expr, base), path, desc) + + for cell, submod in smt.modinfo[mod].cells.items(): + assert_map.update(get_assert_map(submod, "(|%s_h %s| %s)" % (mod, cell, base), path + "." + cell, (mod, cell, key_base))) + + return assert_map + + +def get_assert_keys(): + keys = set() + keys.update(get_assert_map(topmod, 'state', topmod).keys()) + for step_constr_asserts in constr_asserts.values(): + keys.update(loc for loc, expr in step_constr_asserts) + + return keys + + +def get_active_assert_map(step, active): + assert_map = dict() + for key, assert_data in get_assert_map(topmod, "s%s" % step, topmod).items(): + if key in active: + assert_map[key] = assert_data + + for loc, expr, actual_expr in zip(*get_constr_expr(constr_asserts, step, individual=True)): + if loc in active: + assert_map[loc] = (actual_expr, None, (expr, loc)) + + return assert_map + + states = list() asserts_antecedent_cache = [list()] asserts_consequent_cache = [list()] @@ -1337,12 +1633,16 @@ def smt_check_sat(expected=["sat", "unsat"]): print_msg("Temporal induction failed!") print_anyconsts(num_steps) print_failed_asserts(num_steps) - write_trace(step, num_steps+1, '%') + write_trace(step, num_steps+1, '%', allregs=True) + if detect_loops: + loop = detect_state_loop(step, num_steps+1) + if loop: + print_msg(f"Loop detected, increasing induction depth will not help. Step {loop[0]} = step {loop[1]}") elif dumpall: print_anyconsts(num_steps) print_failed_asserts(num_steps) - write_trace(step, num_steps+1, "%d" % step) + write_trace(step, num_steps+1, "%d" % step, allregs=True) else: print_msg("Temporal induction successful.") @@ -1454,6 +1754,10 @@ def smt_check_sat(expected=["sat", "unsat"]): print_msg("Unreached cover statement at %s." % cover_desc[i]) else: # not tempind, covermode + active_assert_keys = get_assert_keys() + failed_assert_infomap = dict() + traceidx = 0 + step = 0 retstatus = "PASSED" while step < num_steps: @@ -1507,44 +1811,95 @@ def smt_check_sat(expected=["sat", "unsat"]): break if not final_only: - if last_check_step == step: - print_msg("Checking assertions in step %d.." % (step)) - else: - print_msg("Checking assertions in steps %d to %d.." % (step, last_check_step)) - smt_push() - - smt_assert("(not (and %s))" % " ".join(["(|%s_a| s%d)" % (topmod, i) for i in range(step, last_check_step+1)] + - [get_constr_expr(constr_asserts, i) for i in range(step, last_check_step+1)])) - - if smt_check_sat() == "sat": - print("%s BMC failed!" % smt.timestamp()) - if append_steps > 0: - for i in range(last_check_step+1, last_check_step+1+append_steps): - print_msg("Appending additional step %d." % i) - smt_state(i) - smt_assert_antecedent("(not (|%s_is| s%d))" % (topmod, i)) - smt_assert_consequent("(|%s_u| s%d)" % (topmod, i)) - smt_assert_antecedent("(|%s_h| s%d)" % (topmod, i)) - smt_assert_antecedent("(|%s_t| s%d s%d)" % (topmod, i-1, i)) - smt_assert_consequent(get_constr_expr(constr_assumes, i)) - print_msg("Re-solving with appended steps..") - if smt_check_sat() == "unsat": - print("%s Cannot append steps without violating assumptions!" % smt.timestamp()) - retstatus = "FAILED" - break - print_anyconsts(step) + recheck_current_step = True + while recheck_current_step: + recheck_current_step = False + if last_check_step == step: + print_msg("Checking assertions in step %d.." % (step)) + else: + print_msg("Checking assertions in steps %d to %d.." % (step, last_check_step)) + smt_push() + + active_assert_maps = dict() + active_assert_exprs = list() for i in range(step, last_check_step+1): - print_failed_asserts(i) - write_trace(0, last_check_step+1+append_steps, '%') - retstatus = "FAILED" - break + assert_expr_map = get_active_assert_map(i, active_assert_keys) + active_assert_maps[i] = assert_expr_map + active_assert_exprs.extend(assert_data[0] for assert_data in assert_expr_map.values()) - smt_pop() + if active_assert_exprs: + if len(active_assert_exprs) == 1: + active_assert_expr = active_assert_exprs[0] + else: + active_assert_expr = "(and %s)" % " ".join(active_assert_exprs) + + smt_assert("(not %s)" % active_assert_expr) + else: + active_assert_expr = "true" + smt_assert("false") + + + if smt_check_sat() == "sat": + if retstatus != "FAILED": + print("%s BMC failed!" % smt.timestamp()) + + if check_witness: + print_msg("Checking witness constraints...") + smt_pop() + smt_push() + smt_assert(active_assert_expr) + if smt_check_sat() != "sat": + retstatus = "PASSED" + check_witness = False + num_steps = -1 + break + + if append_steps > 0: + for i in range(last_check_step+1, last_check_step+1+append_steps): + print_msg("Appending additional step %d." % i) + smt_state(i) + smt_assert_antecedent("(not (|%s_is| s%d))" % (topmod, i)) + smt_assert_consequent("(|%s_u| s%d)" % (topmod, i)) + smt_assert_antecedent("(|%s_h| s%d)" % (topmod, i)) + smt_assert_antecedent("(|%s_t| s%d s%d)" % (topmod, i-1, i)) + smt_assert_consequent(get_constr_expr(constr_assumes, i)) + print_msg("Re-solving with appended steps..") + if smt_check_sat() == "unsat": + print("%s Cannot append steps without violating assumptions!" % smt.timestamp()) + retstatus = "FAILED" + break + print_anyconsts(step) + + for i in range(step, last_check_step+1): + print_failed_asserts(i, infomap=failed_assert_infomap) + + if keep_going: + for i in range(step, last_check_step+1): + for key, (expr, path, desc) in active_assert_maps[i].items(): + if key in active_assert_keys and not smt.bv2int(smt.get(expr)): + failed_assert_infomap[key] = " [failed before]" + + active_assert_keys.remove(key) + + if active_assert_keys: + recheck_current_step = True + + write_trace(0, last_check_step+1+append_steps, "%d" % traceidx if keep_going else '%') + traceidx += 1 + retstatus = "FAILED" + + smt_pop() + if recheck_current_step: + print_msg("Checking remaining assertions..") + + if retstatus == "FAILED" and not (keep_going and active_assert_keys): + break if (constr_final_start is not None) or (last_check_step+1 != num_steps): for i in range(step, last_check_step+1): - smt_assert("(|%s_a| s%d)" % (topmod, i)) - smt_assert(get_constr_expr(constr_asserts, i)) + assert_expr_map = get_active_assert_map(i, active_assert_keys) + for assert_data in assert_expr_map.values(): + smt_assert(assert_data[0]) if constr_final_start is not None: for i in range(step, last_check_step+1): @@ -1591,6 +1946,8 @@ def smt_check_sat(expected=["sat", "unsat"]): print_anyconsts(0) write_trace(0, num_steps, '%') + if check_witness: + retstatus = "FAILED" smt.write("(exit)") smt.wait() diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index d73a875ba4c..a7374589690 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -16,11 +16,11 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # -import sys, re, os, signal +import sys, re, os, signal, json import subprocess if os.name == "posix": import resource -from copy import deepcopy +from copy import copy from select import select from time import time from queue import Queue, Empty @@ -108,6 +108,7 @@ def __init__(self): self.allconsts = dict() self.allseqs = dict() self.asize = dict() + self.witness = [] class SmtIo: @@ -123,6 +124,7 @@ def __init__(self, opts=None): self.forall = False self.timeout = 0 self.produce_models = True + self.recheck = False self.smt2cache = [list()] self.smt2_options = dict() self.p = None @@ -176,7 +178,10 @@ def setup(self): self.unroll = False if self.solver == "yices": - if self.noincr or self.forall: + if self.forall: + self.noincr = True + + if self.noincr: self.popen_vargs = ['yices-smt2'] + self.solver_opts else: self.popen_vargs = ['yices-smt2', '--incremental'] + self.solver_opts @@ -189,11 +194,12 @@ def setup(self): if self.timeout != 0: self.popen_vargs.append('-T:%d' % self.timeout); - if self.solver == "cvc4": + if self.solver in ["cvc4", "cvc5"]: + self.recheck = True if self.noincr: - self.popen_vargs = ['cvc4', '--lang', 'smt2.6' if self.logic_dt else 'smt2'] + self.solver_opts + self.popen_vargs = [self.solver, '--lang', 'smt2.6' if self.logic_dt else 'smt2'] + self.solver_opts else: - self.popen_vargs = ['cvc4', '--incremental', '--lang', 'smt2.6' if self.logic_dt else 'smt2'] + self.solver_opts + self.popen_vargs = [self.solver, '--incremental', '--lang', 'smt2.6' if self.logic_dt else 'smt2'] + self.solver_opts if self.timeout != 0: self.popen_vargs.append('--tlimit=%d000' % self.timeout); @@ -301,7 +307,7 @@ def unroll_stmt(self, stmt): key = tuple(stmt) if key not in self.unroll_cache: - decl = deepcopy(self.unroll_decls[key[0]]) + decl = copy(self.unroll_decls[key[0]]) self.unroll_cache[key] = "|UNROLL#%d|" % self.unroll_idcnt decl[1] = self.unroll_cache[key] @@ -332,7 +338,7 @@ def unroll_stmt(self, stmt): def p_thread_main(self): while True: - data = self.p.stdout.readline().decode("ascii") + data = self.p.stdout.readline().decode("utf-8") if data == "": break self.p_queue.put(data) self.p_queue.put("") @@ -354,7 +360,7 @@ def p_open(self): def p_write(self, data, flush): assert self.p is not None - self.p.stdin.write(bytes(data, "ascii")) + self.p.stdin.write(bytes(data, "utf-8")) if flush: self.p.stdin.flush() def p_read(self): @@ -404,6 +410,15 @@ def write(self, stmt, unroll=True): stmt = re.sub(r" *;.*", "", stmt) if stmt == "": return + recheck = None + + if self.solver != "dummy": + if self.noincr: + # Don't close the solver yet, if we're just unrolling definitions + # required for a (get-...) statement + if self.p is not None and not stmt.startswith("(get-") and unroll: + self.p_close() + if unroll and self.unroll: stmt = self.unroll_buffer + stmt self.unroll_buffer = "" @@ -415,6 +430,9 @@ def write(self, stmt, unroll=True): s = self.parse(stmt) + if self.recheck and s and s[0].startswith("get-"): + recheck = self.unroll_idcnt + if self.debug_print: print("-> %s" % s) @@ -440,12 +458,15 @@ def write(self, stmt, unroll=True): stmt = self.unparse(self.unroll_stmt(s)) + if recheck is not None and recheck != self.unroll_idcnt: + self.check_sat(["sat"]) + if stmt == "(push 1)": self.unroll_stack.append(( - deepcopy(self.unroll_sorts), - deepcopy(self.unroll_objs), - deepcopy(self.unroll_decls), - deepcopy(self.unroll_cache), + copy(self.unroll_sorts), + copy(self.unroll_objs), + copy(self.unroll_decls), + copy(self.unroll_cache), )) if stmt == "(pop 1)": @@ -460,8 +481,6 @@ def write(self, stmt, unroll=True): if self.solver != "dummy": if self.noincr: - if self.p is not None and not stmt.startswith("(get-"): - self.p_close() if stmt == "(push 1)": self.smt2cache.append(list()) elif stmt == "(pop 1)": @@ -536,10 +555,16 @@ def info(self, stmt): self.modinfo[self.curmod].clocks[fields[2]] = "event" if fields[1] == "yosys-smt2-assert": - self.modinfo[self.curmod].asserts["%s_a %s" % (self.curmod, fields[2])] = fields[3] + if len(fields) > 4: + self.modinfo[self.curmod].asserts["%s_a %s" % (self.curmod, fields[2])] = f'{fields[4]} ({fields[3]})' + else: + self.modinfo[self.curmod].asserts["%s_a %s" % (self.curmod, fields[2])] = fields[3] if fields[1] == "yosys-smt2-cover": - self.modinfo[self.curmod].covers["%s_c %s" % (self.curmod, fields[2])] = fields[3] + if len(fields) > 4: + self.modinfo[self.curmod].covers["%s_c %s" % (self.curmod, fields[2])] = f'{fields[4]} ({fields[3]})' + else: + self.modinfo[self.curmod].covers["%s_c %s" % (self.curmod, fields[2])] = fields[3] if fields[1] == "yosys-smt2-maximize": self.modinfo[self.curmod].maximize.add(fields[2]) @@ -563,6 +588,11 @@ def info(self, stmt): self.modinfo[self.curmod].allseqs[fields[2]] = (fields[4], None if len(fields) <= 5 else fields[5]) self.modinfo[self.curmod].asize[fields[2]] = int(fields[3]) + if fields[1] == "yosys-smt2-witness": + data = json.loads(stmt.split(None, 2)[2]) + if data.get("type") in ["cell", "mem", "posedge", "negedge", "input", "reg", "init", "seq", "blackbox"]: + self.modinfo[self.curmod].witness.append(data) + def hiernets(self, top, regs_only=False): def hiernets_worker(nets, mod, cursor): for netname in sorted(self.modinfo[mod].wsize.keys()): @@ -634,6 +664,57 @@ def hiermems_worker(mems, mod, cursor): hiermems_worker(mems, top, []) return mems + def hierwitness(self, top, allregs=False, blackbox=True): + init_witnesses = [] + seq_witnesses = [] + clk_witnesses = [] + mem_witnesses = [] + + def absolute(path, cursor, witness): + return { + **witness, + "path": path + tuple(witness["path"]), + "smtpath": cursor + [witness["smtname"]], + } + + for witness in self.modinfo[top].witness: + if witness["type"] == "input": + seq_witnesses.append(absolute((), [], witness)) + if witness["type"] in ("posedge", "negedge"): + clk_witnesses.append(absolute((), [], witness)) + + init_types = ["init"] + if allregs: + init_types.append("reg") + + seq_types = ["seq"] + if blackbox: + seq_types.append("blackbox") + + def worker(mod, path, cursor): + cell_paths = {} + for witness in self.modinfo[mod].witness: + if witness["type"] in init_types: + init_witnesses.append(absolute(path, cursor, witness)) + if witness["type"] in seq_types: + seq_witnesses.append(absolute(path, cursor, witness)) + if witness["type"] == "mem": + if allregs and not witness["rom"]: + width, size = witness["width"], witness["size"] + witness = {**witness, "uninitialized": [{"width": width * size, "offset": 0}]} + if not witness["uninitialized"]: + continue + + mem_witnesses.append(absolute(path, cursor, witness)) + if witness["type"] == "cell": + cell_paths[witness["smtname"]] = tuple(witness["path"]) + + for cellname, celltype in sorted(self.modinfo[mod].cells.items()): + worker(celltype, path + cell_paths.get(cellname, ("?" + cellname,)), cursor + [cellname]) + + worker(top, (), []) + return init_witnesses, seq_witnesses, clk_witnesses, mem_witnesses + def read(self): stmt = [] count_brackets = 0 @@ -766,31 +847,28 @@ def check_sat(self, expected=["sat", "unsat", "unknown", "timeout", "interrupted return result def parse(self, stmt): - def worker(stmt): - if stmt[0] == '(': + def worker(stmt, cursor=0): + while stmt[cursor] in [" ", "\t", "\r", "\n"]: + cursor += 1 + + if stmt[cursor] == '(': expr = [] - cursor = 1 + cursor += 1 while stmt[cursor] != ')': - el, le = worker(stmt[cursor:]) + el, cursor = worker(stmt, cursor) expr.append(el) - cursor += le return expr, cursor+1 - if stmt[0] == '|': + if stmt[cursor] == '|': expr = "|" - cursor = 1 + cursor += 1 while stmt[cursor] != '|': expr += stmt[cursor] cursor += 1 expr += "|" return expr, cursor+1 - if stmt[0] in [" ", "\t", "\r", "\n"]: - el, le = worker(stmt[1:]) - return el, le+1 - expr = "" - cursor = 0 while stmt[cursor] not in ["(", ")", "|", " ", "\t", "\r", "\n"]: expr += stmt[cursor] cursor += 1 @@ -863,6 +941,8 @@ def net_expr(self, mod, base, path): assert mod in self.modinfo if path[0] == "": return base + if isinstance(path[0], int): + return "(|%s#%d| %s)" % (mod, path[0], base) if path[0] in self.modinfo[mod].cells: return "(|%s_h %s| %s)" % (mod, path[0], base) if path[0] in self.modinfo[mod].wsize: @@ -878,6 +958,15 @@ def net_expr(self, mod, base, path): nextbase = "(|%s_h %s| %s)" % (mod, path[0], base) return self.net_expr(nextmod, nextbase, path[1:]) + def witness_net_expr(self, mod, base, witness): + net = self.net_expr(mod, base, witness["smtpath"]) + is_bool = self.net_width(mod, witness["smtpath"]) == 1 + if is_bool: + assert witness["width"] == 1 + assert witness["smtoffset"] == 0 + return net + return "((_ extract %d %d) %s)" % (witness["smtoffset"] + witness["width"] - 1, witness["smtoffset"], net) + def net_width(self, mod, net_path): for i in range(len(net_path)-1): assert mod in self.modinfo @@ -885,6 +974,8 @@ def net_width(self, mod, net_path): mod = self.modinfo[mod].cells[net_path[i]] assert mod in self.modinfo + if isinstance(net_path[-1], int): + return None assert net_path[-1] in self.modinfo[mod].wsize return self.modinfo[mod].wsize[net_path[-1]] diff --git a/backends/smt2/witness.py b/backends/smt2/witness.py new file mode 100644 index 00000000000..8d0cc8112d1 --- /dev/null +++ b/backends/smt2/witness.py @@ -0,0 +1,410 @@ +#!/usr/bin/env python3 +# +# yosys -- Yosys Open SYnthesis Suite +# +# Copyright (C) 2022 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. +# + +import os, sys, itertools, re +##yosys-sys-path## +import json +import click + +from ywio import ReadWitness, WriteWitness, WitnessSig, WitnessSigMap, WitnessValues, coalesce_signals + +@click.group() +def cli(): + pass + + +@cli.command(help=""" +Display a Yosys witness trace in a human readable format. +""") +@click.argument("input", type=click.File("r")) +def display(input): + click.echo(f"Reading Yosys witness trace {input.name!r}...") + inyw = ReadWitness(input) + + def output(): + + yield click.style("*** RTLIL bit-order below may differ from source level declarations ***", fg="red") + if inyw.clocks: + yield click.style("=== Clock Signals ===", fg="blue") + for clock in inyw.clocks: + yield f" {clock['edge']} {WitnessSig(clock['path'], clock['offset']).pretty()}" + + for t, values in inyw.steps(): + if t: + yield click.style(f"=== Step {t} ===", fg="blue") + else: + yield click.style("=== Initial State ===", fg="blue") + + step_prefix = click.style(f"#{t}", fg="bright_black") + + signals, missing = values.present_signals(inyw.sigmap) + + assert not missing + + for sig in signals: + display_bits = values[sig].replace("?", click.style("?", fg="bright_black")) + yield f" {step_prefix} {sig.pretty()} = {display_bits}" + click.echo_via_pager([line + "\n" for line in output()]) + + +@cli.command(help=""" +Display statistics of a Yosys witness trace. +""") +@click.argument("input", type=click.File("r")) +def stats(input): + click.echo(f"Reading Yosys witness trace {input.name!r}...") + inyw = ReadWitness(input) + + total = 0 + + for t, values in inyw.steps(): + click.echo(f"{t:5}: {len(values.values):8} bits") + total += len(values.values) + + click.echo(f"total: {total:8} bits") + + +@cli.command(help=""" +Transform a Yosys witness trace. + +Currently no transformations are implemented, so it is only useful for testing. +""") +@click.argument("input", type=click.File("r")) +@click.argument("output", type=click.File("w")) +def yw2yw(input, output): + click.echo(f"Copying yosys witness trace from {input.name!r} to {output.name!r}...") + inyw = ReadWitness(input) + outyw = WriteWitness(output, "yosys-witness yw2yw") + + for clock in inyw.clocks: + outyw.add_clock(clock["path"], clock["offset"], clock["edge"]) + + for sig in inyw.signals: + outyw.add_sig(sig.path, sig.offset, sig.width, sig.init_only) + + for t, values in inyw.steps(): + outyw.step(values) + + outyw.end_trace() + + click.echo(f"Copied {outyw.t + 1} time steps.") + + +class AigerMap: + def __init__(self, mapfile): + data = json.load(mapfile) + + version = data.get("version") if isinstance(data, dict) else {} + if version != "Yosys Witness Aiger map": + raise click.ClickException(f"{mapfile.name}: unexpected file format version {version!r}") + + self.latch_count = data["latch_count"] + self.input_count = data["input_count"] + + self.clocks = data["clocks"] + + self.sigmap = WitnessSigMap() + self.init_inputs = set(init["input"] for init in data["inits"]) + + for bit in data["inputs"] + data["seqs"] + data["inits"]: + self.sigmap.add_bit((tuple(bit["path"]), bit["offset"]), bit["input"]) + + + +@cli.command(help=""" +Convert an AIGER witness trace into a Yosys witness trace. + +This requires a Yosys witness AIGER map file as generated by 'write_aiger -ywmap'. +""") +@click.argument("input", type=click.File("r")) +@click.argument("mapfile", type=click.File("r")) +@click.argument("output", type=click.File("w")) +def aiw2yw(input, mapfile, output): + input_name = input.name + click.echo(f"Converting AIGER witness trace {input_name!r} to Yosys witness trace {output.name!r}...") + click.echo(f"Using Yosys witness AIGER map file {mapfile.name!r}") + aiger_map = AigerMap(mapfile) + + header_lines = list(itertools.islice(input, 0, 2)) + + if len(header_lines) == 2 and header_lines[1][0] in ".bcjf": + status = header_lines[0].strip() + if status == "0": + raise click.ClickException(f"{input_name}: file contains no trace, the AIGER status is unsat") + elif status == "2": + raise click.ClickException(f"{input_name}: file contains no trace, the AIGER status is sat") + elif status != "1": + raise click.ClickException(f"{input_name}: unexpected data in AIGER witness file") + else: + input = itertools.chain(header_lines, input) + + ffline = next(input, None) + if ffline is None: + raise click.ClickException(f"{input_name}: unexpected end of file") + ffline = ffline.strip() + if not re.match(r'[01x]*$', ffline): + raise click.ClickException(f"{input_name}: unexpected data in AIGER witness file") + if not re.match(r'[0]*$', ffline): + raise click.ClickException(f"{input_name}: non-default initial state not supported") + + outyw = WriteWitness(output, 'yosys-witness aiw2yw') + + for clock in aiger_map.clocks: + outyw.add_clock(clock["path"], clock["offset"], clock["edge"]) + + for (path, offset), id in aiger_map.sigmap.bit_to_id.items(): + outyw.add_sig(path, offset, init_only=id in aiger_map.init_inputs) + + missing = set() + + while True: + inline = next(input, None) + if inline is None: + click.echo(f"Warning: {input_name}: file may be incomplete") + break + inline = inline.strip() + if inline in [".", "# DONE"]: + break + if inline.startswith("#"): + continue + + if not re.match(r'[01x]*$', ffline): + raise click.ClickException(f"{input_name}: unexpected data in AIGER witness file") + + if len(inline) != aiger_map.input_count: + raise click.ClickException( + f"{input_name}: {mapfile.name}: number of inputs does not match, " + f"{len(inline)} in witness, {aiger_map.input_count} in map file") + + values = WitnessValues() + for i, v in enumerate(inline): + if v == "x" or outyw.t > 0 and i in aiger_map.init_inputs: + continue + + try: + bit = aiger_map.sigmap.id_to_bit[i] + except IndexError: + bit = None + if bit is None: + missing.insert(i) + + values[bit] = v + + outyw.step(values) + + outyw.end_trace() + + if missing: + click.echo("The following AIGER inputs belong to unknown signals:") + click.echo(" " + " ".join(str(id) for id in sorted(missing))) + + click.echo(f"Converted {outyw.t} time steps.") + +@cli.command(help=""" +Convert a Yosys witness trace into an AIGER witness trace. + +This requires a Yosys witness AIGER map file as generated by 'write_aiger -ywmap'. +""") +@click.argument("input", type=click.File("r")) +@click.argument("mapfile", type=click.File("r")) +@click.argument("output", type=click.File("w")) +def yw2aiw(input, mapfile, output): + click.echo(f"Converting Yosys witness trace {input.name!r} to AIGER witness trace {output.name!r}...") + click.echo(f"Using Yosys witness AIGER map file {mapfile.name!r}") + aiger_map = AigerMap(mapfile) + inyw = ReadWitness(input) + + print("1", file=output) + print("b0", file=output) + # TODO the b0 status isn't really accurate, but we don't have any better info here + print("0" * aiger_map.latch_count, file=output) + + all_missing = set() + + for t, step in inyw.steps(): + bits, missing = step.pack_present(aiger_map.sigmap) + bits = bits[::-1].replace('?', 'x') + all_missing.update(missing) + bits += 'x' * (aiger_map.input_count - len(bits)) + print(bits, file=output) + + print(".", file=output) + + if all_missing: + click.echo("The following signals are missing in the AIGER map file and will be dropped:") + for sig in coalesce_signals(WitnessSig(*bit) for bit in all_missing): + click.echo(" " + sig.pretty()) + + + click.echo(f"Converted {len(inyw)} time steps.") + +class BtorMap: + def __init__(self, mapfile): + self.data = data = json.load(mapfile) + + version = data.get("version") if isinstance(data, dict) else {} + if version != "Yosys Witness BTOR map": + raise click.ClickException(f"{mapfile.name}: unexpected file format version {version!r}") + + self.sigmap = WitnessSigMap() + + for mode in ("states", "inputs"): + for btor_signal_def in data[mode]: + if btor_signal_def is None: + continue + if isinstance(btor_signal_def, dict): + btor_signal_def["path"] = tuple(btor_signal_def["path"]) + else: + for chunk in btor_signal_def: + chunk["path"] = tuple(chunk["path"]) + + +@cli.command(help=""" +Convert a BTOR witness trace into a Yosys witness trace. + +This requires a Yosys witness BTOR map file as generated by 'write_btor -ywmap'. +""") +@click.argument("input", type=click.File("r")) +@click.argument("mapfile", type=click.File("r")) +@click.argument("output", type=click.File("w")) +def wit2yw(input, mapfile, output): + input_name = input.name + click.echo(f"Converting BTOR witness trace {input_name!r} to Yosys witness trace {output.name!r}...") + click.echo(f"Using Yosys witness BTOR map file {mapfile.name!r}") + btor_map = BtorMap(mapfile) + + input = filter(None, (line.split(';', 1)[0].strip() for line in input)) + + sat = next(input, None) + if sat != "sat": + raise click.ClickException(f"{input_name}: not a BTOR witness file") + + props = next(input, None) + + t = -1 + + line = next(input, None) + + frames = [] + bits = {} + + while line and not line.startswith('.'): + current_t = int(line[1:].strip()) + if line[0] == '#': + mode = "states" + elif line[0] == '@': + mode = "inputs" + else: + raise click.ClickException(f"{input_name}: unexpected data in BTOR witness file") + + if current_t > t: + t = current_t + values = WitnessValues() + array_inits = set() + frames.append(values) + + line = next(input, None) + while line and line[0] not in "#@.": + if current_t > 0 and mode == "states": + line = next(input, None) + continue + tokens = line.split() + line = next(input, None) + + btor_sig = btor_map.data[mode][int(tokens[0])] + btor_sigs = [btor_sig] + + if btor_sig is None: + continue + + if isinstance(btor_sig, dict): + addr = tokens[1] + if not addr.startswith('['): + addr = '[*]' + value = tokens[1] + else: + value = tokens[2] + if not addr.endswith(']'): + raise click.ClickException(f"{input_name}: expected address in BTOR witness file") + path = btor_sig["path"] + width = btor_sig["width"] + size = btor_sig["size"] + if addr == '[*]': + btor_sigs = [ + [{ + "path": (*path, f"\\[{addr}]"), + "width": width, + "offset": 0, + }] + for addr in range(size) + if (path, addr) not in array_inits + ] + array_inits.update((path, addr) for addr in range(size)) + else: + addr = int(addr[1:-1], 2) + + if addr < 0 or addr >= size: + raise click.ClickException(f"{input_name}: out of bounds address in BTOR witness file") + + array_inits.add((path, addr)) + btor_sig = [{ + "path": (*path, f"\\[{addr}]"), + "width": width, + "offset": 0, + }] + btor_sigs = [btor_sig] + else: + value = tokens[1] + + for btor_sig in btor_sigs: + value_bits = iter(reversed(value)) + + for chunk in btor_sig: + offset = chunk["offset"] + path = chunk["path"] + for i in range(offset, offset + chunk["width"]): + key = (path, i) + bits[key] = mode == "inputs" + values[key] = next(value_bits) + + if next(value_bits, None) is not None: + raise click.ClickException(f"{input_name}: excess bits in BTOR witness file") + + + if line is None: + raise click.ClickException(f"{input_name}: unexpected end of BTOR witness file") + if line.strip() != '.': + raise click.ClickException(f"{input_name}: unexpected data in BTOR witness file") + if next(input, None) is not None: + raise click.ClickException(f"{input_name}: unexpected trailing data in BTOR witness file") + + outyw = WriteWitness(output, 'yosys-witness wit2yw') + + outyw.signals = coalesce_signals((), bits) + for clock in btor_map.data["clocks"]: + outyw.add_clock(clock["path"], clock["offset"], clock["edge"]) + + for values in frames: + outyw.step(values) + + outyw.end_trace() + click.echo(f"Converted {outyw.t} time steps.") + +if __name__ == "__main__": + cli() diff --git a/backends/smt2/ywio.py b/backends/smt2/ywio.py new file mode 100644 index 00000000000..39cfac41e25 --- /dev/null +++ b/backends/smt2/ywio.py @@ -0,0 +1,393 @@ +# +# yosys -- Yosys Open SYnthesis Suite +# +# Copyright (C) 2022 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. +# + +import json, re + +from functools import total_ordering + + +class PrettyJson: + def __init__(self, f): + self.f = f + self.indent = 0 + self.state = ["value"] + + def line(self): + indent = len(self.state) - bool(self.state and self.state[-1] == "value") + print("\n", end=" " * (2 * indent), file=self.f) + + def raw(self, str): + print(end=str, file=self.f) + + def begin_object(self): + self.begin_value() + self.raw("{") + self.state.append("object_first") + + def begin_array(self): + self.begin_value() + self.raw("[") + self.state.append("array_first") + + def end_object(self): + state = self.state.pop() + if state == "object": + self.line() + else: + assert state == "object_first" + self.raw("}") + self.end_value() + + def end_array(self): + state = self.state.pop() + if state == "array": + self.line() + else: + assert state == "array_first" + self.raw("]") + self.end_value() + + def name(self, name): + if self.state[-1] == "object_first": + self.state[-1] = "object" + else: + self.raw(",") + self.line() + json.dump(str(name), self.f) + self.raw(": ") + self.state.append("value") + + def begin_value(self): + if self.state[-1] == "array_first": + self.line() + self.state[-1] = "array" + elif self.state[-1] == "array": + self.raw(",") + self.line() + else: + assert self.state.pop() == "value" + + def end_value(self): + if not self.state: + print(file=self.f, flush=True) + + def value(self, value): + self.begin_value() + json.dump(value, self.f) + self.end_value() + + def entry(self, name, value): + self.name(name) + self.value(value) + + def object(self, entries=None): + if isinstance(entries, dict): + entries = dict.items() + self.begin_object() + for name, value in entries: + self.entry(name, value) + self.end_object() + + def array(self, values=None): + self.begin_array() + for value in values: + self.value(value) + self.end_array() + + +addr_re = re.compile(r'\\\[[0-9]+\]$') +public_name_re = re.compile(r"\\([a-zA-Z_][a-zA-Z0-9_]*(\[[0-9]+\])?|\[[0-9]+\])$") + +def pretty_name(id): + if public_name_re.match(id): + return id.lstrip("\\") + else: + return id + +def pretty_path(path): + out = "" + for name in path: + name = pretty_name(name) + if name.startswith("["): + out += name + continue + if out: + out += "." + if name.startswith("\\") or name.startswith("$"): + out += name + " " + else: + out += name + + return out + +@total_ordering +class WitnessSig: + def __init__(self, path, offset, width=1, init_only=False): + path = tuple(path) + self.path, self.width, self.offset, self.init_only = path, width, offset, init_only + + self.memory_path = None + self.memory_addr = None + + sort_path = path + sort_id = -1 + if path and addr_re.match(path[-1]): + self.memory_path = sort_path = path[:-1] + self.memory_addr = sort_id = int(path[-1][2:-1]) + + self.sort_key = (init_only, sort_path, sort_id, offset, width) + + def bits(self): + return ((self.path, i) for i in range(self.offset, self.offset + self.width)) + + def rev_bits(self): + return ((self.path, i) for i in reversed(range(self.offset, self.offset + self.width))) + + def pretty(self): + if self.width > 1: + last_offset = self.offset + self.width - 1 + return f"{pretty_path(self.path)}[{last_offset}:{self.offset}]" + else: + return f"{pretty_path(self.path)}[{self.offset}]" + + def __eq__(self): + return self.sort_key + + def __hash__(self): + return hash(self.sort_key) + + def __lt__(self, other): + return self.sort_key < other.sort_key + + +def coalesce_signals(signals, bits=None): + if bits is None: + bits = {} + for sig in signals: + for bit in sig.bits(): + if sig.init_only: + bits.setdefault(bit, False) + else: + bits[bit] = True + + active = None + + out = [] + + for bit, not_init in sorted(bits.items()): + if active: + if active[0] == bit[0] and active[2] == bit[1] and active[3] == not_init: + active[2] += 1 + else: + out.append(WitnessSig(active[0], active[1], active[2] - active[1], not active[3])) + active = None + + if active is None: + active = [bit[0], bit[1], bit[1] + 1, not_init] + + if active: + out.append(WitnessSig(active[0], active[1], active[2] - active[1], not active[3])) + + return sorted(out) + + +class WitnessSigMap: + def __init__(self, signals=[]): + self.signals = [] + + self.id_to_bit = [] + self.bit_to_id = {} + self.bit_to_sig = {} + + for sig in signals: + self.add_signal(sig) + + def add_signal(self, sig): + self.signals.append(sig) + for bit in sig.bits(): + self.add_bit(bit) + self.bit_to_sig[bit] = sig + + def add_bit(self, bit, id=None): + if id is None: + id = len(self.id_to_bit) + self.id_to_bit.append(bit) + else: + if len(self.id_to_bit) <= id: + self.id_to_bit += [None] * (id - len(self.id_to_bit) + 1) + self.id_to_bit[id] = bit + self.bit_to_id[bit] = id + + +class WitnessValues: + def __init__(self): + self.values = {} + + def __setitem__(self, key, value): + if isinstance(key, tuple) and len(key) == 2: + if value != "?": + assert isinstance(value, str) + assert len(value) == 1 + self.values[key] = value + else: + assert isinstance(key, WitnessSig) + assert key.width == len(value) + if isinstance(value, str): + value = reversed(value) + for bit, bit_value in zip(key.bits(), value): + if bit_value != "?": + self.values[bit] = bit_value + + def __getitem__(self, key): + if isinstance(key, tuple) and len(key) == 2: + return self.values.get(key, "?") + else: + assert isinstance(key, WitnessSig) + return "".join([self.values.get(bit, "?") for bit in key.rev_bits()]) + + def pack_present(self, sigmap): + missing = [] + + max_id = max((sigmap.bit_to_id.get(bit, -1) for bit in self.values), default=-1) + + vector = ["?"] * (max_id + 1) + for bit, bit_value in self.values.items(): + id = sigmap.bit_to_id.get(bit, - 1) + if id < 0: + missing.append(bit) + else: + vector[max_id - sigmap.bit_to_id[bit]] = bit_value + + return "".join(vector), missing + + def pack(self, sigmap): + packed, missing = self.pack_present(sigmap) + if missing: + raise RuntimeError(f"Cannot pack bits {missing!r}") + return packed + + def unpack(self, sigmap, bits): + for i, bit_value in enumerate(reversed(bits)): + if bit_value != "?": + self.values[sigmap.id_to_bit[i]] = bit_value + + def present_signals(self, sigmap): + signals = set(sigmap.bit_to_sig.get(bit) for bit in self.values) + missing_signals = None in signals + if missing_signals: + signals.discard(None) + + return sorted(signals), missing_signals + + +class WriteWitness: + def __init__(self, f, generator): + self.out = PrettyJson(f) + self.t = 0 + self.header_written = False + self.clocks = [] + self.signals = [] + + self.out.begin_object() + self.out.entry("format", "Yosys Witness Trace") + self.out.entry("generator", generator) + + def add_clock(self, path, offset, edge): + assert not self.header_written + self.clocks.append({ + "path": path, + "edge": edge, + "offset": offset, + }) + + def add_sig(self, path, offset, width=1, init_only=False): + assert not self.header_written + sig = WitnessSig(path, offset, width, init_only) + self.signals.append(sig) + return sig + + def write_header(self): + assert not self.header_written + self.header_written = True + self.out.name("clocks") + self.out.array(self.clocks) + + self.signals = coalesce_signals(self.signals) + self.sigmap = WitnessSigMap(self.signals) + + self.out.name("signals") + self.out.array({ + "path": sig.path, + "width": sig.width, + "offset": sig.offset, + "init_only": sig.init_only, + } for sig in self.signals) + + self.out.name("steps") + self.out.begin_array() + + def step(self, values): + if not self.header_written: + self.write_header() + + self.out.value({"bits": values.pack(self.sigmap)}) + + self.t += 1 + + def end_trace(self): + if not self.header_written: + self.write_header() + self.out.end_array() + self.out.end_object() + + +class ReadWitness: + def __init__(self, f): + data = json.load(f) + if not isinstance(data, dict): + data = {} + + data_format = data.get("format", "Unknown Format") + + if data_format != "Yosys Witness Trace": + raise ValueError(f"unsupported format {data_format!r}") + + self.clocks = data["clocks"] + for clock in self.clocks: + clock["path"] = tuple(clock["path"]) + + self.signals = [ + WitnessSig(sig["path"], sig["offset"], sig["width"], sig["init_only"]) + for sig in data["signals"] + ] + + self.sigmap = WitnessSigMap(self.signals) + + self.bits = [step["bits"] for step in data["steps"]] + + def step(self, t): + values = WitnessValues() + values.unpack(self.sigmap, self.bits[t]) + return values + + def steps(self): + for i in range(len(self.bits)): + yield i, self.step(i) + + def __len__(self): + return len(self.bits) diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc index f4723d2a675..49c2cc7a6c4 100644 --- a/backends/smv/smv.cc +++ b/backends/smv/smv.cc @@ -578,7 +578,7 @@ struct SmvWorker log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smv`.\n", log_id(cell->type), log_id(module), log_id(cell)); } - if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") { + if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smv`.\n", log_id(cell->type), log_id(module), log_id(cell)); } @@ -741,6 +741,12 @@ struct SmvBackend : public Backend { log_header(design, "Executing SMV backend.\n"); + log_push(); + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); + Pass::call(design, "bwmuxmap"); + log_pop(); + size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 47b48a46039..3da168960f4 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -35,7 +35,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog, simple_lhs; +bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog, simple_lhs, noparallelcase; int auto_name_counter, auto_name_offset, auto_name_digits, extmem_counter; std::map auto_name_map; std::set reg_wires; @@ -44,6 +44,7 @@ std::string auto_prefix, extmem_prefix; RTLIL::Module *active_module; dict active_initdata; SigMap active_sigmap; +IdString initial_id; void reset_auto_counter_id(RTLIL::IdString id, bool may_rename) { @@ -357,7 +358,8 @@ void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool no_decima void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig) { if (GetSize(sig) == 0) { - f << "\"\""; + // See IEEE 1364-2005 Clause 5.1.14. + f << "{0{1'b0}}"; return; } if (sig.is_chunk()) { @@ -430,7 +432,7 @@ void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire) dump_const(f, wire->attributes.at(ID::init)); } f << stringf(";\n"); - } else if (!wire->port_input && !wire->port_output) + } else f << stringf("%s" "wire%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); #endif } @@ -1207,7 +1209,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) if (cell->type == ID($modfloor)) { // wire truncated = $signed(A) % $signed(B); - // assign Y = (A[-1] == B[-1]) || truncated == 0 ? truncated : $signed(B) + $signed(truncated); + // assign Y = (A[-1] == B[-1]) || truncated == 0 ? $signed(truncated) : $signed(B) + $signed(truncated); if (cell->getParam(ID::A_SIGNED).as_bool() && cell->getParam(ID::B_SIGNED).as_bool()) { SigSpec sig_a = cell->getPort(ID::A); @@ -1227,7 +1229,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) dump_sigspec(f, sig_a.extract(sig_a.size()-1)); f << stringf(" == "); dump_sigspec(f, sig_b.extract(sig_b.size()-1)); - f << stringf(") || %s == 0 ? %s : ", temp_id.c_str(), temp_id.c_str()); + f << stringf(") || %s == 0 ? $signed(%s) : ", temp_id.c_str(), temp_id.c_str()); dump_cell_expr_port(f, cell, "B", true); f << stringf(" + $signed(%s);\n", temp_id.c_str()); return true; @@ -1312,24 +1314,38 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf("%s" " input [%d:0] s;\n", indent.c_str(), s_width-1); dump_attributes(f, indent + " ", cell->attributes); - if (!noattr) - f << stringf("%s" " (* parallel_case *)\n", indent.c_str()); - f << stringf("%s" " casez (s)", indent.c_str()); - f << stringf(noattr ? " // synopsys parallel_case\n" : "\n"); + if (noparallelcase) + f << stringf("%s" " case (s)\n", indent.c_str()); + else { + if (!noattr) + f << stringf("%s" " (* parallel_case *)\n", indent.c_str()); + f << stringf("%s" " casez (s)", indent.c_str()); + f << stringf(noattr ? " // synopsys parallel_case\n" : "\n"); + } for (int i = 0; i < s_width; i++) { f << stringf("%s" " %d'b", indent.c_str(), s_width); for (int j = s_width-1; j >= 0; j--) - f << stringf("%c", j == i ? '1' : '?'); + f << stringf("%c", j == i ? '1' : noparallelcase ? '0' : '?'); f << stringf(":\n"); f << stringf("%s" " %s = b[%d:%d];\n", indent.c_str(), func_name.c_str(), (i+1)*width-1, i*width); } - f << stringf("%s" " default:\n", indent.c_str()); + if (noparallelcase) { + f << stringf("%s" " %d'b", indent.c_str(), s_width); + for (int j = s_width-1; j >= 0; j--) + f << '0'; + f << stringf(":\n"); + } else + f << stringf("%s" " default:\n", indent.c_str()); f << stringf("%s" " %s = a;\n", indent.c_str(), func_name.c_str()); + if (noparallelcase) { + f << stringf("%s" " default:\n", indent.c_str()); + f << stringf("%s" " %s = %d'bx;\n", indent.c_str(), func_name.c_str(), width); + } f << stringf("%s" " endcase\n", indent.c_str()); f << stringf("%s" "endfunction\n", indent.c_str()); @@ -1398,7 +1414,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) FfData ff(nullptr, cell); // $ff / $_FF_ cell: not supported. - if (ff.has_d && !ff.has_clk && !ff.has_en) + if (ff.has_gclk) return false; std::string reg_name = cellname(cell); @@ -1419,17 +1435,19 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) for (int i = 0; i < chunks; i++) { - SigSpec sig_d; + SigSpec sig_d, sig_ad; Const val_arst, val_srst; - std::string reg_bit_name, sig_set_name, sig_clr_name, sig_arst_name; + std::string reg_bit_name, sig_set_name, sig_clr_name, sig_arst_name, sig_aload_name; if (chunky) { reg_bit_name = stringf("%s[%d]", reg_name.c_str(), i); - if (ff.has_d) + if (ff.has_gclk || ff.has_clk) sig_d = ff.sig_d[i]; + if (ff.has_aload) + sig_ad = ff.sig_ad[i]; } else { reg_bit_name = reg_name; - if (ff.has_d) - sig_d = ff.sig_d; + sig_d = ff.sig_d; + sig_ad = ff.sig_ad; } if (ff.has_arst) val_arst = chunky ? ff.val_arst[i] : ff.val_arst; @@ -1437,28 +1455,38 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) val_srst = chunky ? ff.val_srst[i] : ff.val_srst; // If there are constants in the sensitivity list, replace them with an intermediate wire - if (ff.has_sr) { - if (ff.sig_set[i].wire == NULL) - { - sig_set_name = next_auto_id(); - f << stringf("%s" "wire %s = ", indent.c_str(), sig_set_name.c_str()); - dump_const(f, ff.sig_set[i].data); - f << stringf(";\n"); - } - if (ff.sig_clr[i].wire == NULL) - { - sig_clr_name = next_auto_id(); - f << stringf("%s" "wire %s = ", indent.c_str(), sig_clr_name.c_str()); - dump_const(f, ff.sig_clr[i].data); - f << stringf(";\n"); - } - } else if (ff.has_arst) { - if (ff.sig_arst[i].wire == NULL) - { - sig_arst_name = next_auto_id(); - f << stringf("%s" "wire %s = ", indent.c_str(), sig_arst_name.c_str()); - dump_const(f, ff.sig_arst[i].data); - f << stringf(";\n"); + if (ff.has_clk) { + if (ff.has_sr) { + if (ff.sig_set[i].wire == NULL) + { + sig_set_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_set_name.c_str()); + dump_const(f, ff.sig_set[i].data); + f << stringf(";\n"); + } + if (ff.sig_clr[i].wire == NULL) + { + sig_clr_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_clr_name.c_str()); + dump_const(f, ff.sig_clr[i].data); + f << stringf(";\n"); + } + } else if (ff.has_arst) { + if (ff.sig_arst[0].wire == NULL) + { + sig_arst_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_arst_name.c_str()); + dump_const(f, ff.sig_arst[0].data); + f << stringf(";\n"); + } + } else if (ff.has_aload) { + if (ff.sig_aload[0].wire == NULL) + { + sig_aload_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_aload_name.c_str()); + dump_const(f, ff.sig_aload[0].data); + f << stringf(";\n"); + } } } @@ -1480,13 +1508,18 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf("%s", sig_clr_name.c_str()); else dump_sigspec(f, ff.sig_clr[i]); - } else if (ff.has_arst) { f << stringf(", %sedge ", ff.pol_arst ? "pos" : "neg"); - if (ff.sig_arst[i].wire == NULL) + if (ff.sig_arst[0].wire == NULL) f << stringf("%s", sig_arst_name.c_str()); else dump_sigspec(f, ff.sig_arst); + } else if (ff.has_aload) { + f << stringf(", %sedge ", ff.pol_aload ? "pos" : "neg"); + if (ff.sig_aload[0].wire == NULL) + f << stringf("%s", sig_aload_name.c_str()); + else + dump_sigspec(f, ff.sig_aload); } f << stringf(")\n"); @@ -1507,7 +1540,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf("%s" " else ", indent.c_str()); } else if (ff.has_arst) { f << stringf("if (%s", ff.pol_arst ? "" : "!"); - if (ff.sig_arst[i].wire == NULL) + if (ff.sig_arst[0].wire == NULL) f << stringf("%s", sig_arst_name.c_str()); else dump_sigspec(f, ff.sig_arst); @@ -1515,11 +1548,21 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) dump_sigspec(f, val_arst); f << stringf(";\n"); f << stringf("%s" " else ", indent.c_str()); + } else if (ff.has_aload) { + f << stringf("if (%s", ff.pol_aload ? "" : "!"); + if (ff.sig_aload[0].wire == NULL) + f << stringf("%s", sig_aload_name.c_str()); + else + dump_sigspec(f, ff.sig_aload); + f << stringf(") %s <= ", reg_bit_name.c_str()); + dump_sigspec(f, sig_ad); + f << stringf(";\n"); + f << stringf("%s" " else ", indent.c_str()); } - if (ff.has_srst && ff.has_en && ff.ce_over_srst) { - f << stringf("if (%s", ff.pol_en ? "" : "!"); - dump_sigspec(f, ff.sig_en); + if (ff.has_srst && ff.has_ce && ff.ce_over_srst) { + f << stringf("if (%s", ff.pol_ce ? "" : "!"); + dump_sigspec(f, ff.sig_ce); f << stringf(")\n"); f << stringf("%s" " if (%s", indent.c_str(), ff.pol_srst ? "" : "!"); dump_sigspec(f, ff.sig_srst); @@ -1536,9 +1579,9 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf(";\n"); f << stringf("%s" " else ", indent.c_str()); } - if (ff.has_en) { - f << stringf("if (%s", ff.pol_en ? "" : "!"); - dump_sigspec(f, ff.sig_en); + if (ff.has_ce) { + f << stringf("if (%s", ff.pol_ce ? "" : "!"); + dump_sigspec(f, ff.sig_ce); f << stringf(") "); } } @@ -1560,7 +1603,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf("%s" " else if (%s", indent.c_str(), ff.pol_set ? "" : "!"); dump_sigspec(f, ff.sig_set[i]); f << stringf(") %s = 1'b1;\n", reg_bit_name.c_str()); - if (ff.has_d) + if (ff.has_aload) f << stringf("%s" " else ", indent.c_str()); } else if (ff.has_arst) { f << stringf("if (%s", ff.pol_arst ? "" : "!"); @@ -1568,14 +1611,14 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf(") %s = ", reg_bit_name.c_str()); dump_sigspec(f, val_arst); f << stringf(";\n"); - if (ff.has_d) + if (ff.has_aload) f << stringf("%s" " else ", indent.c_str()); } - if (ff.has_d) { - f << stringf("if (%s", ff.pol_en ? "" : "!"); - dump_sigspec(f, ff.sig_en); + if (ff.has_aload) { + f << stringf("if (%s", ff.pol_aload ? "" : "!"); + dump_sigspec(f, ff.sig_aload); f << stringf(") %s = ", reg_bit_name.c_str()); - dump_sigspec(f, sig_d); + dump_sigspec(f, sig_ad); f << stringf(";\n"); } } @@ -1916,7 +1959,7 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo f << stringf("%s" "always%s begin\n", indent.c_str(), systemverilog ? "_comb" : " @*"); if (!systemverilog) - f << indent + " " << "if (" << id("\\initial") << ") begin end\n"; + f << indent + " " << "if (" << id(initial_id) << ") begin end\n"; dump_case_body(f, indent, &proc->root_case, true); std::string backup_indent = indent; @@ -2035,6 +2078,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) dump_attributes(f, indent, module->attributes, '\n', /*modattr=*/true); f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str()); bool keep_running = true; + int cnt = 0; for (int port_id = 1; keep_running; port_id++) { keep_running = false; for (auto wire : module->wires()) { @@ -2043,14 +2087,16 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) f << stringf(", "); f << stringf("%s", id(wire->name).c_str()); keep_running = true; + if (cnt==20) { f << stringf("\n"); cnt = 0; } else cnt++; continue; } } } f << stringf(");\n"); - - if (!systemverilog && !module->processes.empty()) - f << indent + " " << "reg " << id("\\initial") << " = 0;\n"; + if (!systemverilog && !module->processes.empty()) { + initial_id = NEW_ID; + f << indent + " " << "reg " << id(initial_id) << " = 0;\n"; + } for (auto w : module->wires()) dump_wire(f, indent + " ", w); @@ -2104,6 +2150,11 @@ struct VerilogBackend : public Backend { log(" without this option all internal cells are converted to Verilog\n"); log(" expressions.\n"); log("\n"); + log(" -noparallelcase\n"); + log(" With this option no parallel_case attributes are used. Instead, a case\n"); + log(" statement that assigns don't-care values for priority dependent inputs\n"); + log(" is generated.\n"); + log("\n"); log(" -siminit\n"); log(" add initial statements with hierarchical refs to initialize FFs when\n"); log(" in -noexpr mode.\n"); @@ -2128,7 +2179,8 @@ struct VerilogBackend : public Backend { log(" as binary numbers.\n"); log("\n"); log(" -simple-lhs\n"); - log(" Connection assignments with simple left hand side without concatenations.\n"); + log(" Connection assignments with simple left hand side without\n"); + log(" concatenations.\n"); log("\n"); log(" -extmem\n"); log(" instead of initializing memories using assignments to individual\n"); @@ -2178,6 +2230,7 @@ struct VerilogBackend : public Backend { decimal = false; siminit = false; simple_lhs = false; + noparallelcase = false; auto_prefix = ""; bool blackboxes = false; @@ -2213,6 +2266,10 @@ struct VerilogBackend : public Backend { noexpr = true; continue; } + if (arg == "-noparallelcase") { + noparallelcase = true; + continue; + } if (arg == "-nodec") { nodec = true; continue; @@ -2268,6 +2325,14 @@ struct VerilogBackend : public Backend { extmem_prefix = filename.substr(0, filename.rfind('.')); } + log_push(); + if (!noexpr) { + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); + } + Pass::call(design, "clean_zerowidth"); + log_pop(); + design->sort(); *f << stringf("/* Generated by %s */\n", yosys_version_str); diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000000..e36f2309a01 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,11 @@ +/build/ +/source/cmd +/source/temp +/images/*.log +/images/*.aux +/images/*.pdf +/images/*.svg +/images/011/*.log +/images/011/*.aux +/images/011/*.pdf +/images/011/*.svg diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000000..2319e1665c3 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,226 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " epub3 to make an epub3" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + @echo " dummy to check syntax errors of document sources" + +.PHONY: clean +clean: + rm -rf $(BUILDDIR)/* + +.PHONY: html +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +.PHONY: dirhtml +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +# singlehtml section links are broken +.PHONY: singlehtml +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +.PHONY: pickle +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +.PHONY: json +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +.PHONY: htmlhelp +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +.PHONY: qthelp +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SymbiYosys.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SymbiYosys.qhc" + +.PHONY: applehelp +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +.PHONY: devhelp +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/SymbiYosys" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SymbiYosys" + @echo "# devhelp" + +.PHONY: epub +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +.PHONY: epub3 +epub3: + $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 + @echo + @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." + +.PHONY: latex +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +.PHONY: latexpdf +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: latexpdfja +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: text +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +.PHONY: man +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +.PHONY: texinfo +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +.PHONY: info +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +.PHONY: gettext +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +.PHONY: changes +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +.PHONY: linkcheck +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +.PHONY: doctest +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +.PHONY: coverage +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +.PHONY: xml +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +.PHONY: pseudoxml +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +.PHONY: dummy +dummy: + $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy + @echo + @echo "Build finished. Dummy builder generates no files." diff --git a/docs/images/011/example_out.tex b/docs/images/011/example_out.tex new file mode 100644 index 00000000000..831b036e993 --- /dev/null +++ b/docs/images/011/example_out.tex @@ -0,0 +1,18 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\usepackage{tikz} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture} + \node[inner sep=0pt] at (0,0) + {\includegraphics[width=\linewidth]{example_00.pdf}}; + \node[inner sep=0pt] at (0,-3.8) + {\includegraphics[width=\linewidth]{example_01.pdf}}; + \node[inner sep=0pt] at (0,-7) + {\includegraphics[width=\linewidth]{example_02.pdf}}; +\end{tikzpicture} +\end{document} diff --git a/docs/images/011/select_prod.tex b/docs/images/011/select_prod.tex new file mode 100644 index 00000000000..c4a3c6e379b --- /dev/null +++ b/docs/images/011/select_prod.tex @@ -0,0 +1,19 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture} + \node[inner sep=0pt] at (0,0) + {\hfill \includegraphics[width=4cm,trim=0 1cm 0 1cm]{sumprod_02.pdf}}; + \node[inner sep=0pt] at (0,-2.8) + {\includegraphics[width=\linewidth,trim=0 0cm 0 1cm]{sumprod_03.pdf}}; + \node[inner sep=0pt] at (0,-6.2) + {\includegraphics[width=\linewidth,trim=0 0cm 0 1cm]{sumprod_04.pdf}}; + \node[inner sep=0pt] at (0,-9.2) + {\includegraphics[width=\linewidth,trim=0 1cm 0 1cm]{sumprod_05.pdf}}; +\end{tikzpicture} +\end{document} diff --git a/docs/images/011/splitnets_libfile.tex b/docs/images/011/splitnets_libfile.tex new file mode 100644 index 00000000000..9669ef841b0 --- /dev/null +++ b/docs/images/011/splitnets_libfile.tex @@ -0,0 +1,15 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture} + \node[inner sep=0pt] at (0,0) + {\includegraphics[height=\linewidth]{cmos_00.pdf}}; + \node[inner sep=0pt] at (2,-8) + {\includegraphics[width=\linewidth]{cmos_01.pdf}}; +\end{tikzpicture} +\end{document} diff --git a/docs/images/011/submod_dots.tex b/docs/images/011/submod_dots.tex new file mode 100644 index 00000000000..3d48b46e5a5 --- /dev/null +++ b/docs/images/011/submod_dots.tex @@ -0,0 +1,27 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture} + \node[inner sep=0pt] at (0,0) + {\includegraphics[width=\linewidth,trim=0 1.3cm 0 0cm]{submod_00.pdf}}; + \node at (0, -2.5) + {\tt memdemo}; + \node[inner sep=0pt] at (0,-5) + {\includegraphics[width=\linewidth,trim=0 1.3cm 0 0cm]{submod_01.pdf}}; + \node at (0, -7.5) + {\tt scramble}; + \node[inner sep=0pt] at (0, -11) + {\includegraphics[width=\linewidth,trim=0 1.3cm 0 0cm]{submod_02.pdf}}; + \node at (0, -14.8) + {\tt outstage}; + \node[inner sep=0pt] at (0,-16.6) + {\includegraphics[width=\linewidth,trim=0 1.3cm 0 0cm]{submod_03.pdf}}; + \node at (0, -19) + {\tt selstage}; +\end{tikzpicture} +\end{document} diff --git a/docs/images/Makefile b/docs/images/Makefile new file mode 100644 index 00000000000..a7216ec9010 --- /dev/null +++ b/docs/images/Makefile @@ -0,0 +1,44 @@ +all: dots tex svg tidy + +TEX_SOURCE:= $(wildcard *.tex) +DOT_LOC:= ../source/APPNOTE_011_Design_Investigation +DOT_SOURCE:= $(wildcard $(DOT_LOC)/*.dot) + +TEX_SOURCE+= 011/example_out.tex +011/example_out.pdf: 011/example_00.pdf 011/example_01.pdf 011/example_02.pdf +TEX_SOURCE+= 011/select_prod.tex +011/select_prod.pdf: 011/sumprod_02.pdf 011/sumprod_03.pdf 011/sumprod_04.pdf 011/sumprod_05.pdf +TEX_SOURCE+= 011/splitnets_libfile.tex +011/splitnets_libfile.pdf: 011/cmos_00.pdf 011/cmos_01.pdf +TEX_SOURCE+= 011/submod_dots.tex +011/submod_dots.pdf: 011/submod_00.pdf 011/submod_01.pdf 011/submod_02.pdf 011/submod_03.pdf + +TEX_PDF:= $(patsubst %.tex,%.pdf,$(TEX_SOURCE)) +DOT_PDF:= $(addprefix 011/,$(notdir $(patsubst %.dot,%.pdf,$(DOT_SOURCE)))) +SVG_OUTPUT:= $(patsubst %.pdf,%.svg,$(TEX_PDF) $(DOT_PDF)) + +dots: $(DOT_PDF) +tex: $(TEX_PDF) +svg: $(SVG_OUTPUT) + +011/%.pdf: $(DOT_LOC)/%.dot + faketime -f '2022-01-01 00:00:00 x0,001' dot -Tpdf -o $@ $< + +011/%.pdf: 011/%.tex + cd 011 && faketime -f '2022-01-01 00:00:00 x0,001' pdflatex $()ey%I^36pzH3PMC=W3x;CytlM_mtkc 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 JDs_j5{{iZXWUc@J literal 0 HcmV?d00001 diff --git a/docs/images/approach_flow.tex b/docs/images/approach_flow.tex new file mode 100644 index 00000000000..275baa3f5bf --- /dev/null +++ b/docs/images/approach_flow.tex @@ -0,0 +1,38 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\usepackage{amsmath} +\usepackage{pgfplots} +\usepackage{tikz} +\usetikzlibrary{calc} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture} + \path (-1.5,3) coordinate (cursor); + \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); + \draw[fill=orange!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Frontend} ++(1,3) coordinate (cursor); + \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); + \draw[fill=green!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Pass} ++(1,3) coordinate (cursor); + \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); + \draw[fill=green!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Pass} ++(1,3) coordinate (cursor); + \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); + \draw[fill=green!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Pass} ++(1,3) coordinate (cursor); + \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); + \draw[fill=orange!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Backend} ++(1,3) coordinate (cursor); + \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); + + \path (-3,-0.5) coordinate (cursor); + \draw (cursor) -- node[below] {HDL} ++(3,0) coordinate (cursor); + \draw[|-|] (cursor) -- node[below] {Internal Format(s)} ++(8,0) coordinate (cursor); + \draw (cursor) -- node[below] {Netlist} ++(3,0); + + \path (-3,3.5) coordinate (cursor); + \draw[-] (cursor) -- node[above] {High-Level} ++(3,0) coordinate (cursor); + \draw[-] (cursor) -- ++(8,0) coordinate (cursor); + \draw[->] (cursor) -- node[above] {Low-Level} ++(3,0); + +\end{tikzpicture} +\end{document} diff --git a/docs/images/basics_abstractions.png b/docs/images/basics_abstractions.png new file mode 100644 index 0000000000000000000000000000000000000000..a735fbd3b5e03065def0ea9aa54ab543ee8f2691 GIT binary patch literal 29158 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

HU{k&m%w6VoHjJQ;kJm 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 W6;nPo4tsy&J6TC3i7GLppZ^P;t#1(k literal 0 HcmV?d00001 diff --git a/docs/images/basics_abstractions.tex b/docs/images/basics_abstractions.tex new file mode 100644 index 00000000000..ece06362348 --- /dev/null +++ b/docs/images/basics_abstractions.tex @@ -0,0 +1,41 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\usepackage{amsmath} +\usepackage{pgfplots} +\usepackage{tikz} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture} + \tikzstyle{lvl} = [draw, fill=green!10, rectangle, minimum height=2em, minimum width=15em] + \node[lvl] (sys) {System Level}; + \node[lvl] (hl) [below of=sys] {High Level}; + \node[lvl] (beh) [below of=hl] {Behavioral Level}; + \node[lvl] (rtl) [below of=beh] {Register-Transfer Level (RTL)}; + \node[lvl] (lg) [below of=rtl] {Logical Gate Level}; + \node[lvl] (pg) [below of=lg] {Physical Gate Level}; + \node[lvl] (sw) [below of=pg] {Switch Level}; + + \draw[dotted] (sys.east) -- ++(1,0) coordinate (sysx); + \draw[dotted] (hl.east) -- ++(1,0) coordinate (hlx); + \draw[dotted] (beh.east) -- ++(1,0) coordinate (behx); + \draw[dotted] (rtl.east) -- ++(1,0) coordinate (rtlx); + \draw[dotted] (lg.east) -- ++(1,0) coordinate (lgx); + \draw[dotted] (pg.east) -- ++(1,0) coordinate (pgx); + \draw[dotted] (sw.east) -- ++(1,0) coordinate (swx); + + \draw[gray,|->] (sysx) -- node[right] {System Design} (hlx); + \draw[|->|] (hlx) -- node[right] {High Level Synthesis (HLS)} (behx); + \draw[->|] (behx) -- node[right] {Behavioral Synthesis} (rtlx); + \draw[->|] (rtlx) -- node[right] {RTL Synthesis} (lgx); + \draw[->|] (lgx) -- node[right] {Logic Synthesis} (pgx); + \draw[gray,->|] (pgx) -- node[right] {Cell Library} (swx); + + \draw[dotted] (behx) -- ++(5,0) coordinate (a); + \draw[dotted] (pgx) -- ++(5,0) coordinate (b); + \draw[|->|] (a) -- node[right] {Yosys} (b); +\end{tikzpicture} +\end{document} diff --git a/docs/images/basics_ast.png b/docs/images/basics_ast.png new file mode 100644 index 0000000000000000000000000000000000000000..c2d95c844a93b0284ca934d1716d44d1d42f7cba GIT binary patch literal 9478 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 literal 0 HcmV?d00001 diff --git a/docs/images/basics_ast.tex b/docs/images/basics_ast.tex new file mode 100644 index 00000000000..dac6a8d47d8 --- /dev/null +++ b/docs/images/basics_ast.tex @@ -0,0 +1,30 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\usepackage{amsmath} +\usepackage{pgfplots} +\usepackage{tikz} +\usetikzlibrary{shapes.geometric} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture} + \tikzstyle{node} = [draw, fill=green!10, ellipse, minimum height=2em, minimum width=8em, node distance=10em] + + \draw (+0,+0) node[node] (n1) {\tt ASSIGN}; + + \draw (-2,-2) node[node] (n11) {\tt ID: foo}; + \draw (+2,-2) node[node] (n12) {\tt PLUS}; + + \draw (+0,-4) node[node] (n121) {\tt ID: bar}; + \draw (+4,-4) node[node] (n122) {\tt CONST: 42}; + + \draw[-latex] (n1) -- (n11); + \draw[-latex] (n1) -- (n12); + + \draw[-latex] (n12) -- (n121); + \draw[-latex] (n12) -- (n122); +\end{tikzpicture} +\end{document} diff --git a/docs/images/basics_flow.png b/docs/images/basics_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..a027b5eac3e37db661962a9827dd67212bbcb665 GIT binary patch literal 12540 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 literal 0 HcmV?d00001 diff --git a/docs/images/basics_flow.tex b/docs/images/basics_flow.tex new file mode 100644 index 00000000000..53b55548768 --- /dev/null +++ b/docs/images/basics_flow.tex @@ -0,0 +1,44 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\usepackage{amsmath} +\usepackage{pgfplots} +\usepackage{tikz} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture} + \tikzstyle{manual} = [draw, fill=green!10, rectangle, minimum height=2em, minimum width=8em, node distance=10em] + \tikzstyle{auto} = [draw, fill=orange!10, rectangle, minimum height=2em, minimum width=8em, node distance=10em] + + \node[manual] (sys) {\begin{minipage}{8em} + \center + System Level \\ + Model + \end{minipage}}; + \node[manual] (beh) [right of=sys] {\begin{minipage}{8em} + \center + Behavioral \\ + Model + \end{minipage}}; + \node[auto] (rtl) [right of=beh] {\begin{minipage}{8em} + \center + RTL \\ + Model + \end{minipage}}; + \node[auto] (gates) [right of=rtl] {\begin{minipage}{8em} + \center + Gate-Level \\ + Model + \end{minipage}}; + + \draw[-latex] (beh) edge[double, bend left] node[above] {synthesis} (rtl); + \draw[-latex] (rtl) edge[double, bend left] node[above] {synthesis} (gates); + + \draw[latex-latex] (sys) edge[bend right] node[below] {verify} (beh); + \draw[latex-latex] (beh) edge[bend right] node[below] {verify} (rtl); + \draw[latex-latex] (rtl) edge[bend right] node[below] {verify} (gates); +\end{tikzpicture} +\end{document} diff --git a/docs/images/basics_parsetree.png b/docs/images/basics_parsetree.png new file mode 100644 index 0000000000000000000000000000000000000000..ff7a17e2bd2f55c2a53bcc0567f44ca640fccca0 GIT binary patch literal 23196 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 literal 0 HcmV?d00001 diff --git a/docs/images/overview_flow.tex b/docs/images/overview_flow.tex new file mode 100644 index 00000000000..ac0afde5fda --- /dev/null +++ b/docs/images/overview_flow.tex @@ -0,0 +1,37 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\usepackage{amsmath} +\usepackage{pgfplots} +\usepackage{tikz} +\usetikzlibrary{shapes.geometric} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture} + \tikzstyle{process} = [draw, fill=green!10, rectangle, minimum height=3em, minimum width=10em, node distance=15em] + \tikzstyle{data} = [draw, fill=blue!10, ellipse, minimum height=3em, minimum width=7em, node distance=15em] + \node[process] (vlog) {Verilog Frontend}; + \node[process, dashed, fill=green!5] (vhdl) [right of=vlog] {VHDL Frontend}; + \node[process] (ilang) [right of=vhdl] {RTLIL Frontend}; + \node[data] (ast) [below of=vlog, node distance=5em, xshift=7.5em] {AST}; + \node[process] (astfe) [below of=ast, node distance=5em] {AST Frontend}; + \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL}; + \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes}; + \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend}; + \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend}; + \node[process, dashed, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends}; + + \draw[-latex] (vlog) -- (ast); + \draw[-latex] (vhdl) -- (ast); + \draw[-latex] (ast) -- (astfe); + \draw[-latex] (astfe) -- (rtlil); + \draw[-latex] (ilang) -- (rtlil); + \draw[latex-latex] (rtlil) -- (pass); + \draw[-latex] (rtlil) -- (vlbe); + \draw[-latex] (rtlil) -- (ilangbe); + \draw[-latex] (rtlil) -- (otherbe); +\end{tikzpicture} +\end{document} diff --git a/docs/images/overview_rtlil.png b/docs/images/overview_rtlil.png new file mode 100644 index 0000000000000000000000000000000000000000..f79c667e8b4c4c043bca4085c02dd6292dd3dc03 GIT binary patch literal 16034 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