mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			152 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
| 
 | |
| module \$mem (RD_CLK, RD_EN, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
 | |
| 	parameter MEMID = "";
 | |
| 	parameter SIZE = 256;
 | |
| 	parameter OFFSET = 0;
 | |
| 	parameter ABITS = 8;
 | |
| 	parameter WIDTH = 8;
 | |
| 	parameter signed INIT = 1'bx;
 | |
| 
 | |
| 	parameter RD_PORTS = 1;
 | |
| 	parameter RD_CLK_ENABLE = 1'b1;
 | |
| 	parameter RD_CLK_POLARITY = 1'b1;
 | |
| 	parameter RD_TRANSPARENT = 1'b1;
 | |
| 
 | |
| 	parameter WR_PORTS = 1;
 | |
| 	parameter WR_CLK_ENABLE = 1'b1;
 | |
| 	parameter WR_CLK_POLARITY = 1'b1;
 | |
| 
 | |
| 	input [RD_PORTS-1:0] RD_CLK;
 | |
| 	input [RD_PORTS-1:0] RD_EN;
 | |
| 	input [RD_PORTS*ABITS-1:0] RD_ADDR;
 | |
| 	output reg [RD_PORTS*WIDTH-1:0] RD_DATA;
 | |
| 
 | |
| 	input [WR_PORTS-1:0] WR_CLK;
 | |
| 	input [WR_PORTS*WIDTH-1:0] WR_EN;
 | |
| 	input [WR_PORTS*ABITS-1:0] WR_ADDR;
 | |
| 	input [WR_PORTS*WIDTH-1:0] WR_DATA;
 | |
| 
 | |
| 	wire [1023:0] _TECHMAP_DO_ = "proc; clean";
 | |
| 
 | |
| 	parameter _TECHMAP_CONNMAP_RD_CLK_ = 0;
 | |
| 	parameter _TECHMAP_CONNMAP_WR_CLK_ = 0;
 | |
| 
 | |
| 	parameter _TECHMAP_CONSTVAL_RD_EN_ = 0;
 | |
| 
 | |
| 	parameter _TECHMAP_BITS_CONNMAP_ = 0;
 | |
| 	parameter _TECHMAP_CONNMAP_WR_EN_ = 0;
 | |
| 
 | |
| 	reg _TECHMAP_FAIL_;
 | |
| 	integer k;
 | |
| 	initial begin
 | |
| 		_TECHMAP_FAIL_ <= 0;
 | |
| 
 | |
| 		// no initialized memories
 | |
| 		if (INIT !== 1'bx)
 | |
| 			_TECHMAP_FAIL_ <= 1;
 | |
| 
 | |
| 		// only map cells with only one read and one write port
 | |
| 		if (RD_PORTS > 1 || WR_PORTS > 1)
 | |
| 			_TECHMAP_FAIL_ <= 1;
 | |
| 
 | |
| 		// read enable must be constant high
 | |
| 		if (_TECHMAP_CONSTVAL_RD_EN_[0] !== 1'b1)
 | |
| 			_TECHMAP_FAIL_ <= 1;
 | |
| 
 | |
| 		// we expect positive read clock and non-transparent reads
 | |
| 		if (RD_TRANSPARENT || !RD_CLK_ENABLE || !RD_CLK_POLARITY)
 | |
| 			_TECHMAP_FAIL_ <= 1;
 | |
| 
 | |
| 		// we expect positive write clock
 | |
| 		if (!WR_CLK_ENABLE || !WR_CLK_POLARITY)
 | |
| 			_TECHMAP_FAIL_ <= 1;
 | |
| 
 | |
| 		// only one global write enable bit is supported
 | |
| 		for (k = 1; k < WR_PORTS*WIDTH; k = k+1)
 | |
| 			if (_TECHMAP_CONNMAP_WR_EN_[0 +: _TECHMAP_BITS_CONNMAP_] !=
 | |
| 					_TECHMAP_CONNMAP_WR_EN_[k*_TECHMAP_BITS_CONNMAP_ +: _TECHMAP_BITS_CONNMAP_])
 | |
| 				_TECHMAP_FAIL_ <= 1;
 | |
| 
 | |
| 		// read and write must be in same clock domain
 | |
| 		if (_TECHMAP_CONNMAP_RD_CLK_ != _TECHMAP_CONNMAP_WR_CLK_)
 | |
| 			_TECHMAP_FAIL_ <= 1;
 | |
| 
 | |
| 		// we don't do small memories or memories with offsets
 | |
| 		if (OFFSET != 0 || ABITS < 4 || SIZE < 16)
 | |
| 			_TECHMAP_FAIL_ <= 1;
 | |
| 	end
 | |
| 
 | |
| 	genvar i;
 | |
| 	generate
 | |
| 	  for (i = 0; i < WIDTH; i=i+1) begin:slice
 | |
| 		\$__mem_4x1_generator #(
 | |
| 			.ABITS(ABITS),
 | |
| 			.SIZE(SIZE)
 | |
| 		) bit_slice (
 | |
| 			.CLK(RD_CLK),
 | |
| 			.RD_ADDR(RD_ADDR),
 | |
| 			.RD_DATA(RD_DATA[i]),
 | |
| 			.WR_ADDR(WR_ADDR),
 | |
| 			.WR_DATA(WR_DATA[i]),
 | |
| 			.WR_EN(WR_EN[0])
 | |
| 		);
 | |
| 	  end
 | |
| 	endgenerate
 | |
| endmodule
 | |
| 
 | |
| module \$__mem_4x1_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN);
 | |
| 	parameter ABITS = 4;
 | |
| 	parameter SIZE = 16;
 | |
| 
 | |
| 	input CLK, WR_DATA, WR_EN;
 | |
| 	input [ABITS-1:0] RD_ADDR, WR_ADDR;
 | |
| 	output RD_DATA;
 | |
| 
 | |
| 	wire [1023:0] _TECHMAP_DO_ = "proc; clean";
 | |
| 
 | |
| 	generate
 | |
| 	  if (ABITS > 4) begin
 | |
| 	  	wire high_rd_data, low_rd_data;
 | |
| 	  	if (SIZE > 2**(ABITS-1)) begin
 | |
| 			\$__mem_4x1_generator #(
 | |
| 				.ABITS(ABITS-1),
 | |
| 				.SIZE(SIZE - 2**(ABITS-1))
 | |
| 			) part_high (
 | |
| 				.CLK(CLK),
 | |
| 				.RD_ADDR(RD_ADDR[ABITS-2:0]),
 | |
| 				.RD_DATA(high_rd_data),
 | |
| 				.WR_ADDR(WR_ADDR[ABITS-2:0]),
 | |
| 				.WR_DATA(WR_DATA),
 | |
| 				.WR_EN(WR_EN && WR_ADDR[ABITS-1])
 | |
| 			);
 | |
