forked from libre-chip/fayalite
		
	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::{
 | 
			
		||||
    int::UIntValue,
 | 
			
		||||
    module::{instance_with_loc, reg_builder_with_loc},
 | 
			
		||||
    prelude::*,
 | 
			
		||||
    reset::ResetType,
 | 
			
		||||
    sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation, ToSimValue},
 | 
			
		||||
| 
						 | 
				
			
			@ -1532,3 +1533,83 @@ fn test_extern_module2() {
 | 
			
		|||
        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