BRAM optimizations

This commit is contained in:
tinebp 2025-01-11 03:18:11 -08:00
parent 43d33b942e
commit 84b1c8a43c
5 changed files with 114 additions and 230 deletions

View file

@ -53,7 +53,8 @@ module VX_fetch import VX_gpu_pkg::*; #(
VX_dp_ram #( VX_dp_ram #(
.DATAW (`PC_BITS + `NUM_THREADS), .DATAW (`PC_BITS + `NUM_THREADS),
.SIZE (`NUM_WARPS), .SIZE (`NUM_WARPS),
.RDW_MODE ("R") .RDW_MODE ("R"),
.LUTRAM (1)
) tag_store ( ) tag_store (
.clk (clk), .clk (clk),
.reset (reset), .reset (reset),

View file

@ -270,7 +270,7 @@ module VX_operands import VX_gpu_pkg::*; #(
.RESET_RAM (1), .RESET_RAM (1),
`endif `endif
.OUT_REG (1), .OUT_REG (1),
.RDW_MODE ("U") .RDW_MODE ("R")
) gpr_ram ( ) gpr_ram (
.clk (clk), .clk (clk),
.reset (reset), .reset (reset),

View file

@ -13,6 +13,10 @@
`include "VX_platform.vh" `include "VX_platform.vh"
`ifdef VIVADO
`define ASYNC_BRAM_PATCH
`endif
`define RAM_INITIALIZATION \ `define RAM_INITIALIZATION \
if (INIT_ENABLE != 0) begin : g_init \ if (INIT_ENABLE != 0) begin : g_init \
if (INIT_FILE != "") begin : g_file \ if (INIT_FILE != "") begin : g_file \
@ -49,8 +53,9 @@ module VX_dp_ram #(
parameter WRENW = 1, parameter WRENW = 1,
parameter OUT_REG = 0, parameter OUT_REG = 0,
parameter LUTRAM = 0, parameter LUTRAM = 0,
parameter `STRING RDW_MODE = "W", // W: write-first, R: read-first, U: undefined parameter `STRING RDW_MODE = "W", // W: write-first, R: read-first
parameter RADDR_REG = 0, // read address registered hint parameter RADDR_REG = 0, // read address registered hint
parameter RADDR_RESET = 0, // read address has reset
parameter RDW_ASSERT = 0, parameter RDW_ASSERT = 0,
parameter RESET_RAM = 0, parameter RESET_RAM = 0,
parameter INIT_ENABLE = 0, parameter INIT_ENABLE = 0,
@ -71,13 +76,14 @@ module VX_dp_ram #(
localparam WSELW = DATAW / WRENW; localparam WSELW = DATAW / WRENW;
`UNUSED_PARAM (LUTRAM) `UNUSED_PARAM (LUTRAM)
`UNUSED_PARAM (RADDR_REG) `UNUSED_PARAM (RADDR_REG)
`UNUSED_PARAM (RADDR_RESET)
`STATIC_ASSERT(!(WRENW * WSELW != DATAW), ("invalid parameter")) `STATIC_ASSERT(!(WRENW * WSELW != DATAW), ("invalid parameter"))
`STATIC_ASSERT((RDW_MODE == "R" || RDW_MODE == "W" || RDW_MODE == "U"), ("invalid parameter")) `STATIC_ASSERT((RDW_MODE == "R" || RDW_MODE == "W"), ("invalid parameter"))
`UNUSED_PARAM (RDW_ASSERT) `UNUSED_PARAM (RDW_ASSERT)
`ifdef SYNTHESIS `ifdef SYNTHESIS
localparam FORCE_BRAM = !LUTRAM && (SIZE * DATAW >= `MAX_LUTRAM); localparam FORCE_BRAM = !LUTRAM && `FORCE_BRAM(SIZE, DATAW);
if (OUT_REG) begin : g_sync if (OUT_REG) begin : g_sync
if (FORCE_BRAM) begin : g_bram if (FORCE_BRAM) begin : g_bram
if (RDW_MODE == "W") begin : g_write_first if (RDW_MODE == "W") begin : g_write_first
@ -86,10 +92,10 @@ module VX_dp_ram #(
`RAM_INITIALIZATION `RAM_INITIALIZATION
reg [ADDRW-1:0] raddr_r; reg [ADDRW-1:0] raddr_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (write) begin
if (write) begin `RAM_WRITE_WREN
`RAM_WRITE_WREN end
end if (read) begin
raddr_r <= raddr; raddr_r <= raddr;
end end
end end
@ -99,44 +105,16 @@ module VX_dp_ram #(
`RAM_INITIALIZATION `RAM_INITIALIZATION
reg [ADDRW-1:0] raddr_r; reg [ADDRW-1:0] raddr_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (write) begin
if (write) begin ram[waddr] <= wdata;
ram[waddr] <= wdata; end
end if (read) begin
raddr_r <= raddr; raddr_r <= raddr;
end end
end end
assign rdata = ram[raddr_r]; assign rdata = ram[raddr_r];
end end
end else if (RDW_MODE == "R") begin : g_read_first end else if (RDW_MODE == "R") begin : g_read_first
if (WRENW != 1) begin : g_wren
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
`RAM_WRITE_WREN
end
rdata_r <= ram[raddr];
end
end
assign rdata = rdata_r;
end else begin : g_no_wren
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
ram[waddr] <= wdata;
end
rdata_r <= ram[raddr];
end
end
assign rdata = rdata_r;
end
end else if (RDW_MODE == "U") begin : g_undefined
if (WRENW != 1) begin : g_wren if (WRENW != 1) begin : g_wren
`USE_BLOCK_BRAM `RAM_ARRAY_WREN `USE_BLOCK_BRAM `RAM_ARRAY_WREN
`RAM_INITIALIZATION `RAM_INITIALIZATION
@ -172,10 +150,10 @@ module VX_dp_ram #(
`RAM_INITIALIZATION `RAM_INITIALIZATION
reg [ADDRW-1:0] raddr_r; reg [ADDRW-1:0] raddr_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (write) begin
if (write) begin `RAM_WRITE_WREN
`RAM_WRITE_WREN end
end if (read) begin
raddr_r <= raddr; raddr_r <= raddr;
end end
end end
@ -185,44 +163,16 @@ module VX_dp_ram #(
`RAM_INITIALIZATION `RAM_INITIALIZATION
reg [ADDRW-1:0] raddr_r; reg [ADDRW-1:0] raddr_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (write) begin
if (write) begin ram[waddr] <= wdata;
ram[waddr] <= wdata; end
end if (read) begin
raddr_r <= raddr; raddr_r <= raddr;
end end
end end
assign rdata = ram[raddr_r]; assign rdata = ram[raddr_r];
end end
end else if (RDW_MODE == "R") begin : g_read_first end else if (RDW_MODE == "R") begin : g_read_first
if (WRENW != 1) begin : g_wren
`RAM_ARRAY_WREN
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
`RAM_WRITE_WREN
end
rdata_r <= ram[raddr];
end
end
assign rdata = rdata_r;
end else begin : g_no_wren
reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
ram[waddr] <= wdata;
end
rdata_r <= ram[raddr];
end
end
assign rdata = rdata_r;
end
end else if (RDW_MODE == "U") begin : g_undefined
if (WRENW != 1) begin : g_wren if (WRENW != 1) begin : g_wren
`RAM_ARRAY_WREN `RAM_ARRAY_WREN
`RAM_INITIALIZATION `RAM_INITIALIZATION
@ -255,7 +205,7 @@ module VX_dp_ram #(
end else begin : g_async end else begin : g_async
`UNUSED_VAR (read) `UNUSED_VAR (read)
if (FORCE_BRAM) begin : g_bram if (FORCE_BRAM) begin : g_bram
`ifdef VIVADO `ifdef ASYNC_BRAM_PATCH
VX_async_ram_patch #( VX_async_ram_patch #(
.DATAW (DATAW), .DATAW (DATAW),
.SIZE (SIZE), .SIZE (SIZE),
@ -263,6 +213,7 @@ module VX_dp_ram #(
.DUAL_PORT (1), .DUAL_PORT (1),
.FORCE_BRAM (FORCE_BRAM), .FORCE_BRAM (FORCE_BRAM),
.RADDR_REG (RADDR_REG), .RADDR_REG (RADDR_REG),
.RADDR_RESET(RADDR_RESET),
.WRITE_FIRST(RDW_MODE == "W"), .WRITE_FIRST(RDW_MODE == "W"),
.INIT_ENABLE(INIT_ENABLE), .INIT_ENABLE(INIT_ENABLE),
.INIT_FILE (INIT_FILE), .INIT_FILE (INIT_FILE),
@ -388,20 +339,12 @@ module VX_dp_ram #(
if (RDW_MODE == "W") begin : g_write_first if (RDW_MODE == "W") begin : g_write_first
reg [ADDRW-1:0] raddr_r; reg [ADDRW-1:0] raddr_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (read) begin
raddr_r <= raddr; raddr_r <= raddr;
end end
end end
assign rdata = ram[raddr_r]; assign rdata = ram[raddr_r];
end else if (RDW_MODE == "R") begin : g_read_first end else if (RDW_MODE == "R") begin : g_read_first
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
rdata_r <= ram[raddr];
end
end
assign rdata = rdata_r;
end else begin : g_undefined
reg [DATAW-1:0] rdata_r; reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read) begin if (read) begin

View file

@ -95,7 +95,8 @@ module VX_fifo_queue #(
.SIZE (DEPTH), .SIZE (DEPTH),
.LUTRAM (LUTRAM), .LUTRAM (LUTRAM),
.RDW_MODE ("W"), .RDW_MODE ("W"),
.RADDR_REG (1) .RADDR_REG (1),
.RADDR_RESET (1)
) dp_ram ( ) dp_ram (
.clk (clk), .clk (clk),
.reset (reset), .reset (reset),

View file

@ -13,6 +13,10 @@
`include "VX_platform.vh" `include "VX_platform.vh"
`ifdef VIVADO
`define ASYNC_BRAM_PATCH
`endif
`define RAM_INITIALIZATION \ `define RAM_INITIALIZATION \
if (INIT_ENABLE != 0) begin : g_init \ if (INIT_ENABLE != 0) begin : g_init \
if (INIT_FILE != "") begin : g_file \ if (INIT_FILE != "") begin : g_file \
@ -49,8 +53,9 @@ module VX_sp_ram #(
parameter WRENW = 1, parameter WRENW = 1,
parameter OUT_REG = 0, parameter OUT_REG = 0,
parameter LUTRAM = 0, parameter LUTRAM = 0,
parameter `STRING RDW_MODE = "W", // W: write-first, R: read-first, N: no-change, U: undefined parameter `STRING RDW_MODE = "W", // W: write-first, R: read-first, N: no-change
parameter RADDR_REG = 0, // read address registered hint parameter RADDR_REG = 0, // read address registered hint
parameter RADDR_RESET = 0, // read address has reset
parameter RDW_ASSERT = 0, parameter RDW_ASSERT = 0,
parameter RESET_RAM = 0, parameter RESET_RAM = 0,
parameter INIT_ENABLE = 0, parameter INIT_ENABLE = 0,
@ -70,13 +75,14 @@ module VX_sp_ram #(
localparam WSELW = DATAW / WRENW; localparam WSELW = DATAW / WRENW;
`UNUSED_PARAM (LUTRAM) `UNUSED_PARAM (LUTRAM)
`UNUSED_PARAM (RADDR_REG) `UNUSED_PARAM (RADDR_REG)
`UNUSED_PARAM (RADDR_RESET)
`STATIC_ASSERT(!(WRENW * WSELW != DATAW), ("invalid parameter")) `STATIC_ASSERT(!(WRENW * WSELW != DATAW), ("invalid parameter"))
`STATIC_ASSERT((RDW_MODE == "R" || RDW_MODE == "W" || RDW_MODE == "N" || RDW_MODE == "U"), ("invalid parameter")) `STATIC_ASSERT((RDW_MODE == "R" || RDW_MODE == "W" || RDW_MODE == "N"), ("invalid parameter"))
`UNUSED_PARAM (RDW_ASSERT) `UNUSED_PARAM (RDW_ASSERT)
`ifdef SYNTHESIS `ifdef SYNTHESIS
localparam FORCE_BRAM = !LUTRAM && (SIZE * DATAW >= `MAX_LUTRAM); localparam FORCE_BRAM = !LUTRAM && `FORCE_BRAM(SIZE, DATAW);
if (OUT_REG) begin : g_sync if (OUT_REG) begin : g_sync
if (FORCE_BRAM) begin : g_bram if (FORCE_BRAM) begin : g_bram
if (RDW_MODE == "W") begin : g_write_first if (RDW_MODE == "W") begin : g_write_first
@ -85,10 +91,10 @@ module VX_sp_ram #(
`RAM_INITIALIZATION `RAM_INITIALIZATION
reg [ADDRW-1:0] addr_r; reg [ADDRW-1:0] addr_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (write) begin
if (write) begin `RAM_WRITE_WREN
`RAM_WRITE_WREN end
end if (read) begin
addr_r <= addr; addr_r <= addr;
end end
end end
@ -98,9 +104,11 @@ module VX_sp_ram #(
`RAM_INITIALIZATION `RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r; reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (write) begin
ram[addr] <= wdata;
end
if (read) begin
if (write) begin if (write) begin
ram[addr] <= wdata;
rdata_r <= wdata; rdata_r <= wdata;
end else begin end else begin
rdata_r <= ram[addr]; rdata_r <= ram[addr];
@ -110,64 +118,6 @@ module VX_sp_ram #(
assign rdata = rdata_r; assign rdata = rdata_r;
end end
end else if (RDW_MODE == "R") begin : g_read_first end else if (RDW_MODE == "R") begin : g_read_first
if (WRENW != 1) begin : g_wren
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
`RAM_WRITE_WREN
end
rdata_r <= ram[addr];
end
end
assign rdata = rdata_r;
end else begin : g_no_wren
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
ram[addr] <= wdata;
end
rdata_r <= ram[addr];
end
end
assign rdata = rdata_r;
end
end else if (RDW_MODE == "N") begin : g_no_change
if (WRENW != 1) begin : g_wren
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
`RAM_WRITE_WREN
end else begin
rdata_r <= ram[addr];
end
end
end
assign rdata = rdata_r;
end else begin : g_no_wren
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
ram[addr] <= wdata;
end else begin
rdata_r <= ram[addr];
end
end
end
assign rdata = rdata_r;
end
end else if (RDW_MODE == "U") begin : g_undefined
if (WRENW != 1) begin : g_wren if (WRENW != 1) begin : g_wren
`USE_BLOCK_BRAM `RAM_ARRAY_WREN `USE_BLOCK_BRAM `RAM_ARRAY_WREN
`RAM_INITIALIZATION `RAM_INITIALIZATION
@ -195,6 +145,32 @@ module VX_sp_ram #(
end end
assign rdata = rdata_r; assign rdata = rdata_r;
end end
end else if (RDW_MODE == "N") begin : g_no_change
if (WRENW != 1) begin : g_wren
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (write) begin
`RAM_WRITE_WREN
end else if (read) begin
rdata_r <= ram[addr];
end
end
assign rdata = rdata_r;
end else begin : g_no_wren
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (write) begin
ram[addr] <= wdata;
end else if (read) begin
rdata_r <= ram[addr];
end
end
assign rdata = rdata_r;
end
end end
end else begin : g_auto end else begin : g_auto
if (RDW_MODE == "W") begin : g_write_first if (RDW_MODE == "W") begin : g_write_first
@ -203,10 +179,10 @@ module VX_sp_ram #(
`RAM_INITIALIZATION `RAM_INITIALIZATION
reg [ADDRW-1:0] addr_r; reg [ADDRW-1:0] addr_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (write) begin
if (write) begin `RAM_WRITE_WREN
`RAM_WRITE_WREN end
end if (read) begin
addr_r <= addr; addr_r <= addr;
end end
end end
@ -216,9 +192,11 @@ module VX_sp_ram #(
`RAM_INITIALIZATION `RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r; reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (write) begin
ram[addr] <= wdata;
end
if (read) begin
if (write) begin if (write) begin
ram[addr] <= wdata;
rdata_r <= wdata; rdata_r <= wdata;
end else begin end else begin
rdata_r <= ram[addr]; rdata_r <= ram[addr];
@ -228,64 +206,6 @@ module VX_sp_ram #(
assign rdata = rdata_r; assign rdata = rdata_r;
end end
end else if (RDW_MODE == "R") begin : g_read_first end else if (RDW_MODE == "R") begin : g_read_first
if (WRENW != 1) begin : g_wren
`RAM_ARRAY_WREN
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
`RAM_WRITE_WREN
end
rdata_r <= ram[addr];
end
end
assign rdata = rdata_r;
end else begin : g_no_wren
reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
ram[addr] <= wdata;
end
rdata_r <= ram[addr];
end
end
assign rdata = rdata_r;
end
end else if (RDW_MODE == "N") begin : g_no_change
if (WRENW != 1) begin : g_wren
`RAM_ARRAY_WREN
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
`RAM_WRITE_WREN
end else begin
rdata_r <= ram[addr];
end
end
end
assign rdata = rdata_r;
end else begin : g_no_wren
reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read || write) begin
if (write) begin
ram[addr] <= wdata;
end else begin
rdata_r <= ram[addr];
end
end
end
assign rdata = rdata_r;
end
end else if (RDW_MODE == "U") begin : g_undefined
if (WRENW != 1) begin : g_wren if (WRENW != 1) begin : g_wren
`RAM_ARRAY_WREN `RAM_ARRAY_WREN
`RAM_INITIALIZATION `RAM_INITIALIZATION
@ -313,12 +233,38 @@ module VX_sp_ram #(
end end
assign rdata = rdata_r; assign rdata = rdata_r;
end end
end else if (RDW_MODE == "N") begin : g_no_change
if (WRENW != 1) begin : g_wren
`RAM_ARRAY_WREN
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (write) begin
`RAM_WRITE_WREN
end else if (read) begin
rdata_r <= ram[addr];
end
end
assign rdata = rdata_r;
end else begin : g_no_wren
reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (write) begin
ram[addr] <= wdata;
end else if (read) begin
rdata_r <= ram[addr];
end
end
assign rdata = rdata_r;
end
end end
end end
end else begin : g_async end else begin : g_async
`UNUSED_VAR (read) `UNUSED_VAR (read)
if (FORCE_BRAM) begin : g_bram if (FORCE_BRAM) begin : g_bram
`ifdef VIVADO `ifdef ASYNC_BRAM_PATCH
VX_async_ram_patch #( VX_async_ram_patch #(
.DATAW (DATAW), .DATAW (DATAW),
.SIZE (SIZE), .SIZE (SIZE),
@ -326,6 +272,7 @@ module VX_sp_ram #(
.DUAL_PORT (0), .DUAL_PORT (0),
.FORCE_BRAM (FORCE_BRAM), .FORCE_BRAM (FORCE_BRAM),
.RADDR_REG (RADDR_REG), .RADDR_REG (RADDR_REG),
.RADDR_RESET(RADDR_RESET),
.WRITE_FIRST(RDW_MODE == "W"), .WRITE_FIRST(RDW_MODE == "W"),
.INIT_ENABLE(INIT_ENABLE), .INIT_ENABLE(INIT_ENABLE),
.INIT_FILE (INIT_FILE), .INIT_FILE (INIT_FILE),
@ -451,7 +398,7 @@ module VX_sp_ram #(
if (RDW_MODE == "W") begin : g_write_first if (RDW_MODE == "W") begin : g_write_first
reg [ADDRW-1:0] addr_r; reg [ADDRW-1:0] addr_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (read) begin
addr_r <= addr; addr_r <= addr;
end end
end end
@ -459,7 +406,7 @@ module VX_sp_ram #(
end else if (RDW_MODE == "R") begin : g_read_first end else if (RDW_MODE == "R") begin : g_read_first
reg [DATAW-1:0] rdata_r; reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin always @(posedge clk) begin
if (read || write) begin if (read) begin
rdata_r <= ram[addr]; rdata_r <= ram[addr];
end end
end end
@ -472,14 +419,6 @@ module VX_sp_ram #(
end end
end end
assign rdata = rdata_r; assign rdata = rdata_r;
end else if (RDW_MODE == "U") begin : g_unknown
reg [DATAW-1:0] rdata_r;
always @(posedge clk) begin
if (read) begin
rdata_r <= ram[addr];
end
end
assign rdata = rdata_r;
end end
end else begin : g_async end else begin : g_async
`UNUSED_VAR (read) `UNUSED_VAR (read)