| 		end else begin
 | |
| 			assign high_rd_data = 1'bx;
 | |
| 		end
 | |
| 		\$__mem_4x1_generator #(
 | |
| 			.ABITS(ABITS-1),
 | |
| 			.SIZE(SIZE > 2**(ABITS-1) ? 2**(ABITS-1) : SIZE)
 | |
| 		) part_low (
 | |
| 			.CLK(CLK),
 | |
| 			.RD_ADDR(RD_ADDR[ABITS-2:0]),
 | |
| 			.RD_DATA(low_rd_data),
 | |
| 			.WR_ADDR(WR_ADDR[ABITS-2:0]),
 | |
| 			.WR_DATA(WR_DATA),
 | |
| 			.WR_EN(WR_EN && !WR_ADDR[ABITS-1])
 | |
| 		);
 | |
| 		reg delayed_abit;
 | |
| 		always @(posedge CLK)
 | |
| 			delayed_abit <= RD_ADDR[ABITS-1];
 | |
| 		assign RD_DATA = delayed_abit ? high_rd_data : low_rd_data;
 | |
| 	  end else begin
 | |
| 	  	MEM4X1 _TECHMAP_REPLACE_ (
 | |
| 			.CLK(CLK),
 | |
| 			.RD_ADDR(RD_ADDR),
 | |
| 			.RD_DATA(RD_DATA),
 | |
| 			.WR_ADDR(WR_ADDR),
 | |
| 			.WR_DATA(WR_DATA),
 | |
| 			.WR_EN(WR_EN)
 | |
| 		);
 | |
| 	  end
 | |
| 	endgenerate
 | |
| endmodule
 | |
| 
 |