diff --git a/lib/hardware/memories/ram/iob_ram_at2p/hardware/src/iob_ram_at2p.v b/lib/hardware/memories/ram/iob_ram_at2p/hardware/src/iob_ram_at2p.v deleted file mode 100644 index 9fcf38377..000000000 --- a/lib/hardware/memories/ram/iob_ram_at2p/hardware/src/iob_ram_at2p.v +++ /dev/null @@ -1,48 +0,0 @@ -`timescale 1ns / 1ps - -module iob_ram_at2p #( - parameter HEXFILE = "none", - parameter DATA_W = 0, - parameter ADDR_W = 0 -) ( - // Write port - input w_clk_i, - input w_en_i, - input [ADDR_W-1:0] w_addr_i, - input [DATA_W-1:0] w_data_i, - - // Read port - input r_clk_i, - input r_en_i, - input [ADDR_W-1:0] r_addr_i, - output reg [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] ram[(2**ADDR_W)-1:0]; - - // Initialize the RAM - initial begin - if (MEM_INIT_FILE_INT != "none") begin - $readmemh(MEM_INIT_FILE_INT, ram, 0, (2 ** ADDR_W) - 1); - end - end - - //write - always @(posedge w_clk_i) begin - if (w_en_i) begin - ram[w_addr_i] <= w_data_i; - end - end - - //read - always @(posedge r_clk_i) begin - if (r_en_i) begin - r_data_o <= ram[r_addr_i]; - end - end - -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_at2p/iob_ram_at2p.py b/lib/hardware/memories/ram/iob_ram_at2p/iob_ram_at2p.py index c8ec7c174..668eb7a9a 100644 --- a/lib/hardware/memories/ram/iob_ram_at2p/iob_ram_at2p.py +++ b/lib/hardware/memories/ram/iob_ram_at2p/iob_ram_at2p.py @@ -3,7 +3,129 @@ def setup(py_params_dict): "original_name": "iob_ram_at2p", "name": "iob_ram_at2p", "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": "DATA_W", + "type": "P", + "val": "0", + "min": "NA", + "max": "NA", + "descr": "DATA width", + }, + { + "name": "ADDR_W", + "type": "P", + "val": "0", + "min": "NA", + "max": "NA", + "descr": "Address bus width", + }, + { + "name": "MEM_INIT_FILE_INT", + "type": "F", + "val": "HEXFILE", + "min": "NA", + "max": "NA", + "descr": "", + }, + ], + "ports": [ + { + "name": "w_clk_i", + "descr": "Input port", + "signals": [ + {"name": "w_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_clk_i", + "descr": "Input port", + "signals": [ + {"name": "r_clk", "width": 1, "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] ram[(2**ADDR_W)-1:0]; + reg [DATA_W-1:0] r_data_o_reg; + assign r_data_o=r_data_o_reg; + + // Initialize the RAM + initial begin + if (MEM_INIT_FILE_INT != "none") begin + $readmemh(MEM_INIT_FILE_INT, ram, 0, (2 ** ADDR_W) - 1); + end + end + + //write + always @(posedge w_clk_i) begin + if (w_en_i) begin + ram[w_addr_i] <= w_data_i; + end + end + + //read + always @(posedge r_clk_i) begin + if (r_en_i) begin + r_data_o_reg <= ram[r_addr_i]; + end + end + """, + }, + ], } return attributes_dict diff --git a/lib/hardware/memories/ram/iob_ram_atdp/hardware/src/iob_ram_atdp.v b/lib/hardware/memories/ram/iob_ram_atdp/hardware/src/iob_ram_atdp.v deleted file mode 100644 index f241544f7..000000000 --- a/lib/hardware/memories/ram/iob_ram_atdp/hardware/src/iob_ram_atdp.v +++ /dev/null @@ -1,58 +0,0 @@ -`timescale 1 ns / 1 ps -`include "bsp.vh" - -module iob_ram_atdp #( - parameter HEXFILE = "none", - parameter DATA_W = 0, - parameter ADDR_W = 0 -) ( - // Port A - input clkA_i, - input [(DATA_W-1):0] dA_i, - input [(ADDR_W-1):0] addrA_i, - input enA_i, - input weA_i, - output reg [(DATA_W-1):0] dA_o, - - // Port B - input clkB_i, - input [(DATA_W-1):0] dB_i, - input [(ADDR_W-1):0] addrB_i, - input enB_i, - input weB_i, - output reg [(DATA_W-1):0] dB_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] ram[2**ADDR_W-1:0]; - - // Initialize the RAM - initial if (mem_init_file_int != "none") $readmemh(mem_init_file_int, ram, 0, 2 ** ADDR_W - 1); - - //read port - always @(posedge clkA_i) begin // Port A - if (enA_i) -`ifdef IOB_MEM_NO_READ_ON_WRITE - if (weA_i) ram[addrA_i] <= dA_i; - else dA_o <= ram[addrA_i]; -`else - if (weA_i) ram[addrA_i] <= dA_i; - dA_o <= ram[addrA_i]; -`endif - end - - //write port - always @(posedge clkB_i) begin // Port B - if (enB_i) -`ifdef IOB_MEM_NO_READ_ON_WRITE - if (weB_i) ram[addrB_i] <= dB_i; - else dB_o <= ram[addrB_i]; -`else - if (weB_i) ram[addrB_i] <= dB_i; - dB_o <= ram[addrB_i]; -`endif - end -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_atdp/iob_ram_atdp.py b/lib/hardware/memories/ram/iob_ram_atdp/iob_ram_atdp.py index cdffd83bf..c9c7911b3 100644 --- a/lib/hardware/memories/ram/iob_ram_atdp/iob_ram_atdp.py +++ b/lib/hardware/memories/ram/iob_ram_atdp/iob_ram_atdp.py @@ -3,7 +3,165 @@ def setup(py_params_dict): "original_name": "iob_ram_atdp", "name": "iob_ram_atdp", "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": "DATA_W", + "type": "P", + "val": "0", + "min": "NA", + "max": "NA", + "descr": "DATA width", + }, + { + "name": "ADDR_W", + "type": "P", + "val": "0", + "min": "NA", + "max": "NA", + "descr": "Address bus width", + }, + { + "name": "MEM_INIT_FILE_INT", + "type": "F", + "val": "HEXFILE", + "min": "NA", + "max": "NA", + "descr": "", + }, + ], + "ports": [ + { + "name": "clkA_i", + "descr": "Input port", + "signals": [ + {"name": "clkA", "width": 1, "direction": "input"}, + ], + }, + { + "name": "dA_i", + "descr": "Input port", + "signals": [ + {"name": "dA", "width": "DATA_W", "direction": "input"}, + ], + }, + { + "name": "addrA_i", + "descr": "Input port", + "signals": [ + {"name": "addrA", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "enA_i", + "descr": "Input port", + "signals": [ + {"name": "enA", "width": 1, "direction": "input"}, + ], + }, + { + "name": "weA_i", + "descr": "Input port", + "signals": [ + {"name": "weA", "width": 1, "direction": "input"}, + ], + }, + { + "name": "dA_o", + "descr": "Output port", + "signals": [ + {"name": "dA", "width": "DATA_W", "direction": "output"}, + ], + }, + { + "name": "clkB_i", + "descr": "Input port", + "signals": [ + {"name": "clkB", "width": 1, "direction": "input"}, + ], + }, + { + "name": "dB_i", + "descr": "Input port", + "signals": [ + {"name": "dB", "width": "DATA_W", "direction": "input"}, + ], + }, + { + "name": "addrB_i", + "descr": "Input port", + "signals": [ + {"name": "addrB", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "enB_i", + "descr": "Input port", + "signals": [ + {"name": "enB", "width": 1, "direction": "input"}, + ], + }, + { + "name": "weB_i", + "descr": "Input port", + "signals": [ + {"name": "weB", "width": 1, "direction": "input"}, + ], + }, + { + "name": "dB_o", + "descr": "Output port", + "signals": [ + {"name": "dB", "width": "DATA_W", "direction": "output"}, + ], + }, + ], + "snippets": [ + { + "verilog_code": """ + // Declare the RAM + reg [DATA_W-1:0] ram[2**ADDR_W-1:0]; + reg [DATA_W-1:0] dA_o_reg; + reg [DATA_W-1:0] dB_o_reg; + assign dA_o=dA_o_reg; + assign dB_o=dB_o_reg; + + // Initialize the RAM + initial if (MEM_INIT_FILE_INT != "none") $readmemh(MEM_INIT_FILE_INT, ram, 0, 2 ** ADDR_W - 1); + + //read port + always @(posedge clkA_i) begin // Port A + if (enA_i) +`ifdef IOB_MEM_NO_READ_ON_WRITE + if (weA_i) ram[addrA_i] <= dA_i; + else dA_o_reg <= ram[addrA_i]; +`else + if (weA_i) ram[addrA_i] <= dA_i; + dA_o_reg <= ram[addrA_i]; +`endif + end + + //write port + always @(posedge clkB_i) begin // Port B + if (enB_i) +`ifdef IOB_MEM_NO_READ_ON_WRITE + if (weB_i) ram[addrB_i] <= dB_i; + else dB_o_reg <= ram[addrB_i]; +`else + if (weB_i) ram[addrB_i] <= dB_i; + dB_o_reg <= ram[addrB_i]; +`endif + end + """, + }, + ], } return attributes_dict diff --git a/lib/hardware/memories/ram/iob_ram_atdp_be/hardware/src/iob_ram_atdp_be.v b/lib/hardware/memories/ram/iob_ram_atdp_be/hardware/src/iob_ram_atdp_be.v deleted file mode 100644 index 6adaf90f9..000000000 --- a/lib/hardware/memories/ram/iob_ram_atdp_be/hardware/src/iob_ram_atdp_be.v +++ /dev/null @@ -1,107 +0,0 @@ -// True-Dual-Port BRAM with Byte-wide Write Enable -// Read-First mode - -`timescale 1 ns / 1 ps -`include "bsp.vh" - -module iob_ram_atdp_be #( - parameter HEXFILE = "none", - parameter ADDR_W = 10, // Addr Width in bits : 2*ADDR_W = RAM Depth - parameter DATA_W = 32 // Data Width in bits -) ( - // Port A - input clkA_i, - input enA_i, - input [DATA_W/8-1:0] weA_i, - input [ ADDR_W-1:0] addrA_i, - input [ DATA_W-1:0] dA_i, - output [ DATA_W-1:0] dA_o, - - // Port B - input clkB_i, - input enB_i, - input [DATA_W/8-1:0] weB_i, - input [ ADDR_W-1:0] addrB_i, - input [ DATA_W-1:0] dB_i, - output [DATA_W-1 : 0] dB_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_atdp #( - .HEXFILE(mem_init_file_int), - .ADDR_W (ADDR_W), - .DATA_W (COL_W) - ) ram ( - .clkA_i (clkA_i), - .enA_i (enA_i), - .addrA_i(addrA_i), - .dA_i (dA_i[i*COL_W+:COL_W]), - .weA_i (weA_i[i]), - .dA_o (dA_o[i*COL_W+:COL_W]), - - .clkB_i (clkB_i), - .enB_i (enB_i), - .addrB_i(addrB_i), - .dB_i (dB_i[i*COL_W+:COL_W]), - .weB_i (weB_i[i]), - .dB_o (dB_o[i*COL_W+:COL_W]) - ); - end - endgenerate -`else // !IOB_MEM_NO_READ_ON_WRITE - // this allow ISE 14.7 to work; do not remove - localparam mem_init_file_int = {HEXFILE, ".hex"}; - - // Core Memory - reg [DATA_W-1:0] ram_block[(2**ADDR_W)-1:0]; - - // Initialize the RAM - initial - if (mem_init_file_int != "none.hex") - $readmemh(mem_init_file_int, ram_block, 0, 2 ** ADDR_W - 1); - - // Port-A Operation - reg [DATA_W-1:0] dA_o_int; - integer i; - always @(posedge clkA_i) begin - if (enA_i) begin - for (i = 0; i < NUM_COL; i = i + 1) begin - if (weA_i[i]) begin - ram_block[addrA_i][i*COL_W+:COL_W] <= dA_i[i*COL_W+:COL_W]; - end - end - dA_o_int <= ram_block[addrA_i]; // Send Feedback - end - end - - assign dA_o = dA_o_int; - - // Port-B Operation - reg [DATA_W-1:0] dB_o_int; - integer j; - always @(posedge clkB_i) begin - if (enB_i) begin - for (j = 0; j < NUM_COL; j = j + 1) begin - if (weB_i[j]) begin - ram_block[addrB_i][j*COL_W+:COL_W] <= dB_i[j*COL_W+:COL_W]; - end - end - dB_o_int <= ram_block[addrB_i]; // Send Feedback - end - end - - assign dB_o = dB_o_int; -`endif - -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_atdp_be/iob_ram_atdp_be.py b/lib/hardware/memories/ram/iob_ram_atdp_be/iob_ram_atdp_be.py index ea6d9d36a..92aa0d07f 100644 --- a/lib/hardware/memories/ram/iob_ram_atdp_be/iob_ram_atdp_be.py +++ b/lib/hardware/memories/ram/iob_ram_atdp_be/iob_ram_atdp_be.py @@ -3,11 +3,218 @@ def setup(py_params_dict): "original_name": "iob_ram_atdp_be", "name": "iob_ram_atdp_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": "DATA_W", + "type": "P", + "val": "10", + "min": "NA", + "max": "NA", + "descr": "DATA width", + }, + { + "name": "ADDR_W", + "type": "P", + "val": "32", + "min": "NA", + "max": "NA", + "descr": "Address 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": "clkA_i", + "descr": "Input port", + "signals": [ + {"name": "clkA", "width": 1, "direction": "input"}, + ], + }, + { + "name": "enA_i", + "descr": "Input port", + "signals": [ + {"name": "enA", "width": 1, "direction": "input"}, + ], + }, + { + "name": "weA_i", + "descr": "Input port", + "signals": [ + {"name": "weA", "width": "DATA_W/8", "direction": "input"}, + ], + }, + { + "name": "addrA_i", + "descr": "Input port", + "signals": [ + {"name": "addrA", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "dA_i", + "descr": "Input port", + "signals": [ + {"name": "dA", "width": "DATA_W", "direction": "input"}, + ], + }, + { + "name": "dA_o", + "descr": "Output port", + "signals": [ + {"name": "dA", "width": "DATA_W", "direction": "output"}, + ], + }, + { + "name": "clkB_i", + "descr": "Input port", + "signals": [ + {"name": "clkB", "width": 1, "direction": "input"}, + ], + }, + { + "name": "enB_i", + "descr": "Input port", + "signals": [ + {"name": "enB", "width": 1, "direction": "input"}, + ], + }, + { + "name": "weB_i", + "descr": "Input port", + "signals": [ + {"name": "weB", "width": "DATA_W/8", "direction": "input"}, + ], + }, + { + "name": "addrB_i", + "descr": "Input port", + "signals": [ + {"name": "addrB", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "dB_i", + "descr": "Input port", + "signals": [ + {"name": "dB", "width": "DATA_W", "direction": "input"}, + ], + }, + { + "name": "dB_o", + "descr": "Output port", + "signals": [ + {"name": "dB", "width": "DATA_W", "direction": "output"}, + ], + }, + ], "blocks": [ { "core_name": "iob_ram_atdp", - "instance_name": "iob_ram_atdp_inst", + "instantiate": False, + }, + ], + "snippets": [ + { + "verilog_code": """ + `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_atdp #( + .HEXFILE(mem_init_file_int), + .ADDR_W (ADDR_W), + .DATA_W (COL_W) + ) ram ( + .clkA_i (clkA_i), + .enA_i (enA_i), + .addrA_i(addrA_i), + .dA_i (dA_i[i*COL_W+:COL_W]), + .weA_i (weA_i[i]), + .dA_o (dA_o[i*COL_W+:COL_W]), + + .clkB_i (clkB_i), + .enB_i (enB_i), + .addrB_i(addrB_i), + .dB_i (dB_i[i*COL_W+:COL_W]), + .weB_i (weB_i[i]), + .dB_o (dB_o[i*COL_W+:COL_W]) + ); + end + endgenerate +`else // !IOB_MEM_NO_READ_ON_WRITE + // this allow ISE 14.7 to work; do not remove + localparam mem_init_file_int = {HEXFILE, ".hex"}; + + // Core Memory + reg [DATA_W-1:0] ram_block[(2**ADDR_W)-1:0]; + + // Initialize the RAM + initial + if (mem_init_file_int != "none.hex") + $readmemh(mem_init_file_int, ram_block, 0, 2 ** ADDR_W - 1); + + // Port-A Operation + reg [DATA_W-1:0] dA_o_int; + integer i; + always @(posedge clkA_i) begin + if (enA_i) begin + for (i = 0; i < NUM_COL; i = i + 1) begin + if (weA_i[i]) begin + ram_block[addrA_i][i*COL_W+:COL_W] <= dA_i[i*COL_W+:COL_W]; + end + end + dA_o_int <= ram_block[addrA_i]; // Send Feedback + end + end + + assign dA_o = dA_o_int; + + // Port-B Operation + reg [DATA_W-1:0] dB_o_int; + integer j; + always @(posedge clkB_i) begin + if (enB_i) begin + for (j = 0; j < NUM_COL; j = j + 1) begin + if (weB_i[j]) begin + ram_block[addrB_i][j*COL_W+:COL_W] <= dB_i[j*COL_W+:COL_W]; + end + end + dB_o_int <= ram_block[addrB_i]; // Send Feedback + end + end + + assign dB_o = dB_o_int; +`endif + """, }, ], } diff --git a/lib/hardware/memories/ram/iob_ram_sp_be/hardware/src/iob_ram_sp_be.v b/lib/hardware/memories/ram/iob_ram_sp_be/hardware/src/iob_ram_sp_be.v deleted file mode 100644 index aeff03849..000000000 --- a/lib/hardware/memories/ram/iob_ram_sp_be/hardware/src/iob_ram_sp_be.v +++ /dev/null @@ -1,76 +0,0 @@ -// Single-Port BRAM with Byte-wide Write Enable -// Read-First mode - -`timescale 1 ns / 1 ps -`include "bsp.vh" - -module iob_ram_sp_be #( - parameter HEXFILE = "none", - parameter ADDR_W = 10, // Addr Width in bits : 2*ADDR_W = RAM Depth - parameter DATA_W = 32 // Data Width in bits -) ( - input clk_i, - input en_i, - input [DATA_W/8-1:0] we_i, - input [ ADDR_W-1:0] addr_i, - input [ DATA_W-1:0] d_i, - output [ DATA_W-1:0] d_o -); - - localparam COL_W = 8; - localparam NUM_COL = DATA_W / COL_W; - - // Operation -`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_sp #( - .HEXFILE(mem_init_file_int), - .ADDR_W (ADDR_W), - .DATA_W (COL_W) - ) ram ( - .clk_i(clk_i), - - .en_i (en_i), - .addr_i(addr_i), - .d_i (d_i[i*COL_W+:COL_W]), - .we_i (we_i[i]), - .d_o (d_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, ".hex"}; - - // Core Memory - reg [DATA_W-1:0] ram_block[(2**ADDR_W)-1:0]; - - // Initialize the RAM - initial - if (mem_init_file_int != "none.hex") - $readmemh(mem_init_file_int, ram_block, 0, 2 ** ADDR_W - 1); - - reg [DATA_W-1:0] d_o_int; - integer i; - always @(posedge clk_i) begin - if (en_i) begin - for (i = 0; i < NUM_COL; i = i + 1) begin - if (we_i[i]) begin - ram_block[addr_i][i*COL_W+:COL_W] <= d_i[i*COL_W+:COL_W]; - end - end - d_o_int <= ram_block[addr_i]; // Send Feedback - end - end - - assign d_o = d_o_int; -`endif - -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_sp_be/iob_ram_sp_be.py b/lib/hardware/memories/ram/iob_ram_sp_be/iob_ram_sp_be.py index 41930e4f8..9ae5caeae 100644 --- a/lib/hardware/memories/ram/iob_ram_sp_be/iob_ram_sp_be.py +++ b/lib/hardware/memories/ram/iob_ram_sp_be/iob_ram_sp_be.py @@ -3,12 +3,11 @@ def setup(py_params_dict): "original_name": "iob_ram_sp_be", "name": "iob_ram_sp_be", "version": "0.1", - "generate_hw": False, "confs": [ { "name": "HEXFILE", "type": "P", - "val": "none", + "val": '"none"', "min": "NA", "max": "NA", "descr": "Name of file to load into RAM", @@ -29,6 +28,22 @@ def setup(py_params_dict): "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": [ { @@ -53,7 +68,66 @@ def setup(py_params_dict): "blocks": [ { "core_name": "iob_ram_sp", - "instance_name": "iob_ram_sp_inst", + "instantiate": False, + }, + ], + "snippets": [ + { + "verilog_code": """ + + // Operation +`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_sp #( + .HEXFILE(mem_init_file_int), + .ADDR_W (ADDR_W), + .DATA_W (COL_W) + ) ram ( + .clk_i(clk_i), + + .en_i (en_i), + .addr_i(addr_i), + .d_i (d_i[i*COL_W+:COL_W]), + .we_i (we_i[i]), + .d_o (d_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, ".hex"}; + + // Core Memory + reg [DATA_W-1:0] ram_block[(2**ADDR_W)-1:0]; + + // Initialize the RAM + initial + if (mem_init_file_int != "none.hex") + $readmemh(mem_init_file_int, ram_block, 0, 2 ** ADDR_W - 1); + + reg [DATA_W-1:0] d_o_int; + integer i; + always @(posedge clk_i) begin + if (en_i) begin + for (i = 0; i < NUM_COL; i = i + 1) begin + if (we_i[i]) begin + ram_block[addr_i][i*COL_W+:COL_W] <= d_i[i*COL_W+:COL_W]; + end + end + d_o_int <= ram_block[addr_i]; // Send Feedback + end + end + + assign d_o = d_o_int; +`endif + """, }, ], } diff --git a/lib/hardware/memories/ram/iob_ram_sp_se/hardware/src/iob_ram_sp_se.v b/lib/hardware/memories/ram/iob_ram_sp_se/hardware/src/iob_ram_sp_se.v deleted file mode 100644 index 6fcc88619..000000000 --- a/lib/hardware/memories/ram/iob_ram_sp_se/hardware/src/iob_ram_sp_se.v +++ /dev/null @@ -1,76 +0,0 @@ -// Single-Port BRAM with Byte-wide Write Enable -// Read-First mode - -`timescale 1 ns / 1 ps -`include "bsp.vh" - -module iob_ram_sp_se #( - parameter HEXFILE = "none", - parameter ADDR_W = 10, - parameter DATA_W = 32, - parameter COL_W = 8 -) ( - input clk_i, - input en_i, - input [DATA_W/COL_W-1:0] we_i, - input [ ADDR_W-1:0] addr_i, - input [ DATA_W-1:0] d_i, - output [ DATA_W-1:0] d_o -); - - localparam NUM_COL = DATA_W / COL_W; - - // Operation -`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[COL_W*(i+1)-1-:COL_W], ".hex"} : "none"; - - iob_ram_sp #( - .HEXFILE(mem_init_file_int), - .ADDR_W (ADDR_W), - .DATA_W (COL_W) - ) ram ( - .clk_i(clk_i), - - .en_i (en_i), - .addr_i(addr_i), - .d_i (d_i[i*COL_W+:COL_W]), - .we_i (we_i[i]), - .d_o (d_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, ".hex"}; - - // Core Memory - reg [DATA_W-1:0] ram_block[(2**ADDR_W)-1:0]; - - // Initialize the RAM - initial - if (mem_init_file_int != "none.hex") - $readmemh(mem_init_file_int, ram_block, 0, 2 ** ADDR_W - 1); - - reg [DATA_W-1:0] d_o_int; - integer i; - always @(posedge clk_i) begin - if (en_i) begin - for (i = 0; i < NUM_COL; i = i + 1) begin - if (we_i[i]) begin - ram_block[addr_i][i*COL_W+:COL_W] <= d_i[i*COL_W+:COL_W]; - end - end - d_o_int <= ram_block[addr_i]; // Send Feedback - end - end - - assign d_o = d_o_int; -`endif - -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_sp_se/iob_ram_sp_se.py b/lib/hardware/memories/ram/iob_ram_sp_se/iob_ram_sp_se.py index 5c3d9a5be..eeb898157 100644 --- a/lib/hardware/memories/ram/iob_ram_sp_se/iob_ram_sp_se.py +++ b/lib/hardware/memories/ram/iob_ram_sp_se/iob_ram_sp_se.py @@ -3,11 +3,132 @@ def setup(py_params_dict): "original_name": "iob_ram_sp_se", "name": "iob_ram_sp_se", "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": "10", + "min": "0", + "max": "NA", + "descr": "Address bus width", + }, + { + "name": "DATA_W", + "type": "P", + "val": "32", + "min": "0", + "max": "NA", + "descr": "Data bus width", + }, + { + "name": "COL_W", + "type": "P", + "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": "mem_if", + "descr": "Memory interface", + "signals": [ + {"name": "en", "width": 1, "direction": "input"}, + {"name": "we", "width": "DATA_W/COL_W", "direction": "input"}, + {"name": "addr", "width": "ADDR_W", "direction": "input"}, + {"name": "d", "width": "DATA_W", "direction": "input"}, + {"name": "d", "width": "DATA_W", "direction": "output"}, + ], + }, + ], "blocks": [ { "core_name": "iob_ram_sp", - "instance_name": "iob_ram_sp_inst", + "instantiate": False, + }, + ], + "snippets": [ + { + "verilog_code": """ + + + // Operation +`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[COL_W*(i+1)-1-:COL_W], ".hex"} : "none"; + + iob_ram_sp #( + .HEXFILE(mem_init_file_int), + .ADDR_W (ADDR_W), + .DATA_W (COL_W) + ) ram ( + .clk_i(clk_i), + + .en_i (en_i), + .addr_i(addr_i), + .d_i (d_i[i*COL_W+:COL_W]), + .we_i (we_i[i]), + .d_o (d_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, ".hex"}; + + // Core Memory + reg [DATA_W-1:0] ram_block[(2**ADDR_W)-1:0]; + + // Initialize the RAM + initial + if (mem_init_file_int != "none.hex") + $readmemh(mem_init_file_int, ram_block, 0, 2 ** ADDR_W - 1); + + reg [DATA_W-1:0] d_o_int; + integer i; + always @(posedge clk_i) begin + if (en_i) begin + for (i = 0; i < NUM_COL; i = i + 1) begin + if (we_i[i]) begin + ram_block[addr_i][i*COL_W+:COL_W] <= d_i[i*COL_W+:COL_W]; + end + end + d_o_int <= ram_block[addr_i]; // Send Feedback + end + end + + assign d_o = d_o_int; +`endif + """, }, ], } 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 + """, }, ], } diff --git a/lib/hardware/memories/ram/iob_ram_tdp/hardware/src/iob_ram_tdp.v b/lib/hardware/memories/ram/iob_ram_tdp/hardware/src/iob_ram_tdp.v deleted file mode 100644 index 5a0d112a0..000000000 --- a/lib/hardware/memories/ram/iob_ram_tdp/hardware/src/iob_ram_tdp.v +++ /dev/null @@ -1,60 +0,0 @@ -`timescale 1ns / 1ps - -module iob_ram_tdp #( - parameter HEXFILE = "none", - parameter DATA_W = 8, - parameter ADDR_W = 6, - parameter MEM_NO_READ_ON_WRITE = 1 -) ( - input clk_i, - - // Port A - input [DATA_W-1:0] dA_i, - input [ADDR_W-1:0] addrA_i, - input enA_i, - input weA_i, - output reg [DATA_W-1:0] dA_o, - - // Port B - input [DATA_W-1:0] dB_i, - input [ADDR_W-1:0] addrB_i, - input enB_i, - input weB_i, - output reg [DATA_W-1:0] dB_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] ram[2**ADDR_W-1:0]; - - // Initialize the RAM - initial if (mem_init_file_int != "none") $readmemh(mem_init_file_int, ram, 0, 2 ** ADDR_W - 1); - - generate - if (MEM_NO_READ_ON_WRITE) begin : with_MEM_NO_READ_ON_WRITE - always @(posedge clk_i) begin // Port A - if (enA_i) - if (weA_i) ram[addrA_i] <= dA_i; - else dA_o <= ram[addrA_i]; - end - always @(posedge clk_i) begin // Port B - if (enB_i) - if (weB_i) ram[addrB_i] <= dB_i; - else dB_o <= ram[addrB_i]; - end - end else begin : not_MEM_NO_READ_ON_WRITE - always @(posedge clk_i) begin // Port A - if (enA_i) if (weA_i) ram[addrA_i] <= dA_i; - dA_o <= ram[addrA_i]; - end - always @(posedge clk_i) begin // Port B - if (enB_i) if (weB_i) ram[addrB_i] <= dB_i; - dB_o <= ram[addrB_i]; - end - end - endgenerate - -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_tdp/iob_ram_tdp.py b/lib/hardware/memories/ram/iob_ram_tdp/iob_ram_tdp.py index 49e872dbc..5caa7c2e8 100644 --- a/lib/hardware/memories/ram/iob_ram_tdp/iob_ram_tdp.py +++ b/lib/hardware/memories/ram/iob_ram_tdp/iob_ram_tdp.py @@ -3,7 +3,166 @@ def setup(py_params_dict): "original_name": "iob_ram_tdp", "name": "iob_ram_tdp", "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": "6", + "min": "0", + "max": "NA", + "descr": "Address bus width", + }, + { + "name": "DATA_W", + "type": "P", + "val": "8", + "min": "0", + "max": "NA", + "descr": "Data bus width", + }, + { + "name": "MEM_NO_READ_ON_WRITE", + "type": "P", + "val": "1", + "min": "0", + "max": "NA", + "descr": "", + }, + { + "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": "dA_i", + "descr": "Input port", + "signals": [ + {"name": "dA", "width": "DATA_W", "direction": "input"}, + ], + }, + { + "name": "addrA_i", + "descr": "Input port", + "signals": [ + {"name": "addrA", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "enA_i", + "descr": "Input port", + "signals": [ + {"name": "enA", "width": 1, "direction": "input"}, + ], + }, + { + "name": "weA_i", + "descr": "Input port", + "signals": [ + {"name": "weA", "width": 1, "direction": "input"}, + ], + }, + { + "name": "dA_o", + "descr": "Output port", + "signals": [ + {"name": "dA", "width": "DATA_W", "direction": "output"}, + ], + }, + { + "name": "dB_i", + "descr": "Input port", + "signals": [ + {"name": "dB", "width": "DATA_W", "direction": "input"}, + ], + }, + { + "name": "addrB_i", + "descr": "Input port", + "signals": [ + {"name": "addrB", "width": "ADDR_W", "direction": "input"}, + ], + }, + { + "name": "enB_i", + "descr": "Input port", + "signals": [ + {"name": "enB", "width": 1, "direction": "input"}, + ], + }, + { + "name": "weB_i", + "descr": "Input port", + "signals": [ + {"name": "weB", "width": 1, "direction": "input"}, + ], + }, + { + "name": "dB_o", + "descr": "Output port", + "signals": [ + {"name": "dB", "width": "DATA_W", "direction": "output"}, + ], + }, + ], + "snippets": [ + { + "verilog_code": """ + reg [DATA_W-1:0] dA_o_reg; + reg [DATA_W-1:0] dB_o_reg; + assign dA_o=dA_o_reg; + assign dB_o=dB_o_reg; + // Declare the RAM + reg [DATA_W-1:0] ram[2**ADDR_W-1:0]; + + // Initialize the RAM + initial if (MEM_INIT_FILE_INT != "none") $readmemh(MEM_INIT_FILE_INT, ram, 0, 2 ** ADDR_W - 1); + + generate + if (MEM_NO_READ_ON_WRITE) begin : with_MEM_NO_READ_ON_WRITE + always @(posedge clk_i) begin // Port A + if (enA_i) + if (weA_i) ram[addrA_i] <= dA_i; + else dA_o_reg <= ram[addrA_i]; + end + always @(posedge clk_i) begin // Port B + if (enB_i) + if (weB_i) ram[addrB_i] <= dB_i; + else dB_o_reg <= ram[addrB_i]; + end + end else begin : not_MEM_NO_READ_ON_WRITE + always @(posedge clk_i) begin // Port A + if (enA_i) if (weA_i) ram[addrA_i] <= dA_i; + dA_o_reg <= ram[addrA_i]; + end + always @(posedge clk_i) begin // Port B + if (enB_i) if (weB_i) ram[addrB_i] <= dB_i; + dB_o_reg <= ram[addrB_i]; + end + end + endgenerate + """, + }, + ], } return attributes_dict diff --git a/lib/hardware/memories/ram/iob_ram_tdp_be/hardware/src/iob_ram_tdp_be.v b/lib/hardware/memories/ram/iob_ram_tdp_be/hardware/src/iob_ram_tdp_be.v deleted file mode 100644 index a9b0d38b5..000000000 --- a/lib/hardware/memories/ram/iob_ram_tdp_be/hardware/src/iob_ram_tdp_be.v +++ /dev/null @@ -1,62 +0,0 @@ -// Dual-Port BRAM with Byte-wide Write Enable -// Read-First mode - -`timescale 1 ns / 1 ps - -module iob_ram_tdp_be #( - parameter HEXFILE = "none", - parameter ADDR_W = 10, // Addr Width in bits : 2*ADDR_W = RAM Depth - parameter DATA_W = 32, // Data Width in bits - parameter MEM_NO_READ_ON_WRITE = 0 //no simultaneous read/write -) ( - input clk_i, - - // Port A - input enA_i, - input [DATA_W/8-1:0] weA_i, - input [ ADDR_W-1:0] addrA_i, - input [ DATA_W-1:0] dA_i, - output [ DATA_W-1:0] dA_o, - - // Port B - input enB_i, - input [DATA_W/8-1:0] weB_i, - input [ ADDR_W-1:0] addrB_i, - input [ DATA_W-1:0] dB_i, - output [DATA_W-1 : 0] dB_o -); - - localparam COL_W = DATA_W / 4; - localparam NUM_COL = DATA_W / COL_W; - - localparam file_suffix = {"7", "6", "5", "4", "3", "2", "1", "0"}; - - genvar index; - generate - for (index = 0; index < NUM_COL; index = index + 1) begin : ram_col - localparam mem_init_file_int = (HEXFILE != "none") ? - {HEXFILE, "_", file_suffix[8*(index+1)-1-:8], ".hex"} : "none"; - iob_ram_tdp #( - .HEXFILE (mem_init_file_int), - .ADDR_W (ADDR_W), - .DATA_W (COL_W), - .MEM_NO_READ_ON_WRITE(MEM_NO_READ_ON_WRITE) - ) ram ( - .clk_i(clk_i), - - .enA_i (enA_i), - .addrA_i(addrA_i), - .dA_i (dA_i[index*COL_W+:COL_W]), - .weA_i (weA_i[index]), - .dA_o (dA_o[index*COL_W+:COL_W]), - - .enB_i (enB_i), - .addrB_i(addrB_i), - .dB_i (dB_i[index*COL_W+:COL_W]), - .weB_i (weB_i[index]), - .dB_o (dB_o[index*COL_W+:COL_W]) - ); - end - endgenerate - -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_tdp_be/iob_ram_tdp_be.py b/lib/hardware/memories/ram/iob_ram_tdp_be/iob_ram_tdp_be.py index 74b8ba47f..9bb81f152 100644 --- a/lib/hardware/memories/ram/iob_ram_tdp_be/iob_ram_tdp_be.py +++ b/lib/hardware/memories/ram/iob_ram_tdp_be/iob_ram_tdp_be.py @@ -3,12 +3,11 @@ def setup(py_params_dict): "original_name": "iob_ram_tdp_be", "name": "iob_ram_tdp_be", "version": "0.1", - "generate_hw": False, "confs": [ { "name": "HEXFILE", "type": "P", - "val": "none", + "val": '"none"', "min": "NA", "max": "NA", "descr": "Name of file to load into RAM", @@ -37,6 +36,30 @@ def setup(py_params_dict): "max": "1", "descr": "No simultaneous read/write", }, + { + "name": "COL_W", + "type": "F", + "val": "DATA_W / 4", + "min": "NA", + "max": "NA", + "descr": "", + }, + { + "name": "NUM_COL", + "type": "F", + "val": "DATA_W / COL_W", + "min": "NA", + "max": "NA", + "descr": "", + }, + { + "name": "FILE_SUFFIX", + "type": "F", + "val": '{"7", "6", "5", "4", "3", "2", "1", "0"}', + "min": "NA", + "max": "NA", + "descr": "", + }, ], "ports": [ { @@ -72,7 +95,40 @@ def setup(py_params_dict): "blocks": [ { "core_name": "iob_ram_tdp", - "instance_name": "iob_ram_tdp_inst", + "instantiate": False, + }, + ], + "snippets": [ + { + "verilog_code": """ + genvar index; + generate + for (index = 0; index < NUM_COL; index = index + 1) begin : ram_col + localparam mem_init_file_int = (HEXFILE != "none") ? + {HEXFILE, "_", FILE_SUFFIX[8*(index+1)-1-:8], ".hex"} : "none"; + iob_ram_tdp #( + .HEXFILE (mem_init_file_int), + .ADDR_W (ADDR_W), + .DATA_W (COL_W), + .MEM_NO_READ_ON_WRITE(MEM_NO_READ_ON_WRITE) + ) ram ( + .clk_i(clk_i), + + .enA_i (enA_i), + .addrA_i(addrA_i), + .dA_i (dA_i[index*COL_W+:COL_W]), + .weA_i (weA_i[index]), + .dA_o (dA_o[index*COL_W+:COL_W]), + + .enB_i (enB_i), + .addrB_i(addrB_i), + .dB_i (dB_i[index*COL_W+:COL_W]), + .weB_i (weB_i[index]), + .dB_o (dB_o[index*COL_W+:COL_W]) + ); + end + endgenerate + """, }, ], } diff --git a/lib/hardware/memories/ram/iob_ram_tdp_be_xil/hardware/src/iob_ram_tdp_be_xil.v b/lib/hardware/memories/ram/iob_ram_tdp_be_xil/hardware/src/iob_ram_tdp_be_xil.v deleted file mode 100644 index d1bc83ee1..000000000 --- a/lib/hardware/memories/ram/iob_ram_tdp_be_xil/hardware/src/iob_ram_tdp_be_xil.v +++ /dev/null @@ -1,74 +0,0 @@ -// Dual-Port BRAM with Byte-wide Write Enable -// Read-First mode - -`timescale 1 ns / 1 ps - -module iob_ram_tdp_be_xil #( - parameter HEXFILE = "none", - parameter ADDR_W = 10, // Addr Width in bits : 2*ADDR_W = RAM Depth - parameter DATA_W = 32 // Data Width in bits -) ( - input clk_i, - - // Port A - input enA_i, - input [DATA_W/8-1:0] weA_i, - input [ ADDR_W-1:0] addrA_i, - input [ DATA_W-1:0] dA_i, - output [ DATA_W-1:0] dA_o, - - // Port B - input enB_i, - input [DATA_W/8-1:0] weB_i, - input [ ADDR_W-1:0] addrB_i, - input [ DATA_W-1:0] dB_i, - output [DATA_W-1 : 0] dB_o -); - - localparam COL_W = 8; - localparam NUM_COL = DATA_W / COL_W; - - // this allow ISE 14.7 to work; do not remove - localparam mem_init_file_int = {HEXFILE, ".hex"}; - - // Core Memory - reg [DATA_W-1:0] ram_block[(2**ADDR_W)-1:0]; - - // Initialize the RAM - initial - if (mem_init_file_int != "none.hex") - $readmemh(mem_init_file_int, ram_block, 0, 2 ** ADDR_W - 1); - - // Port-A Operation - reg [DATA_W-1:0] dA_o_int; - integer i; - always @(posedge clk_i) begin - if (enA_i) begin - for (i = 0; i < NUM_COL; i = i + 1) begin - if (weA_i[i]) begin - ram_block[addrA_i][i*COL_W+:COL_W] <= dA_i[i*COL_W+:COL_W]; - end - end - dA_o_int <= ram_block[addrA_i]; // Send Feedback - end - end - - assign dA_o = dA_o_int; - - // Port-B Operation - reg [DATA_W-1:0] dB_o_int; - integer j; - always @(posedge clk_i) begin - if (enB_i) begin - for (j = 0; j < NUM_COL; j = j + 1) begin - if (weB_i[j]) begin - ram_block[addrB_i][j*COL_W+:COL_W] <= dB_i[j*COL_W+:COL_W]; - end - end - dB_o_int <= ram_block[addrB_i]; // Send Feedback - end - end - - assign dB_o = dB_o_int; - -endmodule diff --git a/lib/hardware/memories/ram/iob_ram_tdp_be_xil/iob_ram_tdp_be_xil.py b/lib/hardware/memories/ram/iob_ram_tdp_be_xil/iob_ram_tdp_be_xil.py index 6f2ea3bf2..5a9468204 100644 --- a/lib/hardware/memories/ram/iob_ram_tdp_be_xil/iob_ram_tdp_be_xil.py +++ b/lib/hardware/memories/ram/iob_ram_tdp_be_xil/iob_ram_tdp_be_xil.py @@ -3,12 +3,11 @@ def setup(py_params_dict): "original_name": "iob_ram_tdp_be_xil", "name": "iob_ram_tdp_be_xil", "version": "0.1", - "generate_hw": False, "confs": [ { "name": "HEXFILE", "type": "P", - "val": "none", + "val": '"none"', "min": "NA", "max": "NA", "descr": "Name of file to load into RAM", @@ -29,6 +28,30 @@ def setup(py_params_dict): "max": "NA", "descr": "Data bus width", }, + { + "name": "COL_W", + "type": "F", + "val": "DATA_W / 4", + "min": "NA", + "max": "NA", + "descr": "", + }, + { + "name": "NUM_COL", + "type": "F", + "val": "DATA_W / COL_W", + "min": "NA", + "max": "NA", + "descr": "", + }, + { + "name": "mem_init_file_int", + "type": "F", + "val": '{HEXFILE, ".hex"}', + "min": "NA", + "max": "NA", + "descr": "", + }, ], "ports": [ { @@ -61,6 +84,51 @@ def setup(py_params_dict): ], }, ], + "snippets": [ + { + "verilog_code": """ + // Core Memory + reg [DATA_W-1:0] ram_block[(2**ADDR_W)-1:0]; + + // Initialize the RAM + initial + if (MEM_INIT_FILE_INT != "none.hex") + $readmemh(MEM_INIT_FILE_INT, ram_block, 0, 2 ** ADDR_W - 1); + + // Port-A Operation + reg [DATA_W-1:0] dA_o_int; + integer i; + always @(posedge clk_i) begin + if (enA_i) begin + for (i = 0; i < NUM_COL; i = i + 1) begin + if (weA_i[i]) begin + ram_block[addrA_i][i*COL_W+:COL_W] <= dA_i[i*COL_W+:COL_W]; + end + end + dA_o_int <= ram_block[addrA_i]; // Send Feedback + end + end + + assign dA_o = dA_o_int; + + // Port-B Operation + reg [DATA_W-1:0] dB_o_int; + integer j; + always @(posedge clk_i) begin + if (enB_i) begin + for (j = 0; j < NUM_COL; j = j + 1) begin + if (weB_i[j]) begin + ram_block[addrB_i][j*COL_W+:COL_W] <= dB_i[j*COL_W+:COL_W]; + end + end + dB_o_int <= ram_block[addrB_i]; // Send Feedback + end + end + + assign dB_o = dB_o_int; + """, + }, + ], } return attributes_dict