start debugging reg_alloc with simulator
This commit is contained in:
		
							parent
							
								
									bf34dee043
								
							
						
					
					
						commit
						12481cfab3
					
				
					 8 changed files with 1211 additions and 37 deletions
				
			
		| 
						 | 
				
			
			@ -16,8 +16,25 @@ pub struct CpuConfig {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
impl CpuConfig {
 | 
			
		||||
    pub const DEFAULT_OUT_REG_NUM_WIDTH: usize = 4;
 | 
			
		||||
    pub const DEFAULT_FETCH_WIDTH: NonZeroUsize = {
 | 
			
		||||
        let Some(v) = NonZeroUsize::new(1) else {
 | 
			
		||||
            unreachable!();
 | 
			
		||||
        };
 | 
			
		||||
        v
 | 
			
		||||
    };
 | 
			
		||||
    pub fn new(unit_kinds: Vec<UnitKind>) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            unit_kinds,
 | 
			
		||||
            out_reg_num_width: Self::DEFAULT_OUT_REG_NUM_WIDTH,
 | 
			
		||||
            fetch_width: Self::DEFAULT_FETCH_WIDTH,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn non_const_unit_nums(&self) -> std::ops::Range<usize> {
 | 
			
		||||
        (CONST_ZERO_UNIT_NUM + 1)..(self.unit_kinds.len() + 1)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn unit_num_width(&self) -> usize {
 | 
			
		||||
        UInt::range((CONST_ZERO_UNIT_NUM + 1)..self.unit_kinds.len()).width()
 | 
			
		||||
        UInt::range(self.non_const_unit_nums()).width()
 | 
			
		||||
    }
 | 
			
		||||
    pub fn unit_num(&self) -> UnitNum<DynSize> {
 | 
			
		||||
        UnitNum[self.unit_num_width()]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
			
		||||
// See Notices.txt for copyright information
 | 
			
		||||
use crate::unit::UnitMOp;
 | 
			
		||||
use fayalite::prelude::*;
 | 
			
		||||
use fayalite::{expr::ops::ArrayLiteral, intern::Interned, prelude::*};
 | 
			
		||||
use std::marker::PhantomData;
 | 
			
		||||
 | 
			
		||||
pub mod power_isa;
 | 
			
		||||
| 
						 | 
				
			
			@ -20,58 +20,138 @@ pub enum OutputIntegerMode {
 | 
			
		|||
 | 
			
		||||
pub const MOP_IMM_WIDTH: usize = 34;
 | 
			
		||||
pub const MOP_MIN_REG_WIDTH: usize = 8;
 | 
			
		||||
pub const COMMON_MOP_OTHER_WIDTH: usize =
 | 
			
		||||
    MOP_IMM_WIDTH - (COMMON_MOP_SRC_REG_COUNT - COMMON_MOP_IMM_SRC_REG_COUNT) * MOP_MIN_REG_WIDTH;
 | 
			
		||||
pub const COMMON_MOP_SRC_REG_COUNT: usize = 3;
 | 
			
		||||
pub const COMMON_MOP_IMM_SRC_REG_COUNT: usize = 2;
 | 
			
		||||
pub const COMMON_MOP_SRC_LEN: usize = 3;
 | 
			
		||||
pub const COMMON_MOP_MIN_SRC_LEN_WITH_FULL_IMM: usize = 2;
 | 
			
		||||
pub const COMMON_MOP_IMM_LOW_WIDTH: usize = CommonMOpWithMaxSrcCount::IMM_WIDTH - 1;
 | 
			
		||||
 | 
			
		||||
#[hdl]
 | 
			
		||||
pub struct CommonMOp<PrefixPad: KnownSize, RegWidth: Size, SrcCount: KnownSize> {
 | 
			
		||||
    pub prefix_pad: UIntType<PrefixPad>,
 | 
			
		||||
    pub dest: UIntType<RegWidth>,
 | 
			
		||||
    pub src: Array<UIntType<RegWidth>, { COMMON_MOP_SRC_REG_COUNT }>,
 | 
			
		||||
    pub other: UInt<{ COMMON_MOP_OTHER_WIDTH }>,
 | 
			
		||||
    pub src: Array<UIntType<RegWidth>, { COMMON_MOP_SRC_LEN }>,
 | 
			
		||||
    pub imm_low: UInt<{ COMMON_MOP_IMM_LOW_WIDTH }>,
 | 
			
		||||
    pub imm_sign: SInt<1>,
 | 
			
		||||
    pub _phantom: PhantomData<SrcCount>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[hdl]
 | 
			
		||||
pub struct CommonMOpImmParts<ImmInSrcCount: Size> {
 | 
			
		||||
    // fields must be in this exact order
 | 
			
		||||
    pub imm_low: UInt<{ COMMON_MOP_IMM_LOW_WIDTH }>,
 | 
			
		||||
    pub reversed_src: ArrayType<UInt<{ MOP_MIN_REG_WIDTH }>, ImmInSrcCount>,
 | 
			
		||||
    pub imm_sign: SInt<1>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CommonMOpWithMaxSrcCount = CommonMOpForImm<{ COMMON_MOP_SRC_LEN }>;
 | 
			
		||||
 | 
			
		||||
type CommonMOpForImm<const SRC_COUNT: usize> =
 | 
			
		||||
    CommonMOp<ConstUsize<0>, ConstUsize<{ MOP_MIN_REG_WIDTH }>, ConstUsize<SRC_COUNT>>;
 | 
			
		||||
 | 
			
		||||
pub const COMMON_MOP_0_IMM_WIDTH: usize = CommonMOpForImm::<0>::IMM_WIDTH;
 | 
			
		||||
pub const COMMON_MOP_1_IMM_WIDTH: usize = CommonMOpForImm::<1>::IMM_WIDTH;
 | 
			
		||||
pub const COMMON_MOP_2_IMM_WIDTH: usize = CommonMOpForImm::<2>::IMM_WIDTH;
 | 
			
		||||
pub const COMMON_MOP_3_IMM_WIDTH: usize = CommonMOpForImm::<3>::IMM_WIDTH;
 | 
			
		||||
const COMMON_MOP_0_IMM_IN_SRC_COUNT: usize = CommonMOpForImm::<0>::IMM_IN_SRC_COUNT;
 | 
			
		||||
 | 
			
		||||
impl<PrefixPad: KnownSize, RegWidth: Size, SrcCount: KnownSize>
 | 
			
		||||
    CommonMOp<PrefixPad, RegWidth, SrcCount>
 | 
			
		||||
{
 | 
			
		||||
    pub fn imm_ty(self) -> SInt {
 | 
			
		||||
        assert!(self.src.element().width() >= MOP_MIN_REG_WIDTH);
 | 
			
		||||
        assert!(SrcCount::VALUE <= COMMON_MOP_SRC_REG_COUNT);
 | 
			
		||||
        SInt[(COMMON_MOP_SRC_REG_COUNT - SrcCount::VALUE) * MOP_MIN_REG_WIDTH
 | 
			
		||||
            + COMMON_MOP_OTHER_WIDTH]
 | 
			
		||||
    pub const IMM_IN_SRC_COUNT: usize = {
 | 
			
		||||
        assert!(SrcCount::VALUE <= COMMON_MOP_SRC_LEN, "too many sources");
 | 
			
		||||
        const _: () = assert!(COMMON_MOP_MIN_SRC_LEN_WITH_FULL_IMM <= COMMON_MOP_SRC_LEN);
 | 
			
		||||
        (COMMON_MOP_SRC_LEN - COMMON_MOP_MIN_SRC_LEN_WITH_FULL_IMM)
 | 
			
		||||
            - SrcCount::VALUE.saturating_sub(COMMON_MOP_MIN_SRC_LEN_WITH_FULL_IMM)
 | 
			
		||||
    };
 | 
			
		||||
    pub const IMM_IN_SRC_RANGE: std::ops::Range<usize> =
 | 
			
		||||
        (COMMON_MOP_SRC_LEN - Self::IMM_IN_SRC_COUNT)..COMMON_MOP_SRC_LEN;
 | 
			
		||||
    pub const IMM_WIDTH: usize = {
 | 
			
		||||
        MOP_IMM_WIDTH - (COMMON_MOP_0_IMM_IN_SRC_COUNT - Self::IMM_IN_SRC_COUNT) * MOP_MIN_REG_WIDTH
 | 
			
		||||
    };
 | 
			
		||||
    pub fn imm_ty() -> SInt {
 | 
			
		||||
        SInt::new(Self::IMM_WIDTH)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn imm_parts_ty() -> CommonMOpImmParts<DynSize> {
 | 
			
		||||
        let retval = CommonMOpImmParts[Self::IMM_IN_SRC_COUNT];
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            retval.canonical().bit_width(),
 | 
			
		||||
            Self::IMM_WIDTH,
 | 
			
		||||
            "{retval:#?}"
 | 
			
		||||
        );
 | 
			
		||||
        retval
 | 
			
		||||
    }
 | 
			
		||||
    #[hdl]
 | 
			
		||||
    pub fn new(
 | 
			
		||||
        prefix_pad: impl ToExpr<Type = UIntType<PrefixPad>>,
 | 
			
		||||
        dest: impl ToExpr<Type = UIntType<RegWidth>>,
 | 
			
		||||
        src: impl ToExpr<Type = ArrayType<UIntType<RegWidth>, SrcCount>>,
 | 
			
		||||
        imm: impl ToExpr<Type = SInt>,
 | 
			
		||||
    ) -> Expr<Self> {
 | 
			
		||||
        let prefix_pad = prefix_pad.to_expr();
 | 
			
		||||
        let dest = dest.to_expr();
 | 
			
		||||
        let src_in = src.to_expr();
 | 
			
		||||
        let imm = imm.to_expr();
 | 
			
		||||
        assert_eq!(Expr::ty(imm), Self::imm_ty());
 | 
			
		||||
        let reg_ty = Expr::ty(dest);
 | 
			
		||||
        assert_eq!(reg_ty, Expr::ty(src_in).element());
 | 
			
		||||
        let imm_parts = imm.cast_to_bits().cast_bits_to(Self::imm_parts_ty());
 | 
			
		||||
        let mut src = [0_hdl_u0.cast_to(reg_ty); COMMON_MOP_SRC_LEN];
 | 
			
		||||
        for i in 0..SrcCount::VALUE {
 | 
			
		||||
            src[i] = src_in[i];
 | 
			
		||||
        }
 | 
			
		||||
        for (reversed_src_index, src_index) in Self::IMM_IN_SRC_RANGE.rev().enumerate() {
 | 
			
		||||
            src[src_index] = imm_parts.reversed_src[reversed_src_index].cast_to(reg_ty);
 | 
			
		||||
        }
 | 
			
		||||
        #[hdl]
 | 
			
		||||
        Self {
 | 
			
		||||
            prefix_pad,
 | 
			
		||||
            dest,
 | 
			
		||||
            src: ArrayLiteral::new(
 | 
			
		||||
                reg_ty,
 | 
			
		||||
                Interned::from_iter(src.iter().map(|v| Expr::canonical(*v))),
 | 
			
		||||
            )
 | 
			
		||||
            .to_expr(),
 | 
			
		||||
            imm_low: Expr::from_dyn_int(imm[..COMMON_MOP_IMM_LOW_WIDTH]),
 | 
			
		||||
            imm_sign: Expr::from_dyn_int(imm >> (Self::IMM_WIDTH - 1)),
 | 
			
		||||
            _phantom: PhantomData,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #[hdl]
 | 
			
		||||
    pub fn imm(expr: impl ToExpr<Type = Self>) -> Expr<SInt> {
 | 
			
		||||
        let expr = expr.to_expr();
 | 
			
		||||
        assert!(Expr::ty(expr).src.element().width() >= MOP_MIN_REG_WIDTH);
 | 
			
		||||
        let mut acc = expr.other[..COMMON_MOP_OTHER_WIDTH - 1];
 | 
			
		||||
        for i in SrcCount::VALUE..COMMON_MOP_SRC_REG_COUNT {
 | 
			
		||||
            acc = (acc, expr.src[i][..MOP_MIN_REG_WIDTH]).cast_to_bits();
 | 
			
		||||
        }
 | 
			
		||||
        acc = (acc, expr.other[COMMON_MOP_OTHER_WIDTH - 1]).cast_to_bits();
 | 
			
		||||
        #[hdl]
 | 
			
		||||
        let imm = wire(Expr::ty(expr).imm_ty());
 | 
			
		||||
        debug_assert_eq!(Expr::ty(acc).width(), Expr::ty(imm).width());
 | 
			
		||||
        connect(imm, acc.cast_to(Expr::ty(imm)));
 | 
			
		||||
        imm
 | 
			
		||||
        let reversed_src = Vec::from_iter(
 | 
			
		||||
            Self::IMM_IN_SRC_RANGE
 | 
			
		||||
                .rev()
 | 
			
		||||
                .map(|src_index| expr.src[src_index].cast_to_static()),
 | 
			
		||||
        );
 | 
			
		||||
        let imm_parts = {
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            CommonMOpImmParts {
 | 
			
		||||
                imm_low: expr.imm_low,
 | 
			
		||||
                reversed_src,
 | 
			
		||||
                imm_sign: expr.imm_sign,
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        imm_parts.cast_to_bits().cast_bits_to(Self::imm_ty())
 | 
			
		||||
    }
 | 
			
		||||
    #[hdl]
 | 
			
		||||
    pub fn connect_to_imm(expr: impl ToExpr<Type = Self>, imm: impl ToExpr<Type = SInt>) {
 | 
			
		||||
        let expr = expr.to_expr();
 | 
			
		||||
        let reg_ty = Expr::ty(expr).dest;
 | 
			
		||||
        assert_eq!(reg_ty, Expr::ty(expr).src.element());
 | 
			
		||||
        let imm = imm.to_expr();
 | 
			
		||||
        let imm_ty = Expr::ty(expr).imm_ty();
 | 
			
		||||
        assert_eq!(Expr::ty(imm), imm_ty);
 | 
			
		||||
        let mut pos = COMMON_MOP_OTHER_WIDTH - 1;
 | 
			
		||||
        connect_any(
 | 
			
		||||
            expr.other,
 | 
			
		||||
            (imm[..pos], imm[imm_ty.width() - 1]).cast_to_bits(),
 | 
			
		||||
        );
 | 
			
		||||
        for i in SrcCount::VALUE..COMMON_MOP_SRC_REG_COUNT {
 | 
			
		||||
            connect_any(expr.src[i], imm[pos..pos + MOP_MIN_REG_WIDTH]);
 | 
			
		||||
            pos += MOP_MIN_REG_WIDTH;
 | 
			
		||||
        assert_eq!(Expr::ty(imm), Self::imm_ty());
 | 
			
		||||
        let imm_parts = imm.cast_to_bits().cast_bits_to(Self::imm_parts_ty());
 | 
			
		||||
        let mut src = [Some(0_hdl_u0.cast_to(reg_ty)); COMMON_MOP_SRC_LEN];
 | 
			
		||||
        for i in 0..SrcCount::VALUE {
 | 
			
		||||
            src[i] = None;
 | 
			
		||||
        }
 | 
			
		||||
        for (reversed_src_index, src_index) in Self::IMM_IN_SRC_RANGE.rev().enumerate() {
 | 
			
		||||
            src[src_index] = Some(imm_parts.reversed_src[reversed_src_index].cast_to(reg_ty));
 | 
			
		||||
        }
 | 
			
		||||
        for i in 0..COMMON_MOP_SRC_LEN {
 | 
			
		||||
            if let Some(v) = src[i] {
 | 
			
		||||
                connect(expr.src[i], v);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,9 +2,9 @@
 | 
			
		|||
// See Notices.txt for copyright information
 | 
			
		||||
use crate::{
 | 
			
		||||
    config::CpuConfig,
 | 
			
		||||
    instruction::{MOp, UnitNum},
 | 
			
		||||
    instruction::MOp,
 | 
			
		||||
    unit::{TrapData, UnitTrait},
 | 
			
		||||
    util::tree_reduce::{tree_reduce, tree_reduce_with_state},
 | 
			
		||||
    util::tree_reduce::tree_reduce_with_state,
 | 
			
		||||
};
 | 
			
		||||
use fayalite::{module::instance_with_loc, prelude::*, util::ready_valid::ReadyValid};
 | 
			
		||||
use std::num::NonZeroUsize;
 | 
			
		||||
| 
						 | 
				
			
			@ -124,5 +124,13 @@ pub fn reg_alloc(config: &CpuConfig) {
 | 
			
		|||
        );
 | 
			
		||||
        connect(unit_free_regs_tracker.cd, cd);
 | 
			
		||||
        // TODO: finish
 | 
			
		||||
        connect(
 | 
			
		||||
            unit_free_regs_tracker.free_in[0].data,
 | 
			
		||||
            HdlOption[UInt[config.out_reg_num_width]].uninit(), // FIXME: just for debugging
 | 
			
		||||
        );
 | 
			
		||||
        connect(
 | 
			
		||||
            unit_free_regs_tracker.alloc_out[0].ready,
 | 
			
		||||
            Bool.uninit(), // FIXME: just for debugging
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,8 @@ use fayalite::{
 | 
			
		|||
    util::ready_valid::ReadyValid,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub mod alu_branch;
 | 
			
		||||
 | 
			
		||||
macro_rules! all_units {
 | 
			
		||||
    (
 | 
			
		||||
        #[hdl_unit_kind = $HdlUnitKind:ident]
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +109,7 @@ all_units! {
 | 
			
		|||
    #[unit_kind = UnitKind]
 | 
			
		||||
    #[hdl]
 | 
			
		||||
    pub enum UnitMOp<RegWidth: Size> {
 | 
			
		||||
        #[create_dyn_unit_fn = |config| todo!()]
 | 
			
		||||
        #[create_dyn_unit_fn = |config| alu_branch::AluBranch::new(config).to_dyn()]
 | 
			
		||||
        AluBranch(AluBranchMOp<RegWidth>),
 | 
			
		||||
        #[create_dyn_unit_fn = |config| todo!()]
 | 
			
		||||
        L2RegisterFile(L2RegisterFileMOp<RegWidth>),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										83
									
								
								crates/cpu/src/unit/alu_branch.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								crates/cpu/src/unit/alu_branch.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
			
		||||
// See Notices.txt for copyright information
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    config::CpuConfig,
 | 
			
		||||
    instruction::AluBranchMOp,
 | 
			
		||||
    unit::{DynUnit, DynUnitWrapper, UnitCancelInput, UnitKind, UnitOutput, UnitTrait},
 | 
			
		||||
};
 | 
			
		||||
use fayalite::{
 | 
			
		||||
    intern::{Intern, Interned},
 | 
			
		||||
    prelude::*,
 | 
			
		||||
    util::ready_valid::ReadyValid,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[hdl_module]
 | 
			
		||||
pub fn alu_branch(config: &CpuConfig) {
 | 
			
		||||
    #[hdl]
 | 
			
		||||
    let cd: ClockDomain = m.input();
 | 
			
		||||
    // TODO: finish
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 | 
			
		||||
pub struct AluBranch {
 | 
			
		||||
    config: Interned<CpuConfig>,
 | 
			
		||||
    module: Interned<Module<alu_branch>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl AluBranch {
 | 
			
		||||
    pub fn new(config: &CpuConfig) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            config: config.intern(),
 | 
			
		||||
            module: alu_branch(config),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl UnitTrait for AluBranch {
 | 
			
		||||
    type Type = alu_branch;
 | 
			
		||||
    type ExtraOut = ();
 | 
			
		||||
    type MOp = AluBranchMOp<DynSize>;
 | 
			
		||||
 | 
			
		||||
    fn ty(&self) -> Self::Type {
 | 
			
		||||
        self.module.io_ty()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn extra_out_ty(&self) -> Self::ExtraOut {
 | 
			
		||||
        ()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn mop_ty(&self) -> Self::MOp {
 | 
			
		||||
        AluBranchMOp[self.config.p_reg_num().canonical().bit_width()]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn unit_kind(&self) -> UnitKind {
 | 
			
		||||
        UnitKind::AluBranch
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn make_module(&self) -> Interned<Module<Self::Type>> {
 | 
			
		||||
        self.module
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn cancel_input(
 | 
			
		||||
        &self,
 | 
			
		||||
        this: Expr<Self::Type>,
 | 
			
		||||
    ) -> Expr<ReadyValid<UnitCancelInput<DynSize, DynSize>>> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn output(
 | 
			
		||||
        &self,
 | 
			
		||||
        this: Expr<Self::Type>,
 | 
			
		||||
    ) -> Expr<ReadyValid<UnitOutput<DynSize, DynSize, Self::ExtraOut>>> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn cd(&self, this: Expr<Self::Type>) -> Expr<ClockDomain> {
 | 
			
		||||
        this.cd
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn to_dyn(&self) -> DynUnit {
 | 
			
		||||
        DynUnitWrapper(*self).to_dyn()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										880
									
								
								crates/cpu/tests/expected/reg_alloc.vcd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										880
									
								
								crates/cpu/tests/expected/reg_alloc.vcd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,880 @@
 | 
			
		|||
$timescale 1 ps $end
 | 
			
		||||
$scope module reg_alloc $end
 | 
			
		||||
$scope struct cd $end
 | 
			
		||||
$var wire 1 ! clk $end
 | 
			
		||||
$var wire 1 " rst $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct fetch_decode_interface $end
 | 
			
		||||
$scope struct decoded_insns $end
 | 
			
		||||
$scope struct [0] $end
 | 
			
		||||
$scope struct data $end
 | 
			
		||||
$var string 1 # \$tag $end
 | 
			
		||||
$scope struct HdlSome $end
 | 
			
		||||
$scope struct uop $end
 | 
			
		||||
$var string 1 $ \$tag $end
 | 
			
		||||
$scope struct AluBranch $end
 | 
			
		||||
$var string 1 % \$tag $end
 | 
			
		||||
$scope struct AddSub $end
 | 
			
		||||
$scope struct alu_common $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var string 0 & prefix_pad $end
 | 
			
		||||
$var wire 8 ' dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 ( \[0] $end
 | 
			
		||||
$var wire 8 ) \[1] $end
 | 
			
		||||
$var wire 8 * \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 + imm_low $end
 | 
			
		||||
$var wire 1 , imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var string 1 - output_integer_mode $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 . invert_src0 $end
 | 
			
		||||
$var wire 1 / invert_carry_in $end
 | 
			
		||||
$var wire 1 0 invert_carry_out $end
 | 
			
		||||
$var wire 1 1 add_pc $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct AddSubI $end
 | 
			
		||||
$scope struct alu_common $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var string 0 2 prefix_pad $end
 | 
			
		||||
$var wire 8 3 dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 4 \[0] $end
 | 
			
		||||
$var wire 8 5 \[1] $end
 | 
			
		||||
$var wire 8 6 \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 7 imm_low $end
 | 
			
		||||
$var wire 1 8 imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var string 1 9 output_integer_mode $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 : invert_src0 $end
 | 
			
		||||
$var wire 1 ; invert_carry_in $end
 | 
			
		||||
$var wire 1 < invert_carry_out $end
 | 
			
		||||
$var wire 1 = add_pc $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct Logical $end
 | 
			
		||||
$scope struct alu_common $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var string 0 > prefix_pad $end
 | 
			
		||||
$var wire 8 ? dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 @ \[0] $end
 | 
			
		||||
$var wire 8 A \[1] $end
 | 
			
		||||
$var wire 8 B \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 C imm_low $end
 | 
			
		||||
$var wire 1 D imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var string 1 E output_integer_mode $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 4 F lut $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct L2RegisterFile $end
 | 
			
		||||
$var string 1 G \$tag $end
 | 
			
		||||
$scope struct ReadL2Reg $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var wire 1 H prefix_pad $end
 | 
			
		||||
$var wire 8 I dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 J \[0] $end
 | 
			
		||||
$var wire 8 K \[1] $end
 | 
			
		||||
$var wire 8 L \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 M imm_low $end
 | 
			
		||||
$var wire 1 N imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct WriteL2Reg $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var wire 1 O prefix_pad $end
 | 
			
		||||
$var wire 8 P dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 Q \[0] $end
 | 
			
		||||
$var wire 8 R \[1] $end
 | 
			
		||||
$var wire 8 S \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 T imm_low $end
 | 
			
		||||
$var wire 1 U imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct LoadStore $end
 | 
			
		||||
$var string 1 V \$tag $end
 | 
			
		||||
$scope struct Load $end
 | 
			
		||||
$var wire 1 W prefix_pad $end
 | 
			
		||||
$var wire 8 X dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 Y \[0] $end
 | 
			
		||||
$var wire 8 Z \[1] $end
 | 
			
		||||
$var wire 8 [ \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 \ imm_low $end
 | 
			
		||||
$var wire 1 ] imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct Store $end
 | 
			
		||||
$var wire 1 ^ prefix_pad $end
 | 
			
		||||
$var wire 8 _ dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 ` \[0] $end
 | 
			
		||||
$var wire 8 a \[1] $end
 | 
			
		||||
$var wire 8 b \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 c imm_low $end
 | 
			
		||||
$var wire 1 d imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 e is_unrelated_pc $end
 | 
			
		||||
$var wire 64 f pc $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 g ready $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct [1] $end
 | 
			
		||||
$scope struct data $end
 | 
			
		||||
$var string 1 h \$tag $end
 | 
			
		||||
$scope struct HdlSome $end
 | 
			
		||||
$scope struct uop $end
 | 
			
		||||
$var string 1 i \$tag $end
 | 
			
		||||
$scope struct AluBranch $end
 | 
			
		||||
$var string 1 j \$tag $end
 | 
			
		||||
$scope struct AddSub $end
 | 
			
		||||
$scope struct alu_common $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var string 0 k prefix_pad $end
 | 
			
		||||
$var wire 8 l dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 m \[0] $end
 | 
			
		||||
$var wire 8 n \[1] $end
 | 
			
		||||
$var wire 8 o \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 p imm_low $end
 | 
			
		||||
$var wire 1 q imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var string 1 r output_integer_mode $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 s invert_src0 $end
 | 
			
		||||
$var wire 1 t invert_carry_in $end
 | 
			
		||||
$var wire 1 u invert_carry_out $end
 | 
			
		||||
$var wire 1 v add_pc $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct AddSubI $end
 | 
			
		||||
$scope struct alu_common $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var string 0 w prefix_pad $end
 | 
			
		||||
$var wire 8 x dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 y \[0] $end
 | 
			
		||||
$var wire 8 z \[1] $end
 | 
			
		||||
$var wire 8 { \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 | imm_low $end
 | 
			
		||||
$var wire 1 } imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var string 1 ~ output_integer_mode $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 !" invert_src0 $end
 | 
			
		||||
$var wire 1 "" invert_carry_in $end
 | 
			
		||||
$var wire 1 #" invert_carry_out $end
 | 
			
		||||
$var wire 1 $" add_pc $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct Logical $end
 | 
			
		||||
$scope struct alu_common $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var string 0 %" prefix_pad $end
 | 
			
		||||
$var wire 8 &" dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 '" \[0] $end
 | 
			
		||||
$var wire 8 (" \[1] $end
 | 
			
		||||
$var wire 8 )" \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 *" imm_low $end
 | 
			
		||||
$var wire 1 +" imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var string 1 ," output_integer_mode $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 4 -" lut $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct L2RegisterFile $end
 | 
			
		||||
$var string 1 ." \$tag $end
 | 
			
		||||
$scope struct ReadL2Reg $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var wire 1 /" prefix_pad $end
 | 
			
		||||
$var wire 8 0" dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 1" \[0] $end
 | 
			
		||||
$var wire 8 2" \[1] $end
 | 
			
		||||
$var wire 8 3" \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 4" imm_low $end
 | 
			
		||||
$var wire 1 5" imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct WriteL2Reg $end
 | 
			
		||||
$scope struct common $end
 | 
			
		||||
$var wire 1 6" prefix_pad $end
 | 
			
		||||
$var wire 8 7" dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 8" \[0] $end
 | 
			
		||||
$var wire 8 9" \[1] $end
 | 
			
		||||
$var wire 8 :" \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 ;" imm_low $end
 | 
			
		||||
$var wire 1 <" imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct LoadStore $end
 | 
			
		||||
$var string 1 =" \$tag $end
 | 
			
		||||
$scope struct Load $end
 | 
			
		||||
$var wire 1 >" prefix_pad $end
 | 
			
		||||
$var wire 8 ?" dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 @" \[0] $end
 | 
			
		||||
$var wire 8 A" \[1] $end
 | 
			
		||||
$var wire 8 B" \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 C" imm_low $end
 | 
			
		||||
$var wire 1 D" imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct Store $end
 | 
			
		||||
$var wire 1 E" prefix_pad $end
 | 
			
		||||
$var wire 8 F" dest $end
 | 
			
		||||
$scope struct src $end
 | 
			
		||||
$var wire 8 G" \[0] $end
 | 
			
		||||
$var wire 8 H" \[1] $end
 | 
			
		||||
$var wire 8 I" \[2] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 25 J" imm_low $end
 | 
			
		||||
$var wire 1 K" imm_sign $end
 | 
			
		||||
$scope struct _phantom $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 L" is_unrelated_pc $end
 | 
			
		||||
$var wire 64 M" pc $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 N" ready $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct fetch_decode_special_op $end
 | 
			
		||||
$scope struct data $end
 | 
			
		||||
$var string 1 O" \$tag $end
 | 
			
		||||
$scope struct HdlSome $end
 | 
			
		||||
$var string 1 P" \$tag $end
 | 
			
		||||
$scope struct Trap $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 Q" ready $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct available_units $end
 | 
			
		||||
$scope struct [0] $end
 | 
			
		||||
$var wire 1 R" \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct [1] $end
 | 
			
		||||
$var wire 1 S" \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct selected_unit_nums $end
 | 
			
		||||
$scope struct [0] $end
 | 
			
		||||
$var string 1 T" \$tag $end
 | 
			
		||||
$scope struct HdlSome $end
 | 
			
		||||
$var wire 1 U" value $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct [1] $end
 | 
			
		||||
$var string 1 V" \$tag $end
 | 
			
		||||
$scope struct HdlSome $end
 | 
			
		||||
$var wire 1 W" value $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var string 1 X" unit_kind $end
 | 
			
		||||
$scope struct available_units_for_kind $end
 | 
			
		||||
$var wire 1 Y" \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct selected_unit_leaf $end
 | 
			
		||||
$var string 1 Z" \$tag $end
 | 
			
		||||
$scope struct HdlSome $end
 | 
			
		||||
$var wire 1 [" value $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct unit_num $end
 | 
			
		||||
$var wire 1 \" value $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var string 1 ]" unit_kind $end
 | 
			
		||||
$scope struct available_units_for_kind $end
 | 
			
		||||
$var wire 1 ^" \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct selected_unit_leaf $end
 | 
			
		||||
$var string 1 _" \$tag $end
 | 
			
		||||
$scope struct HdlSome $end
 | 
			
		||||
$var wire 1 `" value $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct unit_num $end
 | 
			
		||||
$var wire 1 a" value $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct unit_0 $end
 | 
			
		||||
$scope struct cd $end
 | 
			
		||||
$var wire 1 d" clk $end
 | 
			
		||||
$var wire 1 e" rst $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope module alu_branch $end
 | 
			
		||||
$scope struct cd $end
 | 
			
		||||
$var wire 1 b" clk $end
 | 
			
		||||
$var wire 1 c" rst $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct unit_0_free_regs_tracker $end
 | 
			
		||||
$scope struct cd $end
 | 
			
		||||
$var wire 1 Q# clk $end
 | 
			
		||||
$var wire 1 R# rst $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct free_in $end
 | 
			
		||||
$scope struct [0] $end
 | 
			
		||||
$scope struct data $end
 | 
			
		||||
$var string 1 S# \$tag $end
 | 
			
		||||
$var wire 4 T# HdlSome $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 U# ready $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct alloc_out $end
 | 
			
		||||
$scope struct [0] $end
 | 
			
		||||
$scope struct data $end
 | 
			
		||||
$var string 1 V# \$tag $end
 | 
			
		||||
$var wire 4 W# HdlSome $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 X# ready $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope module unit_free_regs_tracker $end
 | 
			
		||||
$scope struct cd $end
 | 
			
		||||
$var wire 1 f" clk $end
 | 
			
		||||
$var wire 1 g" rst $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct free_in $end
 | 
			
		||||
$scope struct [0] $end
 | 
			
		||||
$scope struct data $end
 | 
			
		||||
$var string 1 h" \$tag $end
 | 
			
		||||
$var wire 4 i" HdlSome $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 j" ready $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct alloc_out $end
 | 
			
		||||
$scope struct [0] $end
 | 
			
		||||
$scope struct data $end
 | 
			
		||||
$var string 1 k" \$tag $end
 | 
			
		||||
$var wire 4 l" HdlSome $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 m" ready $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct allocated_reg $end
 | 
			
		||||
$var reg 1 n" \[0] $end
 | 
			
		||||
$var reg 1 o" \[1] $end
 | 
			
		||||
$var reg 1 p" \[2] $end
 | 
			
		||||
$var reg 1 q" \[3] $end
 | 
			
		||||
$var reg 1 r" \[4] $end
 | 
			
		||||
$var reg 1 s" \[5] $end
 | 
			
		||||
$var reg 1 t" \[6] $end
 | 
			
		||||
$var reg 1 u" \[7] $end
 | 
			
		||||
$var reg 1 v" \[8] $end
 | 
			
		||||
$var reg 1 w" \[9] $end
 | 
			
		||||
$var reg 1 x" \[10] $end
 | 
			
		||||
$var reg 1 y" \[11] $end
 | 
			
		||||
$var reg 1 z" \[12] $end
 | 
			
		||||
$var reg 1 {" \[13] $end
 | 
			
		||||
$var reg 1 |" \[14] $end
 | 
			
		||||
$var reg 1 }" \[15] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct firing_data $end
 | 
			
		||||
$var string 1 ~" \$tag $end
 | 
			
		||||
$var wire 4 !# HdlSome $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 "# reduced_count_0_2 $end
 | 
			
		||||
$var wire 1 ## reduced_count_overflowed_0_2 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_0_2 $end
 | 
			
		||||
$var wire 1 $# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 %# reduced_count_2_4 $end
 | 
			
		||||
$var wire 1 &# reduced_count_overflowed_2_4 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_2_4 $end
 | 
			
		||||
$var wire 1 '# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 (# reduced_count_0_4 $end
 | 
			
		||||
$var wire 1 )# reduced_count_overflowed_0_4 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_0_4 $end
 | 
			
		||||
$var wire 2 *# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 +# reduced_count_4_6 $end
 | 
			
		||||
$var wire 1 ,# reduced_count_overflowed_4_6 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_4_6 $end
 | 
			
		||||
$var wire 1 -# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 .# reduced_count_6_8 $end
 | 
			
		||||
$var wire 1 /# reduced_count_overflowed_6_8 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_6_8 $end
 | 
			
		||||
$var wire 1 0# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 1# reduced_count_4_8 $end
 | 
			
		||||
$var wire 1 2# reduced_count_overflowed_4_8 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_4_8 $end
 | 
			
		||||
$var wire 2 3# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 4# reduced_count_0_8 $end
 | 
			
		||||
$var wire 1 5# reduced_count_overflowed_0_8 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_0_8 $end
 | 
			
		||||
$var wire 3 6# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 7# reduced_count_8_10 $end
 | 
			
		||||
$var wire 1 8# reduced_count_overflowed_8_10 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_8_10 $end
 | 
			
		||||
$var wire 1 9# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 :# reduced_count_10_12 $end
 | 
			
		||||
$var wire 1 ;# reduced_count_overflowed_10_12 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_10_12 $end
 | 
			
		||||
$var wire 1 <# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 =# reduced_count_8_12 $end
 | 
			
		||||
$var wire 1 ># reduced_count_overflowed_8_12 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_8_12 $end
 | 
			
		||||
$var wire 2 ?# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 @# reduced_count_12_14 $end
 | 
			
		||||
$var wire 1 A# reduced_count_overflowed_12_14 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_12_14 $end
 | 
			
		||||
$var wire 1 B# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 C# reduced_count_14_16 $end
 | 
			
		||||
$var wire 1 D# reduced_count_overflowed_14_16 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_14_16 $end
 | 
			
		||||
$var wire 1 E# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 F# reduced_count_12_16 $end
 | 
			
		||||
$var wire 1 G# reduced_count_overflowed_12_16 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_12_16 $end
 | 
			
		||||
$var wire 2 H# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 I# reduced_count_8_16 $end
 | 
			
		||||
$var wire 1 J# reduced_count_overflowed_8_16 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_8_16 $end
 | 
			
		||||
$var wire 3 K# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$var wire 1 L# reduced_count_0_16 $end
 | 
			
		||||
$var wire 1 M# reduced_count_overflowed_0_16 $end
 | 
			
		||||
$scope struct reduced_alloc_nums_0_16 $end
 | 
			
		||||
$var wire 4 N# \[0] $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$scope struct firing_data $end
 | 
			
		||||
$var string 1 O# \$tag $end
 | 
			
		||||
$var wire 4 P# HdlSome $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$upscope $end
 | 
			
		||||
$enddefinitions $end
 | 
			
		||||
$dumpvars
 | 
			
		||||
0!
 | 
			
		||||
1"
 | 
			
		||||
sHdlSome\x20(1) #
 | 
			
		||||
sAluBranch\x20(0) $
 | 
			
		||||
sAddSub\x20(0) %
 | 
			
		||||
s0 &
 | 
			
		||||
b1 '
 | 
			
		||||
b10 (
 | 
			
		||||
b11 )
 | 
			
		||||
b100 *
 | 
			
		||||
b1001000110100 +
 | 
			
		||||
0,
 | 
			
		||||
sFull64\x20(0) -
 | 
			
		||||
1.
 | 
			
		||||
1/
 | 
			
		||||
10
 | 
			
		||||
11
 | 
			
		||||
s0 2
 | 
			
		||||
b1 3
 | 
			
		||||
b10 4
 | 
			
		||||
b11 5
 | 
			
		||||
b100 6
 | 
			
		||||
b1001000110100 7
 | 
			
		||||
08
 | 
			
		||||
sFull64\x20(0) 9
 | 
			
		||||
1:
 | 
			
		||||
1;
 | 
			
		||||
1<
 | 
			
		||||
1=
 | 
			
		||||
s0 >
 | 
			
		||||
b1 ?
 | 
			
		||||
b10 @
 | 
			
		||||
b11 A
 | 
			
		||||
b100 B
 | 
			
		||||
b1001000110100 C
 | 
			
		||||
0D
 | 
			
		||||
sFull64\x20(0) E
 | 
			
		||||
b1111 F
 | 
			
		||||
sReadL2Reg\x20(0) G
 | 
			
		||||
0H
 | 
			
		||||
b1 I
 | 
			
		||||
b10 J
 | 
			
		||||
b11 K
 | 
			
		||||
b100 L
 | 
			
		||||
b1001000110100 M
 | 
			
		||||
0N
 | 
			
		||||
0O
 | 
			
		||||
b1 P
 | 
			
		||||
b10 Q
 | 
			
		||||
b11 R
 | 
			
		||||
b100 S
 | 
			
		||||
b1001000110100 T
 | 
			
		||||
0U
 | 
			
		||||
sLoad\x20(0) V
 | 
			
		||||
0W
 | 
			
		||||
b1 X
 | 
			
		||||
b10 Y
 | 
			
		||||
b11 Z
 | 
			
		||||
b100 [
 | 
			
		||||
b1001000110100 \
 | 
			
		||||
0]
 | 
			
		||||
0^
 | 
			
		||||
b1 _
 | 
			
		||||
b10 `
 | 
			
		||||
b11 a
 | 
			
		||||
b100 b
 | 
			
		||||
b1001000110100 c
 | 
			
		||||
0d
 | 
			
		||||
1e
 | 
			
		||||
b1000000000000 f
 | 
			
		||||
1g
 | 
			
		||||
sHdlSome\x20(1) h
 | 
			
		||||
sAluBranch\x20(0) i
 | 
			
		||||
sLogical\x20(2) j
 | 
			
		||||
s0 k
 | 
			
		||||
b10 l
 | 
			
		||||
b11 m
 | 
			
		||||
b100 n
 | 
			
		||||
b0 o
 | 
			
		||||
b0 p
 | 
			
		||||
0q
 | 
			
		||||
sFull64\x20(0) r
 | 
			
		||||
0s
 | 
			
		||||
1t
 | 
			
		||||
1u
 | 
			
		||||
0v
 | 
			
		||||
s0 w
 | 
			
		||||
b10 x
 | 
			
		||||
b11 y
 | 
			
		||||
b100 z
 | 
			
		||||
b0 {
 | 
			
		||||
b0 |
 | 
			
		||||
0}
 | 
			
		||||
sFull64\x20(0) ~
 | 
			
		||||
0!"
 | 
			
		||||
1""
 | 
			
		||||
1#"
 | 
			
		||||
0$"
 | 
			
		||||
s0 %"
 | 
			
		||||
b10 &"
 | 
			
		||||
b11 '"
 | 
			
		||||
b100 ("
 | 
			
		||||
b0 )"
 | 
			
		||||
b0 *"
 | 
			
		||||
0+"
 | 
			
		||||
sFull64\x20(0) ,"
 | 
			
		||||
b110 -"
 | 
			
		||||
sReadL2Reg\x20(0) ."
 | 
			
		||||
1/"
 | 
			
		||||
b10 0"
 | 
			
		||||
b11 1"
 | 
			
		||||
b100 2"
 | 
			
		||||
b0 3"
 | 
			
		||||
b0 4"
 | 
			
		||||
05"
 | 
			
		||||
16"
 | 
			
		||||
b10 7"
 | 
			
		||||
b11 8"
 | 
			
		||||
b100 9"
 | 
			
		||||
b0 :"
 | 
			
		||||
b0 ;"
 | 
			
		||||
0<"
 | 
			
		||||
sLoad\x20(0) ="
 | 
			
		||||
1>"
 | 
			
		||||
b10 ?"
 | 
			
		||||
b11 @"
 | 
			
		||||
b100 A"
 | 
			
		||||
b0 B"
 | 
			
		||||
b0 C"
 | 
			
		||||
0D"
 | 
			
		||||
1E"
 | 
			
		||||
b10 F"
 | 
			
		||||
b11 G"
 | 
			
		||||
b100 H"
 | 
			
		||||
b0 I"
 | 
			
		||||
b0 J"
 | 
			
		||||
0K"
 | 
			
		||||
0L"
 | 
			
		||||
b1000000000100 M"
 | 
			
		||||
1N"
 | 
			
		||||
sHdlNone\x20(0) O"
 | 
			
		||||
sTrap\x20(0) P"
 | 
			
		||||
1Q"
 | 
			
		||||
1R"
 | 
			
		||||
1S"
 | 
			
		||||
sHdlSome\x20(1) T"
 | 
			
		||||
0U"
 | 
			
		||||
sHdlSome\x20(1) V"
 | 
			
		||||
0W"
 | 
			
		||||
sAluBranch\x20(0) X"
 | 
			
		||||
1Y"
 | 
			
		||||
sHdlSome\x20(1) Z"
 | 
			
		||||
0["
 | 
			
		||||
0\"
 | 
			
		||||
sAluBranch\x20(0) ]"
 | 
			
		||||
1^"
 | 
			
		||||
sHdlSome\x20(1) _"
 | 
			
		||||
0`"
 | 
			
		||||
0a"
 | 
			
		||||
0b"
 | 
			
		||||
1c"
 | 
			
		||||
0d"
 | 
			
		||||
1e"
 | 
			
		||||
0f"
 | 
			
		||||
1g"
 | 
			
		||||
sHdlNone\x20(0) h"
 | 
			
		||||
b0 i"
 | 
			
		||||
1j"
 | 
			
		||||
sHdlSome\x20(1) k"
 | 
			
		||||
b0 l"
 | 
			
		||||
0m"
 | 
			
		||||
0n"
 | 
			
		||||
0o"
 | 
			
		||||
0p"
 | 
			
		||||
0q"
 | 
			
		||||
0r"
 | 
			
		||||
0s"
 | 
			
		||||
0t"
 | 
			
		||||
0u"
 | 
			
		||||
0v"
 | 
			
		||||
0w"
 | 
			
		||||
0x"
 | 
			
		||||
0y"
 | 
			
		||||
0z"
 | 
			
		||||
0{"
 | 
			
		||||
0|"
 | 
			
		||||
0}"
 | 
			
		||||
sHdlNone\x20(0) ~"
 | 
			
		||||
b0 !#
 | 
			
		||||
0"#
 | 
			
		||||
1##
 | 
			
		||||
0$#
 | 
			
		||||
0%#
 | 
			
		||||
1&#
 | 
			
		||||
0'#
 | 
			
		||||
0(#
 | 
			
		||||
1)#
 | 
			
		||||
b0 *#
 | 
			
		||||
0+#
 | 
			
		||||
1,#
 | 
			
		||||
0-#
 | 
			
		||||
0.#
 | 
			
		||||
1/#
 | 
			
		||||
00#
 | 
			
		||||
01#
 | 
			
		||||
12#
 | 
			
		||||
b0 3#
 | 
			
		||||
04#
 | 
			
		||||
15#
 | 
			
		||||
b0 6#
 | 
			
		||||
07#
 | 
			
		||||
18#
 | 
			
		||||
09#
 | 
			
		||||
0:#
 | 
			
		||||
1;#
 | 
			
		||||
0<#
 | 
			
		||||
0=#
 | 
			
		||||
1>#
 | 
			
		||||
b0 ?#
 | 
			
		||||
0@#
 | 
			
		||||
1A#
 | 
			
		||||
0B#
 | 
			
		||||
0C#
 | 
			
		||||
1D#
 | 
			
		||||
0E#
 | 
			
		||||
0F#
 | 
			
		||||
1G#
 | 
			
		||||
b0 H#
 | 
			
		||||
0I#
 | 
			
		||||
1J#
 | 
			
		||||
b0 K#
 | 
			
		||||
0L#
 | 
			
		||||
1M#
 | 
			
		||||
b0 N#
 | 
			
		||||
sHdlNone\x20(0) O#
 | 
			
		||||
b0 P#
 | 
			
		||||
0Q#
 | 
			
		||||
1R#
 | 
			
		||||
sHdlNone\x20(0) S#
 | 
			
		||||
b0 T#
 | 
			
		||||
1U#
 | 
			
		||||
sHdlSome\x20(1) V#
 | 
			
		||||
b0 W#
 | 
			
		||||
0X#
 | 
			
		||||
$end
 | 
			
		||||
#500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#1000000
 | 
			
		||||
0!
 | 
			
		||||
0"
 | 
			
		||||
0b"
 | 
			
		||||
0c"
 | 
			
		||||
0d"
 | 
			
		||||
0e"
 | 
			
		||||
0f"
 | 
			
		||||
0g"
 | 
			
		||||
0Q#
 | 
			
		||||
0R#
 | 
			
		||||
#1500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#2000000
 | 
			
		||||
0!
 | 
			
		||||
0b"
 | 
			
		||||
0d"
 | 
			
		||||
0f"
 | 
			
		||||
0Q#
 | 
			
		||||
#2500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#3000000
 | 
			
		||||
0!
 | 
			
		||||
0b"
 | 
			
		||||
0d"
 | 
			
		||||
0f"
 | 
			
		||||
0Q#
 | 
			
		||||
#3500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#4000000
 | 
			
		||||
0!
 | 
			
		||||
0b"
 | 
			
		||||
0d"
 | 
			
		||||
0f"
 | 
			
		||||
0Q#
 | 
			
		||||
#4500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#5000000
 | 
			
		||||
0!
 | 
			
		||||
0b"
 | 
			
		||||
0d"
 | 
			
		||||
0f"
 | 
			
		||||
0Q#
 | 
			
		||||
#5500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#6000000
 | 
			
		||||
0!
 | 
			
		||||
0b"
 | 
			
		||||
0d"
 | 
			
		||||
0f"
 | 
			
		||||
0Q#
 | 
			
		||||
#6500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#7000000
 | 
			
		||||
0!
 | 
			
		||||
0b"
 | 
			
		||||
0d"
 | 
			
		||||
0f"
 | 
			
		||||
0Q#
 | 
			
		||||
#7500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#8000000
 | 
			
		||||
0!
 | 
			
		||||
0b"
 | 
			
		||||
0d"
 | 
			
		||||
0f"
 | 
			
		||||
0Q#
 | 
			
		||||
#8500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#9000000
 | 
			
		||||
0!
 | 
			
		||||
0b"
 | 
			
		||||
0d"
 | 
			
		||||
0f"
 | 
			
		||||
0Q#
 | 
			
		||||
#9500000
 | 
			
		||||
1!
 | 
			
		||||
1b"
 | 
			
		||||
1d"
 | 
			
		||||
1f"
 | 
			
		||||
1Q#
 | 
			
		||||
#10000000
 | 
			
		||||
							
								
								
									
										101
									
								
								crates/cpu/tests/reg_alloc.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								crates/cpu/tests/reg_alloc.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,101 @@
 | 
			
		|||
// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
			
		||||
// See Notices.txt for copyright information
 | 
			
		||||
 | 
			
		||||
use cpu::{
 | 
			
		||||
    config::CpuConfig,
 | 
			
		||||
    instruction::{
 | 
			
		||||
        AddSubMOp, AluCommonMOp, CommonMOp, LogicalMOp, MOp, OutputIntegerMode,
 | 
			
		||||
        COMMON_MOP_2_IMM_WIDTH, COMMON_MOP_3_IMM_WIDTH,
 | 
			
		||||
    },
 | 
			
		||||
    reg_alloc::{reg_alloc, FetchedDecodedMOp},
 | 
			
		||||
    unit::UnitKind,
 | 
			
		||||
};
 | 
			
		||||
use fayalite::{
 | 
			
		||||
    prelude::*,
 | 
			
		||||
    sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation},
 | 
			
		||||
    util::RcWriter,
 | 
			
		||||
};
 | 
			
		||||
use std::num::NonZeroUsize;
 | 
			
		||||
 | 
			
		||||
#[hdl]
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_reg_alloc() {
 | 
			
		||||
    let _n = SourceLocation::normalize_files_for_tests();
 | 
			
		||||
    let mut config = CpuConfig::new(vec![UnitKind::AluBranch]);
 | 
			
		||||
    config.fetch_width = NonZeroUsize::new(2).unwrap();
 | 
			
		||||
    let mut sim = Simulation::new(reg_alloc(&config));
 | 
			
		||||
    let mut writer = RcWriter::default();
 | 
			
		||||
    sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
 | 
			
		||||
    let fetch_decode_interface = sim.io().fetch_decode_interface;
 | 
			
		||||
    sim.write_clock(sim.io().cd.clk, false);
 | 
			
		||||
    sim.write_reset(sim.io().cd.rst, true);
 | 
			
		||||
    sim.write_bool(fetch_decode_interface.fetch_decode_special_op.ready, true);
 | 
			
		||||
    sim.write(
 | 
			
		||||
        fetch_decode_interface.decoded_insns[0].data,
 | 
			
		||||
        HdlSome(
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            FetchedDecodedMOp {
 | 
			
		||||
                uop: MOp.AluBranch(MOp.AluBranch.AddSub(
 | 
			
		||||
                    #[hdl]
 | 
			
		||||
                    AddSubMOp {
 | 
			
		||||
                        alu_common: #[hdl]
 | 
			
		||||
                        AluCommonMOp {
 | 
			
		||||
                            common: CommonMOp::new(
 | 
			
		||||
                                0_hdl_u0,
 | 
			
		||||
                                1u8,
 | 
			
		||||
                                [2u8, 3u8, 4u8],
 | 
			
		||||
                                0x1234.cast_to(SInt[COMMON_MOP_3_IMM_WIDTH]),
 | 
			
		||||
                            ),
 | 
			
		||||
                            output_integer_mode: OutputIntegerMode.Full64(),
 | 
			
		||||
                        },
 | 
			
		||||
                        invert_src0: true,
 | 
			
		||||
                        invert_carry_in: true,
 | 
			
		||||
                        invert_carry_out: true,
 | 
			
		||||
                        add_pc: true,
 | 
			
		||||
                    },
 | 
			
		||||
                )),
 | 
			
		||||
                is_unrelated_pc: true,
 | 
			
		||||
                pc: 0x1000_hdl_u64,
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
    );
 | 
			
		||||
    sim.write(
 | 
			
		||||
        fetch_decode_interface.decoded_insns[1].data,
 | 
			
		||||
        HdlSome(
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            FetchedDecodedMOp {
 | 
			
		||||
                uop: MOp.AluBranch(MOp.AluBranch.Logical(
 | 
			
		||||
                    #[hdl]
 | 
			
		||||
                    LogicalMOp {
 | 
			
		||||
                        alu_common: #[hdl]
 | 
			
		||||
                        AluCommonMOp {
 | 
			
		||||
                            common: CommonMOp::new(
 | 
			
		||||
                                0_hdl_u0,
 | 
			
		||||
                                2u8,
 | 
			
		||||
                                [3u8, 4u8],
 | 
			
		||||
                                SInt[COMMON_MOP_2_IMM_WIDTH].zero(),
 | 
			
		||||
                            ),
 | 
			
		||||
                            output_integer_mode: OutputIntegerMode.Full64(),
 | 
			
		||||
                        },
 | 
			
		||||
                        lut: 0b0110_hdl_u4,
 | 
			
		||||
                    },
 | 
			
		||||
                )),
 | 
			
		||||
                is_unrelated_pc: false,
 | 
			
		||||
                pc: 0x1004_hdl_u64,
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
    );
 | 
			
		||||
    for cycle in 0..10 {
 | 
			
		||||
        sim.advance_time(SimDuration::from_nanos(500));
 | 
			
		||||
        sim.write_clock(sim.io().cd.clk, true);
 | 
			
		||||
        sim.advance_time(SimDuration::from_nanos(500));
 | 
			
		||||
        sim.write_clock(sim.io().cd.clk, false);
 | 
			
		||||
        sim.write_reset(sim.io().cd.rst, false);
 | 
			
		||||
    }
 | 
			
		||||
    // FIXME: vcd is just whatever reg_alloc does now, which isn't known to be correct
 | 
			
		||||
    let vcd = String::from_utf8(writer.take()).unwrap();
 | 
			
		||||
    println!("####### VCD:\n{vcd}\n#######");
 | 
			
		||||
    if vcd != include_str!("expected/reg_alloc.vcd") {
 | 
			
		||||
        panic!();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +45,9 @@ function main()
 | 
			
		|||
        */LICENSE.md|*/Notices.txt)
 | 
			
		||||
            # copyright file
 | 
			
		||||
            ;;
 | 
			
		||||
        /crates/cpu/tests/expected/*.vcd)
 | 
			
		||||
            # file that can't contain copyright header
 | 
			
		||||
            ;;
 | 
			
		||||
        /.forgejo/workflows/*.yml|*/.gitignore|*.toml)
 | 
			
		||||
            check_file "$file" "${POUND_HEADER[@]}"
 | 
			
		||||
            ;;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue