mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	gatemate: Add CC_FIFO_40K simulation model
This commit is contained in:
		
							parent
							
								
									c244a7161b
								
							
						
					
					
						commit
						2004a9ff4a
					
				
					 2 changed files with 387 additions and 67 deletions
				
			
		|  | @ -131,70 +131,3 @@ module CC_USR_RSTN ( | ||||||
| 	output USR_RSTN | 	output USR_RSTN | ||||||
| ); | ); | ||||||
| endmodule | endmodule | ||||||
| 
 |  | ||||||
| (* blackbox *) |  | ||||||
| module CC_FIFO_40K ( |  | ||||||
| 	output A_ECC_1B_ERR, |  | ||||||
| 	output B_ECC_1B_ERR, |  | ||||||
| 	output A_ECC_2B_ERR, |  | ||||||
| 	output B_ECC_2B_ERR, |  | ||||||
| 	// FIFO pop port
 |  | ||||||
| 	output [39:0] A_DO, |  | ||||||
| 	output [39:0] B_DO, |  | ||||||
| 	(* clkbuf_sink *) |  | ||||||
| 	input  A_CLK, |  | ||||||
| 	input  A_EN, |  | ||||||
| 	// FIFO push port
 |  | ||||||
| 	input  [39:0] A_DI, |  | ||||||
| 	input  [39:0] B_DI, |  | ||||||
| 	input  [39:0] A_BM, |  | ||||||
| 	input  [39:0] B_BM, |  | ||||||
| 	(* clkbuf_sink *) |  | ||||||
| 	input  B_CLK, |  | ||||||
| 	input  B_EN, |  | ||||||
| 	input  B_WE, |  | ||||||
| 	// FIFO control
 |  | ||||||
| 	input  F_RST_N, |  | ||||||
| 	input  [12:0] F_ALMOST_FULL_OFFSET, |  | ||||||
| 	input  [12:0] F_ALMOST_EMPTY_OFFSET, |  | ||||||
| 	// FIFO status signals
 |  | ||||||
| 	output F_FULL, |  | ||||||
| 	output F_EMPTY, |  | ||||||
| 	output F_ALMOST_FULL, |  | ||||||
| 	output F_ALMOST_EMPTY, |  | ||||||
| 	output F_RD_ERROR, |  | ||||||
| 	output F_WR_ERROR, |  | ||||||
| 	output [15:0] F_RD_PTR, |  | ||||||
| 	output [15:0] F_WR_PTR |  | ||||||
| ); |  | ||||||
| 	// Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED
 |  | ||||||
| 	parameter LOC = "UNPLACED"; |  | ||||||
| 
 |  | ||||||
| 	// Offset configuration
 |  | ||||||
| 	parameter [12:0] ALMOST_FULL_OFFSET = 12'b0; |  | ||||||
| 	parameter [12:0] ALMOST_EMPTY_OFFSET = 12'b0; |  | ||||||
| 
 |  | ||||||
| 	// Port Widths
 |  | ||||||
| 	parameter A_WIDTH = 0; |  | ||||||
| 	parameter B_WIDTH = 0; |  | ||||||
| 
 |  | ||||||
| 	// RAM and Write Modes
 |  | ||||||
| 	parameter RAM_MODE = "SDP"; // "TPD" or "SDP"
 |  | ||||||
| 	parameter FIFO_MODE = "SYNC"; // "ASYNC" or "SYNC"
 |  | ||||||
| 
 |  | ||||||
| 	// Inverting Control Pins
 |  | ||||||
| 	parameter A_CLK_INV = 1'b0; |  | ||||||
| 	parameter B_CLK_INV = 1'b0; |  | ||||||
| 	parameter A_EN_INV = 1'b0; |  | ||||||
| 	parameter B_EN_INV = 1'b0; |  | ||||||
| 	parameter A_WE_INV = 1'b0; |  | ||||||
| 	parameter B_WE_INV = 1'b0; |  | ||||||
| 
 |  | ||||||
| 	// Output Register
 |  | ||||||
| 	parameter A_DO_REG = 1'b0; |  | ||||||
| 	parameter B_DO_REG = 1'b0; |  | ||||||
| 
 |  | ||||||
| 	// Error Checking and Correction |  | ||||||
| 	parameter A_ECC_EN  = 1'b0; |  | ||||||
| 	parameter B_ECC_EN  = 1'b0; |  | ||||||
| endmodule |  | ||||||
|  |  | ||||||
|  | @ -1410,6 +1410,393 @@ module CC_BRAM_40K ( | ||||||
| 	endgenerate | 	endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | module CC_FIFO_40K ( | ||||||
|  | 	output A_ECC_1B_ERR, | ||||||
|  | 	output B_ECC_1B_ERR, | ||||||
|  | 	output A_ECC_2B_ERR, | ||||||
|  | 	output B_ECC_2B_ERR, | ||||||
|  | 	// FIFO pop port
 | ||||||
|  | 	output [39:0] A_DO, | ||||||
|  | 	output [39:0] B_DO, | ||||||
|  | 	(* clkbuf_sink *) | ||||||
|  | 	input  A_CLK, | ||||||
|  | 	input  A_EN, | ||||||
|  | 	// FIFO push port
 | ||||||
|  | 	input  [39:0] A_DI, | ||||||
|  | 	input  [39:0] B_DI, | ||||||
|  | 	input  [39:0] A_BM, | ||||||
|  | 	input  [39:0] B_BM, | ||||||
|  | 	(* clkbuf_sink *) | ||||||
|  | 	input  B_CLK, | ||||||
|  | 	input  B_EN, | ||||||
|  | 	input  B_WE, | ||||||
|  | 	// FIFO control
 | ||||||
|  | 	input  F_RST_N, | ||||||
|  | 	input  [14:0] F_ALMOST_FULL_OFFSET, | ||||||
|  | 	input  [14:0] F_ALMOST_EMPTY_OFFSET, | ||||||
|  | 	// FIFO status signals
 | ||||||
|  | 	output F_FULL, | ||||||
|  | 	output F_EMPTY, | ||||||
|  | 	output F_ALMOST_FULL, | ||||||
|  | 	output F_ALMOST_EMPTY, | ||||||
|  | 	output F_RD_ERROR, | ||||||
|  | 	output F_WR_ERROR, | ||||||
|  | 	output [15:0] F_RD_PTR, | ||||||
|  | 	output [15:0] F_WR_PTR | ||||||
|  | ); | ||||||
|  | 	// Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED
 | ||||||
|  | 	parameter LOC = "UNPLACED"; | ||||||
|  | 
 | ||||||
|  | 	// Offset configuration
 | ||||||
|  | 	parameter DYN_STAT_SELECT = 1'b0; | ||||||
|  | 	parameter [14:0] ALMOST_FULL_OFFSET = 15'b0; | ||||||
|  | 	parameter [14:0] ALMOST_EMPTY_OFFSET = 15'b0; | ||||||
|  | 
 | ||||||
|  | 	// Port Widths
 | ||||||
|  | 	parameter A_WIDTH = 0; | ||||||
|  | 	parameter B_WIDTH = 0; | ||||||
|  | 
 | ||||||
|  | 	// RAM and Write Modes
 | ||||||
|  | 	parameter RAM_MODE = "TDP"; // "TDP" or "SDP"
 | ||||||
|  | 	parameter FIFO_MODE = "SYNC"; // "ASYNC" or "SYNC"
 | ||||||
|  | 
 | ||||||
|  | 	// Inverting Control Pins
 | ||||||
|  | 	parameter A_CLK_INV = 1'b0; | ||||||
|  | 	parameter B_CLK_INV = 1'b0; | ||||||
|  | 	parameter A_EN_INV = 1'b0; | ||||||
|  | 	parameter B_EN_INV = 1'b0; | ||||||
|  | 	parameter A_WE_INV = 1'b0; | ||||||
|  | 	parameter B_WE_INV = 1'b0; | ||||||
|  | 
 | ||||||
|  | 	// Output Register
 | ||||||
|  | 	parameter A_DO_REG = 1'b0; | ||||||
|  | 	parameter B_DO_REG = 1'b0; | ||||||
|  | 
 | ||||||
|  | 	// Error Checking and Correction
 | ||||||
|  | 	parameter A_ECC_EN  = 1'b0; | ||||||
|  | 	parameter B_ECC_EN  = 1'b0; | ||||||
|  | 
 | ||||||
|  | 	integer i, k; | ||||||
|  | 
 | ||||||
|  | 	// 512 x 80 bit
 | ||||||
|  | 	reg [40959:0] memory = 40960'b0; | ||||||
|  | 
 | ||||||
|  | 	reg [15:0] counter_max; | ||||||
|  | 	reg [15:0] sram_depth; | ||||||
|  | 	localparam tp = (A_WIDTH ==  1) ? 15 : | ||||||
|  | 					(A_WIDTH ==  2) ? 14 : | ||||||
|  | 					(A_WIDTH ==  5) ? 13 : | ||||||
|  | 					(A_WIDTH == 10) ? 12 : | ||||||
|  | 					(A_WIDTH == 20) ? 11 : | ||||||
|  | 					(A_WIDTH == 40) ? 10 : 9; | ||||||
|  | 
 | ||||||
|  | 	initial begin | ||||||
|  | 		// Check parameters
 | ||||||
|  | 		if ((RAM_MODE != "SDP") && (RAM_MODE != "TDP")) begin | ||||||
|  | 			$display("ERROR: Illegal RAM MODE %d.", RAM_MODE); | ||||||
|  | 			$finish(); | ||||||
|  | 		end | ||||||
|  | 		if ((FIFO_MODE != "ASYNC") && (FIFO_MODE != "SYNC")) begin | ||||||
|  | 			$display("ERROR: Illegal FIFO MODE %d.", FIFO_MODE); | ||||||
|  | 			$finish(); | ||||||
|  | 		end | ||||||
|  | 		if ((RAM_MODE == "SDP") && (DYN_STAT_SELECT == 1)) begin | ||||||
|  | 			$display("ERROR: Dynamic offset configuration is not supported in %s mode.", RAM_MODE); | ||||||
|  | 			$finish(); | ||||||
|  | 		end | ||||||
|  | 		if ((RAM_MODE == "SDP") && ((A_WIDTH != 80) || (B_WIDTH != 80))) begin | ||||||
|  | 			$display("ERROR: SDP is ony supported in 80 bit mode."); | ||||||
|  | 			$finish(); | ||||||
|  | 		end | ||||||
|  | 		if ((A_WIDTH == 80) && (RAM_MODE == "TDP")) begin | ||||||
|  | 			$display("ERROR: Port A width of 80 bits is only supported in SDP mode."); | ||||||
|  | 			$finish(); | ||||||
|  | 		end | ||||||
|  | 		if ((B_WIDTH == 80) && (RAM_MODE == "TDP")) begin | ||||||
|  | 			$display("ERROR: Port B width of 80 bits is only supported in SDP mode."); | ||||||
|  | 			$finish(); | ||||||
|  | 		end | ||||||
|  | 		if ((A_WIDTH != 80) && (A_WIDTH != 40) && (A_WIDTH != 20) && (A_WIDTH != 10) && | ||||||
|  | 			(A_WIDTH != 5)  && (A_WIDTH != 2)  && (A_WIDTH != 1) && (A_WIDTH != 0)) begin | ||||||
|  | 			$display("ERROR: Illegal %s Port A width configuration %d.", RAM_MODE, A_WIDTH); | ||||||
|  | 			$finish(); | ||||||
|  | 		end | ||||||
|  | 		if ((B_WIDTH != 80) && (B_WIDTH != 40) && (B_WIDTH != 20) && (B_WIDTH != 10) && | ||||||
|  | 			(B_WIDTH != 5)  && (B_WIDTH != 2)  && (B_WIDTH != 1) && (B_WIDTH != 0)) begin | ||||||
|  | 			$display("ERROR: Illegal %s Port B width configuration %d.", RAM_MODE, B_WIDTH); | ||||||
|  | 			$finish(); | ||||||
|  | 		end | ||||||
|  | 		if (A_WIDTH != B_WIDTH) begin | ||||||
|  | 			$display("ERROR: The values of A_WIDTH and B_WIDTH must be equal."); | ||||||
|  | 		end | ||||||
|  | 		if ((A_ECC_EN == 1'b1) && (RAM_MODE != "SDP") && (A_WIDTH != 40)) begin | ||||||
|  | 			$display("ERROR: Illegal ECC Port A configuration. ECC mode requires TDP >=40 bit or SDP 80 bit, but is %s %d.", RAM_MODE, A_WIDTH); | ||||||
|  | 			$finish(); | ||||||
|  | 		end | ||||||
|  | 		// Set local parameters
 | ||||||
|  | 		if (A_WIDTH == 1) begin // A_WIDTH=B_WIDTH
 | ||||||
|  | 			counter_max = 2 * 32*1024 - 1; | ||||||
|  | 			sram_depth  =     32*1024; | ||||||
|  | 		end | ||||||
|  | 		else if (A_WIDTH == 2) begin | ||||||
|  | 			counter_max = 2 * 16*1024 - 1; | ||||||
|  | 			sram_depth  =     16*1024; | ||||||
|  | 		end | ||||||
|  | 		else if (A_WIDTH == 5) begin | ||||||
|  | 			counter_max = 2 * 8*1024 - 1; | ||||||
|  | 			sram_depth  =     8*1024; | ||||||
|  | 		end | ||||||
|  | 		else if (A_WIDTH == 10) begin | ||||||
|  | 			counter_max = 2 * 4*1024 - 1; | ||||||
|  | 			sram_depth  =     4*1024; | ||||||
|  | 		end | ||||||
|  | 		else if (A_WIDTH == 20) begin | ||||||
|  | 			counter_max = 2 * 2*1024 - 1; | ||||||
|  | 			sram_depth  =     2*1024; | ||||||
|  | 		end | ||||||
|  | 		else if (A_WIDTH == 40) begin | ||||||
|  | 			counter_max = 2 * 1*1024 - 1; | ||||||
|  | 			sram_depth  =     1*1024; | ||||||
|  | 		end | ||||||
|  | 		else begin // 80 bit SDP
 | ||||||
|  | 			counter_max = 2 * 512 - 1; | ||||||
|  | 			sram_depth  =     512; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	// Internal signals
 | ||||||
|  | 	wire fifo_rdclk = A_CLK ^ A_CLK_INV; | ||||||
|  | 	wire fifo_wrclk = (FIFO_MODE == "ASYNC") ? (B_CLK ^ B_CLK_INV) : (A_CLK ^ A_CLK_INV); | ||||||
|  | 	wire [15:0] almost_full_offset  = DYN_STAT_SELECT ? F_ALMOST_FULL_OFFSET  : ALMOST_FULL_OFFSET; | ||||||
|  | 	wire [15:0] almost_empty_offset = DYN_STAT_SELECT ? F_ALMOST_EMPTY_OFFSET : ALMOST_EMPTY_OFFSET; | ||||||
|  | 	reg  [39:0] A_DO_out = 0, A_DO_reg = 0; | ||||||
|  | 	reg  [39:0] B_DO_out = 0, B_DO_reg = 0; | ||||||
|  | 
 | ||||||
|  | 	// Status signals
 | ||||||
|  | 	reg fifo_full; | ||||||
|  | 	reg fifo_empty; | ||||||
|  | 	reg fifo_almost_full; | ||||||
|  | 	reg fifo_almost_empty; | ||||||
|  | 	assign F_FULL         = fifo_full; | ||||||
|  | 	assign F_EMPTY        = fifo_empty; | ||||||
|  | 	assign F_ALMOST_FULL  = fifo_almost_full; | ||||||
|  | 	assign F_ALMOST_EMPTY = fifo_almost_empty; | ||||||
|  | 	assign F_WR_ERROR     = (F_FULL && (B_EN ^ B_EN_INV) && (B_WE ^ B_WE_INV)); | ||||||
|  | 	assign F_RD_ERROR     = (F_EMPTY && (A_EN ^ A_EN_INV)); | ||||||
|  | 	assign ram_we = (~F_FULL  && (B_EN ^ B_EN_INV) && (B_WE ^ B_WE_INV)); | ||||||
|  | 	assign ram_en = (~F_EMPTY && (A_EN ^ A_EN_INV)); | ||||||
|  | 
 | ||||||
|  | 	// Reset synchronizers
 | ||||||
|  | 	reg  [1:0] aclk_reset_q, bclk_reset_q; | ||||||
|  | 	wire fifo_sync_rstn    = aclk_reset_q; | ||||||
|  | 	wire fifo_async_wrrstn = bclk_reset_q; | ||||||
|  | 	wire fifo_async_rdrstn = aclk_reset_q; | ||||||
|  | 
 | ||||||
|  | 	always @(posedge fifo_rdclk or negedge F_RST_N) | ||||||
|  | 	begin | ||||||
|  | 		if (F_RST_N == 1'b0) begin | ||||||
|  | 			aclk_reset_q <= 2'b0; | ||||||
|  | 		end | ||||||
|  | 		else begin | ||||||
|  | 			aclk_reset_q[1] <= aclk_reset_q[0]; | ||||||
|  | 			aclk_reset_q[0] <= 1'b1; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	always @(posedge fifo_wrclk or negedge F_RST_N) | ||||||
|  | 	begin | ||||||
|  | 		if (F_RST_N == 1'b0) begin | ||||||
|  | 			bclk_reset_q <= 2'b0; | ||||||
|  | 		end | ||||||
|  | 		else begin | ||||||
|  | 			bclk_reset_q[1] <= bclk_reset_q[0]; | ||||||
|  | 			bclk_reset_q[0] <= 1'b1; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	// Push/pop pointers
 | ||||||
|  | 	reg  [15:0] rd_pointer, rd_pointer_int; | ||||||
|  | 	reg  [15:0] wr_pointer, wr_pointer_int; | ||||||
|  | 	reg  [15:0] rd_pointer_cmp, wr_pointer_cmp; | ||||||
|  | 	wire [15:0] rd_pointer_nxt; | ||||||
|  | 	wire [15:0] wr_pointer_nxt; | ||||||
|  | 	reg  [15:0] fifo_rdaddr, rdaddr; | ||||||
|  | 	reg  [15:0] fifo_wraddr, wraddr; | ||||||
|  | 	assign F_RD_PTR = fifo_rdaddr; | ||||||
|  | 	assign F_WR_PTR = fifo_wraddr; | ||||||
|  | 
 | ||||||
|  | 	always @(posedge fifo_rdclk or negedge F_RST_N) | ||||||
|  | 	begin | ||||||
|  | 		if (F_RST_N == 1'b0) begin | ||||||
|  | 			rd_pointer <= 0; | ||||||
|  | 			rd_pointer_int <= 0; | ||||||
|  | 		end | ||||||
|  | 		else if (ram_en) begin | ||||||
|  | 			rd_pointer <= rd_pointer_nxt; | ||||||
|  | 			rd_pointer_int <= rd_pointer_nxt[15:1] ^ rd_pointer_nxt[14:0]; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	assign rd_pointer_nxt = (rd_pointer == counter_max) ? (0) : (rd_pointer + 1'b1); | ||||||
|  | 
 | ||||||
|  | 	always @(posedge fifo_wrclk or negedge F_RST_N) | ||||||
|  | 	begin | ||||||
|  | 		if (F_RST_N == 1'b0) begin | ||||||
|  | 			wr_pointer <= 0; | ||||||
|  | 			wr_pointer_int <= 0; | ||||||
|  | 		end | ||||||
|  | 		else if (ram_we) begin | ||||||
|  | 			wr_pointer <= wr_pointer_nxt; | ||||||
|  | 			wr_pointer_int <= wr_pointer_nxt[15:1] ^ wr_pointer_nxt[14:0]; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	assign wr_pointer_nxt = (wr_pointer == counter_max) ? (0) : (wr_pointer + 1'b1); | ||||||
|  | 
 | ||||||
|  | 	// Address synchronizers
 | ||||||
|  | 	reg [15:0] rd_pointer_sync, wr_pointer_sync; | ||||||
|  | 	reg [15:0] rd_pointer_sync_0, rd_pointer_sync_1; | ||||||
|  | 	reg [15:0] wr_pointer_sync_0, wr_pointer_sync_1; | ||||||
|  | 
 | ||||||
|  | 	always @(posedge fifo_rdclk or negedge F_RST_N) | ||||||
|  | 	begin | ||||||
|  | 		if (F_RST_N == 1'b0) begin | ||||||
|  | 			wr_pointer_sync_0 <= 0; | ||||||
|  | 			wr_pointer_sync_1 <= 0; | ||||||
|  | 		end | ||||||
|  | 		else begin | ||||||
|  | 			wr_pointer_sync_0 <= wraddr; | ||||||
|  | 			wr_pointer_sync_1 <= wr_pointer_sync_0; | ||||||
|  | 		end | ||||||
|  | 	 end | ||||||
|  | 
 | ||||||
|  | 	always @(posedge fifo_wrclk or negedge F_RST_N) | ||||||
|  | 	 begin | ||||||
|  | 		if (F_RST_N == 1'b0) begin | ||||||
|  | 			rd_pointer_sync_0 <= 0; | ||||||
|  | 			rd_pointer_sync_1 <= 0; | ||||||
|  | 		end | ||||||
|  | 		else begin | ||||||
|  | 			rd_pointer_sync_0 <= rdaddr; | ||||||
|  | 			rd_pointer_sync_1 <= rd_pointer_sync_0; | ||||||
|  | 		end | ||||||
|  | 	 end | ||||||
|  | 
 | ||||||
|  | 	always @(*) begin | ||||||
|  | 		fifo_wraddr = {wr_pointer[tp-1:0], {(15-tp){1'b0}}}; | ||||||
|  | 		fifo_rdaddr = {rd_pointer[tp-1:0], {(15-tp){1'b0}}}; | ||||||
|  | 
 | ||||||
|  | 		rdaddr = {rd_pointer[tp], rd_pointer_int[tp-1:0]}; | ||||||
|  | 		wraddr = {{(15-tp){1'b0}}, wr_pointer[tp], wr_pointer_int[tp:0]}; | ||||||
|  | 
 | ||||||
|  | 		if (FIFO_MODE == "ASYNC") | ||||||
|  | 			fifo_full = (wraddr[tp-2:0] == rd_pointer_sync_1[tp-2:0] ) && (wraddr[tp] != rd_pointer_sync_1[tp] ) && ( wraddr[tp-1] != rd_pointer_sync_1[tp-1] ); | ||||||
|  | 		else | ||||||
|  | 			fifo_full = (wr_pointer[tp-1:0] == rd_pointer[tp-1:0]) && (wr_pointer[tp] ^ rd_pointer[tp]); | ||||||
|  | 
 | ||||||
|  | 		if (FIFO_MODE == "ASYNC") | ||||||
|  | 			fifo_empty = (wr_pointer_sync_1[tp:0] == rdaddr[tp:0]); | ||||||
|  | 		else | ||||||
|  | 			fifo_empty = (wr_pointer[tp:0] == rd_pointer[tp:0]); | ||||||
|  | 
 | ||||||
|  | 		rd_pointer_cmp = (FIFO_MODE == "ASYNC") ? rd_pointer_sync : rd_pointer; | ||||||
|  | 		if (wr_pointer[tp] == rd_pointer_cmp[tp]) | ||||||
|  | 			fifo_almost_full = ((wr_pointer[tp-1:0] - rd_pointer_cmp[tp-1:0]) >= (sram_depth - almost_full_offset)); | ||||||
|  | 		else | ||||||
|  | 			fifo_almost_full = ((rd_pointer_cmp[tp-1:0] - wr_pointer[tp-1:0]) <= almost_full_offset); | ||||||
|  | 
 | ||||||
|  | 		wr_pointer_cmp = (FIFO_MODE == "ASYNC") ? wr_pointer_sync : wr_pointer; | ||||||
|  | 		if (wr_pointer_cmp[tp] == rd_pointer[tp]) | ||||||
|  | 			fifo_almost_empty = ((wr_pointer_cmp[tp-1:0] - rd_pointer[tp-1:0]) <= almost_empty_offset); | ||||||
|  | 		else | ||||||
|  | 			fifo_almost_empty = ((rd_pointer[tp-1:0] - wr_pointer_cmp[tp-1:0]) >= (sram_depth - almost_empty_offset)); | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	generate | ||||||
|  | 		always @(*) begin | ||||||
|  | 			wr_pointer_sync = 0; | ||||||
|  | 			rd_pointer_sync = 0; | ||||||
|  | 			for (i=tp; i >= 0; i=i-1) begin | ||||||
|  | 				if (i == tp) begin | ||||||
|  | 					wr_pointer_sync[i] = wr_pointer_sync_1[i]; | ||||||
|  | 					rd_pointer_sync[i] = rd_pointer_sync_1[i]; | ||||||
|  | 				end | ||||||
|  | 				else begin | ||||||
|  | 					wr_pointer_sync[i] = wr_pointer_sync_1[i] ^ wr_pointer_sync[i+1]; | ||||||
|  | 					rd_pointer_sync[i] = rd_pointer_sync_1[i] ^ rd_pointer_sync[i+1]; | ||||||
|  | 				end | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 		if (RAM_MODE == "SDP") begin | ||||||
|  | 			// SDP push ports A+B
 | ||||||
|  | 			always @(posedge fifo_wrclk) | ||||||
|  | 			begin | ||||||
|  | 				for (k=0; k < A_WIDTH; k=k+1) begin | ||||||
|  | 					if (k < 40) begin | ||||||
|  | 						if (ram_we && A_BM[k]) memory[fifo_wraddr+k] <= A_DI[k]; | ||||||
|  | 					end | ||||||
|  | 					else begin // use both ports
 | ||||||
|  | 						if (ram_we && B_BM[k-40]) memory[fifo_wraddr+k] <= B_DI[k-40]; | ||||||
|  | 					end | ||||||
|  | 				end | ||||||
|  | 			end | ||||||
|  | 			// SDP pop ports A+B
 | ||||||
|  | 			always @(posedge fifo_rdclk) | ||||||
|  | 			begin | ||||||
|  | 				for (k=0; k < B_WIDTH; k=k+1) begin | ||||||
|  | 					if (k < 40) begin | ||||||
|  | 						if (ram_en) A_DO_out[k] <= memory[fifo_rdaddr+k]; | ||||||
|  | 					end | ||||||
|  | 					else begin // use both ports
 | ||||||
|  | 						if (ram_en) B_DO_out[k-40] <= memory[fifo_rdaddr+k]; | ||||||
|  | 					end | ||||||
|  | 				end | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 		else if (RAM_MODE == "TDP") begin | ||||||
|  | 			// TDP pop port A
 | ||||||
|  | 			always @(posedge fifo_rdclk) | ||||||
|  | 			begin | ||||||
|  | 				for (i=0; i < A_WIDTH; i=i+1) begin | ||||||
|  | 					if (ram_en) begin | ||||||
|  | 						A_DO_out[i] <= memory[fifo_rdaddr+i]; | ||||||
|  | 					end | ||||||
|  | 				end | ||||||
|  | 			end | ||||||
|  | 			// TDP push port B
 | ||||||
|  | 			always @(posedge fifo_wrclk) | ||||||
|  | 			begin | ||||||
|  | 				for (i=0; i < B_WIDTH; i=i+1) begin | ||||||
|  | 					if (ram_we && B_BM[i]) | ||||||
|  | 						memory[fifo_wraddr+i] <= B_DI[i]; | ||||||
|  | 				end | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 	endgenerate | ||||||
|  | 
 | ||||||
|  | 	// Optional output register
 | ||||||
|  | 	generate | ||||||
|  | 		if (A_DO_REG) begin | ||||||
|  | 			always @(posedge fifo_rdclk) begin | ||||||
|  | 				A_DO_reg <= A_DO_out; | ||||||
|  | 			end | ||||||
|  | 			assign A_DO = A_DO_reg; | ||||||
|  | 		end | ||||||
|  | 		else begin | ||||||
|  | 			assign A_DO = A_DO_out; | ||||||
|  | 		end | ||||||
|  | 		if (B_DO_REG) begin | ||||||
|  | 			always @(posedge fifo_rdclk) begin | ||||||
|  | 				B_DO_reg <= B_DO_out; | ||||||
|  | 			end | ||||||
|  | 			assign B_DO = B_DO_reg; | ||||||
|  | 		end | ||||||
|  | 		else begin | ||||||
|  | 			assign B_DO = B_DO_out; | ||||||
|  | 		end | ||||||
|  | 	endgenerate | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
| // Models of the LUT2 tree primitives
 | // Models of the LUT2 tree primitives
 | ||||||
| module CC_L2T4( | module CC_L2T4( | ||||||
| 	output O, | 	output O, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue