forked from libre-chip/fayalite
		
	writing VCD for combinatorial circuits works!
This commit is contained in:
		
							parent
							
								
									c4b5d00419
								
							
						
					
					
						commit
						11ddbc43c7
					
				
					 2 changed files with 92 additions and 20 deletions
				
			
		|  | @ -3620,6 +3620,7 @@ struct SimulationImpl { | |||
|     uninitialized_inputs: HashSet<Target>, | ||||
|     io_targets: HashMap<Target, CompiledValue<CanonicalType>>, | ||||
|     made_initial_step: bool, | ||||
|     needs_settle: bool, | ||||
|     trace_decls: TraceModule, | ||||
|     traces: Box<[SimTrace<BitVec>]>, | ||||
|     trace_writers: Vec<TraceWriterState<DynTraceWriterDecls>>, | ||||
|  | @ -3669,6 +3670,7 @@ impl SimulationImpl { | |||
|             uninitialized_inputs: HashSet::new(), | ||||
|             io_targets: HashMap::new(), | ||||
|             made_initial_step: false, | ||||
|             needs_settle: true, | ||||
|             trace_decls: compiled.base_module.trace_decls, | ||||
|             traces: Box::from_iter(compiled.traces.iter().map( | ||||
|                 |&SimTrace { | ||||
|  | @ -3804,9 +3806,7 @@ impl SimulationImpl { | |||
|     } | ||||
|     #[track_caller] | ||||
|     fn advance_time(&mut self, duration: SimDuration) { | ||||
|         if !self.made_initial_step { | ||||
|             self.settle_step(); | ||||
|         } | ||||
|         self.settle_step(); | ||||
|         self.instant += duration; | ||||
|         self.for_each_trace_writer_storing_error(|this, mut trace_writer_state| { | ||||
|             match &mut trace_writer_state { | ||||
|  | @ -3825,6 +3825,9 @@ impl SimulationImpl { | |||
|             self.uninitialized_inputs.is_empty(), | ||||
|             "didn't initialize all inputs", | ||||
|         ); | ||||
|         if !self.needs_settle { | ||||
|             return; | ||||
|         } | ||||
|         self.state.setup_call(0); | ||||
|         self.state.run(); | ||||
|         if self.made_initial_step { | ||||
|  | @ -3833,6 +3836,7 @@ impl SimulationImpl { | |||
|             self.read_traces::<true>(); | ||||
|         } | ||||
|         self.made_initial_step = true; | ||||
|         self.needs_settle = false; | ||||
|         self.for_each_trace_writer_storing_error(|this, trace_writer_state| { | ||||
|             Ok(match trace_writer_state { | ||||
|                 TraceWriterState::Decls(trace_writer_decls) => TraceWriterState::Running( | ||||
|  | @ -3861,12 +3865,14 @@ impl SimulationImpl { | |||
|         panic!("simulator read/write expression must not have dynamic array indexes"); | ||||
|     } | ||||
|     #[track_caller] | ||||
|     fn read_bool_or_int<I: BoolOrIntType>(&self, io: Expr<I>) -> I::Value { | ||||
|     fn read_bool_or_int<I: BoolOrIntType>(&mut self, io: Expr<I>) -> I::Value { | ||||
|         let Some(target) = io.target() else { | ||||
|             panic!("can't read from expression that's not a field/element of `Simulation::io()`"); | ||||
|         }; | ||||
|         let compiled_value = self.get_io(*target); | ||||
|         if !self.made_initial_step { | ||||
|         if self.made_initial_step { | ||||
|             self.settle_step(); | ||||
|         } else { | ||||
|             match target.flow() { | ||||
|                 Flow::Source => { | ||||
|                     panic!("can't read from an output before the simulation has made any steps"); | ||||
|  | @ -3906,6 +3912,7 @@ impl SimulationImpl { | |||
|         if !self.made_initial_step { | ||||
|             self.uninitialized_inputs.remove(&*target); | ||||
|         } | ||||
|         self.needs_settle = true; | ||||
|         match compiled_value.range.len() { | ||||
|             TypeLen::A_SMALL_SLOT => { | ||||
|                 self.state.small_slots[compiled_value.range.small_slots.start] = | ||||
|  | @ -3981,9 +3988,15 @@ impl SimulationImpl { | |||
|         retval | ||||
|     } | ||||
|     fn close(mut self) -> std::io::Result<()> { | ||||
|         if self.made_initial_step { | ||||
|             self.settle_step(); | ||||
|         } | ||||
|         self.close_all_trace_writers() | ||||
|     } | ||||
|     fn flush_traces(&mut self) -> std::io::Result<()> { | ||||
|         if self.made_initial_step { | ||||
|             self.settle_step(); | ||||
|         } | ||||
|         self.for_each_trace_writer_getting_error( | ||||
|             |this, trace_writer: TraceWriterState<DynTraceWriterDecls>| match trace_writer { | ||||
|                 TraceWriterState::Decls(v) => { | ||||
|  | @ -4068,6 +4081,7 @@ impl<T: BundleType> fmt::Debug for Simulation<T> { | |||
|                     uninitialized_inputs, | ||||
|                     io_targets, | ||||
|                     made_initial_step, | ||||
|                     needs_settle, | ||||
|                     trace_decls, | ||||
|                     traces, | ||||
|                     trace_writers, | ||||
|  | @ -4084,6 +4098,7 @@ impl<T: BundleType> fmt::Debug for Simulation<T> { | |||
|             ) | ||||
|             .field("io_targets", &SortedMapDebug(io_targets)) | ||||
|             .field("made_initial_step", made_initial_step) | ||||
|             .field("needs_settle", needs_settle) | ||||
|             .field("trace_decls", trace_decls) | ||||
|             .field("traces", traces) | ||||
|             .field("trace_writers", trace_writers) | ||||
|  | @ -4140,7 +4155,7 @@ impl<T: BundleType> Simulation<T> { | |||
|         self.sim_impl.advance_time(duration); | ||||
|     } | ||||
|     #[track_caller] | ||||
|     pub fn read_bool_or_int<I: BoolOrIntType>(&self, io: Expr<I>) -> I::Value { | ||||
|     pub fn read_bool_or_int<I: BoolOrIntType>(&mut self, io: Expr<I>) -> I::Value { | ||||
|         self.sim_impl.read_bool_or_int(io) | ||||
|     } | ||||
|     #[track_caller] | ||||
|  |  | |||
|  | @ -120,6 +120,7 @@ fn test_connect_const() { | |||
|         }, | ||||
|     }, | ||||
|     made_initial_step: true, | ||||
|     needs_settle: false, | ||||
|     trace_decls: TraceModule { | ||||
|         name: "connect_const", | ||||
|         children: [ | ||||
|  | @ -182,7 +183,6 @@ pub fn mod1() { | |||
|     connect(o, child); | ||||
| } | ||||
| 
 | ||||
| #[cfg(todo)] | ||||
| #[hdl] | ||||
| #[test] | ||||
| fn test_mod1() { | ||||
|  | @ -195,10 +195,58 @@ fn test_mod1() { | |||
|     sim.advance_time(SimDuration::from_micros(1)); | ||||
|     sim.write_bool_or_int(sim.io().o.i, 0xA_hdl_u4); | ||||
|     sim.advance_time(SimDuration::from_micros(1)); | ||||
|     sim.flush_traces().unwrap(); | ||||
|     let vcd = String::from_utf8(writer.take()).unwrap(); | ||||
|     println!("####### VCD:\n{vcd}\n#######"); | ||||
|     todo!("generated vcd is incorrect"); | ||||
|     if vcd != r#""# { | ||||
|     if vcd | ||||
|         != r#"$timescale 1 ps $end
 | ||||
| $scope module mod1 $end | ||||
| $scope struct o $end | ||||
| $var wire 4 ! i $end | ||||
| $var wire 2 " o $end
 | ||||
| $var wire 2 # i2 $end | ||||
| $var wire 4 $ o2 $end | ||||
| $upscope $end | ||||
| $scope struct child $end | ||||
| $var wire 4 ) i $end | ||||
| $var wire 2 * o $end | ||||
| $var wire 2 + i2 $end | ||||
| $var wire 4 , o2 $end | ||||
| $upscope $end | ||||
| $scope module mod1_child $end | ||||
| $var wire 4 % i $end | ||||
| $var wire 2 & o $end | ||||
| $var wire 2 ' i2 $end | ||||
| $var wire 4 ( o2 $end | ||||
| $upscope $end | ||||
| $upscope $end | ||||
| $enddefinitions $end | ||||
| $dumpvars | ||||
| b11 ! | ||||
| b11 " | ||||
| b10 # | ||||
| b1110 $ | ||||
| b11 % | ||||
| b11 & | ||||
| b10 ' | ||||
| b1110 ( | ||||
| b11 ) | ||||
| b11 * | ||||
| b10 + | ||||
| b1110 , | ||||
| $end | ||||
| #1000000 | ||||
| b1010 ! | ||||
| b10 " | ||||
| b1111 $ | ||||
| b1010 % | ||||
| b10 & | ||||
| b1111 ( | ||||
| b1010 ) | ||||
| b10 * | ||||
| b1111 , | ||||
| #2000000 | ||||
| "# {
 | ||||
|         panic!(); | ||||
|     } | ||||
|     let sim_debug = format!("{sim:#?}"); | ||||
|  | @ -718,6 +766,7 @@ fn test_mod1() { | |||
|         }, | ||||
|     }, | ||||
|     made_initial_step: true, | ||||
|     needs_settle: false, | ||||
|     trace_decls: TraceModule { | ||||
|         name: "mod1", | ||||
|         children: [ | ||||
|  | @ -887,7 +936,7 @@ fn test_mod1() { | |||
|                 ty: UInt<4>, | ||||
|             }, | ||||
|             state: 0xa, | ||||
|             last_state: 0xa, | ||||
|             last_state: 0x3, | ||||
|         }, | ||||
|         SimTrace { | ||||
|             id: TraceScalarId(1), | ||||
|  | @ -896,7 +945,7 @@ fn test_mod1() { | |||
|                 ty: SInt<2>, | ||||
|             }, | ||||
|             state: 0x2, | ||||
|             last_state: 0x2, | ||||
|             last_state: 0x3, | ||||
|         }, | ||||
|         SimTrace { | ||||
|             id: TraceScalarId(2), | ||||
|  | @ -914,7 +963,7 @@ fn test_mod1() { | |||
|                 ty: UInt<4>, | ||||
|             }, | ||||
|             state: 0xf, | ||||
|             last_state: 0xf, | ||||
|             last_state: 0xe, | ||||
|         }, | ||||
|         SimTrace { | ||||
|             id: TraceScalarId(4), | ||||
|  | @ -923,7 +972,7 @@ fn test_mod1() { | |||
|                 ty: UInt<4>, | ||||
|             }, | ||||
|             state: 0xa, | ||||
|             last_state: 0xa, | ||||
|             last_state: 0x3, | ||||
|         }, | ||||
|         SimTrace { | ||||
|             id: TraceScalarId(5), | ||||
|  | @ -932,7 +981,7 @@ fn test_mod1() { | |||
|                 ty: SInt<2>, | ||||
|             }, | ||||
|             state: 0x2, | ||||
|             last_state: 0x2, | ||||
|             last_state: 0x3, | ||||
|         }, | ||||
|         SimTrace { | ||||
|             id: TraceScalarId(6), | ||||
|  | @ -950,7 +999,7 @@ fn test_mod1() { | |||
|                 ty: UInt<4>, | ||||
|             }, | ||||
|             state: 0xf, | ||||
|             last_state: 0xf, | ||||
|             last_state: 0xe, | ||||
|         }, | ||||
|         SimTrace { | ||||
|             id: TraceScalarId(8), | ||||
|  | @ -959,7 +1008,7 @@ fn test_mod1() { | |||
|                 ty: UInt<4>, | ||||
|             }, | ||||
|             state: 0xa, | ||||
|             last_state: 0xa, | ||||
|             last_state: 0x3, | ||||
|         }, | ||||
|         SimTrace { | ||||
|             id: TraceScalarId(9), | ||||
|  | @ -968,7 +1017,7 @@ fn test_mod1() { | |||
|                 ty: SInt<2>, | ||||
|             }, | ||||
|             state: 0x2, | ||||
|             last_state: 0x2, | ||||
|             last_state: 0x3, | ||||
|         }, | ||||
|         SimTrace { | ||||
|             id: TraceScalarId(10), | ||||
|  | @ -986,11 +1035,19 @@ fn test_mod1() { | |||
|                 ty: UInt<4>, | ||||
|             }, | ||||
|             state: 0xf, | ||||
|             last_state: 0xf, | ||||
|             last_state: 0xe, | ||||
|         }, | ||||
|     ], | ||||
|     trace_writers: [], | ||||
|     instant: 0 s, | ||||
|     trace_writers: [ | ||||
|         Running( | ||||
|             VcdWriter { | ||||
|                 finished_init: true, | ||||
|                 timescale: 1 ps, | ||||
|                 .. | ||||
|             }, | ||||
|         ), | ||||
|     ], | ||||
|     instant: 2 μs, | ||||
| }"# {
 | ||||
|         panic!(); | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue