forked from libre-chip/cpu
		
	Compare commits
	
		
			6 commits
		
	
	
		
			master
			...
			main_memor
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8433f4f150 | ||
|  | 672a29e76d | ||
|  | 35ea85d074 | ||
|  | 1ead550d13 | ||
|  | 540a91878c | ||
|  | 9f68cbb953 | 
					 3 changed files with 154 additions and 0 deletions
				
			
		|  | @ -6,3 +6,5 @@ pub mod reg_alloc; | ||||||
| pub mod register; | pub mod register; | ||||||
| pub mod unit; | pub mod unit; | ||||||
| pub mod util; | pub mod util; | ||||||
|  | //TODO read other modules
 | ||||||
|  | pub mod main_memory; | ||||||
|  |  | ||||||
							
								
								
									
										60
									
								
								crates/cpu/src/main_memory.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								crates/cpu/src/main_memory.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,60 @@ | ||||||
|  | // 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<64> = m.output(); | ||||||
|  |     #[hdl] | ||||||
|  |     let en: Bool = m.input(); | ||||||
|  | 
 | ||||||
|  |     //WIP: add write support
 | ||||||
|  |     #[hdl] | ||||||
|  |     let write_en: Bool = m.input(); | ||||||
|  |     #[hdl] | ||||||
|  |     let write_data: UInt<64> = m.input(); | ||||||
|  | 
 | ||||||
|  |     #[hdl] | ||||||
|  |     let cd: ClockDomain = m.input(); | ||||||
|  | 
 | ||||||
|  |     #[hdl] // FIXME: do not hardcode memory size and content --
 | ||||||
|  |     //let mut my_memory = memory_with_init([0x12_hdl_u8, 0x34_hdl_u8, 0x56_hdl_u8, 0x78_hdl_u8]);
 | ||||||
|  |     let mut my_memory = memory(); | ||||||
|  |     my_memory.depth(256); //TODO make configurable
 | ||||||
|  | 
 | ||||||
|  |     let read_port = my_memory.new_read_port(); | ||||||
|  |     connect_any(read_port.addr, addr); | ||||||
|  |     connect_any(read_port.en, addr.cmp_lt(256u64) & en); // and not write_en
 | ||||||
|  |     connect(read_port.clk, cd.clk); | ||||||
|  |     connect(read_data, read_port.data); | ||||||
|  | 
 | ||||||
|  |     let write_port = my_memory.new_write_port(); | ||||||
|  |     connect_any(write_port.addr, addr); | ||||||
|  |     connect_any(write_port.en, addr.cmp_lt(256u64) & en & write_en); | ||||||
|  |     connect_any(write_port.data, write_data); | ||||||
|  |     connect(write_port.clk, cd.clk); | ||||||
|  | 
 | ||||||
|  |     connect_any(write_port.mask, true); //can only write 8 bits at a time
 | ||||||
|  | } | ||||||
							
								
								
									
										92
									
								
								crates/cpu/tests/main_memory.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								crates/cpu/tests/main_memory.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | ||||||
|  | // 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}, | ||||||
|  |     main_memory::main_memory, | ||||||
|  |     reg_alloc::{FetchedDecodedMOp, reg_alloc}, | ||||||
|  |     register::{FlagsMode, PRegFlagsPowerISA}, | ||||||
|  |     unit::{GlobalState, UnitKind}, | ||||||
|  | }; | ||||||
|  | use fayalite::{ | ||||||
|  |     assert_export_firrtl, | ||||||
|  |     firrtl::ExportOptions, | ||||||
|  |     prelude::*, | ||||||
|  |     sim::{Simulation, time::SimDuration, vcd::VcdWriterDecls}, | ||||||
|  |     util::RcWriter, | ||||||
|  | }; | ||||||
|  | use std::num::NonZeroUsize; | ||||||
|  | 
 | ||||||
|  | //new test - much simpler
 | ||||||
|  | #[test] | ||||||
|  | fn test_main_memory() { | ||||||
|  |     let mut config = CpuConfig::new( | ||||||
|  |         vec![ | ||||||
|  |             UnitConfig::new(UnitKind::AluBranch), | ||||||
|  |             UnitConfig::new(UnitKind::AluBranch), | ||||||
|  |         ], | ||||||
|  |         NonZeroUsize::new(20).unwrap(), | ||||||
|  |     ); | ||||||
|  |     // create a simulation from main_memory()
 | ||||||
|  |     let mut sim = Simulation::new(main_memory(&config)); | ||||||
|  |     // add a .vcd writer that writes to main_memory.vcd -- this is simple for demo purposes,
 | ||||||
|  |     // but for our actual code we should do better than just writing
 | ||||||
|  |     // to main_memory.vcd in the repository's root
 | ||||||
|  |     //WRONG: sim.add_trace_writer(std::fs::File::create("main_memory.vcd").unwrap());
 | ||||||
|  | 
 | ||||||
|  |     let out_file = std::fs::File::create("main_memory.vcd").unwrap(); | ||||||
|  |     sim.add_trace_writer(VcdWriterDecls::new(out_file)); | ||||||
|  | 
 | ||||||
|  |     sim.write(sim.io().en, true); | ||||||
|  |     sim.write(sim.io().cd.rst, false); | ||||||
|  |     sim.write(sim.io().cd.clk, false); | ||||||
|  |     sim.write(sim.io().write_en, false); | ||||||
|  |     sim.write(sim.io().write_data, 0xFF00FF00FF00FF00u64); | ||||||
|  | 
 | ||||||
|  |     // TODO convert to for loop
 | ||||||
|  |     // you need to write an initial value to all inputs before you can start running the simulation
 | ||||||
|  |     sim.write(sim.io().addr, 0x12345u64); | ||||||
|  |     // now wait 1us because why not
 | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); //panic here at simulation
 | ||||||
|  | 
 | ||||||
|  |     dbg!(sim.read(sim.io().read_data)); // dbg! macro just displays the value you pass to it
 | ||||||
|  | 
 | ||||||
|  |     for n in 0u64..4u64 { | ||||||
|  |         sim.write(sim.io().addr, n); | ||||||
|  |         // now wait 1us because why not
 | ||||||
|  |         sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     sim.write(sim.io().write_en, true); | ||||||
|  |     sim.write(sim.io().addr, 0u64); | ||||||
|  |     sim.write(sim.io().write_data, 0xFFFFFFFFFFFFFFFFu64); //fill with ones
 | ||||||
|  | 
 | ||||||
|  |     sim.write_clock(sim.io().cd.clk, true); | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |     sim.write_clock(sim.io().cd.clk, false); | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  | 
 | ||||||
|  |     sim.write(sim.io().addr, 1u64); | ||||||
|  | 
 | ||||||
|  |     sim.write_clock(sim.io().cd.clk, true); | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |     sim.write_clock(sim.io().cd.clk, false); | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  | 
 | ||||||
|  |     sim.write(sim.io().addr, 2u64); | ||||||
|  | 
 | ||||||
|  |     sim.write_clock(sim.io().cd.clk, true); | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |     sim.write_clock(sim.io().cd.clk, false); | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  | 
 | ||||||
|  |     sim.write(sim.io().addr, 3u64); | ||||||
|  | 
 | ||||||
|  |     sim.write_clock(sim.io().cd.clk, true); | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |     sim.write_clock(sim.io().cd.clk, false); | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  | 
 | ||||||
|  |     sim.flush_traces().unwrap(); // make sure everything is written to the output file
 | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue