mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Added $meminit support to "memory" command
This commit is contained in:
		
							parent
							
								
									913c304fe6
								
							
						
					
					
						commit
						dcf2e24240
					
				
					 7 changed files with 99 additions and 49 deletions
				
			
		|  | @ -917,6 +917,7 @@ namespace { | ||||||
| 				param("\\MEMID"); | 				param("\\MEMID"); | ||||||
| 				param("\\SIZE"); | 				param("\\SIZE"); | ||||||
| 				param("\\OFFSET"); | 				param("\\OFFSET"); | ||||||
|  | 				param("\\INIT"); | ||||||
| 				param_bits("\\RD_CLK_ENABLE", param("\\RD_PORTS")); | 				param_bits("\\RD_CLK_ENABLE", param("\\RD_PORTS")); | ||||||
| 				param_bits("\\RD_CLK_POLARITY", param("\\RD_PORTS")); | 				param_bits("\\RD_CLK_POLARITY", param("\\RD_PORTS")); | ||||||
| 				param_bits("\\RD_TRANSPARENT", param("\\RD_PORTS")); | 				param_bits("\\RD_TRANSPARENT", param("\\RD_PORTS")); | ||||||
|  |  | ||||||
|  | @ -905,6 +905,11 @@ void handle_cell(Cell *cell, const rules_t &rules) | ||||||
| { | { | ||||||
| 	log("Processing %s.%s:\n", log_id(cell->module), log_id(cell)); | 	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; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	dict<string, int> match_properties; | 	dict<string, int> match_properties; | ||||||
| 	match_properties["words"]  = cell->getParam("\\SIZE").as_int(); | 	match_properties["words"]  = cell->getParam("\\SIZE").as_int(); | ||||||
| 	match_properties["abits"]  = cell->getParam("\\ABITS").as_int(); | 	match_properties["abits"]  = cell->getParam("\\ABITS").as_int(); | ||||||
|  |  | ||||||
|  | @ -17,11 +17,8 @@ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include "kernel/register.h" | #include "kernel/yosys.h" | ||||||
| #include "kernel/log.h" | #include "kernel/sigtools.h" | ||||||
| #include <sstream> |  | ||||||
| #include <algorithm> |  | ||||||
| #include <stdlib.h> |  | ||||||
| 
 | 
 | ||||||
| USING_YOSYS_NAMESPACE | USING_YOSYS_NAMESPACE | ||||||
| PRIVATE_NAMESPACE_BEGIN | PRIVATE_NAMESPACE_BEGIN | ||||||
|  | @ -37,13 +34,16 @@ bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b) | ||||||
| 
 | 
 | ||||||
| void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | ||||||
| { | { | ||||||
| 	log("Collecting $memrd and $memwr for memory `%s' in module `%s':\n", | 	log("Collecting $memrd, $memwr and $meminit for memory `%s' in module `%s':\n", | ||||||
| 			memory->name.c_str(), module->name.c_str()); | 			memory->name.c_str(), module->name.c_str()); | ||||||
| 
 | 
 | ||||||
| 	int addr_bits = 0; | 	int addr_bits = 0; | ||||||
| 	while ((1 << addr_bits) < memory->size) | 	while ((1 << addr_bits) < memory->size) | ||||||
| 		addr_bits++; | 		addr_bits++; | ||||||
| 
 | 
 | ||||||
|  | 	Const init_data(State::Sx, memory->size * memory->width); | ||||||
|  | 	SigMap sigmap(module); | ||||||
|  | 
 | ||||||
| 	int wr_ports = 0; | 	int wr_ports = 0; | ||||||
| 	RTLIL::SigSpec sig_wr_clk; | 	RTLIL::SigSpec sig_wr_clk; | ||||||
| 	RTLIL::SigSpec sig_wr_clk_enable; | 	RTLIL::SigSpec sig_wr_clk_enable; | ||||||
|  | @ -60,12 +60,11 @@ void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | ||||||
| 	RTLIL::SigSpec sig_rd_addr; | 	RTLIL::SigSpec sig_rd_addr; | ||||||
| 	RTLIL::SigSpec sig_rd_data; | 	RTLIL::SigSpec sig_rd_data; | ||||||
| 
 | 
 | ||||||
| 	std::vector<RTLIL::Cell*> del_cells; |  | ||||||
| 	std::vector<RTLIL::Cell*> memcells; | 	std::vector<RTLIL::Cell*> memcells; | ||||||
| 
 | 
 | ||||||
| 	for (auto &cell_it : module->cells_) { | 	for (auto &cell_it : module->cells_) { | ||||||
| 		RTLIL::Cell *cell = cell_it.second; | 		RTLIL::Cell *cell = cell_it.second; | ||||||
| 		if ((cell->type == "$memwr" || cell->type == "$memrd") && memory->name == cell->parameters["\\MEMID"].decode_string()) | 		if (cell->type.in("$memrd", "$memwr", "$meminit") && memory->name == cell->parameters["\\MEMID"].decode_string()) | ||||||
| 			memcells.push_back(cell); | 			memcells.push_back(cell); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -73,17 +72,38 @@ void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | ||||||
| 
 | 
 | ||||||
| 	for (auto cell : memcells) | 	for (auto cell : memcells) | ||||||
| 	{ | 	{ | ||||||
| 		if (cell->type == "$memwr" && memory->name == cell->parameters["\\MEMID"].decode_string()) | 		log("  %s (%s)\n", log_id(cell), log_id(cell->type)); | ||||||
| 		{ |  | ||||||
| 			wr_ports++; |  | ||||||
| 			del_cells.push_back(cell); |  | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec clk = cell->getPort("\\CLK"); | 		if (cell->type == "$meminit") | ||||||
| 			RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); | 		{ | ||||||
| 			RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); | 			SigSpec addr = sigmap(cell->getPort("\\ADDR")); | ||||||
| 			RTLIL::SigSpec addr = cell->getPort("\\ADDR"); | 			SigSpec data = sigmap(cell->getPort("\\DATA")); | ||||||
| 			RTLIL::SigSpec data = cell->getPort("\\DATA"); | 
 | ||||||
| 			RTLIL::SigSpec en = cell->getPort("\\EN"); | 			if (!addr.is_fully_const()) | ||||||
|  | 				log_error("Non-constant address %s in memory initialization %s.\n", log_signal(addr), log_id(cell)); | ||||||
|  | 			if (!data.is_fully_const()) | ||||||
|  | 				log_error("Non-constant data %s in memory initialization %s.\n", log_signal(data), log_id(cell)); | ||||||
|  | 
 | ||||||
|  | 			int offset = (addr.as_int() - memory->start_offset) * memory->width; | ||||||
|  | 
 | ||||||
|  | 			if (offset < 0 || offset + GetSize(data) > GetSize(init_data)) | ||||||
|  | 				log_warning("Address %s in memory initialization %s is out-of-bounds.\n", log_signal(addr), log_id(cell)); | ||||||
|  | 
 | ||||||
|  | 			for (int i = 0; i < GetSize(data); i++) | ||||||
|  | 				if (0 <= i+offset && i+offset < GetSize(init_data)) | ||||||
|  | 					init_data.bits[i+offset] = data[i].data; | ||||||
|  | 
 | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (cell->type == "$memwr") | ||||||
|  | 		{ | ||||||
|  | 			SigSpec clk = sigmap(cell->getPort("\\CLK")); | ||||||
|  | 			SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); | ||||||
|  | 			SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); | ||||||
|  | 			SigSpec addr = sigmap(cell->getPort("\\ADDR")); | ||||||
|  | 			SigSpec data = sigmap(cell->getPort("\\DATA")); | ||||||
|  | 			SigSpec en = sigmap(cell->getPort("\\EN")); | ||||||
| 
 | 
 | ||||||
| 			clk.extend_u0(1, false); | 			clk.extend_u0(1, false); | ||||||
| 			clk_enable.extend_u0(1, false); | 			clk_enable.extend_u0(1, false); | ||||||
|  | @ -98,19 +118,19 @@ void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | ||||||
| 			sig_wr_addr.append(addr); | 			sig_wr_addr.append(addr); | ||||||
| 			sig_wr_data.append(data); | 			sig_wr_data.append(data); | ||||||
| 			sig_wr_en.append(en); | 			sig_wr_en.append(en); | ||||||
|  | 
 | ||||||
|  | 			wr_ports++; | ||||||
|  | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$memrd" && memory->name == cell->parameters["\\MEMID"].decode_string()) | 		if (cell->type == "$memrd") | ||||||
| 		{ | 		{ | ||||||
| 			rd_ports++; | 			SigSpec clk = sigmap(cell->getPort("\\CLK")); | ||||||
| 			del_cells.push_back(cell); | 			SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); | ||||||
| 
 | 			SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); | ||||||
| 			RTLIL::SigSpec clk = cell->getPort("\\CLK"); | 			SigSpec transparent = RTLIL::SigSpec(cell->parameters["\\TRANSPARENT"]); | ||||||
| 			RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); | 			SigSpec addr = sigmap(cell->getPort("\\ADDR")); | ||||||
| 			RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); | 			SigSpec data = sigmap(cell->getPort("\\DATA")); | ||||||
| 			RTLIL::SigSpec transparent = RTLIL::SigSpec(cell->parameters["\\TRANSPARENT"]); |  | ||||||
| 			RTLIL::SigSpec addr = cell->getPort("\\ADDR"); |  | ||||||
| 			RTLIL::SigSpec data = cell->getPort("\\DATA"); |  | ||||||
| 
 | 
 | ||||||
| 			clk.extend_u0(1, false); | 			clk.extend_u0(1, false); | ||||||
| 			clk_enable.extend_u0(1, false); | 			clk_enable.extend_u0(1, false); | ||||||
|  | @ -125,6 +145,9 @@ void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | ||||||
| 			sig_rd_transparent.append(transparent); | 			sig_rd_transparent.append(transparent); | ||||||
| 			sig_rd_addr.append(addr); | 			sig_rd_addr.append(addr); | ||||||
| 			sig_rd_data.append(data); | 			sig_rd_data.append(data); | ||||||
|  | 
 | ||||||
|  | 			rd_ports++; | ||||||
|  | 			continue; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -138,6 +161,10 @@ void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | ||||||
| 	mem->parameters["\\SIZE"] = RTLIL::Const(memory->size); | 	mem->parameters["\\SIZE"] = RTLIL::Const(memory->size); | ||||||
| 	mem->parameters["\\ABITS"] = RTLIL::Const(addr_bits); | 	mem->parameters["\\ABITS"] = RTLIL::Const(addr_bits); | ||||||
| 
 | 
 | ||||||
|  | 	while (GetSize(init_data) > 1 && init_data.bits.back() == State::Sx && init_data.bits[GetSize(init_data)-2] == State::Sx) | ||||||
|  | 		init_data.bits.pop_back(); | ||||||
|  | 	mem->parameters["\\INIT"] = init_data; | ||||||
|  | 
 | ||||||
| 	log_assert(sig_wr_clk.size() == wr_ports); | 	log_assert(sig_wr_clk.size() == wr_ports); | ||||||
| 	log_assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const()); | 	log_assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const()); | ||||||
| 	log_assert(sig_wr_clk_polarity.size() == wr_ports && sig_wr_clk_polarity.is_fully_const()); | 	log_assert(sig_wr_clk_polarity.size() == wr_ports && sig_wr_clk_polarity.is_fully_const()); | ||||||
|  | @ -169,7 +196,7 @@ void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | ||||||
| 	mem->setPort("\\RD_ADDR", sig_rd_addr); | 	mem->setPort("\\RD_ADDR", sig_rd_addr); | ||||||
| 	mem->setPort("\\RD_DATA", sig_rd_data); | 	mem->setPort("\\RD_DATA", sig_rd_data); | ||||||
| 
 | 
 | ||||||
| 	for (auto c : del_cells) | 	for (auto c : memcells) | ||||||
| 		module->remove(c); | 		module->remove(c); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -80,11 +80,15 @@ struct MemoryMapWorker | ||||||
| 	{ | 	{ | ||||||
| 		std::set<int> static_ports; | 		std::set<int> static_ports; | ||||||
| 		std::map<int, RTLIL::SigSpec> static_cells_map; | 		std::map<int, RTLIL::SigSpec> static_cells_map; | ||||||
|  | 
 | ||||||
| 		int mem_size = cell->parameters["\\SIZE"].as_int(); | 		int mem_size = cell->parameters["\\SIZE"].as_int(); | ||||||
| 		int mem_width = cell->parameters["\\WIDTH"].as_int(); | 		int mem_width = cell->parameters["\\WIDTH"].as_int(); | ||||||
| 		int mem_offset = cell->parameters["\\OFFSET"].as_int(); | 		// int mem_offset = cell->parameters["\\OFFSET"].as_int();
 | ||||||
| 		int mem_abits = cell->parameters["\\ABITS"].as_int(); | 		int mem_abits = cell->parameters["\\ABITS"].as_int(); | ||||||
| 
 | 
 | ||||||
|  | 		SigSpec init_data = cell->getParam("\\INIT"); | ||||||
|  | 		init_data.extend_u0(mem_size*mem_width, true); | ||||||
|  | 
 | ||||||
| 		// delete unused memory cell
 | 		// delete unused memory cell
 | ||||||
| 		if (cell->parameters["\\RD_PORTS"].as_int() == 0 && cell->parameters["\\WR_PORTS"].as_int() == 0) { | 		if (cell->parameters["\\RD_PORTS"].as_int() == 0 && cell->parameters["\\WR_PORTS"].as_int() == 0) { | ||||||
| 			module->remove(cell); | 			module->remove(cell); | ||||||
|  | @ -165,7 +169,10 @@ struct MemoryMapWorker | ||||||
| 					w_out_name = genid(cell->name, "", i, "$q"); | 					w_out_name = genid(cell->name, "", i, "$q"); | ||||||
| 
 | 
 | ||||||
| 				RTLIL::Wire *w_out = module->addWire(w_out_name, mem_width); | 				RTLIL::Wire *w_out = module->addWire(w_out_name, mem_width); | ||||||
| 				w_out->start_offset = mem_offset; | 				SigSpec w_init = init_data.extract(i*mem_width, mem_width); | ||||||
|  | 
 | ||||||
|  | 				if (!w_init.is_fully_undef()) | ||||||
|  | 					w_out->attributes["\\init"] = w_init.as_const(); | ||||||
| 
 | 
 | ||||||
| 				data_reg_out.push_back(RTLIL::SigSpec(w_out)); | 				data_reg_out.push_back(RTLIL::SigSpec(w_out)); | ||||||
| 				c->setPort("\\Q", data_reg_out.back()); | 				c->setPort("\\Q", data_reg_out.back()); | ||||||
|  |  | ||||||
|  | @ -1543,6 +1543,7 @@ parameter SIZE = 256; | ||||||
| parameter OFFSET = 0; | parameter OFFSET = 0; | ||||||
| parameter ABITS = 8; | parameter ABITS = 8; | ||||||
| parameter WIDTH = 8; | parameter WIDTH = 8; | ||||||
|  | parameter signed INIT = 1'bx; | ||||||
| 
 | 
 | ||||||
| parameter RD_PORTS = 1; | parameter RD_PORTS = 1; | ||||||
| parameter RD_CLK_ENABLE = 1'b1; | parameter RD_CLK_ENABLE = 1'b1; | ||||||
|  | @ -1583,26 +1584,37 @@ function port_active; | ||||||
| 	end | 	end | ||||||
| endfunction | endfunction | ||||||
| 
 | 
 | ||||||
|  | initial begin | ||||||
|  | 	for (i = 0; i < SIZE; i = i+1) | ||||||
|  | 		memory[i] = INIT >>> (i*WIDTH); | ||||||
|  | end | ||||||
|  | 
 | ||||||
| always @(RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA) begin | always @(RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA) begin | ||||||
| `ifdef SIMLIB_MEMDELAY | `ifdef SIMLIB_MEMDELAY | ||||||
| 	#`SIMLIB_MEMDELAY; | 	#`SIMLIB_MEMDELAY; | ||||||
| `endif | `endif | ||||||
| 	for (i = 0; i < RD_PORTS; i = i+1) begin | 	for (i = 0; i < RD_PORTS; i = i+1) begin | ||||||
| 		if ((!RD_TRANSPARENT[i] && RD_CLK_ENABLE[i]) && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) | 		if ((!RD_TRANSPARENT[i] && RD_CLK_ENABLE[i]) && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin | ||||||
|  | 			// $display("Read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS],  memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]); | ||||||
| 			RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; | 			RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; | ||||||
| 		end | 		end | ||||||
|  | 	end | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < WR_PORTS; i = i+1) begin | 	for (i = 0; i < WR_PORTS; i = i+1) begin | ||||||
| 		if (port_active(WR_CLK_ENABLE[i], WR_CLK_POLARITY[i], LAST_WR_CLK[i], WR_CLK[i])) | 		if (port_active(WR_CLK_ENABLE[i], WR_CLK_POLARITY[i], LAST_WR_CLK[i], WR_CLK[i])) | ||||||
| 			for (j = 0; j < WIDTH; j = j+1) | 			for (j = 0; j < WIDTH; j = j+1) | ||||||
| 				if (WR_EN[i*WIDTH+j]) | 				if (WR_EN[i*WIDTH+j]) begin | ||||||
|  | 					// $display("Write to %s: addr=%b data=%b", MEMID, WR_ADDR[i*ABITS +: ABITS], WR_DATA[i*WIDTH+j]); | ||||||
| 					memory[WR_ADDR[i*ABITS +: ABITS] - OFFSET][j] = WR_DATA[i*WIDTH+j]; | 					memory[WR_ADDR[i*ABITS +: ABITS] - OFFSET][j] = WR_DATA[i*WIDTH+j]; | ||||||
| 				end | 				end | ||||||
|  | 	end | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < RD_PORTS; i = i+1) begin | 	for (i = 0; i < RD_PORTS; i = i+1) begin | ||||||
| 		if ((RD_TRANSPARENT[i] || !RD_CLK_ENABLE[i]) && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) | 		if ((RD_TRANSPARENT[i] || !RD_CLK_ENABLE[i]) && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin | ||||||
|  | 			// $display("Transparent read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS],  memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]); | ||||||
| 			RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; | 			RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; | ||||||
| 		end | 		end | ||||||
|  | 	end | ||||||
| 
 | 
 | ||||||
| 	LAST_RD_CLK <= RD_CLK; | 	LAST_RD_CLK <= RD_CLK; | ||||||
| 	LAST_WR_CLK <= WR_CLK; | 	LAST_WR_CLK <= WR_CLK; | ||||||
|  |  | ||||||
|  | @ -209,29 +209,22 @@ endmodule | ||||||
| 
 | 
 | ||||||
| module memtest09 ( | module memtest09 ( | ||||||
|     input clk, |     input clk, | ||||||
|     input [1:0] a_addr, a_din, b_addr, b_din, |     input [3:0] a_addr, a_din, b_addr, b_din, | ||||||
|     input a_wen, b_wen, |     input a_wen, b_wen, | ||||||
|     output reg [1:0] a_dout, b_dout |     output reg [3:0] a_dout, b_dout | ||||||
| ); | ); | ||||||
|     reg [1:0] memory [0:3]; |     reg [3:0] memory [0:35]; | ||||||
| 
 |  | ||||||
|     initial begin |  | ||||||
|         memory[0] <= 0; |  | ||||||
|         memory[1] <= 1; |  | ||||||
|         memory[2] <= 2; |  | ||||||
|         memory[3] <= 3; |  | ||||||
|     end |  | ||||||
| 
 | 
 | ||||||
|     always @(posedge clk) begin |     always @(posedge clk) begin | ||||||
|         if (a_wen) |         if (a_wen) | ||||||
|             memory[a_addr] <= a_din; |             memory[10 + a_addr] <= a_din; | ||||||
|         a_dout <= memory[a_addr]; |         a_dout <= memory[10 + a_addr]; | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     always @(posedge clk) begin |     always @(posedge clk) begin | ||||||
|         if (b_wen) |         if (b_wen && (10 + a_addr != 20 + b_addr)) | ||||||
|             memory[b_addr] <= b_din; |             memory[20 + b_addr] <= b_din; | ||||||
|         b_dout <= memory[b_addr]; |         b_dout <= memory[20 + b_addr]; | ||||||
|     end |     end | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); | ||||||
| 	parameter OFFSET = 0; | 	parameter OFFSET = 0; | ||||||
| 	parameter ABITS = 8; | 	parameter ABITS = 8; | ||||||
| 	parameter WIDTH = 8; | 	parameter WIDTH = 8; | ||||||
|  | 	parameter signed INIT = 1'bx; | ||||||
| 
 | 
 | ||||||
| 	parameter RD_PORTS = 1; | 	parameter RD_PORTS = 1; | ||||||
| 	parameter RD_CLK_ENABLE = 1'b1; | 	parameter RD_CLK_ENABLE = 1'b1; | ||||||
|  | @ -37,6 +38,10 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); | ||||||
| 	initial begin | 	initial begin | ||||||
| 		_TECHMAP_FAIL_ <= 0; | 		_TECHMAP_FAIL_ <= 0; | ||||||
| 
 | 
 | ||||||
|  | 		// no initialized memories | ||||||
|  | 		if (INIT !== 1'bx) | ||||||
|  | 			_TECHMAP_FAIL_ <= 1; | ||||||
|  | 
 | ||||||
| 		// only map cells with only one read and one write port | 		// only map cells with only one read and one write port | ||||||
| 		if (RD_PORTS > 1 || WR_PORTS > 1) | 		if (RD_PORTS > 1 || WR_PORTS > 1) | ||||||
| 			_TECHMAP_FAIL_ <= 1; | 			_TECHMAP_FAIL_ <= 1; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue