mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Merge pull request #3289 from YosysHQ/micko/sim_improve
Simulation improvements
This commit is contained in:
		
						commit
						a511c27eb7
					
				
					 2 changed files with 74 additions and 29 deletions
				
			
		|  | @ -201,9 +201,10 @@ void FstData::reconstructAllAtTimes(std::vector<fstHandle> &signal, uint64_t sta | ||||||
| 	fstReaderSetUnlimitedTimeRange(ctx); | 	fstReaderSetUnlimitedTimeRange(ctx); | ||||||
| 	fstReaderSetFacProcessMaskAll(ctx); | 	fstReaderSetFacProcessMaskAll(ctx); | ||||||
| 	fstReaderIterBlocks2(ctx, reconstruct_clb_attimes, reconstruct_clb_varlen_attimes, this, nullptr); | 	fstReaderIterBlocks2(ctx, reconstruct_clb_attimes, reconstruct_clb_varlen_attimes, this, nullptr); | ||||||
|  | 	if (last_time!=end_time) { | ||||||
| 		past_data = last_data; | 		past_data = last_data; | ||||||
| 		callback(last_time); | 		callback(last_time); | ||||||
| 	if (last_time!=end_time) | 	} | ||||||
| 	callback(end_time); | 	callback(end_time); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -782,22 +782,21 @@ struct SimInstance | ||||||
| 	bool setInitState() | 	bool setInitState() | ||||||
| 	{ | 	{ | ||||||
| 		bool did_something = false; | 		bool did_something = false; | ||||||
|  | 		for(auto &item : fst_handles) { | ||||||
|  | 			if (item.second==0) continue; // Ignore signals not found
 | ||||||
|  | 			std::string v = shared->fst->valueOf(item.second); | ||||||
|  | 			did_something |= set_state(item.first, Const::from_string(v)); | ||||||
|  | 		} | ||||||
| 		for (auto &it : ff_database) | 		for (auto &it : ff_database) | ||||||
| 		{ | 		{ | ||||||
| 			ff_state_t &ff = it.second; | 			ff_state_t &ff = it.second; | ||||||
| 			SigSpec qsig = it.second.data.sig_q; | 			SigSpec dsig = it.second.data.sig_d; | ||||||
| 			if (qsig.is_wire()) { | 			Const value = get_state(dsig); | ||||||
| 				IdString name = qsig.as_wire()->name; | 			if (dsig.is_wire()) { | ||||||
| 				fstHandle id = shared->fst->getHandle(scope + "." + RTLIL::unescape_id(name)); | 				ff.past_d = value; | ||||||
| 				if (id==0 && name.isPublic()) |  | ||||||
| 					log_warning("Unable to find wire %s in input file.\n", (scope + "." + RTLIL::unescape_id(name)).c_str()); |  | ||||||
| 				if (id!=0) { |  | ||||||
| 					Const fst_val = Const::from_string(shared->fst->valueOf(id)); |  | ||||||
| 					ff.past_d = fst_val; |  | ||||||
| 				if (ff.data.has_aload) | 				if (ff.data.has_aload) | ||||||
| 						ff.past_ad = fst_val; | 					ff.past_ad = value; | ||||||
| 					did_something = set_state(qsig, fst_val); | 				did_something |= true; | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		for (auto child : children) | 		for (auto child : children) | ||||||
|  | @ -805,6 +804,31 @@ struct SimInstance | ||||||
| 		return did_something; | 		return did_something; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void addAdditionalInputs(std::map<Wire*,fstHandle> &inputs) | ||||||
|  | 	{ | ||||||
|  | 		for (auto cell : module->cells()) | ||||||
|  | 		{ | ||||||
|  | 			if (cell->type.in(ID($anyseq))) { | ||||||
|  | 				SigSpec sig_y = sigmap(cell->getPort(ID::Y)); | ||||||
|  | 				if (sig_y.is_wire()) { | ||||||
|  | 					bool found = false; | ||||||
|  | 					for(auto &item : fst_handles) { | ||||||
|  | 						if (item.second==0) continue; // Ignore signals not found
 | ||||||
|  | 						if (sig_y == sigmap(item.first)) { | ||||||
|  | 							inputs[sig_y.as_wire()] = item.second; | ||||||
|  | 							found = true; | ||||||
|  | 							break; | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					if (!found) | ||||||
|  | 						log_error("Unable to find required '%s' signal in file\n",(scope + "." + RTLIL::unescape_id(sig_y.as_wire()->name)).c_str()); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		for (auto child : children) | ||||||
|  | 			child.second->addAdditionalInputs(inputs); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	void setState(dict<int, std::pair<SigBit,bool>> bits, std::string values) | 	void setState(dict<int, std::pair<SigBit,bool>> bits, std::string values) | ||||||
| 	{ | 	{ | ||||||
| 		for(auto bit : bits) { | 		for(auto bit : bits) { | ||||||
|  | @ -1066,6 +1090,8 @@ struct SimWorker : SimShared | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		top->addAdditionalInputs(inputs); | ||||||
|  | 
 | ||||||
| 		uint64_t startCount = 0; | 		uint64_t startCount = 0; | ||||||
| 		uint64_t stopCount = 0; | 		uint64_t stopCount = 0; | ||||||
| 		if (start_time==0) { | 		if (start_time==0) { | ||||||
|  | @ -1313,8 +1339,10 @@ struct SimWorker : SimShared | ||||||
| 	void run_cosim_btor2_witness(Module *topmod) | 	void run_cosim_btor2_witness(Module *topmod) | ||||||
| 	{ | 	{ | ||||||
| 		log_assert(top == nullptr); | 		log_assert(top == nullptr); | ||||||
| 		if ((clock.size()+clockn.size())==0) | 		if (!multiclock && (clock.size()+clockn.size())==0) | ||||||
| 			log_error("Clock signal must be specified.\n"); | 			log_error("Clock signal must be specified.\n"); | ||||||
|  | 		if (multiclock && (clock.size()+clockn.size())>0) | ||||||
|  | 			log_error("For multiclock witness there should be no clock signal.\n"); | ||||||
| 		std::ifstream f; | 		std::ifstream f; | ||||||
| 		f.open(sim_filename.c_str()); | 		f.open(sim_filename.c_str()); | ||||||
| 		if (f.fail() || GetSize(sim_filename) == 0) | 		if (f.fail() || GetSize(sim_filename) == 0) | ||||||
|  | @ -1347,10 +1375,12 @@ struct SimWorker : SimShared | ||||||
| 					set_inports(clockn, State::S0); | 					set_inports(clockn, State::S0); | ||||||
| 					update(); | 					update(); | ||||||
| 					register_output_step(10*cycle+0); | 					register_output_step(10*cycle+0); | ||||||
|  | 					if (!multiclock) { | ||||||
| 						set_inports(clock, State::S0); | 						set_inports(clock, State::S0); | ||||||
| 						set_inports(clockn, State::S1); | 						set_inports(clockn, State::S1); | ||||||
| 						update(); | 						update(); | ||||||
| 						register_output_step(10*cycle+5); | 						register_output_step(10*cycle+5); | ||||||
|  | 					} | ||||||
| 					cycle++; | 					cycle++; | ||||||
| 					prev_cycle = curr_cycle; | 					prev_cycle = curr_cycle; | ||||||
| 				} | 				} | ||||||
|  | @ -1779,6 +1809,12 @@ struct AIWWriter : public OutputWriter | ||||||
| 				log_error("Index %d for wire %s is out of range\n", index, log_signal(w)); | 				log_error("Index %d for wire %s is out of range\n", index, log_signal(w)); | ||||||
| 			if (type == "input") { | 			if (type == "input") { | ||||||
| 				aiw_inputs[variable] = SigBit(w,index-w->start_offset); | 				aiw_inputs[variable] = SigBit(w,index-w->start_offset); | ||||||
|  | 				if (worker->clock.count(escaped_s)) { | ||||||
|  | 					clocks[variable] = true; | ||||||
|  | 				} | ||||||
|  | 				if (worker->clockn.count(escaped_s)) { | ||||||
|  | 					clocks[variable] = false; | ||||||
|  | 				} | ||||||
| 			} else if (type == "init") { | 			} else if (type == "init") { | ||||||
| 				aiw_inits[variable] = SigBit(w,index-w->start_offset); | 				aiw_inits[variable] = SigBit(w,index-w->start_offset); | ||||||
| 			} else if (type == "latch") { | 			} else if (type == "latch") { | ||||||
|  | @ -1796,8 +1832,9 @@ struct AIWWriter : public OutputWriter | ||||||
| 
 | 
 | ||||||
| 		std::map<int, Yosys::RTLIL::Const> current; | 		std::map<int, Yosys::RTLIL::Const> current; | ||||||
| 		bool first = true; | 		bool first = true; | ||||||
| 		for(auto& d : worker->output_data) | 		for (auto iter = worker->output_data.begin(); iter != std::prev(worker->output_data.end()); ++iter) | ||||||
| 		{ | 		{ | ||||||
|  | 			auto& d = *iter; | ||||||
| 			for (auto &data : d.second) | 			for (auto &data : d.second) | ||||||
| 			{ | 			{ | ||||||
| 				current[data.first] = data.second; | 				current[data.first] = data.second; | ||||||
|  | @ -1806,12 +1843,7 @@ struct AIWWriter : public OutputWriter | ||||||
| 				for (int i = 0;; i++) | 				for (int i = 0;; i++) | ||||||
| 				{ | 				{ | ||||||
| 					if (aiw_latches.count(i)) { | 					if (aiw_latches.count(i)) { | ||||||
| 						SigBit bit = aiw_latches.at(i).first; | 						aiwfile << '0'; | ||||||
| 						auto v = current[mapping[bit.wire]].bits.at(bit.offset); |  | ||||||
| 						if (v == State::S1) |  | ||||||
| 							aiwfile << (aiw_latches.at(i).second ? '0' : '1'); |  | ||||||
| 						else |  | ||||||
| 							aiwfile << (aiw_latches.at(i).second ? '1' : '0'); |  | ||||||
| 						continue; | 						continue; | ||||||
| 					} | 					} | ||||||
| 					aiwfile << '\n'; | 					aiwfile << '\n'; | ||||||
|  | @ -1820,6 +1852,17 @@ struct AIWWriter : public OutputWriter | ||||||
| 				first = false; | 				first = false; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			bool skip = false; | ||||||
|  | 			for (auto it : clocks) | ||||||
|  | 			{ | ||||||
|  | 				auto val = it.second ? State::S1 : State::S0; | ||||||
|  | 				SigBit bit = aiw_inputs.at(it.first); | ||||||
|  | 				auto v = current[mapping[bit.wire]].bits.at(bit.offset); | ||||||
|  | 				if (v == val) | ||||||
|  | 					skip = true; | ||||||
|  | 			} | ||||||
|  | 			if (skip) | ||||||
|  | 				continue; | ||||||
| 			for (int i = 0;; i++) | 			for (int i = 0;; i++) | ||||||
| 			{ | 			{ | ||||||
| 				if (aiw_inputs.count(i)) { | 				if (aiw_inputs.count(i)) { | ||||||
|  | @ -1849,6 +1892,7 @@ struct AIWWriter : public OutputWriter | ||||||
| 	std::ofstream aiwfile; | 	std::ofstream aiwfile; | ||||||
| 	dict<int, std::pair<SigBit, bool>> aiw_latches; | 	dict<int, std::pair<SigBit, bool>> aiw_latches; | ||||||
| 	dict<int, SigBit> aiw_inputs, aiw_inits; | 	dict<int, SigBit> aiw_inputs, aiw_inits; | ||||||
|  | 	dict<int, bool> clocks; | ||||||
| 	std::map<Wire*,int> mapping; | 	std::map<Wire*,int> mapping; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue