Compare commits

...
Sign in to create a new pull request.

7 commits

Author SHA1 Message Date
e5a439d56e
WIP adding next_pc 2025-11-05 23:04:20 -08:00
42462127db
add Serialize/Deserialize impls for CpuConfig 2025-11-05 23:04:20 -08:00
6ebc57eb17
update Fayalite to 0b77d1bea0 to get support for PhantomConst accessor type aliases, fork_join, and resettable 2025-11-05 23:04:00 -08:00
c30bd0737f
add readme 2025-10-24 16:36:31 -07:00
291ad59b02
update CI to use new fayalite-deps container 2025-10-24 02:54:03 -07:00
5e8bc3e580
upgrade to Fayalite edcc5927a5f9ebca6
as part of this I switched to using Fayalite's UIntInRangeInclusive instead of using a custom Length struct
2025-10-24 02:53:35 -07:00
0e7a518bd0
switch to use server's new actions org 2025-10-10 00:03:53 -07:00
16 changed files with 867 additions and 814 deletions

View file

@ -1,77 +0,0 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
# See Notices.txt for copyright information
on:
workflow_call:
outputs:
cache-primary-key:
value: ${{ jobs.deps.outputs.cache-primary-key }}
jobs:
deps:
runs-on: debian-12
outputs:
cache-primary-key: ${{ steps.restore-deps.outputs.cache-primary-key }}
steps:
- uses: https://git.libre-chip.org/mirrors/checkout@v3
with:
fetch-depth: 0
- uses: https://git.libre-chip.org/mirrors/cache/restore@v3
id: restore-deps
with:
path: deps
key: ${{ github.repository }}-deps-${{ runner.os }}-${{ hashFiles('.forgejo/workflows/deps.yml') }}
lookup-only: true
- name: Install Apt packages
if: steps.restore-deps.outputs.cache-hit != 'true'
run: |
apt-get update -qq
apt-get install -qq \
bison \
build-essential \
ccache \
clang \
cvc5 \
flex \
gawk \
g++ \
git \
libboost-filesystem-dev \
libboost-python-dev \
libboost-system-dev \
libffi-dev \
libreadline-dev \
lld \
pkg-config \
python3 \
python3-click \
tcl-dev \
zlib1g-dev
- name: Install Firtool
if: steps.restore-deps.outputs.cache-hit != 'true'
run: |
mkdir -p deps
wget -O deps/firrtl.tar.gz https://github.com/llvm/circt/releases/download/firtool-1.86.0/firrtl-bin-linux-x64.tar.gz
sha256sum -c - <<<'bf6f4ab18ae76f135c944efbd81e25391c31c1bd0617c58ab0592640abefee14 deps/firrtl.tar.gz'
tar -C deps -xvaf deps/firrtl.tar.gz
rm -rf deps/firtool
mv deps/firtool-1.86.0 deps/firtool
- name: Get SymbiYosys
if: steps.restore-deps.outputs.cache-hit != 'true'
run: |
git clone --depth=1 --branch=yosys-0.45 https://git.libre-chip.org/mirrors/sby deps/sby
- name: Build Z3
if: steps.restore-deps.outputs.cache-hit != 'true'
run: |
git clone --depth=1 --recursive --branch=z3-4.13.3 https://git.libre-chip.org/mirrors/z3 deps/z3
(cd deps/z3; PYTHON=python3 ./configure --prefix=/usr/local)
make -C deps/z3/build -j"$(nproc)"
- name: Build Yosys
if: steps.restore-deps.outputs.cache-hit != 'true'
run: |
git clone --depth=1 --recursive --branch=0.45 https://git.libre-chip.org/mirrors/yosys deps/yosys
make -C deps/yosys -j"$(nproc)"
- uses: https://git.libre-chip.org/mirrors/cache/save@v3
if: steps.restore-deps.outputs.cache-hit != 'true'
with:
path: deps
key: ${{ steps.restore-deps.outputs.cache-primary-key }}

View file

@ -3,56 +3,16 @@
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
deps:
runs-on: debian-12
uses: ./.forgejo/workflows/deps.yml
test: test:
runs-on: debian-12 runs-on: debian-12
needs: deps container:
image: git.libre-chip.org/libre-chip/fayalite-deps:latest
steps: steps:
- uses: https://git.libre-chip.org/mirrors/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- run: | - run: |
scripts/check-copyright.sh scripts/check-copyright.sh
- run: |
apt-get update -qq
apt-get install -qq \
bison \
build-essential \
ccache \
clang \
cvc5 \
flex \
gawk \
git \
libboost-filesystem-dev \
libboost-python-dev \
libboost-system-dev \
libffi-dev \
libreadline-dev \
lld \
pkg-config \
python3 \
python3-click \
tcl-dev \
z3 \
zlib1g-dev
- run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.89.0
source "$HOME/.cargo/env"
echo "$PATH" >> "$GITHUB_PATH"
- uses: https://git.libre-chip.org/mirrors/cache/restore@v3
with:
path: deps
key: ${{ needs.deps.outputs.cache-primary-key }}
fail-on-cache-miss: true
- run: |
make -C deps/z3/build install
make -C deps/sby install
make -C deps/yosys install
export PATH="$(realpath deps/firtool/bin):$PATH"
echo "$PATH" >> "$GITHUB_PATH"
- uses: https://git.libre-chip.org/mirrors/rust-cache@v2 - uses: https://git.libre-chip.org/mirrors/rust-cache@v2
with: with:
save-if: ${{ github.ref == 'refs/heads/master' }} save-if: ${{ github.ref == 'refs/heads/master' }}

167
Cargo.lock generated
View file

