mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-20 14:20:32 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			218 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
| module $__ICE40_RAM4K_ (...);
 | |
| 
 | |
| parameter INIT = 0;
 | |
| parameter OPTION_HAS_BE = 1;
 | |
| parameter PORT_R_WIDTH = 16;
 | |
| parameter PORT_W_WIDTH = 16;
 | |
| parameter PORT_W_WR_BE_WIDTH = 16;
 | |
| parameter PORT_R_CLK_POL = 1;
 | |
| parameter PORT_W_CLK_POL = 1;
 | |
| 
 | |
| input PORT_R_CLK;
 | |
| input PORT_R_RD_EN;
 | |
| input [10:0] PORT_R_ADDR;
 | |
| output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
 | |
| 
 | |
| input PORT_W_CLK;
 | |
| input PORT_W_WR_EN;
 | |
| input [15:0] PORT_W_WR_BE;
 | |
| input [10:0] PORT_W_ADDR;
 | |
| input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
 | |
| 
 | |
| wire [15:0] RDATA;
 | |
| wire [15:0] WDATA;
 | |
| wire [15:0] MASK;
 | |
| wire [10:0] RADDR = {PORT_R_ADDR[0], PORT_R_ADDR[1], PORT_R_ADDR[2], PORT_R_ADDR[10:3]};
 | |
| wire [10:0] WADDR = {PORT_W_ADDR[0], PORT_W_ADDR[1], PORT_W_ADDR[2], PORT_W_ADDR[10:3]};
 | |
| 
 | |
| function [1:0] mode;
 | |
| 	input integer width;
 | |
| 	case (width)
 | |
| 	16: mode = 0;
 | |
| 	8: mode = 1;
 | |
| 	4: mode = 2;
 | |
| 	2: mode = 3;
 | |
| 	endcase
 | |
| endfunction
 | |
| 
 | |
| function [255:0] slice_init;
 | |
| 	input [3:0] idx;
 | |
| 	integer i;
 | |
| 	reg [7:0] ri;
 | |
| 	reg [11:0] a;
 | |
| 	for (i = 0; i < 256; i = i + 1) begin
 | |
| 		ri = i;
 | |
| 		a = {idx, ri[7:4], ri[0], ri[1], ri[2], ri[3]};
 | |
| 		slice_init[i] = INIT[a];
 | |
| 	end
 | |
| endfunction
 | |
| 
 | |
| `define INSTANCE(type, rclk, wclk) \
 | |
| 	type #( \
 | |
| 		.INIT_0(slice_init(0)), \
 | |
| 		.INIT_1(slice_init(1)), \
 | |
| 		.INIT_2(slice_init(2)), \
 | |
| 		.INIT_3(slice_init(3)), \
 | |
| 		.INIT_4(slice_init(4)), \
 | |
| 		.INIT_5(slice_init(5)), \
 | |
| 		.INIT_6(slice_init(6)), \
 | |
| 		.INIT_7(slice_init(7)), \
 | |
| 		.INIT_8(slice_init(8)), \
 | |
| 		.INIT_9(slice_init(9)), \
 | |
| 		.INIT_A(slice_init(10)), \
 | |
| 		.INIT_B(slice_init(11)), \
 | |
| 		.INIT_C(slice_init(12)), \
 | |
| 		.INIT_D(slice_init(13)), \
 | |
| 		.INIT_E(slice_init(14)), \
 | |
| 		.INIT_F(slice_init(15)), \
 | |
| 		.READ_MODE(mode(PORT_R_WIDTH)), \
 | |
| 		.WRITE_MODE(mode(PORT_W_WIDTH)) \
 | |
| 	) _TECHMAP_REPLACE_ ( \
 | |
| 		.RDATA(RDATA), \
 | |
| 		.rclk(PORT_R_CLK), \
 | |
| 		.RCLKE(PORT_R_RD_EN), \
 | |
| 		.RE(1'b1), \
 | |
| 		.RADDR(RADDR), \
 | |
| 		.WDATA(WDATA), \
 | |
| 		.wclk(PORT_W_CLK), \
 | |
| 		.WCLKE(PORT_W_WR_EN), \
 | |
| 		.WE(1'b1), \
 | |
| 		.WADDR(WADDR), \
 | |
| 		.MASK(MASK), \
 | |
| 	);
 | |
| 
 | |
| generate
 | |
| 
 | |
| case(PORT_R_WIDTH)
 | |
| 	2: begin
 | |
| 		assign PORT_R_RD_DATA = {
 | |
| 			RDATA[11],
 | |
| 			RDATA[3]
 | |
| 		};
 | |
| 	end
 | |
| 	4: begin
 | |
| 		assign PORT_R_RD_DATA = {
 | |
| 			RDATA[13],
 | |
| 			RDATA[5],
 | |
| 			RDATA[9],
 | |
| 			RDATA[1]
 | |
| 		};
 | |
| 	end
 | |
| 	8: begin
 | |
| 		assign PORT_R_RD_DATA = {
 | |
| 			RDATA[14],
 | |
| 			RDATA[6],
 | |
| 			RDATA[10],
 | |
| 			RDATA[2],
 | |
| 			RDATA[12],
 | |
| 			RDATA[4],
 | |
| 			RDATA[8],
 | |
| 			RDATA[0]
 | |
| 		};
 | |
| 	end
 | |
| 	16: begin
 | |
| 		assign PORT_R_RD_DATA = {
 | |
| 			RDATA[15],
 | |
| 			RDATA[7],
 | |
| 			RDATA[11],
 | |
| 			RDATA[3],
 | |
| 			RDATA[13],
 | |
| 			RDATA[5],
 | |
| 			RDATA[9],
 | |
| 			RDATA[1],
 | |
| 			RDATA[14],
 | |
| 			RDATA[6],
 | |
| 			RDATA[10],
 | |
| 			RDATA[2],
 | |
| 			RDATA[12],
 | |
| 			RDATA[4],
 | |
| 			RDATA[8],
 | |
| 			RDATA[0]
 | |
| 		};
 | |
| 	end
 | |
| endcase
 | |
| 
 | |
| case(PORT_W_WIDTH)
 | |
| 	2: begin
 | |
| 		assign {
 | |
| 			WDATA[11],
 | |
| 			WDATA[3]
 | |
| 		} = PORT_W_WR_DATA;
 | |
| 	end
 | |
| 	4: begin
 | |
| 		assign {
 | |
| 			WDATA[13],
 | |
| 			WDATA[5],
 | |
| 			WDATA[9],
 | |
| 			WDATA[1]
 | |
| 		} = PORT_W_WR_DATA;
 | |
| 	end
 | |
| 	8: begin
 | |
| 		assign {
 | |
| 			WDATA[14],
 | |
| 			WDATA[6],
 | |
| 			WDATA[10],
 | |
| 			WDATA[2],
 | |
| 			WDATA[12],
 | |
| 			WDATA[4],
 | |
| 			WDATA[8],
 | |
| 			WDATA[0]
 | |
| 		} = PORT_W_WR_DATA;
 | |
| 	end
 | |
| 	16: begin
 | |
| 		assign WDATA = {
 | |
| 			PORT_W_WR_DATA[15],
 | |
| 			PORT_W_WR_DATA[7],
 | |
| 			PORT_W_WR_DATA[11],
 | |
| 			PORT_W_WR_DATA[3],
 | |
| 			PORT_W_WR_DATA[13],
 | |
| 			PORT_W_WR_DATA[5],
 | |
| 			PORT_W_WR_DATA[9],
 | |
| 			PORT_W_WR_DATA[1],
 | |
| 			PORT_W_WR_DATA[14],
 | |
| 			PORT_W_WR_DATA[6],
 | |
| 			PORT_W_WR_DATA[10],
 | |
| 			PORT_W_WR_DATA[2],
 | |
| 			PORT_W_WR_DATA[12],
 | |
| 			PORT_W_WR_DATA[4],
 | |
| 			PORT_W_WR_DATA[8],
 | |
| 			PORT_W_WR_DATA[0]
 | |
| 		};
 | |
| 		assign MASK = ~{
 | |
| 			PORT_W_WR_BE[15],
 | |
| 			PORT_W_WR_BE[7],
 | |
| 			PORT_W_WR_BE[11],
 | |
| 			PORT_W_WR_BE[3],
 | |
| 			PORT_W_WR_BE[13],
 | |
| 			PORT_W_WR_BE[5],
 | |
| 			PORT_W_WR_BE[9],
 | |
| 			PORT_W_WR_BE[1],
 | |
| 			PORT_W_WR_BE[14],
 | |
| 			PORT_W_WR_BE[6],
 | |
| 			PORT_W_WR_BE[10],
 | |
| 			PORT_W_WR_BE[2],
 | |
| 			PORT_W_WR_BE[12],
 | |
| 			PORT_W_WR_BE[4],
 | |
| 			PORT_W_WR_BE[8],
 | |
| 			PORT_W_WR_BE[0]
 | |
| 		};
 | |
| 	end
 | |
| endcase
 | |
| 
 | |
| if (PORT_R_CLK_POL) begin
 | |
| 	if (PORT_W_CLK_POL) begin
 | |
| 		`INSTANCE(SB_RAM40_4K, RCLK, WCLK)
 | |
| 	end else begin
 | |
| 		`INSTANCE(SB_RAM40_4KNW, RCLK, WCLKN)
 | |
| 	end
 | |
| end else begin
 | |
| 	if (PORT_W_CLK_POL) begin
 | |
| 		`INSTANCE(SB_RAM40_4KNR, RCLKN, WCLK)
 | |
| 	end else begin
 | |
| 		`INSTANCE(SB_RAM40_4KNRNW, RCLKN, WCLKN)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| endgenerate
 | |
| 
 | |
| endmodule
 |