mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Added correct handling of $memwr priority
This commit is contained in:
		
							parent
							
								
									536e20bde1
								
							
						
					
					
						commit
						fb2bf934dc
					
				
					 5 changed files with 42 additions and 2 deletions
				
			
		|  | @ -1271,6 +1271,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | ||||||
| 
 | 
 | ||||||
| 			cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0); | 			cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0); | ||||||
| 			cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0); | 			cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0); | ||||||
|  | 
 | ||||||
|  | 			cell->parameters["\\PRIORITY"] = RTLIL::Const(RTLIL::autoidx-1); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -567,6 +567,7 @@ namespace { | ||||||
| 				param("\\MEMID"); | 				param("\\MEMID"); | ||||||
| 				param("\\CLK_ENABLE"); | 				param("\\CLK_ENABLE"); | ||||||
| 				param("\\CLK_POLARITY"); | 				param("\\CLK_POLARITY"); | ||||||
|  | 				param("\\PRIORITY"); | ||||||
| 				port("\\CLK", 1); | 				port("\\CLK", 1); | ||||||
| 				port("\\EN", 1); | 				port("\\EN", 1); | ||||||
| 				port("\\ADDR", param("\\ABITS")); | 				port("\\ADDR", param("\\ABITS")); | ||||||
|  |  | ||||||
|  | @ -272,6 +272,9 @@ the \B{CLK} input is not used. | ||||||
| \item \B{CLK\_POLARITY} \\ | \item \B{CLK\_POLARITY} \\ | ||||||
| Clock is active on positive edge if this parameter has the value {\tt 1'b1} and on the negative | Clock is active on positive edge if this parameter has the value {\tt 1'b1} and on the negative | ||||||
| edge if this parameter is {\tt 1'b0}. | edge if this parameter is {\tt 1'b0}. | ||||||
|  | 
 | ||||||
|  | \item \B{PRIORITY} \\ | ||||||
|  | The cell with the higher integer value in this parameter wins a write conflict. | ||||||
| \end{itemize} | \end{itemize} | ||||||
| 
 | 
 | ||||||
| The HDL frontend models a memory using RTLIL::Memory objects and asynchronous | The HDL frontend models a memory using RTLIL::Memory objects and asynchronous | ||||||
|  |  | ||||||
|  | @ -20,9 +20,19 @@ | ||||||
| #include "kernel/register.h" | #include "kernel/register.h" | ||||||
| #include "kernel/log.h" | #include "kernel/log.h" | ||||||
| #include <sstream> | #include <sstream> | ||||||
|  | #include <algorithm> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| 
 | 
 | ||||||
|  | static bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b) | ||||||
|  | { | ||||||
|  | 	if (a->type == "$memrd" && b->type == "$memrd") | ||||||
|  | 		return a->name < b->name; | ||||||
|  | 	if (a->type == "$memrd" || b->type == "$memrd") | ||||||
|  | 		return (a->type == "$memrd") < (b->type == "$memrd"); | ||||||
|  | 	return a->parameters.at("\\PRIORITY").as_int() < b->parameters.at("\\PRIORITY").as_int(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | ||||||
| { | { | ||||||
| 	log("Collecting $memrd and $memwr for memory `%s' in module `%s':\n", | 	log("Collecting $memrd and $memwr for memory `%s' in module `%s':\n", | ||||||
|  | @ -48,11 +58,18 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) | ||||||
| 	RTLIL::SigSpec sig_rd_data; | 	RTLIL::SigSpec sig_rd_data; | ||||||
| 
 | 
 | ||||||
| 	std::vector<std::string> del_cell_ids; | 	std::vector<std::string> del_cell_ids; | ||||||
|  | 	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") && cell->parameters["\\MEMID"].decode_string() == memory->name) | ||||||
|  | 			memcells.push_back(cell); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|  | 	std::sort(memcells.begin(), memcells.end(), memcells_cmp); | ||||||
|  | 
 | ||||||
|  | 	for (auto cell : memcells) | ||||||
|  | 	{ | ||||||
| 		if (cell->type == "$memwr" && cell->parameters["\\MEMID"].decode_string() == memory->name) | 		if (cell->type == "$memwr" && cell->parameters["\\MEMID"].decode_string() == memory->name) | ||||||
| 		{ | 		{ | ||||||
| 			wr_ports++; | 			wr_ports++; | ||||||
|  |  | ||||||
|  | @ -1,4 +1,21 @@ | ||||||
| 
 | 
 | ||||||
|  | module test00(clk, setA, setB, y); | ||||||
|  | 
 | ||||||
|  | input clk, setA, setB; | ||||||
|  | output y; | ||||||
|  | reg mem [1:0]; | ||||||
|  | 
 | ||||||
|  | always @(posedge clk) begin | ||||||
|  | 	if (setA) mem[0] <= 0;  // this is line 9 | ||||||
|  | 	if (setB) mem[0] <= 1;  // this is line 10 | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | assign y = mem[0]; | ||||||
|  | 
 | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // ---------------------------------------------------------- | ||||||
|  | 
 | ||||||
| module test01(clk, wr_en, wr_addr, wr_value, rd_addr, rd_value); | module test01(clk, wr_en, wr_addr, wr_value, rd_addr, rd_value); | ||||||
| 
 | 
 | ||||||
| input clk, wr_en; | input clk, wr_en; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue