mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Merge pull request #5108 from marzoul/adrien-uram
Create a single-port URAM mapping to support memories 2048 x 144b
This commit is contained in:
		
						commit
						5268565410
					
				
					 4 changed files with 203 additions and 7 deletions
				
			
		|  | @ -35,3 +35,25 @@ ram huge $__XILINX_URAM_ { | ||||||
| 		wrbe_separate; | 		wrbe_separate; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | ram huge $__XILINX_URAM_SP_ { | ||||||
|  | 	abits 11; | ||||||
|  | 	width 144; | ||||||
|  | 	cost 1024; | ||||||
|  | 	option "BYTEWIDTH" 8 byte 8; | ||||||
|  | 	option "BYTEWIDTH" 9 byte 9; | ||||||
|  | 	init zero; | ||||||
|  | 	port srsw "A" { | ||||||
|  | 		clock anyedge "C"; | ||||||
|  | 		clken; | ||||||
|  | 		rdwr no_change; | ||||||
|  | 		rdinit zero; | ||||||
|  | 		portoption "RST_MODE" "SYNC" { | ||||||
|  | 			rdsrst zero ungated; | ||||||
|  | 		} | ||||||
|  | 		portoption "RST_MODE" "ASYNC" { | ||||||
|  | 			rdarst zero; | ||||||
|  | 		} | ||||||
|  | 		wrbe_separate; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -150,3 +150,141 @@ module $__XILINX_URAM_ (...); | ||||||
| 		.SLEEP(1'b0) | 		.SLEEP(1'b0) | ||||||
| 	); | 	); | ||||||
| endmodule | endmodule | ||||||
|  | 
 | ||||||
|  | module $__XILINX_URAM_SP_ (...); | ||||||
|  | 	parameter OPTION_BYTEWIDTH = 8; | ||||||
|  | 	localparam WR_BE_WIDTH = 144 / OPTION_BYTEWIDTH; | ||||||
|  | 
 | ||||||
|  | 	parameter CLK_C_POL = 1; | ||||||
|  | 	parameter PORT_A_CLK_POL = 1; | ||||||
|  | 	parameter PORT_A_OPTION_RST_MODE = "SYNC"; | ||||||
|  | 
 | ||||||
|  | 	input CLK_C; | ||||||
|  | 
 | ||||||
|  | 	input PORT_A_CLK; | ||||||
|  | 	input PORT_A_CLK_EN; | ||||||
|  | 	input PORT_A_RD_SRST; | ||||||
|  | 	input PORT_A_RD_ARST; | ||||||
|  | 	input PORT_A_WR_EN; | ||||||
|  | 	input [WR_BE_WIDTH-1:0] PORT_A_WR_BE; | ||||||
|  | 	input [10:0] PORT_A_ADDR; | ||||||
|  | 	input [143:0] PORT_A_WR_DATA; | ||||||
|  | 	output [143:0] PORT_A_RD_DATA; | ||||||
|  | 
 | ||||||
|  | 	wire [71:0] DIN_A, DIN_B, DOUT_A, DOUT_B; | ||||||
|  | 
 | ||||||
|  | 	generate | ||||||
|  | 		if (OPTION_BYTEWIDTH == 8) begin | ||||||
|  | 			assign DIN_A = PORT_A_WR_DATA[71:0]; | ||||||
|  | 			assign DIN_B = PORT_A_WR_DATA[143:72]; | ||||||
|  | 			assign PORT_A_RD_DATA = {DOUT_B, DOUT_A}; | ||||||
|  | 		end else begin | ||||||
|  | 			assign DIN_A = { | ||||||
|  | 				PORT_A_WR_DATA[71], | ||||||
|  | 				PORT_A_WR_DATA[62], | ||||||
|  | 				PORT_A_WR_DATA[53], | ||||||
|  | 				PORT_A_WR_DATA[44], | ||||||
|  | 				PORT_A_WR_DATA[35], | ||||||
|  | 				PORT_A_WR_DATA[26], | ||||||
|  | 				PORT_A_WR_DATA[17], | ||||||
|  | 				PORT_A_WR_DATA[8], | ||||||
|  | 				PORT_A_WR_DATA[70:63], | ||||||
|  | 				PORT_A_WR_DATA[61:54], | ||||||
|  | 				PORT_A_WR_DATA[52:45], | ||||||
|  | 				PORT_A_WR_DATA[43:36], | ||||||
|  | 				PORT_A_WR_DATA[34:27], | ||||||
|  | 				PORT_A_WR_DATA[25:18], | ||||||
|  | 				PORT_A_WR_DATA[16:9], | ||||||
|  | 				PORT_A_WR_DATA[7:0] | ||||||
|  | 			}; | ||||||
|  | 			assign DIN_B = { | ||||||
|  | 				PORT_A_WR_DATA[72+71], | ||||||
|  | 				PORT_A_WR_DATA[72+62], | ||||||
|  | 				PORT_A_WR_DATA[72+53], | ||||||
|  | 				PORT_A_WR_DATA[72+44], | ||||||
|  | 				PORT_A_WR_DATA[72+35], | ||||||
|  | 				PORT_A_WR_DATA[72+26], | ||||||
|  | 				PORT_A_WR_DATA[72+17], | ||||||
|  | 				PORT_A_WR_DATA[72+8], | ||||||
|  | 				PORT_A_WR_DATA[72+70:72+63], | ||||||
|  | 				PORT_A_WR_DATA[72+61:72+54], | ||||||
|  | 				PORT_A_WR_DATA[72+52:72+45], | ||||||
|  | 				PORT_A_WR_DATA[72+43:72+36], | ||||||
|  | 				PORT_A_WR_DATA[72+34:72+27], | ||||||
|  | 				PORT_A_WR_DATA[72+25:72+18], | ||||||
|  | 				PORT_A_WR_DATA[72+16:72+ 9], | ||||||
|  | 				PORT_A_WR_DATA[72+ 7:72+ 0] | ||||||
|  | 			}; | ||||||
|  | 			assign PORT_A_RD_DATA = { | ||||||
|  | 				DOUT_B[71], | ||||||
|  | 				DOUT_B[63:56], | ||||||
|  | 				DOUT_B[70], | ||||||
|  | 				DOUT_B[55:48], | ||||||
|  | 				DOUT_B[69], | ||||||
|  | 				DOUT_B[47:40], | ||||||
|  | 				DOUT_B[68], | ||||||
|  | 				DOUT_B[39:32], | ||||||
|  | 				DOUT_B[67], | ||||||
|  | 				DOUT_B[31:24], | ||||||
|  | 				DOUT_B[66], | ||||||
|  | 				DOUT_B[23:16], | ||||||
|  | 				DOUT_B[65], | ||||||
|  | 				DOUT_B[15:8], | ||||||
|  | 				DOUT_B[64], | ||||||
|  | 				DOUT_B[7:0], | ||||||
|  | 				DOUT_A[71], | ||||||
|  | 				DOUT_A[63:56], | ||||||
|  | 				DOUT_A[70], | ||||||
|  | 				DOUT_A[55:48], | ||||||
|  | 				DOUT_A[69], | ||||||
|  | 				DOUT_A[47:40], | ||||||
|  | 				DOUT_A[68], | ||||||
|  | 				DOUT_A[39:32], | ||||||
|  | 				DOUT_A[67], | ||||||
|  | 				DOUT_A[31:24], | ||||||
|  | 				DOUT_A[66], | ||||||
|  | 				DOUT_A[23:16], | ||||||
|  | 				DOUT_A[65], | ||||||
|  | 				DOUT_A[15:8], | ||||||
|  | 				DOUT_A[64], | ||||||
|  | 				DOUT_A[7:0] | ||||||
|  | 			}; | ||||||
|  | 		end | ||||||
|  | 	endgenerate | ||||||
|  | 
 | ||||||
|  | 	URAM288 #( | ||||||
|  | 		.BWE_MODE_A(OPTION_BYTEWIDTH == 8 ? "PARITY_INDEPENDENT" : "PARITY_INTERLEAVED"), | ||||||
|  | 		.BWE_MODE_B(OPTION_BYTEWIDTH == 8 ? "PARITY_INDEPENDENT" : "PARITY_INTERLEAVED"), | ||||||
|  | 		.EN_AUTO_SLEEP_MODE("FALSE"), | ||||||
|  | 		.IREG_PRE_A("FALSE"), | ||||||
|  | 		.IREG_PRE_B("FALSE"), | ||||||
|  | 		.IS_CLK_INVERTED(!CLK_C_POL), | ||||||
|  | 		.OREG_A("FALSE"), | ||||||
|  | 		.OREG_B("FALSE"), | ||||||
|  | 		.RST_MODE_A(PORT_A_OPTION_RST_MODE), | ||||||
|  | 		.RST_MODE_B(PORT_A_OPTION_RST_MODE), | ||||||
|  | 	) _TECHMAP_REPLACE_ ( | ||||||
|  | 		.ADDR_A({11'b0, PORT_A_ADDR, 1'b0}), | ||||||
|  | 		.BWE_A(PORT_A_WR_BE[WR_BE_WIDTH/2-1:0]), | ||||||
|  | 		.EN_A(PORT_A_CLK_EN), | ||||||
|  | 		.RDB_WR_A(PORT_A_WR_EN), | ||||||
|  | 		.INJECT_DBITERR_A(1'b0), | ||||||
|  | 		.INJECT_SBITERR_A(1'b0), | ||||||
|  | 		.RST_A(PORT_A_OPTION_RST_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), | ||||||
|  | 		.DIN_A(DIN_A), | ||||||
|  | 		.DOUT_A(DOUT_A), | ||||||
|  | 
 | ||||||
|  | 		.ADDR_B({11'b0, PORT_A_ADDR, 1'b1}), | ||||||
|  | 		.BWE_B(PORT_A_WR_BE[WR_BE_WIDTH-1:WR_BE_WIDTH/2]), | ||||||
|  | 		.EN_B(PORT_A_CLK_EN), | ||||||
|  | 		.RDB_WR_B(PORT_A_WR_EN), | ||||||
|  | 		.INJECT_DBITERR_B(1'b0), | ||||||
|  | 		.INJECT_SBITERR_B(1'b0), | ||||||
|  | 		.RST_B(PORT_A_OPTION_RST_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), | ||||||
|  | 		.DIN_B(DIN_B), | ||||||
|  | 		.DOUT_B(DOUT_B), | ||||||
|  | 
 | ||||||
|  | 		.CLK(CLK_C), | ||||||
|  | 		.SLEEP(1'b0) | ||||||
|  | 	); | ||||||
|  | endmodule | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ module priority_memory ( | ||||||
| 	clk, wren_a, rden_a, addr_a, wdata_a, rdata_a, | 	clk, wren_a, rden_a, addr_a, wdata_a, rdata_a, | ||||||
| 	wren_b, rden_b, addr_b, wdata_b, rdata_b | 	wren_b, rden_b, addr_b, wdata_b, rdata_b | ||||||
| 	); | 	); | ||||||
| 	 | 
 | ||||||
| 	parameter ABITS = 12; | 	parameter ABITS = 12; | ||||||
| 	parameter WIDTH = 72; | 	parameter WIDTH = 72; | ||||||
| 
 | 
 | ||||||
|  | @ -30,7 +30,7 @@ module priority_memory ( | ||||||
| 			mem[addr_a] <= wdata_a; | 			mem[addr_a] <= wdata_a; | ||||||
| 		else if (rden_a) | 		else if (rden_a) | ||||||
| 			rdata_a <= mem[addr_a]; | 			rdata_a <= mem[addr_a]; | ||||||
| 		 | 
 | ||||||
| 		// B port
 | 		// B port
 | ||||||
| 		if (wren_b) | 		if (wren_b) | ||||||
| 			mem[addr_b] <= wdata_b; | 			mem[addr_b] <= wdata_b; | ||||||
|  | @ -47,7 +47,7 @@ module priority_memory ( | ||||||
| 			mem[addr_b] <= wdata_b; | 			mem[addr_b] <= wdata_b; | ||||||
| 		else if (rden_b) | 		else if (rden_b) | ||||||
| 			rdata_b <= mem[addr_b]; | 			rdata_b <= mem[addr_b]; | ||||||
| 		 | 
 | ||||||
| 		// B port
 | 		// B port
 | ||||||
| 		if (wren_a) | 		if (wren_a) | ||||||
| 			mem[addr_a] <= wdata_a; | 			mem[addr_a] <= wdata_a; | ||||||
|  | @ -79,12 +79,11 @@ module sp_write_first (clk, wren_a, rden_a, addr_a, wdata_a, rdata_a); | ||||||
| 		rdata_a <= 'h0; | 		rdata_a <= 'h0; | ||||||
| 	end | 	end | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	always @(posedge clk) begin | 	always @(posedge clk) begin | ||||||
| 		// A port
 | 		// A port
 | ||||||
| 		if (wren_a) | 		if (wren_a) | ||||||
| 			mem[addr_a] <= wdata_a; | 			mem[addr_a] <= wdata_a; | ||||||
| 		if (rden_a)  | 		if (rden_a) | ||||||
| 			if (wren_a) | 			if (wren_a) | ||||||
| 				rdata_a <= wdata_a; | 				rdata_a <= wdata_a; | ||||||
| 			else | 			else | ||||||
|  | @ -111,12 +110,39 @@ module sp_read_first (clk, wren_a, rden_a, addr_a, wdata_a, rdata_a); | ||||||
| 		rdata_a <= 'h0; | 		rdata_a <= 'h0; | ||||||
| 	end | 	end | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	always @(posedge clk) begin | 	always @(posedge clk) begin | ||||||
| 		// A port
 | 		// A port
 | ||||||
| 		if (wren_a) | 		if (wren_a) | ||||||
| 			mem[addr_a] <= wdata_a; | 			mem[addr_a] <= wdata_a; | ||||||
| 		if (rden_a)  | 		if (rden_a) | ||||||
| 			rdata_a <= mem[addr_a]; | 			rdata_a <= mem[addr_a]; | ||||||
| 	end | 	end | ||||||
| endmodule | endmodule | ||||||
|  | 
 | ||||||
|  | module sp_read_or_write (clk, wren_a, rden_a, addr_a, wdata_a, rdata_a); | ||||||
|  | 
 | ||||||
|  | 	parameter ABITS = 11; | ||||||
|  | 	parameter WIDTH = 144; | ||||||
|  | 
 | ||||||
|  | 	input clk; | ||||||
|  | 	input wren_a, rden_a; | ||||||
|  | 	input [ABITS-1:0] addr_a; | ||||||
|  | 	input [WIDTH-1:0] wdata_a; | ||||||
|  | 	output reg [WIDTH-1:0] rdata_a; | ||||||
|  | 
 | ||||||
|  | 	(* ram_style = "huge" *) | ||||||
|  | 	reg [WIDTH-1:0] mem [0:2**ABITS-1]; | ||||||
|  | 
 | ||||||
|  | 	integer i; | ||||||
|  | 	initial begin | ||||||
|  | 		rdata_a <= 'h0; | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	always @(posedge clk) begin | ||||||
|  | 		if (wren_a) | ||||||
|  | 			mem[addr_a] <= wdata_a; | ||||||
|  | 		else if (rden_a) | ||||||
|  | 			rdata_a <= mem[addr_a]; | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | endmodule | ||||||
|  |  | ||||||
|  | @ -58,3 +58,13 @@ select -assert-count 1 t:URAM288 | ||||||
| #  see above for details | #  see above for details | ||||||
| select -assert-count 1 t:URAM288 %co:+[DOUT_A] w:rdata_a %i | select -assert-count 1 t:URAM288 %co:+[DOUT_A] w:rdata_a %i | ||||||
| select -assert-none 1 t:URAM288 %co:+[DOUT_B] w:rdata_a %i | select -assert-none 1 t:URAM288 %co:+[DOUT_B] w:rdata_a %i | ||||||
|  | 
 | ||||||
|  | # sp read or write for size 2048 x 144b | ||||||
|  | # the two URAM ports A and B are concatenated, with port A serving LSBs and port B serving MSBs | ||||||
|  | design -reset | ||||||
|  | read_verilog priority_memory.v | ||||||
|  | synth_xilinx -family xcup -top sp_read_or_write -noiopad | ||||||
|  | select -assert-count 1 t:URAM288 | ||||||
|  | # we expect no more than 1 LUT2 to control the hardware enable ports | ||||||
|  | #  see above for details about this command | ||||||
|  | select -assert-max 1 t:LUT* n:*blif* %d | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue