aboutsummaryrefslogtreecommitdiff
path: root/rtl/_modexpng_storage_manager.v
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-01 16:18:33 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-01 16:18:33 +0300
commit71f70252dfc7e41103dde420a721be8aa48486d5 (patch)
tree182c413b590d6056b02c5d20818c3385c83610e3 /rtl/_modexpng_storage_manager.v
parentfde62e373fdfcefefb7da10757a3db933160c911 (diff)
Redesigned core architecture, unified bank structure. All storage blocks now
have eight 4kbit entries and occupy one 36K BRAM tile.
Diffstat (limited to 'rtl/_modexpng_storage_manager.v')
-rw-r--r--rtl/_modexpng_storage_manager.v199
1 files changed, 199 insertions, 0 deletions
diff --git a/rtl/_modexpng_storage_manager.v b/rtl/_modexpng_storage_manager.v
new file mode 100644
index 0000000..958596a
--- /dev/null
+++ b/rtl/_modexpng_storage_manager.v
@@ -0,0 +1,199 @@
+module modexpng_storage_manager
+(
+ clk, rst,
+
+ wr_wide_xy_ena,
+ wr_wide_xy_bank,
+ wr_wide_xy_addr,
+ wr_wide_x_din,
+ wr_wide_y_din,
+
+ wr_narrow_xy_ena,
+ wr_narrow_xy_bank,
+ wr_narrow_xy_addr,
+ wr_narrow_x_din,
+ wr_narrow_y_din,
+
+ ext_wide_xy_ena,
+ ext_wide_xy_bank,
+ ext_wide_xy_addr,
+ ext_wide_x_din,
+ ext_wide_y_din,
+
+ ext_narrow_xy_ena,
+ ext_narrow_xy_bank,
+ ext_narrow_xy_addr,
+ ext_narrow_x_din,
+ ext_narrow_y_din,
+
+ rcmb_wide_xy_ena,
+ rcmb_wide_xy_bank,
+ rcmb_wide_xy_addr,
+ rcmb_wide_x_din,
+ rcmb_wide_y_din,
+
+ rcmb_narrow_xy_ena,
+ rcmb_narrow_xy_bank,
+ rcmb_narrow_xy_addr,
+ rcmb_narrow_x_din,
+ rcmb_narrow_y_din
+);
+
+
+ //
+ // Headers
+ //
+ `include "../rtl/modexpng_parameters.vh"
+
+
+ //
+ // Ports
+ //
+ input clk;
+ input rst;
+
+ output wr_wide_xy_ena;
+ output [BANK_ADDR_W -1:0] wr_wide_xy_bank;
+ output [ OP_ADDR_W -1:0] wr_wide_xy_addr;
+ output [ WORD_EXT_W -1:0] wr_wide_x_din;
+ output [ WORD_EXT_W -1:0] wr_wide_y_din;
+
+ output wr_narrow_xy_ena;
+ output [BANK_ADDR_W -1:0] wr_narrow_xy_bank;
+ output [ OP_ADDR_W -1:0] wr_narrow_xy_addr;
+ output [ WORD_EXT_W -1:0] wr_narrow_x_din;
+ output [ WORD_EXT_W -1:0] wr_narrow_y_din;
+
+ input ext_wide_xy_ena;
+ input [BANK_ADDR_W -1:0] ext_wide_xy_bank;
+ input [ OP_ADDR_W -1:0] ext_wide_xy_addr;
+ input [ WORD_EXT_W -1:0] ext_wide_x_din;
+ input [ WORD_EXT_W -1:0] ext_wide_y_din;
+
+ input ext_narrow_xy_ena;
+ input [BANK_ADDR_W -1:0] ext_narrow_xy_bank;
+ input [ OP_ADDR_W -1:0] ext_narrow_xy_addr;
+ input [ WORD_EXT_W -1:0] ext_narrow_x_din;
+ input [ WORD_EXT_W -1:0] ext_narrow_y_din;
+
+ input rcmb_wide_xy_ena;
+ input [BANK_ADDR_W -1:0] rcmb_wide_xy_bank;
+ input [ OP_ADDR_W -1:0] rcmb_wide_xy_addr;
+ input [ WORD_EXT_W -1:0] rcmb_wide_x_din;
+ input [ WORD_EXT_W -1:0] rcmb_wide_y_din;
+
+ input rcmb_narrow_xy_ena;
+ input [BANK_ADDR_W -1:0] rcmb_narrow_xy_bank;
+ input [ OP_ADDR_W -1:0] rcmb_narrow_xy_addr;
+ input [ WORD_EXT_W -1:0] rcmb_narrow_x_din;
+ input [ WORD_EXT_W -1:0] rcmb_narrow_y_din;
+
+ reg wr_wide_xy_ena_reg = 1'b0;
+ reg [BANK_ADDR_W -1:0] wr_wide_xy_bank_reg;
+ reg [ OP_ADDR_W -1:0] wr_wide_xy_addr_reg;
+ reg [ WORD_EXT_W -1:0] wr_wide_x_din_reg;
+ reg [ WORD_EXT_W -1:0] wr_wide_y_din_reg;
+
+ reg wr_narrow_xy_ena_reg = 1'b0;
+ reg [BANK_ADDR_W -1:0] wr_narrow_xy_bank_reg;
+ reg [ OP_ADDR_W -1:0] wr_narrow_xy_addr_reg;
+ reg [ WORD_EXT_W -1:0] wr_narrow_x_din_reg;
+ reg [ WORD_EXT_W -1:0] wr_narrow_y_din_reg;
+
+ task _update_wide;
+ input xy_ena;
+ input [BANK_ADDR_W -1:0] xy_bank;
+ input [ OP_ADDR_W -1:0] xy_addr;
+ input [ WORD_EXT_W -1:0] x_din;
+ input [ WORD_EXT_W -1:0] y_din;
+ begin
+ wr_wide_xy_ena_reg <= xy_ena;
+ wr_wide_xy_bank_reg <= xy_bank;
+ wr_wide_xy_addr_reg <= xy_addr;
+ wr_wide_x_din_reg <= x_din;
+ wr_wide_y_din_reg <= y_din;
+ end
+ endtask
+
+ task _update_narrow;
+ input xy_ena;
+ input [BANK_ADDR_W -1:0] xy_bank;
+ input [ OP_ADDR_W -1:0] xy_addr;
+ input [ WORD_EXT_W -1:0] x_din;
+ input [ WORD_EXT_W -1:0] y_din;
+ begin
+ wr_narrow_xy_ena_reg <= xy_ena;
+ wr_narrow_xy_bank_reg <= xy_bank;
+ wr_narrow_xy_addr_reg <= xy_addr;
+ wr_narrow_x_din_reg <= x_din;
+ wr_narrow_y_din_reg <= y_din;
+ end
+ endtask
+
+ task enable_wide;
+ input [BANK_ADDR_W -1:0] xy_bank;
+ input [ OP_ADDR_W -1:0] xy_addr;
+ input [ WORD_EXT_W -1:0] x_din;
+ input [ WORD_EXT_W -1:0] y_din;
+ begin
+ _update_wide(1'b1, xy_bank, xy_addr, x_din, y_din);
+ end
+ endtask
+
+ task enable_narrow;
+ input [BANK_ADDR_W -1:0] xy_bank;
+ input [ OP_ADDR_W -1:0] xy_addr;
+ input [ WORD_EXT_W -1:0] x_din;
+ input [ WORD_EXT_W -1:0] y_din;
+ begin
+ _update_narrow(1'b1, xy_bank, xy_addr, x_din, y_din);
+ end
+ endtask
+
+ task disable_wide;
+ begin
+ _update_wide(1'b0, BANK_DONT_CARE, OP_ADDR_DONT_CARE, WORD_EXT_DONT_CARE, WORD_EXT_DONT_CARE);
+ end
+ endtask
+
+ task disable_narrow;
+ begin
+ _update_narrow(1'b0, BANK_DONT_CARE, OP_ADDR_DONT_CARE, WORD_EXT_DONT_CARE, WORD_EXT_DONT_CARE);
+ end
+ endtask
+
+ always @(posedge clk)
+ //
+ if (rst) disable_wide;
+ else begin
+ //
+ if (ext_wide_xy_ena) enable_wide(ext_wide_xy_bank, ext_wide_xy_addr, ext_wide_x_din, ext_wide_y_din);
+ else if (rcmb_wide_xy_ena) enable_wide(rcmb_wide_xy_bank, rcmb_wide_xy_addr, rcmb_wide_x_din, rcmb_wide_y_din);
+ else disable_wide;
+ //
+ end
+
+ always @(posedge clk)
+ //
+ if (rst) disable_narrow;
+ else begin
+ //
+ if (ext_narrow_xy_ena) enable_narrow(ext_narrow_xy_bank, ext_narrow_xy_addr, ext_narrow_x_din, ext_narrow_y_din);
+ else if (rcmb_narrow_xy_ena) enable_narrow(rcmb_narrow_xy_bank, rcmb_narrow_xy_addr, rcmb_narrow_x_din, rcmb_narrow_y_din);
+ else disable_narrow;
+ //
+ end
+
+ assign wr_wide_xy_ena = wr_wide_xy_ena_reg;
+ assign wr_wide_xy_bank = wr_wide_xy_bank_reg;
+ assign wr_wide_xy_addr = wr_wide_xy_addr_reg;
+ assign wr_wide_x_din = wr_wide_x_din_reg;
+ assign wr_wide_y_din = wr_wide_y_din_reg;
+
+ assign wr_narrow_xy_ena = wr_narrow_xy_ena_reg;
+ assign wr_narrow_xy_bank = wr_narrow_xy_bank_reg;
+ assign wr_narrow_xy_addr = wr_narrow_xy_addr_reg;
+ assign wr_narrow_x_din = wr_narrow_x_din_reg;
+ assign wr_narrow_y_din = wr_narrow_y_din_reg;
+
+endmodule