@ -1,18 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]] [[package]]
name = "allocator-api2" name = "allocator-api2"
@ -93,6 +81,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.6.0" version = "2.6.0"
@ -172,6 +166,15 @@ dependencies = [
"strsim", "strsim",
] ]
[[package]]
name = "clap_complete"
version = "4.5.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2348487adcd4631696ced64ccdb40d38ac4d31cae7f2eec8817fcea1b9d1c43c"
dependencies = [
"clap",
]
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.18" version = "4.5.18"
@ -207,6 +210,7 @@ name = "cpu"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"fayalite", "fayalite",
"serde",
] ]
[[package]] [[package]]
@ -300,20 +304,22 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
[[package]] [[package]]
name = "fayalite" name = "fayalite"
version = "0.3.0" version = "0.3.0"
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bd75fdfefd642f6dd2210cfb003fa63f9dce114e" source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#0b77d1bea0af932a40fd221daf65d5a9b7d62bc5"
dependencies = [ dependencies = [
"base64",
"bitvec", "bitvec",
"blake3", "blake3",
"clap", "clap",
"clap_complete",
"ctor", "ctor",
"eyre", "eyre",
"fayalite-proc-macros", "fayalite-proc-macros",
"fayalite-visit-gen", "fayalite-visit-gen",
"hashbrown", "hashbrown 0.15.5",
"jobslot", "jobslot",
"num-bigint", "num-bigint",
"num-traits", "num-traits",
"os_pipe", "ordered-float",
"petgraph", "petgraph",
"serde", "serde",
"serde_json", "serde_json",
@ -325,7 +331,7 @@ dependencies = [
[[package]] [[package]]
name = "fayalite-proc-macros" name = "fayalite-proc-macros"
version = "0.3.0" version = "0.3.0"
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bd75fdfefd642f6dd2210cfb003fa63f9dce114e" source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#0b77d1bea0af932a40fd221daf65d5a9b7d62bc5"
dependencies = [ dependencies = [
"fayalite-proc-macros-impl", "fayalite-proc-macros-impl",
] ]
@ -333,7 +339,7 @@ dependencies = [
[[package]] [[package]]
name = "fayalite-proc-macros-impl" name = "fayalite-proc-macros-impl"
version = "0.3.0" version = "0.3.0"
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bd75fdfefd642f6dd2210cfb003fa63f9dce114e" source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#0b77d1bea0af932a40fd221daf65d5a9b7d62bc5"
dependencies = [ dependencies = [
"base16ct", "base16ct",
"num-bigint", "num-bigint",
@ -348,7 +354,7 @@ dependencies = [
[[package]] [[package]]
name = "fayalite-visit-gen" name = "fayalite-visit-gen"
version = "0.3.0" version = "0.3.0"
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bd75fdfefd642f6dd2210cfb003fa63f9dce114e" source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#0b77d1bea0af932a40fd221daf65d5a9b7d62bc5"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"prettyplease", "prettyplease",
@ -366,6 +372,12 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]] [[package]]
name = "funty" name = "funty"
version = "2.0.0" version = "2.0.0"
@ -384,13 +396,14 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.15" version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"wasi", "r-efi",
"wasip2",
] ]
[[package]] [[package]]
@ -398,9 +411,16 @@ name = "hashbrown"
version = "0.14.5" version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [ dependencies = [
"ahash",
"allocator-api2", "allocator-api2",
"equivalent",
"foldhash",
] ]
[[package]] [[package]]
@ -431,7 +451,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown 0.14.5",
"serde", "serde",
] ]
@ -449,16 +469,16 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]] [[package]]
name = "jobslot" name = "jobslot"
version = "0.2.19" version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe10868679d7a24c2c67d862d0e64a342ce9aef7cdde9ce8019bd35d353d458d" checksum = "58715c67c327da7f1558708348d68c207fd54900c4ae0529e29305d04d795b8c"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"derive_destructure2", "derive_destructure2",
"getrandom", "getrandom",
"libc", "libc",
"scopeguard", "scopeguard",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -514,22 +534,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]] [[package]]
name = "os_pipe" name = "ordered-float"
version = "1.2.1" version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d"
dependencies = [ dependencies = [
"libc", "num-traits",
"windows-sys 0.59.0", "rand",
"serde",
] ]
[[package]] [[package]]
name = "petgraph" name = "petgraph"
version = "0.6.5" version = "0.8.3"
source = "git+https://github.com/programmerjake/petgraph.git?rev=258ea8071209a924b73fe96f9f87a3b7b45cbc9f#258ea8071209a924b73fe96f9f87a3b7b45cbc9f" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
dependencies = [ dependencies = [
"fixedbitset", "fixedbitset",
"hashbrown 0.15.5",
"indexmap", "indexmap",
"serde",
] ]
[[package]] [[package]]
@ -560,12 +584,37 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]] [[package]]
name = "radium" name = "radium"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"rand_core",
"serde",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.37" version = "0.38.37"
@ -728,10 +777,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "wasi" name = "wasip2"
version = "0.11.0+wasi-snapshot-preview1" version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
dependencies = [
"wit-bindgen",
]
[[package]] [[package]]
name = "which" name = "which"
@ -745,6 +797,12 @@ dependencies = [
"winsafe", "winsafe",
] ]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
@ -763,6 +821,15 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.52.6" version = "0.52.6"
@ -833,6 +900,12 @@ version = "0.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
[[package]]
name = "wit-bindgen"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
[[package]] [[package]]
name = "wyz" name = "wyz"
version = "0.5.1" version = "0.5.1"
@ -841,23 +914,3 @@ checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [ dependencies = [
"tap", "tap",
] ]
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View file

