mirror of
https://github.com/YosysHQ/yosys
synced 2025-07-25 13:47:02 +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