mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Refactor sim output writers
This commit is contained in:
		
							parent
							
								
									dfd4c81eac
								
							
						
					
					
						commit
						94505395a9
					
				
					 1 changed files with 257 additions and 213 deletions
				
			
		|  | @ -65,6 +65,20 @@ static double stringToTime(std::string str) | |||
| 	return value * pow(10.0, g_units.at(endptr)); | ||||
| } | ||||
| 
 | ||||
| struct SimWorker; | ||||
| struct OutputWriter | ||||
| { | ||||
| 	OutputWriter(SimWorker *w) { worker = w;}; | ||||
| 	virtual ~OutputWriter() {}; | ||||
| 	virtual void write_header() = 0; | ||||
| 	virtual void write_step_header(int t) = 0; | ||||
| 	virtual void enter_scope(IdString name) = 0; | ||||
| 	virtual void exit_scope() = 0; | ||||
| 	virtual void register_signal(Wire *wire, int id) = 0; | ||||
| 	virtual void write_value(int id, Const& value) = 0; | ||||
| 	SimWorker *worker; | ||||
| }; | ||||
| 
 | ||||
| struct SimShared | ||||
| { | ||||
| 	bool debug = false; | ||||
|  | @ -77,6 +91,7 @@ struct SimShared | |||
| 	double stop_time = -1; | ||||
| 	SimulationMode sim_mode = SimulationMode::sim; | ||||
| 	bool cycles_set = false; | ||||
| 	std::vector<std::unique_ptr<OutputWriter>> outputfiles; | ||||
| }; | ||||
| 
 | ||||
| void zinit(State &v) | ||||
|  | @ -140,8 +155,7 @@ struct SimInstance | |||
| 
 | ||||
| 	std::vector<Mem> memories; | ||||
| 
 | ||||
| 	dict<Wire*, pair<int, Const>> vcd_database; | ||||
| 	dict<Wire*, pair<fstHandle, Const>> fst_database; | ||||
| 	dict<Wire*, pair<int, Const>> signal_database; | ||||
| 	dict<Wire*, fstHandle> fst_handles; | ||||
| 
 | ||||