@ -15,6 +15,7 @@ rust-version = "1.89.0"
[workspace.dependencies] [workspace.dependencies]
fayalite = { git = "https://git.libre-chip.org/libre-chip/fayalite.git", version = "0.3.0", branch = "master" } fayalite = { git = "https://git.libre-chip.org/libre-chip/fayalite.git", version = "0.3.0", branch = "master" }
serde = { version = "1.0.202", features = ["derive"] }
[profile.dev] [profile.dev]
opt-level = 1 opt-level = 1

15
README.md Normal file
View file

@ -0,0 +1,15 @@
<!--
SPDX-License-Identifier: LGPL-3.0-or-later
See Notices.txt for copyright information
-->
# Libre-Chip's CPU
<https://libre-chip.org/first_arch/index.html>
# Funding
## NLnet Grants
* [Libre-Chip CPU with proof of No Spectre bugs](https://nlnet.nl/project/Libre-Chip-proof/) 2024-12-324 [(progress)](https://git.libre-chip.org/libre-chip/grant-tracking/src/branch/master/nlnet-2024-12-324/progress.md)
This project was funded through the [NGI0 Commons Fund](https://nlnet.nl/commonsfund), a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) programme, under the aegis of [DG Communications Networks, Content and Technology](https://commission.europa.eu/about-european-commission/departments-and-executive-agencies/communications-networks-content-and-technology_en) under grant agreement &numero; [101135429](https://cordis.europa.eu/project/id/101135429). Additional funding is made available by the [Swiss State Secretariat for Education, Research and Innovation](https://www.sbfi.admin.ch/sbfi/en/home.html) (SERI).

View file

@ -16,3 +16,4 @@ version.workspace = true
[dependencies] [dependencies]
fayalite.workspace = true fayalite.workspace = true
serde.workspace = true

1
crates/cpu/README.md Symbolic link
View file

@ -0,0 +1 @@
../../README.md

View file

@ -8,9 +8,10 @@ use crate::{
}, },
}; };
use fayalite::prelude::*; use fayalite::prelude::*;
use serde::{Deserialize, Serialize};
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
#[derive(Clone, Eq, PartialEq, Hash, Debug)] #[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
#[non_exhaustive] #[non_exhaustive]
pub struct UnitConfig { pub struct UnitConfig {
pub kind: UnitKind, pub kind: UnitKind,
@ -27,12 +28,14 @@ impl UnitConfig {
} }
} }
#[derive(Clone, Eq, PartialEq, Hash, Debug)] #[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
#[non_exhaustive] #[non_exhaustive]
pub struct CpuConfig { pub struct CpuConfig {
pub units: Vec<UnitConfig>, pub units: Vec<UnitConfig>,
pub out_reg_num_width: usize, pub out_reg_num_width: usize,
pub fetch_width: NonZeroUsize, pub fetch_width: NonZeroUsize,
pub max_branches_per_fetch: NonZeroUsize,
pub fetch_width_in_bytes: NonZeroUsize,
/// default value for [`UnitConfig::max_in_flight`] /// default value for [`UnitConfig::max_in_flight`]
pub default_unit_max_in_flight: NonZeroUsize, pub default_unit_max_in_flight: NonZeroUsize,
pub rob_size: NonZeroUsize, pub rob_size: NonZeroUsize,
@ -46,6 +49,18 @@ impl CpuConfig {
}; };
v v
}; };
pub const DEFAULT_MAX_BRANCHES_PER_FETCH: NonZeroUsize = {
let Some(v) = NonZeroUsize::new(1) else {
unreachable!();
};
v
};
pub const DEFAULT_FETCH_WIDTH_IN_BYTES: NonZeroUsize = {
let Some(v) = NonZeroUsize::new(4) else {
unreachable!();
};
v
};
pub const DEFAULT_UNIT_MAX_IN_FLIGHT: NonZeroUsize = { pub const DEFAULT_UNIT_MAX_IN_FLIGHT: NonZeroUsize = {
let Some(v) = NonZeroUsize::new(8) else { let Some(v) = NonZeroUsize::new(8) else {
unreachable!(); unreachable!();
@ -57,6 +72,8 @@ impl CpuConfig {
units, units,
out_reg_num_width: Self::DEFAULT_OUT_REG_NUM_WIDTH, out_reg_num_width: Self::DEFAULT_OUT_REG_NUM_WIDTH,
fetch_width: Self::DEFAULT_FETCH_WIDTH, fetch_width: Self::DEFAULT_FETCH_WIDTH,
max_branches_per_fetch: Self::DEFAULT_MAX_BRANCHES_PER_FETCH,
fetch_width_in_bytes: Self::DEFAULT_FETCH_WIDTH_IN_BYTES,
default_unit_max_in_flight: Self::DEFAULT_UNIT_MAX_IN_FLIGHT, default_unit_max_in_flight: Self::DEFAULT_UNIT_MAX_IN_FLIGHT,
rob_size, rob_size,
} }
@ -117,3 +134,12 @@ impl CpuConfig {
[self.non_const_unit_nums().len()] [self.non_const_unit_nums().len()]
} }
} }
#[hdl(get(|c| c.fetch_width.get()))]
pub type CpuConfigFetchWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(get(|c| c.max_branches_per_fetch.get()))]
pub type CpuConfigMaxBranchesPerFetch<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(get(|c| c.fetch_width_in_bytes.get()))]
pub type CpuConfigFetchWidthInBytes<C: PhantomConstGet<CpuConfig>> = DynSize;

View file

@ -5,6 +5,7 @@ use fayalite::{
expr::ops::{ArrayLiteral, ExprPartialEq}, expr::ops::{ArrayLiteral, ExprPartialEq},
intern::Interned, intern::Interned,
prelude::*, prelude::*,
sim::value::SimValuePartialEq,
}; };
use std::{fmt, marker::PhantomData, ops::Range}; use std::{fmt, marker::PhantomData, ops::Range};
@ -181,6 +182,12 @@ impl ExprPartialEq<Self> for OutputIntegerMode {
} }
} }
impl SimValuePartialEq<Self> for OutputIntegerMode {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
SimValue::opaque(this) == SimValue::opaque(other)
}
}
pub const MOP_IMM_WIDTH: usize = 34; pub const MOP_IMM_WIDTH: usize = 34;
pub const MOP_MIN_REG_WIDTH: usize = 8; pub const MOP_MIN_REG_WIDTH: usize = 8;
pub const COMMON_MOP_SRC_LEN: usize = 3; pub const COMMON_MOP_SRC_LEN: usize = 3;

View file

@ -2,6 +2,7 @@
// See Notices.txt for copyright information // See Notices.txt for copyright information
pub mod config; pub mod config;
pub mod instruction; pub mod instruction;
pub mod next_pc;
pub mod reg_alloc; pub mod reg_alloc;
pub mod register; pub mod register;
pub mod unit; pub mod unit;

206
crates/cpu/src/next_pc.rs Normal file
View file

