mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Improved attributes API and handling of "src" attributes
This commit is contained in:
		
							parent
							
								
									687f5a5b12
								
							
						
					
					
						commit
						49859393bb
					
				
					 7 changed files with 119 additions and 27 deletions
				
			
		
							
								
								
									
										5
									
								
								README
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								README
									
										
									
									
									
								
							|  | @ -300,6 +300,11 @@ Verilog Attributes and non-standard features | |||
|   with "-top". Other commands, such as "flatten" and various backends | ||||
|   use this attribute to determine the top module. | ||||
| 
 | ||||
| - The "src" attribute is set on cells and wires created by to the string | ||||
|   "<hdl-file-name>:<line-number>" by the HDL front-end and is then carried | ||||
|   through the synthesis. When entities are combined, a new |-separated | ||||
|   string is created that contains all the string from the original entities. | ||||
| 
 | ||||
| - In addition to the (* ... *) attribute syntax, yosys supports | ||||
|   the non-standard {* ... *} attribute syntax to set default attributes | ||||
|   for everything that comes after the {* ... *} statement. (Reset | ||||
|  |  | |||
|  | @ -161,6 +161,46 @@ std::string RTLIL::Const::decode_string() const | |||
| 	return string; | ||||
| } | ||||
| 
 | ||||
| void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id) | ||||
| { | ||||
| 	attributes[id] = RTLIL::Const(1); | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const | ||||
| { | ||||
| 	if (attributes.count(id) == 0) | ||||
| 		return false; | ||||
| 	return attributes.at(id).as_bool(); | ||||
| } | ||||
| 
 | ||||
| void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool<string> &data) | ||||
| { | ||||
| 	string attrval; | ||||
| 	for (auto &s : data) { | ||||
| 		if (!attrval.empty()) | ||||
| 			attrval += "|"; | ||||
| 		attrval += s; | ||||
| 	} | ||||
| 	attributes[id] = RTLIL::Const(attrval); | ||||
| } | ||||
| 
 | ||||
| void RTLIL::AttrObject::add_strpool_attribute(RTLIL::IdString id, const pool<string> &data) | ||||
| { | ||||
| 	pool<string> union_data = get_strpool_attribute(id); | ||||
| 	union_data.insert(data.begin(), data.end()); | ||||
| 	if (!union_data.empty()) | ||||
| 		set_strpool_attribute(id, union_data); | ||||
| } | ||||
| 
 | ||||
| pool<string> RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const | ||||
| { | ||||
| 	pool<string> data; | ||||
| 	if (attributes.count(id) != 0) | ||||
| 		for (auto s : split_tokens(attributes.at(id).decode_string(), "|")) | ||||
| 			data.insert(s); | ||||
| 	return data; | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const | ||||
| { | ||||
| 	if (full_selection) | ||||
|  |  | |||
|  | @ -53,6 +53,7 @@ namespace RTLIL | |||
| 	}; | ||||
| 
 | ||||
| 	struct Const; | ||||
| 	struct AttrObject; | ||||
| 	struct Selection; | ||||
| 	struct Monitor; | ||||
| 	struct Design; | ||||
|  | @ -493,6 +494,17 @@ struct RTLIL::Const | |||
| 	} | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::AttrObject | ||||
| { | ||||
| 	dict<RTLIL::IdString, RTLIL::Const> attributes; | ||||
| 
 | ||||
| 	void set_bool_attribute(RTLIL::IdString id); | ||||
| 	bool get_bool_attribute(RTLIL::IdString id) const; | ||||
| 	void set_strpool_attribute(RTLIL::IdString id, const pool<string> &data); | ||||
| 	void add_strpool_attribute(RTLIL::IdString id, const pool<string> &data); | ||||
| 	pool<string> get_strpool_attribute(RTLIL::IdString id) const; | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::SigChunk | ||||
| { | ||||
| 	RTLIL::Wire *wire; | ||||
|  | @ -849,18 +861,7 @@ struct RTLIL::Design | |||
| 	std::vector<RTLIL::Module*> selected_whole_modules_warn() const; | ||||
| }; | ||||
| 
 | ||||
| #define RTLIL_ATTRIBUTE_MEMBERS                                \ | ||||
| 	dict<RTLIL::IdString, RTLIL::Const> attributes;    \ | ||||
| 	void set_bool_attribute(RTLIL::IdString id) {          \ | ||||
| 		attributes[id] = RTLIL::Const(1);              \ | ||||
| 	}                                                      \ | ||||
| 	bool get_bool_attribute(RTLIL::IdString id) const {    \ | ||||
| 		if (attributes.count(id) == 0)                 \ | ||||
| 			return false;                          \ | ||||
| 		return attributes.at(id).as_bool();            \ | ||||
| 	} | ||||
| 
 | ||||
| struct RTLIL::Module | ||||
| struct RTLIL::Module : public RTLIL::AttrObject | ||||
| { | ||||
| 	unsigned int hashidx_; | ||||
| 	unsigned int hash() const { return hashidx_; } | ||||
|  | @ -884,7 +885,6 @@ public: | |||
| 	pool<RTLIL::IdString> avail_parameters; | ||||
| 	dict<RTLIL::IdString, RTLIL::Memory*> memories; | ||||
| 	dict<RTLIL::IdString, RTLIL::Process*> processes; | ||||
| 	RTLIL_ATTRIBUTE_MEMBERS | ||||
| 
 | ||||
| 	Module(); | ||||
| 	virtual ~Module(); | ||||
|  | @ -1095,7 +1095,7 @@ public: | |||
| 	RTLIL::SigBit Oai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d); | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Wire | ||||
| struct RTLIL::Wire : public RTLIL::AttrObject | ||||
| { | ||||
| 	unsigned int hashidx_; | ||||
| 	unsigned int hash() const { return hashidx_; } | ||||
|  | @ -1115,10 +1115,9 @@ public: | |||
| 	RTLIL::IdString name; | ||||
| 	int width, start_offset, port_id; | ||||
| 	bool port_input, port_output, upto; | ||||
| 	RTLIL_ATTRIBUTE_MEMBERS | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Memory | ||||
| struct RTLIL::Memory : public RTLIL::AttrObject | ||||
| { | ||||
| 	unsigned int hashidx_; | ||||
| 	unsigned int hash() const { return hashidx_; } | ||||
|  | @ -1127,10 +1126,9 @@ struct RTLIL::Memory | |||
| 
 | ||||
| 	RTLIL::IdString name; | ||||
| 	int width, start_offset, size; | ||||
| 	RTLIL_ATTRIBUTE_MEMBERS | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Cell | ||||
| struct RTLIL::Cell : public RTLIL::AttrObject | ||||
| { | ||||
| 	unsigned int hashidx_; | ||||
| 	unsigned int hash() const { return hashidx_; } | ||||
|  | @ -1150,7 +1148,6 @@ public: | |||
| 	RTLIL::IdString type; | ||||
| 	dict<RTLIL::IdString, RTLIL::SigSpec> connections_; | ||||
| 	dict<RTLIL::IdString, RTLIL::Const> parameters; | ||||
| 	RTLIL_ATTRIBUTE_MEMBERS | ||||
| 
 | ||||
| 	// access cell ports
 | ||||
| 	bool hasPort(RTLIL::IdString portname) const; | ||||
|  | @ -1195,10 +1192,9 @@ struct RTLIL::CaseRule | |||
| 	RTLIL::CaseRule *clone() const; | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::SwitchRule | ||||
| struct RTLIL::SwitchRule : public RTLIL::AttrObject | ||||
| { | ||||
| 	RTLIL::SigSpec signal; | ||||
| 	RTLIL_ATTRIBUTE_MEMBERS | ||||
| 	std::vector<RTLIL::CaseRule*> cases; | ||||
| 
 | ||||
| 	~SwitchRule(); | ||||
|  | @ -1217,10 +1213,9 @@ struct RTLIL::SyncRule | |||
| 	RTLIL::SyncRule *clone() const; | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Process | ||||
| struct RTLIL::Process : public RTLIL::AttrObject | ||||
| { | ||||
| 	RTLIL::IdString name; | ||||
| 	RTLIL_ATTRIBUTE_MEMBERS | ||||
| 	RTLIL::CaseRule root_case; | ||||
| 	std::vector<RTLIL::SyncRule*> syncs; | ||||
| 
 | ||||
|  |  | |||
|  | @ -209,6 +209,26 @@ std::string next_token(std::string &text, const char *sep, bool long_strings) | |||
| 	return token; | ||||
| } | ||||
| 
 | ||||
| std::vector<std::string> split_tokens(const std::string &text, const char *sep) | ||||
| { | ||||
| 	std::vector<std::string> tokens; | ||||
| 	std::string current_token; | ||||
| 	for (char c : text) { | ||||
| 		if (strchr(sep, c)) { | ||||
| 			if (!current_token.empty()) { | ||||
| 				tokens.push_back(current_token); | ||||
| 				current_token.clear(); | ||||
| 			} | ||||
| 		} else | ||||
| 			current_token += c; | ||||
| 	} | ||||
| 	if (!current_token.empty()) { | ||||
| 		tokens.push_back(current_token); | ||||
| 		current_token.clear(); | ||||
| 	} | ||||
| 	return tokens; | ||||
| } | ||||
| 
 | ||||
| // this is very similar to fnmatch(). the exact rules used by this
 | ||||
| // function are:
 | ||||
| //
 | ||||
|  |  | |||
|  | @ -205,6 +205,7 @@ std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); | |||
| std::string vstringf(const char *fmt, va_list ap); | ||||
| int readsome(std::istream &f, char *s, int n); | ||||
| std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false); | ||||
| std::vector<std::string> split_tokens(const std::string &text, const char *sep = " \t\r\n"); | ||||
| bool patmatch(const char *pattern, const char *string); | ||||
| int run_command(const std::string &command, std::function<void(const std::string&)> process_line = std::function<void(const std::string&)>()); | ||||
| std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX"); | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < GetSize(sig_y); i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\A", sig_a[i]); | ||||
| 		gate->setPort("\\Y", sig_y[i]); | ||||
| 	} | ||||
|  | @ -65,6 +66,7 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 		for (int i = 0; i < GetSize(sig_y); i++) { | ||||
| 			RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); | ||||
| 			gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 			gate->setPort("\\A", sig_t[i]); | ||||
| 			gate->setPort("\\Y", sig_y[i]); | ||||
| 		} | ||||
|  | @ -81,6 +83,7 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < GetSize(sig_y); i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\A", sig_a[i]); | ||||
| 		gate->setPort("\\B", sig_b[i]); | ||||
| 		gate->setPort("\\Y", sig_y[i]); | ||||
|  | @ -131,6 +134,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 			} | ||||
| 
 | ||||
| 			RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); | ||||
| 			gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 			gate->setPort("\\A", sig_a[i]); | ||||
| 			gate->setPort("\\B", sig_a[i+1]); | ||||
| 			gate->setPort("\\Y", sig_t[i/2]); | ||||
|  | @ -143,6 +147,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 	if (cell->type == "$reduce_xnor") { | ||||
| 		RTLIL::SigSpec sig_t = module->addWire(NEW_ID); | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\A", sig_a); | ||||
| 		gate->setPort("\\Y", sig_t); | ||||
| 		last_output_cell = gate; | ||||
|  | @ -156,7 +161,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) | ||||
| static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell *cell) | ||||
| { | ||||
| 	while (sig.size() > 1) | ||||
| 	{ | ||||
|  | @ -170,6 +175,7 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) | |||
| 			} | ||||
| 
 | ||||
| 			RTLIL::Cell *gate = module->addCell(NEW_ID, "$_OR_"); | ||||
| 			gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 			gate->setPort("\\A", sig[i]); | ||||
| 			gate->setPort("\\B", sig[i+1]); | ||||
| 			gate->setPort("\\Y", sig_t[i/2]); | ||||
|  | @ -185,7 +191,7 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) | |||
| void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) | ||||
| { | ||||
| 	RTLIL::SigSpec sig_a = cell->getPort("\\A"); | ||||
| 	logic_reduce(module, sig_a); | ||||
| 	logic_reduce(module, sig_a, cell); | ||||
| 
 | ||||
| 	RTLIL::SigSpec sig_y = cell->getPort("\\Y"); | ||||
| 
 | ||||
|  | @ -198,6 +204,7 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 	} | ||||
| 
 | ||||
| 	RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); | ||||
| 	gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 	gate->setPort("\\A", sig_a); | ||||
| 	gate->setPort("\\Y", sig_y); | ||||
| } | ||||
|  | @ -205,10 +212,10 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) | ||||
| { | ||||
| 	RTLIL::SigSpec sig_a = cell->getPort("\\A"); | ||||
| 	logic_reduce(module, sig_a); | ||||
| 	logic_reduce(module, sig_a, cell); | ||||
| 
 | ||||
| 	RTLIL::SigSpec sig_b = cell->getPort("\\B"); | ||||
| 	logic_reduce(module, sig_b); | ||||
| 	logic_reduce(module, sig_b, cell); | ||||
| 
 | ||||
| 	RTLIL::SigSpec sig_y = cell->getPort("\\Y"); | ||||
| 
 | ||||
|  | @ -226,6 +233,7 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 	log_assert(!gate_type.empty()); | ||||
| 
 | ||||
| 	RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); | ||||
| 	gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 	gate->setPort("\\A", sig_a); | ||||
| 	gate->setPort("\\B", sig_b); | ||||
| 	gate->setPort("\\Y", sig_y); | ||||
|  | @ -241,16 +249,19 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	RTLIL::SigSpec xor_out = module->addWire(NEW_ID, std::max(GetSize(sig_a), GetSize(sig_b))); | ||||
| 	RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed); | ||||
| 	xor_cell->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 	simplemap_bitop(module, xor_cell); | ||||
| 	module->remove(xor_cell); | ||||
| 
 | ||||
| 	RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID); | ||||
| 	RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out); | ||||
| 	reduce_cell->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 	simplemap_reduce(module, reduce_cell); | ||||
| 	module->remove(reduce_cell); | ||||
| 
 | ||||
| 	if (!is_ne) { | ||||
| 		RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID, reduce_out, sig_y); | ||||
| 		not_cell->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		simplemap_lognot(module, not_cell); | ||||
| 		module->remove(not_cell); | ||||
| 	} | ||||
|  | @ -264,6 +275,7 @@ void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < GetSize(sig_y); i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, "$_MUX_"); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\A", sig_a[i]); | ||||
| 		gate->setPort("\\B", sig_b[i]); | ||||
| 		gate->setPort("\\S", cell->getPort("\\S")); | ||||
|  | @ -301,6 +313,7 @@ void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < width; i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\S", sig_s[i]); | ||||
| 		gate->setPort("\\R", sig_r[i]); | ||||
| 		gate->setPort("\\Q", sig_q[i]); | ||||
|  | @ -320,6 +333,7 @@ void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < width; i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\C", sig_clk); | ||||
| 		gate->setPort("\\D", sig_d[i]); | ||||
| 		gate->setPort("\\Q", sig_q[i]); | ||||
|  | @ -341,6 +355,7 @@ void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < width; i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\C", sig_clk); | ||||
| 		gate->setPort("\\E", sig_en); | ||||
| 		gate->setPort("\\D", sig_d[i]); | ||||
|  | @ -365,6 +380,7 @@ void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < width; i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\C", sig_clk); | ||||
| 		gate->setPort("\\S", sig_s[i]); | ||||
| 		gate->setPort("\\R", sig_r[i]); | ||||
|  | @ -393,6 +409,7 @@ void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < width; i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\C", sig_clk); | ||||
| 		gate->setPort("\\R", sig_rst); | ||||
| 		gate->setPort("\\D", sig_d[i]); | ||||
|  | @ -413,6 +430,7 @@ void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < width; i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); | ||||
| 		gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); | ||||
| 		gate->setPort("\\E", sig_en); | ||||
| 		gate->setPort("\\D", sig_d[i]); | ||||
| 		gate->setPort("\\Q", sig_q[i]); | ||||
|  |  | |||
|  | @ -170,7 +170,10 @@ struct TechmapWorker | |||
| 		} | ||||
| 
 | ||||
| 		std::string orig_cell_name; | ||||
| 		pool<string> extra_src_attrs; | ||||
| 
 | ||||
| 		if (!flatten_mode) | ||||
| 		{ | ||||
| 			for (auto &it : tpl->cells_) | ||||
| 				if (it.first == "\\_TECHMAP_REPLACE_") { | ||||
| 					orig_cell_name = cell->name.str(); | ||||
|  | @ -178,6 +181,9 @@ struct TechmapWorker | |||
| 					break; | ||||
| 				} | ||||
| 
 | ||||
| 			extra_src_attrs = cell->get_strpool_attribute("\\src"); | ||||
| 		} | ||||
| 
 | ||||
| 		dict<IdString, IdString> memory_renames; | ||||
| 
 | ||||
| 		for (auto &it : tpl->memories) { | ||||
|  | @ -189,6 +195,8 @@ struct TechmapWorker | |||
| 			m->start_offset = it.second->start_offset; | ||||
| 			m->size = it.second->size; | ||||
| 			m->attributes = it.second->attributes; | ||||
| 			if (m->attributes.count("\\src")) | ||||
| 				m->add_strpool_attribute("\\src", extra_src_attrs); | ||||
| 			module->memories[m->name] = m; | ||||
| 			memory_renames[it.first] = m->name; | ||||
| 			design->select(module, m); | ||||
|  | @ -207,6 +215,8 @@ struct TechmapWorker | |||
| 			w->port_id = 0; | ||||
| 			if (it.second->get_bool_attribute("\\_techmap_special_")) | ||||
| 				w->attributes.clear(); | ||||
| 			if (w->attributes.count("\\src")) | ||||
| 				w->add_strpool_attribute("\\src", extra_src_attrs); | ||||
| 			design->select(module, w); | ||||
| 		} | ||||
| 
 | ||||
|  | @ -281,6 +291,9 @@ struct TechmapWorker | |||
| 				log_assert(memory_renames.count(memid)); | ||||
| 				c->setParam("\\MEMID", Const(memory_renames[memid].str())); | ||||
| 			} | ||||
| 
 | ||||
| 			if (c->attributes.count("\\src")) | ||||
| 				c->add_strpool_attribute("\\src", extra_src_attrs); | ||||
| 		} | ||||
| 
 | ||||
| 		for (auto &it : tpl->connections()) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue