From 08c13f635cb59f701b51a14caf608c503b6eecb1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 6 Jan 2015 23:54:33 +0100 Subject: [PATCH] Xilinx RAMB36/RAMB18 memory_bram support complete --- techlibs/xilinx/brams.txt | 42 +++-- techlibs/xilinx/brams.v | 292 +++++++++++++++++++++++++++++++ techlibs/xilinx/tests/bram1_tb.v | 2 +- 3 files changed, 320 insertions(+), 16 deletions(-) diff --git a/techlibs/xilinx/brams.txt b/techlibs/xilinx/brams.txt index 59af1bc51..46a6ab49e 100644 --- a/techlibs/xilinx/brams.txt +++ b/techlibs/xilinx/brams.txt @@ -101,21 +101,33 @@ match $__XILINX_RAMB18_TDP18 min bits 4096 min efficiency 5 shuffle_enable 2 - # or_next_if_better + or_next_if_better endmatch -# match $__XILINX_RAMB18_TDP9 -# or_next_if_better -# endmatch -# -# match $__XILINX_RAMB18_TDP4 -# or_next_if_better -# endmatch -# -# match $__XILINX_RAMB18_TDP2 -# or_next_if_better -# endmatch -# -# match $__XILINX_RAMB18_TDP1 -# endmatch +match $__XILINX_RAMB18_TDP9 + min bits 4096 + min efficiency 5 + shuffle_enable 2 + or_next_if_better +endmatch + +match $__XILINX_RAMB18_TDP4 + min bits 4096 + min efficiency 5 + shuffle_enable 2 + or_next_if_better +endmatch + +match $__XILINX_RAMB18_TDP2 + min bits 4096 + min efficiency 5 + shuffle_enable 2 + or_next_if_better +endmatch + +match $__XILINX_RAMB18_TDP1 + min bits 4096 + min efficiency 5 + shuffle_enable 2 +endmatch diff --git a/techlibs/xilinx/brams.v b/techlibs/xilinx/brams.v index a2724fe37..cfa598bce 100644 --- a/techlibs/xilinx/brams.v +++ b/techlibs/xilinx/brams.v @@ -231,3 +231,295 @@ module \$__XILINX_RAMB18_TDP18 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN ); endmodule +// ------------------------------------------------------------------------ + +module \$__XILINX_RAMB18_TDP9 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter TRANSP2 = 1; + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + + input CLK2; + input CLK3; + + input [10:0] A1ADDR; + output [8:0] A1DATA; + + input [10:0] B1ADDR; + input [8:0] B1DATA; + input B1EN; + + wire [13:0] A1ADDR_14 = {A1ADDR, 3'b0}; + wire [13:0] B1ADDR_14 = {B1ADDR, 3'b0}; + + wire DIP, DOP; + wire [7:0] DI, DO; + + wire [8:0] A1DATA_BUF; + reg [8:0] B1DATA_Q; + reg transparent_cycle; + + wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; + + generate if (CLKPOL2) + always @(posedge CLK2) begin transparent_cycle <= TRANSP2 && A1ADDR == B1ADDR ? B1EN : 0; B1DATA_Q <= B1DATA; end + else + always @(negedge CLK2) begin transparent_cycle <= TRANSP2 && A1ADDR == B1ADDR ? B1EN : 0; B1DATA_Q <= B1DATA; end + endgenerate + + assign A1DATA = transparent_cycle ? B1DATA_Q : A1DATA_BUF; + + assign A1DATA_BUF = { DOP, DO }; + assign { DIP, DI } = B1DATA; + + RAMB18E1 #( + .RAM_MODE("TDP"), + .READ_WIDTH_A(9), + .READ_WIDTH_B(9), + .WRITE_WIDTH_A(9), + .WRITE_WIDTH_B(9), + .WRITE_MODE_A(TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"), + .WRITE_MODE_B(TRANSP2 ? "WRITE_FIRST" : "READ_FIRST") + ) _TECHMAP_REPLACE_ ( + .DIADI(16'b0), + .DIPADIP(2'b0), + .DOADO(DO[7:0]), + .DOPADOP(DOP), + .ADDRARDADDR(A1ADDR_14), + .CLKARDCLK(CLKPOL2 ? CLK2 : ~CLK2), + .ENARDEN(|1), + .REGCEAREGCE(|1), + .RSTRAMARSTRAM(|0), + .RSTREGARSTREG(|0), + .WEA(2'b0), + + .DIBDI({8'b0, DI}), + .DIPBDIP({1'b0, DIP}), + .ADDRBWRADDR(B1ADDR_14), + .CLKBWRCLK(CLKPOL3 ? CLK3 : ~CLK3), + .ENBWREN(|1), + .REGCEB(|0), + .RSTRAMB(|0), + .RSTREGB(|0), + .WEBWE({3'b00, B1EN}) + ); +endmodule + +// ------------------------------------------------------------------------ + +module \$__XILINX_RAMB18_TDP4 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter TRANSP2 = 1; + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + + input CLK2; + input CLK3; + + input [11:0] A1ADDR; + output [3:0] A1DATA; + + input [11:0] B1ADDR; + input [3:0] B1DATA; + input B1EN; + + wire [13:0] A1ADDR_14 = {A1ADDR, 2'b0}; + wire [13:0] B1ADDR_14 = {B1ADDR, 2'b0}; + + wire DIP, DOP; + wire [7:0] DI, DO; + + wire [3:0] A1DATA_BUF; + reg [3:0] B1DATA_Q; + reg transparent_cycle; + + wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; + + generate if (CLKPOL2) + always @(posedge CLK2) begin transparent_cycle <= TRANSP2 && A1ADDR == B1ADDR ? B1EN : 0; B1DATA_Q <= B1DATA; end + else + always @(negedge CLK2) begin transparent_cycle <= TRANSP2 && A1ADDR == B1ADDR ? B1EN : 0; B1DATA_Q <= B1DATA; end + endgenerate + + assign A1DATA = transparent_cycle ? B1DATA_Q : A1DATA_BUF; + + assign A1DATA_BUF = { DOP, DO }; + assign { DIP, DI } = B1DATA; + + RAMB18E1 #( + .RAM_MODE("TDP"), + .READ_WIDTH_A(4), + .READ_WIDTH_B(4), + .WRITE_WIDTH_A(4), + .WRITE_WIDTH_B(4), + .WRITE_MODE_A(TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"), + .WRITE_MODE_B(TRANSP2 ? "WRITE_FIRST" : "READ_FIRST") + ) _TECHMAP_REPLACE_ ( + .DIADI(16'b0), + .DIPADIP(2'b0), + .DOADO(DO[7:0]), + .DOPADOP(DOP), + .ADDRARDADDR(A1ADDR_14), + .CLKARDCLK(CLKPOL2 ? CLK2 : ~CLK2), + .ENARDEN(|1), + .REGCEAREGCE(|1), + .RSTRAMARSTRAM(|0), + .RSTREGARSTREG(|0), + .WEA(2'b0), + + .DIBDI({8'b0, DI}), + .DIPBDIP({1'b0, DIP}), + .ADDRBWRADDR(B1ADDR_14), + .CLKBWRCLK(CLKPOL3 ? CLK3 : ~CLK3), + .ENBWREN(|1), + .REGCEB(|0), + .RSTRAMB(|0), + .RSTREGB(|0), + .WEBWE({3'b00, B1EN}) + ); +endmodule + +// ------------------------------------------------------------------------ + +module \$__XILINX_RAMB18_TDP2 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter TRANSP2 = 1; + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + + input CLK2; + input CLK3; + + input [12:0] A1ADDR; + output [1:0] A1DATA; + + input [12:0] B1ADDR; + input [1:0] B1DATA; + input B1EN; + + wire [13:0] A1ADDR_14 = {A1ADDR, 1'b0}; + wire [13:0] B1ADDR_14 = {B1ADDR, 1'b0}; + + wire DIP, DOP; + wire [7:0] DI, DO; + + wire [3:0] A1DATA_BUF; + reg [3:0] B1DATA_Q; + reg transparent_cycle; + + wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; + + generate if (CLKPOL2) + always @(posedge CLK2) begin transparent_cycle <= TRANSP2 && A1ADDR == B1ADDR ? B1EN : 0; B1DATA_Q <= B1DATA; end + else + always @(negedge CLK2) begin transparent_cycle <= TRANSP2 && A1ADDR == B1ADDR ? B1EN : 0; B1DATA_Q <= B1DATA; end + endgenerate + + assign A1DATA = transparent_cycle ? B1DATA_Q : A1DATA_BUF; + + assign A1DATA_BUF = { DOP, DO }; + assign { DIP, DI } = B1DATA; + + RAMB18E1 #( + .RAM_MODE("TDP"), + .READ_WIDTH_A(2), + .READ_WIDTH_B(2), + .WRITE_WIDTH_A(2), + .WRITE_WIDTH_B(2), + .WRITE_MODE_A(TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"), + .WRITE_MODE_B(TRANSP2 ? "WRITE_FIRST" : "READ_FIRST") + ) _TECHMAP_REPLACE_ ( + .DIADI(16'b0), + .DIPADIP(2'b0), + .DOADO(DO[7:0]), + .DOPADOP(DOP), + .ADDRARDADDR(A1ADDR_14), + .CLKARDCLK(CLKPOL2 ? CLK2 : ~CLK2), + .ENARDEN(|1), + .REGCEAREGCE(|1), + .RSTRAMARSTRAM(|0), + .RSTREGARSTREG(|0), + .WEA(2'b0), + + .DIBDI({8'b0, DI}), + .DIPBDIP({1'b0, DIP}), + .ADDRBWRADDR(B1ADDR_14), + .CLKBWRCLK(CLKPOL3 ? CLK3 : ~CLK3), + .ENBWREN(|1), + .REGCEB(|0), + .RSTRAMB(|0), + .RSTREGB(|0), + .WEBWE({3'b00, B1EN}) + ); +endmodule + +// ------------------------------------------------------------------------ + +module \$__XILINX_RAMB18_TDP1 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter TRANSP2 = 1; + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + + input CLK2; + input CLK3; + + input [13:0] A1ADDR; + output A1DATA; + + input [13:0] B1ADDR; + input B1DATA; + input B1EN; + + wire [13:0] A1ADDR_14 = A1ADDR; + wire [13:0] B1ADDR_14 = B1ADDR; + + wire DIP, DOP; + wire [7:0] DI, DO; + + wire [3:0] A1DATA_BUF; + reg [3:0] B1DATA_Q; + reg transparent_cycle; + + wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; + + generate if (CLKPOL2) + always @(posedge CLK2) begin transparent_cycle <= TRANSP2 && A1ADDR == B1ADDR ? B1EN : 0; B1DATA_Q <= B1DATA; end + else + always @(negedge CLK2) begin transparent_cycle <= TRANSP2 && A1ADDR == B1ADDR ? B1EN : 0; B1DATA_Q <= B1DATA; end + endgenerate + + assign A1DATA = transparent_cycle ? B1DATA_Q : A1DATA_BUF; + + assign A1DATA_BUF = { DOP, DO }; + assign { DIP, DI } = B1DATA; + + RAMB18E1 #( + .RAM_MODE("TDP"), + .READ_WIDTH_A(1), + .READ_WIDTH_B(1), + .WRITE_WIDTH_A(1), + .WRITE_WIDTH_B(1), + .WRITE_MODE_A(TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"), + .WRITE_MODE_B(TRANSP2 ? "WRITE_FIRST" : "READ_FIRST") + ) _TECHMAP_REPLACE_ ( + .DIADI(16'b0), + .DIPADIP(2'b0), + .DOADO(DO[7:0]), + .DOPADOP(DOP), + .ADDRARDADDR(A1ADDR_14), + .CLKARDCLK(CLKPOL2 ? CLK2 : ~CLK2), + .ENARDEN(|1), + .REGCEAREGCE(|1), + .RSTRAMARSTRAM(|0), + .RSTREGARSTREG(|0), + .WEA(2'b0), + + .DIBDI({8'b0, DI}), + .DIPBDIP({1'b0, DIP}), + .ADDRBWRADDR(B1ADDR_14), + .CLKBWRCLK(CLKPOL3 ? CLK3 : ~CLK3), + .ENBWREN(|1), + .REGCEB(|0), + .RSTRAMB(|0), + .RSTREGB(|0), + .WEBWE({3'b00, B1EN}) + ); +endmodule + diff --git a/techlibs/xilinx/tests/bram1_tb.v b/techlibs/xilinx/tests/bram1_tb.v index ff0929dab..6ed04d4ad 100644 --- a/techlibs/xilinx/tests/bram1_tb.v +++ b/techlibs/xilinx/tests/bram1_tb.v @@ -21,7 +21,7 @@ module bram1_tb #( .RD_DATA(RD_DATA) ); - reg [63:0] xorshift64_state = 64'd88172645463325252; + reg [63:0] xorshift64_state = 64'd88172645463325252 ^ (ABITS << 24) ^ (DBITS << 16) ^ (TRANSP << 8); task xorshift64_next; begin -- 2.30.2