sim: fix "label address not set" bug when the last Assignment is conditional
This commit is contained in:
		
							parent
							
								
									404a2ee043
								
							
						
					
					
						commit
						d4ea826051
					
				
					 4 changed files with 242 additions and 0 deletions
				
			
		|  | @ -4773,6 +4773,9 @@ impl Compiler { | ||||||
|             } |             } | ||||||
|             self.insns.extend(insns.iter().copied(), *source_location); |             self.insns.extend(insns.iter().copied(), *source_location); | ||||||
|         } |         } | ||||||
|  |         for CondStackEntry { cond: _, end_label } in cond_stack { | ||||||
|  |             self.insns.define_label_at_next_insn(end_label); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     fn process_clocks(&mut self) -> Interned<[StatePartIndex<StatePartKindSmallSlots>]> { |     fn process_clocks(&mut self) -> Interned<[StatePartIndex<StatePartKindSmallSlots>]> { | ||||||
|         mem::take(&mut self.clock_triggers) |         mem::take(&mut self.clock_triggers) | ||||||
|  |  | ||||||
|  | @ -1407,3 +1407,39 @@ fn test_array_rw() { | ||||||
|         panic!(); |         panic!(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | #[hdl_module(outline_generated)] | ||||||
|  | pub fn conditional_assignment_last() { | ||||||
|  |     #[hdl] | ||||||
|  |     let i: Bool = m.input(); | ||||||
|  |     #[hdl] | ||||||
|  |     let w = wire(); | ||||||
|  |     connect(w, true); | ||||||
|  |     #[hdl] | ||||||
|  |     if i { | ||||||
|  |         connect(w, false); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn test_conditional_assignment_last() { | ||||||
|  |     let _n = SourceLocation::normalize_files_for_tests(); | ||||||
|  |     let mut sim = Simulation::new(conditional_assignment_last()); | ||||||
|  |     let mut writer = RcWriter::default(); | ||||||
|  |     sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); | ||||||
|  |     sim.write(sim.io().i, false); | ||||||
|  |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |     sim.write(sim.io().i, 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/conditional_assignment_last.vcd") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  |     let sim_debug = format!("{sim:#?}"); | ||||||
|  |     println!("#######\n{sim_debug}\n#######"); | ||||||
|  |     if sim_debug != include_str!("sim/expected/conditional_assignment_last.txt") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,189 @@ | ||||||
|  | Simulation { | ||||||
|  |     state: State { | ||||||
|  |         insns: Insns { | ||||||
|  |             state_layout: StateLayout { | ||||||
|  |                 ty: TypeLayout { | ||||||
|  |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|  |                         len: 0, | ||||||
|  |                         debug_data: [], | ||||||
|  |                         .. | ||||||
|  |                     }, | ||||||
|  |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|  |                         len: 4, | ||||||
|  |                         debug_data: [ | ||||||
|  |                             SlotDebugData { | ||||||
|  |                                 name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::i", | ||||||
|  |                                 ty: Bool, | ||||||
|  |                             }, | ||||||
|  |                             SlotDebugData { | ||||||
|  |                                 name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::w", | ||||||
|  |                                 ty: Bool, | ||||||
|  |                             }, | ||||||
|  |                             SlotDebugData { | ||||||
|  |                                 name: "", | ||||||
|  |                                 ty: Bool, | ||||||
|  |                             }, | ||||||
|  |                             SlotDebugData { | ||||||
|  |                                 name: "", | ||||||
|  |                                 ty: Bool, | ||||||
|  |                             }, | ||||||
|  |                         ], | ||||||
|  |                         .. | ||||||
|  |                     }, | ||||||
|  |                 }, | ||||||
|  |                 memories: StatePartLayout<Memories> { | ||||||
|  |                     len: 0, | ||||||
|  |                     debug_data: [], | ||||||
|  |                     layout_data: [], | ||||||
|  |                     .. | ||||||
|  |                 }, | ||||||
|  |             }, | ||||||
|  |             insns: [ | ||||||
|  |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|  |                 0: Const { | ||||||
|  |                     dest: StatePartIndex<BigSlots>(3), // (0x0) SlotDebugData { name: "", ty: Bool }, | ||||||
|  |                     value: 0x0, | ||||||
|  |                 }, | ||||||
|  |                 1: Const { | ||||||
|  |                     dest: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "", ty: Bool }, | ||||||
|  |                     value: 0x1, | ||||||
|  |                 }, | ||||||
|  |                 // at: module-XXXXXXXXXX.rs:4:1 | ||||||
|  |                 2: Copy { | ||||||
|  |                     dest: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::w", ty: Bool }, | ||||||
|  |                     src: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "", ty: Bool }, | ||||||
|  |                 }, | ||||||
|  |                 // at: module-XXXXXXXXXX.rs:5:1 | ||||||
|  |                 3: BranchIfZero { | ||||||
|  |                     target: 5, | ||||||
|  |                     value: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::i", ty: Bool }, | ||||||
|  |                 }, | ||||||
|  |                 // at: module-XXXXXXXXXX.rs:6:1 | ||||||
|  |                 4: Copy { | ||||||
|  |                     dest: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::w", ty: Bool }, | ||||||
|  |                     src: StatePartIndex<BigSlots>(3), // (0x0) SlotDebugData { name: "", ty: Bool }, | ||||||
|  |                 }, | ||||||
|  |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|  |                 5: Return, | ||||||
|  |             ], | ||||||
|  |             .. | ||||||
|  |         }, | ||||||
|  |         pc: 5, | ||||||
|  |         memory_write_log: [], | ||||||
|  |         memories: StatePart { | ||||||
|  |             value: [], | ||||||
|  |         }, | ||||||
|  |         small_slots: StatePart { | ||||||
|  |             value: [], | ||||||
|  |         }, | ||||||
|  |         big_slots: StatePart { | ||||||
|  |             value: [ | ||||||
|  |                 1, | ||||||
|  |                 0, | ||||||
|  |                 1, | ||||||
|  |                 0, | ||||||
|  |             ], | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  |     io: Instance { | ||||||
|  |         name: <simulator>::conditional_assignment_last, | ||||||
|  |         instantiated: Module { | ||||||
|  |             name: conditional_assignment_last, | ||||||
|  |             .. | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  |     uninitialized_inputs: {}, | ||||||
|  |     io_targets: { | ||||||
|  |         Instance { | ||||||
|  |             name: <simulator>::conditional_assignment_last, | ||||||
|  |             instantiated: Module { | ||||||
|  |                 name: conditional_assignment_last, | ||||||
|  |                 .. | ||||||
|  |             }, | ||||||
|  |         }.i: CompiledValue { | ||||||
|  |             layout: CompiledTypeLayout { | ||||||
|  |                 ty: Bool, | ||||||
|  |                 layout: TypeLayout { | ||||||
|  |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|  |                         len: 0, | ||||||
|  |                         debug_data: [], | ||||||
|  |                         .. | ||||||
|  |                     }, | ||||||
|  |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|  |                         len: 1, | ||||||
|  |                         debug_data: [ | ||||||
|  |                             SlotDebugData { | ||||||
|  |                                 name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::i", | ||||||
|  |                                 ty: Bool, | ||||||
|  |                             }, | ||||||
|  |                         ], | ||||||
|  |                         .. | ||||||
|  |                     }, | ||||||
|  |                 }, | ||||||
|  |                 body: Scalar, | ||||||
|  |             }, | ||||||
|  |             range: TypeIndexRange { | ||||||
|  |                 small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 }, | ||||||
|  |                 big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 }, | ||||||
|  |             }, | ||||||
|  |             write: None, | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  |     made_initial_step: true, | ||||||
|  |     needs_settle: false, | ||||||
|  |     trace_decls: TraceModule { | ||||||
|  |         name: "conditional_assignment_last", | ||||||
|  |         children: [ | ||||||
|  |             TraceModuleIO { | ||||||
|  |                 name: "i", | ||||||
|  |                 child: TraceBool { | ||||||
|  |                     location: TraceScalarId(0), | ||||||
|  |                     name: "i", | ||||||
|  |                     flow: Source, | ||||||
|  |                 }, | ||||||
|  |                 ty: Bool, | ||||||
|  |                 flow: Source, | ||||||
|  |             }, | ||||||
|  |             TraceWire { | ||||||
|  |                 name: "w", | ||||||
|  |                 child: TraceBool { | ||||||
|  |                     location: TraceScalarId(1), | ||||||
|  |                     name: "w", | ||||||
|  |                     flow: Duplex, | ||||||
|  |                 }, | ||||||
|  |                 ty: Bool, | ||||||
|  |             }, | ||||||
|  |         ], | ||||||
|  |     }, | ||||||
|  |     traces: [ | ||||||
|  |         SimTrace { | ||||||
|  |             id: TraceScalarId(0), | ||||||
|  |             kind: BigBool { | ||||||
|  |                 index: StatePartIndex<BigSlots>(0), | ||||||
|  |             }, | ||||||
|  |             state: 0x1, | ||||||
|  |             last_state: 0x0, | ||||||
|  |         }, | ||||||
|  |         SimTrace { | ||||||
|  |             id: TraceScalarId(1), | ||||||
|  |             kind: BigBool { | ||||||
|  |                 index: StatePartIndex<BigSlots>(1), | ||||||
|  |             }, | ||||||
|  |             state: 0x0, | ||||||
|  |             last_state: 0x1, | ||||||
|  |         }, | ||||||
|  |     ], | ||||||
|  |     trace_memories: {}, | ||||||
|  |     trace_writers: [ | ||||||
|  |         Running( | ||||||
|  |             VcdWriter { | ||||||
|  |                 finished_init: true, | ||||||
|  |                 timescale: 1 ps, | ||||||
|  |                 .. | ||||||
|  |             }, | ||||||
|  |         ), | ||||||
|  |     ], | ||||||
|  |     instant: 2 μs, | ||||||
|  |     clocks_triggered: [], | ||||||
|  |     .. | ||||||
|  | } | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | $timescale 1 ps $end | ||||||
|  | $scope module conditional_assignment_last $end | ||||||
|  | $var wire 1 ! i $end | ||||||
|  | $var wire 1 " w $end | ||||||
|  | $upscope $end | ||||||
|  | $enddefinitions $end | ||||||
|  | $dumpvars | ||||||
|  | 0! | ||||||
|  | 1" | ||||||
|  | $end | ||||||
|  | #1000000 | ||||||
|  | 1! | ||||||
|  | 0" | ||||||
|  | #2000000 | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue