From e7429439f31909aa9dc9d72121bf6179268ec16e Mon Sep 17 00:00:00 2001 From: Martim Esteves Date: Sat, 7 Sep 2024 01:19:37 +0100 Subject: [PATCH] modules iob_ram_t2ps generated with py2hwsw --- .../iob_ram_t2p/hardware/src/iob_ram_t2p.v | 51 ------ .../memories/ram/iob_ram_t2p/iob_ram_t2p.py | 121 +++++++++++- .../hardware/src/iob_ram_t2p_be.v | 76 -------- .../ram/iob_ram_t2p_be/iob_ram_t2p_be.py | 156 +++++++++++++++- .../hardware/src/iob_ram_t2p_tiled.v | 98 ---------- .../iob_ram_t2p_tiled/iob_ram_t2p_tiled.py | 172 +++++++++++++++++- 6 files changed, 445 insertions(+), 229 deletions(-) delete mode 100644 lib/hardware/memories/ram/iob_ram_t2p/hardware/src/iob_ram_t2p.v delete mode 100644 lib/hardware/memories/ram/iob_ram_t2p_be/hardware/src/iob_ram_t2p_be.v delete mode 100644 lib/hardware/memories/ram/iob_ram_t2p_tiled/hardware/src/iob_ram_t2p_tiled.v diff --git a/lib/hardware/memories/ram/iob_ram_t2p/hardware/src/iob_ram_t2p.v b/lib/hardware/memories/ram/iob_ram_t2p/hardware/src/iob_ram_t2p.v deleted file mode 100644 index 06796f53b..000000000 --- a/lib/hardware/memories/ram/iob_ram_t2p/hardware/src/iob_ram_t2p.v +++ /dev/null @@ -1,51 +0,0 @@ -`timescale 1ns / 1ps - -module iob_ram_t2p #( - parameter HEXFILE = "none", - parameter DATA_W = 0, - parameter ADDR_W = 0 -) ( - input clk_i, - - //write port - input w_en_i, - input [ADDR_W-1:0] w_addr_i, - input [DATA_W-1:0] w_data_i, - - //read port - input r_en_i, - input [ADDR_W-1:0] r_addr_i, - output [DATA_W-1:0] r_data_o -); - - //this allows ISE 14.7 to work; do not remove - localparam MEM_INIT_FILE_INT = HEXFILE; - - // Declare the RAM - reg [DATA_W-1:0] mem [(2**ADDR_W)-1:0]; - - reg [DATA_W-1:0] r_data; - // Initialize the RAM - initial begin - if (MEM_INIT_FILE_INT != "none") begin - $readmemh(MEM_INIT_FILE_INT, mem, 0, (2 ** ADDR_W) - 1); - end - end - - //read port - always @(posedge clk_i) begin - if (r_en_i) begin - r_data <= mem[r_addr_i]; - end - end - - //write port - always @(posedge clk_i) begin - if (w_en_i) begin - mem[w_addr_i] <= w_data_i; - end - end - - assign r_data_o = r_data; - -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_t2p/iob_ram_t2p.py b/lib/hardware/memories/ram/iob_ram_t2p/iob_ram_t2p.py index e7c593cad..4db1fd983 100644 --- a/lib/hardware/memories/ram/iob_ram_t2p/iob_ram_t2p.py +++ b/lib/hardware/memories/ram/iob_ram_t2p/iob_ram_t2p.py @@ -3,7 +3,126 @@ def setup(py_params_dict): "original_name": "iob_ram_t2p", "name": "iob_ram_t2p", "version": "0.1", - "generate_hw": False, + "confs": [ + { + "name": "HEXFILE", + "type": "P", + "val": '"none"', + "min": "NA", + "max": "NA", + "descr": "Name of file to load into RAM", + }, + { + "name": "ADDR_W", + "type": "P", + "val": "0", + "min": "0", + "max": "NA", + "descr": "Address bus width", + }, + { + "name": "DATA_W", + "type": "P", + "val": "0", + "min": "0", + "max": "NA", + "descr": "Data bus width", + }, + { + "name": "MEM_INIT_FILE_INT", + "type": "F", + "val": "HEXFILE", + "min": "0", + "max": "NA", + "descr": "", + }, + ], + "ports": [ + { + "name": "clk", + "descr": "Clock", + "signals": [ + {"name": "clk", "width": 1, "direction": "input"}, + ], + }, + { + "name": "w_en_i", + "descr": "Input port", + "signals": [ + {"name": "w_en", "width": 1, "direction": "input"}, + ], + }, + { + "name": "w_addr_i", + "descr": "Input port", + "signals": [ + {"name": "w_addr", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "w_data_i", + "descr": "Input port", + "signals": [ + {"name": "w_data", "width": "DATA_W", "direction": "input"}, + ], + }, + { + "name": "r_en_i", + "descr": "Input port", + "signals": [ + {"name": "r_en", "width": 1, "direction": "input"}, + ], + }, + { + "name": "r_addr_i", + "descr": "Input port", + "signals": [ + {"name": "r_addr", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "r_data_o", + "descr": "Output port", + "signals": [ + {"name": "r_data", "width": "DATA_W", "direction": "output"}, + ], + }, + ], + "snippets": [ + { + "verilog_code": """ + + + + // Declare the RAM + reg [DATA_W-1:0] mem [(2**ADDR_W)-1:0]; + + reg [DATA_W-1:0] r_data; + // Initialize the RAM + initial begin + if (MEM_INIT_FILE_INT != "none") begin + $readmemh(MEM_INIT_FILE_INT, mem, 0, (2 ** ADDR_W) - 1); + end + end + + //read port + always @(posedge clk_i) begin + if (r_en_i) begin + r_data <= mem[r_addr_i]; + end + end + + //write port + always @(posedge clk_i) begin + if (w_en_i) begin + mem[w_addr_i] <= w_data_i; + end + end + + assign r_data_o = r_data; + """, + }, + ], } return attributes_dict diff --git a/lib/hardware/memories/ram/iob_ram_t2p_be/hardware/src/iob_ram_t2p_be.v b/lib/hardware/memories/ram/iob_ram_t2p_be/hardware/src/iob_ram_t2p_be.v deleted file mode 100644 index 5cea44ba2..000000000 --- a/lib/hardware/memories/ram/iob_ram_t2p_be/hardware/src/iob_ram_t2p_be.v +++ /dev/null @@ -1,76 +0,0 @@ -// 2p BRAM with Byte-wide Write Enable - -`timescale 1ns / 1ps -`include "bsp.vh" - -module iob_ram_t2p_be #( - parameter HEXFILE = "none", - parameter DATA_W = 0, - parameter ADDR_W = 0 -) ( - input clk_i, - - //write port - input [DATA_W/8-1:0] w_en_i, - input [ ADDR_W-1:0] w_addr_i, - input [ DATA_W-1:0] w_data_i, - - //read port - input r_en_i, - input [ADDR_W-1:0] r_addr_i, - output reg [DATA_W-1:0] r_data_o -); - - localparam COL_W = 8; - localparam NUM_COL = DATA_W / COL_W; - -`ifdef IOB_MEM_NO_READ_ON_WRITE - localparam file_suffix = {"7", "6", "5", "4", "3", "2", "1", "0"}; - - genvar i; - generate - for (i = 0; i < NUM_COL; i = i + 1) begin : ram_col - localparam mem_init_file_int = (HEXFILE != "none") ? - {HEXFILE, "_", file_suffix[8*(i+1)-1-:8], ".hex"} : "none"; - - iob_ram_t2p #( - .HEXFILE(mem_init_file_int), - .ADDR_W (ADDR_W), - .DATA_W (COL_W) - ) ram ( - .clk_i(clk_i), - - .w_en_i (w_en_i[i]), - .w_addr_i(w_addr_i), - .w_data_i(w_data_i[i*COL_W+:COL_W]), - .r_en_i (r_en_i), - .r_addr_i(r_addr_i), - .r_data_o(r_data_o[i*COL_W+:COL_W]) - ); - end - endgenerate -`else // !IOB_MEM_NO_READ_ON_WRITE - //this allows ISE 14.7 to work; do not remove - localparam mem_init_file_int = HEXFILE; - - // Declare the RAM - reg [DATA_W-1:0] mem[(2**ADDR_W)-1:0]; - - // Initialize the RAM - initial if (mem_init_file_int != "none") $readmemh(mem_init_file_int, mem, 0, (2 ** ADDR_W) - 1); - - //read port - always @(posedge clk_i) if (r_en_i) r_data_o <= mem[r_addr_i]; - - //write port - integer i; - always @(posedge clk_i) begin - for (i = 0; i < NUM_COL; i = i + 1) begin - if (w_en_i[i]) begin - mem[w_addr_i][i*COL_W+:COL_W] <= w_data_i[i*COL_W+:COL_W]; - end - end - end -`endif - -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_t2p_be/iob_ram_t2p_be.py b/lib/hardware/memories/ram/iob_ram_t2p_be/iob_ram_t2p_be.py index 547a3b170..3c165c576 100644 --- a/lib/hardware/memories/ram/iob_ram_t2p_be/iob_ram_t2p_be.py +++ b/lib/hardware/memories/ram/iob_ram_t2p_be/iob_ram_t2p_be.py @@ -3,7 +3,161 @@ def setup(py_params_dict): "original_name": "iob_ram_t2p_be", "name": "iob_ram_t2p_be", "version": "0.1", - "generate_hw": False, + "confs": [ + { + "name": "HEXFILE", + "type": "P", + "val": '"none"', + "min": "NA", + "max": "NA", + "descr": "Name of file to load into RAM", + }, + { + "name": "ADDR_W", + "type": "P", + "val": "0", + "min": "0", + "max": "NA", + "descr": "Address bus width", + }, + { + "name": "DATA_W", + "type": "P", + "val": "0", + "min": "0", + "max": "NA", + "descr": "Data bus width", + }, + { + "name": "COL_W", + "type": "F", + "val": "8", + "min": "NA", + "max": "NA", + "descr": "", + }, + { + "name": "NUM_COL", + "type": "F", + "val": "DATA_W / COL_W", + "min": "NA", + "max": "NA", + "descr": "", + }, + ], + "ports": [ + { + "name": "clk", + "descr": "Clock", + "signals": [ + {"name": "clk", "width": 1, "direction": "input"}, + ], + }, + { + "name": "w_en_i", + "descr": "Input port", + "signals": [ + {"name": "w_en", "width": "DATA_W/8", "direction": "input"}, + ], + }, + { + "name": "w_addr_i", + "descr": "Input port", + "signals": [ + {"name": "w_addr", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "w_data_i", + "descr": "Input port", + "signals": [ + {"name": "w_data", "width": "DATA_W", "direction": "input"}, + ], + }, + { + "name": "r_en_i", + "descr": "Input port", + "signals": [ + {"name": "r_en", "width": 1, "direction": "input"}, + ], + }, + { + "name": "r_addr_i", + "descr": "Input port", + "signals": [ + {"name": "r_addr", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "r_data_o", + "descr": "Output port", + "signals": [ + {"name": "r_data", "width": "DATA_W", "direction": "output"}, + ], + }, + ], + "blocks": [ + { + "core_name": "iob_ram_t2p", + "instantiate": False, + }, + ], + "snippets": [ + { + "verilog_code": """ + reg [DATA_W-1:0] r_data_o_reg; + assign r_data_o=r_data_o_reg; + `ifdef IOB_MEM_NO_READ_ON_WRITE + localparam file_suffix = {"7", "6", "5", "4", "3", "2", "1", "0"}; + + genvar i; + generate + for (i = 0; i < NUM_COL; i = i + 1) begin : ram_col + localparam mem_init_file_int = (HEXFILE != "none") ? + {HEXFILE, "_", file_suffix[8*(i+1)-1-:8], ".hex"} : "none"; + + iob_ram_t2p #( + .HEXFILE(mem_init_file_int), + .ADDR_W (ADDR_W), + .DATA_W (COL_W) + ) ram ( + .clk_i(clk_i), + + .w_en_i (w_en_i[i]), + .w_addr_i(w_addr_i), + .w_data_i(w_data_i[i*COL_W+:COL_W]), + .r_en_i (r_en_i), + .r_addr_i(r_addr_i), + .r_data_o(r_data_o_reg[i*COL_W+:COL_W]) + ); + end + endgenerate +`else // !IOB_MEM_NO_READ_ON_WRITE + //this allows ISE 14.7 to work; do not remove + localparam mem_init_file_int = HEXFILE; + + // Declare the RAM + reg [DATA_W-1:0] mem[(2**ADDR_W)-1:0]; + + // Initialize the RAM + initial if (mem_init_file_int != "none") $readmemh(mem_init_file_int, mem, 0, (2 ** ADDR_W) - 1); + + //read port + always @(posedge clk_i) if (r_en_i) r_data_o_reg <= mem[r_addr_i]; + + //write port + integer i; + always @(posedge clk_i) begin + for (i = 0; i < NUM_COL; i = i + 1) begin + if (w_en_i[i]) begin + mem[w_addr_i][i*COL_W+:COL_W] <= w_data_i[i*COL_W+:COL_W]; + end + end + end +`endif + """, + }, + ], } return attributes_dict diff --git a/lib/hardware/memories/ram/iob_ram_t2p_tiled/hardware/src/iob_ram_t2p_tiled.v b/lib/hardware/memories/ram/iob_ram_t2p_tiled/hardware/src/iob_ram_t2p_tiled.v deleted file mode 100644 index afbef7750..000000000 --- a/lib/hardware/memories/ram/iob_ram_t2p_tiled/hardware/src/iob_ram_t2p_tiled.v +++ /dev/null @@ -1,98 +0,0 @@ -`timescale 1ns / 1ps - -module iob_ram_t2p_tiled #( - parameter DATA_W = 32, // data width - parameter ADDR_W = 13, // address width - parameter TILE_ADDR_W = 11 // tile address width -) ( - // Inputs - input clk_i, - input w_en_i, - input r_en_i, - input [DATA_W-1:0] w_data_i, // input data to write port - input [ADDR_W-1:0] addr_i, // address for write/read port - - // Outputs - output reg [DATA_W-1:0] r_data_o //output port -); - - // Number of BRAMs to generate, each containing 2048 bytes maximum - localparam K = $ceil(2 ** (ADDR_W - TILE_ADDR_W)); // 2**11 == 2048 - - // Address decoder: enables write on selected BRAM - wire [K-1:0] addr_en; // address decoder output - decN #( - .N_OUTPUTS(K) - ) addr_dec ( - .dec_i(addr_i[ADDR_W-1:ADDR_W-$clog2(K)]), // only the first clog2(K) MSBs select the BRAM - .dec_o(addr_en) - ); - - // Generate K BRAMs - genvar i; - generate - // Vector containing all BRAM outputs - wire [DATA_W-1:0] r_data_vec[K-1:0]; - for (i = 0; i < K; i = i + 1) begin : ram_tile - iob_ram_t2p #( - .DATA_W(DATA_W), - .ADDR_W(ADDR_W - $clog2(K)) - ) bram ( - .clk_i(clk_i), - - .w_en_i (w_en_i & addr_en[i]), - .w_addr_i(addr_i[ADDR_W-$clog2(K)-1:0]), - .w_data_i(w_data_i), - - .r_en_i (r_en_i & addr_en[i]), - .r_addr_i(addr_i[ADDR_W-$clog2(K)-1:0]), - .r_data_o(r_data_vec[i]) - ); - end - endgenerate - - // bram mux: outputs selected BRAM - muxN #( - .N_INPUTS(K), - .INPUT_W (DATA_W) - ) bram_out_sel ( - .data_i(r_data_vec), - .sel_i (addr_i[ADDR_W-1:ADDR_W-$clog2(K)]), - .data_o(r_data_o) - ); - -endmodule - -// decoder with parameterizable output -module decN #( - parameter N_OUTPUTS = 16 -) ( - input [$clog2(N_OUTPUTS)-1:0] dec_i, - output reg [ N_OUTPUTS-1:0] dec_o -); - - always @* begin - dec_o = 0; - dec_o[dec_i] = 1'b1; - end -endmodule - -// multiplexer with parameterizable input -module muxN #( - parameter N_INPUTS = 4, // number of inputs - parameter INPUT_W = 8, // input bit width - parameter S = $clog2(N_INPUTS), // number of select lines - parameter W = N_INPUTS * INPUT_W // total data width -) ( - // Inputs - input [INPUT_W-1:0] data_i[N_INPUTS-1:0], // input port - input [ S-1:0] sel_i, // selection port - - // Outputs - output reg [INPUT_W-1:0] data_o // output port -); - - always @* begin - data_o = data_i[sel_i]; - end -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_t2p_tiled/iob_ram_t2p_tiled.py b/lib/hardware/memories/ram/iob_ram_t2p_tiled/iob_ram_t2p_tiled.py index 5855d1cf7..f7574b3c1 100644 --- a/lib/hardware/memories/ram/iob_ram_t2p_tiled/iob_ram_t2p_tiled.py +++ b/lib/hardware/memories/ram/iob_ram_t2p_tiled/iob_ram_t2p_tiled.py @@ -3,11 +3,179 @@ def setup(py_params_dict): "original_name": "iob_ram_t2p_tiled", "name": "iob_ram_t2p_tiled", "version": "0.1", - "generate_hw": False, + "confs": [ + { + "name": "ADDR_W", + "type": "P", + "val": "13", + "min": "0", + "max": "NA", + "descr": "Address bus width", + }, + { + "name": "DATA_W", + "type": "P", + "val": "32", + "min": "0", + "max": "NA", + "descr": "Data bus width", + }, + { + "name": "TILE_ADDR_W", + "type": "P", + "val": "11", + "min": "0", + "max": "NA", + "descr": "", + }, + { + "name": "K", + "type": "F", + "val": "$ceil(2 ** (ADDR_W - TILE_ADDR_W))", + "min": "0", + "max": "NA", + "descr": "", + }, + ], + "ports": [ + { + "name": "clk", + "descr": "Clock", + "signals": [ + {"name": "clk", "width": 1, "direction": "input"}, + ], + }, + { + "name": "w_en_i", + "descr": "Input port", + "signals": [ + {"name": "w_en", "width": 1, "direction": "input"}, + ], + }, + { + "name": "r_en_i", + "descr": "Input port", + "signals": [ + {"name": "r_en", "width": 1, "direction": "input"}, + ], + }, + { + "name": "w_data_i", + "descr": "Input port", + "signals": [ + {"name": "w_data", "width": "DATA_W", "direction": "input"}, + ], + }, + { + "name": "addr_i", + "descr": "Input port", + "signals": [ + {"name": "addr", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "r_data_o", + "descr": "Output port", + "signals": [ + {"name": "r_data", "width": "DATA_W", "direction": "output"}, + ], + }, + ], + "wires": [ + { + "name": "addr_en", + "descr": "addr_en wire", + "signals": [ + {"name": "addr_en", "width": "K"}, + ], + }, + ], "blocks": [ { "core_name": "iob_ram_t2p", - "instance_name": "iob_ram_t2p_inst", + "instantiate": False, + }, + ], + "snippets": [ + { + "verilog_code": """ + reg [DATA_W-1:0] r_data_o_reg; + assign r_data_o=r_data_o_reg; + decN #( + .N_OUTPUTS(K) + ) addr_dec ( + .dec_i(addr_i[ADDR_W-1:ADDR_W-$clog2(K)]), // only the first clog2(K) MSBs select the BRAM + .dec_o(addr_en) + ); + + // Generate K BRAMs + genvar i; + generate + // Vector containing all BRAM outputs + wire [DATA_W-1:0] r_data_vec[K-1:0]; + for (i = 0; i < K; i = i + 1) begin : ram_tile + iob_ram_t2p #( + .DATA_W(DATA_W), + .ADDR_W(ADDR_W - $clog2(K)) + ) bram ( + .clk_i(clk_i), + + .w_en_i (w_en_i & addr_en[i]), + .w_addr_i(addr_i[ADDR_W-$clog2(K)-1:0]), + .w_data_i(w_data_i), + + .r_en_i (r_en_i & addr_en[i]), + .r_addr_i(addr_i[ADDR_W-$clog2(K)-1:0]), + .r_data_o(r_data_vec[i]) + ); + end + endgenerate + + // bram mux: outputs selected BRAM + muxN #( + .N_INPUTS(K), + .INPUT_W (DATA_W) + ) bram_out_sel ( + .data_i(r_data_vec), + .sel_i (addr_i[ADDR_W-1:ADDR_W-$clog2(K)]), + .data_o(r_data_o_reg) + ); + +endmodule + +// decoder with parameterizable output +module decN #( + parameter N_OUTPUTS = 16 +) ( + input [$clog2(N_OUTPUTS)-1:0] dec_i, + output reg [ N_OUTPUTS-1:0] dec_o +); + + always @* begin + dec_o = 0; + dec_o[dec_i] = 1'b1; + end +endmodule + +// multiplexer with parameterizable input +module muxN #( + parameter N_INPUTS = 4, // number of inputs + parameter INPUT_W = 8, // input bit width + parameter S = $clog2(N_INPUTS), // number of select lines + parameter W = N_INPUTS * INPUT_W // total data width +) ( + // Inputs + input [INPUT_W-1:0] data_i[N_INPUTS-1:0], // input port + input [ S-1:0] sel_i, // selection port + + // Outputs + output reg [INPUT_W-1:0] data_o // output port +); + + always @* begin + data_o = data_i[sel_i]; + end + """, }, ], }