| 	SimInstance(SimShared *shared, std::string scope, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) : | ||||
|  | @ -685,28 +699,29 @@ struct SimInstance | |||
| 			it.second->writeback(wbmods); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_vcd_header(std::ofstream &f, int &id) | ||||
| 	void write_output_header(OutputWriter *writer, int &id) | ||||
| 	{ | ||||
| 		f << stringf("$scope module %s $end\n", log_id(name())); | ||||
| 		writer->enter_scope(name()); | ||||
| 
 | ||||
| 		for (auto wire : module->wires()) | ||||
| 		{ | ||||
| 			if (shared->hide_internal && wire->name[0] == '$') | ||||
| 				continue; | ||||
| 
 | ||||
| 			f << stringf("$var wire %d n%d %s%s $end\n", GetSize(wire), id, wire->name[0] == '$' ? "\\" : "", log_id(wire)); | ||||
| 			vcd_database[wire] = make_pair(id++, Const()); | ||||
| 			signal_database[wire] = make_pair(id, Const()); | ||||
| 			writer->register_signal(wire, id); | ||||
| 			id++; | ||||
| 		} | ||||
| 
 | ||||
| 		for (auto child : children) | ||||
| 			child.second->write_vcd_header(f, id); | ||||
| 			child.second->write_output_header(writer, id); | ||||
| 
 | ||||
| 		f << stringf("$upscope $end\n"); | ||||
| 		writer->exit_scope(); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_vcd_step(std::ofstream &f) | ||||
| 	void write_output_step_values() | ||||
| 	{ | ||||
| 		for (auto &it : vcd_database) | ||||
| 		for (auto &it : signal_database) | ||||
| 		{ | ||||
| 			Wire *wire = it.first; | ||||
| 			Const value = get_state(wire); | ||||
|  | @ -717,68 +732,12 @@ struct SimInstance | |||
| 
 | ||||
| 			it.second.second = value; | ||||
| 
 | ||||
| 			f << "b"; | ||||
| 			for (int i = GetSize(value)-1; i >= 0; i--) { | ||||
| 				switch (value[i]) { | ||||
| 					case State::S0: f << "0"; break; | ||||
| 					case State::S1: f << "1"; break; | ||||
| 					case State::Sx: f << "x"; break; | ||||
| 					default: f << "z"; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			f << stringf(" n%d\n", id); | ||||
| 			for(auto& writer : shared->outputfiles) | ||||
| 				writer->write_value(id, value); | ||||
| 		} | ||||
| 
 | ||||
| 		for (auto child : children) | ||||
| 			child.second->write_vcd_step(f); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_fst_header(struct fstContext *f) | ||||
| 	{ | ||||
| 		fstWriterSetScope(f, FST_ST_VCD_MODULE, stringf("%s",log_id(name())).c_str(), nullptr); | ||||
| 		for (auto wire : module->wires()) | ||||
| 		{ | ||||
| 			if (shared->hide_internal && wire->name[0] == '$') | ||||
| 				continue; | ||||
| 
 | ||||
| 			fstHandle id = fstWriterCreateVar(f, FST_VT_VCD_WIRE, FST_VD_IMPLICIT, GetSize(wire), | ||||
| 												stringf("%s%s", wire->name[0] == '$' ? "\\" : "", log_id(wire)).c_str(), 0); | ||||
| 			fst_database[wire] = make_pair(id, Const()); | ||||
| 		} | ||||
| 
 | ||||
| 		for (auto child : children) | ||||
| 			child.second->write_fst_header(f); | ||||
| 
 | ||||
| 		fstWriterSetUpscope(f); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_fst_step(struct fstContext *f) | ||||
| 	{ | ||||
| 		for (auto &it : fst_database) | ||||
| 		{ | ||||
| 			Wire *wire = it.first; | ||||
| 			Const value = get_state(wire); | ||||
| 			fstHandle id = it.second.first; | ||||
| 
 | ||||
| 			if (it.second.second == value) | ||||
| 				continue; | ||||
| 
 | ||||
| 			it.second.second = value; | ||||
| 			std::stringstream ss; | ||||
| 			for (int i = GetSize(value)-1; i >= 0; i--) { | ||||
| 				switch (value[i]) { | ||||
| 					case State::S0: ss << "0"; break; | ||||
| 					case State::S1: ss << "1"; break; | ||||
| 					case State::Sx: ss << "x"; break; | ||||
| 					default: ss << "z"; | ||||
| 				} | ||||
| 			} | ||||
| 			fstWriterEmitValueChange(f, id, ss.str().c_str()); | ||||
| 		} | ||||
| 
 | ||||
| 		for (auto child : children) | ||||
| 			child.second->write_fst_step(f); | ||||
| 			child.second->write_output_step_values(); | ||||
| 	} | ||||
| 
 | ||||
| 	void setInitState() | ||||
|  | @ -857,11 +816,7 @@ struct SimInstance | |||
| struct SimWorker : SimShared | ||||
| { | ||||
| 	SimInstance *top = nullptr; | ||||
| 	std::ofstream vcdfile, aiwfile; | ||||
| 	struct fstContext *fstfile = nullptr; | ||||
| 	pool<IdString> clock, clockn, reset, resetn; | ||||
| 	dict<int, std::pair<SigBit, bool>> aiw_latches; | ||||
| 	dict<int, SigBit> aiw_inputs, aiw_inits; | ||||
| 	std::string timescale; | ||||
| 	std::string sim_filename; | ||||
| 	std::string map_filename; | ||||
|  | @ -869,150 +824,24 @@ struct SimWorker : SimShared | |||
| 
 | ||||
| 	~SimWorker() | ||||
| 	{ | ||||
| 		outputfiles.clear(); | ||||
| 		delete top; | ||||
| 	} | ||||
| 
 | ||||
| 	void write_vcd_header() | ||||
| 	{ | ||||
| 		vcdfile << stringf("$version %s $end\n", yosys_version_str); | ||||
| 
 | ||||
| 		std::time_t t = std::time(nullptr); | ||||
| 		char mbstr[255]; | ||||
| 		if (std::strftime(mbstr, sizeof(mbstr), "%c", std::localtime(&t))) { | ||||
| 			vcdfile << stringf("$date ") << mbstr << stringf(" $end\n"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (!timescale.empty()) | ||||
| 			vcdfile << stringf("$timescale %s $end\n", timescale.c_str()); | ||||
| 
 | ||||
| 		int id = 1; | ||||
| 		top->write_vcd_header(vcdfile, id); | ||||
| 
 | ||||
| 		vcdfile << stringf("$enddefinitions $end\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_vcd_step(int t) | ||||
| 	{ | ||||
| 		vcdfile << stringf("#%d\n", t); | ||||
| 		top->write_vcd_step(vcdfile); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_fst_header() | ||||
| 	{ | ||||
| 		std::time_t t = std::time(nullptr); | ||||
| 		fstWriterSetDate(fstfile, asctime(std::localtime(&t))); | ||||
| 		fstWriterSetVersion(fstfile, yosys_version_str); | ||||
| 		if (!timescale.empty()) | ||||
| 			fstWriterSetTimescaleFromString(fstfile, timescale.c_str()); | ||||
| 
 | ||||
| 		fstWriterSetPackType(fstfile, FST_WR_PT_FASTLZ); | ||||
| 		fstWriterSetRepackOnClose(fstfile, 1); | ||||
| 	    | ||||
| 		top->write_fst_header(fstfile); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_fst_step(int t) | ||||
| 	{ | ||||
| 		fstWriterEmitTimeChange(fstfile, t); | ||||
| 
 | ||||
| 		top->write_fst_step(fstfile); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_aiw_header() | ||||
| 	{ | ||||
| 		std::ifstream mf(map_filename); | ||||
| 		std::string type, symbol; | ||||
| 		int variable, index; | ||||
| 		while (mf >> type >> variable >> index >> symbol) { | ||||
| 			RTLIL::IdString escaped_s = RTLIL::escape_id(symbol); | ||||
| 			Wire *w = top->module->wire(escaped_s); | ||||
| 			if (!w) | ||||
| 				log_error("Wire %s not present in module %s\n",log_signal(w),log_id(top->module)); | ||||
| 			if (index < w->start_offset || index > w->start_offset + w->width) | ||||
| 				log_error("Index %d for wire %s is out of range\n", index, log_signal(w)); | ||||
| 			if (type == "input") { | ||||
| 				aiw_inputs[variable] = SigBit(w,index); | ||||
| 			} else if (type == "init") { | ||||
| 				aiw_inits[variable] = SigBit(w,index); | ||||
| 			} else if (type == "latch") { | ||||
| 				aiw_latches[variable] = {SigBit(w,index), false}; | ||||
| 			} else if (type == "invlatch") { | ||||
| 				aiw_latches[variable] = {SigBit(w,index), true}; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		for (int i = 0;; i++) | ||||
| 		{ | ||||
| 			if (aiw_latches.count(i)) { | ||||
| 				auto v = top->get_state(aiw_latches.at(i).first); | ||||
| 				if (v == State::S1) | ||||
| 					aiwfile << (aiw_latches.at(i).second ? '0' : '1'); | ||||
| 				else | ||||
| 					aiwfile << (aiw_latches.at(i).second ? '1' : '0'); | ||||
| 				continue; | ||||
| 			} | ||||
| 			aiwfile << '\n'; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void write_aiw_step() | ||||
| 	{ | ||||
| 		for (int i = 0;; i++) | ||||
| 		{ | ||||
| 			if (aiw_inputs.count(i)) { | ||||
| 				auto v = top->get_state(aiw_inputs.at(i)); | ||||
| 				if (v == State::S1) | ||||
| 					aiwfile << '1'; | ||||
| 				else | ||||
| 					aiwfile << '0'; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (aiw_inits.count(i)) { | ||||
| 				auto v = top->get_state(aiw_inits.at(i)); | ||||
| 				if (v == State::S1) | ||||
| 					aiwfile << '1'; | ||||
| 				else | ||||
| 					aiwfile << '0'; | ||||
| 				continue; | ||||
| 			} | ||||
| 			aiwfile << '\n'; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void write_aiw_end() | ||||
| 	{ | ||||
| 		aiwfile << '.' << '\n'; | ||||
| 	} | ||||
| 
 | ||||
| 	void write_output_header() | ||||
| 	{ | ||||
| 		if (vcdfile.is_open()) | ||||
| 			write_vcd_header(); | ||||
| 		if (fstfile) | ||||
| 			write_fst_header(); | ||||
| 		if (aiwfile.is_open()) | ||||
| 			write_aiw_header(); | ||||
| 		for(auto& writer : outputfiles) | ||||
| 			writer->write_header(); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_output_step(int t) | ||||
| 	{ | ||||
| 		if (vcdfile.is_open()) | ||||
| 			write_vcd_step(t); | ||||
| 		if (fstfile) | ||||
| 			write_fst_step(t); | ||||
| 		if (aiwfile.is_open()) | ||||
| 			write_aiw_step(); | ||||
| 		for(auto& writer : outputfiles) | ||||
| 			writer->write_step_header(t); | ||||
| 
 | ||||
| 		top->write_output_step_values(); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_output_end() | ||||
| 	{ | ||||
| 		if (fstfile) | ||||
| 			fstWriterClose(fstfile); | ||||
| 		if (aiwfile.is_open()) | ||||
| 			write_aiw_end(); | ||||
| 	} | ||||
| 
 | ||||
| 	void update() | ||||
| 	{ | ||||
|  | @ -1101,8 +930,6 @@ struct SimWorker : SimShared | |||
| 
 | ||||
| 		write_output_step(10*numcycles + 2); | ||||
| 
 | ||||
| 		write_output_end(); | ||||
| 
 | ||||
| 		if (writeback) { | ||||
| 			pool<Module*> wbmods; | ||||
| 			top->writeback(wbmods); | ||||
|  | @ -1230,7 +1057,6 @@ struct SimWorker : SimShared | |||
| 		} catch(fst_end_of_data_exception) { | ||||
| 			// end of data detected
 | ||||
| 		} | ||||
| 		write_output_end(); | ||||
| 
 | ||||
| 		if (writeback) { | ||||
| 			pool<Module*> wbmods; | ||||
|  | @ -1327,10 +1153,228 @@ struct SimWorker : SimShared | |||
| 			} | ||||
| 		} | ||||
| 		write_output_step(10*cycle); | ||||
| 		write_output_end(); | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| struct VCDWriter : public OutputWriter | ||||
| { | ||||
| 	VCDWriter(SimWorker *worker, std::string filename) : OutputWriter(worker) { | ||||
| 		vcdfile.open(filename.c_str()); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_header() override | ||||
| 	{ | ||||
| 		if (!vcdfile.is_open()) return; | ||||
| 		vcdfile << stringf("$version %s $end\n", yosys_version_str); | ||||
| 
 | ||||
| 		std::time_t t = std::time(nullptr); | ||||
| 		char mbstr[255]; | ||||
| 		if (std::strftime(mbstr, sizeof(mbstr), "%c", std::localtime(&t))) { | ||||
| 			vcdfile << stringf("$date ") << mbstr << stringf(" $end\n"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (!worker->timescale.empty()) | ||||
| 			vcdfile << stringf("$timescale %s $end\n", worker->timescale.c_str()); | ||||
| 
 | ||||
| 		int id = 1; | ||||
| 		worker->top->write_output_header(this, id); | ||||
| 
 | ||||
| 		vcdfile << stringf("$enddefinitions $end\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_step_header(int t) override | ||||
| 	{ | ||||
| 		if (!vcdfile.is_open()) return; | ||||
| 		vcdfile << stringf("#%d\n", t); | ||||
| 	} | ||||
| 				 | ||||
| 	void enter_scope(IdString name) override | ||||
| 	{ | ||||
| 		vcdfile << stringf("$scope module %s $end\n", log_id(name)); | ||||
| 	} | ||||
| 	void exit_scope() override | ||||
| 	{ | ||||
| 		vcdfile << stringf("$upscope $end\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	void register_signal(Wire *wire, int id) override | ||||
| 	{ | ||||
| 		vcdfile << stringf("$var wire %d n%d %s%s $end\n", GetSize(wire), id, wire->name[0] == '$' ? "\\" : "", log_id(wire)); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_value(int id, Const& value) override | ||||
| 	{ | ||||
| 		if (!vcdfile.is_open()) return; | ||||
| 		vcdfile << "b"; | ||||
| 		for (int i = GetSize(value)-1; i >= 0; i--) { | ||||
| 			switch (value[i]) { | ||||
| 				case State::S0: vcdfile << "0"; break; | ||||
| 				case State::S1: vcdfile << "1"; break; | ||||
| 				case State::Sx: vcdfile << "x"; break; | ||||
| 				default: vcdfile << "z"; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		vcdfile << stringf(" n%d\n", id); | ||||
| 	} | ||||
| 
 | ||||
| 	std::ofstream vcdfile; | ||||
| }; | ||||
| 
 | ||||
| struct FSTWriter : public OutputWriter | ||||
| { | ||||
| 	FSTWriter(SimWorker *worker, std::string filename) : OutputWriter(worker) { | ||||
| 		fstfile = (struct fstContext *)fstWriterCreate(filename.c_str(),1); | ||||
| 	} | ||||
| 
 | ||||
| 	virtual ~FSTWriter() | ||||
| 	{ | ||||
| 		fstWriterClose(fstfile); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_header() override | ||||
| 	{ | ||||
| 		if (!fstfile) return; | ||||
| 		std::time_t t = std::time(nullptr); | ||||
| 		fstWriterSetDate(fstfile, asctime(std::localtime(&t))); | ||||
| 		fstWriterSetVersion(fstfile, yosys_version_str); | ||||
| 		if (!worker->timescale.empty()) | ||||
| 			fstWriterSetTimescaleFromString(fstfile, worker->timescale.c_str()); | ||||
| 
 | ||||
| 		fstWriterSetPackType(fstfile, FST_WR_PT_FASTLZ); | ||||
| 		fstWriterSetRepackOnClose(fstfile, 1); | ||||
| 	    | ||||
| 	   	int id = 1; | ||||
| 		worker->top->write_output_header(this, id); | ||||
| 	} | ||||
| 
 | ||||
| 	void write_step_header(int t) override | ||||
| 	{ | ||||
| 		if (!fstfile) return; | ||||
| 		fstWriterEmitTimeChange(fstfile, t); | ||||
| 	} | ||||
| 
 | ||||
| 	void enter_scope(IdString name) override | ||||
| 	{ | ||||
| 		fstWriterSetScope(fstfile, FST_ST_VCD_MODULE, stringf("%s",log_id(name)).c_str(), nullptr); | ||||
| 	} | ||||
| 
 | ||||
| 	void exit_scope() override | ||||
| 	{ | ||||
| 		fstWriterSetUpscope(fstfile); | ||||
| 	} | ||||
| 
 | ||||
| 	void register_signal(Wire *wire, int id) override | ||||
| 	{ | ||||
| 		fstHandle fst_id = fstWriterCreateVar(fstfile, FST_VT_VCD_WIRE, FST_VD_IMPLICIT, GetSize(wire), | ||||
| 												stringf("%s%s", wire->name[0] == '$' ? "\\" : "", log_id(wire)).c_str(), 0); | ||||
| 
 | ||||
| 		mapping.emplace(id, fst_id); | ||||
| 	} | ||||
| 	void write_value(int id, Const& value) override | ||||
| 	{ | ||||
| 		if (!fstfile) return; | ||||
| 		std::stringstream ss; | ||||
| 		for (int i = GetSize(value)-1; i >= 0; i--) { | ||||
| 			switch (value[i]) { | ||||
| 				case State::S0: ss << "0"; break; | ||||
| 				case State::S1: ss << "1"; break; | ||||
| 				case State::Sx: ss << "x"; break; | ||||
| 				default: ss << "z"; | ||||
| 			} | ||||
| 		} | ||||
| 		fstWriterEmitValueChange(fstfile, mapping[id], ss.str().c_str()); | ||||
| 	} | ||||
| 	struct fstContext *fstfile = nullptr; | ||||
| 	std::map<int,fstHandle> mapping; | ||||
| }; | ||||
| 
 | ||||
| struct AIWWriter : public OutputWriter | ||||
| { | ||||
| 	AIWWriter(SimWorker *worker, std::string filename) : OutputWriter(worker) { | ||||
| 		aiwfile.open(filename.c_str()); | ||||
| 	} | ||||
| 
 | ||||
| 	virtual ~AIWWriter() | ||||
| 	{ | ||||
| 		aiwfile << '.' << '\n'; | ||||
| 	} | ||||
| 
 | ||||
| 	void write_header() override | ||||
| 	{ | ||||
| 		if (!aiwfile.is_open()) return; | ||||
| 		std::ifstream mf(worker->map_filename); | ||||
| 		std::string type, symbol; | ||||
| 		int variable, index; | ||||
| 		while (mf >> type >> variable >> index >> symbol) { | ||||
| 			RTLIL::IdString escaped_s = RTLIL::escape_id(symbol); | ||||
| 			Wire *w = worker->top->module->wire(escaped_s); | ||||
| 			if (!w) | ||||
| 				log_error("Wire %s not present in module %s\n",log_signal(w),log_id(worker->top->module)); | ||||
| 			if (index < w->start_offset || index > w->start_offset + w->width) | ||||
| 				log_error("Index %d for wire %s is out of range\n", index, log_signal(w)); | ||||
| 			if (type == "input") { | ||||
| 				aiw_inputs[variable] = SigBit(w,index); | ||||
| 			} else if (type == "init") { | ||||
| 				aiw_inits[variable] = SigBit(w,index); | ||||
| 			} else if (type == "latch") { | ||||
| 				aiw_latches[variable] = {SigBit(w,index), false}; | ||||
| 			} else if (type == "invlatch") { | ||||
| 				aiw_latches[variable] = {SigBit(w,index), true}; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		for (int i = 0;; i++) | ||||
| 		{ | ||||
| 			if (aiw_latches.count(i)) { | ||||
| 				auto v = worker->top->get_state(aiw_latches.at(i).first); | ||||
| 				if (v == State::S1) | ||||
| 					aiwfile << (aiw_latches.at(i).second ? '0' : '1'); | ||||
| 				else | ||||
| 					aiwfile << (aiw_latches.at(i).second ? '1' : '0'); | ||||
| 				continue; | ||||
| 			} | ||||
| 			aiwfile << '\n'; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void write_step_header(int) override | ||||
| 	{ | ||||
| 		if (!aiwfile.is_open()) return; | ||||
| 		for (int i = 0;; i++) | ||||
| 		{ | ||||
| 			if (aiw_inputs.count(i)) { | ||||
| 				auto v = worker->top->get_state(aiw_inputs.at(i)); | ||||
| 				if (v == State::S1) | ||||
| 					aiwfile << '1'; | ||||
| 				else | ||||
| 					aiwfile << '0'; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (aiw_inits.count(i)) { | ||||
| 				auto v = worker->top->get_state(aiw_inits.at(i)); | ||||
| 				if (v == State::S1) | ||||
| 					aiwfile << '1'; | ||||
| 				else | ||||
| 					aiwfile << '0'; | ||||
| 				continue; | ||||
| 			} | ||||
| 			aiwfile << '\n'; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 				 | ||||
| 	void enter_scope(IdString) override {} | ||||
| 	void exit_scope() override {} | ||||
| 	void register_signal(Wire*, int) override {} | ||||
| 	void write_value(int , Const&  ) override {} | ||||
| 
 | ||||
| 	std::ofstream aiwfile; | ||||
| 	dict<int, std::pair<SigBit, bool>> aiw_latches; | ||||
| 	dict<int, SigBit> aiw_inputs, aiw_inits; | ||||
| }; | ||||
| 
 | ||||
| struct SimPass : public Pass { | ||||
| 	SimPass() : Pass("sim", "simulate the circuit") { } | ||||
| 	void help() override | ||||
|  | @ -1428,19 +1472,19 @@ struct SimPass : public Pass { | |||
| 			if (args[argidx] == "-vcd" && argidx+1 < args.size()) { | ||||
| 				std::string vcd_filename = args[++argidx]; | ||||
| 				rewrite_filename(vcd_filename); | ||||
| 				worker.vcdfile.open(vcd_filename.c_str()); | ||||
| 				worker.outputfiles.emplace_back(std::unique_ptr<VCDWriter>(new VCDWriter(&worker, vcd_filename.c_str()))); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-fst" && argidx+1 < args.size()) { | ||||
| 				std::string fst_filename = args[++argidx]; | ||||
| 				rewrite_filename(fst_filename); | ||||
| 				worker.fstfile = (struct fstContext *)fstWriterCreate(fst_filename.c_str(),1); | ||||
| 				worker.outputfiles.emplace_back(std::unique_ptr<FSTWriter>(new FSTWriter(&worker, fst_filename.c_str()))); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-aiw" && argidx+1 < args.size()) { | ||||
| 				std::string aiw_filename = args[++argidx]; | ||||
| 				rewrite_filename(aiw_filename); | ||||
| 				worker.aiwfile.open(aiw_filename.c_str()); | ||||
| 				worker.outputfiles.emplace_back(std::unique_ptr<AIWWriter>(new AIWWriter(&worker, aiw_filename.c_str()))); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-n" && argidx+1 < args.size()) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue