add ripple counter test to test simulating alternating circuits and extern modules
This commit is contained in:
		
							parent
							
								
									a115585d5a
								
							
						
					
					
						commit
						1b220b73e7
					
				
					 3 changed files with 1834 additions and 0 deletions
				
			
		|  | @ -3,6 +3,7 @@ | ||||||
| 
 | 
 | ||||||
| use fayalite::{ | use fayalite::{ | ||||||
|     int::UIntValue, |     int::UIntValue, | ||||||
|  |     module::{instance_with_loc, reg_builder_with_loc}, | ||||||
|     prelude::*, |     prelude::*, | ||||||
|     reset::ResetType, |     reset::ResetType, | ||||||
|     sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation, ToSimValue}, |     sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation, ToSimValue}, | ||||||
|  | @ -1532,3 +1533,83 @@ fn test_extern_module2() { | ||||||
|         panic!(); |         panic!(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // use an extern module to simulate a register to test that the
 | ||||||
|  | // simulator can handle chains of alternating circuits and extern modules.
 | ||||||
|  | #[hdl_module(outline_generated, extern)] | ||||||
|  | pub fn sw_reg() { | ||||||
|  |     #[hdl] | ||||||
|  |     let clk: Clock = m.input(); | ||||||
|  |     #[hdl] | ||||||
|  |     let o: Bool = m.output(); | ||||||
|  |     m.extern_module_simulation_fn((clk, o), |(clk, o), mut sim| async move { | ||||||
|  |         let mut state = false; | ||||||
|  |         loop { | ||||||
|  |             sim.write(o, state).await; | ||||||
|  |             sim.wait_for_clock_edge(clk).await; | ||||||
|  |             state = !state; | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[hdl_module(outline_generated)] | ||||||
|  | pub fn ripple_counter() { | ||||||
|  |     #[hdl] | ||||||
|  |     let clk: Clock = m.input(); | ||||||
|  |     #[hdl] | ||||||
|  |     let o: UInt<6> = m.output(); | ||||||
|  | 
 | ||||||
|  |     #[hdl] | ||||||
|  |     let bits: Array<Bool, 6> = wire(); | ||||||
|  | 
 | ||||||
|  |     connect_any(o, bits.cast_to_bits()); | ||||||
|  | 
 | ||||||
|  |     let mut clk_in = clk; | ||||||
|  |     for (i, bit) in bits.into_iter().enumerate() { | ||||||
|  |         if i % 2 == 0 { | ||||||
|  |             let bit_reg = reg_builder_with_loc(&format!("bit_reg_{i}"), SourceLocation::caller()) | ||||||
|  |                 .clock_domain( | ||||||
|  |                     #[hdl] | ||||||
|  |                     ClockDomain { | ||||||
|  |                         clk: clk_in, | ||||||
|  |                         rst: false.to_sync_reset(), | ||||||
|  |                     }, | ||||||
|  |                 ) | ||||||
|  |                 .no_reset(Bool) | ||||||
|  |                 .build(); | ||||||
|  |             connect(bit, bit_reg); | ||||||
|  |             connect(bit_reg, !bit_reg); | ||||||
|  |         } else { | ||||||
|  |             let bit_reg = | ||||||
|  |                 instance_with_loc(&format!("bit_reg_{i}"), sw_reg(), SourceLocation::caller()); | ||||||
|  |             connect(bit_reg.clk, clk_in); | ||||||
|  |             connect(bit, bit_reg.o); | ||||||
|  |         } | ||||||
|  |         clk_in = bit.to_clock(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn test_ripple_counter() { | ||||||
|  |     let _n = SourceLocation::normalize_files_for_tests(); | ||||||
|  |     let mut sim = Simulation::new(ripple_counter()); | ||||||
|  |     let mut writer = RcWriter::default(); | ||||||
|  |     sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); | ||||||
|  |     for _ in 0..0x80 { | ||||||
|  |         sim.write(sim.io().clk, false); | ||||||
|  |         sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |         sim.write(sim.io().clk, true); | ||||||
|  |         sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |     } | ||||||
|  |     sim.flush_traces().unwrap(); | ||||||
|  |     let vcd = String::from_utf8(writer.take()).unwrap(); | ||||||
|  |     println!("####### VCD:\n{vcd}\n#######"); | ||||||
|  |     if vcd != include_str!("sim/expected/ripple_counter.vcd") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  |     let sim_debug = format!("{sim:#?}"); | ||||||
|  |     println!("#######\n{sim_debug}\n#######"); | ||||||
|  |     if sim_debug != include_str!("sim/expected/ripple_counter.txt") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										0
									
								
								crates/fayalite/tests/sim/expected/ripple_counter.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								crates/fayalite/tests/sim/expected/ripple_counter.txt
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										1753
									
								
								crates/fayalite/tests/sim/expected/ripple_counter.vcd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1753
									
								
								crates/fayalite/tests/sim/expected/ripple_counter.vcd
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue