mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Added support for initialized brams
This commit is contained in:
		
							parent
							
								
									d19866615b
								
							
						
					
					
						commit
						169d1c4711
					
				
					 2 changed files with 45 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -474,7 +474,16 @@ struct RTLIL::Const
 | 
			
		|||
	std::string decode_string() const;
 | 
			
		||||
 | 
			
		||||
	inline int size() const { return bits.size(); }
 | 
			
		||||
	inline RTLIL::State operator[](int index) { return bits.at(index); }
 | 
			
		||||
	inline RTLIL::State &operator[](int index) { return bits.at(index); }
 | 
			
		||||
	inline const RTLIL::State &operator[](int index) const { return bits.at(index); };
 | 
			
		||||
 | 
			
		||||
	inline RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const {
 | 
			
		||||
		RTLIL::Const ret;
 | 
			
		||||
		ret.bits.reserve(len);
 | 
			
		||||
		for (int i = offset; i < offset + len; i++)
 | 
			
		||||
			ret.bits.push_back(i < GetSize(bits) ? bits[i] : padding);
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline unsigned int hash() const {
 | 
			
		||||
		unsigned int h = mkhash_init;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -393,6 +393,16 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram,
 | 
			
		|||
	int mem_width = cell->getParam("\\WIDTH").as_int();
 | 
			
		||||
	// int mem_offset = cell->getParam("\\OFFSET").as_int();
 | 
			
		||||
 | 
			
		||||
	bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();
 | 
			
		||||
	vector<Const> initdata;
 | 
			
		||||
 | 
			
		||||
	if (cell_init) {
 | 
			
		||||
		Const initparam = cell->getParam("\\INIT");
 | 
			
		||||
		initdata.reserve(mem_size);
 | 
			
		||||
		for (int i=0; i < mem_size; i++)
 | 
			
		||||
			initdata.push_back(initparam.extract(mem_width*i, mem_width, State::Sx));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int wr_ports = cell->getParam("\\WR_PORTS").as_int();
 | 
			
		||||
	auto wr_clken = SigSpec(cell->getParam("\\WR_CLK_ENABLE"));
 | 
			
		||||
	auto wr_clkpol = SigSpec(cell->getParam("\\WR_CLK_POLARITY"));
 | 
			
		||||
| 
						 | 
				
			
			@ -789,6 +799,22 @@ grow_read_ports:;
 | 
			
		|||
			for (auto &vp : variant_params)
 | 
			
		||||
				c->setParam(vp.first, vp.second);
 | 
			
		||||
 | 
			
		||||
			if (cell_init) {
 | 
			
		||||
				int init_offset = grid_a*(1 << bram.abits);
 | 
			
		||||
				int init_shift = grid_d*bram.dbits;
 | 
			
		||||
				int init_size = (1 << bram.abits);
 | 
			
		||||
				Const initparam(State::Sx, init_size*bram.dbits);
 | 
			
		||||
				for (int i = 0; i < init_size; i++) {
 | 
			
		||||
					State padding = State::Sx;
 | 
			
		||||
					for (int j = 0; j < bram.dbits; j++)
 | 
			
		||||
						if (init_offset+i < GetSize(initdata) && init_shift+j < GetSize(initdata[init_offset+i]))
 | 
			
		||||
							padding = initparam[i*bram.dbits+j] = initdata[init_offset+i][init_shift+j];
 | 
			
		||||
						else
 | 
			
		||||
							initparam[i*bram.dbits+j] = padding;
 | 
			
		||||
				}
 | 
			
		||||
				c->setParam("\\INIT", initparam);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto &pi : portinfos)
 | 
			
		||||
			{
 | 
			
		||||
				if (pi.dupidx != dupidx)
 | 
			
		||||
| 
						 | 
				
			
			@ -905,10 +931,7 @@ void handle_cell(Cell *cell, const rules_t &rules)
 | 
			
		|||
{
 | 
			
		||||
	log("Processing %s.%s:\n", log_id(cell->module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
	if (!SigSpec(cell->getParam("\\INIT")).is_fully_undef()) {
 | 
			
		||||
		log("  initialized memories are not supported yet.");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();
 | 
			
		||||
 | 
			
		||||
	dict<string, int> match_properties;
 | 
			
		||||
	match_properties["words"]  = cell->getParam("\\SIZE").as_int();
 | 
			
		||||
| 
						 | 
				
			
			@ -980,6 +1003,12 @@ void handle_cell(Cell *cell, const rules_t &rules)
 | 
			
		|||
			log("    Metrics for %s: awaste=%d dwaste=%d bwaste=%d waste=%d efficiency=%d\n",
 | 
			
		||||
					log_id(match.name), awaste, dwaste, bwaste, waste, efficiency);
 | 
			
		||||
 | 
			
		||||
			if (cell_init && bram.init == 0) {
 | 
			
		||||
				log("    Rule #%d for bram type %s (variant %d) rejected: cannot be initialized.\n",
 | 
			
		||||
						i+1, log_id(bram.name), bram.variant);
 | 
			
		||||
				goto next_match_rule;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto it : match.min_limits) {
 | 
			
		||||
				if (it.first == "waste" || it.first == "dups" || it.first == "acells" || it.first == "dcells" || it.first == "cells")
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -992,6 +1021,7 @@ void handle_cell(Cell *cell, const rules_t &rules)
 | 
			
		|||
						i+1, log_id(bram.name), bram.variant, it.first.c_str(), it.second);
 | 
			
		||||
				goto next_match_rule;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto it : match.max_limits) {
 | 
			
		||||
				if (it.first == "acells" || it.first == "dcells" || it.first == "cells")
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -1021,9 +1051,6 @@ void handle_cell(Cell *cell, const rules_t &rules)
 | 
			
		|||
				log("      Storing for later selection.\n");
 | 
			
		||||
				best_rule_cache[pair<int, int>(i, vi)] = std::tuple<int, int, int>(match_properties["efficiency"], -match_properties["cells"], -match_properties["acells"]);
 | 
			
		||||
 | 
			
		||||
				if (or_next_if_better)
 | 
			
		||||
					goto next_match_rule;
 | 
			
		||||
 | 
			
		||||
		next_match_rule:
 | 
			
		||||
				if (or_next_if_better || best_rule_cache.empty())
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -1075,7 +1102,7 @@ struct MemoryBramPass : public Pass {
 | 
			
		|||
		log("rules. A block ram description looks like this:\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    bram RAMB1024X32     # name of BRAM cell\n");
 | 
			
		||||
		// log("      init 1             # set to '1' if BRAM can be initialized\n");
 | 
			
		||||
		log("      init 1             # set to '1' if BRAM can be initialized\n");
 | 
			
		||||
		log("      abits 10           # number of address bits\n");
 | 
			
		||||
		log("      dbits 32           # number of data bits\n");
 | 
			
		||||
		log("      groups 2           # number of port groups\n");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue