start adding cpu data types
This commit is contained in:
commit
0f4f067996
12 changed files with 1190 additions and 0 deletions
18
crates/cpu/Cargo.toml
Normal file
18
crates/cpu/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
|||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
# See Notices.txt for copyright information
|
||||
[package]
|
||||
name = "cpu"
|
||||
description = "CPU"
|
||||
workspace = "../.."
|
||||
readme = "README.md"
|
||||
publish = false
|
||||
categories.workspace = true
|
||||
edition.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
fayalite.workspace = true
|
1
crates/cpu/LICENSE.md
Symbolic link
1
crates/cpu/LICENSE.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../LICENSE.md
|
1
crates/cpu/Notices.txt
Symbolic link
1
crates/cpu/Notices.txt
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../Notices.txt
|
14
crates/cpu/src/config.rs
Normal file
14
crates/cpu/src/config.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
use crate::instruction::{UnitKind, UnitNum};
|
||||
use fayalite::prelude::*;
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub struct CpuConfig {
|
||||
pub units: Vec<UnitKind>,
|
||||
}
|
||||
|
||||
impl CpuConfig {
|
||||
pub fn unit_num(&self) -> UnitNum<DynSize> {
|
||||
UnitNum[UInt::range(0..self.units.len()).width()]
|
||||
}
|
||||
}
|
155
crates/cpu/src/instruction.rs
Normal file
155
crates/cpu/src/instruction.rs
Normal file
|
@ -0,0 +1,155 @@
|
|||
use fayalite::prelude::*;
|
||||
use crate::config::CpuConfig;
|
||||
|
||||
pub mod power_isa;
|
||||
|
||||
macro_rules! all_units {
|
||||
(
|
||||
#[hdl_unit_kind = $HdlUnitKind:ident]
|
||||
#[unit_kind = $UnitKind:ident]
|
||||
#[hdl]
|
||||
$(#[$enum_meta:meta])*
|
||||
$vis:vis enum $UnitMOpEnum:ident {
|
||||
$(
|
||||
$(#[$variant_meta:meta])*
|
||||
$Unit:ident($Op:ty),
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
$(#[$enum_meta])*
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
|
||||
$vis enum $UnitKind {
|
||||
$(
|
||||
$(#[$variant_meta])*
|
||||
$Unit,
|
||||
)*
|
||||
}
|
||||
|
||||
impl ToExpr for $UnitKind {
|
||||
type Type = $HdlUnitKind;
|
||||
|
||||
fn to_expr(&self) -> Expr<Self::Type> {
|
||||
match self {
|
||||
$($UnitKind::$Unit => $HdlUnitKind.$Unit(),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
$(#[$enum_meta])*
|
||||
$vis enum $HdlUnitKind {
|
||||
$(
|
||||
$(#[$variant_meta])*
|
||||
$Unit,
|
||||
)*
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
$(#[$enum_meta])*
|
||||
$vis enum $UnitMOpEnum {
|
||||
$(
|
||||
$(#[$variant_meta])*
|
||||
$Unit($Op),
|
||||
)*
|
||||
}
|
||||
|
||||
impl $UnitMOpEnum {
|
||||
#[hdl]
|
||||
$vis fn kind(expr: impl ToExpr<Type = Self>) -> Expr<$HdlUnitKind> {
|
||||
#[hdl]
|
||||
let unit_kind = wire();
|
||||
#[hdl]
|
||||
match expr {
|
||||
$($UnitMOpEnum::$Unit(_) => connect(unit_kind, $HdlUnitKind.$Unit()),)*
|
||||
}
|
||||
unit_kind
|
||||
}
|
||||
}
|
||||
|
||||
impl CpuConfig {
|
||||
#[hdl]
|
||||
pub fn available_units_for_kind(&self, unit_kind: impl ToExpr<Type = $HdlUnitKind>) -> Expr<Array<Bool>> {
|
||||
#[hdl]
|
||||
let available_units_for_kind = wire(Array[Bool][self.units.len()]);
|
||||
#[hdl]
|
||||
match unit_kind {
|
||||
$($HdlUnitKind::$Unit => for (index, &unit) in self.units.iter().enumerate() {
|
||||
connect(available_units_for_kind[index], unit == $UnitKind::$Unit);
|
||||
})*
|
||||
}
|
||||
available_units_for_kind
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
all_units! {
|
||||
#[hdl_unit_kind = HdlUnitKind]
|
||||
#[unit_kind = UnitKind]
|
||||
#[hdl]
|
||||
pub enum UnitMOp {
|
||||
AluBranch(AluBranchMOp),
|
||||
L2RegisterFile(L2RegisterFileMOp),
|
||||
LoadStore(LoadStoreMOp),
|
||||
}
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
pub enum AluBranchMOp {
|
||||
Add64,
|
||||
Sub64,
|
||||
And64,
|
||||
Or64,
|
||||
Xor64,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
pub enum L2RegisterFileMOp {
|
||||
Read,
|
||||
Write,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
pub enum LoadStoreMOp {
|
||||
Load,
|
||||
Store,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
/// there may be more than one unit of a given kind, so UnitNum is not the same as UnitKind
|
||||
pub struct UnitNum<Width: Size> {
|
||||
pub value: UIntType<Width>,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
pub struct UnitOutRegNum<Width: Size> {
|
||||
pub value: UIntType<Width>,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
/// Physical Register Number -- registers in the CPU's backend
|
||||
pub struct PRegNum<UnitNumWidth: Size, OutRegNumWidth: Size> {
|
||||
pub unit_num: UnitNum<UnitNumWidth>,
|
||||
pub unit_out_reg: UnitOutRegNum<OutRegNumWidth>,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
/// µOp Register Number -- register in a micro-operation
|
||||
#[doc(alias = "UOpRegNum")] // help you find it in the docs if you mis-spell it
|
||||
#[doc(alias = "\u{B5}OpRegNum")] // micro sign
|
||||
#[doc(alias = "\u{39C}OpRegNum")] // greek capital letter mu
|
||||
#[doc(alias = "\u{3BC}OpRegNum")] // greek small letter mu
|
||||
pub struct MOpRegNum {
|
||||
pub value: UInt<8>,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
/// µOp -- a micro-operation
|
||||
#[doc(alias = "UOp")] // help you find it in the docs if you mis-spell it
|
||||
#[doc(alias = "\u{B5}Op")] // micro sign
|
||||
#[doc(alias = "\u{39C}Op")] // greek capital letter mu
|
||||
#[doc(alias = "\u{3BC}Op")] // greek small letter mu
|
||||
pub struct MOp {
|
||||
pub op: UnitMOp,
|
||||
pub value: UInt<8>,
|
||||
}
|
22
crates/cpu/src/instruction/power_isa.rs
Normal file
22
crates/cpu/src/instruction/power_isa.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use fayalite::prelude::*;
|
||||
|
||||
#[hdl]
|
||||
pub struct PowerIsaRegNum {
|
||||
pub value: UInt<5>,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
pub struct PowerIsaFRegNum {
|
||||
pub value: UInt<5>,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
pub struct PowerIsaCrFieldNum {
|
||||
pub value: UInt<3>,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
pub struct PowerIsaCrBitNum {
|
||||
pub cr_field: PowerIsaCrFieldNum,
|
||||
pub bit_in_field: UInt<2>,
|
||||
}
|
2
crates/cpu/src/lib.rs
Normal file
2
crates/cpu/src/lib.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
pub mod instruction;
|
||||
pub mod config;
|
Loading…
Add table
Add a link
Reference in a new issue