cpu/crates/cpu/tests/reg_alloc.rs
Jacob Lifshay 6c91d1b0b0
All checks were successful
/ deps (push) Successful in 1m19s
/ test (push) Successful in 26m13s
start adding ROB
2025-02-27 18:22:01 -08:00

156 lines
4.9 KiB
Rust

// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
use cpu::{
config::{CpuConfig, UnitConfig},
instruction::{AddSubMOp, LogicalMOp, MOp, MOpDestReg, MOpRegNum, OutputIntegerMode},
reg_alloc::{reg_alloc, FetchedDecodedMOp},
register::{FlagsMode, PRegFlagsPowerISA},
unit::{GlobalState, UnitKind},
};
use fayalite::{
assert_export_firrtl,
firrtl::ExportOptions,
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![
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::AluBranch),
],
NonZeroUsize::new(20).unwrap(),
);
config.fetch_width = NonZeroUsize::new(2).unwrap();
let m = reg_alloc(&config);
let mut sim = Simulation::new(m);
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(
sim.io().global_state,
#[hdl]
GlobalState {
flags_mode: FlagsMode.PowerISA(
#[hdl]
PRegFlagsPowerISA {},
),
},
);
let insns_init: [Expr<MOp>; 4] = std::array::from_fn(|i| {
AddSubMOp::add_sub_i(
#[hdl]
MOpDestReg {
normal_regs: #[hdl]
[
#[hdl]
MOpRegNum { value: i as u8 + 1 },
MOpRegNum::const_zero(),
],
flag_regs: #[hdl]
[HdlSome(()), HdlNone()],
},
[0u8; 2],
0x12345678u32.cast_to_static(),
OutputIntegerMode.DupLow32(),
false,
false,
false,
false,
)
});
let insns_loop = [
AddSubMOp::add_sub(
#[hdl]
MOpDestReg {
normal_regs: #[hdl]
[
#[hdl]
MOpRegNum { value: 1u8 },
MOpRegNum::const_zero(),
],
flag_regs: #[hdl]
[HdlSome(()), HdlNone()],
},
[1u8, 0, 0],
1.cast_to_static(),
OutputIntegerMode.Full64(),
false,
false,
false,
false,
),
LogicalMOp::logical(
#[hdl]
MOpDestReg {
normal_regs: [
#[hdl]
MOpRegNum { value: 2u8 },
MOpRegNum::const_zero(),
],
flag_regs: [HdlNone(), HdlSome(())],
},
[2u8, 4u8],
0.cast_to_static(),
OutputIntegerMode.Full64(),
0b0110_hdl_u4,
),
];
let insns = insns_init.into_iter().chain(insns_loop.into_iter().cycle());
let mut insn_index = 0;
for cycle in 0..20 {
for fetch_index in 0..config.fetch_width.get() {
let mop = insns.clone().nth(insn_index).unwrap();
sim.write(
fetch_decode_interface.decoded_insns[fetch_index].data,
HdlSome(
#[hdl]
FetchedDecodedMOp {
mop,
is_unrelated_pc: insn_index == 0,
pc: 0x1000u64 + 4 * insn_index as u64,
},
),
);
insn_index += 1;
}
if cycle == 0 {
insn_index = 0;
}
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!();
}
// #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
// assert_export_firrtl! {
// m =>
// options: ExportOptions {
// simplify_enums: None,
// ..ExportOptions::default()
// },
// "/test/reg_alloc.fir": "",
// };
// let sim_debug = format!("{sim:#?}");
// println!("#######\n{sim_debug}\n#######");
// if sim_debug != include_str!("expected/reg_alloc.txt") {
// panic!();
// }
}