mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	sim: Bring $print trigger/sampling semantics in line with FFs
This commit is contained in:
		
							parent
							
								
									80511ced71
								
							
						
					
					
						commit
						7c818d30f7
					
				
					 1 changed files with 35 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -813,7 +813,7 @@ struct SimInstance
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void update_ph3(bool check_assertions)
 | 
			
		||||
	void update_ph3(bool gclk_trigger)
 | 
			
		||||
	{
 | 
			
		||||
		for (auto &it : ff_database)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -858,49 +858,53 @@ struct SimInstance
 | 
			
		|||
			Const en = get_state(cell->getPort(ID::EN));
 | 
			
		||||
			Const args = get_state(cell->getPort(ID::ARGS));
 | 
			
		||||
 | 
			
		||||
			if (!en.as_bool())
 | 
			
		||||
				goto update_print;
 | 
			
		||||
			bool sampled = trg_en && trg.size() > 0;
 | 
			
		||||
 | 
			
		||||
			if (trg.size() > 0 && trg_en) {
 | 
			
		||||
				Const trg_pol = cell->getParam(ID::TRG_POLARITY);
 | 
			
		||||
				for (int i = 0; i < trg.size(); i++) {
 | 
			
		||||
					bool pol = trg_pol[i] == State::S1;
 | 
			
		||||
					State curr = trg[i], past = print.past_trg[i];
 | 
			
		||||
					if (pol && curr == State::S1 && past == State::S0)
 | 
			
		||||
			if (sampled ? print.past_en.as_bool() : en.as_bool()) {
 | 
			
		||||
				if (sampled) {
 | 
			
		||||
					sampled = true;
 | 
			
		||||
					Const trg_pol = cell->getParam(ID::TRG_POLARITY);
 | 
			
		||||
					for (int i = 0; i < trg.size(); i++) {
 | 
			
		||||
						bool pol = trg_pol[i] == State::S1;
 | 
			
		||||
						State curr = trg[i], past = print.past_trg[i];
 | 
			
		||||
						if (pol && curr == State::S1 && past == State::S0)
 | 
			
		||||
							triggered = true;
 | 
			
		||||
						if (!pol && curr == State::S0 && past == State::S1)
 | 
			
		||||
							triggered = true;
 | 
			
		||||
					}
 | 
			
		||||
				} else if (trg_en) {
 | 
			
		||||
					// initial $print (TRG width = 0, TRG_ENABLE = true)
 | 
			
		||||
					if (!print.initial_done && en != print.past_en)
 | 
			
		||||
						triggered = true;
 | 
			
		||||
					if (!pol && curr == State::S0 && past == State::S1)
 | 
			
		||||
				} else if (cell->get_bool_attribute(ID(trg_on_gclk))) {
 | 
			
		||||
					// unified $print for cycle based FV semantics
 | 
			
		||||
					triggered = gclk_trigger;
 | 
			
		||||
				} else {
 | 
			
		||||
					// always @(*) $print
 | 
			
		||||
					if (args != print.past_args || en != print.past_en)
 | 
			
		||||
						triggered = true;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (trg_en) {
 | 
			
		||||
				// initial $print (TRG width = 0, TRG_ENABLE = true)
 | 
			
		||||
				if (!print.initial_done && en != print.past_en)
 | 
			
		||||
					triggered = true;
 | 
			
		||||
			} else {
 | 
			
		||||
				// always @(*) $print
 | 
			
		||||
				if (args != print.past_args || en != print.past_en)
 | 
			
		||||
					triggered = true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (triggered) {
 | 
			
		||||
				int pos = 0;
 | 
			
		||||
				for (auto &part : print.fmt.parts) {
 | 
			
		||||
					part.sig = args.extract(pos, part.sig.size());
 | 
			
		||||
					pos += part.sig.size();
 | 
			
		||||
				if (triggered) {
 | 
			
		||||
					int pos = 0;
 | 
			
		||||
					for (auto &part : print.fmt.parts) {
 | 
			
		||||
						part.sig = (sampled ? print.past_args : args).extract(pos, part.sig.size());
 | 
			
		||||
						pos += part.sig.size();
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					std::string rendered = print.fmt.render();
 | 
			
		||||
					log("%s", rendered.c_str());
 | 
			
		||||
					shared->display_output.emplace_back(shared->step, this, cell, rendered);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				std::string rendered = print.fmt.render();
 | 
			
		||||
				log("%s", rendered.c_str());
 | 
			
		||||
				shared->display_output.emplace_back(shared->step, this, cell, rendered);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		update_print:
 | 
			
		||||
			print.past_trg = trg;
 | 
			
		||||
			print.past_en = en;
 | 
			
		||||
			print.past_args = args;
 | 
			
		||||
			print.initial_done = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_assertions)
 | 
			
		||||
		if (gclk_trigger)
 | 
			
		||||
		{
 | 
			
		||||
			for (auto cell : formal_database)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -932,7 +936,7 @@ struct SimInstance
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto it : children)
 | 
			
		||||
			it.second->update_ph3(check_assertions);
 | 
			
		||||
			it.second->update_ph3(gclk_trigger);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void set_initstate_outputs(State state)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue