start adding cpu data types

This commit is contained in:
Jacob Lifshay 2024-10-08 20:22:15 -07:00
commit 0f4f067996
Signed by: programmerjake
SSH key fingerprint: SHA256:B1iRVvUJkvd7upMIiMqn6OyxvD2SgJkAH3ZnUOj6z+c
12 changed files with 1190 additions and 0 deletions

18
crates/cpu/Cargo.toml Normal file
View 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
View file

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

1
crates/cpu/Notices.txt Symbolic link
View file

@ -0,0 +1 @@
../../Notices.txt

14
crates/cpu/src/config.rs Normal file
View 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()]
}
}

View 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>,
}

View 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
View file

@ -0,0 +1,2 @@
pub mod instruction;
pub mod config;