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); | ||||
|         } | ||||
|         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>]> { | ||||
|         mem::take(&mut self.clock_triggers) | ||||
|  |  | |||
|  | @ -1407,3 +1407,39 @@ fn test_array_rw() { | |||
|         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