diff --git a/.github/workflows/extra-builds.yml b/.github/workflows/extra-builds.yml index d7c6e13ff..1a00d0163 100644 --- a/.github/workflows/extra-builds.yml +++ b/.github/workflows/extra-builds.yml @@ -86,7 +86,11 @@ jobs: name: "Build nix flake" needs: pre_job if: needs.pre_job.outputs.should_skip != 'true' - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + fail-fast: false steps: - uses: actions/checkout@v4 with: @@ -94,4 +98,4 @@ jobs: - uses: cachix/install-nix-action@v26 with: install_url: https://releases.nixos.org/nix/nix-2.18.1/install - - run: nix build .?submodules=1 + - run: nix build .?submodules=1 -L diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index a892c91ce..089e65ca7 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -40,8 +40,8 @@ jobs: - os: macos-13 compiler: 'clang' # oldest clang not available on ubuntu-latest - - os: ubuntu-22.04 - compiler: 'clang-11' + - os: ubuntu-20.04 + compiler: 'clang-10' fail-fast: false steps: - name: Checkout Yosys diff --git a/.github/workflows/test-verific.yml b/.github/workflows/test-verific.yml index e08f7bd2e..627a70d47 100644 --- a/.github/workflows/test-verific.yml +++ b/.github/workflows/test-verific.yml @@ -3,7 +3,7 @@ name: Build and run tests with Verific (Linux) on: [push, pull_request] jobs: - pre_job: + pre-job: runs-on: ubuntu-latest outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} @@ -20,9 +20,9 @@ jobs: skip_after_successful_duplicate: 'false' test-verific: - needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' - runs-on: [self-hosted, linux, x64] + needs: pre-job + if: needs.pre-job.outputs.should_skip != 'true' + runs-on: [self-hosted, linux, x64, fast] steps: - name: Checkout Yosys uses: actions/checkout@v4 @@ -47,30 +47,6 @@ jobs: run: | make install DESTDIR=${GITHUB_WORKSPACE}/.local PREFIX= - - name: Checkout Documentation - if: ${{ github.ref == 'refs/heads/main' }} - uses: actions/checkout@v4 - with: - path: 'yosys-cmd-ref' - repository: 'YosysHQ-Docs/yosys-cmd-ref' - fetch-depth: 0 - token: ${{ secrets.CI_DOCS_UPDATE_PAT }} - persist-credentials: true - - - name: Update documentation - if: ${{ github.ref == 'refs/heads/main' }} - run: | - make docs - rm -rf docs/build - cd yosys-cmd-ref - rm -rf * - git checkout README.md - cp -R ../docs/* . - rm -rf util/__pycache__ - git add -A . - git diff-index --quiet HEAD || git commit -m "Update" - git push - - name: Checkout SBY uses: actions/checkout@v4 with: @@ -94,3 +70,51 @@ jobs: if: ${{ github.ref == 'refs/heads/main' }} run: | make -C sby run_ci + + prepare-docs: + name: Generate docs artifact + needs: [pre-job, test-verific] + if: needs.pre-job.outputs.should_skip != 'true' + runs-on: [self-hosted, linux, x64, fast] + steps: + - name: Checkout Yosys + uses: actions/checkout@v4 + with: + persist-credentials: false + submodules: true + - name: Runtime environment + run: | + echo "procs=$(nproc)" >> $GITHUB_ENV + + - name: Build Yosys + run: | + make config-clang + echo "ENABLE_VERIFIC := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_EDIF := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf + echo "ENABLE_CCACHE := 1" >> Makefile.conf + make -j${{ env.procs }} ENABLE_LTO=1 + + - name: Prepare docs + shell: bash + run: + make docs/source/cmd/abc.rst docs/gen_examples docs/gen_images docs/guidelines docs/usage docs/reqs TARGETS= EXTRA_TARGETS= + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: cmd-ref-${{ github.sha }} + path: | + docs/source/cmd + docs/source/generated + docs/source/_images + docs/source/code_examples + + - name: Trigger RTDs build + if: ${{ github.ref == 'refs/heads/main' }} + uses: dfm/rtds-action@v1.1.0 + with: + webhook_url: ${{ secrets.RTDS_WEBHOOK_URL }} + webhook_token: ${{ secrets.RTDS_WEBHOOK_TOKEN }} + commit_ref: ${{ github.ref }} diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..cb700dc1c --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,19 @@ +# .readthedocs.yaml +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: '3.12' + +formats: + - pdf + +sphinx: + configuration: docs/source/conf.py + +python: + install: + - requirements: docs/source/requirements.txt diff --git a/Makefile b/Makefile index d9386eb45..0c7761827 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.44+9 +YOSYS_VER := 0.44+20 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -814,7 +814,7 @@ check-git-abc: exit 1; \ fi -abc/abc$(EXE) abc/libabc.a: check-git-abc +abc/abc$(EXE) abc/libabc.a: | check-git-abc $(P) $(Q) mkdir -p abc && $(MAKE) -C $(PROGRAM_PREFIX)abc -f "$(realpath $(YOSYS_SRC)/abc/Makefile)" ABCSRC="$(realpath $(YOSYS_SRC)/abc/)" $(S) $(ABCMKARGS) $(if $(filter %.a,$@),PROG="abc",PROG="abc$(EXE)") MSG_PREFIX="$(eval P_OFFSET = 5)$(call P_SHOW)$(eval P_OFFSET = 10) ABC: " $(if $(filter %.a,$@),libabc.a) @@ -991,8 +991,8 @@ docs/guidelines docs/source/generated: # some commands return an error and print the usage text to stderr define DOC_USAGE_STDERR -docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated - -$(Q) ./$$< --help 2> $$@ +docs/source/generated/$(1): $(TARGETS) docs/source/generated + -$(Q) ./$(PROGRAM_PREFIX)$(1) --help 2> $$@ endef DOCS_USAGE_STDERR := yosys-config yosys-filterlib @@ -1005,8 +1005,8 @@ $(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage)))) # others print to stdout define DOC_USAGE_STDOUT -docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated - $(Q) ./$$< --help > $$@ +docs/source/generated/$(1): $(TARGETS) docs/source/generated + $(Q) ./$(PROGRAM_PREFIX)$(1) --help > $$@ endef DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness $(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage)))) diff --git a/docs/source/code_examples/synth_flow/Makefile b/docs/source/code_examples/synth_flow/Makefile index cc5a34b26..7db1c12f4 100644 --- a/docs/source/code_examples/synth_flow/Makefile +++ b/docs/source/code_examples/synth_flow/Makefile @@ -1,13 +1,13 @@ -TARGETS += proc_01 proc_02 proc_03 -TARGETS += memory_01 memory_02 -TARGETS += techmap_01 +DOT_TARGETS += proc_01 proc_02 proc_03 +DOT_TARGETS += memory_01 memory_02 +DOT_TARGETS += techmap_01 PROGRAM_PREFIX := YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -DOTS = $(addsuffix .dot,$(TARGETS)) +DOTS = $(addsuffix .dot,$(DOT_TARGETS)) .PHONY: all dots all: dots diff --git a/docs/source/conf.py b/docs/source/conf.py index 2fdd43a31..23efe2b43 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -41,7 +41,13 @@ html_static_path = ['_static', "_images"] pygments_style = 'colorful' highlight_language = 'none' -extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.bibtex'] +extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.bibtex', 'rtds_action'] + +# rtds_action +rtds_action_github_repo = "YosysHQ/yosys" +rtds_action_path = "." +rtds_action_artifact_prefix = "cmd-ref-" +rtds_action_github_token = os.environ["GITHUB_TOKEN"] # Ensure that autosectionlabel will produce unique names autosectionlabel_prefix_document = True diff --git a/docs/source/requirements.txt b/docs/source/requirements.txt index 74c8dd090..dbba55832 100644 --- a/docs/source/requirements.txt +++ b/docs/source/requirements.txt @@ -1,2 +1,3 @@ furo sphinxcontrib-bibtex +rtds-action diff --git a/passes/pmgen/peepopt_shiftadd.pmg b/passes/pmgen/peepopt_shiftadd.pmg index 62f54efe5..ecd43355f 100644 --- a/passes/pmgen/peepopt_shiftadd.pmg +++ b/passes/pmgen/peepopt_shiftadd.pmg @@ -63,10 +63,12 @@ match add define constport_signed param(add, !varport_A ? \A_SIGNED : \B_SIGNED).as_bool() define varport_signed param(add, varport_A ? \A_SIGNED : \B_SIGNED).as_bool(); - define offset_negative ((port(add, constport).bits().back() == State::S1) ^ (is_sub && varport_A)) + define const_negative (constport_signed && (port(add, constport).bits().back() == State::S1)) + define offset_negative ((is_sub && varport_A) ^ const_negative) // checking some value boundaries as well: - // data[...-c +:W1] is fine for +/-var (pad at LSB, all data still accessible) + // data[...-c +:W1] is fine for any signed var (pad at LSB, all data still accessible) + // unsigned shift may underflow (eg var-3 with var<3) -> cannot be converted // data[...+c +:W1] is only fine for +var(add) and var unsigned // (+c cuts lower C bits, making them inaccessible, a signed var could try to access them) // either its an add or the variable port is A (it must be positive) @@ -74,6 +76,8 @@ match add // -> data[var+c +:W1] (with var signed) is illegal filter !(!offset_negative && varport_signed) + // -> data >> (var-c) (with var unsigned) is illegal + filter !(offset_negative && !varport_signed) // state-variables are assigned at the end only: // shift the log2scale offset in-front of add to get true value: (var+c)< (var<>' operator. +//- module \$shr (A, B, Y); parameter A_SIGNED = 0; @@ -419,6 +431,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $sshl (A, B, Y) +//- +//- An arithmatic shift-left operation. +//- This corresponds to the Verilog '<<<' operator. +//- module \$sshl (A, B, Y); parameter A_SIGNED = 0; @@ -443,6 +462,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $sshr (A, B, Y) +//- +//- An arithmatic shift-right operation. +//- This corresponds to the Verilog '>>>' operator. +//- module \$sshr (A, B, Y); parameter A_SIGNED = 0; @@ -639,6 +665,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $lt (A, B, Y) +//- +//- A less-than comparison between inputs 'A' and 'B'. +//- This corresponds to the Verilog '<' operator. +//- module \$lt (A, B, Y); parameter A_SIGNED = 0; @@ -663,6 +696,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $le (A, B, Y) +//- +//- A less-than-or-equal-to comparison between inputs 'A' and 'B'. +//- This corresponds to the Verilog '<=' operator. +//- module \$le (A, B, Y); parameter A_SIGNED = 0; @@ -687,6 +727,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $eq (A, B, Y) +//- +//- An equality comparison between inputs 'A' and 'B'. +//- This corresponds to the Verilog '==' operator. +//- module \$eq (A, B, Y); parameter A_SIGNED = 0; @@ -711,6 +758,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $ne (A, B, Y) +//- +//- An inequality comparison between inputs 'A' and 'B'. +//- This corresponds to the Verilog '!=' operator. +//- module \$ne (A, B, Y); parameter A_SIGNED = 0; @@ -735,6 +789,15 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $eqx (A, B, Y) +//- +//- An exact equality comparison between inputs 'A' and 'B'. +//- This corresponds to the Verilog '===' operator. +//- Unlike equality comparison that can give 'x' as output, +//- an exact equality comparison will strictly give '0' or '1' as output. +//- module \$eqx (A, B, Y); parameter A_SIGNED = 0; @@ -759,6 +822,15 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $nex (A, B, Y) +//- +//- An exact inequality comparison between inputs 'A' and 'B'. +//- This corresponds to the Verilog '!==' operator. +//- Unlike inequality comparison that can give 'x' as output, +//- an exact inequality comparison will strictly give '0' or '1' as output. +//- module \$nex (A, B, Y); parameter A_SIGNED = 0; @@ -783,6 +855,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $ge (A, B, Y) +//- +//- A greater-than-or-equal-to comparison between inputs 'A' and 'B'. +//- This corresponds to the Verilog '>=' operator. +//- module \$ge (A, B, Y); parameter A_SIGNED = 0; @@ -807,6 +886,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $gt (A, B, Y) +//- +//- A greater-than comparison between inputs 'A' and 'B'. +//- This corresponds to the Verilog '>' operator. +//- module \$gt (A, B, Y); parameter A_SIGNED = 0; @@ -831,6 +917,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $add (A, B, Y) +//- +//- Addition of inputs 'A' and 'B'. This corresponds to the Verilog '+' operator. +//- module \$add (A, B, Y); parameter A_SIGNED = 0; @@ -855,6 +947,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $sub (A, B, Y) +//- +//- Subtraction between inputs 'A' and 'B'. +//- This corresponds to the Verilog '-' operator. +//- module \$sub (A, B, Y); parameter A_SIGNED = 0; @@ -879,6 +978,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $mul (A, B, Y) +//- +//- Multiplication of inputs 'A' and 'B'. +//- This corresponds to the Verilog '*' operator. +//- module \$mul (A, B, Y); parameter A_SIGNED = 0; @@ -1191,6 +1297,14 @@ endgenerate endmodule // -------------------------------------------------------- + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $pow (A, B, Y) +//- +//- Exponentiation of an input (Y = A ** B). +//- This corresponds to the Verilog '**' operator. +//- `ifndef SIMLIB_NOPOW module \$pow (A, B, Y); @@ -1222,6 +1336,12 @@ endmodule `endif // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $logic_not (A, Y) +//- +//- A logical inverter. This corresponds to the Verilog unary prefix '!' operator. +//- module \$logic_not (A, Y); parameter A_SIGNED = 0; @@ -1243,6 +1363,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $logic_and (A, B, Y) +//- +//- A logical AND. This corresponds to the Verilog '&&' operator. +//- module \$logic_and (A, B, Y); parameter A_SIGNED = 0; @@ -1267,6 +1393,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $logic_or (A, B, Y) +//- +//- A logical OR. This corresponds to the Verilog '||' operator. +//- module \$logic_or (A, B, Y); parameter A_SIGNED = 0; @@ -1306,6 +1438,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $concat (A, B, Y) +//- +//- Concatenation of inputs into a single output ( Y = {B, A} ). +//- module \$concat (A, B, Y); parameter A_WIDTH = 0; @@ -1321,6 +1459,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $mux (A, B, S, Y) +//- +//- Multiplexer i.e selecting between two inputs based on select signal. +//- module \$mux (A, B, S, Y); parameter WIDTH = 0; @@ -1396,6 +1540,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $demux (A, S, Y) +//- +//- Demultiplexer i.e routing single input to several outputs based on select signal. +//- Unselected outputs are driven to zero. +//- module \$demux (A, S, Y); parameter WIDTH = 1; @@ -1460,6 +1611,14 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $tribuf (A, EN, Y) +//- +//- A tri-state buffer. +//- This buffer conditionally drives the output with the value of the input +//- based on the enable signal. +//- module \$tribuf (A, EN, Y); parameter WIDTH = 0; diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 3edf6c8fc..96121a881 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -618,6 +618,21 @@ module OSER4(D3, D2, D1, D0, TX1, TX0, FCLK, PCLK, RESET, Q1, Q0); parameter HWL = "false"; endmodule +module OSER4_MEM (Q0, Q1, D0, D1, D2, D3, TX0, TX1, PCLK, FCLK, TCLK, RESET) ; + parameter GSREN = ""; + parameter LSREN = ""; + parameter HWL = ""; + parameter TCLK_SOURCE = ""; + parameter TXCLK_POL = ""; + + input D0, D1, D2, D3; + input TX0, TX1; + input PCLK, FCLK, TCLK, RESET; + output Q0, Q1; + + parameter ID = ""; +endmodule + module OSER8(D7, D6, D5, D4, D3, D2, D1, D0, TX3, TX2, TX1, TX0, FCLK, PCLK, RESET, Q1, Q0); output Q1; output Q0; @@ -729,6 +744,21 @@ RESET, CALIB, D); parameter LSREN = "true"; endmodule +module IDES4_MEM (Q0, Q1, Q2, Q3, D, WADDR, +RADDR, CALIB, PCLK, FCLK, ICLK, RESET) ; +parameter GSREN = ""; +parameter LSREN = ""; + +input D, ICLK, FCLK, PCLK; +input [2:0] WADDR; +input [2:0] RADDR; +input CALIB, RESET; + +output Q0,Q1,Q2,Q3; + +parameter ID = ""; +endmodule + module IDES8(Q7, Q6, Q5, Q4, Q3, Q2, Q1, Q0, FCLK, PCLK, RESET, CALIB, D); input D; @@ -842,6 +872,28 @@ module IDDRC(D, CLK, CLEAR, Q0, Q1); parameter Q1_INIT = 1'b0; endmodule +module DQS(DQSR90, DQSW0, DQSW270, RPOINT, WPOINT, RVALID, RBURST, RFLAG, +WFLAG, DQSIN, DLLSTEP, WSTEP, READ, RLOADN, RMOVE, RDIR, WLOADN, WMOVE, WDIR, +HOLD, RCLKSEL, PCLK, FCLK, RESET) ; + input DQSIN,PCLK,FCLK,RESET; + input [3:0] READ; + input [2:0] RCLKSEL; + input [7:0] DLLSTEP; + input [7:0] WSTEP; + input RLOADN, RMOVE, RDIR, WLOADN, WMOVE, WDIR, HOLD; + + output DQSR90, DQSW0, DQSW270; + output [2:0] RPOINT, WPOINT; + output RVALID,RBURST, RFLAG, WFLAG; + + parameter FIFO_MODE_SEL = ""; + parameter RD_PNTR = ""; + parameter DQS_MODE = ""; + parameter HWL = ""; + parameter GSREN = ""; + parameter ID = ""; +endmodule + (* blackbox *) module ODDR(D0, D1, TX, CLK, Q0, Q1); input D0; diff --git a/tests/opt/bug4413.ys b/tests/opt/bug4413.ys new file mode 100644 index 000000000..6c4158882 --- /dev/null +++ b/tests/opt/bug4413.ys @@ -0,0 +1,15 @@ +read_verilog <> shift2; +endmodule + +EOT + +equiv_opt -assert peepopt