From a6750b375301f2c2ebb51a2496cdf2c820b2546b Mon Sep 17 00:00:00 2001
From: Clifford Wolf <clifford@clifford.at>
Date: Mon, 3 Feb 2014 13:01:45 +0100
Subject: Added TRANSPARENT parameter to $memrd (and RD_TRANSPARENT to $mem)

---
 techlibs/common/simlib.v | 60 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 47 insertions(+), 13 deletions(-)

(limited to 'techlibs/common')

diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v
index c0c564fc7..87e83bd15 100644
--- a/techlibs/common/simlib.v
+++ b/techlibs/common/simlib.v
@@ -1220,6 +1220,7 @@ parameter WIDTH = 8;
 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;
@@ -1242,37 +1243,70 @@ generate
 	for (i = 0; i < RD_PORTS; i = i+1) begin:rd
 		if (RD_CLK_ENABLE[i] == 0) begin:rd_noclk
 			always @(RD_ADDR or update_async_rd)
-				RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ];
+				RD_DATA[ i*WIDTH +: WIDTH ] <= data[ RD_ADDR[ i*ABITS +: ABITS ] - OFFSET ];
 		end else
-		if (RD_CLK_POLARITY[i] == 1) begin:rd_posclk
-			always @(posedge RD_CLK[i])
-				RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ];
-		end else begin:rd_negclk
-			always @(negedge RD_CLK[i])
-				RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ];
+		if (RD_TRANSPARENT[i] == 1) begin:rd_transparent
+			reg [ABITS-1:0] addr_buf;
+			if (RD_CLK_POLARITY[i] == 1) begin:rd_trans_posclk
+				always @(posedge RD_CLK[i])
+					addr_buf <= RD_ADDR[ i*ABITS +: ABITS ];
+			end else begin:rd_trans_negclk
+				always @(negedge RD_CLK[i])
+					addr_buf <= RD_ADDR[ i*ABITS +: ABITS ];
+			end
+			always @(addr_buf or update_async_rd)
+				RD_DATA[ i*WIDTH +: WIDTH ] <= data[ addr_buf - OFFSET ];
+		end else begin:rd_notransparent
+			if (RD_CLK_POLARITY[i] == 1) begin:rd_notrans_posclk
+				always @(posedge RD_CLK[i])
+					RD_DATA[ i*WIDTH +: WIDTH ] <= data[ RD_ADDR[ i*ABITS +: ABITS ] - OFFSET ];
+			end else begin:rd_notrans_negclk
+				always @(negedge RD_CLK[i])
+					RD_DATA[ i*WIDTH +: WIDTH ] <= data[ RD_ADDR[ i*ABITS +: ABITS ] - OFFSET ];
+			end
 		end
 	end
 
 	for (i = 0; i < WR_PORTS; i = i+1) begin:wr
+		integer k;
+		reg found_collision;
 		if (WR_CLK_ENABLE[i] == 0) begin:wr_noclk
 			always @(WR_ADDR or WR_DATA or WR_EN) begin
 				if (WR_EN[i]) begin
-					data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ];
-					update_async_rd <= 1; update_async_rd <= 0;
+					found_collision = 0;
+					for (k = i+1; k < WR_PORTS; k = k+1)
+						if (WR_EN[k] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ])
+							found_collision = 1;
+					if (!found_collision) begin
+						data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ] <= WR_DATA[ i*WIDTH +: WIDTH ];
+						update_async_rd <= 1; update_async_rd <= 0;
+					end
 				end
 			end
 		end else
 		if (WR_CLK_POLARITY[i] == 1) begin:rd_posclk
 			always @(posedge WR_CLK[i])
 				if (WR_EN[i]) begin
-					data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ];
-					update_async_rd <= 1; update_async_rd <= 0;
+					found_collision = 0;
+					for (k = i+1; k < WR_PORTS; k = k+1)
+						if (WR_EN[k] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ])
+							found_collision = 1;
+					if (!found_collision) begin
+						data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ] <= WR_DATA[ i*WIDTH +: WIDTH ];
+						update_async_rd <= 1; update_async_rd <= 0;
+					end
 				end
 		end else begin:rd_negclk
 			always @(negedge WR_CLK[i])
 				if (WR_EN[i]) begin
-					data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ];
-					update_async_rd <= 1; update_async_rd <= 0;
+					found_collision = 0;
+					for (k = i+1; k < WR_PORTS; k = k+1)
+						if (WR_EN[k] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ])
+							found_collision = 1;
+					if (!found_collision) begin
+						data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ] <= WR_DATA[ i*WIDTH +: WIDTH ];
+						update_async_rd <= 1; update_async_rd <= 0;
+					end
 				end
 		end
 	end
-- 
cgit v1.2.3