├── bscRuntime ├── .gitignore ├── memories │ └── Makefile ├── libs │ ├── Makefile │ ├── PrioFifo.bsv │ └── NamedEhr.bsv └── verilog │ └── Makefile ├── src ├── main │ ├── resources │ │ └── badReUse.txt │ └── scala │ │ └── pipedsl │ │ ├── typechecker │ │ ├── .DS_Store │ │ ├── AnalysisProvider.scala │ │ ├── CheckpointChecker.scala │ │ └── TypeChecker.scala │ │ ├── passes │ │ ├── Passes.scala │ │ ├── BindModuleTypes.scala │ │ └── LockEliminationPass.scala │ │ ├── common │ │ ├── Security.scala │ │ ├── ProgInfo.scala │ │ └── MemoryInputParser.scala │ │ └── codegen │ │ └── Translations.scala ├── test │ ├── tests │ │ ├── risc-pipe │ │ │ ├── memInputs │ │ │ │ ├── mm1 │ │ │ │ ├── mm3 │ │ │ │ ├── mm4 │ │ │ │ ├── td1 │ │ │ │ ├── td3 │ │ │ │ ├── td4 │ │ │ │ ├── ti4 │ │ │ │ ├── rf │ │ │ │ ├── mm2 │ │ │ │ ├── mm5 │ │ │ │ ├── ti2 │ │ │ │ ├── ti5 │ │ │ │ ├── td2 │ │ │ │ ├── ti1 │ │ │ │ ├── td5 │ │ │ │ └── ti3 │ │ │ └── solutions │ │ │ │ ├── risc-pipe.typechecksol │ │ │ │ ├── risc-pipe-3stg.typechecksol │ │ │ │ ├── risc-pipe-spec.typechecksol │ │ │ │ ├── risc-pipe-cache.typechecksol │ │ │ │ ├── risc-pipe-spec-write-2.typechecksol │ │ │ │ ├── risc-pipe-spec-write.typechecksol │ │ │ │ ├── risc-pipe-spec-bypass-bht.typechecksol │ │ │ │ ├── risc-pipe-spec-rename-bht.typechecksol │ │ │ │ ├── risc-pipe-spec-rename-ooo.typechecksol │ │ │ │ ├── risc-pipe-spec-write-infer.typechecksol │ │ │ │ ├── risc-pipe-spec-rename-ooo-infer.typechecksol │ │ │ │ └── 4.simsol │ │ ├── histogram │ │ │ ├── histogram_nested.sim │ │ │ ├── solutions │ │ │ │ ├── histogram.typechecksol │ │ │ │ ├── histogram_bram.typechecksol │ │ │ │ ├── histogram_bram2.typechecksol │ │ │ │ ├── histogram_nested.typechecksol │ │ │ │ ├── histogram_short.typechecksol │ │ │ │ ├── histogram_short.parsesol │ │ │ │ ├── histogram.parsesol │ │ │ │ └── histogram_bram.parsesol │ │ │ ├── histogram_short.pdl │ │ │ ├── histogram_bram.pdl │ │ │ ├── histogram_bram2.pdl │ │ │ ├── histogram.pdl │ │ │ └── histogram_nested.pdl │ │ ├── matpow │ │ │ ├── solutions │ │ │ │ ├── matpow.typechecksol │ │ │ │ ├── matpow_alt.typechecksol │ │ │ │ ├── matpow_bram.typechecksol │ │ │ │ ├── matpow_alt.parsesol │ │ │ │ └── matpow.parsesol │ │ │ ├── memInputs │ │ │ │ ├── a_2 │ │ │ │ ├── c │ │ │ │ └── r │ │ │ ├── matpow_alt.pdl │ │ │ ├── matpow.pdl │ │ │ └── matpow_bram.pdl │ │ ├── multiExec │ │ │ ├── solutions │ │ │ │ ├── multiexec.typechecksol │ │ │ │ ├── multiexec_alt.typechecksol │ │ │ │ ├── multiexec_split.typechecksol │ │ │ │ ├── multiexec.simsol │ │ │ │ ├── multiexec_alt.simsol │ │ │ │ └── multiexec_split.simsol │ │ │ └── memInputs │ │ │ │ └── r │ │ ├── branchesCheck │ │ │ ├── solutions │ │ │ │ ├── branch-1.typechecksol │ │ │ │ ├── branch-2.typechecksol │ │ │ │ ├── branch-3.typechecksol │ │ │ │ ├── nested-1.typechecksol │ │ │ │ ├── nested-2.typechecksol │ │ │ │ ├── split-1.typechecksol │ │ │ │ ├── split-2.typechecksol │ │ │ │ ├── split-3.typechecksol │ │ │ │ ├── split-4.typechecksol │ │ │ │ ├── branch-3.simsol │ │ │ │ ├── nested-branches-1.typechecksol │ │ │ │ ├── nested-branches-1.simsol │ │ │ │ ├── branch-2.parsesol │ │ │ │ ├── nested-2.parsesol │ │ │ │ ├── branch-3.parsesol │ │ │ │ ├── branch-1.parsesol │ │ │ │ ├── split-1.parsesol │ │ │ │ ├── nested-1.parsesol │ │ │ │ ├── split-2.parsesol │ │ │ │ ├── split-3.parsesol │ │ │ │ └── split-4.parsesol │ │ │ ├── branch-2.pdl │ │ │ ├── nested-2.pdl │ │ │ ├── branch-1.pdl │ │ │ ├── memInputs │ │ │ │ ├── r_branch-3 │ │ │ │ └── r_nested-branches-1 │ │ │ ├── branch-3.pdl │ │ │ ├── nested-1.pdl │ │ │ ├── split-1.pdl │ │ │ ├── split-2.pdl │ │ │ ├── split-3.pdl │ │ │ └── split-4.pdl │ │ ├── lockTests │ │ │ ├── solutions │ │ │ │ ├── lock-infer-1.typechecksol │ │ │ │ ├── lock-infer-2.typechecksol │ │ │ │ ├── lock-infer-3.typechecksol │ │ │ │ ├── lock-infer-4.typechecksol │ │ │ │ ├── lock-merge-1.typechecksol │ │ │ │ ├── lock-merge-2.typechecksol │ │ │ │ ├── lock-merge-3.typechecksol │ │ │ │ ├── lock-merge-4.typechecksol │ │ │ │ ├── lock-merge-2.parsesol │ │ │ │ ├── lock-merge-1.parsesol │ │ │ │ ├── lock-merge-4.parsesol │ │ │ │ └── lock-merge-3.parsesol │ │ │ ├── lock-infer-2.pdl │ │ │ ├── lock-infer-1.pdl │ │ │ ├── lock-merge-2.pdl │ │ │ ├── lock-merge-1.pdl │ │ │ ├── lock-infer-3.pdl │ │ │ ├── lock-merge-3.pdl │ │ │ ├── lock-infer-4.pdl │ │ │ └── lock-merge-4.pdl │ │ ├── simtests │ │ │ ├── solutions │ │ │ │ ├── unlocked-reg.typechecksol │ │ │ │ └── unlocked-reg.simsol │ │ │ └── unlocked-reg.pdl │ │ ├── speculation │ │ │ ├── solutions │ │ │ │ ├── 3-stg-pipe.typechecksol │ │ │ │ ├── bad-spec-1.typechecksol │ │ │ │ ├── bad-spec-2.typechecksol │ │ │ │ ├── bad-spec-3.typechecksol │ │ │ │ ├── bad-spec-4.typechecksol │ │ │ │ ├── bad-spec-5.typechecksol │ │ │ │ ├── spec-write-2.typechecksol │ │ │ │ ├── spec-write.typechecksol │ │ │ │ ├── 3-stg-pipe-spec-2.typechecksol │ │ │ │ ├── 3-stg-pipe-spec-3.typechecksol │ │ │ │ ├── 3-stg-pipe-spec.typechecksol │ │ │ │ ├── spec-write-fail.typechecksol │ │ │ │ ├── spec-write-fail2.typechecksol │ │ │ │ ├── spec-write-fail3.typechecksol │ │ │ │ ├── spec-write-infer.typechecksol │ │ │ │ ├── unnecessary-checkpoint.typechecksol │ │ │ │ ├── 3-stg-pipe.simsol │ │ │ │ ├── spec-write-2.simsol │ │ │ │ ├── 3-stg-pipe-spec-2.simsol │ │ │ │ ├── 3-stg-pipe-spec-3.simsol │ │ │ │ └── 3-stg-pipe-spec.simsol │ │ │ ├── memInputs │ │ │ │ ├── rename │ │ │ │ └── ti │ │ │ ├── spec-write.pdl │ │ │ ├── spec-write-infer.pdl │ │ │ ├── spec-write-fail.pdl │ │ │ ├── spec-write-fail2.pdl │ │ │ ├── spec-write-fail3.pdl │ │ │ ├── 3-stg-pipe.pdl │ │ │ ├── unnecessary-checkpoint.pdl │ │ │ ├── 3-stg-pipe-spec-3.pdl │ │ │ ├── 3-stg-pipe-spec-2.pdl │ │ │ ├── 3-stg-pipe-spec.pdl │ │ │ ├── spec-write-2.pdl │ │ │ ├── bad-spec-3.pdl │ │ │ ├── bad-spec-4.pdl │ │ │ ├── bad-spec-5.pdl │ │ │ └── bad-spec-2.pdl │ │ ├── typecheckTests │ │ │ ├── solutions │ │ │ │ ├── pipe-lock.typechecksol │ │ │ │ ├── boolean-mishap.typechecksol │ │ │ │ ├── extern_pass.typechecksol │ │ │ │ ├── input-smt-fail.typechecksol │ │ │ │ ├── signedInts.typechecksol │ │ │ │ ├── unlocked-mem-1.typechecksol │ │ │ │ ├── unlocked-mem.typechecksol │ │ │ │ ├── unlocked-reg.typechecksol │ │ │ │ ├── acquire-in-expr.typechecksol │ │ │ │ ├── double-call-fail.typechecksol │ │ │ │ ├── double-call-guarded.typechecksol │ │ │ │ ├── extern-synch-fail.typechecksol │ │ │ │ ├── generic-bht.typechecksol │ │ │ │ ├── generic_adder.typechecksol │ │ │ │ ├── lock-tests-general.typechecksol │ │ │ │ ├── lock-tests-specific.typechecksol │ │ │ │ ├── missing-one-fail.typechecksol │ │ │ │ ├── nested_generic.typechecksol │ │ │ │ ├── pipe-lock-fail1.typechecksol │ │ │ │ ├── pipe-lock-fail2.typechecksol │ │ │ │ ├── quad-call-disjoint.typechecksol │ │ │ │ ├── superscalar-fail.typechecksol │ │ │ │ ├── unlocked-mem-fail-1.typechecksol │ │ │ │ ├── unlocked-mem-fail.typechecksol │ │ │ │ ├── acquire-in-expr-fail.typechecksol │ │ │ │ ├── generic-bht-fail.typechecksol │ │ │ │ ├── generic_func_fail.typechecksol │ │ │ │ ├── generic_funcs_pass.typechecksol │ │ │ │ ├── generic_unify_fail.typechecksol │ │ │ │ ├── lock-fail-branch-acquire.typechecksol │ │ │ │ ├── lock-fail-branch-release.typechecksol │ │ │ │ ├── lock-fail-double-write.typechecksol │ │ │ │ ├── lock-fail-top-branch.typechecksol │ │ │ │ ├── lock-release-OOO-fail.typechecksol │ │ │ │ ├── lock-wellformedness-fail.typechecksol │ │ │ │ ├── more_generic_tests.typechecksol │ │ │ │ ├── type-inference-fail-call.typechecksol │ │ │ │ ├── generic_adder_unsigned.typechecksol │ │ │ │ ├── generic_funcs_passz3.typechecksol │ │ │ │ ├── lock-acquire-in-split-case.typechecksol │ │ │ │ ├── lock-fail-reads-after-writes.typechecksol │ │ │ │ ├── lock-release-OOO-split-fail.typechecksol │ │ │ │ ├── lock-success-read-write-order.typechecksol │ │ │ │ ├── risc-pipe-spec-generic.typechecksol │ │ │ │ ├── type-inference-basic-pass.typechecksol │ │ │ │ ├── type-inference-fail-base-type.typechecksol │ │ │ │ ├── type-inference-fail-boolBinOp.typechecksol │ │ │ │ ├── type-inference-fail-call-args.typechecksol │ │ │ │ ├── type-inference-fail-eqBinOp.typechecksol │ │ │ │ ├── type-inference-fail-funcApp.typechecksol │ │ │ │ ├── type-inference-fail-numBinOp.typechecksol │ │ │ │ ├── type-inference-fail-ternary.typechecksol │ │ │ │ ├── lock-fail-acquire-before-access.typechecksol │ │ │ │ ├── lock-fail-no-acquire-in-split-case.typechecksol │ │ │ │ ├── lock-fail-no-default-acquire-split.typechecksol │ │ │ │ ├── lock-fail-read-after-writes-branch.typechecksol │ │ │ │ ├── lock-fail-reserve-without-write.typechecksol │ │ │ │ ├── lock-fail-wrong-branch-acquire.typechecksol │ │ │ │ ├── lock-release-OOO-nested-if-fail.typechecksol │ │ │ │ ├── type-inference-bit-width-tests.typechecksol │ │ │ │ ├── type-inference-fail-func-app-arg.typechecksol │ │ │ │ ├── lock-fail-no-acquire-before-release.typechecksol │ │ │ │ ├── lock-fail-read-after-writes-release.typechecksol │ │ │ │ ├── lock-release-OOO-different-address-fail.typechecksol │ │ │ │ ├── lock-release-OOO-nested-branches-fail.typechecksol │ │ │ │ ├── type-inference-fail-bit-too-small-minus.typechecksol │ │ │ │ ├── type-inference-fail-bit-too-small-mult.typechecksol │ │ │ │ ├── type-inference-fail-bit-too-small-plus.typechecksol │ │ │ │ └── type-inference-fail-bit-too-small-memAccessToosmall.typechecksol │ │ │ ├── type-inference-fail-bit-too-small-minus.pdl │ │ │ ├── type-inference-fail-bit-too-small-mult.pdl │ │ │ ├── type-inference-fail-bit-too-small-plus.pdl │ │ │ ├── type-inference-fail-eqBinOp.pdl │ │ │ ├── type-inference-fail-numBinOp.pdl │ │ │ ├── generic_adder_unsigned.pdl │ │ │ ├── type-inference-fail-boolBinOp.pdl │ │ │ ├── type-inference-fail-bit-too-small-memAccessToosmall.pdl │ │ │ ├── type-inference-fail-ternary.pdl │ │ │ ├── type-inference-fail-base-type.pdl │ │ │ ├── generic_func_fail.pdl │ │ │ ├── type-inference-fail-func-app-arg.pdl │ │ │ ├── type-inference-fail-funcApp.pdl │ │ │ ├── lock-fail-branch-acquire.pdl │ │ │ ├── input-smt-fail.pdl │ │ │ ├── unlocked-mem.pdl │ │ │ ├── unlocked-mem-fail-1.pdl │ │ │ ├── lock-fail-branch-release.pdl │ │ │ ├── lock-fail-no-acquire-before-release.pdl │ │ │ ├── nested_generic.pdl │ │ │ ├── acquire-in-expr-fail.pdl │ │ │ ├── acquire-in-expr.pdl │ │ │ ├── extern-synch-fail.pdl │ │ │ ├── unlocked-mem-1.pdl │ │ │ ├── generic_unify_fail.pdl │ │ │ ├── type-inference-fail-call.pdl │ │ │ ├── type-inference-fail-call-args.pdl │ │ │ ├── lock-fail-top-branch.pdl │ │ │ ├── lock-fail-acquire-before-access.pdl │ │ │ ├── unlocked-mem-fail.pdl │ │ │ ├── double-call-fail.pdl │ │ │ ├── unlocked-reg.pdl │ │ │ ├── extern_pass.pdl │ │ │ ├── double-call-guarded.pdl │ │ │ ├── signedInts.pdl │ │ │ ├── lock-release-OOO-fail.pdl │ │ │ ├── boolean-mishap.pdl │ │ │ ├── lock-wellformedness-fail.pdl │ │ │ ├── lock-fail-no-default-acquire-split.pdl │ │ │ ├── lock-fail-reads-after-writes.pdl │ │ │ ├── lock-fail-double-write.pdl │ │ │ ├── lock-fail-read-after-writes-branch.pdl │ │ │ ├── lock-fail-read-after-writes-release.pdl │ │ │ ├── lock-fail-wrong-branch-acquire.pdl │ │ │ ├── lock-release-OOO-split-fail.pdl │ │ │ ├── lock-release-OOO-different-address-fail.pdl │ │ │ ├── lock-fail-no-acquire-in-split-case.pdl │ │ │ ├── lock-release-OOO-nested-if-fail.pdl │ │ │ ├── generic_adder.pdl │ │ │ ├── superscalar-fail.pdl │ │ │ ├── lock-acquire-in-split-case.pdl │ │ │ ├── missing-one-fail.pdl │ │ │ ├── lock-fail-reserve-without-write.pdl │ │ │ ├── lock-release-OOO-nested-branches-fail.pdl │ │ │ ├── pipe-lock-fail1.pdl │ │ │ ├── pipe-lock-fail2.pdl │ │ │ ├── type-inference-bit-width-tests.pdl │ │ │ ├── more_generic_tests.pdl │ │ │ ├── generic_funcs_passz3.pdl │ │ │ ├── pipe-lock.pdl │ │ │ ├── lock-success-read-write-order.pdl │ │ │ ├── lock-tests-specific.pdl │ │ │ └── quad-call-disjoint.pdl │ │ ├── autocastTests │ │ │ ├── solutions │ │ │ │ ├── risc-pipe-spec.typechecksol │ │ │ │ ├── autocast-basic-pass.typechecksol │ │ │ │ ├── type-inference-basic-pass.typechecksol │ │ │ │ ├── type-inference-fail-call.typechecksol │ │ │ │ ├── type-inference-bit-width-tests.typechecksol │ │ │ │ ├── type-inference-fail-base-type.typechecksol │ │ │ │ ├── type-inference-fail-boolBinOp.typechecksol │ │ │ │ ├── type-inference-fail-call-args.typechecksol │ │ │ │ ├── type-inference-fail-eqBinOp.typechecksol │ │ │ │ ├── type-inference-fail-funcApp.typechecksol │ │ │ │ ├── type-inference-fail-numBinOp.typechecksol │ │ │ │ ├── type-inference-fail-ternary.typechecksol │ │ │ │ ├── type-inference-fail-func-app-arg.typechecksol │ │ │ │ ├── type-inference-fail-bit-too-small-minus.typechecksol │ │ │ │ ├── type-inference-fail-bit-too-small-mult.typechecksol │ │ │ │ ├── type-inference-fail-bit-too-small-plus.typechecksol │ │ │ │ └── type-inference-fail-bit-too-small-memAccessToosmall.typechecksol │ │ │ ├── type-inference-fail-bit-too-small-mult.pdl │ │ │ ├── type-inference-fail-bit-too-small-plus.pdl │ │ │ ├── type-inference-fail-bit-too-small-minus.pdl │ │ │ ├── type-inference-fail-numBinOp.pdl │ │ │ ├── type-inference-fail-eqBinOp.pdl │ │ │ ├── type-inference-fail-boolBinOp.pdl │ │ │ ├── type-inference-fail-bit-too-small-memAccessToosmall.pdl │ │ │ ├── type-inference-fail-ternary.pdl │ │ │ ├── type-inference-fail-base-type.pdl │ │ │ ├── type-inference-fail-func-app-arg.pdl │ │ │ ├── type-inference-fail-funcApp.pdl │ │ │ ├── type-inference-fail-call.pdl │ │ │ ├── type-inference-fail-call-args.pdl │ │ │ └── type-inference-bit-width-tests.pdl │ │ └── registerRenamingTests │ │ │ ├── solutions │ │ │ ├── 3-stg-lsq.typechecksol │ │ │ ├── 3-stg-pipe.typechecksol │ │ │ ├── validLockTypes.typechecksol │ │ │ ├── lock-wrong-type-nested-fail.typechecksol │ │ │ ├── lock-wrong-type-read-write-fail.typechecksol │ │ │ ├── lock-wrong-type-write-read-fail.typechecksol │ │ │ ├── 3-stg-lsq.simsol │ │ │ └── 3-stg-pipe.simsol │ │ │ ├── memInputs │ │ │ ├── m │ │ │ └── rename │ │ │ ├── lock-wrong-type-read-write-fail.pdl │ │ │ ├── lock-wrong-type-write-read-fail.pdl │ │ │ ├── lock-wrong-type-nested-fail.pdl │ │ │ ├── 3-stg-pipe.pdl │ │ │ ├── 3-stg-lsq.pdl │ │ │ └── validLockTypes.pdl │ ├── scala │ │ └── pipedsl │ │ │ ├── TypeAutoCastSuite.scala │ │ │ ├── LockTypecheckSuite.scala │ │ │ ├── MiscSimulationSuite.scala │ │ │ ├── SpeculationSuite.scala │ │ │ ├── RegisterRenamingSuite.scala │ │ │ ├── LockMergeSuite.scala │ │ │ ├── RiscSuite.scala │ │ │ ├── util │ │ │ └── memFileGen.sh │ │ │ └── CSplitSuite.scala │ └── README.md └── resources │ └── grammar.txt ├── project ├── build.properties └── assembly.sbt ├── examples └── README.md ├── bin ├── pdl ├── check-setup.sh └── pdl-completion.bash ├── .gitignore ├── Makefile ├── LICENSE ├── docs ├── inference.md └── lock-lang.md └── .github └── workflows └── scala.yml /bscRuntime/.gitignore: -------------------------------------------------------------------------------- 1 | stages/* -------------------------------------------------------------------------------- /src/main/resources/badReUse.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/mm1: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/mm3: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/mm4: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/td1: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/td3: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/td4: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/tests/histogram/histogram_nested.sim: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.4.4 2 | 3 | -------------------------------------------------------------------------------- /src/test/tests/matpow/solutions/matpow.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/histogram/solutions/histogram.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/matpow/solutions/matpow_alt.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/matpow/solutions/matpow_bram.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/multiExec/solutions/multiexec.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/branch-1.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/branch-2.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/branch-3.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/nested-1.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/nested-2.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/split-1.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/split-2.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/split-3.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/split-4.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/histogram/solutions/histogram_bram.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-infer-1.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-infer-2.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-infer-3.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-infer-4.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-merge-1.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-merge-2.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-merge-3.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-merge-4.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/multiExec/solutions/multiexec_alt.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-3stg.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-spec.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/simtests/solutions/unlocked-reg.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/3-stg-pipe.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/bad-spec-1.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/bad-spec-2.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/bad-spec-3.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/bad-spec-4.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/bad-spec-5.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/spec-write-2.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/spec-write.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/pipe-lock.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/risc-pipe-spec.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/branch-3.simsol: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /src/test/tests/histogram/solutions/histogram_bram2.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/histogram/solutions/histogram_nested.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/histogram/solutions/histogram_short.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/multiExec/solutions/multiexec_split.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-cache.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/3-stg-pipe-spec-2.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/3-stg-pipe-spec-3.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/3-stg-pipe-spec.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/spec-write-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/spec-write-fail2.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/spec-write-fail3.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/spec-write-infer.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/boolean-mishap.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/extern_pass.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/input-smt-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/signedInts.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/unlocked-mem-1.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/unlocked-mem.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/unlocked-reg.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /project/assembly.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.10") -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/autocast-basic-pass.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/nested-branches-1.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/solutions/3-stg-lsq.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/solutions/3-stg-pipe.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-spec-write-2.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-spec-write.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/unnecessary-checkpoint.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/acquire-in-expr.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/double-call-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/double-call-guarded.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/extern-synch-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/generic-bht.typechecksol: -------------------------------------------------------------------------------- 1 | Passed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/generic_adder.typechecksol: -------------------------------------------------------------------------------- 1 | Passed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-tests-general.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-tests-specific.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/missing-one-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/nested_generic.typechecksol: -------------------------------------------------------------------------------- 1 | Passed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/pipe-lock-fail1.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/pipe-lock-fail2.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/quad-call-disjoint.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/superscalar-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/unlocked-mem-fail-1.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/unlocked-mem-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-basic-pass.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-call.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/solutions/validLockTypes.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-spec-bypass-bht.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-spec-rename-bht.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-spec-rename-ooo.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-spec-write-infer.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/acquire-in-expr-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/generic-bht-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/generic_func_fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/generic_funcs_pass.typechecksol: -------------------------------------------------------------------------------- 1 | Passed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/generic_unify_fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-branch-acquire.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-branch-release.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-double-write.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-top-branch.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-release-OOO-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-wellformedness-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/more_generic_tests.typechecksol: -------------------------------------------------------------------------------- 1 | Passed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-call.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-bit-width-tests.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-base-type.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-boolBinOp.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-call-args.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-eqBinOp.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-funcApp.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-numBinOp.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-ternary.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/risc-pipe-spec-rename-ooo-infer.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/generic_adder_unsigned.typechecksol: -------------------------------------------------------------------------------- 1 | Passed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/generic_funcs_passz3.typechecksol: -------------------------------------------------------------------------------- 1 | Passed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-acquire-in-split-case.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-reads-after-writes.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-release-OOO-split-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-success-read-write-order.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/risc-pipe-spec-generic.typechecksol: -------------------------------------------------------------------------------- 1 | Passed 2 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-basic-pass.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-base-type.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-boolBinOp.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-call-args.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-eqBinOp.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-funcApp.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-numBinOp.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-ternary.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-func-app-arg.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/solutions/lock-wrong-type-nested-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-acquire-before-access.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-no-acquire-in-split-case.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-no-default-acquire-split.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-read-after-writes-branch.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-reserve-without-write.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-wrong-branch-acquire.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-release-OOO-nested-if-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-bit-width-tests.typechecksol: -------------------------------------------------------------------------------- 1 | Passed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-func-app-arg.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-bit-too-small-minus.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-bit-too-small-mult.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-bit-too-small-plus.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/solutions/lock-wrong-type-read-write-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/solutions/lock-wrong-type-write-read-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-no-acquire-before-release.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-fail-read-after-writes-release.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-release-OOO-different-address-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/lock-release-OOO-nested-branches-fail.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-bit-too-small-minus.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-bit-too-small-mult.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-bit-too-small-plus.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/autocastTests/solutions/type-inference-fail-bit-too-small-memAccessToosmall.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/solutions/type-inference-fail-bit-too-small-memAccessToosmall.typechecksol: -------------------------------------------------------------------------------- 1 | Failed -------------------------------------------------------------------------------- /src/main/scala/pipedsl/typechecker/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apl-cornell/PDL/HEAD/src/main/scala/pipedsl/typechecker/.DS_Store -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/3-stg-pipe.simsol: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 4 4 | 2 5 | 6 6 | 8 7 | 10 8 | 4 9 | -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/spec-write-2.simsol: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 4 4 | 2 5 | 6 6 | 8 7 | 10 8 | 4 9 | -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/3-stg-pipe-spec-2.simsol: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 4 4 | 2 5 | 6 6 | 8 7 | 10 8 | 4 9 | -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/3-stg-pipe-spec-3.simsol: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 4 4 | 2 5 | 6 6 | 8 7 | 10 8 | 4 9 | -------------------------------------------------------------------------------- /src/test/tests/speculation/solutions/3-stg-pipe-spec.simsol: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 4 4 | 2 5 | 6 6 | 8 7 | 10 8 | 4 9 | -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-bit-too-small-mult.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test6()[] { 3 | a = 6 * 6; 4 | int<5> b = a; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-bit-too-small-plus.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test6()[] { 3 | a = 6 + 6; 4 | int<2> b = a; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-bit-too-small-minus.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test6()[] { 3 | a = 6 - 6; 4 | int<2> b = a; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-bit-too-small-minus.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test6()[] { 3 | a = 6 - 6; 4 | int<2> b = a; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-bit-too-small-mult.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test6()[] { 3 | a = 6 * 6; 4 | int<5> b = a; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-bit-too-small-plus.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test6()[] { 3 | a = 6 + 6; 4 | int<2> b = a; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-numBinOp.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: int<32>)[rf: int<32>[32]] { 2 | a = true; 3 | b = a + a; 4 | } 5 | 6 | circuit { 7 | r = memory(int<32>, 32); 8 | } -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-eqBinOp.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: int<32>)[rf: int<32>[32]] { 2 | a = true; 3 | b = a == input; 4 | } 5 | 6 | circuit { 7 | r = memory(int<32>, 32); 8 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-eqBinOp.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: int<32>)[rf: int<32>[32]] { 2 | a = true; 3 | b = a == input; 4 | } 5 | 6 | circuit { 7 | r = memory(int<32>, 32); 8 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-numBinOp.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: int<32>)[rf: int<32>[32]] { 2 | a = true; 3 | b = a + a; 4 | } 5 | 6 | circuit { 7 | r = memory(int<32>, 32); 8 | } -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-boolBinOp.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test1(input: int<32>)[rf: int<32>[32]] { 3 | a = input; 4 | b = a || a; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/generic_adder_unsigned.pdl: -------------------------------------------------------------------------------- 1 | def adder(x :uint, y :uint) :int 2 | { 3 | return cast(x + y, int); 4 | } 5 | 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-boolBinOp.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test1(input: int<32>)[rf: int<32>[32]] { 3 | a = input; 4 | b = a || a; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/main/scala/pipedsl/typechecker/AnalysisProvider.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.typechecker 2 | 3 | import pipedsl.common.Syntax.Prog 4 | 5 | trait AnalysisProvider[Analysis] 6 | { 7 | def get(program :Prog) :Analysis 8 | } 9 | -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test6()[rf: int<32>[32]] { 3 | int<64> a = 6 * 6; 4 | c = rf[a]; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-ternary.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: int<32>)[rf: int<32>[32]] { 2 | a = true; 3 | b = input; 4 | c = (b) ? a : b; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/simtests/solutions/unlocked-reg.simsol: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 11 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test6()[rf: int<32>[32]] { 3 | int<64> a = 6 * 6; 4 | c = rf[a]; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-ternary.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: int<32>)[rf: int<32>[32]] { 2 | a = true; 3 | b = input; 4 | c = (b) ? a : b; 5 | } 6 | 7 | circuit { 8 | r = memory(int<32>, 32); 9 | } -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | ## TODO 2 | 3 | For now, consider the test pipelines (in src/test/tests) as examples. 4 | In the future we will make annotated examples available in this directory to highlight specific features of PDL. 5 | 6 | -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-base-type.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: int<32>)[rf: int<32>[32]] { 2 | a = input + 2<32>; 3 | if (a) { 4 | 5 | } 6 | } 7 | 8 | circuit { 9 | r = memory(int<32>, 32); 10 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-base-type.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: int<32>)[rf: int<32>[32]] { 2 | a = input + 2<32>; 3 | if (a) { 4 | 5 | } 6 | } 7 | 8 | circuit { 9 | r = memory(int<32>, 32); 10 | } -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/ti4: -------------------------------------------------------------------------------- 1 | 010000ef 2 | 0000006f 3 | 00000000 4 | 00000000 5 | ff010113 6 | fb500793 7 | 00f12623 8 | 01700793 9 | 00f12423 10 | 00c12703 11 | 00812783 12 | 02f757b3 13 | 00078513 14 | 01010113 15 | 00008067 16 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/rf: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 400 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 0 14 | 0 15 | 0 16 | 0 17 | 0 18 | 0 19 | 0 20 | 0 21 | 0 22 | 0 23 | 0 24 | 0 25 | 0 26 | 0 27 | 0 28 | 0 29 | 0 30 | 0 31 | 0 32 | 0 -------------------------------------------------------------------------------- /src/test/tests/matpow/memInputs/a_2: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | 3 4 | 1 5 | 0 6 | 2 7 | 0 8 | 3 9 | 2 10 | 0 11 | 0 12 | 2 13 | 0 14 | 0 15 | 3 16 | 1 17 | 1 18 | 0 19 | 3 20 | 3 21 | 0 22 | 3 23 | 1 24 | 2 25 | 2 26 | 0 27 | 0 28 | 2 29 | 1 30 | 2 31 | 1 32 | 1 33 | -------------------------------------------------------------------------------- /src/test/tests/matpow/memInputs/c: -------------------------------------------------------------------------------- 1 | 0 2 | 2 3 | 6 4 | 2 5 | 5 6 | b 7 | c 8 | f 9 | b 10 | 3 11 | d 12 | a 13 | f 14 | 5 15 | 8 16 | a 17 | f 18 | 8 19 | a 20 | f 21 | 9 22 | d 23 | b 24 | 5 25 | 10 26 | b 27 | 12 28 | e 29 | a 30 | 7 31 | 7 32 | 12 33 | -------------------------------------------------------------------------------- /src/test/tests/matpow/memInputs/r: -------------------------------------------------------------------------------- 1 | b 2 | 2 3 | e 4 | 2 5 | 7 6 | 7 7 | e 8 | 2 9 | e 10 | 10 11 | d 12 | 10 13 | 0 14 | 9 15 | d 16 | a 17 | 12 18 | 11 19 | f 20 | 5 21 | 3 22 | 6 23 | 10 24 | 11 25 | c 26 | 13 27 | e 28 | 0 29 | e 30 | 5 31 | f 32 | 2 33 | -------------------------------------------------------------------------------- /src/test/tests/speculation/memInputs/rename: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | 2 4 | 3 5 | 4 6 | 5 7 | 6 8 | 7 9 | 8 10 | 9 11 | a 12 | b 13 | c 14 | d 15 | e 16 | f 17 | 10 18 | 11 19 | 12 20 | 13 21 | 14 22 | 15 23 | 16 24 | 17 25 | 18 26 | 19 27 | 1a 28 | 1b 29 | 1c 30 | 1d 31 | 1e 32 | 1f -------------------------------------------------------------------------------- /bin/pdl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | #execute the pdl compiler 6 | JARNAME=pdl.jar 7 | JARPATH=target/scala-2.13/"$JARNAME" 8 | SCRIPTPATH=$(cd "$(dirname "$0")" && pwd -P) 9 | #pass through all cmds except fist 10 | java -jar "$SCRIPTPATH"/../"$JARPATH" "$@" 11 | -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/memInputs/m: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | 2 4 | 3 5 | 4 6 | 5 7 | 6 8 | 7 9 | 8 10 | 9 11 | a 12 | b 13 | c 14 | d 15 | e 16 | f 17 | 10 18 | 11 19 | 12 20 | 13 21 | 14 22 | 15 23 | 16 24 | 17 25 | 18 26 | 19 27 | 1a 28 | 1b 29 | 1c 30 | 1d 31 | 1e 32 | 1f -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/memInputs/rename: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | 2 4 | 3 5 | 4 6 | 5 7 | 6 8 | 7 9 | 8 10 | 9 11 | a 12 | b 13 | c 14 | d 15 | e 16 | f 17 | 10 18 | 11 19 | 12 20 | 13 21 | 14 22 | 15 23 | 16 24 | 17 25 | 18 26 | 19 27 | 1a 28 | 1b 29 | 1c 30 | 1d 31 | 1e 32 | 1f -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-func-app-arg.pdl: -------------------------------------------------------------------------------- 1 | def func(a: bool, b: int<32>): bool { 2 | return b; 3 | } 4 | 5 | pipe test1(input: int<32>)[rf: int<32>[32]] { 6 | a = true; 7 | b = func(a, a); 8 | } 9 | 10 | circuit { 11 | r = memory(int<32>, 32); 12 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/generic_func_fail.pdl: -------------------------------------------------------------------------------- 1 | def indexing(x :int, y :int) :int<6> 2 | { 3 | return x{J - 1:0}; 4 | } 5 | 6 | def error(x :int<3>, y :int<6>) :int<6> 7 | { 8 | return indexing(x, y); 9 | } 10 | 11 | circuit { 12 | r = memory(int<32>, 32); 13 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-func-app-arg.pdl: -------------------------------------------------------------------------------- 1 | def func(a: bool, b: int<32>): bool { 2 | return b; 3 | } 4 | 5 | pipe test1(input: int<32>)[rf: int<32>[32]] { 6 | a = true; 7 | b = func(a, a); 8 | } 9 | 10 | circuit { 11 | r = memory(int<32>, 32); 12 | } -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-funcApp.pdl: -------------------------------------------------------------------------------- 1 | def func(a: bool, b: int<32>): bool { 2 | return b; 3 | } 4 | 5 | pipe test1(input: int<32>)[rf: int<32>[32]] { 6 | a = true; 7 | b = func(a, input) + 5<32>; 8 | } 9 | 10 | circuit { 11 | r = memory(int<32>, 32); 12 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-funcApp.pdl: -------------------------------------------------------------------------------- 1 | def func(a: bool, b: int<32>): bool { 2 | return b; 3 | } 4 | 5 | pipe test1(input: int<32>)[rf: int<32>[32]] { 6 | a = true; 7 | b = func(a, input) + 5<32>; 8 | } 9 | 10 | circuit { 11 | r = memory(int<32>, 32); 12 | } -------------------------------------------------------------------------------- /src/test/tests/multiExec/solutions/multiexec.simsol: -------------------------------------------------------------------------------- 1 | 0 2 | 2 3 | 4 4 | 6 5 | 0 6 | 24 7 | 27 8 | 2 9 | 96 10 | 41 11 | 16 12 | 1 13 | 6 14 | 12 15 | 0 16 | -------------------------------------------------------------------------------- /src/test/tests/multiExec/solutions/multiexec_alt.simsol: -------------------------------------------------------------------------------- 1 | 0 2 | 2 3 | 4 4 | 6 5 | 0 6 | 24 7 | 27 8 | 96 9 | 2 10 | 41 11 | 16 12 | 1 13 | 6 14 | 12 15 | 0 16 | -------------------------------------------------------------------------------- /src/test/tests/multiExec/solutions/multiexec_split.simsol: -------------------------------------------------------------------------------- 1 | 0 2 | 2 3 | 4 4 | 6 5 | 0 6 | 24 7 | 27 8 | 2 9 | 96 10 | 41 11 | 16 12 | 1 13 | 6 14 | 12 15 | 0 16 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/mm2: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000000000000000000000000000 2 | 0000000000000000000000000000000000000000000000000000000000000000 3 | 0000000000000000000000000000000000000000000000000000000000000000 4 | 000000040000000300000002ffffffff00000000000000000000000000000000 5 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/nested-branches-1.simsol: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 8 4 | 6 5 | 0 6 | 48 7 | -1 8 | 12 9 | 384 10 | 41943040 11 | 387 12 | 580 13 | 96 14 | 90 15 | 0 16 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-branch-acquire.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: int<32>)[rf: int<32>[5]] { 2 | start(rf); 3 | if (input{0:0} == 1) { 4 | acquire(rf); 5 | } 6 | release(rf); 7 | end(rf); 8 | call test1(input); 9 | } 10 | 11 | circuit { 12 | r = memory(int<32>, 5); 13 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/input-smt-fail.pdl: -------------------------------------------------------------------------------- 1 | pipe should_fail(input : int<32>)[] 2 | { 3 | if(input{1:1} == 1) 4 | { 5 | call should_fail(input); 6 | } 7 | --- 8 | if(input{2:2} == 1) 9 | { 10 | call should_fail(input); 11 | } 12 | } 13 | 14 | circuit 15 | { 16 | r = memory(int<32>, 5); 17 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/unlocked-mem.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe unlock(input: int<32>)[rf: int<32>[5]] { 3 | start(rf); 4 | int<32> x = rf[u0<5>] + input; 5 | rf[u1<5>] <- x; 6 | end(rf); 7 | --- 8 | call unlock(input); 9 | } 10 | 11 | circuit { 12 | r = memory(int<32>, 5); 13 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/unlocked-mem-fail-1.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe unlock(input: int<32>)[rf: int<32>[5]] { 3 | start(rf); 4 | int<32> x = rf[u0<5>] + input; 5 | end(rf); 6 | --- 7 | rf[u1<5>] <- x; 8 | call unlock(input); 9 | } 10 | 11 | circuit { 12 | r = memory(int<32>, 5); 13 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-branch-release.pdl: -------------------------------------------------------------------------------- 1 | pipe test3(input: int<32>)[rf: int<32>[5]] { 2 | start(rf); 3 | acquire(rf); 4 | if (input{0:0} == 1) { 5 | int<32> arg <- rf[cast(input{4:0}, uint<5>)]; 6 | release(rf); 7 | } 8 | end(rf); 9 | } 10 | 11 | circuit { 12 | r = memory(int<32>, 5); 13 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-no-acquire-before-release.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test7(input: int<32>)[rf: int<32>[5]] { 3 | start(rf); 4 | if (input{0:0} == 1) { 5 | release(rf); 6 | } else { 7 | release(rf); 8 | } 9 | end(rf); 10 | call test7(input); 11 | } 12 | 13 | circuit { 14 | r = memory(int<32>, 5); 15 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/branch-2.pdl: -------------------------------------------------------------------------------- 1 | pipe test(inarg: int<32>)[rf: int<32>[5]] { 2 | start(rf); 3 | if (inarg{0:0} == 1) { 4 | int<32> y = 4<32>; 5 | } else { 6 | int<32> y <- rf[cast(inarg{4:0}, uint<5>)]; 7 | --- 8 | } 9 | end(rf); 10 | call test(y); 11 | } 12 | 13 | circuit { 14 | rf = regfile(int<32>, 5); 15 | } -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/mm5: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000000000000000000000000000 2 | 0000000000000000000000000000000000000000000000000000000000000000 3 | 0000000000000000000000000000000000000000000000000000000000000000 4 | 0000000000000000000000000000000000000000000000000000000000000000 5 | 00000000000000000000000000000000000000000000000000000000040302ff 6 | -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/lock-wrong-type-read-write-fail.pdl: -------------------------------------------------------------------------------- 1 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 2 | uint<5> rs1 = input{0:4}; 3 | uint<5> rs2 = input{5:9}; 4 | start(rf); 5 | acquire(rf[rs2], R); 6 | end(rf); 7 | rf[rs2] <- 0<32>; 8 | release(rf[rs2]); 9 | } 10 | 11 | circuit { 12 | r = memory(int<32>, 5); 13 | 14 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/nested_generic.pdl: -------------------------------------------------------------------------------- 1 | def iden(a :int) :int 2 | { 3 | return a; 4 | } 5 | 6 | 7 | def adder(x :int, y :int) :int 8 | { 9 | return x + iden(y); 10 | } 11 | 12 | pipe test1(inpt: int<32>)[rf: int<32>[32]] :int<100> 13 | { 14 | output (adder(3, 4)); 15 | } 16 | 17 | 18 | circuit { 19 | r = memory(int<32>, 32); 20 | } -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/lock-wrong-type-write-read-fail.pdl: -------------------------------------------------------------------------------- 1 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 2 | uint<5> rs1 = input{0:4}; 3 | uint<5> rs2 = input{5:9}; 4 | start(rf); 5 | acquire(rf[rs2], W); 6 | end(rf); 7 | int<32> arg2 <- rf[rs2]; 8 | release(rf[rs2]); 9 | } 10 | 11 | circuit { 12 | r = memory(int<32>, 5); 13 | 14 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/acquire-in-expr-fail.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe test6(input: int<32>)[rf: int<32>[5]] { 3 | start(rf); 4 | reserve(rf); 5 | end(rf); 6 | --- 7 | int<32> x = rf[u0<5>] + input; 8 | --- 9 | block(rf); 10 | release(rf); 11 | call test6(input); 12 | } 13 | 14 | circuit { 15 | r = memory(int<32>, 5); 16 | } -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/lock-wrong-type-nested-fail.pdl: -------------------------------------------------------------------------------- 1 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 2 | uint<5> rs1 = input{0:4}; 3 | uint<5> rs2 = input{5:9}; 4 | start(rf); 5 | acquire(rf[rs2], W); 6 | end(rf); 7 | int<32> arg2 = 1<32> + rf[rs2]; 8 | release(rf[rs2]); 9 | } 10 | 11 | circuit { 12 | rf = regfile(int<32>, 5); 13 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/acquire-in-expr.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe test6(input: int<32>)[rf: int<32>[5](Queue)] { 3 | start(rf); 4 | reserve(rf); 5 | end(rf); 6 | --- 7 | block(rf); 8 | int<32> x = rf[u0<5>] + input; 9 | --- 10 | release(rf); 11 | call test6(input); 12 | } 13 | 14 | circuit { 15 | r = memory(int<32>, 5); 16 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/extern-synch-fail.pdl: -------------------------------------------------------------------------------- 1 | extern myExt { 2 | method mySyncMethod(a :int<32>) :int<32>; 3 | method myCombMethod(a :int<32>) :int<32>; 4 | } 5 | 6 | pipe test1(v :int<32>)[ext :myExt] :int<32> 7 | { 8 | s <- ext.mySyncMethod(v); 9 | q = s + v; 10 | --- 11 | output(q); 12 | } 13 | circuit { 14 | ext = new myExt[](); 15 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.log 3 | *.aux 4 | *.pdf 5 | .idea 6 | *.bo 7 | *.sched 8 | *.parse 9 | *.typecheck 10 | *.interpret 11 | out 12 | testOutputs/* 13 | miscnotes 14 | \#* 15 | tmp/ 16 | 17 | ### SBT ### 18 | 19 | dist/* 20 | target/ 21 | lib_managed/ 22 | src_managed/ 23 | project/boot/ 24 | project/plugins/project/ 25 | project/**/target/ 26 | .history 27 | .cache 28 | .lib/ 29 | .bsp 30 | -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-call.pdl: -------------------------------------------------------------------------------- 1 | pipe test10(a: bool, b: int<32>)[rf: int<32>[32]]: int<32> { 2 | output(5<32>); 3 | } 4 | 5 | pipe test11()[rf: int<32>[32]] { 6 | a = 5<32>; 7 | b = 10<32>; 8 | c = a + b; 9 | d = false; 10 | e = true; 11 | f = e || d; 12 | g = call test10(f, c); 13 | h = g == d; 14 | } 15 | 16 | circuit { 17 | r = memory(int<32>, 32); 18 | } -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/ti2: -------------------------------------------------------------------------------- 1 | 010000ef 2 | 0000006f 3 | 00000000 4 | 00000000 5 | ff010113 6 | 00012623 7 | 00012423 8 | 0340006f 9 | 00000717 10 | 05070713 11 | 00812783 12 | 00279793 13 | 00f707b3 14 | 0007a783 15 | 00c12703 16 | 00f707b3 17 | 00f12623 18 | 00812783 19 | 00178793 20 | 00f12423 21 | 00812703 22 | 00300793 23 | fce7d4e3 24 | 00c12783 25 | 00078513 26 | 01010113 27 | 00008067 28 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/unlocked-mem-1.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe unlock(input: int<32>)[rf: int<32>[5]] { 3 | spec_check(); 4 | s <- speccall unlock(input + 1<32>); 5 | --- 6 | start(rf); 7 | int<32> x = rf[u0<5>] + input; 8 | end(rf); 9 | --- 10 | spec_barrier(); 11 | verify(s, input); 12 | } 13 | 14 | circuit { 15 | r = memory(int<32>, 5); 16 | } -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-fail-call-args.pdl: -------------------------------------------------------------------------------- 1 | pipe test10(a: bool, b: int<32>)[rf: int<32>[32]]: int<32> { 2 | output(5<32>); 3 | } 4 | 5 | pipe test11()[rf: int<32>[32]] { 6 | a = 5<32>; 7 | b = 10<32>; 8 | c = a + b; 9 | d = false; 10 | e = true; 11 | f = e || d; 12 | g = call test10(c, c); 13 | h = g == b; 14 | } 15 | 16 | circuit { 17 | r = memory(int<32>, 32); 18 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/generic_unify_fail.pdl: -------------------------------------------------------------------------------- 1 | def adder(x :int, y :int) :int 2 | { 3 | return x + y; 4 | } 5 | 6 | pipe test1(input: int<32>)[rf: int<32>[32]] :int<100> 7 | { 8 | first = adder(input, 15); 9 | second = adder(cast(input, int<16>), 15); 10 | whoops = adder(first, second); 11 | output(1); 12 | } 13 | 14 | 15 | circuit { 16 | r = memory(int<32>, 32); 17 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-call.pdl: -------------------------------------------------------------------------------- 1 | pipe test10(a: bool, b: int<32>)[rf: int<32>[32]]: int<32> { 2 | output(5<32>); 3 | } 4 | 5 | pipe test11()[rf: int<32>[32]] { 6 | a = 5<32>; 7 | b = 10<32>; 8 | c = a + b; 9 | d = false; 10 | e = true; 11 | f = e || d; 12 | g = call test10(f, c); 13 | h = g == d; 14 | } 15 | 16 | circuit { 17 | r = memory(int<32>, 32); 18 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-fail-call-args.pdl: -------------------------------------------------------------------------------- 1 | pipe test10(a: bool, b: int<32>)[rf: int<32>[32]]: int<32> { 2 | output(5<32>); 3 | } 4 | 5 | pipe test11()[rf: int<32>[32]] { 6 | a = 5<32>; 7 | b = 10<32>; 8 | c = a + b; 9 | d = false; 10 | e = true; 11 | f = e || d; 12 | g = call test10(c, c); 13 | h = g == b; 14 | } 15 | 16 | circuit { 17 | r = memory(int<32>, 32); 18 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/nested-2.pdl: -------------------------------------------------------------------------------- 1 | pipe test(inarg: uint<32>)[] { 2 | if (cast (inarg{0:0}, bool)) { 3 | if (inarg{1:1} == u0) { 4 | uint<2> x = u0<2>; 5 | } else { 6 | --- 7 | uint<2> x = u1<2>; 8 | } 9 | } else { 10 | uint<2> x = u3<2>; 11 | } 12 | call test(u0<30> ++ x); 13 | } 14 | 15 | circuit { 16 | t = new test[]; 17 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-top-branch.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test16(input: int<32>)[rf: int<32>[5]] { 3 | int<32> y = 3<32>; 4 | int<32> x = 0<32>; 5 | start(rf); 6 | if (x == y + 3<32>) { 7 | acquire(rf); 8 | } 9 | if (x == 10<32>) { 10 | acquire(rf); 11 | } 12 | release(rf); 13 | end(rf); 14 | call test16(input); 15 | } 16 | circuit { 17 | r = memory(int<32>, 5); 18 | } 19 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-acquire-before-access.pdl: -------------------------------------------------------------------------------- 1 | 2 | pipe test6(input: uint<32>)[rf: int<32>[5]] { 3 | start(rf); 4 | if (input{0:0} == u1) { 5 | int<32> arg <- rf[input{31:27}]; 6 | release(rf); 7 | } else { 8 | int<32> arg <- rf[input{31:27}]; 9 | release(rf); 10 | } 11 | end(rf); 12 | call test6(input); 13 | } 14 | 15 | circuit { 16 | r = memory(int<32>, 5); 17 | } -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/ti5: -------------------------------------------------------------------------------- 1 | 010000ef 2 | 0000006f 3 | 00000000 4 | 00000000 5 | ff010113 6 | 000107a3 7 | 00011623 8 | 0400006f 9 | 00c11783 10 | 00000717 11 | 05c70713 12 | 00f707b3 13 | 0007c703 14 | 00f14783 15 | 00f707b3 16 | 00f107a3 17 | 00c11783 18 | 01079793 19 | 0107d793 20 | 00178793 21 | 01079793 22 | 0107d793 23 | 00f11623 24 | 00c11703 25 | 00300793 26 | fae7dee3 27 | 00f14783 28 | 00078513 29 | 01010113 30 | 00008067 31 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/unlocked-mem-fail.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe unlock(input: int<32>)[rf: int<32>[5]] { 3 | spec_check(); 4 | s <- speccall unlock(input + 1<32>); 5 | --- 6 | start(rf); 7 | int<32> x = rf[u0<5>] + input; 8 | rf[u1<5>] <- x; //no speculative write 9 | end(rf); 10 | --- 11 | spec_barrier(); 12 | verify(s, input); 13 | } 14 | 15 | circuit { 16 | r = memory(int<32>, 5); 17 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/double-call-fail.pdl: -------------------------------------------------------------------------------- 1 | //cannot call twice in same pipe 2 | pipe call2(input: int<32>)[rf: int<32>[5]] { 3 | start(rf); 4 | reserve(rf); 5 | end(rf); 6 | --- 7 | block(rf); 8 | int<32> x = rf[0<5>] + input; 9 | call call2(x); 10 | --- 11 | int<32> y = rf[0<5>] + input; 12 | call call2(y); 13 | --- 14 | release(rf); 15 | } 16 | 17 | circuit { 18 | r = memory(int<32>, 5); 19 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/branch-2.parsesol: -------------------------------------------------------------------------------- 1 | pipe test(inarg:int<32>)[rf:int<32>[5]] { 2 | start(rf); 3 | reserved(rf); 4 | acquired(rf); 5 | end(rf); 6 | if ( inarg{0:0} == 1<1> ) { 7 | int<32> y = 4<32>; 8 | 9 | } else { 10 | int<32> y <- rf[inarg{4:0}]; 11 | 12 | --- 13 | 14 | } 15 | released(rf); 16 | call test(y); 17 | 18 | } 19 | circuit { 20 | rf = regfile(int<32>,5); 21 | } 22 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/unlocked-reg.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe unlock(tinput: int<32>)[rf: int<32>[0]] { 3 | spec_check(); 4 | s <- speccall unlock(tinput + 1<32>); 5 | --- 6 | start(rf); 7 | int<32> x = rf[] + tinput; 8 | end(rf); 9 | --- 10 | spec_barrier(); 11 | verify(s, tinput); 12 | } 13 | 14 | circuit { 15 | r = register(int<32>, 0); 16 | un = new unlock[r]; 17 | call un(0<32>); 18 | } -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/td2: -------------------------------------------------------------------------------- 1 | 00000000 2 | 00000000 3 | 00000000 4 | 00000000 5 | 00000000 6 | 00000000 7 | 00000000 8 | 00000000 9 | 00000000 10 | 00000000 11 | 00000000 12 | 00000000 13 | 00000000 14 | 00000000 15 | 00000000 16 | 00000000 17 | 00000000 18 | 00000000 19 | 00000000 20 | 00000000 21 | 00000000 22 | 00000000 23 | 00000000 24 | 00000000 25 | 00000000 26 | 00000000 27 | 00000000 28 | 00000000 29 | ffffffff 30 | 00000002 31 | 00000003 32 | 00000004 33 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/ti1: -------------------------------------------------------------------------------- 1 | 05c000ef 2 | 0000006f 3 | 00000000 4 | 00000000 5 | fe010113 6 | 00112e23 7 | 00a12623 8 | 00c12703 9 | 00100793 10 | 00f71663 11 | 00100793 12 | 0200006f 13 | 00c12783 14 | fff78793 15 | 00078513 16 | fd5ff0ef 17 | 00050713 18 | 00c12783 19 | 02f707b3 20 | 00078513 21 | 01c12083 22 | 02010113 23 | 00008067 24 | ff010113 25 | 00112623 26 | 00a00513 27 | fa9ff0ef 28 | 00050793 29 | 00078513 30 | 00c12083 31 | 01010113 32 | 00008067 33 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/branch-1.pdl: -------------------------------------------------------------------------------- 1 | pipe test(inarg: int<32>)[rf: int<32>[5]] { 2 | start(rf); 3 | 4 | if (inarg{0:0} == 1) { 5 | rf[cast(inarg{4:0},uint<5>)] <- inarg; 6 | --- 7 | int<32> y = inarg; 8 | --- 9 | int<32> z = inarg; 10 | } else { 11 | int<32> x = inarg; 12 | } 13 | end(rf); 14 | --- 15 | call test(inarg + 1<32>); 16 | } 17 | 18 | circuit { 19 | rf = regfile(int<32>, 5); 20 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/memInputs/r_branch-3: -------------------------------------------------------------------------------- 1 | 00000000 2 | 00000001 3 | 00000002 4 | 00000003 5 | 00000004 6 | 00000005 7 | 00000006 8 | 00000007 9 | 00000008 10 | 00000009 11 | 0000000A 12 | 0000000B 13 | 0000000C 14 | 0000000D 15 | 0000000E 16 | 0000000F 17 | 00000010 18 | 00000011 19 | 00000012 20 | 00000013 21 | 00000014 22 | 00000015 23 | 00000016 24 | 00000017 25 | 00000018 26 | 00000019 27 | 0000001A 28 | 0000001B 29 | 0000001C 30 | 0000001D 31 | 0000001E 32 | 0000001F 33 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/nested-2.parsesol: -------------------------------------------------------------------------------- 1 | pipe test(inarg:int<32>)[] { 2 | if ( cast(inarg{0:0},bool) ) { 3 | if ( inarg{1:1} == 0<1> ) { 4 | int<2> x = 0<2>; 5 | 6 | } else { 7 | 8 | --- 9 | int<2> x = 1<2>; 10 | 11 | } 12 | 13 | } else { 14 | int<2> x = 3<2>; 15 | 16 | } 17 | call test(0<30> ++ x); 18 | 19 | } 20 | circuit { 21 | t = new test[]; 22 | } 23 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/td5: -------------------------------------------------------------------------------- 1 | 00000000 2 | 00000000 3 | 00000000 4 | 00000000 5 | 00000000 6 | 00000000 7 | 00000000 8 | 00000000 9 | 00000000 10 | 00000000 11 | 00000000 12 | 00000000 13 | 00000000 14 | 00000000 15 | 00000000 16 | 00000000 17 | 00000000 18 | 00000000 19 | 00000000 20 | 00000000 21 | 00000000 22 | 00000000 23 | 00000000 24 | 00000000 25 | 00000000 26 | 00000000 27 | 00000000 28 | 00000000 29 | 00000000 30 | 00000000 31 | 00000000 32 | 00000000 33 | 040302ff 34 | -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/memInputs/ti3: -------------------------------------------------------------------------------- 1 | 05c000ef 2 | 0000006f 3 | 00000000 4 | 00000000 5 | fe010113 6 | 00a12623 7 | 00b12423 8 | 00012e23 9 | 0240006f 10 | 00812783 11 | 00f12e23 12 | 00c12703 13 | 00812783 14 | 02f767b3 15 | 00f12423 16 | 01c12783 17 | 00f12623 18 | 00812783 19 | fc079ee3 20 | 00c12783 21 | 00078513 22 | 02010113 23 | 00008067 24 | ff010113 25 | 00112623 26 | 00c00593 27 | 04200513 28 | fa5ff0ef 29 | 00050793 30 | 00078513 31 | 00c12083 32 | 01010113 33 | 00008067 34 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/memInputs/r_nested-branches-1: -------------------------------------------------------------------------------- 1 | 00000000 2 | 00000001 3 | 00000002 4 | 00000003 5 | 00000004 6 | 00000005 7 | 00000006 8 | 00000007 9 | 00000008 10 | 00000009 11 | 0000000A 12 | 0000000B 13 | 0000000C 14 | 0000000D 15 | 0000000E 16 | 0000000F 17 | 00000010 18 | 00000011 19 | 00000012 20 | 00000013 21 | 00000014 22 | 00000015 23 | 00000016 24 | 00000017 25 | 00000018 26 | 00000019 27 | 0000001A 28 | 0000001B 29 | 0000001C 30 | 0000001D 31 | 0000001E 32 | 0000001F 33 | -------------------------------------------------------------------------------- /bin/check-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if ! which sbt &>/dev/null 3 | then 4 | echo "- sbt not found. Is sbt installed?" 5 | exit 1 6 | else 7 | echo "+ sbt found" 8 | fi 9 | 10 | if ! which bsc &>/dev/null 11 | then 12 | echo "- bsc not found. Is bluespec system verilog installed?" 13 | exit 1 14 | else 15 | echo "+ bsc found" 16 | fi 17 | 18 | if [[ -z "$BLUESPECDIR" ]] 19 | then 20 | echo "- BLUESPECDIR environment variable must point to BSV installation" 21 | exit 1 22 | fi 23 | -------------------------------------------------------------------------------- /src/test/tests/multiExec/memInputs/r: -------------------------------------------------------------------------------- 1 | 00000000 2 | 00000001 3 | 00000002 4 | 00000003 5 | 00000004 6 | 00000005 7 | 00000006 8 | 00000007 9 | 00000008 10 | 00000009 11 | 0000000a 12 | 0000000b 13 | 0000000c 14 | 0000000d 15 | 0000000e 16 | 0000000f 17 | 00000010 18 | 00000011 19 | 00000012 20 | 00000013 21 | 00000014 22 | 00000015 23 | 00000016 24 | 00000017 25 | 00000018 26 | 00000019 27 | 0000001a 28 | 0000001b 29 | 0000001c 30 | 0000001d 31 | 0000001e 32 | 0000001f 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/extern_pass.pdl: -------------------------------------------------------------------------------- 1 | extern myExt { 2 | method mySyncMethod(a :int<32>) :int<32>; 3 | method myCombMethod(a :int<32>) :int<32>; 4 | } 5 | 6 | pipe test1(v :int<32>)[ext :myExt] :int<32> 7 | { 8 | s <- ext.mySyncMethod(v); 9 | --- 10 | output(s + v); 11 | } 12 | pipe test2(v :int<32>)[ext :myExt] :int<32> 13 | { 14 | c = ext.myCombMethod(v); 15 | d = c + v; 16 | --- 17 | call test2(v + d); 18 | } 19 | circuit { 20 | ext = new myExt[](); 21 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/double-call-guarded.pdl: -------------------------------------------------------------------------------- 1 | pipe call_guard(input: int<32>)[rf: int<32>[5](Queue)] { 2 | start(rf); 3 | reserve(rf); 4 | end(rf); 5 | --- 6 | block(rf); 7 | int<32> x = rf[u0<5>] + input; 8 | int<1> bit = input{0:0}; 9 | if (bit == 1) { 10 | call call_guard(x); 11 | } 12 | --- 13 | if (bit != 1) { 14 | call call_guard(x); 15 | } 16 | --- 17 | release(rf); 18 | } 19 | 20 | circuit { 21 | r = memory(int<32>, 5); 22 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/branch-3.pdl: -------------------------------------------------------------------------------- 1 | pipe test(cond: uint<2>, addr: uint<16>)[mem: int<32>[16]]: bool { 2 | start(mem); 3 | if (cond == 0) { 4 | int<32> wdata <- mem[addr]; 5 | } else { 6 | int<32> wdata <- 3; 7 | } 8 | end(mem); 9 | --- 10 | x = (cond == 0) ? wdata : wdata + 1; 11 | print(x); 12 | output(true); 13 | } 14 | 15 | circuit { 16 | ti = memory(int<32>, 16); 17 | tr = regfile(int<32>, 5); 18 | c = new test[ti]; 19 | call c(u0<2>, u10<16>); 20 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/branch-3.parsesol: -------------------------------------------------------------------------------- 1 | pipe test(cond:int<2>,addr:int<16>)[mem:sint<32>[16]] { 2 | start(mem); 3 | if ( (cond == 0<-1>) ) { 4 | sint<32> wdata <- mem[addr]<, >; 5 | } else { 6 | sint<32> wdata <- 3<-1>; 7 | } 8 | end(mem); 9 | --- 10 | x = (cond == 0<-1>) ? wdata : (wdata + 1<-1>); 11 | print(x); 12 | output true; 13 | } 14 | circuit { 15 | ti = memory(sint<32>,16,1); 16 | tr = regfile(sint<32>, 5,1); 17 | c = new test[ti]; 18 | call c(0<2>,10<16>); 19 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/nested-1.pdl: -------------------------------------------------------------------------------- 1 | pipe test(inarg: int<32>)[] { 2 | if (inarg{0:0} == 1) { 3 | if (inarg{1:1} == 0) { 4 | int<2> x = 0<2>; 5 | int<2> y = 1<2>; 6 | } else { 7 | int<2> x = 1<2>; 8 | } 9 | } else { 10 | if (inarg{2:2} == 0) { 11 | int<2> x = 3<2>; 12 | } else { 13 | int<2> x = 2<2>; 14 | } 15 | } 16 | call test(0<30> ++ x); 17 | } 18 | 19 | circuit { 20 | rf = regfile(int<32>, 5); 21 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/signedInts.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe signtest(input: int<8>)[]: bool { 3 | int<8> x = input + 1<8>; 4 | bool a = x > -1<8>; 5 | print(a); 6 | bool b = cast(x, uint<8>) > cast(-1<8>, uint<8>); 7 | print(b); 8 | int<16> y = cast(x, int<16>); 9 | print(y); 10 | uint<8> z = cast(x, uint<8>); 11 | print(z); 12 | uint<16> zz = cast(z, uint<16>); 13 | print(zz); 14 | output(true); 15 | } 16 | 17 | circuit { 18 | s = new signtest[]; 19 | call s(0<8>); 20 | } -------------------------------------------------------------------------------- /src/test/scala/pipedsl/TypeAutoCastSuite.scala: -------------------------------------------------------------------------------- 1 | package pipedsl 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | 5 | import java.io.File 6 | 7 | class TypeAutoCastSuite extends AnyFunSuite 8 | { 9 | private val folder = "src/test/tests/autocastTests" 10 | private val testFiles = getListOfTests(folder) 11 | private val testFolder = new File(folder) 12 | 13 | testFiles.foreach(t => 14 | {val testBaseName = getTestName(t) 15 | test(testBaseName + " Typecheck") 16 | {testTypecheck(testFolder, t, autocast = true)}}) 17 | } 18 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-release-OOO-fail.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | start(rf); 6 | acquire(rf[rs1],W); 7 | acquire(rf[rs2],R); 8 | end(rf); 9 | if (input{0:0} == u1) { 10 | release(rf[rs1]); 11 | release(rf[rs2]); 12 | } else { 13 | release(rf[rs1]); 14 | release(rf[rs2]); 15 | } 16 | call test3(input); 17 | } 18 | 19 | circuit { 20 | r = memory(int<32>, 5); 21 | } -------------------------------------------------------------------------------- /src/main/scala/pipedsl/passes/Passes.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.passes 2 | 3 | import pipedsl.common.DAGSyntax.PStage 4 | import pipedsl.common.Syntax._ 5 | 6 | object Passes { 7 | 8 | trait ProgPass[T] { 9 | def run(p: Prog): T 10 | } 11 | 12 | trait ModulePass[T] { 13 | def run(m: ModuleDef): T 14 | } 15 | 16 | trait FunctionPass[T] { 17 | def run(f: FuncDef): T 18 | } 19 | 20 | trait CommandPass[T] { 21 | def run(c: Command): T 22 | } 23 | 24 | trait StagePass[T] { 25 | def run(s: List[PStage]): T 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/scala/pipedsl/LockTypecheckSuite.scala: -------------------------------------------------------------------------------- 1 | package pipedsl 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | 5 | import java.io.File 6 | 7 | class LockTypecheckSuite extends AnyFunSuite { 8 | private val folder = "src/test/tests/typecheckTests" 9 | private val testFiles = getListOfTests(folder) 10 | private val testFolder = new File(folder) 11 | 12 | testFiles.foreach(t => { 13 | val testBaseName = getTestName(t) 14 | test(testBaseName + " Typecheck") { 15 | testTypecheck(testFolder, t) 16 | } 17 | 18 | }) 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/split-1.pdl: -------------------------------------------------------------------------------- 1 | pipe test(inarg: int<32>)[] { 2 | split { 3 | case: (inarg{1:0} == 0<2>) { 4 | int<2> x = 3<2>; 5 | } 6 | case: (inarg{1:0} == 1<2>) { 7 | int<2> x = 0<2>; 8 | int<2> y = 1<2>; 9 | } 10 | case: (inarg{1:0} == 2<2>) { 11 | int<2> x = 2<2>; 12 | } 13 | default: { 14 | int<2> x = 1<2>; 15 | } 16 | } 17 | call test(0<30> ++ x); 18 | } 19 | 20 | circuit { 21 | rf = regfile(int<32>, 5); 22 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/boolean-mishap.pdl: -------------------------------------------------------------------------------- 1 | pipe mistake(input: int<32>)[rf: int<32>[5]] { 2 | bool a = input{0:0}; 3 | bool b = input{1:1}; 4 | if(a && b) 5 | { 6 | call mistake(input); 7 | } 8 | --- 9 | if(a && !b) 10 | { 11 | call mistake(input); 12 | } 13 | --- 14 | if((!a) && b) 15 | { 16 | call mistake(input); 17 | } 18 | --- 19 | if(!(a && b)) 20 | { 21 | call mistake(input); 22 | } 23 | } 24 | 25 | circuit 26 | { 27 | r = memory(int<32>, 5); 28 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-wellformedness-fail.pdl: -------------------------------------------------------------------------------- 1 | pipe test1(input: uint<32>)[rf: int<32>[5]] { 2 | uint<5> rs2 = input{13:9}; 3 | if (input{0:0} == u1) { 4 | reserve(rf[rs2]); 5 | acquire(rf[rs2]); 6 | release(rf[rs2]); 7 | } 8 | call test1(input); 9 | } 10 | 11 | pipe test2(input: uint<32>)[rf: int<32>[5]] { 12 | if (input{0:0} == u1) { 13 | reserve(rf); 14 | acquire(rf); 15 | release(rf); 16 | } 17 | call test2(input); 18 | } 19 | 20 | circuit { 21 | r = memory(int<32>, 5); 22 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/branch-1.parsesol: -------------------------------------------------------------------------------- 1 | pipe test(inarg:int<32>)[rf:int<32>[5]] { 2 | start(rf); 3 | reserved(rf); 4 | acquired(rf); 5 | end(rf); 6 | if ( inarg{0:0} == 1<1> ) { 7 | rf[inarg{4:0}] <- inarg; 8 | 9 | --- 10 | int<32> y = inarg; 11 | 12 | --- 13 | int<32> z = inarg; 14 | 15 | } else { 16 | int<32> x = inarg; 17 | 18 | } 19 | released(rf); 20 | 21 | --- 22 | call test(inarg + 1<32>); 23 | 24 | } 25 | circuit { 26 | rf = regfile(int<32>,5); 27 | } 28 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/split-1.parsesol: -------------------------------------------------------------------------------- 1 | pipe test(inarg:int<32>)[] { 2 | split { 3 | case: inarg{1:0} == 0<2> { 4 | int<2> x = 3<2>; 5 | 6 | } 7 | case: inarg{1:0} == 1<2> { 8 | int<2> x = 0<2>; 9 | int<2> y = 1<2>; 10 | 11 | } 12 | case: inarg{1:0} == 2<2> { 13 | int<2> x = 2<2>; 14 | 15 | } 16 | default: { 17 | int<2> x = 1<2>; 18 | 19 | } 20 | } 21 | call test(0<30> ++ x); 22 | 23 | } 24 | circuit { 25 | rf = regfile(int<32>,5); 26 | } 27 | -------------------------------------------------------------------------------- /src/test/tests/simtests/unlocked-reg.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe unlock(tinput: int<32>)[rf: int<32>[0]]: bool { 3 | spec_check(); 4 | s <- speccall unlock(tinput + 1<32>); 5 | --- 6 | start(rf); 7 | int<32> x = rf[] + tinput; 8 | end(rf); 9 | --- 10 | spec_barrier(); 11 | print(x); 12 | if (x < 10) { 13 | verify(s, x); 14 | } else { 15 | invalidate(s); 16 | output true; 17 | } 18 | } 19 | 20 | circuit { 21 | r = register(int<32>, 1); 22 | un = new unlock[r]; 23 | call un(0<32>); 24 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-no-default-acquire-split.pdl: -------------------------------------------------------------------------------- 1 | pipe test21(input: int<32>, randomBool: bool, randomBool2: bool)[rf: int<32>[5]] { 2 | start(rf); 3 | split { 4 | case: randomBool { 5 | acquire(rf); 6 | } 7 | case: randomBool2 { 8 | acquire(rf); 9 | } 10 | case: (input{0:0} == 1) { 11 | acquire(rf); 12 | } 13 | } 14 | release(rf); 15 | end(rf); 16 | call test21(input, randomBool, randomBool2); 17 | } 18 | 19 | circuit { 20 | r = memory(int<32>, 5); 21 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-reads-after-writes.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | start(rf); 6 | acquire(rf[rs2],W); 7 | acquire(rf[rs1],R); 8 | end(rf); 9 | if (input{0:0} == u1) { 10 | int<32> arg1 <- rf[rs1]; 11 | release(rf[rs1]); 12 | } else { 13 | int<32> arg1 <- rf[rs1]; 14 | release(rf[rs1]); 15 | } 16 | release(rf[rs2]); 17 | call test3(input); 18 | } 19 | 20 | circuit { 21 | r = memory(int<32>, 5); 22 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-double-write.pdl: -------------------------------------------------------------------------------- 1 | pipe test3(input: uint<32>)[rf: int<32>[5], m:int<32>[5]] { 2 | uint<5> rs1 = input{0:4}; 3 | uint<5> rs2 = input{5:9}; 4 | start(rf); 5 | start(m); 6 | acquire(rf[rs1],R); 7 | acquire(rf[rs2],W); 8 | acquire(m[rs1], R); 9 | rf[rs2] <- 1<32>; 10 | end(m); 11 | end(rf); 12 | rf[rs2] <- 2<32>; 13 | --- 14 | release(rf[rs1]); 15 | release(rf[rs2]); 16 | release(m[rs1]); 17 | call test3(input); 18 | } 19 | 20 | 21 | circuit { 22 | r = memory(int<32>, 5); 23 | m = memory(int<32>, 5); 24 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-read-after-writes-branch.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | start(rf); 6 | acquire(rf[rs1],R); 7 | acquire(rf[rs2],W); 8 | end(rf); 9 | --- 10 | release(rf[rs2]); 11 | if (input{0:0} == u1) { 12 | int<32> arg1 <- rf[rs1]; 13 | release(rf[rs1]); 14 | } else { 15 | int<32> arg1 <- rf[rs1]; 16 | release(rf[rs1]); 17 | } 18 | call test3(input); 19 | } 20 | 21 | circuit { 22 | r = memory(int<32>, 5); 23 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-read-after-writes-release.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | start(rf); 6 | acquire(rf[rs1],R); 7 | acquire(rf[rs2],W); 8 | end(rf); 9 | --- 10 | release(rf[rs2]); 11 | if (input{0:0} == u1) { 12 | int<32> arg1 <- rf[rs1]; 13 | release(rf[rs1]); 14 | } else { 15 | int<32> arg1 <- rf[rs1]; 16 | release(rf[rs1]); 17 | } 18 | call test3(input); 19 | } 20 | 21 | circuit { 22 | r = memory(int<32>, 5); 23 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-wrong-branch-acquire.pdl: -------------------------------------------------------------------------------- 1 | pipe test18(input: int<32>, randomBool: bool, randomBool2: bool)[rf: int<32>[5]] { 2 | bool a = true; 3 | bool b = false; 4 | start(rf); 5 | if (randomBool == a) { 6 | if (randomBool2 == b){ 7 | acquire(rf); 8 | } 9 | } 10 | int<32> c <- rf[0<5>]; 11 | if (randomBool == a) { 12 | if (randomBool2 == b){ 13 | release(rf); 14 | } 15 | } 16 | end(rf); 17 | call test18(input, randomBool2, randomBool); 18 | } 19 | 20 | circuit { 21 | r = memory(int<32>, 5); 22 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/nested-1.parsesol: -------------------------------------------------------------------------------- 1 | pipe test(inarg:int<32>)[] { 2 | if ( inarg{0:0} == 1<1> ) { 3 | if ( inarg{1:1} == 0<1> ) { 4 | int<2> x = 0<2>; 5 | int<2> y = 1<2>; 6 | 7 | } else { 8 | int<2> x = 1<2>; 9 | 10 | } 11 | 12 | } else { 13 | if ( inarg{2:2} == 0<1> ) { 14 | int<2> x = 3<2>; 15 | 16 | } else { 17 | int<2> x = 2<2>; 18 | 19 | } 20 | 21 | } 22 | call test(0<30> ++ x); 23 | 24 | } 25 | circuit { 26 | rf = regfile(int<32>,5); 27 | } 28 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-release-OOO-split-fail.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | start(rf); 6 | acquire(rf[rs1],W); 7 | acquire(rf[rs2],W); 8 | end(rf); 9 | split { 10 | case: (input{0:0} == u0) { 11 | release(rf[rs2]); 12 | } 13 | case: ( input{0:0} == u1) { 14 | release(rf[rs2]); 15 | } 16 | default: { 17 | release(rf[rs2]); 18 | } 19 | } 20 | release(rf[rs1]); 21 | } 22 | 23 | circuit { 24 | r = memory(int<32>, 5); 25 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-release-OOO-different-address-fail.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | bool a = input{0:0} == u1; 6 | start(rf); 7 | acquire(rf[rs1],W); 8 | acquire(rf[rs2],W); 9 | end(rf); 10 | if (a) { 11 | release(rf[rs2]); 12 | } else { 13 | release(rf[rs1]); 14 | } 15 | 16 | if (a) { 17 | release(rf[rs1]); 18 | } 19 | if (!a) { 20 | release(rf[rs2]); 21 | } 22 | call test3(input); 23 | } 24 | 25 | circuit { 26 | r = memory(int<32>, 5); 27 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | export SCALA_V := 2.13 2 | export COMPILER_JAR := target/scala-$(SCALA_V)/pdl.jar 3 | 4 | export BSV_MEMS := $(realpath bscRuntime/memories) 5 | 6 | all: setup compiler runtime 7 | 8 | setup: 9 | @echo "--- Checking setup ---" 10 | @./bin/check-setup.sh 11 | 12 | compiler: 13 | @echo "--- Building Compiler ---" 14 | @sbt assembly 15 | @echo 16 | 17 | runtime: 18 | @echo "--- Building BSV Libraries ---" 19 | @$(MAKE) -C $(BSV_MEMS) 20 | @echo 21 | clean: 22 | @echo "Cleaning compiler" 23 | @sbt clean 24 | @echo 25 | @echo "Cleaning BSV Libraries" 26 | @$(MAKE) -C $(BSV_MEMS) clean 27 | @echo 28 | 29 | .PHONY: setup, clean, compiler 30 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-no-acquire-in-split-case.pdl: -------------------------------------------------------------------------------- 1 | pipe test22(input: int<32>, randomBool: bool, randomBool2: bool)[rf: int<32>[5]] { 2 | start(rf); 3 | split { 4 | case: randomBool { 5 | acquire(rf); 6 | } 7 | case: randomBool2 { 8 | int<32> c <- rf[u0<5>]; 9 | } 10 | case: (input{0:0} == 1) { 11 | acquire(rf); 12 | } 13 | default: { 14 | acquire(rf); 15 | } 16 | } 17 | release(rf); 18 | end(rf); 19 | call test22(input, randomBool, randomBool2); 20 | } 21 | 22 | circuit { 23 | r = memory(int<32>, 5); 24 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-release-OOO-nested-if-fail.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | bool a = rs1 == rs2; 6 | bool b = rs1 + u5<5> == rs2 + u5<5>; 7 | start(rf); 8 | acquire(rf[rs1],W); 9 | acquire(rf[rs2],W); 10 | end(rf); 11 | if (a) { 12 | if (b) { 13 | release(rf[rs1]); 14 | } 15 | } else { 16 | release(rf[rs1]); 17 | } 18 | release(rf[rs2]); 19 | if(a && !b) { 20 | release(rf[rs1]); 21 | } 22 | call test3(input); 23 | } 24 | 25 | circuit { 26 | r = memory(int<32>, 5); 27 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/generic_adder.pdl: -------------------------------------------------------------------------------- 1 | def adder(x :int, y :int) :int 2 | { 3 | return x + y; 4 | } 5 | 6 | def multiply_pos(x :int, y :int) :bool 7 | { 8 | a = x $* cast(y, int);//doesn't work fully with different widths 9 | return a > 0; 10 | } 11 | 12 | pipe test1(input: int<32>)[rf: int<32>[32]] :int<100> 13 | { 14 | out = adder(3, 4); 15 | other = adder(1<1>, 0<1>); //test to see we can use different ones 16 | output (out); 17 | } 18 | 19 | pipe test2(input: int<32>)[rf: int<32>[32]] :int<100> 20 | { 21 | bool pos = multiply_pos(4<4>, 8<5>); 22 | output (1); 23 | } 24 | 25 | 26 | circuit { 27 | r = memory(int<32>, 32); 28 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/superscalar-fail.pdl: -------------------------------------------------------------------------------- 1 | pipe pp(val: int<8>)[]:int<8> 2 | { 3 | int<8> a = val + 1<8>; 4 | --- 5 | output(val - 1<8>); 6 | } 7 | 8 | pipe main(idx: uint<5>)[rf: int<8>[5](RenameRF)] :bool 9 | { 10 | start(rf); 11 | reserve(rf[idx], R); 12 | block(rf[idx]); 13 | int<8> num = rf[idx]; 14 | release(rf[idx]); 15 | end(rf); 16 | if(idx{2:2} == u1<1>) 17 | { 18 | int<8> v1 <- call pp(num); 19 | } else { 20 | int<8> v2 <- call pp(num);} 21 | call pp(num); 22 | --- 23 | output(true); 24 | } 25 | 26 | circuit 27 | { 28 | rename = rflock(int<8>, 5, 128); 29 | m = new main[rename]; 30 | call m(u0<5>); 31 | } -------------------------------------------------------------------------------- /src/test/tests/lockTests/lock-infer-2.pdl: -------------------------------------------------------------------------------- 1 | pipe ex2(in: bool)[rf: int<32>[5](Queue)] :bool { 2 | uint<5> addr = u1<5>; 3 | if (in) { 4 | reserve(rf[addr], R); 5 | } 6 | --- 7 | uint<5> addr2 = u2<5>; 8 | bool cond2 = true; 9 | if (cond2) { 10 | reserve(rf[addr2], R); 11 | } 12 | --- 13 | if (in) { 14 | block(rf[addr]); 15 | y <- rf[addr]; 16 | release(rf[addr]); 17 | } 18 | --- 19 | if (cond2) { 20 | block(rf[addr2]); 21 | z <- rf[addr2]; 22 | release(rf[addr2]); 23 | } 24 | output(in); 25 | } 26 | 27 | circuit { 28 | t1 = memory(int<32>, 5); 29 | r1 = Queue(t1); 30 | e = new ex2[r1]; 31 | call e(true); 32 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-acquire-in-split-case.pdl: -------------------------------------------------------------------------------- 1 | pipe test22(input: uint<32>, randomBool: bool, randomBool2: bool)[rf: int<32>[5](Queue)] { 2 | start(rf); 3 | split { 4 | case: randomBool { 5 | reserve(rf); 6 | } 7 | case: randomBool2 { 8 | reserve(rf); 9 | } 10 | case: (input{0:0} == u1) { 11 | reserve(rf); 12 | } 13 | default: { 14 | reserve(rf); 15 | } 16 | } 17 | end(rf); 18 | --- 19 | block(rf); 20 | int<32> x <- rf[input{4:0}]; 21 | release(rf); 22 | --- 23 | call test22(input, randomBool, randomBool2); 24 | } 25 | 26 | circuit { 27 | r = memory(int<32>, 5); 28 | } -------------------------------------------------------------------------------- /src/test/tests/risc-pipe/solutions/4.simsol: -------------------------------------------------------------------------------- 1 | PC: 0000 2 | INSN: 010000ef 3 | Writing 4 to r 1 4 | PC: 0010 5 | INSN: ff010113 6 | Writing 1008 to r 2 7 | PC: 0014 8 | INSN: fb500793 9 | Writing -75 to r15 10 | PC: 0018 11 | INSN: 00f12623 12 | PC: 001c 13 | INSN: 01700793 14 | Writing 23 to r15 15 | PC: 0020 16 | INSN: 00f12423 17 | PC: 0024 18 | INSN: 00c12703 19 | Writing -75 to r14 20 | PC: 0028 21 | INSN: 00812783 22 | Writing 23 to r15 23 | PC: 002c 24 | INSN: 02f757b3 25 | Writing 186737705 to r15 26 | PC: 0030 27 | INSN: 00078513 28 | Writing 186737705 to r10 29 | PC: 0034 30 | INSN: 01010113 31 | Writing 1024 to r 2 32 | PC: 0038 33 | INSN: 00008067 34 | PC: 0004 35 | INSN: 0000006f 36 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/split-2.parsesol: -------------------------------------------------------------------------------- 1 | pipe test(inarg:int<32>)[rf:int<32>[5]] { 2 | start(rf); 3 | int<2> cond = inarg{1:0}; 4 | split { 5 | case: cond == 0<2> { 6 | int<5> addr = 0<5>; 7 | 8 | } 9 | case: cond == 1<2> { 10 | int<5> addr = 1<5>; 11 | 12 | } 13 | case: cond == 2<2> { 14 | int<5> addr = 2<5>; 15 | 16 | } 17 | default: { 18 | int<5> addr = 3<5>; 19 | 20 | } 21 | } 22 | reserved(rf[addr],W); 23 | acquired(rf[addr],W); 24 | end(rf); 25 | 26 | --- 27 | rf[addr] <- 0<32>; 28 | released(rf[addr]); 29 | 30 | --- 31 | call test(inarg + 1<32>); 32 | 33 | } 34 | circuit { 35 | rf = regfile(int<32>,5); 36 | } 37 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/split-2.pdl: -------------------------------------------------------------------------------- 1 | pipe test(inarg: int<32>)[rf: int<32>[5](Queue)] { 2 | start(rf); 3 | int<2> cond = inarg{1:0}; 4 | split { 5 | case: (cond == 0<2>) { 6 | uint<5> addr = u0<5>; 7 | } 8 | case: (cond == 1<2>) { 9 | uint<5> addr = u1<5>; 10 | } 11 | case: (cond == 2<2>) { 12 | uint<5> addr = u2<5>; 13 | } 14 | default: { 15 | uint<5> addr = u3<5>; 16 | } 17 | } 18 | reserve(rf[addr], W); 19 | end(rf); 20 | --- 21 | block(rf[addr]); 22 | rf[addr] <- 0<32>; 23 | release(rf[addr]); 24 | --- 25 | call test(inarg + 1<32>); 26 | } 27 | 28 | circuit { 29 | rf = regfile(int<32>, 5); 30 | } -------------------------------------------------------------------------------- /src/test/tests/lockTests/lock-infer-1.pdl: -------------------------------------------------------------------------------- 1 | pipe ex1(in: bool)[r1: int<32>[5](Queue), r2: int<32>[5](Queue)] :bool { 2 | uint<5> addr = u1<5>; 3 | if (in) { 4 | reserve(r1[addr], W); 5 | } else { 6 | reserve(r2[addr], W); 7 | } 8 | --- 9 | if (in) { 10 | block(r1[addr]); 11 | r1[addr] <- 32<32>; 12 | release(r1[addr]); 13 | } 14 | --- 15 | if (!in) { 16 | block(r2[addr]); 17 | r2[addr] <- 32<32>; 18 | release(r2[addr]); 19 | } 20 | print(in); 21 | output(in); 22 | } 23 | 24 | circuit { 25 | t1 = memory(int<32>, 5); 26 | r1 = Queue(t1); 27 | t2 = memory(int<32>, 5); 28 | r2 = Queue(t2); 29 | e = new ex1[r1, r2]; 30 | call e(false); 31 | } -------------------------------------------------------------------------------- /src/test/tests/lockTests/lock-merge-2.pdl: -------------------------------------------------------------------------------- 1 | pipe ex2(in: bool)[rf: int<32>[5](Queue)] :bool { 2 | start(rf); 3 | uint<5> addr = u1<5>; 4 | if (in) { 5 | reserve(rf[addr], R); 6 | } 7 | --- 8 | uint<5> addr2 = u2<5>; 9 | bool cond2 = true; 10 | if (cond2) { 11 | reserve(rf[addr2], R); 12 | } 13 | --- 14 | if (in) { 15 | block(rf[addr]); 16 | y <- rf[addr]; 17 | release(rf[addr]); 18 | } 19 | end(rf); 20 | --- 21 | if (cond2) { 22 | block(rf[addr2]); 23 | z <- rf[addr2]; 24 | release(rf[addr2]); 25 | } 26 | output(in); 27 | } 28 | 29 | circuit { 30 | t1 = memory(int<32>, 5); 31 | r1 = Queue(t1); 32 | e = new ex2[r1]; 33 | call e(true); 34 | } -------------------------------------------------------------------------------- /bin/pdl-completion.bash: -------------------------------------------------------------------------------- 1 | #/usr/bin/bash 2 | 3 | _pdl() 4 | { 5 | local cur=${COMP_WORDS[COMP_CWORD]} 6 | 7 | if [[ $cur == -* ]] ; then 8 | local opts="--help --out --printStages --debug --portwarn --autocast --addrLockModule --reglockModule" 9 | local fword=${COMP_WORDS[1]} 10 | if [ $fword == "interpret" ]; then 11 | opts="$opts --maxIterations --memoryInput" 12 | elif [ $fword == "gen" ]; then 13 | opts="$opts --memInit" 14 | fi 15 | COMPREPLY=( $( compgen -W "$opts" -- "$cur")) 16 | else 17 | if [ "${#COMP_WORDS[@]}" != "2" ]; then 18 | COMPREPLY=( $( compgen -o plusdirs -f -X "!*.pdl" -- $cur )) 19 | else 20 | COMPREPLY=( $( compgen -W "gen typecheck parse interpret" -- "$cur")) 21 | fi 22 | fi 23 | } 24 | 25 | 26 | complete -o filenames -F _pdl ./bin/pdl pdl 27 | -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/3-stg-pipe.pdl: -------------------------------------------------------------------------------- 1 | pipe test(pc: uint<32>)[rf: int<32>[5](RenameRF)]: bool { 2 | uint<5> rs1 = pc{4:0}; 3 | uint<5> rd = rs1 - u1<5>; 4 | if (pc < u100<32>) { 5 | call test(pc + u1<32>); 6 | } else { 7 | output(true); 8 | } 9 | start(rf); 10 | reserve(rf[rs1], R); 11 | reserve(rf[rd], W); 12 | end(rf); 13 | --- 14 | block(rf[rs1]); 15 | int<32> arg = 1<32> + rf[rs1]; 16 | release(rf[rs1]); 17 | --- 18 | block(rf[rd]); 19 | print(arg); 20 | rf[rd] <- arg; 21 | release(rf[rd]); 22 | --- 23 | } 24 | 25 | circuit { 26 | // rf = regfile(int<32>, 5); 27 | // rename = RenameRF(rf)<128>; 28 | rename = rflock(int<32>, 5, 128); 29 | t = new test[rename]; 30 | call t(u1<32>); 31 | } -------------------------------------------------------------------------------- /src/test/scala/pipedsl/MiscSimulationSuite.scala: -------------------------------------------------------------------------------- 1 | package pipedsl 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | 5 | import java.io.File 6 | 7 | class MiscSimulationSuite extends AnyFunSuite 8 | { 9 | private val folder = "src/test/tests/simtests" 10 | private val testFiles = getListOfTests(folder) 11 | private val testFolder = new File(folder) 12 | 13 | testFiles.foreach(t => { 14 | val testBaseName = getTestName(t) 15 | test(testBaseName + " Typecheck") { 16 | testTypecheck(testFolder, t, autocast = true) 17 | } 18 | test(testBaseName + " BSV Compile") { 19 | testBlueSpecCompile(testFolder, t, None, Map()) 20 | } 21 | test(testBaseName + " Simulate ") { 22 | testBlueSpecSim(testFolder, t, None, Map(), Some(testBaseName + ".simsol")) 23 | } 24 | }) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/split-3.pdl: -------------------------------------------------------------------------------- 1 | pipe test(inarg: int<32>)[rf: int<32>[5](Queue)] { 2 | start(rf); 3 | int<2> cond = inarg{1:0}; 4 | split { 5 | case: (cond == 0<2>) { 6 | uint<5> addr = u7<5>; 7 | reserve(rf[addr], W); 8 | } 9 | case: (cond == 1<2>) { 10 | uint<5> addr = u1<5>; 11 | } 12 | case: (cond == 2<2>) { 13 | uint<5> addr = u2<5>; 14 | } 15 | default: { 16 | uint<5> addr = u0<5>; 17 | } 18 | } 19 | end(rf); 20 | --- 21 | if (cond == 0<2>) { 22 | block(rf[addr]); 23 | rf[addr] <- 0<32>; 24 | release(rf[addr]); 25 | } 26 | --- 27 | call test(inarg + 1<32>); 28 | } 29 | 30 | circuit { 31 | rf = regfile(int<32>, 5); 32 | } -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/split-4.pdl: -------------------------------------------------------------------------------- 1 | pipe test(inarg: int<32>)[rf: int<32>[5](Queue)] { 2 | start(rf); 3 | int<2> cond = inarg{1:0}; 4 | split { 5 | case: (cond == 0<2>) { 6 | uint<5> addr = u3<5>; 7 | } 8 | case: (cond == 1<2>) { 9 | uint<5> addr = u1<5>; 10 | } 11 | case: (cond == 2<2>) { 12 | uint<5> addr = u2<5>; 13 | } 14 | default: { 15 | uint<5> addr = u0<5>; 16 | reserve(rf[addr], W); 17 | } 18 | } 19 | end(rf); 20 | --- 21 | if (cond == 0<2>) { 22 | block(rf[addr]); 23 | rf[addr] <- 0<32>; 24 | release(rf[addr]); 25 | } 26 | --- 27 | call test(inarg + 1<32>); 28 | } 29 | 30 | circuit { 31 | rf = regfile(int<32>, 5); 32 | } -------------------------------------------------------------------------------- /src/test/README.md: -------------------------------------------------------------------------------- 1 | #Testing 2 | 3 | Automated tests use sbt's built in testing infrastructure 4 | 5 | ##Adding a Test/Tests 6 | 7 | - Create a folder for the tests in `src/test/tests/` 8 | - Put the relevant tests in the created folder 9 | - Create a folder `src/test/tests//solutions` and put expected output files for the tests 10 | - Solution files should be of the form `.sol` 11 | - For example, an expected output parse file would be `test.parsesol" 12 | - Create a folder `src/test/tests//memInputs` and put any memory initializations for simulation in the folder 13 | - Add a test in `src/test/scala/pipedsl/MainSuite`, following the current tests as examples 14 | 15 | ##Running the Tests 16 | 17 | - run `sbt test` from the top level directory 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/tests/speculation/memInputs/ti: -------------------------------------------------------------------------------- 1 | // 1111 1111 1111 11111 11111 11111 1111 1 2 | // rd rs2 rs1 brImm op 3 | 00000000 // rf[0] <= rf[0] + rf[0] ; pc + 1 PRED CORRECT (print 0) 4 | 00000000 // rf[0] <= rf[0] + rf[0] ; pc + 1 PRED CORRECT (print 0) 5 | 00000005 // beq rf[0], rf[0], pc + 2 ; pc + 2 PRED WRONG 6 | 00000005 // beq rf[0], rf[0], pc + 2 ; SKIPPED 7 | 00008420 // rf[1] <= rf[1] + rf[1] ; pc + 1 PRED CORRECT (print 2) 8 | 00000025 // beq rf[0], rf[1], pc + 2 ; pc + 1 PRED CORRECT 9 | 00000425 // beq rf[1], rf[1], pc + 2 ; pc + 2 PRED WRONG 10 | 00000420 // rf[0] <= rf[1] + rf[1] ; pc + 1 SKIPPED 11 | 00000845 // beq rf[2], rf[2], pc + 2 ; pc + 2 PRED WRONG 12 | 00000000 // w/e SKIPPED 13 | 00000420 // rf[0] <= rf[1] + rf[1] ; pc + 1 PRED CORRECT (print 4) 14 | ffffffff // END -------------------------------------------------------------------------------- /src/main/scala/pipedsl/common/Security.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.common 2 | 3 | import scala.util.parsing.input.Positional 4 | 5 | object Security { 6 | 7 | sealed trait Label extends Positional { 8 | def flowsTo(lbl: Label): Boolean 9 | def meet(lbl: Label): Label 10 | def join(lbl: Label): Label 11 | } 12 | 13 | case object LTop extends Label { 14 | override def flowsTo(lbl: Label): Boolean = lbl match { 15 | case LTop => true 16 | case _ => false 17 | } 18 | override def meet(lbl: Label): Label = lbl 19 | override def join(lbl: Label): Label = LTop 20 | } 21 | 22 | case object LBottom extends Label { 23 | override def flowsTo(lbl: Label): Boolean = true 24 | override def meet(lbl: Label): Label = LBottom 25 | override def join(lbl: Label): Label = lbl 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-merge-2.parsesol: -------------------------------------------------------------------------------- 1 | pipe ex2(in:bool)[rf:int<32>[5]] { 2 | start(rf); 3 | int<5> addr = 1<5>; 4 | if ( in ) { 5 | reserved(rf[addr],R); 6 | 7 | } else { 8 | 9 | } 10 | 11 | --- 12 | int<5> addr2 = 2<5>; 13 | bool cond2 = true; 14 | if ( cond2 ) { 15 | reserved(rf[addr2],R); 16 | 17 | } else { 18 | 19 | } 20 | 21 | --- 22 | if ( in ) { 23 | acquired(rf[addr]); 24 | released(rf[addr]); 25 | 26 | } else { 27 | 28 | } 29 | end(rf); 30 | 31 | --- 32 | if ( cond2 ) { 33 | acquired(rf[addr2]); 34 | released(rf[addr2]); 35 | 36 | } else { 37 | 38 | } 39 | 40 | } 41 | circuit { 42 | r1 = memory(int<32>,5); 43 | e = new ex2[r1]; 44 | call e(true); 45 | } 46 | -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/3-stg-lsq.pdl: -------------------------------------------------------------------------------- 1 | pipe test(pc: uint<32>)[rf: int<32>[5](LSQ)]: bool { 2 | uint<5> rs1 = pc{4:0}; 3 | uint<5> rd = rs1 - u1<5>; 4 | bool done = pc >= u100<32>; 5 | if (!done) { 6 | call test(pc + u1<32>); 7 | start(rf); 8 | reserve(rf[rs1], R); 9 | reserve(rf[rd], W); 10 | end(rf); 11 | --- 12 | block(rf[rs1]); 13 | int<32> a1 <- rf[rs1]; 14 | --- 15 | int<32> arg = 1<32> + a1; 16 | release(rf[rs1]); 17 | --- 18 | block(rf[rd]); 19 | print(arg); 20 | rf[rd] <- arg; 21 | release(rf[rd]); 22 | } 23 | --- 24 | if (done) { 25 | output(true); 26 | } 27 | } 28 | 29 | circuit { 30 | m = memlock LSQ(int<32>, 5); 31 | t = new test[m]; 32 | call t(u1<32>); 33 | } -------------------------------------------------------------------------------- /src/main/scala/pipedsl/codegen/Translations.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.codegen 2 | 3 | import pipedsl.common.Syntax._ 4 | 5 | object Translations { 6 | 7 | trait Translator[T,E,V,F] { 8 | 9 | def toType(t: Type): T 10 | 11 | def toType(t: Option[Type]): Option[T] = t match { 12 | case Some(value) => Some(toType(value)) 13 | case None => None 14 | } 15 | 16 | def toExpr(e: Expr): E 17 | 18 | def toExpr(e: Option[Expr]): Option[E] = e match { 19 | case Some(value) => Some(toExpr(value)) 20 | case None => None 21 | } 22 | 23 | def toVar(i: Id): V 24 | 25 | def toVar(v: EVar): V 26 | 27 | def toVar(v: Option[EVar]): Option[V] = v match { 28 | case Some(value) => Some(toVar(value)) 29 | case None => None 30 | } 31 | 32 | def toFunc(f: FuncDef): F 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/tests/lockTests/lock-merge-1.pdl: -------------------------------------------------------------------------------- 1 | pipe ex1(in: bool)[r1: int<32>[5](Queue), r2: int<32>[5](Queue)] :bool { 2 | start(r1); 3 | start(r2); 4 | uint<5> addr = u1<5>; 5 | if (in) { 6 | reserve(r1[addr], W); 7 | } else { 8 | reserve(r2[addr], W); 9 | } 10 | end(r1); 11 | end(r2); 12 | --- 13 | if (in) { 14 | block(r1[addr]); 15 | r1[addr] <- 32<32>; 16 | release(r1[addr]); 17 | } 18 | --- 19 | if (!in) { 20 | block(r2[addr]); 21 | r2[addr] <- 32<32>; 22 | release(r2[addr]); 23 | } 24 | print(in); 25 | output(in); 26 | } 27 | 28 | circuit { 29 | t1 = memory(int<32>, 5); 30 | r1 = Queue(t1); 31 | t2 = memory(int<32>, 5); 32 | r2 = Queue(t2); 33 | e = new ex1[r1, r2]; 34 | call e(false); 35 | } -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-merge-1.parsesol: -------------------------------------------------------------------------------- 1 | pipe ex1(in:bool)[r1:int<32>[5],r2:int<32>[5]] { 2 | start(r1); 3 | start(r2); 4 | int<5> addr = 1<5>; 5 | if ( in ) { 6 | reserved(r1[addr],W); 7 | 8 | } else { 9 | reserved(r2[addr],W); 10 | 11 | } 12 | end(r1); 13 | end(r2); 14 | 15 | --- 16 | if ( in ) { 17 | acquired(r1[addr]); 18 | r1[addr] <- 32<32>; 19 | released(r1[addr]); 20 | 21 | } else { 22 | 23 | } 24 | 25 | --- 26 | if ( !in ) { 27 | acquired(r2[addr]); 28 | r2[addr] <- 32<32>; 29 | released(r2[addr]); 30 | 31 | } else { 32 | 33 | } 34 | print(in); 35 | 36 | } 37 | circuit { 38 | r1 = memory(int<32>,5); 39 | r2 = memory(int<32>,5); 40 | e = new ex1[r1,r2]; 41 | call e(false); 42 | } 43 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/split-3.parsesol: -------------------------------------------------------------------------------- 1 | pipe test(inarg:int<32>)[rf:int<32>[5]] { 2 | start(rf); 3 | int<2> cond = inarg{1:0}; 4 | split { 5 | case: cond == 0<2> { 6 | int<5> addr = 7<5>; 7 | reserved(rf[addr],W); 8 | acquired(rf[addr],W); 9 | 10 | } 11 | case: cond == 1<2> { 12 | int<5> addr = 1<5>; 13 | 14 | } 15 | case: cond == 2<2> { 16 | int<5> addr = 2<5>; 17 | 18 | } 19 | default: { 20 | int<5> addr = 0<5>; 21 | 22 | } 23 | } 24 | end(rf); 25 | 26 | --- 27 | if ( cond == 0<2> ) { 28 | rf[addr] <- 0<32>; 29 | released(rf[addr]); 30 | 31 | } else { 32 | 33 | } 34 | 35 | --- 36 | call test(inarg + 1<32>); 37 | 38 | } 39 | circuit { 40 | rf = regfile(int<32>,5); 41 | } 42 | -------------------------------------------------------------------------------- /src/test/tests/branchesCheck/solutions/split-4.parsesol: -------------------------------------------------------------------------------- 1 | pipe test(inarg:int<32>)[rf:int<32>[5]] { 2 | start(rf); 3 | int<2> cond = inarg{1:0}; 4 | split { 5 | case: cond == 0<2> { 6 | int<5> addr = 3<5>; 7 | 8 | } 9 | case: cond == 1<2> { 10 | int<5> addr = 1<5>; 11 | 12 | } 13 | case: cond == 2<2> { 14 | int<5> addr = 2<5>; 15 | 16 | } 17 | default: { 18 | int<5> addr = 0<5>; 19 | reserved(rf[addr],W); 20 | acquired(rf[addr],W); 21 | 22 | } 23 | } 24 | end(rf); 25 | 26 | --- 27 | if ( cond == 0<2> ) { 28 | rf[addr] <- 0<32>; 29 | released(rf[addr]); 30 | 31 | } else { 32 | 33 | } 34 | 35 | --- 36 | call test(inarg + 1<32>); 37 | 38 | } 39 | circuit { 40 | rf = regfile(int<32>,5); 41 | } 42 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/missing-one-fail.pdl: -------------------------------------------------------------------------------- 1 | pipe quad_call(input: int<32>)[rf: int<32>[5]] 2 | { 3 | bool a = input{0:0}; 4 | bool b = input{1:1}; 5 | bool c = input{2:2}; 6 | if(a && b && c) 7 | { 8 | output(true); 9 | } 10 | --- 11 | if(a && b && (!c)) 12 | { 13 | output(false); 14 | } 15 | --- 16 | if(a && (!b) && c) 17 | { 18 | output(true); 19 | } 20 | --- 21 | if(a && (!b) && (!c)) 22 | { 23 | output(false); 24 | } 25 | --- 26 | if((!a) && b && c) 27 | { 28 | output(true); 29 | } 30 | --- 31 | if((!a) && b && (!c)) 32 | { 33 | output(false); 34 | } 35 | --- 36 | if((!a) && (!b) && c) 37 | { 38 | output(true); 39 | } 40 | } 41 | 42 | circuit 43 | { 44 | r = memory(int<32>, 5); 45 | } -------------------------------------------------------------------------------- /src/main/scala/pipedsl/passes/BindModuleTypes.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.passes 2 | 3 | import pipedsl.common.Syntax._ 4 | import pipedsl.passes.Passes.ProgPass 5 | import pipedsl.typechecker.Environments.Environment 6 | 7 | /** 8 | * This replaces any module parameters which currently have the type 9 | * NamedType with the type given by the provided type environment. 10 | * @param tenv The environment containing top level type mappings. 11 | */ 12 | class BindModuleTypes(val tenv: Environment[Id, Type]) extends ProgPass[Prog] { 13 | override def run(p: Prog): Prog = { 14 | p.copy(exts = p.exts, fdefs = p.fdefs, moddefs = p.moddefs.map(run)) 15 | } 16 | 17 | def run(m: ModuleDef): ModuleDef = { 18 | m.copy(modules = m.modules.map(p => Param(p.name, replaceNamedType(p.typ)))).copyMeta(m) 19 | } 20 | 21 | private def replaceNamedType(t: Type): Type = t match { 22 | case TNamedType(name) => tenv(name) 23 | case _ => t 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /bscRuntime/memories/Makefile: -------------------------------------------------------------------------------- 1 | BSC=bsc -no-show-timestamps -no-show-version --aggressive-conditions 2 | TOBUILD=Ehr.bo Locks.bo Memories.bo Speculation.bo SpecialQueues.bo 3 | 4 | ## Default simulator is iverilog 5 | VSIM = -vsim iverilog 6 | 7 | all: $(TOBUILD) 8 | 9 | Ehr.bo: Ehr.bsv 10 | $(BSC) -show-schedule $< 11 | Locks.bo: Locks.bsv Ehr.bo 12 | $(BSC) -show-schedule $< 13 | %.bo: %.bsv Ehr.bo Locks.bo 14 | $(BSC) -show-schedule $< 15 | 16 | .PHONY: sim 17 | sim: $(B_LIB) $(B_SIM) 18 | 19 | $(BSC) -show-schedule -sim $(B_SIM) 20 | $(BSC) -sim -o mk$(OUT).bexe -e mk$(OUT) mk$(OUT).ba 21 | ./mk$(OUT).bexe > smoke_test_bluesim.out 22 | 23 | .PHONY: clean 24 | clean: 25 | @rm -f *.bi *.bo *.ba 26 | @rm -f *.cxx *.h *.o *.so *.bexe 27 | @rm -f *.v *.vexe 28 | @rm -f *.vcd *~ *.fsdb *.log 29 | @rm -f *.sched 30 | @rm -f smoke_test_verilog.out smoke_test_bluesim.out 31 | @rm -rf csrc INCA_libs simv.daidir vfastLog/ nWaveLog/ work_mkFibOne/ 32 | 33 | -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/validLockTypes.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe test1(tinput: uint<32>)[rf: int<32>[5]] { 3 | uint<5> rs1 = tinput{4:0}; 4 | uint<5> rs2 = tinput{9:5}; 5 | start(rf); 6 | int<32> arg1 <- rf[rs1]; 7 | rf[rs2] <- 1<32> ; 8 | end(rf); 9 | --- 10 | call test1(tinput); 11 | } 12 | 13 | //Expected Success 14 | pipe test2(tinput: uint<32>)[rf: int<32>[5]] { 15 | uint<5> rs1 = tinput{4:0}; 16 | uint<5> rs2 = tinput{9:5}; 17 | start(rf); 18 | if (tinput{0:0} == u1) { 19 | int<32> x <- rf[rs1]; 20 | } 21 | int<32> rf[rs2] <- 1<32>; 22 | end(rf); 23 | --- 24 | call test2(tinput); 25 | } 26 | 27 | pipe test3(tinput: uint<32>)[rf: int<32>[5]] { 28 | uint<5> rs1 = tinput{4:0}; 29 | uint<5> rs2 = tinput{9:5}; 30 | start(rf); 31 | int<32> arg2 = rf[rs2] + 4<32>; 32 | end(rf); 33 | call test3(tinput); 34 | } 35 | 36 | circuit { 37 | r = memory(int<32>, 5, 2); 38 | rf = regfile(int<32>, 5); 39 | 40 | } -------------------------------------------------------------------------------- /src/test/scala/pipedsl/SpeculationSuite.scala: -------------------------------------------------------------------------------- 1 | package pipedsl 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | 5 | import java.io.File 6 | 7 | class SpeculationSuite extends AnyFunSuite{ 8 | private val folder = "src/test/tests/speculation" 9 | private val testFiles = getListOfTests(folder) 10 | private val testFolder = new File(folder) 11 | 12 | private val inputFolder = folder + "/memInputs" 13 | private val inputRF = inputFolder + "/rename" 14 | private val inputIMEM = inputFolder + "/ti" 15 | private val inputMap = Map("rename" -> inputRF, "ti" -> inputIMEM) 16 | 17 | testFiles.foreach(t => { 18 | val testBaseName = getTestName(t) 19 | val simFile = getSimFile(testFolder, testBaseName) 20 | test(testBaseName + " Typecheck; Compile; Simulate") { 21 | val doesTypecheck = testTypecheck(testFolder, t) 22 | if (doesTypecheck) { 23 | testBlueSpecCompile(testFolder, t, None, inputMap) 24 | if (simFile.exists) { 25 | testBlueSpecSim(testFolder, t, None, inputMap) 26 | } 27 | } 28 | } 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /bscRuntime/libs/Makefile: -------------------------------------------------------------------------------- 1 | BSC=bsc -no-show-timestamps -no-show-version --aggressive-conditions 2 | BMOD= 3 | B_IN=$(BMOD).bsv 4 | B_LIB=$(BMOD).bo 5 | B_SIM=tb.bsv 6 | OUT=Top 7 | 8 | TOBUILD=Ehr.bo Speculation.bo 9 | 10 | ## Default simulator is iverilog 11 | VSIM = -vsim iverilog 12 | 13 | all: $(TOBUILD) 14 | 15 | %.bo: %.bsv 16 | $(BSC) -show-schedule $< 17 | 18 | $(B_LIB): $(B_IN) 19 | $(BSC) -show-schedule $< 20 | verilog: mk$(OUT).v 21 | 22 | %.v: %.bsv 23 | $(BSC) -show-schedule -verilog $< 24 | 25 | mk$(OUT).v: $(B_IN) 26 | $(BSC) -show-schedule -verilog $(B_IN) 27 | 28 | .PHONY: sim 29 | sim: $(B_SIM) 30 | 31 | $(BSC) -show-schedule -sim $(B_SIM) 32 | $(BSC) -sim -o mk$(OUT).bexe -e mk$(OUT) mk$(OUT).ba 33 | ./mk$(OUT).bexe > smoke_test_bluesim.out 34 | 35 | .PHONY: clean 36 | clean: 37 | @rm -f *.bi *.bo *.ba 38 | @rm -f *.cxx *.h *.o *.so *.bexe 39 | @rm -f *.v *.vexe 40 | @rm -f *.vcd *~ *.fsdb *.log 41 | @rm -f *.sched 42 | @rm -f smoke_test_verilog.out smoke_test_bluesim.out 43 | @rm -rf csrc INCA_libs simv.daidir vfastLog/ nWaveLog/ work_mkFibOne/ 44 | 45 | -------------------------------------------------------------------------------- /bscRuntime/libs/PrioFifo.bsv: -------------------------------------------------------------------------------- 1 | package PrioFifo; 2 | 3 | import FIFOF :: *; 4 | import RWire :: *; 5 | 6 | 7 | export mkNBFIFOF; 8 | 9 | module mkNBFIFOF(FIFOF#(dtyp)) provisos (Bits#(dtyp, szdtyp)); 10 | 11 | FIFOF#(dtyp) f <- mkFIFOF(); 12 | //allow multiple writes in the same cycle 13 | RWire#(dtyp) enq_data <- mkRWireSBR(); 14 | 15 | (*fire_when_enabled*) 16 | rule doEnq (enq_data.wget() matches tagged Valid.d); 17 | f.enq(d); 18 | endrule 19 | //only allow the FIRST enq each cycle to work, drop the others 20 | method Action enq(dtyp a) if (f.notFull()); 21 | enq_data.wset(a); 22 | endmethod 23 | 24 | method Action deq(); 25 | f.deq(); 26 | endmethod 27 | 28 | method dtyp first(); 29 | return f.first(); 30 | endmethod 31 | 32 | method Bool notFull(); 33 | return f.notFull(); 34 | endmethod 35 | 36 | method Bool notEmpty(); 37 | return f.notEmpty(); 38 | endmethod 39 | 40 | method Action clear(); 41 | f.clear(); 42 | endmethod 43 | 44 | endmodule 45 | 46 | endpackage 47 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-fail-reserve-without-write.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe test3(input: uint<32>)[rf: int<32>[5], m:int<32>[5]] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | start(rf); 6 | start(m); 7 | acquire(rf[rs1],R); 8 | acquire(rf[rs2],W); 9 | acquire(m[rs1], R); 10 | rf[rs2] <- 1<32>; 11 | end(m); 12 | end(rf); 13 | --- 14 | release(rf[rs1]); 15 | release(rf[rs2]); 16 | release(m[rs1]); 17 | call test3(input); 18 | } 19 | 20 | //Tests that modules are analyzed separately 21 | pipe test4(input: uint<32>)[rf: int<32>[5], m:int<32>[5]] :bool { 22 | uint<5> rs1 = input{0:4}; 23 | uint<5> rs2 = input{5:9}; 24 | start(rf); 25 | start(m); 26 | acquire(rf[rs1],R); 27 | acquire(rf[rs2],W); 28 | acquire(m[rs1], R); 29 | end(m); 30 | end(rf); 31 | --- 32 | release(rf[rs1]); 33 | release(rf[rs2]); 34 | release(m[rs1]); 35 | call test3(input); 36 | output(true); 37 | } 38 | 39 | circuit { 40 | r = memory(int<32>, 5); 41 | m = memory(int<32>, 5); 42 | } -------------------------------------------------------------------------------- /src/test/scala/pipedsl/RegisterRenamingSuite.scala: -------------------------------------------------------------------------------- 1 | package pipedsl 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | 5 | import java.io.File 6 | 7 | class RegisterRenamingSuite extends AnyFunSuite{ 8 | private val folder = "src/test/tests/registerRenamingTests" 9 | private val testFiles = getListOfTests(folder) 10 | private val testFolder = new File(folder) 11 | 12 | private val inputFolder = folder + "/memInputs" 13 | private val inputRename = inputFolder + "/rename" 14 | private val inputM = inputFolder + "/m" 15 | private val inputMap = Map("rename" -> inputRename, "m" -> inputM) 16 | 17 | testFiles.foreach(t => { 18 | val testBaseName = getTestName(t) 19 | val simFile = getSimFile(testFolder, testBaseName) 20 | test((testBaseName + " Typecheck; Compile; Simulate")) { 21 | val doesTypecheck = testTypecheck(testFolder, t) 22 | if (doesTypecheck) { 23 | testBlueSpecCompile(testFolder, t, None, inputMap) 24 | if (simFile.exists) { 25 | testBlueSpecSim(testFolder, t, None, inputMap) 26 | } 27 | } 28 | } 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /src/main/scala/pipedsl/common/ProgInfo.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.common 2 | 3 | import pipedsl.common.Locks.LockGranularity 4 | import pipedsl.common.Syntax.{Id, Prog} 5 | 6 | //A holder class for metadata about programs that we want to pass between stages, etc. 7 | //TODO move other metadata here from the various random ways that it's currently stored. 8 | class ProgInfo(val p: Prog) { 9 | 10 | private val modInfo: Map[Id, ModInfo] = p.moddefs.foldLeft(Map[Id, ModInfo]())((map, mod) => { 11 | map + (mod.name -> new ModInfo()) 12 | }) 13 | 14 | def getModInfo(mod: Id): ModInfo = { 15 | modInfo(mod) 16 | } 17 | 18 | def addLockInfo(locktypeinfo: Map[Id, Map[Id, LockGranularity]]): Unit = { 19 | locktypeinfo.keys.foreach(m => { 20 | modInfo(m).setLockTypes(locktypeinfo(m)) 21 | }) 22 | } 23 | 24 | class ModInfo { 25 | 26 | private var lockType: Map[Id, LockGranularity] = Map() 27 | 28 | def setLockTypes(lockTypes: Map[Id, LockGranularity]): Unit = { 29 | lockType = lockTypes 30 | } 31 | def getLockTypes: Map[Id, LockGranularity] = lockType 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/tests/lockTests/lock-infer-3.pdl: -------------------------------------------------------------------------------- 1 | pipe ex4(inarg: int<32>)[rf: int<32>[5](Queue)] :int<32> { 2 | 3 | uint<5> a1 = u0<5>; 4 | uint<5> a2 = u1<5>; 5 | bool b1 = cast(inarg{0:0} == 1, bool); 6 | bool b2 = cast(inarg{1:1} == 1, bool); 7 | reserve(rf[a2], R); 8 | --- 9 | if (b1) { 10 | reserve(rf[a1], R); 11 | } else { 12 | reserve(rf[a1], R); 13 | } 14 | --- 15 | if (b1) { 16 | block(rf[a1]); 17 | int<32> x <- rf[a1]; 18 | if (b2) { 19 | release(rf[a1]); 20 | } 21 | } 22 | --- 23 | if(b1) { 24 | block(rf[a2]); 25 | int<32> y <- rf[a2]; 26 | } else { 27 | block(rf[a2]); 28 | int<32> y <- rf[a2]; 29 | } 30 | release(rf[a2]); 31 | --- 32 | if (b1 && (!b2)) { 33 | release(rf[a1]); 34 | } 35 | if(!b1) { 36 | block(rf[a1]); 37 | int<32> z <- rf[a1]; 38 | release(rf[a1]); 39 | } 40 | output(inarg); 41 | } 42 | 43 | circuit { 44 | t = memory(int<32>, 5); 45 | r = Queue(t); 46 | e = new ex4[r]; 47 | call e(1<32>); 48 | } -------------------------------------------------------------------------------- /src/test/tests/speculation/spec-write.pdl: -------------------------------------------------------------------------------- 1 | pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool { 2 | spec_check(); 3 | start(imem); 4 | int<40> insn <- imem[cast(pc, uint<8>)]; 5 | end(imem); 6 | s <- speccall testwrite(pc + 1); 7 | --- 8 | spec_check(); 9 | int<32> data = insn{36:5}; 10 | uint<5> addr = cast(insn{4:0}, uint<5>); 11 | start(rf); 12 | int<32> sdata = rf[addr]; 13 | checkpoint(rf); 14 | reserve(rf[addr], W); //stupid to put here, but doing it just for the sake of things 15 | end(rf); 16 | wdata = data + sdata; 17 | --- 18 | spec_check(); 19 | block(rf[addr]); 20 | rf[addr] <- wdata; 21 | --- 22 | spec_barrier(); 23 | nextPc = (addr{0:0} == 0) ? pc + 2 : pc + 1; 24 | verify(s, nextPc); 25 | print("ADDR: %d, DATA: %h", addr, wdata); 26 | release(rf[addr]); 27 | } 28 | 29 | circuit { 30 | ti = memory(int<40>, 8); 31 | rf = regfile(int<32>, 5); 32 | qrf = CheckpointQueue(rf); 33 | t = new testwrite[qrf, ti]; 34 | call t(0<32>); 35 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 APL Cornell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/test/tests/speculation/spec-write-infer.pdl: -------------------------------------------------------------------------------- 1 | pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool { 2 | spec_check(); 3 | start(imem); 4 | int<40> insn <- imem[cast(pc, uint<8>)]; 5 | end(imem); 6 | s <- speccall testwrite(pc + 1); 7 | --- 8 | spec_check(); 9 | int<32> data = insn{36:5}; 10 | uint<5> addr = cast(insn{4:0}, uint<5>); 11 | start(rf); 12 | int<32> sdata = rf[addr]; 13 | //should infer this: checkpoint(rf); 14 | reserve(rf[addr], W); //stupid to put here, but doing it just for the sake of things 15 | end(rf); 16 | wdata = data + sdata; 17 | --- 18 | spec_check(); 19 | block(rf[addr]); 20 | rf[addr] <- wdata; 21 | --- 22 | spec_barrier(); 23 | nextPc = (addr{0:0} == 0) ? pc + 2 : pc + 1; 24 | verify(s, nextPc); 25 | print("ADDR: %d, DATA: %h", addr, wdata); 26 | release(rf[addr]); 27 | } 28 | 29 | circuit { 30 | ti = memory(int<40>, 8); 31 | rf = regfile(int<32>, 5); 32 | qrf = CheckpointQueue(rf); 33 | t = new testwrite[qrf, ti]; 34 | call t(0<32>); 35 | } -------------------------------------------------------------------------------- /src/test/tests/lockTests/lock-merge-3.pdl: -------------------------------------------------------------------------------- 1 | pipe ex4(inarg: int<32>)[rf: int<32>[5](Queue)] :int<32> { 2 | 3 | start(rf); 4 | uint<5> a1 = u0<5>; 5 | uint<5> a2 = u1<5>; 6 | bool b1 = cast(inarg{0:0} == 1, bool); 7 | bool b2 = cast(inarg{1:1} == 1, bool); 8 | reserve(rf[a2], R); 9 | --- 10 | if (b1) { 11 | reserve(rf[a1], R); 12 | } else { 13 | reserve(rf[a1], R); 14 | } 15 | end(rf); 16 | --- 17 | if (b1) { 18 | block(rf[a1]); 19 | int<32> x <- rf[a1]; 20 | if (b2) { 21 | release(rf[a1]); 22 | } 23 | } 24 | --- 25 | if(b1) { 26 | block(rf[a2]); 27 | int<32> y <- rf[a2]; 28 | } else { 29 | block(rf[a2]); 30 | int<32> y <- rf[a2]; 31 | } 32 | release(rf[a2]); 33 | --- 34 | if (b1 && (!b2)) { 35 | release(rf[a1]); 36 | } 37 | if(!b1) { 38 | block(rf[a1]); 39 | int<32> z <- rf[a1]; 40 | release(rf[a1]); 41 | } 42 | output(inarg); 43 | } 44 | 45 | circuit { 46 | t = memory(int<32>, 5); 47 | r = Queue(t); 48 | e = new ex4[r]; 49 | call e(1<32>); 50 | } -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-merge-4.parsesol: -------------------------------------------------------------------------------- 1 | pipe ex4(in:bool)[rf:int<32>[5]] { 2 | start(rf); 3 | int<5> addr = 1<5>; 4 | reserved(rf[addr],R); 5 | 6 | --- 7 | int<5> addr2 = 2<5>; 8 | bool cond2 = true; 9 | if ( cond2 ) { 10 | reserved(rf[addr2],R); 11 | 12 | } else { 13 | 14 | } 15 | end(rf); 16 | if ( in ) { 17 | 18 | --- 19 | if ( in ) { 20 | acquired(rf[addr]); 21 | 22 | } else { 23 | 24 | } 25 | 26 | --- 27 | if ( cond2 ) { 28 | acquired(rf[addr2]); 29 | released(rf[addr2]); 30 | 31 | } else { 32 | 33 | } 34 | 35 | --- 36 | 37 | } else { 38 | 39 | --- 40 | acquired(rf[addr]); 41 | 42 | --- 43 | 44 | } 45 | released(rf[addr]); 46 | if ( !in && cond2 ) { 47 | acquired(rf[addr2]); 48 | released(rf[addr2]); 49 | 50 | } else { 51 | 52 | } 53 | int<1> x = 1<1>; 54 | 55 | } 56 | circuit { 57 | r1 = memory(int<32>,5); 58 | e = new ex4[r1]; 59 | call e(true); 60 | } 61 | -------------------------------------------------------------------------------- /src/test/tests/speculation/spec-write-fail.pdl: -------------------------------------------------------------------------------- 1 | pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool { 2 | spec_check(); 3 | start(imem); 4 | int<40> insn <- imem[cast(pc, uint<8>)]; 5 | end(imem); 6 | s <- speccall testwrite(pc + 1); 7 | --- 8 | spec_check(); 9 | int<32> data = insn{36:5}; 10 | uint<5> addr = cast(insn{4:0}, uint<5>); 11 | start(rf); 12 | int<32> sdata = rf[addr]; 13 | reserve(rf[addr], W); //stupid to put here, but doing it just for the sake of things 14 | end(rf); 15 | wdata = data + sdata; 16 | --- 17 | spec_check(); 18 | block(rf[addr]); 19 | rf[addr] <- wdata; 20 | --- 21 | spec_barrier(); 22 | checkpoint(rf); //ERROR checkpoint too late 23 | nextPc = (addr{0:0} == 0) ? pc + 2 : pc + 1; 24 | verify(s, nextPc); 25 | print("ADDR: %d, DATA: %h", addr, wdata); 26 | release(rf[addr]); 27 | } 28 | 29 | 30 | 31 | circuit { 32 | ti = memory(int<40>, 8); 33 | rf = regfile(int<32>, 5); 34 | qrf = CheckpointQueue(rf); 35 | t = new testwrite[qrf, ti]; 36 | call t(0<32>); 37 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-release-OOO-nested-branches-fail.pdl: -------------------------------------------------------------------------------- 1 | //Expected Fail 2 | pipe test3(input: uint<32>)[rf: int<32>[5]] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | bool a = rs1 == rs2; 6 | bool b = rs1 + u5<5> == rs2 + u5<5>; 7 | bool c = rs1 + u6<5> == rs2 + u6<5>; 8 | bool d = rs1 + u7<5> == rs2 + u7<5>; 9 | 10 | start(rf); 11 | acquire(rf[rs1],W); 12 | acquire(rf[rs2],W); 13 | end(rf); 14 | split { 15 | case: (a) { 16 | if(c) { 17 | release(rf[rs2]); 18 | } 19 | } 20 | case: (b) { 21 | } 22 | default: { 23 | if(c) { 24 | release(rf[rs2]); 25 | } 26 | } 27 | } 28 | if(b && !a) { 29 | release(rf[rs2]); 30 | } 31 | if (a && !c) { 32 | release(rf[rs2]); 33 | } 34 | if(!a) { 35 | if(!b) { 36 | if(!c) { 37 | release(rf[rs2]); 38 | } 39 | } 40 | } 41 | release(rf[rs1]); 42 | call test3(input); 43 | } 44 | 45 | circuit { 46 | r = memory(int<32>, 5); 47 | } -------------------------------------------------------------------------------- /src/test/tests/lockTests/lock-infer-4.pdl: -------------------------------------------------------------------------------- 1 | pipe ex4(in: bool)[rf: int<32>[5](Queue)] :bool{ 2 | uint<5> addr = u1<5>; 3 | reserve(rf[addr],R); 4 | --- 5 | uint<5> addr2 = u2<5>; 6 | bool cond2 = true; 7 | if (cond2) { 8 | reserve(rf[addr2],R); 9 | } 10 | if (in) { 11 | --- 12 | if (in) { 13 | block(rf[addr]); 14 | z <- rf[addr]; 15 | } 16 | --- 17 | if (cond2) { 18 | block(rf[addr2]); 19 | zz <- rf[addr2]; 20 | release(rf[addr2]); 21 | } 22 | --- 23 | } else { 24 | --- 25 | block(rf[addr]); 26 | xx <- rf[addr]; 27 | --- 28 | } 29 | --- 30 | release(rf[addr]); 31 | --- //TODO remove this separation, currently can't compile due to concurrent release w/ only 1 release port 32 | if ((!in) && cond2) { 33 | block(rf[addr2]); 34 | aa <- rf[addr2]; 35 | release(rf[addr2]); 36 | } 37 | int<1> x = 1<1>; 38 | output(in); 39 | } 40 | 41 | circuit { 42 | t1 = memory(int<32>, 5); 43 | r1 = Queue(t1); 44 | e = new ex4[r1]; 45 | call e(true); 46 | } -------------------------------------------------------------------------------- /src/main/scala/pipedsl/passes/LockEliminationPass.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.passes 2 | 3 | import pipedsl.common.DAGSyntax.{IfStage, PStage} 4 | import pipedsl.common.Locks.eliminateLockRegions 5 | import pipedsl.common.Syntax.{Command, ICondCommand, ILockNoOp} 6 | import pipedsl.common.Utilities.flattenStageList 7 | import pipedsl.passes.Passes.StagePass 8 | 9 | object LockEliminationPass extends StagePass[List[PStage]] { 10 | 11 | override def run(stgs: List[PStage]): List[PStage] = { 12 | flattenStageList(stgs).foreach { s => 13 | eliminateLockRegions(s) 14 | removeNops(s) 15 | } 16 | stgs 17 | } 18 | 19 | 20 | //Lock No-Ops were introduced by prior passes to track sets of 21 | //possible lock states. They're no longer needed at this point. 22 | private def removeNops(stg: PStage): Unit = { 23 | stg.setCmds(stg.getCmds.foldLeft(List[Command]())((l, c) => c match { 24 | case ICondCommand(cond, cs) => 25 | l :+ ICondCommand(cond, cs.filterNot { 26 | case _: ILockNoOp => true 27 | case _ => false 28 | }) 29 | case ILockNoOp(_) => l 30 | case _ => l :+ c 31 | })) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/pipe-lock-fail1.pdl: -------------------------------------------------------------------------------- 1 | pipe cache(addr: uint<5>, data: int<32>)[dmem: int<32>[5](Queue)]: bool { 2 | //spec_check(); 3 | start(dmem); 4 | int<32> sdata <- dmem[addr]; 5 | //checkpoint(dmem); 6 | reserve(dmem[addr], W); //stupid to put here, but doing it just for the sake of things 7 | end(dmem); 8 | --- 9 | //spec_check(); 10 | wdata = data + sdata; 11 | block(dmem[addr]); 12 | dmem[addr] <- wdata; 13 | release(dmem[addr]); 14 | print("ADDR: %d, DATA: %h", addr, wdata); 15 | --- 16 | //spec_check(); 17 | output(true); 18 | } 19 | 20 | pipe cpu(pc: int<32>)[cache1: cache, imem: int<32>[16]]: bool { 21 | start(imem); 22 | int<32> insn <- imem[cast(pc, uint<16>)]; 23 | end(imem); 24 | 25 | call cpu(pc + 1); 26 | --- 27 | uint<5> addr = cast(insn{31:27}, uint<5>); 28 | 29 | cs <- call cache1(addr, 1<32>); 30 | --- 31 | nextPc = (addr{0:0} == 0) ? pc + 2 : pc + 1; 32 | } 33 | circuit { 34 | ti = memory(int<32>, 16); 35 | td = memory(int<32>, 5); 36 | d = Queue(td); 37 | s = new cache[d]; 38 | c = new cpu[s, ti]; 39 | call c(0<32>); 40 | } -------------------------------------------------------------------------------- /src/test/tests/lockTests/lock-merge-4.pdl: -------------------------------------------------------------------------------- 1 | pipe ex4(in: bool)[rf: int<32>[5](Queue)] :bool{ 2 | start(rf); 3 | uint<5> addr = u1<5>; 4 | reserve(rf[addr],R); 5 | --- 6 | uint<5> addr2 = u2<5>; 7 | bool cond2 = true; 8 | if (cond2) { 9 | reserve(rf[addr2],R); 10 | } 11 | end(rf); 12 | if (in) { 13 | --- 14 | if (in) { 15 | block(rf[addr]); 16 | z <- rf[addr]; 17 | } 18 | --- 19 | if (cond2) { 20 | block(rf[addr2]); 21 | zz <- rf[addr2]; 22 | release(rf[addr2]); 23 | } 24 | --- 25 | } else { 26 | --- 27 | block(rf[addr]); 28 | xx <- rf[addr]; 29 | --- 30 | } 31 | --- 32 | release(rf[addr]); 33 | --- //TODO remove this separation, currently can't compile due to concurrent release w/ only 1 release port 34 | if ((!in) && cond2) { 35 | block(rf[addr2]); 36 | aa <- rf[addr2]; 37 | release(rf[addr2]); 38 | } 39 | int<1> x = 1<1>; 40 | output(in); 41 | } 42 | 43 | circuit { 44 | t1 = memory(int<32>, 5); 45 | r1 = Queue(t1); 46 | e = new ex4[r1]; 47 | call e(true); 48 | } -------------------------------------------------------------------------------- /src/test/scala/pipedsl/LockMergeSuite.scala: -------------------------------------------------------------------------------- 1 | package pipedsl 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | 5 | import java.io.File 6 | 7 | class LockMergeSuite extends AnyFunSuite { 8 | 9 | private val folder = "src/test/tests/lockTests" 10 | private val testFiles = getListOfTests(folder) 11 | private val simFiles = getListOfSims(folder) 12 | private val testFolder = new File(folder) 13 | 14 | testFiles.foreach(t => { 15 | val testBaseName = getTestName(t) 16 | val simFile = getSimFile(testFolder, testBaseName) 17 | 18 | //TODO find a way to only run the right set of tests 19 | //based on whether we expect success or not 20 | /* for now, skip these as they aren't that useful atm. 21 | test((testBaseName + " Parse")) { 22 | testParse(testFolder, t) 23 | }*/ 24 | 25 | test((testBaseName + " Typecheck")) { 26 | testTypecheck(testFolder, t) 27 | } 28 | 29 | 30 | test((testBaseName + " BSV Compile")) { 31 | testBlueSpecCompile(testFolder, t, None, Map()) 32 | } 33 | 34 | if (simFile.exists) { 35 | test((testBaseName + " Simulation")) { 36 | testBlueSpecSim(testFolder, t, None, Map()) 37 | } 38 | } 39 | }) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/pipe-lock-fail2.pdl: -------------------------------------------------------------------------------- 1 | pipe cache(addr: uint<5>, data: int<32>)[dmem: int<32>[5](Queue)]: bool { 2 | //spec_check(); 3 | start(dmem); 4 | int<32> sdata <- dmem[addr]; 5 | //checkpoint(dmem); 6 | reserve(dmem[addr], W); //stupid to put here, but doing it just for the sake of things 7 | end(dmem); 8 | --- 9 | //spec_check(); 10 | wdata = data + sdata; 11 | block(dmem[addr]); 12 | dmem[addr] <- wdata; 13 | release(dmem[addr]); 14 | print("ADDR: %d, DATA: %h", addr, wdata); 15 | --- 16 | //spec_check(); 17 | output(true); 18 | } 19 | 20 | pipe cpu(pc: int<32>)[cache1: cache, imem: int<32>[16]]: bool { 21 | start(imem); 22 | int<32> insn <- imem[cast(pc, uint<16>)]; 23 | end(imem); 24 | start(cache1); 25 | reserve(cache1); 26 | end(cache1); 27 | call cpu(pc + 1); 28 | --- 29 | uint<5> addr = cast(insn{31:27}, uint<5>); 30 | cs <- call cache1(addr, 1<32>); 31 | --- 32 | nextPc = (addr{0:0} == 0) ? pc + 2 : pc + 1; 33 | } 34 | circuit { 35 | ti = memory(int<32>, 16); 36 | td = memory(int<32>, 5); 37 | d = Queue(td); 38 | s = new cache[d]; 39 | c = new cpu[s, ti]; 40 | call c(0<32>); 41 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/type-inference-bit-width-tests.pdl: -------------------------------------------------------------------------------- 1 | 2 | def helper1(a: int<32>, b:bool, c: String): int<32> { 3 | d = a + 1; 4 | f = d + 4; 5 | if (f == d) { 6 | return f; 7 | } else {return d;} 8 | } 9 | 10 | def helper2(a:bool, b: bool): bool { 11 | c = a && b; 12 | return c; 13 | } 14 | 15 | pipe test1(input: int<32>)[rf: int<32>[32]] { 16 | a = 6 * 6<5>; 17 | int<32> b = a; 18 | int<32> c = a + b; 19 | call test1(c); 20 | } 21 | 22 | pipe test2(input: int<32>)[rf: int<32>[32](Queue)] { 23 | a = 1; 24 | start(rf); 25 | b <- rf[a]; 26 | end(rf); 27 | --- 28 | call test2(b); 29 | } 30 | 31 | pipe test3(input: int<32>)[rf: int<32>[32]] { 32 | a = 1<32>; 33 | int<32> b = a << 4; 34 | c = a << 4; 35 | call test3(c); 36 | } 37 | 38 | pipe test4(input: int<32>)[rf: int<32>[32]] { 39 | a = 15<32>; 40 | int<32> b = cast(a{0:8}, int<32>); 41 | call test4(a); 42 | } 43 | 44 | pipe test5()[] { 45 | a = 6 * 6<3>; 46 | int<6> b = a; 47 | int<32> c = helper1(cast(a, int<32>), true, "hi"); 48 | call test5(); 49 | } 50 | 51 | pipe test6()[] { 52 | a = 6 - 6; 53 | int<3> b = a; 54 | call test6(); 55 | } 56 | 57 | circuit { 58 | r = memory(int<32>, 32); 59 | } -------------------------------------------------------------------------------- /src/test/tests/histogram/solutions/histogram_short.parsesol: -------------------------------------------------------------------------------- 1 | pipe hist(counter:int<10>)[feature:int<10>[10],weight:int<32>[10],h:int<32>[10]] { 2 | if ( counter < 1000<10> ) { 3 | call hist(counter + 1<10>); 4 | start(feature); 5 | reserved(feature[counter],R); 6 | acquired(feature[counter],R); 7 | end(feature); 8 | start(weight); 9 | reserved(weight[counter],R); 10 | acquired(weight[counter],R); 11 | end(weight); 12 | int<10> m = feature[counter]; 13 | int<10> mcp = m; 14 | int<32> wt = weight[counter]; 15 | released(feature[counter]); 16 | released(weight[counter]); 17 | start(h); 18 | reserved(h[m],R); 19 | acquired(h[m],R); 20 | reserved(h[mcp],W); 21 | acquired(h[mcp],W); 22 | end(h); 23 | int<32> nm = h[m] + wt; 24 | released(h[m]); 25 | 26 | --- 27 | print(nm); 28 | h[mcp] <- nm; 29 | released(h[mcp]); 30 | 31 | --- 32 | 33 | } else { 34 | output true; 35 | 36 | } 37 | 38 | } 39 | circuit { 40 | f = regfile(int<10>,10); 41 | w = regfile(int<32>,10); 42 | h = regfile(int<32>,10); 43 | hg = new hist[f,w,h]; 44 | call hg(0<10>); 45 | } 46 | -------------------------------------------------------------------------------- /src/test/tests/speculation/spec-write-fail2.pdl: -------------------------------------------------------------------------------- 1 | pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool { 2 | spec_check(); 3 | start(imem); 4 | int<40> insn <- imem[cast(pc, uint<8>)]; 5 | end(imem); 6 | s <- speccall testwrite(pc + 1); 7 | --- 8 | spec_check(); 9 | int<32> data = insn{36:5}; 10 | uint<5> addr = cast(insn{4:0}, uint<5>); 11 | start(rf); 12 | int<32> sdata = rf[addr]; 13 | bool x = true; 14 | if (x) { 15 | checkpoint(rf); //ERROR some speculative paths don't have a checkpoint that need it 16 | } 17 | reserve(rf[addr], W); //stupid to put here, but doing it just for the sake of things 18 | end(rf); 19 | wdata = data + sdata; 20 | --- 21 | spec_check(); 22 | block(rf[addr]); 23 | rf[addr] <- wdata; 24 | --- 25 | spec_barrier(); 26 | 27 | nextPc = (addr{0:0} == 0) ? pc + 2 : pc + 1; 28 | verify(s, nextPc); 29 | print("ADDR: %d, DATA: %h", addr, wdata); 30 | release(rf[addr]); 31 | } 32 | 33 | 34 | 35 | circuit { 36 | ti = memory(int<40>, 8); 37 | rf = regfile(int<32>, 5); 38 | qrf = CheckpointQueue(rf); 39 | t = new testwrite[qrf, ti]; 40 | call t(0<32>); 41 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/more_generic_tests.pdl: -------------------------------------------------------------------------------- 1 | // def error(inpt :int<10>) :bool 2 | // { 3 | // shamt = cast(inpt{4:0}, uint<5>); 4 | // return true; 5 | // } 6 | 7 | // def extract(inpt :uint<32>) :bool 8 | // { 9 | // uint<5> a = inpt{0:4}; 10 | // return true; 11 | // } 12 | 13 | // def iden(a :int) :int 14 | // { 15 | // return a; 16 | // } 17 | 18 | 19 | // def adder(x :int, y :int) :int 20 | // { 21 | // return x + iden(y); 22 | // } 23 | 24 | // def my_concat(a :int, b :int, c :int) :int 25 | // { 26 | // tmp = a ++ b ++ c; 27 | // other = b ++ a ++ c; 28 | // return tmp + other; 29 | // } 30 | 31 | // def indexing(x :int, y :int) :int<5> 32 | // { 33 | // tmp = (x ++ y){4:0}; 34 | // return (x ++ y){4:0}; 35 | // } 36 | 37 | // // def in_scope(x :int, y :int) :int<1> 38 | // // { 39 | // // return x{J:0}; 40 | // // } 41 | 42 | 43 | // def infty(x :int<5>, y :int<5>) :int<10> 44 | // { 45 | // return x ++ y; 46 | // } 47 | 48 | pipe test1(inpt: uint<32>)[rf: int<32>[32]] :int<100> 49 | { 50 | uint<5> a = inpt{0:4}; 51 | //output (adder(3, 4)); 52 | output (4); 53 | } 54 | 55 | 56 | 57 | circuit { 58 | r = memory(int<32>, 32); 59 | } -------------------------------------------------------------------------------- /src/main/scala/pipedsl/common/MemoryInputParser.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.common 2 | 3 | import scala.collection.immutable 4 | import scala.io.Source 5 | 6 | /** 7 | * Parser to parse command line arguments for input test memories. Currently, memory file arguments are in the 8 | * format "($memoryName, $filePath, $memorySize)" 9 | */ 10 | object MemoryInputParser { 11 | 12 | def parse(args: Seq[String]): Map[String, Array[Int]] = { 13 | val memCli= "\\(([a-zA-Z_][a-zA-Z0-9_]*);(.*);(\\d*)\\)".r 14 | var memories = immutable.HashMap[String, Array[Int]]() 15 | for (arg <- args) { 16 | arg match { 17 | case memCli(iden, file, address) => { 18 | val inputFile = Source.fromFile(file).getLines.toArray.map(s => Integer.decode(s).toInt) 19 | val memSize = Math.pow(2, Integer.parseInt(address)).toInt 20 | if (inputFile.length > memSize) { 21 | throw new RuntimeException(s"Size of memory is not big enough for provided memory") 22 | } 23 | val memArray = Array.copyOf(inputFile, memSize) 24 | memories = memories + (iden -> memArray) 25 | } 26 | case _ => throw new RuntimeException(s"Malformed command line arguments") 27 | } 28 | } 29 | memories 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/tests/histogram/solutions/histogram.parsesol: -------------------------------------------------------------------------------- 1 | pipe hist(counter:int<10>)[feature:int<10>[10],weight:int<32>[10],h:int<32>[10]] { 2 | if ( counter < 1000<10> ) { 3 | call hist(counter + 1<10>); 4 | start(feature); 5 | reserved(feature[counter],R); 6 | acquired(feature[counter],R); 7 | end(feature); 8 | start(weight); 9 | reserved(weight[counter],R); 10 | acquired(weight[counter],R); 11 | end(weight); 12 | int<10> m = feature[counter]; 13 | int<32> wt = weight[counter]; 14 | released(feature[counter]); 15 | released(weight[counter]); 16 | 17 | --- 18 | int<10> mcp = m; 19 | start(h); 20 | reserved(h[m],R); 21 | acquired(h[m],R); 22 | reserved(h[mcp],W); 23 | acquired(h[mcp],W); 24 | end(h); 25 | int<32> nm = h[m] + wt; 26 | released(h[m]); 27 | print(nm); 28 | 29 | --- 30 | h[mcp] <- nm; 31 | released(h[mcp]); 32 | 33 | --- 34 | 35 | } else { 36 | output true; 37 | 38 | } 39 | 40 | } 41 | circuit { 42 | f = regfile(int<10>,10); 43 | w = regfile(int<32>,10); 44 | h = regfile(int<32>,10); 45 | hg = new hist[f,w,h]; 46 | call hg(0<10>); 47 | } 48 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/generic_funcs_passz3.pdl: -------------------------------------------------------------------------------- 1 | 2 | def extract(inpt :uint<32>) :bool 3 | { 4 | uint<5> a = inpt{4:0}; 5 | return true; 6 | } 7 | 8 | def iden(a :int) :int 9 | { 10 | return a; 11 | } 12 | 13 | 14 | def adder(x :int, y :int) :int 15 | { 16 | return x + iden(y); 17 | } 18 | 19 | def my_concat(a :int, b :int, c :int) :int 20 | { 21 | tmp = a ++ b ++ c; 22 | other = b ++ a ++ c; 23 | return tmp + other; 24 | } 25 | 26 | def indexing(x :int, y :int) :int<5> 27 | { 28 | tmp = (x ++ y){4:0}; 29 | return (x ++ y){4:0}; 30 | } 31 | 32 | def in_scope(x :int, y :int) :int 33 | { 34 | int z = x{J - 1:0}; 35 | q = x{I - 1:0}; 36 | return z; 37 | } 38 | 39 | 40 | def test_in_scope(x :int<6>, y :int<3>) :int<3> 41 | { 42 | return in_scope(x, y); 43 | } 44 | 45 | def infty(x :int<5>, y :int<5>) :int<10> 46 | { 47 | return x ++ y; 48 | } 49 | 50 | pipe test1(inpt: uint<32>)[rf: int<32>[32]] :int<100> 51 | { 52 | uint<5> a = inpt{4:0}; 53 | output (adder(3, 4)); 54 | 55 | } 56 | 57 | pipe test2(inpt :int<3>)[] :int<5> 58 | { 59 | tmp = indexing(inpt, inpt); 60 | output(tmp); 61 | } 62 | 63 | 64 | circuit { 65 | r = memory(int<32>, 32); 66 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/pipe-lock.pdl: -------------------------------------------------------------------------------- 1 | pipe cache(addr: uint<5>, data: int<32>)[dmem: int<32>[5](Queue)]: bool { 2 | //spec_check(); 3 | start(dmem); 4 | int<32> sdata <- dmem[addr]; 5 | //checkpoint(dmem); 6 | reserve(dmem[addr], W); //stupid to put here, but doing it just for the sake of things 7 | end(dmem); 8 | --- 9 | //spec_check(); 10 | wdata = data + sdata; 11 | block(dmem[addr]); 12 | dmem[addr] <- wdata; 13 | release(dmem[addr]); 14 | print("ADDR: %d, DATA: %h", addr, wdata); 15 | --- 16 | //spec_check(); 17 | output(true); 18 | } 19 | 20 | pipe cpu(pc: int<32>)[cache1: cache, imem: int<32>[16]]: bool { 21 | start(imem); 22 | int<32> insn <- imem[cast(pc, uint<16>)]; 23 | end(imem); 24 | 25 | call cpu(pc + 1); 26 | 27 | start(cache1); 28 | reserve(cache1); 29 | end(cache1); 30 | --- 31 | uint<5> addr = cast(insn{31:27}, uint<5>); 32 | 33 | block(cache1); 34 | cs <- call cache1(addr, 1<32>); 35 | release(cache1); 36 | --- 37 | nextPc = (addr{0:0} == 0) ? pc + 2 : pc + 1; 38 | } 39 | circuit { 40 | ti = memory(int<32>, 16); 41 | td = memory(int<32>, 5); 42 | d = Queue(td); 43 | s = new cache[d]; 44 | c = new cpu[s, ti]; 45 | call c(0<32>); 46 | } -------------------------------------------------------------------------------- /src/test/tests/autocastTests/type-inference-bit-width-tests.pdl: -------------------------------------------------------------------------------- 1 | 2 | def helper1(a: int<32>, b:bool, c: String): int<32> { 3 | d = a + 1; 4 | f = d + 4; 5 | if (f == d) { 6 | return f; 7 | } else {return d;} 8 | } 9 | 10 | def helper2(a:bool, b: bool): bool { 11 | c = a && b; 12 | return c; 13 | } 14 | 15 | pipe test1(input: int<32>)[rf: int<32>[32]] { 16 | a = 6 * 6<10>; 17 | int<32> b = a; 18 | int<32> c = a + b; 19 | call test1(c); 20 | } 21 | 22 | pipe test2(input: int<32>)[rf: int<32>[32](Queue)] { 23 | a = 1; 24 | start(rf); 25 | reserve(rf[a]); 26 | --- 27 | block(rf[a]); 28 | b <- rf[a]; 29 | release(rf[a]); 30 | end(rf); 31 | --- 32 | call test2(b); 33 | } 34 | 35 | pipe test3(input: int<32>)[rf: int<32>[32]] { 36 | a = 1<32>; 37 | int<32> b = a << 4; 38 | c = a << 4; 39 | call test3(c); 40 | } 41 | 42 | pipe test4(input: int<32>)[rf: int<32>[32]] { 43 | a = 15<32>; 44 | int<32> b = cast(a{0:8}, int<32>); 45 | call test4(a); 46 | } 47 | 48 | pipe test5()[] { 49 | a = 6 * 6<5>; 50 | int<6> b = a; 51 | int<32> c = helper1(cast(a, int<32>), true, "hi"); 52 | call test5(); 53 | } 54 | 55 | pipe test6()[] { 56 | a = 6 - 6; 57 | int<3> b = a; 58 | call test6(); 59 | } 60 | 61 | circuit { 62 | r = memory(int<32>, 32); 63 | } -------------------------------------------------------------------------------- /src/test/tests/lockTests/solutions/lock-merge-3.parsesol: -------------------------------------------------------------------------------- 1 | pipe ex4(inarg:int<32>)[rf:int<32>[5]] { 2 | start(rf); 3 | int<5> a1 = 0<5>; 4 | int<5> a2 = 1<5>; 5 | bool b1 = cast(inarg{0:0} == 1<1>,bool); 6 | bool b2 = cast(inarg{1:1} == 1<1>,bool); 7 | reserved(rf[a2],R); 8 | 9 | --- 10 | if ( b1 ) { 11 | reserved(rf[a1],R); 12 | 13 | } else { 14 | reserved(rf[a1],R); 15 | 16 | } 17 | end(rf); 18 | if ( b1 ) { 19 | acquired(rf[a1]); 20 | int<32> x <- rf[a1]; 21 | if ( b2 ) { 22 | released(rf[a1]); 23 | 24 | } else { 25 | 26 | } 27 | 28 | } else { 29 | 30 | } 31 | 32 | --- 33 | if ( b1 ) { 34 | acquired(rf[a2]); 35 | int<32> y <- rf[a2]; 36 | 37 | } else { 38 | acquired(rf[a2]); 39 | int<32> y <- rf[a2]; 40 | 41 | } 42 | released(rf[a2]); 43 | 44 | --- 45 | if ( b1 && !b2 ) { 46 | released(rf[a1]); 47 | 48 | } else { 49 | 50 | } 51 | if ( !b1 ) { 52 | acquired(rf[a1]); 53 | int<32> z <- rf[a1]; 54 | released(rf[a1]); 55 | 56 | } else { 57 | 58 | } 59 | 60 | } 61 | circuit { 62 | r = memory(int<32>,5); 63 | e = new ex4[r]; 64 | call e(1<32>); 65 | } 66 | -------------------------------------------------------------------------------- /src/test/tests/histogram/solutions/histogram_bram.parsesol: -------------------------------------------------------------------------------- 1 | pipe hist(counter:int<10>)[feature:int<10>[10],weight:int<32>[10],h:int<32>[10]] { 2 | if ( counter < 1000<10> ) { 3 | call hist(counter + 1<10>); 4 | start(feature); 5 | reserved(feature[counter],R); 6 | acquired(feature[counter],R); 7 | end(feature); 8 | start(weight); 9 | reserved(weight[counter],R); 10 | acquired(weight[counter],R); 11 | end(weight); 12 | int<10> m <- feature[counter]; 13 | int<32> wt <- weight[counter]; 14 | released(feature[counter]); 15 | released(weight[counter]); 16 | 17 | --- 18 | int<10> mcp = m; 19 | start(h); 20 | reserved(h[m],R); 21 | acquired(h[m],R); 22 | reserved(h[mcp],W); 23 | acquired(h[mcp],W); 24 | end(h); 25 | int<32> oldh <- h[m]; 26 | released(h[m]); 27 | 28 | --- 29 | int<32> nm = oldh + wt; 30 | print(nm); 31 | h[mcp] <- nm; 32 | released(h[mcp]); 33 | 34 | --- 35 | 36 | } else { 37 | output true; 38 | 39 | } 40 | 41 | } 42 | circuit { 43 | f = memory(int<10>,10); 44 | w = memory(int<32>,10); 45 | h = memory(int<32>,10); 46 | hg = new hist[f,w,h]; 47 | call hg(0<10>); 48 | } 49 | -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-success-read-write-order.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe test3(input: uint<32>)[rf: int<32>[5](RenameRF), m:int<32>[5](RenameRF)] { 3 | uint<5> rs1 = input{4:0}; 4 | uint<5> rs2 = input{9:5}; 5 | start(rf); 6 | start(m); 7 | reserve(rf[rs1],R); 8 | reserve(rf[rs2],W); 9 | reserve(m[rs1], R); 10 | end(m); 11 | end(rf); 12 | --- 13 | block(rf[rs1]); 14 | block(rf[rs2]); 15 | rf[rs2] <- rf[rs1]; 16 | block(m[rs1]); 17 | y = m[rs1]; 18 | --- 19 | release(rf[rs1]); 20 | release(rf[rs2]); 21 | release(m[rs1]); 22 | call test3(input); 23 | } 24 | 25 | //Tests that modules are analyzed separately 26 | pipe test4(input: uint<32>)[rf: int<32>[5](RenameRF), m:int<32>[5](RenameRF)] :bool { 27 | uint<5> rs1 = input{4:0}; 28 | uint<5> rs2 = input{9:5}; 29 | start(rf); 30 | start(m); 31 | acquire(rf[rs1],R); 32 | reserve(rf[rs2],W); 33 | acquire(m[rs1], R); 34 | end(m); 35 | end(rf); 36 | --- 37 | block(rf[rs2]); 38 | rf[rs2] <- rf[rs1]; 39 | y = m[rs1]; 40 | release(rf[rs1]); 41 | release(rf[rs2]); 42 | release(m[rs1]); 43 | output(true); 44 | --- 45 | } 46 | 47 | circuit { 48 | r = memory(int<32>, 5); 49 | m = memory(int<32>, 5); 50 | } -------------------------------------------------------------------------------- /src/test/tests/histogram/histogram_short.pdl: -------------------------------------------------------------------------------- 1 | /* 2 | n = 128 3 | void histogram ( int feature [] , float weight [] , float hist [] , int n ) { 4 | for (int i =0; i < n ; ++ i ) { 5 | int m = feature [ i ]; 6 | float wt = weight [ i ]; 7 | float x = hist [ m ]; 8 | hist [ m ] = x + wt ; 9 | } 10 | } 11 | */ 12 | 13 | pipe hist(counter: uint<10>)[feature: uint<16>[10], weight: uint<32>[10], h: uint<32>[10](FAQueue)]: bool { 14 | bool done = counter >= u1000<10>; 15 | if (!done) { 16 | call hist(counter + u1<10>); 17 | start(feature); 18 | uint<16> m = feature[counter]; 19 | end(feature); 20 | uint<10> m1 = m{9:0}; 21 | uint<10> mcp = m{9:0}; 22 | start(weight); 23 | uint<32> wt = weight[counter]; 24 | end(weight); 25 | start(h); 26 | reserve(h[mcp]); 27 | uint<32> nm = h[m1] + wt; 28 | end(h); 29 | --- 30 | print(nm); 31 | block(h[mcp]); 32 | h[mcp] <- nm; 33 | release(h[mcp]); 34 | --- 35 | } 36 | if (done) { 37 | output(true); 38 | } 39 | } 40 | 41 | circuit { 42 | tf = regfile(uint<16>, 10); 43 | tw = regfile(uint<32>, 10); 44 | th = regfile(uint<32>, 10); 45 | h = FAQueue(th); 46 | hg = new hist[tf, tw, h]; 47 | call hg(u0<10>); 48 | } -------------------------------------------------------------------------------- /docs/inference.md: -------------------------------------------------------------------------------- 1 | # Type inference 2 | 3 | This document describes what you can and can't expect from the type inference 4 | engine. 5 | 6 | # Implicit casting 7 | Implicit casting could be confusing to the programmer, so it is disabled by 8 | default. The "autocast" commandline option enables it, in which cast casts 9 | to higher bitwidths will be automatically inserted 10 | 11 | # Constants 12 | 13 | Integer constant types have two components: the bit width and the 14 | signedness. You can specify the signedness with a `u` in front of the constant, 15 | and the width is specified with angle brackets after. So if you want to write 16 | the number four as an unsigned, 16 bit number, it would be `u4<16>` 17 | 18 | You do not have to specify these types, as they can be inferred. However, if you 19 | have a multiplication of constants, one of them will need to be annotated 20 | 21 | # Generics 22 | 23 | You can parameterize both external modules as well as functions on named 24 | types. You can write down expressions in type variables, though for now the only 25 | supported operation is addition. To do this, the type variables you want to use 26 | are placed in java style <> before the arguments. These type variables 27 | necessarily are always bit widths, and can be referenced in the function body in 28 | other types. They will soon be allowed to be used in bit indexing expressions. 29 | -------------------------------------------------------------------------------- /src/test/tests/histogram/histogram_bram.pdl: -------------------------------------------------------------------------------- 1 | /* 2 | n = 128 3 | void histogram ( int feature [] , float weight [] , float hist [] , int n ) { 4 | for (int i =0; i < n ; ++ i ) { 5 | int m = feature [ i ]; 6 | float wt = weight [ i ]; 7 | float x = hist [ m ]; 8 | hist [ m ] = x + wt ; 9 | } 10 | } 11 | */ 12 | 13 | pipe hist(counter: uint<10>)[feature: uint<16>[10], weight: uint<32>[10], h: uint<32>[10](FAQueue)]: bool { 14 | bool done = counter >= u1000<10>; 15 | if (!done) { 16 | call hist(counter + u1<10>); 17 | start(feature); 18 | start(weight); 19 | uint<16> m <- feature[counter]; 20 | uint<32> wt <- weight[counter]; 21 | end(feature); 22 | end(weight); 23 | --- 24 | uint<10> m1 = m{9:0}; 25 | uint<10> mcp = m{9:0}; 26 | 27 | start(h); 28 | reserve(h[mcp]); 29 | uint<32> oldh <- h[m1]; 30 | end(h); 31 | --- 32 | uint<32> nm = oldh + wt; 33 | print(nm); 34 | block(h[mcp]); 35 | h[mcp] <- nm; 36 | release(h[mcp]); 37 | --- 38 | } 39 | 40 | if (done) { 41 | output(true); 42 | } 43 | } 44 | 45 | circuit { 46 | tf = memory(uint<16>, 10); 47 | tw = memory(uint<32>, 10); 48 | th = memory(uint<32>, 10); 49 | h = FAQueue(th); 50 | hg = new hist[tf, tw, h]; 51 | call hg(u0<10>); 52 | } -------------------------------------------------------------------------------- /src/test/tests/histogram/histogram_bram2.pdl: -------------------------------------------------------------------------------- 1 | /* 2 | n = 128 3 | void histogram ( int feature [] , float weight [] , float hist [] , int n ) { 4 | for (int i =0; i < n ; ++ i ) { 5 | int m = feature [ i ]; 6 | float wt = weight [ i ]; 7 | float x = hist [ m ]; 8 | hist [ m ] = x + wt ; 9 | } 10 | } 11 | */ 12 | 13 | pipe hist(counter: uint<10>)[feature: uint<16>[10], weight: uint<32>[10], h: uint<32>[10](FAQueue)]: bool { 14 | bool done = counter >= u1000<10>; 15 | if (!done) { 16 | call hist(counter + u1<10>); 17 | start(feature); 18 | start(weight); 19 | uint<16> m <- feature[counter]; 20 | uint<32> wt <- weight[counter]; 21 | end(feature); 22 | end(weight); 23 | --- 24 | uint<10> m1 = m{9:0}; 25 | uint<10> mcp = m{9:0}; 26 | 27 | start(h); 28 | uint<32> oldh <- h[m1]; 29 | reserve(h[mcp]); 30 | end(h); 31 | --- 32 | uint<32> nm = oldh + wt; 33 | print(nm); 34 | block(h[mcp]); 35 | h[mcp] <- nm; 36 | release(h[mcp]); 37 | --- 38 | } 39 | 40 | if (done) { 41 | output(true); 42 | } 43 | } 44 | 45 | circuit { 46 | tf = memory(uint<16>, 10); 47 | tw = memory(uint<32>, 10); 48 | th = memory(uint<32>, 10, 2); 49 | h = FAQueue(th); 50 | hg = new hist[tf, tw, h]; 51 | call hg(u0<10>); 52 | } -------------------------------------------------------------------------------- /src/test/tests/histogram/histogram.pdl: -------------------------------------------------------------------------------- 1 | /* 2 | n = 128 3 | void histogram ( int feature [] , float weight [] , float hist [] , int n ) { 4 | for (int i =0; i < n ; ++ i ) { 5 | int m = feature [ i ]; 6 | float wt = weight [ i ]; 7 | float x = hist [ m ]; 8 | hist [ m ] = x + wt ; 9 | } 10 | } 11 | */ 12 | 13 | 14 | pipe hist(counter: uint<10>)[feature: uint<16>[10](FAQueue), weight: uint<32>[10](FAQueue), h: uint<32>[10](FAQueue)]: bool { 15 | bool done = counter >= u1000<10>; 16 | if (!done) { 17 | call hist(counter + u1<10>); 18 | start(feature); 19 | start(weight); 20 | uint<16> m = feature[counter]; 21 | uint<10> m1 = m{9:0}; 22 | uint<32> wt = weight[counter]; 23 | end(feature); 24 | end(weight); 25 | --- 26 | uint<10> mcp = m1; 27 | start(h); 28 | uint<32> nm = h[m1] + wt; 29 | reserve(h[mcp]); 30 | end(h); 31 | print(nm); 32 | --- 33 | block(h[mcp]); 34 | h[mcp] <- nm; 35 | release(h[mcp]); 36 | --- 37 | } 38 | 39 | if (done) { 40 | output(true); 41 | } 42 | } 43 | 44 | circuit { 45 | tf = regfile(uint<16>, 10); 46 | f = FAQueue(tf); 47 | tw = regfile(uint<32>, 10); 48 | w = FAQueue(tw); 49 | th = regfile(uint<32>, 10); 50 | h = FAQueue(th); 51 | hg = new hist[f, w, h]; 52 | call hg(u0<10>); 53 | } -------------------------------------------------------------------------------- /bscRuntime/verilog/Makefile: -------------------------------------------------------------------------------- 1 | LABNAME = Stages Stuff 2 | 3 | BSC=bsc -no-show-timestamps -no-show-version --aggressive-conditions 4 | BMOD=VerilogLibs 5 | B_IN=$(BMOD).bsv 6 | B_LIB=$(BMOD).bo 7 | B_SIM=tb.bsv 8 | OUT=Top 9 | 10 | ## Default simulator is iverilog 11 | VSIM = -vsim iverilog 12 | 13 | ifdef cvc 14 | VSIM = -vsim cvc 15 | endif 16 | 17 | ifdef vcs 18 | VSIM = -vsim vcs 19 | endif 20 | 21 | ifdef vcsi 22 | VSIM = -vsim vcsi 23 | endif 24 | 25 | ifdef ncverilog 26 | VSIM = -vsim ncverilog 27 | endif 28 | 29 | ifdef ncsim 30 | VSIM = -vsim ncsim 31 | endif 32 | 33 | ifdef modelsim 34 | VSIM = -vsim modelsim 35 | endif 36 | 37 | 38 | $(B_LIB): $(B_IN) 39 | $(BSC) -show-schedule $< 40 | 41 | verilog: mk$O(UT).v 42 | 43 | %.v: %.bsv 44 | $(BSC) -show-schedule -verilog $< 45 | 46 | mk$(OUT).v: $(B_IN) 47 | $(BSC) -show-schedule -verilog $(B_IN) 48 | 49 | .PHONY: sim 50 | sim: $(B_LIB) $(B_SIM) 51 | 52 | $(BSC) -show-schedule $(DEBUG) $(VSIM) $(B_SIM) 53 | $(BSC) $(DEBUG) -verilog -e mk$(OUT) -o mk$(OUT).bexe 54 | # $(BSC) $(VSIM) -o mk$(OUT).bexe -e mk$(OUT) mk$(OUT).ba 55 | ./mk$(OUT).bexe +bscvcd > smoke_test_bluesim.out 56 | 57 | .PHONY: clean 58 | clean: 59 | @rm -f *.bi *.bo *.ba 60 | @rm -f *.cxx *.h *.o *.so *.bexe 61 | @rm -f mkTop.v 62 | @rm -f *.vexe 63 | @rm -f *.vcd *~ *.fsdb *.log 64 | @rm -f *.sched 65 | @rm -f smoke_test_verilog.out smoke_test_bluesim.out 66 | @rm -rf csrc INCA_libs simv.daidir vfastLog/ nWaveLog/ work_mkFibOne/ 67 | 68 | -------------------------------------------------------------------------------- /src/test/scala/pipedsl/RiscSuite.scala: -------------------------------------------------------------------------------- 1 | package pipedsl 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | 5 | import java.io.File 6 | 7 | class RiscSuite extends AnyFunSuite { 8 | private val folder = "src/test/tests/risc-pipe" 9 | private val testFiles = getListOfTests(folder) 10 | private val testFolder = new File(folder) 11 | 12 | private val inputFolder = folder + "/memInputs" 13 | private val inputRF = inputFolder + "/rf" 14 | private val inputIMEM = inputFolder + "/ti" 15 | private val inputDMEM = inputFolder + "/td" 16 | private val inputCmem = inputFolder + "/cmem" 17 | private val mainMem = inputFolder + "/mm" 18 | 19 | private def getInputMap(s: String): Map[String, String] = { 20 | Map("rf" -> inputRF, "ti" -> (inputIMEM + s), "td" -> (inputDMEM + s), "cmem" -> inputCmem, 21 | "mm" -> (mainMem +s) ) 22 | } 23 | 24 | private val sims = getListOfSims(folder).map(s => getTestName(s)) 25 | 26 | //For each processor impl 27 | testFiles.foreach(t => { 28 | val testBaseName = getTestName(t) 29 | test(testBaseName + " Typecheck") { 30 | testTypecheck(testFolder, t) 31 | } 32 | test(testBaseName + " BSV Compile") { 33 | testBlueSpecCompile(testFolder, t, None, Map()) 34 | } 35 | //For each program 36 | sims.foreach(s => { 37 | val simInputs = getInputMap(s) 38 | test(testBaseName + " Simulate " + s) { 39 | testBlueSpecSim(testFolder, t, None, simInputs, Some(s + ".simsol")) 40 | } 41 | }) 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /src/test/tests/speculation/spec-write-fail3.pdl: -------------------------------------------------------------------------------- 1 | pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool { 2 | spec_check(); 3 | start(imem); 4 | int<40> insn <- imem[cast(pc, uint<8>)]; 5 | end(imem); 6 | s <- speccall testwrite(pc + 1); 7 | --- 8 | spec_check(); 9 | bool x = pc == 1; 10 | --- 11 | spec_check(); 12 | int<32> data = insn{36:5}; 13 | uint<5> addr = cast(insn{4:0}, uint<5>); 14 | start(rf); 15 | int<32> sdata = rf[addr]; 16 | checkpoint(rf); //ERROR checkpoint is made even on NONSPEC paths (i.e., when !x) 17 | //TODO allow these and generate the right logic to release along those paths 18 | reserve(rf[addr], W); //stupid to put here, but doing it just for the sake of things 19 | end(rf); 20 | wdata = data + sdata; 21 | if (x) { invalidate(s); } 22 | --- 23 | spec_check(); 24 | block(rf[addr]); 25 | rf[addr] <- wdata; 26 | --- 27 | spec_barrier(); 28 | 29 | nextPc = (addr{0:0} == 0) ? pc + 2 : pc + 1; 30 | if (!x) { 31 | verify(s, nextPc); 32 | } else { 33 | call testwrite(nextPc); 34 | } 35 | print("ADDR: %d, DATA: %h", addr, wdata); 36 | release(rf[addr]); 37 | } 38 | 39 | 40 | 41 | circuit { 42 | ti = memory(int<40>, 8); 43 | rf = regfile(int<32>, 5); 44 | qrf = CheckpointQueue(rf); 45 | t = new testwrite[qrf, ti]; 46 | call t(0<32>); 47 | } -------------------------------------------------------------------------------- /src/test/tests/speculation/3-stg-pipe.pdl: -------------------------------------------------------------------------------- 1 | pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool { 2 | start(imem); 3 | int<32> insn <- imem[cast(pc, uint<8>)]; 4 | end(imem); 5 | --- 6 | if (insn{31:31} != 1<1>) { 7 | --- 8 | int<1> op = insn{0:0}; 9 | int<8> brImm = 0<4> ++ insn{4:1}; 10 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 11 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 12 | uint<5> rd = cast(insn{19:15}, uint<5>); 13 | 14 | if (op == 0<1>) { 15 | call cpu(pc + 1<8>); 16 | } 17 | start(rf); 18 | reserve(rf[rs1], R); 19 | reserve(rf[rs2], R); 20 | if (op == 0<1>) { 21 | reserve(rf[rd], W); 22 | } 23 | end(rf); 24 | --- 25 | block(rf[rs1]); 26 | block(rf[rs2]); 27 | if (op != 0<1>) { 28 | int<8> npc = (rf[rs1] == rf[rs2]) ? (pc + brImm) : (pc + 1<8>); 29 | print(npc); 30 | call cpu(npc); 31 | } 32 | int<32> out = rf[rs1] + rf[rs2]; 33 | release(rf[rs1]); 34 | release(rf[rs2]); 35 | --- 36 | if (op == 0<1>) { 37 | block(rf[rd]); 38 | print(out); 39 | rf[rd] <- out; 40 | release(rf[rd]); 41 | } 42 | } else { 43 | output(true); 44 | } 45 | } 46 | 47 | circuit { 48 | rename = rflock(int<32>, 5, 128); 49 | ti = memory(int<32>, 8); 50 | t = new cpu[rename,ti]; 51 | call t(0<8>); 52 | } -------------------------------------------------------------------------------- /src/main/scala/pipedsl/typechecker/CheckpointChecker.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.typechecker 2 | 3 | import com.microsoft.z3.{AST => Z3AST, BoolExpr => Z3BoolExpr, Context => Z3Context, Solver => Z3Solver, Status => Z3Status} 4 | import pipedsl.common.Syntax 5 | import pipedsl.common.Syntax.Id 6 | import pipedsl.typechecker.Environments.ConditionalEnv 7 | import pipedsl.typechecker.TypeChecker.TypeChecks 8 | 9 | /** 10 | * This class checks that checkpoints are instantiated in the correct context. 11 | * - If a pipeline may speculatively reserve locks, then it must have a checkpoint for that memory. 12 | * - Checkpoints must be instantiated in the context in which they are used (i.e., with the necessary branch conditions) 13 | * - Checkpoints must be resolved by some Verify or Invalidate 14 | * @param ctx 15 | */ 16 | class CheckpointChecker(val ctx: Z3Context) extends TypeChecks[Id, Z3AST] { 17 | 18 | override def emptyEnv(): Environments.Environment[Id, Z3AST] = ConditionalEnv(ctx = ctx) 19 | 20 | override def checkExt(e: Syntax.ExternDef, env: Environments.Environment[Id, Z3AST]): Environments.Environment[Id, Z3AST] = ??? 21 | 22 | override def checkFunc(f: Syntax.FuncDef, env: Environments.Environment[Id, Z3AST]): Environments.Environment[Id, Z3AST] = ??? 23 | 24 | override def checkModule(m: Syntax.ModuleDef, env: Environments.Environment[Id, Z3AST]): Environments.Environment[Id, Z3AST] = ??? 25 | 26 | override def checkCircuit(c: Syntax.Circuit, env: Environments.Environment[Id, Z3AST]): Environments.Environment[Id, Z3AST] = ??? 27 | } 28 | -------------------------------------------------------------------------------- /src/resources/grammar.txt: -------------------------------------------------------------------------------- 1 | Function 2 | = id:ID _ "(" _ p:Params _ ")"_ "{" 3 | _ b:Body _ 4 | "}" { return { "name": id, "params": p, "body": b}; } 5 | 6 | Params 7 | = id:ID _ "," _ p:Params { p.unshift(id); return p; } 8 | / id:ID { return [id]; } 9 | Body 10 | = s:Statement "\n" m:Body { m.unshift(s); return m; } 11 | / s:Statement { return [s]; } 12 | 13 | Statement 14 | = _ c:Connect ";" { return c; } 15 | / _ r:Run ";" { return r; } 16 | / _ r:Ret ";" { return r; } 17 | 18 | Connect 19 | = dest:ID _ "<=" _ src:Expr { return dest + " := " + src; } 20 | 21 | Run 22 | = "run" _ c:Call { return "run " + c; } 23 | 24 | Ret 25 | = "ret" _ c:Call { return "return " + c; } 26 | 27 | Call 28 | = id:ID "(" _ e:ExprList _ ")" { return "call " + id + " with " + e; } 29 | 30 | ExprList 31 | = e:Expr _ "," _ p:ExprList { p.unshift(e); return p; } 32 | / el:Expr { return [el]; } 33 | 34 | Expr 35 | = b:Binop { return b; } 36 | / c:Call { return c; } 37 | / l:LHS { return l; } 38 | 39 | LHS 40 | = "(" i:Expr ")" { return i; } 41 | / i:ID { return i; } 42 | / i:Integer { return i; } 43 | 44 | Binop 45 | = lhs: LHS _ "+" _ rhs: Expr { return "(" + lhs + " + " + rhs + ")"; } 46 | / lhs: LHS _ "&" _ rhs: Expr { return "(" + lhs + " and " + rhs + ")" ; } 47 | / lhs: LHS _ "|" _ rhs: Expr { return "(" + lhs + " or " + rhs + ")"; } 48 | 49 | ID "identifier" 50 | = [a-zA-Z][a-zA-Z0-9]* { return text(); } 51 | 52 | Integer "integer" 53 | = [0-9]+ { return parseInt(text(), 10); } 54 | 55 | _ "whitespace" 56 | = [ \t\n\r]* 57 | -------------------------------------------------------------------------------- /docs/lock-lang.md: -------------------------------------------------------------------------------- 1 | # Language Level Locking 2 | 3 | This document covers how locks are presented in the language and the static analyses 4 | we're going to use to supplement typechecking. This document *does not cover* 5 | the _runtime implementation_ of locks. 6 | 7 | ## Locks as a Transaction Implementation 8 | 9 | In transactions, conflicts are found via interesctions of _read_ and _write_ sets. 10 | We can view lock acquisition in our language similarly: each thread will acquire some set of locks 11 | associated with the locations that it is reading and writing. 12 | 13 | We need to ensure that each thread gets to acquire _all_ of the locks in its read/write set before 14 | another thread starts to acquire locks in *its* read/write set. 15 | 16 | The following program snippet shows where this can go wrong: 17 | 18 | ``` 19 | acquire(rf[x]); 20 | --- 21 | acquire(rf[y]); 22 | ``` 23 | 24 | We can get an execution trace that looks like: `acq(rf[0], t0), acq(rf[1], t1), acq(rf[1], t0)` 25 | where `x = 0, y = 1` in `t0` and `x = 1, y = ?` in `t1`. 26 | 27 | In this case, we see a deadlock happen; in other cases we might actually not deadlock but 28 | have writes be missed or have an incorrectly linearized execution. 29 | 30 | ### Ensuring Atomcity of Transaction Set Acquisition 31 | 32 | We can introduce _another layer of locking_ to ensure that threads don't interleave 33 | their locking operations. This lock must be acquired in order to _reserve_ address specific 34 | locks. 35 | 36 | ``` 37 | start(rf); 38 | acquire(rf[x]); 39 | --- 40 | acquire(rf[y]); 41 | end(rf); 42 | ``` 43 | -------------------------------------------------------------------------------- /src/test/tests/speculation/unnecessary-checkpoint.pdl: -------------------------------------------------------------------------------- 1 | pipe cpu(pc: int<8>)[rf: int<32>[5](CheckpointRF), imem: int<32>[8]]: bool { 2 | start(imem); 3 | int<32> insn <- imem[cast(pc, uint<8>)]; 4 | end(imem); 5 | --- 6 | if (insn{31:31} != 1<1>) { 7 | --- 8 | int<1> op = insn{0:0}; 9 | int<8> brImm = 0<4> ++ insn{4:1}; 10 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 11 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 12 | uint<5> rd = cast(insn{19:15}, uint<5>); 13 | 14 | if (op == 0<1>) { 15 | call cpu(pc + 1<8>); 16 | } 17 | start(rf); 18 | checkpoint(rf); 19 | reserve(rf[rs1], R); 20 | reserve(rf[rs2], R); 21 | if (op == 0<1>) { 22 | reserve(rf[rd], W); 23 | } 24 | end(rf); 25 | --- 26 | block(rf[rs1]); 27 | block(rf[rs2]); 28 | if (op != 0<1>) { 29 | int<8> npc = (rf[rs1] == rf[rs2]) ? (pc + brImm) : (pc + 1<8>); 30 | print(npc); 31 | call cpu(npc); 32 | } 33 | int<32> out = rf[rs1] + rf[rs2]; 34 | release(rf[rs1]); 35 | release(rf[rs2]); 36 | --- 37 | if (op == 0<1>) { 38 | block(rf[rd]); 39 | print(out); 40 | rf[rd] <- out; 41 | release(rf[rd]); 42 | } 43 | } else { 44 | output(true); 45 | } 46 | } 47 | 48 | circuit { 49 | rename = rflock CheckpointRF(int<32>, 5, 128); 50 | ti = memory(int<32>, 8); 51 | t = new cpu[rename,ti]; 52 | call t(0<8>); 53 | } -------------------------------------------------------------------------------- /src/main/scala/pipedsl/typechecker/TypeChecker.scala: -------------------------------------------------------------------------------- 1 | package pipedsl.typechecker 2 | 3 | import pipedsl.common.Syntax._ 4 | import Environments.Environment 5 | 6 | object TypeChecker { 7 | 8 | trait TypeChecks[U, T] { 9 | 10 | def emptyEnv(): Environment[U, T] 11 | 12 | /** 13 | * Given a program and an optional current envrionment mapping IDs to some type 14 | * information [[T]], check the program in that environment and 15 | * produce a new type environment 16 | * @param p The program to check 17 | * @param env The current type environment 18 | * @return The new type environment 19 | */ 20 | def check(p: Prog, env: Option[Environment[U, T]]): Environment[U, T] = { 21 | val Prog(edefs, fdefs, mdefs, cir) = p 22 | val senv = env match { case Some(e) => e; case None => emptyEnv() } 23 | val eenv = edefs.foldLeft[Environment[U, T]](senv)((tenv, edef) => { 24 | checkExt(edef, tenv) 25 | }) 26 | val fenv = fdefs.foldLeft[Environment[U, T]](eenv)((tenv, fdef) => { 27 | checkFunc(fdef, tenv) 28 | }) 29 | val menv = mdefs.foldLeft[Environment[U, T]](fenv)((tenv, mdef) => { 30 | checkModule(mdef, tenv) 31 | }) 32 | checkCircuit(cir, menv) 33 | } 34 | 35 | def checkExt(e: ExternDef, env:Environment[U, T]): Environment[U, T] 36 | 37 | def checkFunc(f: FuncDef, env:Environment[U, T]): Environment[U, T] 38 | 39 | def checkModule(m: ModuleDef, env: Environment[U, T]): Environment[U, T] 40 | 41 | def checkCircuit(c: Circuit, env: Environment[U, T]): Environment[U, T] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/scala/pipedsl/util/memFileGen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec scala "$0" "$@" 3 | !# 4 | 5 | import java.io.{BufferedWriter, File, FileWriter} 6 | 7 | 8 | object GenTestFiles { 9 | def main(args: Array[String]) { 10 | val fileName = args(0) 11 | //size of the address in bits 12 | val memAddrSize = args(1) 13 | //size of the contents of memory in bits 14 | val memType = args(2) 15 | //random or constant or range 16 | val genType = args(3) 17 | val file = new File(fileName) 18 | val bw = new BufferedWriter(new FileWriter(file)) 19 | val r = scala.util.Random 20 | //Max possible value that the int can be + 1 21 | val maxInt = if(args.size == 5) args(4).toLong else scala.math.pow(2, memType.toInt).asInstanceOf[Long] 22 | val str = new StringBuilder() 23 | var a = 0; 24 | val hexDigits = memType.toInt / 4 + (if(memType.toInt % 4 == 0) 0 else 1) 25 | //max possible address + 1 26 | val maxMem = scala.math.pow(2, memAddrSize.toInt).asInstanceOf[Long] 27 | var counter = 0L 28 | while (a < maxMem) { 29 | if (genType.equals("rand")) str.addAll(r.nextLong(maxInt).toHexString takeRight hexDigits) 30 | if (genType.equals("constant")) str.addAll(args(4).toLong.toHexString takeRight hexDigits) 31 | if (genType.equals("range")) if (counter < args(4).toLong) str.addAll(counter.toHexString takeRight hexDigits); counter = counter + 1L 32 | str.addOne('\n') 33 | a = a + 1 34 | } 35 | bw.write(str.toString()) 36 | bw.close() 37 | } 38 | } 39 | 40 | GenTestFiles.main(args) 41 | -------------------------------------------------------------------------------- /src/test/scala/pipedsl/CSplitSuite.scala: -------------------------------------------------------------------------------- 1 | package pipedsl 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | 5 | import java.io.File 6 | 7 | class CSplitSuite extends AnyFunSuite { 8 | 9 | private val folder = "src/test/tests/branchesCheck" 10 | private val testFiles = getListOfTests(folder) 11 | private val simFiles = getListOfSims(folder) 12 | private val testFolder = new File(folder) 13 | //TODO better way to set this up (right now convention 14 | //requires test only has memories containing 32-bit values i and r -> they may omit these and it will still work 15 | 16 | private val memInputs = folder + "/memInputs" 17 | def defaultInputMap(testName: String): Map[String,String] = Map( 18 | "ti" -> (memInputs + "/i_" + testName ), 19 | "tr" -> (memInputs + "/r_" + testName ) 20 | ) 21 | 22 | testFiles.foreach(t => { 23 | val testBaseName = getTestName(t) 24 | val simFile = getSimFile(testFolder, testBaseName) 25 | 26 | //TODO find a way to only run the right set of tests 27 | //based on whether we expect success or not 28 | 29 | /* for now, skip these as they aren't that useful atm. 30 | test((testBaseName + " Parse")) { 31 | testParse(testFolder, t) 32 | }*/ 33 | 34 | var doesTypecheck = false 35 | test((testBaseName + " Typecheck; Compile; Simulate")) { 36 | doesTypecheck = testTypecheck(testFolder, t) 37 | 38 | if (doesTypecheck) { 39 | testBlueSpecCompile(testFolder, t, None, Map()) 40 | } 41 | 42 | if (doesTypecheck && simFile.exists) { 43 | testBlueSpecSim(testFolder, t, None, defaultInputMap(testBaseName)) 44 | } 45 | } 46 | }) 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/test/tests/speculation/3-stg-pipe-spec-3.pdl: -------------------------------------------------------------------------------- 1 | pipe cpu(pc: int<8>)[rf: int<32>[5](FAQueue), imem: int<32>[8]]: bool { 2 | spec_check(); //nonblocking check 3 | start(imem); 4 | uint<8> pcaddr = cast(pc, uint<8>); 5 | int<32> insn <- imem[pcaddr]; 6 | end(imem); 7 | s <- speccall cpu(pc + 1<8>); 8 | --- 9 | spec_barrier(); //blocking check 10 | bool done = insn{31:31} == 1<1>; 11 | if (!done) { 12 | --- 13 | int<1> op = insn{0:0}; 14 | int<8> brImm = 0<4> ++ insn{4:1}; 15 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 16 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 17 | uint<5> rd = cast(insn{19:15}, uint<5>); 18 | bool op_is_nil = op == 0<1>; 19 | if (op_is_nil) { 20 | verify(s, pc + 1<8>); 21 | } else { 22 | invalidate(s); 23 | } 24 | start(rf); 25 | int<32> a1 = rf[rs1]; 26 | int<32> a2 = rf[rs2]; 27 | if (op == 0<1>) { 28 | reserve(rf[rd]); 29 | } 30 | end(rf); 31 | --- 32 | if (!op_is_nil) { 33 | int<8> npc = (a1 == a2) ? (pc + brImm) : (pc + 1<8>); 34 | print(npc); 35 | call cpu(npc); 36 | } 37 | int<32> out = a1 + a2; 38 | --- 39 | if (op == 0<1>) { 40 | block(rf[rd]); 41 | print(out); 42 | rf[rd] <- out; 43 | release(rf[rd]); 44 | } 45 | } 46 | --- 47 | if (done) { 48 | invalidate(s); 49 | output(true); 50 | } 51 | } 52 | 53 | circuit { 54 | rename = regfile(int<32>, 5); 55 | r = FAQueue(rename); 56 | ti = memory(int<32>, 8); 57 | t = new cpu[r,ti]; 58 | call t(0<8>); 59 | } -------------------------------------------------------------------------------- /src/test/tests/histogram/histogram_nested.pdl: -------------------------------------------------------------------------------- 1 | /* 2 | n = 128 3 | void histogram ( int feature [] , float weight [] , float hist [] , int n ) { 4 | for (int i =0; i < n ; ++ i ) { 5 | int m = feature [ i ]; 6 | float wt = weight [ i ]; 7 | float x = hist [ m ]; 8 | hist [ m ] = x + wt ; 9 | } 10 | } 11 | */ 12 | 13 | 14 | pipe hist(counter: uint<10>)[feature: uint<16>[10](FAQueue), weight: uint<32>[10](FAQueue), h: uint<32>[10](FAQueue)]: bool { 15 | start(feature); 16 | start(weight); 17 | uint<16> m = feature[counter]; 18 | uint<10> m1 = m{9:0}; 19 | uint<32> wt = weight[counter]; 20 | end(feature); 21 | end(weight); 22 | --- 23 | uint<10> mcp = m1; 24 | start(h); 25 | uint<32> nm = h[m1] + wt; 26 | reserve(h[mcp]); 27 | end(h); 28 | print(nm); 29 | --- 30 | block(h[mcp]); 31 | h[mcp] <- nm; 32 | release(h[mcp]); 33 | --- 34 | output(true); 35 | } 36 | 37 | pipe outer(counter: uint<10>)[h: hist] { 38 | bool done = counter >= u1000<10>; 39 | if (!done) { 40 | call outer(counter + u1<10>); 41 | start(h); 42 | reserve(h); 43 | end(h); 44 | --- 45 | block(h); 46 | bool x <- call h(counter); 47 | release(h); 48 | } else { 49 | output(true); 50 | } 51 | } 52 | 53 | circuit { 54 | tf = regfile(uint<16>, 10); 55 | f = FAQueue(tf); 56 | tw = regfile(uint<32>, 10); 57 | w = FAQueue(tw); 58 | th = regfile(uint<32>, 10); 59 | h = FAQueue(th); 60 | hg = new hist[f, w, h]; 61 | o = new outer[hg]; 62 | call o(u0<10>); 63 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/lock-tests-specific.pdl: -------------------------------------------------------------------------------- 1 | //Expected Success 2 | pipe test1(input: uint<32>)[rf: int<32>[5](Queue)] { 3 | uint<5> rs1 = input{0:4}; 4 | uint<5> rs2 = input{5:9}; 5 | start(rf); 6 | int<32> arg1 <- rf[rs1]; 7 | int<32> arg2 <- rf[rs2]; 8 | end(rf); 9 | --- 10 | call test1(input); 11 | } 12 | 13 | //Expected Success 14 | pipe test2(input: uint<32>)[rf: int<32>[5](Queue)] { 15 | uint<5> rs1 = input{0:4}; 16 | uint<5> rs2 = input{5:9}; 17 | start(rf); 18 | bool doR1 = (input{0:0} == u1); 19 | if (doR1) { 20 | reserve(rf[rs1],R); 21 | } 22 | reserve(rf[rs2],R); 23 | end(rf); 24 | --- 25 | if (doR1) { 26 | block(rf[rs1]); 27 | int<32> arg1 <- rf[rs1]; 28 | release(rf[rs1]); 29 | } 30 | block(rf[rs2]); 31 | int<32> arg2 <- rf[rs2]; 32 | release(rf[rs2]); 33 | call test2(input); 34 | --- 35 | } 36 | 37 | 38 | //Expected Success 39 | pipe test5(input: uint<32>, randomBool: bool, randomBool2: bool)[rf:int<32>[5](Queue)] { 40 | bool a = true; 41 | bool b = false; 42 | uint<5> rs1 = input{0:4}; 43 | uint<5> rs2 = input{5:9}; 44 | start(rf); 45 | reserve(rf[rs2],R); 46 | if (randomBool == a) { 47 | if (randomBool2 == b){ 48 | reserve(rf[rs1],R); 49 | } 50 | } 51 | end(rf); 52 | --- 53 | if (randomBool == a) { 54 | if (randomBool2 == b){ 55 | block(rf[rs1]); 56 | x = rf[rs1]; 57 | release(rf[rs1]); 58 | } 59 | } 60 | block(rf[rs2]); 61 | y = rf[rs2]; 62 | release(rf[rs2]); 63 | call test5(input, randomBool2, randomBool); 64 | } 65 | circuit { 66 | r = memory(int<32>, 5); 67 | } -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/solutions/3-stg-lsq.simsol: -------------------------------------------------------------------------------- 1 | 2 2 | 3 3 | 4 4 | 5 5 | 6 6 | 7 7 | 8 8 | 9 9 | 10 10 | 11 11 | 12 12 | 13 13 | 14 14 | 15 15 | 16 16 | 17 17 | 18 18 | 19 19 | 20 20 | 21 21 | 22 22 | 23 23 | 24 24 | 25 25 | 26 26 | 27 27 | 28 28 | 29 29 | 30 30 | 31 31 | 32 32 | 3 33 | 4 34 | 5 35 | 6 36 | 7 37 | 8 38 | 9 39 | 10 40 | 11 41 | 12 42 | 13 43 | 14 44 | 15 45 | 16 46 | 17 47 | 18 48 | 19 49 | 20 50 | 21 51 | 22 52 | 23 53 | 24 54 | 25 55 | 26 56 | 27 57 | 28 58 | 29 59 | 30 60 | 31 61 | 32 62 | 33 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19 79 | 20 80 | 21 81 | 22 82 | 23 83 | 24 84 | 25 85 | 26 86 | 27 87 | 28 88 | 29 89 | 30 90 | 31 91 | 32 92 | 33 93 | 34 94 | 5 95 | 6 96 | 7 97 | 8 98 | 9 99 | 10 100 | -------------------------------------------------------------------------------- /src/test/tests/registerRenamingTests/solutions/3-stg-pipe.simsol: -------------------------------------------------------------------------------- 1 | 2 2 | 3 3 | 4 4 | 5 5 | 6 6 | 7 7 | 8 8 | 9 9 | 10 10 | 11 11 | 12 12 | 13 13 | 14 14 | 15 15 | 16 16 | 17 17 | 18 18 | 19 19 | 20 20 | 21 21 | 22 22 | 23 23 | 24 24 | 25 25 | 26 26 | 27 27 | 28 28 | 29 29 | 30 30 | 31 31 | 32 32 | 3 33 | 4 34 | 5 35 | 6 36 | 7 37 | 8 38 | 9 39 | 10 40 | 11 41 | 12 42 | 13 43 | 14 44 | 15 45 | 16 46 | 17 47 | 18 48 | 19 49 | 20 50 | 21 51 | 22 52 | 23 53 | 24 54 | 25 55 | 26 56 | 27 57 | 28 58 | 29 59 | 30 60 | 31 61 | 32 62 | 33 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19 79 | 20 80 | 21 81 | 22 82 | 23 83 | 24 84 | 25 85 | 26 86 | 27 87 | 28 88 | 29 89 | 30 90 | 31 91 | 32 92 | 33 93 | 34 94 | 5 95 | 6 96 | 7 97 | 8 98 | 9 99 | 10 100 | -------------------------------------------------------------------------------- /src/test/tests/speculation/3-stg-pipe-spec-2.pdl: -------------------------------------------------------------------------------- 1 | pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool { 2 | spec_check(); //nonblocking check 3 | start(imem); 4 | uint<8> pcaddr = cast(pc, uint<8>); 5 | int<32> insn <- imem[pcaddr]; 6 | end(imem); 7 | s <- speccall cpu(pc + 1<8>); 8 | --- 9 | spec_barrier(); //blocking check 10 | bool done = insn{31:31} == 1<1>; 11 | if (!done) { 12 | --- 13 | int<1> op = insn{0:0}; 14 | int<8> brImm = 0<4> ++ insn{4:1}; 15 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 16 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 17 | uint<5> rd = cast(insn{19:15}, uint<5>); 18 | bool isBrOp = op == 1<1>; 19 | if (!isBrOp) { 20 | verify(s, pc + 1<8>); 21 | } 22 | start(rf); 23 | reserve(rf[rs1], R); 24 | reserve(rf[rs2], R); 25 | if (!isBrOp) { 26 | reserve(rf[rd], W); 27 | } 28 | end(rf); 29 | --- 30 | block(rf[rs1]); 31 | block(rf[rs2]); 32 | if (isBrOp) { 33 | int<8> npc = (rf[rs1] == rf[rs2]) ? (pc + brImm) : (pc + 1<8>); 34 | print(npc); 35 | verify(s, npc); 36 | } 37 | int<32> out = rf[rs1] + rf[rs2]; 38 | release(rf[rs1]); 39 | release(rf[rs2]); 40 | --- 41 | if (!isBrOp) { 42 | block(rf[rd]); 43 | print(out); 44 | rf[rd] <- out; 45 | release(rf[rd]); 46 | } 47 | } 48 | --- 49 | if (done) { 50 | invalidate(s); 51 | output(true); 52 | } 53 | } 54 | 55 | circuit { 56 | rename = rflock(int<32>, 5, 128); 57 | ti = memory(int<32>, 8); 58 | t = new cpu[rename,ti]; 59 | call t(0<8>); 60 | } -------------------------------------------------------------------------------- /src/test/tests/speculation/3-stg-pipe-spec.pdl: -------------------------------------------------------------------------------- 1 | pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool { 2 | spec_check(); //nonblocking check 3 | start(imem); 4 | uint<8> pcaddr = cast(pc, uint<8>); 5 | int<32> insn <- imem[pcaddr]; 6 | end(imem); 7 | s <- speccall cpu(pc + 1<8>); 8 | --- 9 | spec_barrier(); //blocking check 10 | bool done = insn{31:31} == 1<1>; 11 | if (!done) { 12 | --- 13 | int<1> op = insn{0:0}; 14 | int<8> brImm = 0<4> ++ insn{4:1}; 15 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 16 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 17 | uint<5> rd = cast(insn{19:15}, uint<5>); 18 | if (op == 0<1>) { 19 | verify(s, pc + 1<8>); 20 | } else { 21 | invalidate(s); 22 | } 23 | start(rf); 24 | reserve(rf[rs1], R); 25 | reserve(rf[rs2], R); 26 | if (op == 0<1>) { 27 | reserve(rf[rd], W); 28 | } 29 | end(rf); 30 | --- 31 | block(rf[rs1]); 32 | block(rf[rs2]); 33 | if (op != 0<1>) { 34 | int<8> npc = (rf[rs1] == rf[rs2]) ? (pc + brImm) : (pc + 1<8>); 35 | print(npc); 36 | call cpu(npc); 37 | } 38 | int<32> out = rf[rs1] + rf[rs2]; 39 | release(rf[rs1]); 40 | release(rf[rs2]); 41 | --- 42 | if (op == 0<1>) { 43 | block(rf[rd]); 44 | print(out); 45 | rf[rd] <- out; 46 | release(rf[rd]); 47 | } 48 | } 49 | --- 50 | if (done) { 51 | invalidate(s); 52 | output(true); 53 | } 54 | } 55 | 56 | circuit { 57 | rename = rflock(int<32>, 5, 128); 58 | ti = memory(int<32>, 8); 59 | t = new cpu[rename,ti]; 60 | call t(0<8>); 61 | } -------------------------------------------------------------------------------- /src/test/tests/typecheckTests/quad-call-disjoint.pdl: -------------------------------------------------------------------------------- 1 | pipe quad_call(input: uint<32>)[rf: int<32>[5]] { 2 | bool a = input{0:0}; 3 | bool b = input{1:1}; 4 | if(a && b) 5 | { 6 | call quad_call(input); 7 | } 8 | --- 9 | if(a && !b) 10 | { 11 | call quad_call(input); 12 | } 13 | --- 14 | if((!a) && b) 15 | { 16 | call quad_call(input); 17 | } 18 | --- 19 | if((!a) && (!b)) 20 | { 21 | call quad_call(input); 22 | } 23 | } 24 | 25 | pipe comparison(input: int<32>, bool1: bool, bool2: bool)[rf: int<32>[5]] 26 | { 27 | int<16> a = input{0:15}; 28 | int<16> b = input{16:31}; 29 | bool lt = a < b; 30 | bool eq = a == b; 31 | split { 32 | case: bool1 33 | { 34 | call comparison(input, bool2, bool1); 35 | } 36 | case: bool2 37 | { 38 | call comparison(input + 1<32>, bool1, bool2); 39 | } 40 | case: (input{0:0} == 1) 41 | { 42 | call comparison(input - 1<32>, bool2, bool1); 43 | } 44 | default: 45 | { 46 | call comparison(input, bool1, bool2); 47 | } 48 | } 49 | } 50 | 51 | pipe getFalse()[] :bool 52 | { 53 | output(false); 54 | } 55 | 56 | //at least it is smart about else lol 57 | pipe test1(input: int<32>)[rf: int<32>[5]] 58 | { 59 | if(input{0:0} == 1) 60 | { 61 | call test1(input); 62 | } else 63 | { 64 | call test1(input); 65 | } 66 | --- 67 | 68 | call getFalse(); 69 | } 70 | 71 | pipe very_simple()[] 72 | { 73 | call very_simple(); 74 | } 75 | 76 | pipe falsification()[] 77 | { 78 | if(false) 79 | { 80 | call very_simple(); 81 | } else 82 | { 83 | call falsification(); 84 | } 85 | } 86 | 87 | circuit 88 | { 89 | r = memory(int<32>, 5); 90 | } -------------------------------------------------------------------------------- /src/test/tests/speculation/spec-write-2.pdl: -------------------------------------------------------------------------------- 1 | pipe testwrite(pc: int<8>)[rf: int<32>[5](CheckpointQueue), imem: int<32>[8]]: bool { 2 | spec_check(); 3 | start(imem); 4 | int<32> insn <- imem[cast(pc, uint<8>)]; 5 | end(imem); 6 | s <- speccall testwrite(pc + 1); 7 | --- 8 | spec_check(); 9 | done = (insn{31:31} == 1<1>); 10 | int<1> op = insn{0:0}; 11 | int<8> brImm = 0<4> ++ insn{4:1}; 12 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 13 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 14 | uint<5> rd = cast(insn{19:15}, uint<5>); 15 | if (!done) { 16 | start(rf); 17 | a1 = rf[rs1]; 18 | a2 = rf[rs2]; 19 | checkpoint(rf); 20 | if (op == 0<1>) { 21 | reserve(rf[rd], W); 22 | } 23 | end(rf); 24 | } else { 25 | int<32> a1 = 0; 26 | int<32> a2 = 0; 27 | invalidate(s); 28 | } 29 | --- 30 | spec_check(); 31 | int<32> out = a1 + a2; 32 | if (!done) { 33 | if (op == 0<1>) { 34 | block(rf[rd]); 35 | rf[rd] <- out; 36 | } 37 | } 38 | --- 39 | --- 40 | spec_barrier(); 41 | int<8> npc = (a1 == a2) ? (pc + brImm) : (pc + 1<8>); 42 | if (!done) { 43 | if (op != 0<1>) { 44 | verify(s, npc); 45 | } else { 46 | verify(s, pc + 1<8>); 47 | } 48 | } 49 | --- 50 | if (!done) { 51 | if (op == 0<1>) { 52 | print(out); 53 | release(rf[rd]); 54 | } else { 55 | print(npc); 56 | } 57 | } 58 | --- 59 | if (done) { 60 | output(true); 61 | } 62 | } 63 | 64 | circuit { 65 | ti = memory(int<32>, 8); 66 | rename = regfile(int<32>, 5); 67 | qrf = CheckpointQueue(rename); 68 | t = new testwrite[qrf, ti]; 69 | call t(0<8>); 70 | } -------------------------------------------------------------------------------- /.github/workflows/scala.yml: -------------------------------------------------------------------------------- 1 | name: Scala CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-18.04 13 | 14 | steps: 15 | - name: Set up JDK 1.8 16 | uses: actions/setup-java@v1 17 | with: 18 | java-version: 1.8 19 | - name: Install IVerilog 20 | run: sudo apt-get install iverilog 21 | - name: Install GHC Dependencies 22 | run: | 23 | sudo apt-get update 24 | sudo apt-get install ghc 25 | sudo apt-get install libghc-regex-compat-dev libghc-syb-dev libghc-old-time-dev libghc-split-dev 26 | sudo apt-get install autoconf gperf 27 | sudo apt-get install tcl-dev 28 | sudo apt-get install flex bison 29 | - name: Checkout Code 30 | uses: actions/checkout@v2 31 | - name: Cache BSV 32 | id: cache-bsc 33 | uses: actions/cache@v2 34 | with: 35 | path: bsc 36 | key: ubuntu-bsc 37 | - name: Install BSV 38 | id: install-bsv 39 | run: | 40 | wget https://github.com/B-Lang-org/bsc/releases/download/2021.07/bsc-2021.07-ubuntu-18.04.tar.gz 41 | tar -xvf bsc-2021.07-ubuntu-18.04.tar.gz 42 | mv bsc-2021.07-ubuntu-18.04 bsc 43 | - name: Build Libs 44 | env: 45 | BLUESPECDIR: ${{github.workspace}}/bsc 46 | run: | 47 | export BLUESPECDIR=${{env.BLUESPECDIR}} 48 | export PATH="$PATH":"$BLUESPECDIR"/bin 49 | echo "$BLUESPECDIR" 50 | echo "$PATH" 51 | make 52 | - name: Run tests 53 | env: 54 | BLUESPECDIR: ${{github.workspace}}/bsc 55 | run: | 56 | export BLUESPECDIR=${{env.BLUESPECDIR}} 57 | export PATH="$PATH":"$BLUESPECDIR"/bin 58 | sbt test 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/test/tests/matpow/matpow_alt.pdl: -------------------------------------------------------------------------------- 1 | /* 2 | void matrix_power( inout_int_t x[20][20], in_int_t row[20], in_int_t col[20], in_int_t a[20] ) 3 | { 4 | for (int k=1; k<20; k++) { 5 | for (int p=0; p<20; p++) { 6 | x[k][row[p]] += a[p]*x[k-1][col[p]]; 7 | } 8 | } 9 | } 10 | */ 11 | 12 | pipe matpow(k: uint<5>, p: uint<5>)[x: uint<32>[9](FAQueue), row: uint<5>[5], col: uint<5>[5], a: uint<32>[5]]: bool { 13 | if (p == u19<5>) { 14 | if (k != u19<5>) { 15 | call matpow(k + u1<5>, u0<5>); 16 | } 17 | } else { 18 | call matpow(k, p + u1<5>); 19 | } 20 | start(col); 21 | uint<5> col_p = col[p]; 22 | end(col); 23 | start(row); 24 | uint<5> row_p = row[p]; 25 | end(row); 26 | uint<18> x_in_mul = u20<9> * (u0<4> ++ (k - u1<5>)); 27 | uint<9> x_in_idx = x_in_mul{8:0} + (u0<4> ++ col_p); 28 | uint<18> x_out_mul = (u20<9> * (u0<4> ++ k)); 29 | uint<9> x_out_idx = x_out_mul{8:0} + (u0<4> ++ row_p); 30 | uint<9> x_out_idx_cp = x_out_idx; 31 | start(x); 32 | uint<32> x_in_val = x[x_in_idx]; 33 | uint<32> x_out_val_read = x[x_out_idx]; 34 | reserve(x[x_out_idx_cp]); 35 | end(x); 36 | start(a); 37 | uint<32> a_val = a[p]; 38 | end(a); 39 | --- 40 | uint<64> nmul = a_val * x_in_val; 41 | uint<32> nval = x_out_val_read + nmul{31:0}; 42 | print(nval); 43 | block(x[x_out_idx_cp]); 44 | x[x_out_idx_cp] <- nval; 45 | release(x[x_out_idx_cp]); 46 | --- 47 | if ((k == u19<5>) && (p == u19<5>)) { 48 | output(true); 49 | } 50 | } 51 | 52 | circuit { 53 | tx = regfile(uint<32>, 9); 54 | x = FAQueue(tx); 55 | ta = regfile(uint<32>, 5); 56 | tr = regfile(uint<5>, 5); 57 | tc = regfile(uint<5>, 5); 58 | mp = new matpow[x, tr, tc, ta]; 59 | call mp(u1<5>,u 0<5>); 60 | } -------------------------------------------------------------------------------- /src/test/tests/matpow/matpow.pdl: -------------------------------------------------------------------------------- 1 | /* 2 | void matrix_power( inout_int_t x[20][20], in_int_t row[20], in_int_t col[20], in_int_t a[20] ) 3 | { 4 | for (int k=1; k<20; k++) { 5 | for (int p=0; p<20; p++) { 6 | x[k][row[p]] += a[p]*x[k-1][col[p]]; 7 | } 8 | } 9 | } 10 | */ 11 | 12 | pipe matpow(k: uint<5>, p: uint<5>)[x: uint<32>[9](FAQueue), row: uint<5>[5], col: uint<5>[5], a: uint<32>[5]]: bool { 13 | if (p == u19<5>) { 14 | if (k != u19<5>) { 15 | call matpow(k + u1<5>, u0<5>); 16 | } 17 | } else { 18 | call matpow(k, p + u1<5>); 19 | } 20 | start(col); 21 | uint<5> col_p = col[p]; 22 | end(col); 23 | start(row); 24 | uint<5> row_p = row[p]; 25 | end(row); 26 | --- 27 | uint<18> x_in_mul = u20<9> * (u0<4> ++ (k - u1<5>)); 28 | uint<9> x_in_idx = x_in_mul{8:0} + (u0<4> ++ col_p); 29 | uint<18> x_out_mul = (u20<9> * (u0<4> ++ k)); 30 | uint<9> x_out_idx = x_out_mul{8:0} + (u0<4> ++ row_p); 31 | uint<9> x_out_idx_cp = x_out_idx; 32 | start(x); 33 | uint<32> x_in_val = x[x_in_idx]; 34 | uint<32> x_out_val_read = x[x_out_idx]; 35 | reserve(x[x_out_idx_cp]); 36 | end(x); 37 | start(a); 38 | uint<32> a_val = a[p]; 39 | end(a); 40 | --- 41 | uint<64> nmul = a_val * x_in_val; 42 | uint<32> nval = x_out_val_read + nmul{31:0}; 43 | print(nval); 44 | block(x[x_out_idx_cp]); 45 | x[x_out_idx_cp] <- nval; 46 | release(x[x_out_idx_cp]); 47 | --- 48 | if ((k == u19<5>) && (p == u19<5>)) { 49 | output(true); 50 | } 51 | } 52 | 53 | circuit { 54 | tx = regfile(uint<32>, 9); 55 | x = FAQueue(tx); 56 | ta = regfile(uint<32>, 5); 57 | tr = regfile(uint<5>, 5); 58 | tc = regfile(uint<5>, 5); 59 | mp = new matpow[x, tr, tc, ta]; 60 | call mp(u1<5>, u0<5>); 61 | } -------------------------------------------------------------------------------- /src/test/tests/matpow/matpow_bram.pdl: -------------------------------------------------------------------------------- 1 | /* 2 | void matrix_power( inout_int_t x[20][20], in_int_t row[20], in_int_t col[20], in_int_t a[20] ) 3 | { 4 | for (int k=1; k<20; k++) { 5 | for (int p=0; p<20; p++) { 6 | x[k][row[p]] += a[p]*x[k-1][col[p]]; 7 | } 8 | } 9 | } 10 | */ 11 | 12 | pipe matpow(k: uint<5>, p: uint<5>)[x: uint<32>[9](FAQueue), row: uint<8>[5], col: uint<8>[5], a: uint<32>[5]]: bool { 13 | if (p == u19<5>) { 14 | if (k != u19<5>) { 15 | call matpow(k + u1<5>, u0<5>); 16 | } 17 | } else { 18 | call matpow(k, p + u1<5>); 19 | } 20 | start(col); 21 | uint<8> col_p <- col[p]; 22 | end(col); 23 | start(row); 24 | uint<8> row_p <- row[p]; 25 | end(row); 26 | --- 27 | uint<18> x_in_mul = u20<9> * (u0<4> ++ (k - u1<5>)); 28 | uint<9> x_in_idx = x_in_mul{8:0} + (u0<1> ++ col_p); 29 | uint<18> x_out_mul = (u20<9> * (u0<4> ++ k)); 30 | uint<9> x_out_idx = x_out_mul{8:0} + (u0<1> ++ row_p); 31 | uint<9> x_out_idx_cp = x_out_idx; 32 | start(x); 33 | reserve(x[x_out_idx]); 34 | uint<32> x_in_val <- x[x_in_idx]; 35 | end(x); 36 | start(a); 37 | uint<32> a_val <- a[p]; 38 | end(a); 39 | --- 40 | uint<64> nmul = a_val * x_in_val; 41 | uint<32> nval = nmul{31:0}; 42 | block(x[x_out_idx]); 43 | uint<32> oldx <- x[x_out_idx]; 44 | --- 45 | uint<32> newval = nval + oldx; 46 | print(newval); 47 | x[x_out_idx] <- newval; 48 | release(x[x_out_idx]); 49 | --- 50 | if ((k == u19<5>) && (p == u19<5>)) { 51 | output(true); 52 | } 53 | } 54 | 55 | circuit { 56 | tx = memory(uint<32>, 9, 2); 57 | x = FAQueue(tx); 58 | ta = memory(uint<32>, 5); 59 | tr = memory(uint<8>, 5); 60 | tc = memory(uint<8>, 5); 61 | mp = new matpow[x, tr, tc, ta]; 62 | call mp(u1<5>, u0<5>); 63 | } -------------------------------------------------------------------------------- /src/test/tests/matpow/solutions/matpow_alt.parsesol: -------------------------------------------------------------------------------- 1 | pipe matpow(k:int<5>,p:int<5>)[x:int<32>[9],row:int<5>[5],col:int<5>[5],a:int<32>[5]] { 2 | if ( p == 19<5> ) { 3 | if ( k != 19<5> ) { 4 | call matpow(k + 1<5>,0<5>); 5 | 6 | } else { 7 | 8 | } 9 | 10 | } else { 11 | call matpow(k,p + 1<5>); 12 | 13 | } 14 | start(col); 15 | reserved(col); 16 | acquired(col); 17 | int<5> col_p = col[p]; 18 | released(col); 19 | end(col); 20 | start(row); 21 | reserved(row); 22 | acquired(row); 23 | int<5> row_p = row[p]; 24 | released(row); 25 | end(row); 26 | int<18> x_in_mul = 20<9> * 0<4> ++ k - 1<5>; 27 | int<9> x_in_idx = x_in_mul{8:0} + 0<4> ++ col_p; 28 | int<18> x_out_mul = 20<9> * 0<4> ++ k; 29 | int<9> x_out_idx = x_out_mul{8:0} + 0<4> ++ row_p; 30 | int<9> x_out_idx_cp = x_out_idx; 31 | start(x); 32 | reserved(x[x_in_idx],R); 33 | acquired(x[x_in_idx],R); 34 | reserved(x[x_out_idx],R); 35 | acquired(x[x_out_idx],R); 36 | reserved(x[x_out_idx_cp],W); 37 | acquired(x[x_out_idx_cp],W); 38 | end(x); 39 | int<32> x_in_val = x[x_in_idx]; 40 | int<32> x_out_val_read = x[x_out_idx]; 41 | released(x[x_in_idx]); 42 | released(x[x_out_idx]); 43 | start(a); 44 | reserved(a); 45 | acquired(a); 46 | int<32> a_val = a[p]; 47 | released(a); 48 | end(a); 49 | 50 | --- 51 | int<64> nmul = a_val * x_in_val; 52 | int<32> nval = x_out_val_read + nmul{31:0}; 53 | print(nval); 54 | x[x_out_idx_cp] <- nval; 55 | released(x[x_out_idx_cp]); 56 | 57 | --- 58 | if ( k == 19<5> && p == 19<5> ) { 59 | output true; 60 | 61 | } else { 62 | 63 | } 64 | 65 | } 66 | circuit { 67 | x = regfile(int<32>,9); 68 | a = regfile(int<32>,5); 69 | r = regfile(int<5>,5); 70 | c = regfile(int<5>,5); 71 | mp = new matpow[x,r,c,a]; 72 | call mp(1<5>,0<5>); 73 | } 74 | -------------------------------------------------------------------------------- /bscRuntime/libs/NamedEhr.bsv: -------------------------------------------------------------------------------- 1 | package Named; 2 | 3 | import RegFile :: *; 4 | import Ehr :: *; 5 | import FIFOF :: *; 6 | import SpecialFIFOs :: *; 7 | import BRAMCore::*; 8 | import DReg :: *; 9 | import Vector :: *; 10 | 11 | export LSQ(..); 12 | export mkLSQ; 13 | 14 | interface LSQ#(type addr, type elem, type name); 15 | 16 | endinterface; 17 | 18 | //TODO make size of queues a parameter 19 | module mkLSQ#(parameter Bool init, parameter String fileInit)(AsyncMem#(elem, addr, name)) provisos 20 | (Bits#(elem, szElem), Bits#(addr, szAddr), Bits#(name, szName), Eq#(addr), Literal#(name)); 21 | 22 | let memSize = 2 ** valueOf(szAddr); 23 | let hasOutputReg = False; 24 | BRAM_PORT #(addr, elem) memory <- (init) ? mkBRAMCore1Load(memSize, hasOutputReg, fileInit, False) : mkBRAMCore1(memSize, hasOutputReg); 25 | 26 | //TODO make size of store queue parameter 27 | Integer stSize = 5; 28 | Vector#(5, Reg#(addr)) stQ <- replicateM( mkReg(unpack(0))); 29 | Vector#(5, Reg#(Maybe#(elem))) stDQ <- replicateM (mkReg(tagged Invalid)); 30 | //TODO make size of ld queue parameter 31 | 32 | function Maybe#(name) getMatchingStore(addr a); 33 | Maybe#(name) result = tagged Invalid; 34 | for (Integer i = 0; i < stSize; i = i + 1) begin 35 | if (result matches tagged Invalid &&& stQ[i] == a) 36 | result = tagged Valid fromInteger(i); 37 | end 38 | return result; 39 | endfunction 40 | 41 | //TODO 42 | method ActionValue#(name) reserveEntry(addr a, Bool isWrite); 43 | return unpack(0); 44 | endmethod 45 | //TODO 46 | method Action write(name n, elem b); 47 | endmethod 48 | //TODO 49 | method Bool isValid(name n); 50 | return False; 51 | endmethod 52 | //TODO 53 | method elem read(name n); 54 | return unpack(0); 55 | endmethod 56 | //TODO 57 | method Action commit(name n); 58 | endmethod 59 | endmodule 60 | 61 | endpackage 62 | -------------------------------------------------------------------------------- /src/test/tests/matpow/solutions/matpow.parsesol: -------------------------------------------------------------------------------- 1 | pipe matpow(k:int<5>,p:int<5>)[x:int<32>[9],row:int<5>[5],col:int<5>[5],a:int<32>[5]] { 2 | if ( p == 19<5> ) { 3 | if ( k != 19<5> ) { 4 | call matpow(k + 1<5>,0<5>); 5 | 6 | } else { 7 | 8 | } 9 | 10 | } else { 11 | call matpow(k,p + 1<5>); 12 | 13 | } 14 | start(col); 15 | reserved(col); 16 | acquired(col); 17 | int<5> col_p = col[p]; 18 | released(col); 19 | end(col); 20 | start(row); 21 | reserved(row); 22 | acquired(row); 23 | int<5> row_p = row[p]; 24 | released(row); 25 | end(row); 26 | 27 | --- 28 | int<18> x_in_mul = 20<9> * 0<4> ++ k - 1<5>; 29 | int<9> x_in_idx = x_in_mul{8:0} + 0<4> ++ col_p; 30 | int<18> x_out_mul = 20<9> * 0<4> ++ k; 31 | int<9> x_out_idx = x_out_mul{8:0} + 0<4> ++ row_p; 32 | int<9> x_out_idx_cp = x_out_idx; 33 | start(x); 34 | reserved(x[x_in_idx],R); 35 | acquired(x[x_in_idx],R); 36 | reserved(x[x_out_idx],R); 37 | acquired(x[x_out_idx],R); 38 | reserved(x[x_out_idx_cp],W); 39 | acquired(x[x_out_idx_cp],W); 40 | end(x); 41 | int<32> x_in_val = x[x_in_idx]; 42 | int<32> x_out_val_read = x[x_out_idx]; 43 | released(x[x_in_idx]); 44 | released(x[x_out_idx]); 45 | start(a); 46 | reserved(a); 47 | acquired(a); 48 | int<32> a_val = a[p]; 49 | released(a); 50 | end(a); 51 | 52 | --- 53 | int<64> nmul = a_val * x_in_val; 54 | int<32> nval = x_out_val_read + nmul{31:0}; 55 | print(nval); 56 | x[x_out_idx_cp] <- nval; 57 | released(x[x_out_idx_cp]); 58 | 59 | --- 60 | if ( k == 19<5> && p == 19<5> ) { 61 | output true; 62 | 63 | } else { 64 | 65 | } 66 | 67 | } 68 | circuit { 69 | x = regfile(int<32>,9); 70 | a = regfile(int<32>,5); 71 | r = regfile(int<5>,5); 72 | c = regfile(int<5>,5); 73 | mp = new matpow[x,r,c,a]; 74 | call mp(1<5>,0<5>); 75 | } 76 | -------------------------------------------------------------------------------- /src/test/tests/speculation/bad-spec-3.pdl: -------------------------------------------------------------------------------- 1 | pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool { 2 | spec_check(); //nonblocking check 3 | start(imem); 4 | uint<8> pcaddr = cast(pc, uint<8>); 5 | acquire(imem[pcaddr], R); 6 | int<32> insn <- imem[pcaddr]; 7 | release(imem[pcaddr]); 8 | end(imem); 9 | s <- speccall cpu(pc + 1<8>); 10 | --- 11 | if (insn{31:31} != 1<1>) { 12 | --- 13 | int<1> op = insn{0:0}; 14 | int<8> brImm = 0<4> ++ insn{4:1}; 15 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 16 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 17 | uint<5> rd = cast(insn{19:15}, uint<5>); 18 | spec_check(); //nonblocking check -> need blocking check 19 | if (op == 0<1>) { 20 | verify(s, pc + 1<8>); 21 | } else { 22 | invalidate(s); 23 | } 24 | start(rf); 25 | reserve(rf[rs1], R); 26 | reserve(rf[rs2], R); 27 | if (op == 0<1>) { 28 | reserve(rf[rd], W); 29 | } 30 | end(rf); 31 | --- 32 | block(rf[rs1]); 33 | block(rf[rs2]); 34 | if (op == 1<1>) { 35 | int<8> npc = (rf[rs1] == rf[rs2]) ? (pc + brImm) : (pc + 1<8>); 36 | print(npc); 37 | call cpu(npc); 38 | } 39 | int<32> out = rf[rs1] + rf[rs2]; 40 | release(rf[rs1]); 41 | release(rf[rs2]); 42 | --- 43 | if (op == 0<1>) { 44 | block(rf[rd]); 45 | print(out); 46 | rf[rd] <- out; 47 | release(rf[rd]); 48 | } 49 | } else { 50 | --- 51 | spec_barrier(); //blocking check 52 | invalidate(s); 53 | output(true); 54 | } 55 | } 56 | 57 | circuit { 58 | rename = rflock(int<32>, 5, 128); 59 | ti = memory(int<32>, 8); 60 | i = Queue(ti); 61 | t = new cpu[rename,i]; 62 | call t(0<8>); 63 | } -------------------------------------------------------------------------------- /src/test/tests/speculation/bad-spec-4.pdl: -------------------------------------------------------------------------------- 1 | pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool { 2 | //spec_check(); //nonblocking check 3 | //missing nonblocking check 4 | start(imem); 5 | uint<8> pcaddr = cast(pc, uint<8>); 6 | acquire(imem[pcaddr], R); 7 | int<32> insn <- imem[pcaddr]; 8 | release(imem[pcaddr]); 9 | end(imem); 10 | s <- speccall cpu(pc + 1<8>); 11 | --- 12 | if (insn{31:31} != 1<1>) { 13 | --- 14 | int<1> op = insn{0:0}; 15 | int<8> brImm = 0<4> ++ insn{4:1}; 16 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 17 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 18 | uint<5> rd = cast(insn{19:15}, uint<5>); 19 | spec_barrier(); //blocking check 20 | if (op == 0<1>) { 21 | verify(s, pc + 1<8>); 22 | } else { 23 | invalidate(s); 24 | } 25 | start(rf); 26 | reserve(rf[rs1], R); 27 | reserve(rf[rs2], R); 28 | if (op == 0<1>) { 29 | reserve(rf[rd], W); 30 | } 31 | end(rf); 32 | --- 33 | block(rf[rs1]); 34 | block(rf[rs2]); 35 | if (op == 1<1>) { 36 | int<8> npc = (rf[rs1] == rf[rs2]) ? (pc + brImm) : (pc + 1<8>); 37 | print(npc); 38 | call cpu(npc); 39 | } 40 | int<32> out = rf[rs1] + rf[rs2]; 41 | release(rf[rs1]); 42 | release(rf[rs2]); 43 | --- 44 | if (op == 0<1>) { 45 | block(rf[rd]); 46 | print(out); 47 | rf[rd] <- out; 48 | release(rf[rd]); 49 | } 50 | } else { 51 | --- 52 | spec_barrier(); //blocking check 53 | invalidate(s); 54 | output(true); 55 | } 56 | } 57 | 58 | circuit { 59 | rename = rflock(int<32>, 5, 128); 60 | ti = memory(int<32>, 8); 61 | i = Queue(ti); 62 | t = new cpu[rename,i]; 63 | call t(0<8>); 64 | } -------------------------------------------------------------------------------- /src/test/tests/speculation/bad-spec-5.pdl: -------------------------------------------------------------------------------- 1 | pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool { 2 | //spec_check(); //nonblocking check 3 | //missing nonblocking check 4 | s <- speccall cpu(pc + 1<8>); 5 | start(imem); 6 | uint<8> pcaddr = cast(pc, uint<8>); 7 | acquire(imem[pcaddr], R); 8 | int<32> insn <- imem[pcaddr]; 9 | release(imem[pcaddr]); 10 | end(imem); 11 | --- 12 | if (insn{31:31} != 1<1>) { 13 | --- 14 | int<1> op = insn{0:0}; 15 | int<8> brImm = 0<4> ++ insn{4:1}; 16 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 17 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 18 | uint<5> rd = cast(insn{19:15}, uint<5>); 19 | spec_barrier(); //blocking check 20 | if (op == 0<1>) { 21 | verify(s, pc + 1<8>); 22 | } else { 23 | invalidate(s); 24 | } 25 | start(rf); 26 | reserve(rf[rs1], R); 27 | reserve(rf[rs2], R); 28 | if (op == 0<1>) { 29 | reserve(rf[rd], W); 30 | } 31 | end(rf); 32 | --- 33 | block(rf[rs1]); 34 | block(rf[rs2]); 35 | if (op == 1<1>) { 36 | int<8> npc = (rf[rs1] == rf[rs2]) ? (pc + brImm) : (pc + 1<8>); 37 | print(npc); 38 | call cpu(npc); 39 | } 40 | int<32> out = rf[rs1] + rf[rs2]; 41 | release(rf[rs1]); 42 | release(rf[rs2]); 43 | --- 44 | if (op == 0<1>) { 45 | block(rf[rd]); 46 | print(out); 47 | rf[rd] <- out; 48 | release(rf[rd]); 49 | } 50 | } else { 51 | --- 52 | spec_barrier(); //blocking check 53 | invalidate(s); 54 | output(true); 55 | } 56 | } 57 | 58 | circuit { 59 | rename = rflock(int<32>, 5, 128); 60 | ti = memory(int<32>, 8); 61 | i = Queue(ti); 62 | t = new cpu[rename,i]; 63 | call t(0<8>); 64 | } -------------------------------------------------------------------------------- /src/test/tests/speculation/bad-spec-2.pdl: -------------------------------------------------------------------------------- 1 | pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool { 2 | spec_check(); //nonblocking check 3 | start(imem); 4 | uint<8> pcaddr = cast(pc, uint<8>); 5 | acquire(imem[pcaddr], R); 6 | int<32> insn <- imem[pcaddr]; 7 | release(imem[pcaddr]); 8 | end(imem); 9 | s <- speccall cpu(pc + 1<8>); 10 | --- 11 | if (insn{31:31} != 1<1>) { 12 | --- 13 | int<1> op = insn{0:0}; 14 | int<8> brImm = 0<4> ++ insn{4:1}; 15 | uint<5> rs1 = cast(insn{9:5}, uint<5>); 16 | uint<5> rs2 = cast(insn{14:10}, uint<5>); 17 | uint<5> rd = cast(insn{19:15}, uint<5>); 18 | //spec_barrier(); //blocking check 19 | //missing speculation check 20 | if (op == 0<1>) { 21 | verify(s, pc + 1<8>); 22 | } else { 23 | invalidate(s); 24 | } 25 | start(rf); 26 | reserve(rf[rs1], R); 27 | reserve(rf[rs2], R); 28 | if (op == 0<1>) { 29 | reserve(rf[rd], W); 30 | } 31 | end(rf); 32 | --- 33 | block(rf[rs1]); 34 | block(rf[rs2]); 35 | if (op == 1<1>) { 36 | int<8> npc = (rf[rs1] == rf[rs2]) ? (pc + brImm) : (pc + 1<8>); 37 | print(npc); 38 | call cpu(npc); 39 | } 40 | int<32> out = rf[rs1] + rf[rs2]; 41 | release(rf[rs1]); 42 | release(rf[rs2]); 43 | --- 44 | if (op == 0<1>) { 45 | block(rf[rd]); 46 | print(out); 47 | rf[rd] <- out; 48 | release(rf[rd]); 49 | } 50 | } else { 51 | --- 52 | spec_barrier(); //blocking check 53 | invalidate(s); 54 | output(true); 55 | } 56 | } 57 | 58 | circuit { 59 | rename = rflock(int<32>, 5, 128); 60 | ti = memory(int<32>, 8); 61 | i = Queue(ti); 62 | t = new cpu[rename,i]; 63 | call t(0<8>); 64 | } --------------------------------------------------------------------------------