@ -0,0 +1,206 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
//! [Next-Instruction Logic](https://git.libre-chip.org/libre-chip/grant-tracking/issues/10)
//!
//! The basic idea here is that there's a `next_pc` stage that sends predicted fetch PCs to the `fetch` stage,
//! the `fetch` stage's outputs eventually end up in the `decode` stage,
//! after the `decode` stage there's a `post_decode` stage (that may run in the same clock cycle as `decode`)
//! that checks that the fetched instructions' kinds match the predicted instruction kinds and that feeds
//! information back to the `fetch` stage to cancel fetches that need to be predicted differently.
use crate::{config::CpuConfig, util::array_vec::ArrayVec};
use fayalite::prelude::*;
use fayalite::util::ready_valid::ReadyValid;
use std::collections::{HashMap, VecDeque};
#[hdl]
pub enum PredictedCond {
Taken,
Fallthrough,
}
#[hdl]
pub struct PredictedFallthrough {}
#[hdl]
pub enum BranchPredictionKind<CondKind> {
Branch(HdlOption<CondKind>),
IndirectBranch(HdlOption<CondKind>),
Call(HdlOption<CondKind>),
IndirectCall(HdlOption<CondKind>),
Ret(HdlOption<CondKind>),
}
#[hdl(get(|c| c.max_branches_per_fetch.get() - 1))]
pub type NextPcPredictionMaxBranchesBeforeLast<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(no_static)]
pub struct NextPcPrediction<C: PhantomConstGet<CpuConfig>> {
pub fetch_pc: UInt<64>,
pub async_interrupt: Bool,
pub branches_before_last: ArrayVec<
BranchPredictionKind<PredictedFallthrough>,
NextPcPredictionMaxBranchesBeforeLast<C>,
>,
pub last_branch: HdlOption<BranchPredictionKind<PredictedCond>>,
pub last_branch_target_pc: UInt<64>,
}
#[hdl]
pub struct NextPcToFetchInterfaceInner {
pub next_fetch_pc: UInt<64>,
pub fetch_block_id: UInt<8>,
pub in_progress_fetches_to_cancel: UInt<8>,
}
#[hdl(no_static)]
pub struct NextPcToFetchInterface<C: PhantomConstGet<CpuConfig>> {
pub inner: ReadyValid<NextPcToFetchInterfaceInner>,
pub config: C,
}
#[hdl]
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`] since the actual instruction definition isn't finalized yet. This will be replaced at a later point.
pub enum WipDecodedInsnKind {
NonBranch,
Branch(UInt<64>),
BranchCond(UInt<64>),
IndirectBranch,
IndirectBranchCond,
Call(UInt<64>),
CallCond(UInt<64>),
IndirectCall,
IndirectCallCond,
Ret,
RetCond,
/// not actually an instruction read from memory, covers stuff like external interrupts, page faults, memory errors, and so on.
Interrupt(UInt<64>),
}
#[hdl]
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`] since the actual instruction definition isn't finalized yet. This will be replaced at a later point.
pub struct WipDecodedInsn {
pub fetch_block_id: UInt<8>,
pub id: UInt<12>,
pub pc: UInt<64>,
pub kind: WipDecodedInsnKind,
}
#[hdl(no_static)]
/// handles updating speculative branch predictor state (e.g. branch histories) when instructions retire,
/// as well as updating state when a branch instruction is mis-speculated.
pub struct NextPcToRetireInterface<C: PhantomConstGet<CpuConfig>> {
// TODO: add needed fields
pub config: C,
}
#[hdl(no_static)]
pub struct DecodeToPostDecodeInterface<C: PhantomConstGet<CpuConfig>> {
// TODO: add needed fields
pub config: C,
}
#[hdl(no_static)]
pub struct PostDecodeOutputInterface<C: PhantomConstGet<CpuConfig>> {
// TODO: add needed fields
pub config: C,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
enum BranchPredictionState {
StronglyNotTaken,
#[default]
WeaklyNotTaken,
WeaklyTaken,
StronglyTaken,
}
impl BranchPredictionState {
#[must_use]
fn is_taken(self) -> bool {
match self {
Self::StronglyNotTaken => false,
Self::WeaklyNotTaken => false,
Self::WeaklyTaken => true,
Self::StronglyTaken => true,
}
}
#[must_use]
fn towards_taken(self) -> Self {
match self {
Self::StronglyNotTaken => Self::WeaklyNotTaken,
Self::WeaklyNotTaken => Self::WeaklyTaken,
Self::WeaklyTaken => Self::StronglyTaken,
Self::StronglyTaken => Self::StronglyTaken,
}
}
#[must_use]
fn towards_not_taken(self) -> Self {
match self {
Self::StronglyNotTaken => Self::StronglyNotTaken,
Self::WeaklyNotTaken => Self::StronglyNotTaken,
Self::WeaklyTaken => Self::WeaklyNotTaken,
Self::StronglyTaken => Self::WeaklyTaken,
}
}
}
struct NextPcState {
call_stack: Vec<u64>,
branch_target_buffer: HashMap<u64, u64>,
history: VecDeque<bool>,
speculative_history_len: usize,
branch_predictor: Box<[BranchPredictionState; Self::BRANCH_PREDICTOR_SIZE]>,
}
impl NextPcState {
const BRANCH_PREDICTOR_LOG2_SIZE: usize = 8;
const BRANCH_PREDICTOR_SIZE: usize = 1 << Self::BRANCH_PREDICTOR_LOG2_SIZE;
fn branch_predictor_index(&self, pc: u64) -> usize {
let mut history = 0u64;
for i in 0..Self::BRANCH_PREDICTOR_LOG2_SIZE {
history <<= 1;
if self.history.get(i).copied().unwrap_or(false) {
history |= 1;
}
}
let mut t = history;
t ^= t.rotate_left(5) & !pc.rotate_right(3);
t ^= pc;
t ^= !t.rotate_left(2) & t.rotate_left(4);
let mut retval = 0;
for i in (0..Self::BRANCH_PREDICTOR_LOG2_SIZE).step_by(Self::BRANCH_PREDICTOR_LOG2_SIZE) {
retval ^= t >> i;
}
retval as usize % Self::BRANCH_PREDICTOR_SIZE
}
}
impl Default for NextPcState {
fn default() -> Self {
Self {
call_stack: Default::default(),
branch_target_buffer: Default::default(),
history: Default::default(),
speculative_history_len: Default::default(),
branch_predictor: vec![Default::default(); Self::BRANCH_PREDICTOR_SIZE]
.try_into()
.expect("has right size"),
}
}
}
#[hdl_module(extern)]
pub fn next_pc(config: PhantomConst<CpuConfig>) {
#[hdl]
let cd: ClockDomain = m.input();
m.extern_module_simulation_fn((cd,), |(cd,), mut sim| async move {
sim.resettable(
cd,
|mut sim: ExternModuleSimulationState| async move { NextPcState::default() },
|mut sim: ExternModuleSimulationState, mut state| async move {},
)
.await;
});
}

View file

@ -120,10 +120,7 @@ pub fn unit_free_regs_tracker(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use fayalite::{ use fayalite::{firrtl::ExportOptions, module::transform::simplify_enums::SimplifyEnumsKind};
cli::FormalMode, firrtl::ExportOptions,
module::transform::simplify_enums::SimplifyEnumsKind, testing::assert_formal,
};
use std::num::NonZero; use std::num::NonZero;
fn test_unit_free_regs_tracker( fn test_unit_free_regs_tracker(

View file

@ -15,6 +15,7 @@ use fayalite::{
intern::{Intern, Interned}, intern::{Intern, Interned},
prelude::*, prelude::*,
}; };
use serde::{Deserialize, Serialize};
pub mod alu_branch; pub mod alu_branch;
pub mod unit_base; pub mod unit_base;
@ -36,7 +37,7 @@ macro_rules! all_units {
} }
) => { ) => {
$(#[$enum_meta])* $(#[$enum_meta])*
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Serialize, Deserialize)]
$vis enum $UnitKind { $vis enum $UnitKind {
$( $(
$(#[$variant_meta])* $(#[$variant_meta])*

View file

@ -1,147 +1,10 @@
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information // See Notices.txt for copyright information
use fayalite::{ use fayalite::{expr::ops::ExprIndex, int::UIntInRangeInclusiveType, prelude::*};
expr::ops::{ExprCastTo, ExprIndex, ExprPartialEq, ExprPartialOrd},
int::SizeType,
intern::{Intern, Interned},
prelude::*,
ty::{MatchVariantWithoutScope, StaticType, TypeProperties},
};
use std::{marker::PhantomData, ops::Index};
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[hdl]
pub struct Length<Max: Size> { pub type Length<Max: Size> = UIntInRangeInclusiveType<ConstUsize<0>, Max>;
ty: UInt,
_phantom: PhantomData<Max>,
}
impl<Max: Size> Length<Max> {
pub fn new(max: Max::SizeType) -> Self {
Self {
ty: UInt::range_inclusive(0..=Max::as_usize(max)),
_phantom: PhantomData,
}
}
pub fn ty(self) -> UInt {
self.ty
}
pub fn zero(self) -> Expr<Self> {
Self::from_uint_unchecked(self.ty.zero())
}
pub fn from_uint_unchecked(v: impl ToExpr<Type = UInt>) -> Expr<Self> {
Expr::from_canonical(Expr::canonical(v.to_expr()))
}
pub fn cast_from_uint_unchecked<SrcWidth: Size>(
self,
v: impl ToExpr<Type = UIntType<SrcWidth>>,
) -> Expr<Self> {
Self::from_uint_unchecked(v.to_expr().cast_to(self.ty))
}
pub fn as_uint(this: impl ToExpr<Type = Self>) -> Expr<UInt> {
let this = this.to_expr();
this.cast_to(Expr::ty(this).ty)
}
}
impl<Max: Size, DestWidth: Size> ExprCastTo<UIntType<DestWidth>> for Length<Max> {
fn cast_to(src: Expr<Self>, to_type: UIntType<DestWidth>) -> Expr<UIntType<DestWidth>> {
Expr::<UInt>::from_canonical(Expr::canonical(src)).cast_to(to_type)
}
}
#[allow(non_upper_case_globals)]
pub const Length: __LengthWithoutGenerics = __LengthWithoutGenerics {};
#[non_exhaustive]
pub struct __LengthWithoutGenerics {}
impl<M: SizeType> Index<M> for __LengthWithoutGenerics {
type Output = Length<M::Size>;
fn index(&self, max: M) -> &Self::Output {
Interned::into_inner(Length::new(max).intern_sized())
}
}
impl<Max: Size> Type for Length<Max> {
type BaseType = UInt;
type MaskType = Bool;
type MatchVariant = Expr<Self>;
type MatchActiveScope = ();
type MatchVariantAndInactiveScope = MatchVariantWithoutScope<Self::MatchVariant>;
type MatchVariantsIter = std::iter::Once<Self::MatchVariantAndInactiveScope>;
fn match_variants(
this: Expr<Self>,
source_location: SourceLocation,
) -> Self::MatchVariantsIter {
let _ = source_location;
std::iter::once(MatchVariantWithoutScope(this))
}
fn mask_type(&self) -> Self::MaskType {
Bool
}
fn canonical(&self) -> CanonicalType {
self.ty.canonical()
}
fn from_canonical(canonical_type: CanonicalType) -> Self {
let ty = <UInt>::from_canonical(canonical_type);
if let Some(known_max) = Max::KNOWN_VALUE {
assert_eq!(ty, UInt::range_inclusive(0..=known_max));
}
Self {
ty,
_phantom: PhantomData,
}
}
fn source_location() -> SourceLocation {
SourceLocation::caller()
}
}
impl<Max: KnownSize> StaticType for Length<Max> {
const TYPE: Self = Self {
ty: UInt {
width: Max::VALUE.next_power_of_two().ilog2() as usize,
},
_phantom: PhantomData,
};
const MASK_TYPE: Self::MaskType = Bool;
const TYPE_PROPERTIES: TypeProperties = {
let mut p = <UInt<1>>::TYPE_PROPERTIES;
p.bit_width = Self::TYPE.ty.width;
p
};
const MASK_TYPE_PROPERTIES: TypeProperties = Bool::TYPE_PROPERTIES;
}
impl<Max: Size> ExprPartialEq<Self> for Length<Max> {
fn cmp_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
Self::as_uint(lhs).cmp_eq(Self::as_uint(rhs))
}
fn cmp_ne(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
Self::as_uint(lhs).cmp_ne(Self::as_uint(rhs))
}
}
impl<Max: Size> ExprPartialOrd<Self> for Length<Max> {
fn cmp_lt(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
Self::as_uint(lhs).cmp_lt(Self::as_uint(rhs))
}
fn cmp_le(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
Self::as_uint(lhs).cmp_le(Self::as_uint(rhs))
}
fn cmp_gt(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
Self::as_uint(lhs).cmp_gt(Self::as_uint(rhs))
}
fn cmp_ge(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
Self::as_uint(lhs).cmp_ge(Self::as_uint(rhs))
}
}
/// like [`std::vec::Vec`], except with a [`Expr`] for [`len()`][`Self::len()`] and a fixed capacity /// like [`std::vec::Vec`], except with a [`Expr`] for [`len()`][`Self::len()`] and a fixed capacity
#[hdl] #[hdl]
@ -156,7 +19,7 @@ impl<T: Type, N: Size> ArrayVec<T, N> {
#[hdl] #[hdl]
ArrayVec { ArrayVec {
elements: self.elements.uninit(), elements: self.elements.uninit(),
len: self.len.zero(), len: 0u8.cast_to(self.len),
} }
} }
pub fn element(self) -> T { pub fn element(self) -> T {
@ -176,7 +39,7 @@ impl<T: Type, N: Size> ArrayVec<T, N> {
let elements = elements.to_expr(); let elements = elements.to_expr();
let len = len.to_expr(); let len = len.to_expr();
assert_eq!( assert_eq!(
Length::new(N::from_usize(Expr::ty(elements).len())), Length[N::from_usize(Expr::ty(elements).len())],
Expr::ty(len), Expr::ty(len),
"len type mismatch", "len type mismatch",
); );
@ -191,7 +54,7 @@ impl<T: Type, N: Size> ArrayVec<T, N> {
} }
pub fn is_empty(this: impl ToExpr<Type = Self>) -> Expr<Bool> { pub fn is_empty(this: impl ToExpr<Type = Self>) -> Expr<Bool> {
let len = Self::len(this); let len = Self::len(this);
len.cmp_eq(Expr::ty(len).zero()) len.cmp_eq(0u8)
} }
pub fn capacity(self) -> usize { pub fn capacity(self) -> usize {
self.elements.len() self.elements.len()
@ -207,7 +70,7 @@ impl<T: Type, N: Size> ArrayVec<T, N> {
let this = this.to_expr(); let this = this.to_expr();
for (index, element) in this.elements.into_iter().enumerate() { for (index, element) in this.elements.into_iter().enumerate() {
#[hdl] #[hdl]
if index.cmp_lt(Length::as_uint(this.len)) { if index.cmp_lt(this.len) {
f(index, element); f(index, element);
} }
} }

View file

@ -16832,38 +16832,6 @@ $upscope $end
$upscope $end $upscope $end
$enddefinitions $end $enddefinitions $end
$dumpvars $dumpvars
0vg
0wg
0xg
0yg
0zg
0{g
0|g
0}g
0~g
0!h
0"h
0#h
0$h
0%h
0&h
0'h
0(h
0)h
0*h
0+h
0,h
0-h
0.h
0/h
00h
01h
02h
03h
04h
05h
06h
07h
b0 (_ b0 (_
b0 ia b0 ia
b0 )_ b0 )_
@ -17370,6 +17338,26 @@ b0 ga
b0 Jd b0 Jd
b0 ha b0 ha
b0 Kd b0 Kd
b0 Ld
b0 Nd
b0 Md
b0 Od
0Pd
0Qd
0Rd
0Sd
0Td
0Ud
0Vd
0Wd
0Xd
0Yd
0Zd
0[d
0\d
0]d
0^d
0_d
0`d 0`d
0ad 0ad
0bd 0bd
@ -17386,438 +17374,6 @@ b0 Kd
0md 0md
0nd 0nd
0od 0od
b0 8h
0Hh
0Xh
0hh
0xh
0*i
0:i
0Ji
0Zi
b0 9h
0Ih
0Yh
0ih
0yh
0+i
0;i
0Ki
0[i
b0 :h
0Jh
0Zh
0jh
0zh
0,i
0<i
0Li
0\i
b0 ;h
0Kh
0[h
0kh
0{h
0-i
0=i
0Mi
0]i
b0 <h
0Lh
0\h
0lh
0|h
0.i
0>i
0Ni
0^i
b0 =h
0Mh
0]h
0mh
0}h
0/i
0?i
0Oi
0_i
b0 >h
0Nh
0^h
0nh
0~h
00i
0@i
0Pi
0`i
b0 ?h
0Oh
0_h
0oh
0!i
01i
0Ai
0Qi
0ai
b0 @h
0Ph
0`h
0ph
0"i
02i
0Bi
0Ri
0bi
b0 Ah
0Qh
0ah
0qh
0#i
03i
0Ci
0Si
0ci
b0 Bh
0Rh
0bh
0rh
0$i
04i
0Di
0Ti
0di
b0 Ch
0Sh
0ch
0sh
0%i
05i
0Ei
0Ui
0ei
b0 Dh
0Th
0dh
0th
0&i
06i
0Fi
0Vi
0fi
b0 Eh
0Uh
0eh
0uh
0'i
07i
0Gi
0Wi
0gi
b0 Fh
0Vh
0fh
0vh
0(i
08i
0Hi
0Xi
0hi
b0 Gh
0Wh
0gh
0wh
0)i
09i
0Ii
0Yi
0ii
b0 Df
0Tf
0df
0tf
0&g
06g
0Fg
0Vg
0fg
b0 Ef
0Uf
0ef
0uf
0'g
07g
0Gg
0Wg
0gg
b0 Ff
0Vf
0ff
0vf
0(g
08g
0Hg
0Xg
0hg
b0 Gf
0Wf
0gf
0wf
0)g
09g
0Ig
0Yg
0ig
b0 Hf
0Xf
0hf
0xf
0*g
0:g
0Jg
0Zg
0jg
b0 If
0Yf
0if
0yf
0+g
0;g
0Kg
0[g
0kg
b0 Jf
0Zf
0jf
0zf
0,g
0<g
0Lg
0\g
0lg
b0 Kf
0[f
0kf
0{f
0-g
0=g
0Mg
0]g
0mg
b0 Lf
0\f
0lf
0|f
0.g
0>g
0Ng
0^g
0ng
b0 Mf
0]f
0mf
0}f
0/g
0?g
0Og
0_g
0og
b0 Nf
0^f
0nf
0~f
00g
0@g
0Pg
0`g
0pg
b0 Of
0_f
0of
0!g
01g
0Ag
0Qg
0ag
0qg
b0 Pf
0`f
0pf
0"g
02g
0Bg
0Rg
0bg
0rg
b0 Qf
0af
0qf
0#g
03g
0Cg
0Sg
0cg
0sg
b0 Rf
0bf
0rf
0$g
04g
0Dg
0Tg
0dg
0tg
b0 Sf
0cf
0sf
0%g
05g
0Eg
0Ug
0eg
0ug
b0 ji
0zi
0,j
0<j
0Lj
0\j
0lj
0|j
0.k
b0 ki
0{i
0-j
0=j
0Mj
0]j
0mj
0}j
0/k
b0 li
0|i
0.j
0>j
0Nj
0^j
0nj
0~j
00k
b0 mi
0}i
0/j
0?j
0Oj
0_j
0oj
0!k
01k
b0 ni
0~i
00j
0@j
0Pj
0`j
0pj
0"k
02k
b0 oi
0!j
01j
0Aj
0Qj
0aj
0qj
0#k
03k
b0 pi
0"j
02j
0Bj
0Rj
0bj
0rj
0$k
04k
b0 qi
0#j
03j
0Cj
0Sj
0cj
0sj
0%k
05k
b0 ri
0$j
04j
0Dj
0Tj
0dj
0tj
0&k
06k
b0 si
0%j
05j
0Ej
0Uj
0ej
0uj
0'k
07k
b0 ti
0&j
06j
0Fj
0Vj
0fj
0vj
0(k
08k
b0 ui
0'j
07j
0Gj
0Wj
0gj
0wj
0)k
09k
b0 vi
0(j
08j
0Hj
0Xj
0hj
0xj
0*k
0:k
b0 wi
0)j
09j
0Ij
0Yj
0ij
0yj
0+k
0;k
b0 xi
0*j
0:j
0Jj
0Zj
0jj
0zj
0,k
0<k
b0 yi
0+j
0;j
0Kj
0[j
0kj
0{j
0-k
0=k
b0 pd b0 pd
0"e 0"e
02e 02e
@ -17962,26 +17518,470 @@ b0 !e
0#f 0#f
03f 03f
0Cf 0Cf
0Pd b0 Df
0Qd 0Tf
0Rd 0df
0Sd 0tf
0Td 0&g
0Ud 06g
0Vd 0Fg
0Wd 0Vg
0Xd 0fg
0Yd b0 Ef
0Zd 0Uf
0[d 0ef
0\d 0uf
0]d 0'g
0^d 07g
0_d 0Gg
b0 Ld 0Wg
b0 Nd 0gg
b0 Md b0 Ff
b0 Od 0Vf
0ff
0vf
0(g
08g
0Hg
0Xg
0hg
b0 Gf
0Wf
0gf
0wf
0)g
09g
0Ig
0Yg
0ig
b0 Hf
0Xf
0hf
0xf
0*g
0:g
0Jg
0Zg
0jg
b0 If
0Yf
0if
0yf
0+g
0;g
0Kg
0[g
0kg
b0 Jf
0Zf
0jf
0zf
0,g
0<g
0Lg
0\g
0lg
b0 Kf
0[f
0kf
0{f
0-g
0=g
0Mg
0]g
0mg
b0 Lf
0\f
0lf
0|f
0.g
0>g
0Ng
0^g
0ng
b0 Mf
0]f
0mf
0}f
0/g
0?g
0Og
0_g
0og
b0 Nf
0^f
0nf
0~f
00g
0@g
0Pg
0`g
0pg
b0 Of
0_f
0of
0!g
01g
0Ag
0Qg
0ag
0qg
b0 Pf
0`f
0pf
0"g
02g
0Bg
0Rg
0bg
0rg
b0 Qf
0af
0qf
0#g
03g
0Cg
0Sg
0cg
0sg
b0 Rf
0bf
0rf
0$g
04g
0Dg
0Tg
0dg
0tg
b0 Sf
0cf
0sf
0%g
05g
0Eg
0Ug
0eg
0ug
0vg
0wg
0xg
0yg
0zg
0{g
0|g
0}g
0~g
0!h
0"h
0#h
0$h
0%h
0&h
0'h
0(h
0)h
0*h
0+h
0,h
0-h
0.h
0/h
00h
01h
02h
03h
04h
05h
06h
07h
b0 8h
0Hh
0Xh
0hh
0xh
0*i
0:i
0Ji
0Zi
b0 9h
0Ih
0Yh
0ih
0yh
0+i
0;i
0Ki
0[i
b0 :h
0Jh
0Zh
0jh
0zh
0,i
0<i
0Li
0\i
b0 ;h
0Kh
0[h
0kh
0{h
0-i
0=i
0Mi
0]i
b0 <h
0Lh
0\h
0lh
0|h
0.i
0>i
0Ni
0^i
b0 =h
0Mh
0]h
0mh
0}h
0/i
0?i
0Oi
0_i
b0 >h
0Nh
0^h
0nh
0~h
00i
0@i
0Pi
0`i
b0 ?h
0Oh
0_h
0oh
0!i
01i
0Ai
0Qi
0ai
b0 @h
0Ph
0`h
0ph
0"i
02i
0Bi
0Ri
0bi
b0 Ah
0Qh
0ah
0qh
0#i
03i
0Ci
0Si
0ci
b0 Bh
0Rh
0bh
0rh
0$i
04i
0Di
0Ti
0di
b0 Ch
0Sh
0ch
0sh
0%i
05i
0Ei
0Ui
0ei
b0 Dh
0Th
0dh
0th
0&i
06i
0Fi
0Vi
0fi
b0 Eh
0Uh
0eh
0uh
0'i
07i
0Gi
0Wi
0gi
b0 Fh
0Vh
0fh
0vh
0(i
08i
0Hi
0Xi
0hi
b0 Gh
0Wh
0gh
0wh
0)i
09i
0Ii
0Yi
0ii
b0 ji
0zi
0,j
0<j
0Lj
0\j
0lj
0|j
0.k
b0 ki
0{i
0-j
0=j
0Mj
0]j
0mj
0}j
0/k
b0 li
0|i
0.j
0>j
0Nj
0^j
0nj
0~j
00k
b0 mi
0}i
0/j
0?j
0Oj
0_j
0oj
0!k
01k
b0 ni
0~i
00j
0@j
0Pj
0`j
0pj
0"k
02k
b0 oi
0!j
01j
0Aj
0Qj
0aj
0qj
0#k
03k
b0 pi
0"j
02j
0Bj
0Rj
0bj
0rj
0$k
04k
b0 qi
0#j
03j
0Cj
0Sj
0cj
0sj
0%k
05k
b0 ri
0$j
04j
0Dj
0Tj
0dj
0tj
0&k
06k
b0 si
0%j
05j
0Ej
0Uj
0ej
0uj
0'k
07k
b0 ti
0&j
06j
0Fj
0Vj
0fj
0vj
0(k
08k
b0 ui
0'j
07j
0Gj
0Wj
0gj
0wj
0)k
09k
b0 vi
0(j
08j
0Hj
0Xj
0hj
0xj
0*k
0:k
b0 wi
0)j
09j
0Ij
0Yj
0ij
0yj
0+k
0;k
b0 xi
0*j
0:j
0Jj
0Zj
0jj
0zj
0,k
0<k
b0 yi
0+j
0;j
0Kj
0[j
0kj
0{j
0-k
0=k
0! 0!
1" 1"
sHdlSome\x20(1) # sHdlSome\x20(1) #

View file

@ -9,8 +9,6 @@ use cpu::{
unit::{GlobalState, UnitKind}, unit::{GlobalState, UnitKind},
}; };
use fayalite::{ use fayalite::{
assert_export_firrtl,
firrtl::ExportOptions,
prelude::*, prelude::*,
sim::{Simulation, time::SimDuration, vcd::VcdWriterDecls}, sim::{Simulation, time::SimDuration, vcd::VcdWriterDecls},
util::RcWriter, util::RcWriter,