From 9f68cbb953980d4bf197684a53b874664a6beb53 Mon Sep 17 00:00:00 2001 From: Tobias Alexandra Platen Date: Sun, 5 Oct 2025 11:04:18 +0200 Subject: [PATCH] add main_memory --- crates/cpu/src/lib.rs | 2 ++ crates/cpu/src/main_memory.rs | 62 ++++++++++++++++++++++++++++++++ crates/cpu/tests/main_memory.rs | 64 +++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 crates/cpu/src/main_memory.rs create mode 100644 crates/cpu/tests/main_memory.rs diff --git a/crates/cpu/src/lib.rs b/crates/cpu/src/lib.rs index bae3720..c6fd36c 100644 --- a/crates/cpu/src/lib.rs +++ b/crates/cpu/src/lib.rs @@ -6,3 +6,5 @@ pub mod reg_alloc; pub mod register; pub mod unit; pub mod util; +//TODO read other modules +pub mod main_memory; diff --git a/crates/cpu/src/main_memory.rs b/crates/cpu/src/main_memory.rs new file mode 100644 index 0000000..f386061 --- /dev/null +++ b/crates/cpu/src/main_memory.rs @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information + +// first copied code block -- changes needed +use crate::{ + config::CpuConfig, + instruction::{ + AluBranchMOp, LoadStoreMOp, MOp, MOpDestReg, MOpInto, MOpRegNum, MOpTrait, RenamedMOp, + UnitOutRegNum, mop_enum, + }, + register::{FlagsMode, PRegValue}, + unit::unit_base::UnitToRegAlloc, +}; +use fayalite::{ + bundle::{Bundle, BundleType}, + intern::{Intern, Interned}, + prelude::*, +}; + +//input address <32> bit ? +//output data word <8> bit for first test (read only) + +#[hdl_module] +/// add a comment here +pub fn main_memory(config: &CpuConfig) { + #[hdl] + let addr: UInt<64> = m.input(); + #[hdl] + let read_data: UInt<8> = m.output(); + #[hdl] + let en: Bool = m.input(); + + #[hdl] + let cd: ClockDomain = m.input(); + // for each instance do + // connect(instance.cd, cd); + + + #[hdl] + //let mut mem = memory_with_init([0x12u8, 0x34, 0x56, 0x78]); + let mut my_memory = memory_with_init([0x12_hdl_u8, 0x34_hdl_u8, 0x56_hdl_u8, 0x78_hdl_u8]); + + let read_port = my_memory.new_read_port(); + // note that `read_addr` is `UInt<2>` since the memory only has 4 elements + //need to connect addr en clk and data->out + connect_any(read_port.addr, addr); //FIXME + connect(read_port.en, en); + connect(read_port.clk, cd.clk); + connect(read_data,read_port.data); + + + + +} + +// see https://git.libre-chip.org/libre-chip/fayalite/src/branch/master/crates/fayalite/tests/sim.rs +// how to write testbenches +// start with a very simple memory model -> +// TODO create a branch for the memory + +// 1 connect up the read port, add write later +// ask how I make the memory pipelined later ... not today diff --git a/crates/cpu/tests/main_memory.rs b/crates/cpu/tests/main_memory.rs new file mode 100644 index 0000000..4792bef --- /dev/null +++ b/crates/cpu/tests/main_memory.rs @@ -0,0 +1,64 @@ +// 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::{FetchedDecodedMOp, reg_alloc}, + register::{FlagsMode, PRegFlagsPowerISA}, + unit::{GlobalState, UnitKind}, + main_memory::main_memory, +}; +use fayalite::{ + assert_export_firrtl, + firrtl::ExportOptions, + prelude::*, + sim::{Simulation, time::SimDuration, vcd::VcdWriterDecls}, + util::RcWriter, +}; +use std::num::NonZeroUsize; + +#[hdl] +#[test] +fn test_main_memory() { +// see reg_alloc.rs for reference + 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(); //unchanged for now + let m = main_memory(&config); + let mut sim = Simulation::new(m); + let mut writer = RcWriter::default(); + sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); + sim.write_clock(sim.io().cd.clk, false); + sim.write_reset(sim.io().cd.rst, true); + //TODO sim.write_bool + //TODO sim.write( + //footer for tests + // 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") { //FIXME panic on result compare + // panic!(); //test is incomplete here, getting 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!(); + // } + +}