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 "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 [ 7:0] rcmb_wide_xy_addr;
input [17:0] rcmb_wide_x_din;
input [17:0] rcmb_wide_y_din;
input rcmb_narrow_xy_ena;
input [ BANK_ADDR_W -1:0] rcmb_narrow_xy_bank;
input [ 7:0] rcmb_narrow_xy_addr;
input [17:0] rcmb_narrow_x_din;
input [17: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