aboutsummaryrefslogtreecommitdiff
path: root/rtl/modexpng_core_top.v
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-03 16:40:25 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-03 16:40:25 +0300
commitaffada8d5da7426d22035360c3674ab3b3311ab5 (patch)
treea3db075dc03033db45e3ad5279badf2da48b4566 /rtl/modexpng_core_top.v
parent0b4b42da734c1164b65a334351274f946b2d4dcb (diff)
Reworked storage architecture (moved I/O memory to a separate module, since there's
only one instance of input/output values, while storage manager has dual storage space for P and Q multipliers). Started working on microcoded layer, added input operation and modular multiplication.
Diffstat (limited to 'rtl/modexpng_core_top.v')
-rw-r--r--rtl/modexpng_core_top.v1009
1 files changed, 998 insertions, 11 deletions
diff --git a/rtl/modexpng_core_top.v b/rtl/modexpng_core_top.v
index e834d37..eb6826c 100644
--- a/rtl/modexpng_core_top.v
+++ b/rtl/modexpng_core_top.v
@@ -3,7 +3,9 @@ module modexpng_core_top
clk, clk_bus,
rst,
next, valid,
- word_index_last,
+ crt_mode,
+ word_index_last_n,
+ word_index_last_pq,
bus_cs,
bus_we,
bus_addr,
@@ -16,26 +18,1011 @@ module modexpng_core_top
// Headers
//
`include "modexpng_parameters.vh"
+ `include "modexpng_microcode.vh"
//
// Ports
//
- input clk;
- input clk_bus;
+ input clk;
+ input clk_bus;
- input rst;
+ input rst;
- input next;
- output valid;
+ input next;
+ output valid;
+
+ input crt_mode;
+
+ input [ OP_ADDR_W -1:0] word_index_last_n;
+ input [ OP_ADDR_W -1:0] word_index_last_pq;
+
+ input bus_cs;
+ input bus_we;
+ input [2 + BANK_ADDR_W + BUS_OP_ADDR_W -1:0] bus_addr;
+ input [ BUS_DATA_W -1:0] bus_data_wr;
+ output [ BUS_DATA_W -1:0] bus_data_rd;
+
+
+ //
+ // UOP_FSM
+ //
+ localparam [1:0] UOP_FSM_STATE_IDLE = 2'b00;
+ localparam [1:0] UOP_FSM_STATE_FETCH = 2'b01;
+ localparam [1:0] UOP_FSM_STATE_DECODE = 2'b10;
+ localparam [1:0] UOP_FSM_STATE_BUSY = 2'b11;
+
+ reg [1:0] uop_fsm_state = UOP_FSM_STATE_IDLE;
+ reg [1:0] uop_fsm_state_next;
+
+
+ //
+ // UOP ROM
+ //
+ reg [UOP_ADDR_W -1:0] uop_addr;
+ wire [UOP_W -1:0] uop_data;
+ wire [UOP_OPCODE_W -1:0] uop_data_opcode = uop_data[UOP_W -1-: UOP_OPCODE_W];
+ wire [UOP_CRT_W -1:0] uop_data_crt = uop_data[UOP_W -UOP_OPCODE_W -1-: UOP_CRT_W ];
+ wire [UOP_NPQ_W -1:0] uop_data_npq = uop_data[UOP_W -UOP_OPCODE_W -UOP_CRT_W -1-: UOP_NPQ_W ];
+ wire [UOP_AUX_W -1:0] uop_data_aux = uop_data[UOP_W -UOP_OPCODE_W -UOP_CRT_W -UOP_NPQ_W -1-: UOP_AUX_W ];
+ wire [UOP_LADDER_W -1:0] uop_data_ladder = uop_data[UOP_W -UOP_OPCODE_W -UOP_CRT_W -UOP_NPQ_W -UOP_AUX_W -1-: UOP_LADDER_W];
+ wire [BANK_ADDR_W -1:0] uop_data_sel_wide_in = uop_data[UOP_W -UOP_OPCODE_W -UOP_CRT_W -UOP_NPQ_W -UOP_AUX_W -UOP_LADDER_W -1-: BANK_ADDR_W ];
+ wire [BANK_ADDR_W -1:0] uop_data_sel_narrow_in = uop_data[UOP_W -UOP_OPCODE_W -UOP_CRT_W -UOP_NPQ_W -UOP_AUX_W -UOP_LADDER_W -1*BANK_ADDR_W -1-: BANK_ADDR_W ];
+ wire [BANK_ADDR_W -1:0] uop_data_sel_wide_out = uop_data[UOP_W -UOP_OPCODE_W -UOP_CRT_W -UOP_NPQ_W -UOP_AUX_W -UOP_LADDER_W -2*BANK_ADDR_W -1-: BANK_ADDR_W ];
+ wire [BANK_ADDR_W -1:0] uop_data_sel_narrow_out = uop_data[UOP_W -UOP_OPCODE_W -UOP_CRT_W -UOP_NPQ_W -UOP_AUX_W -UOP_LADDER_W -3*BANK_ADDR_W -1-: BANK_ADDR_W ];
+
+ wire uop_opcode_is_stop = uop_data_opcode == UOP_OPCODE_STOP;
+ wire uop_opcode_is_io = (uop_data_opcode == UOP_OPCODE_INPUT_TO_WIDE ) ||
+ (uop_data_opcode == UOP_OPCODE_INPUT_TO_NARROW ) ||
+ (uop_data_opcode == UOP_OPCODE_OUTPUT_FROM_NARROW) ;
+ wire uop_opcode_is_mmm = uop_data_opcode == UOP_OPCODE_MODULAR_MULTIPLY;
+
+ wire [UOP_ADDR_W -1:0] uop_addr_offset = crt_mode ? UOP_ADDR_OFFSET_USING_CRT : UOP_ADDR_OFFSET_WITHOUT_CRT;
+ wire [UOP_ADDR_W -1:0] uop_addr_next = uop_addr + 1'b1;
+
+ modexpng_uop_rom uop_rom
+ (
+ .clk (clk),
+ .addr (uop_addr),
+ .data (uop_data)
+ );
+
+
+ //
+ // UOP ROM Address Logic
+ //
+
+ always @(posedge clk)
+ //
+ if (uop_fsm_state_next == UOP_FSM_STATE_FETCH)
+ uop_addr <= (uop_fsm_state == UOP_FSM_STATE_IDLE) ? uop_addr_offset : uop_addr_next;
+
+
+ //
+ // Storage Interfaces (X, Y)
+ //
+ wire wr_wide_xy_ena_x;
+ wire [BANK_ADDR_W -1:0] wr_wide_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] wr_wide_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] wr_wide_x_din_x;
+ wire [ WORD_EXT_W -1:0] wr_wide_y_din_x;
+
+ wire wr_narrow_xy_ena_x;
+ wire [BANK_ADDR_W -1:0] wr_narrow_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] wr_narrow_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] wr_narrow_x_din_x;
+ wire [ WORD_EXT_W -1:0] wr_narrow_y_din_x;
+
+ wire rd_wide_xy_ena_x;
+ wire rd_wide_xy_ena_aux_x;
+ wire [ BANK_ADDR_W -1:0] rd_wide_xy_bank_x;
+ wire [ BANK_ADDR_W -1:0] rd_wide_xy_bank_aux_x;
+ wire [NUM_MULTS_HALF * OP_ADDR_W -1:0] rd_wide_xy_addr_x;
+ wire [ OP_ADDR_W -1:0] rd_wide_xy_addr_aux_x;
+ wire [NUM_MULTS_HALF * WORD_EXT_W -1:0] rd_wide_x_dout_x;
+ wire [NUM_MULTS_HALF * WORD_EXT_W -1:0] rd_wide_y_dout_x;
+ wire [ WORD_EXT_W -1:0] rd_wide_x_dout_aux_x;
+ wire [ WORD_EXT_W -1:0] rd_wide_y_dout_aux_x;
+
+ wire rd_narrow_xy_ena_x;
+ wire [ BANK_ADDR_W -1:0] rd_narrow_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] rd_narrow_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] rd_narrow_x_dout_x;
+ wire [ WORD_EXT_W -1:0] rd_narrow_y_dout_x;
+
+ wire ext_wide_xy_ena_x;
+ wire [BANK_ADDR_W -1:0] ext_wide_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] ext_wide_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] ext_wide_x_din_x;
+ wire [ WORD_EXT_W -1:0] ext_wide_y_din_x;
+
+ wire ext_narrow_xy_ena_x;
+ wire [BANK_ADDR_W -1:0] ext_narrow_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] ext_narrow_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] ext_narrow_x_din_x;
+ wire [ WORD_EXT_W -1:0] ext_narrow_y_din_x;
+
+ wire wr_wide_xy_ena_y;
+ wire [BANK_ADDR_W -1:0] wr_wide_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] wr_wide_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] wr_wide_x_din_y;
+ wire [ WORD_EXT_W -1:0] wr_wide_y_din_y;
+
+ wire wr_narrow_xy_ena_y;
+ wire [BANK_ADDR_W -1:0] wr_narrow_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] wr_narrow_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] wr_narrow_x_din_y;
+ wire [ WORD_EXT_W -1:0] wr_narrow_y_din_y;
+
+ wire rd_wide_xy_ena_y;
+ wire rd_wide_xy_ena_aux_y;
+ wire [ BANK_ADDR_W -1:0] rd_wide_xy_bank_y;
+ wire [ BANK_ADDR_W -1:0] rd_wide_xy_bank_aux_y;
+ wire [NUM_MULTS_HALF * OP_ADDR_W -1:0] rd_wide_xy_addr_y;
+ wire [ OP_ADDR_W -1:0] rd_wide_xy_addr_aux_y;
+ wire [NUM_MULTS_HALF * WORD_EXT_W -1:0] rd_wide_x_dout_y;
+ wire [NUM_MULTS_HALF * WORD_EXT_W -1:0] rd_wide_y_dout_y;
+ wire [ WORD_EXT_W -1:0] rd_wide_x_dout_aux_y;
+ wire [ WORD_EXT_W -1:0] rd_wide_y_dout_aux_y;
+
+ wire rd_narrow_xy_ena_y;
+ wire [ BANK_ADDR_W -1:0] rd_narrow_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] rd_narrow_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] rd_narrow_x_dout_y;
+ wire [ WORD_EXT_W -1:0] rd_narrow_y_dout_y;
+
+ wire ext_wide_xy_ena_y;
+ wire [BANK_ADDR_W -1:0] ext_wide_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] ext_wide_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] ext_wide_x_din_y;
+ wire [ WORD_EXT_W -1:0] ext_wide_y_din_y;
+
+ wire ext_narrow_xy_ena_y;
+ wire [BANK_ADDR_W -1:0] ext_narrow_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] ext_narrow_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] ext_narrow_x_din_y;
+ wire [ WORD_EXT_W -1:0] ext_narrow_y_din_y;
+
+
+ //
+ // Recombinator Interfaces (X, Y)
+ //
+ wire [BANK_ADDR_W -1:0] rcmb_wide_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] rcmb_wide_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] rcmb_wide_x_dout_x;
+ wire [ WORD_EXT_W -1:0] rcmb_wide_y_dout_x;
+ wire rcmb_wide_xy_valid_x;
+
+ wire [BANK_ADDR_W -1:0] rcmb_narrow_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] rcmb_narrow_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] rcmb_narrow_x_dout_x;
+ wire [ WORD_EXT_W -1:0] rcmb_narrow_y_dout_x;
+ wire rcmb_narrow_xy_valid_x;
+
+ wire [BANK_ADDR_W -1:0] rcmb_final_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] rcmb_final_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] rcmb_final_x_dout_x;
+ wire [ WORD_EXT_W -1:0] rcmb_final_y_dout_x;
+ wire rcmb_final_xy_valid_x;
- input bus_cs;
- input bus_we;
- input [4 * (BANK_ADDR_W + BUS_OP_ADDR_W) -1:0] bus_addr;
- input [ BUS_DATA_W -1:0] bus_data_wr;
- output [ BUS_DATA_W -1:0] bus_data_rd;
+ wire [BANK_ADDR_W -1:0] rcmb_wide_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] rcmb_wide_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] rcmb_wide_x_dout_y;
+ wire [ WORD_EXT_W -1:0] rcmb_wide_y_dout_y;
+ wire rcmb_wide_xy_valid_y;
+
+ wire [BANK_ADDR_W -1:0] rcmb_narrow_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] rcmb_narrow_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] rcmb_narrow_x_dout_y;
+ wire [ WORD_EXT_W -1:0] rcmb_narrow_y_dout_y;
+ wire rcmb_narrow_xy_valid_y;
+
+ wire [BANK_ADDR_W -1:0] rcmb_final_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] rcmb_final_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] rcmb_final_x_dout_y;
+ wire [ WORD_EXT_W -1:0] rcmb_final_y_dout_y;
+ wire rcmb_final_xy_valid_y;
+
+
+ //
+ // Reductor Interfaces (X, Y)
+ //
+ wire [BANK_ADDR_W -1:0] rdct_wide_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] rdct_wide_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] rdct_wide_x_dout_x;
+ wire [ WORD_EXT_W -1:0] rdct_wide_y_dout_x;
+ wire rdct_wide_xy_valid_x;
+
+ wire [BANK_ADDR_W -1:0] rdct_narrow_xy_bank_x;
+ wire [ OP_ADDR_W -1:0] rdct_narrow_xy_addr_x;
+ wire [ WORD_EXT_W -1:0] rdct_narrow_x_dout_x;
+ wire [ WORD_EXT_W -1:0] rdct_narrow_y_dout_x;
+ wire rdct_narrow_xy_valid_x;
+
+ wire [BANK_ADDR_W -1:0] rdct_wide_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] rdct_wide_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] rdct_wide_x_dout_y;
+ wire [ WORD_EXT_W -1:0] rdct_wide_y_dout_y;
+ wire rdct_wide_xy_valid_y;
+
+ wire [BANK_ADDR_W -1:0] rdct_narrow_xy_bank_y;
+ wire [ OP_ADDR_W -1:0] rdct_narrow_xy_addr_y;
+ wire [ WORD_EXT_W -1:0] rdct_narrow_x_dout_y;
+ wire [ WORD_EXT_W -1:0] rdct_narrow_y_dout_y;
+ wire rdct_narrow_xy_valid_y;
+
+
+ //
+ // Storage Blocks (X, Y)
+ //
+ modexpng_storage_block storage_block_x
+ (
+ .clk (clk),
+ .rst (rst),
+
+ .wr_wide_xy_ena (wr_wide_xy_ena_x),
+ .wr_wide_xy_bank (wr_wide_xy_bank_x),
+ .wr_wide_xy_addr (wr_wide_xy_addr_x),
+ .wr_wide_x_din (wr_wide_x_din_x),
+ .wr_wide_y_din (wr_wide_y_din_x),
+
+ .wr_narrow_xy_ena (wr_narrow_xy_ena_x),
+ .wr_narrow_xy_bank (wr_narrow_xy_bank_x),
+ .wr_narrow_xy_addr (wr_narrow_xy_addr_x),
+ .wr_narrow_x_din (wr_narrow_x_din_x),
+ .wr_narrow_y_din (wr_narrow_y_din_x),
+
+ .rd_wide_xy_ena (rd_wide_xy_ena_x),
+ .rd_wide_xy_ena_aux (rd_wide_xy_ena_aux_x),
+ .rd_wide_xy_bank (rd_wide_xy_bank_x),
+ .rd_wide_xy_bank_aux (rd_wide_xy_bank_aux_x),
+ .rd_wide_xy_addr (rd_wide_xy_addr_x),
+ .rd_wide_xy_addr_aux (rd_wide_xy_addr_aux_x),
+ .rd_wide_x_dout (rd_wide_x_dout_x),
+ .rd_wide_y_dout (rd_wide_y_dout_x),
+ .rd_wide_x_dout_aux (rd_wide_x_dout_aux_x),
+ .rd_wide_y_dout_aux (rd_wide_y_dout_aux_x),
+
+ .rd_narrow_xy_ena (rd_narrow_xy_ena_x),
+ .rd_narrow_xy_bank (rd_narrow_xy_bank_x),
+ .rd_narrow_xy_addr (rd_narrow_xy_addr_x),
+ .rd_narrow_x_dout (rd_narrow_x_dout_x),
+ .rd_narrow_y_dout (rd_narrow_y_dout_x)
+ );
+
+ modexpng_storage_block storage_block_y
+ (
+ .clk (clk),
+ .rst (rst),
+
+ .wr_wide_xy_ena (wr_wide_xy_ena_y),
+ .wr_wide_xy_bank (wr_wide_xy_bank_y),
+ .wr_wide_xy_addr (wr_wide_xy_addr_y),
+ .wr_wide_x_din (wr_wide_x_din_y),
+ .wr_wide_y_din (wr_wide_y_din_y),
+
+ .wr_narrow_xy_ena (wr_narrow_xy_ena_y),
+ .wr_narrow_xy_bank (wr_narrow_xy_bank_y),
+ .wr_narrow_xy_addr (wr_narrow_xy_addr_y),
+ .wr_narrow_x_din (wr_narrow_x_din_y),
+ .wr_narrow_y_din (wr_narrow_y_din_y),
+
+ .rd_wide_xy_ena (rd_wide_xy_ena_y),
+ .rd_wide_xy_ena_aux (rd_wide_xy_ena_aux_y),
+ .rd_wide_xy_bank (rd_wide_xy_bank_y),
+ .rd_wide_xy_bank_aux (rd_wide_xy_bank_aux_y),
+ .rd_wide_xy_addr (rd_wide_xy_addr_y),
+ .rd_wide_xy_addr_aux (rd_wide_xy_addr_aux_y),
+ .rd_wide_x_dout (rd_wide_x_dout_y),
+ .rd_wide_y_dout (rd_wide_y_dout_y),
+ .rd_wide_x_dout_aux (rd_wide_x_dout_aux_y),
+ .rd_wide_y_dout_aux (rd_wide_y_dout_aux_y),
+
+ .rd_narrow_xy_ena (rd_narrow_xy_ena_y),
+ .rd_narrow_xy_bank (rd_narrow_xy_bank_y),
+ .rd_narrow_xy_addr (rd_narrow_xy_addr_y),
+ .rd_narrow_x_dout (rd_narrow_x_dout_y),
+ .rd_narrow_y_dout (rd_narrow_y_dout_y)
+ );
+
+
+ //
+ // Storage Managers (X, Y)
+ //
+ modexpng_storage_manager storage_manager_x
+ (
+ .clk (clk),
+ .rst (rst),
+
+ .wr_wide_xy_ena (wr_wide_xy_ena_x),
+ .wr_wide_xy_bank (wr_wide_xy_bank_x),
+ .wr_wide_xy_addr (wr_wide_xy_addr_x),
+ .wr_wide_x_din (wr_wide_x_din_x),
+ .wr_wide_y_din (wr_wide_y_din_x),
+
+ .wr_narrow_xy_ena (wr_narrow_xy_ena_x),
+ .wr_narrow_xy_bank (wr_narrow_xy_bank_x),
+ .wr_narrow_xy_addr (wr_narrow_xy_addr_x),
+ .wr_narrow_x_din (wr_narrow_x_din_x),
+ .wr_narrow_y_din (wr_narrow_y_din_x),
+
+ .ext_wide_xy_ena (ext_wide_xy_ena_x),
+ .ext_wide_xy_bank (ext_wide_xy_bank_x),
+ .ext_wide_xy_addr (ext_wide_xy_addr_x),
+ .ext_wide_x_din (ext_wide_x_din_x),
+ .ext_wide_y_din (ext_wide_y_din_x),
+
+ .ext_narrow_xy_ena (ext_narrow_xy_ena_x),
+ .ext_narrow_xy_bank (ext_narrow_xy_bank_x),
+ .ext_narrow_xy_addr (ext_narrow_xy_addr_x),
+ .ext_narrow_x_din (ext_narrow_x_din_x),
+ .ext_narrow_y_din (ext_narrow_y_din_x),
+
+ .rcmb_wide_xy_bank (rcmb_wide_xy_bank_x),
+ .rcmb_wide_xy_addr (rcmb_wide_xy_addr_x),
+ .rcmb_wide_x_din (rcmb_wide_x_dout_x),
+ .rcmb_wide_y_din (rcmb_wide_y_dout_x),
+ .rcmb_wide_xy_ena (rcmb_wide_xy_valid_x),
+
+ .rcmb_narrow_xy_bank (rcmb_narrow_xy_bank_x),
+ .rcmb_narrow_xy_addr (rcmb_narrow_xy_addr_x),
+ .rcmb_narrow_x_din (rcmb_narrow_x_dout_x),
+ .rcmb_narrow_y_din (rcmb_narrow_y_dout_x),
+ .rcmb_narrow_xy_ena (rcmb_narrow_xy_valid_x),
+
+ .rdct_wide_xy_bank (rdct_wide_xy_bank_x),
+ .rdct_wide_xy_addr (rdct_wide_xy_addr_x),
+ .rdct_wide_x_din (rdct_wide_x_dout_x), // TODO: maybe just rename to {x|y}_x, since that's an
+ .rdct_wide_y_din (rdct_wide_y_dout_x), // internal signal??
+ .rdct_wide_xy_valid (rdct_wide_xy_valid_x),
+
+ .rdct_narrow_xy_bank (rdct_narrow_xy_bank_x),
+ .rdct_narrow_xy_addr (rdct_narrow_xy_addr_x),
+ .rdct_narrow_x_din (rdct_narrow_x_dout_x),
+ .rdct_narrow_y_din (rdct_narrow_y_dout_x),
+ .rdct_narrow_xy_valid (rdct_narrow_xy_valid_x)
+ );
+
+ modexpng_storage_manager storage_manager_y
+ (
+ .clk (clk),
+ .rst (rst),
+
+ .wr_wide_xy_ena (wr_wide_xy_ena_y),
+ .wr_wide_xy_bank (wr_wide_xy_bank_y),
+ .wr_wide_xy_addr (wr_wide_xy_addr_y),
+ .wr_wide_x_din (wr_wide_x_din_y),
+ .wr_wide_y_din (wr_wide_y_din_y),
+
+ .wr_narrow_xy_ena (wr_narrow_xy_ena_y),
+ .wr_narrow_xy_bank (wr_narrow_xy_bank_y),
+ .wr_narrow_xy_addr (wr_narrow_xy_addr_y),
+ .wr_narrow_x_din (wr_narrow_x_din_y),
+ .wr_narrow_y_din (wr_narrow_y_din_y),
+
+ .ext_wide_xy_ena (ext_wide_xy_ena_y),
+ .ext_wide_xy_bank (ext_wide_xy_bank_y),
+ .ext_wide_xy_addr (ext_wide_xy_addr_y),
+ .ext_wide_x_din (ext_wide_x_din_y),
+ .ext_wide_y_din (ext_wide_y_din_y),
+
+ .ext_narrow_xy_ena (ext_narrow_xy_ena_y),
+ .ext_narrow_xy_bank (ext_narrow_xy_bank_y),
+ .ext_narrow_xy_addr (ext_narrow_xy_addr_y),
+ .ext_narrow_x_din (ext_narrow_x_din_y),
+ .ext_narrow_y_din (ext_narrow_y_din_y),
+
+ .rcmb_wide_xy_bank (rcmb_wide_xy_bank_y),
+ .rcmb_wide_xy_addr (rcmb_wide_xy_addr_y),
+ .rcmb_wide_x_din (rcmb_wide_x_dout_y),
+ .rcmb_wide_y_din (rcmb_wide_y_dout_y),
+ .rcmb_wide_xy_ena (rcmb_wide_xy_valid_y),
+
+ .rcmb_narrow_xy_bank (rcmb_narrow_xy_bank_y),
+ .rcmb_narrow_xy_addr (rcmb_narrow_xy_addr_y),
+ .rcmb_narrow_x_din (rcmb_narrow_x_dout_y),
+ .rcmb_narrow_y_din (rcmb_narrow_y_dout_y),
+ .rcmb_narrow_xy_ena (rcmb_narrow_xy_valid_y),
+
+ .rdct_wide_xy_bank (rdct_wide_xy_bank_y),
+ .rdct_wide_xy_addr (rdct_wide_xy_addr_y),
+ .rdct_wide_x_din (rdct_wide_x_dout_y),
+ .rdct_wide_y_din (rdct_wide_y_dout_y),
+ .rdct_wide_xy_valid (rdct_wide_xy_valid_y),
+
+ .rdct_narrow_xy_bank (rdct_narrow_xy_bank_y),
+ .rdct_narrow_xy_addr (rdct_narrow_xy_addr_y),
+ .rdct_narrow_x_din (rdct_narrow_x_dout_y),
+ .rdct_narrow_y_din (rdct_narrow_y_dout_y),
+ .rdct_narrow_xy_valid (rdct_narrow_xy_valid_y)
+
+ );
+
+
+ //
+ // IO Block
+ //
+ wire io_in_1_en;
+ wire [BANK_ADDR_W + OP_ADDR_W -1:0] io_in_1_addr;
+ wire [ WORD_W -1:0] io_in_1_dout;
+ wire io_in_2_en;
+ wire [BANK_ADDR_W + OP_ADDR_W -1:0] io_in_2_addr;
+ wire [ WORD_W -1:0] io_in_2_dout;
+ wire io_out_en;
+ wire io_out_we;
+ wire [BANK_ADDR_W + OP_ADDR_W -1:0] io_out_addr;
+ wire [ WORD_W -1:0] io_out_din;
+
+ // TODO: Separate reset for clock domains (core/bus)???
+
+ modexpng_io_block io_block
+ (
+ .clk (clk),
+ .clk_bus (clk_bus),
+
+ .rst (rst),
+
+ .bus_cs (bus_cs),
+ .bus_we (bus_we),
+ .bus_addr (bus_addr),
+ .bus_data_wr (bus_data_wr),
+ .bus_data_rd (bus_data_rd),
+
+ .in_1_en (io_in_1_en),
+ .in_1_addr (io_in_1_addr),
+ .in_1_dout (io_in_1_dout),
+
+ .in_2_en (io_in_2_en),
+ .in_2_addr (io_in_2_addr),
+ .in_2_dout (io_in_2_dout),
+
+ .out_en (io_out_en),
+ .out_we (io_out_we),
+ .out_addr (io_out_addr),
+ .out_din (io_out_din)
+ );
+
+
+ //
+ // IO Manager
+ //
+ reg io_mgr_ena = 1'b0;
+ wire io_mgr_rdy;
+ reg [UOP_CRT_W -1:0] io_mgr_sel_crt;
+ reg [UOP_AUX_W -1:0] io_mgr_sel_aux;
+ reg [BANK_ADDR_W -1:0] io_mgr_sel_in;
+ reg [BANK_ADDR_W -1:0] io_mgr_sel_out;
+ reg [OP_ADDR_W -1:0] io_mgr_word_index_last;
+ reg [UOP_OPCODE_W -1:0] io_mgr_opcode;
+
+ modexpng_io_manager io_manager
+ (
+ .clk (clk),
+ .rst (rst),
+
+ .ena (io_mgr_ena),
+ .rdy (io_mgr_rdy),
+
+ .sel_crt (io_mgr_sel_crt),
+ .sel_aux (io_mgr_sel_aux),
+ .sel_in (io_mgr_sel_in),
+ .sel_out (io_mgr_sel_out),
+
+ .opcode (io_mgr_opcode),
+
+ .word_index_last (io_mgr_word_index_last),
+
+ .ext_wide_xy_ena_x (ext_wide_xy_ena_x),
+ .ext_wide_xy_bank_x (ext_wide_xy_bank_x),
+ .ext_wide_xy_addr_x (ext_wide_xy_addr_x),
+ .ext_wide_x_din_x (ext_wide_x_din_x),
+ .ext_wide_y_din_x (ext_wide_y_din_x),
+
+ .ext_narrow_xy_ena_x (ext_narrow_xy_ena_x),
+ .ext_narrow_xy_bank_x (ext_narrow_xy_bank_x),
+ .ext_narrow_xy_addr_x (ext_narrow_xy_addr_x),
+ .ext_narrow_x_din_x (ext_narrow_x_din_x),
+ .ext_narrow_y_din_x (ext_narrow_y_din_x),
+
+ .ext_wide_xy_ena_y (ext_wide_xy_ena_y),
+ .ext_wide_xy_bank_y (ext_wide_xy_bank_y),
+ .ext_wide_xy_addr_y (ext_wide_xy_addr_y),
+ .ext_wide_x_din_y (ext_wide_x_din_y),
+ .ext_wide_y_din_y (ext_wide_y_din_y),
+
+ .ext_narrow_xy_ena_y (ext_narrow_xy_ena_y),
+ .ext_narrow_xy_bank_y (ext_narrow_xy_bank_y),
+ .ext_narrow_xy_addr_y (ext_narrow_xy_addr_y),
+ .ext_narrow_x_din_y (ext_narrow_x_din_y),
+ .ext_narrow_y_din_y (ext_narrow_y_din_y),
+
+ .io_in_1_en (io_in_1_en),
+ .io_in_1_addr (io_in_1_addr),
+ .io_in_1_dout (io_in_1_dout),
+
+ .io_in_2_en (io_in_2_en),
+ .io_in_2_addr (io_in_2_addr),
+ .io_in_2_dout (io_in_2_dout),
+
+ .io_out_en (io_out_en),
+ .io_out_we (io_out_we),
+ .io_out_addr (io_out_addr),
+ .io_out_din (io_out_din)
+ );
+
+
+ //
+ // Multipliers (X, Y)
+ //
+ reg mmm_ena_x = 1'b0;
+ reg mmm_ena_y = 1'b0;
+ wire mmm_ena = mmm_ena_x & mmm_ena_y;
+
+ wire mmm_rdy_x;
+ wire mmm_rdy_y;
+ wire mmm_rdy = mmm_rdy_x & mmm_rdy_y;
+
+ reg [OP_ADDR_W -1:0] mmm_word_index_last_x;
+ reg [OP_ADDR_W -1:0] mmm_word_index_last_y;
+
+ reg [OP_ADDR_W -1:0] mmm_word_index_last_minus1_x;
+ reg [OP_ADDR_W -1:0] mmm_word_index_last_minus1_y;
+
+ reg mmm_ladder_mode_x;
+ reg mmm_ladder_mode_y;
+
+ reg [BANK_ADDR_W -1:0] mmm_sel_wide_in_x;
+ reg [BANK_ADDR_W -1:0] mmm_sel_wide_in_y;
+ reg [BANK_ADDR_W -1:0] mmm_sel_narrow_in_x;
+ reg [BANK_ADDR_W -1:0] mmm_sel_narrow_in_y;
+
+ wire rdct_ena_x;
+ wire rdct_ena_y;
+ wire rdct_rdy_x;
+ wire rdct_rdy_y;
+
+ modexpng_mmm_dual mmm_x
+ (
+ .clk (clk),
+ .rst (rst),
+
+ .ena (mmm_ena_x),
+ .rdy (mmm_rdy_x),
+
+ .ladder_mode (mmm_ladder_mode_x),
+ .word_index_last (mmm_word_index_last_x),
+ .word_index_last_minus1 (mmm_word_index_last_minus1_x),
+
+ .sel_wide_in (mmm_sel_wide_in_x),
+ .sel_narrow_in (mmm_sel_narrow_in_x),
+
+ .rd_wide_xy_ena (rd_wide_xy_ena_x),
+ .rd_wide_xy_ena_aux (rd_wide_xy_ena_aux_x),
+ .rd_wide_xy_bank (rd_wide_xy_bank_x),
+ .rd_wide_xy_bank_aux (rd_wide_xy_bank_aux_x),
+ .rd_wide_xy_addr (rd_wide_xy_addr_x),
+ .rd_wide_xy_addr_aux (rd_wide_xy_addr_aux_x),
+ .rd_wide_x_dout (rd_wide_x_dout_x),
+ .rd_wide_y_dout (rd_wide_y_dout_x),
+ .rd_wide_x_dout_aux (rd_wide_x_dout_aux_x),
+ .rd_wide_y_dout_aux (rd_wide_y_dout_aux_x),
+
+ .rd_narrow_xy_ena (rd_narrow_xy_ena_x),
+ .rd_narrow_xy_bank (rd_narrow_xy_bank_x),
+ .rd_narrow_xy_addr (rd_narrow_xy_addr_x),
+ .rd_narrow_x_dout (rd_narrow_x_dout_x),
+ .rd_narrow_y_dout (rd_narrow_y_dout_x),
+
+ .rcmb_wide_xy_bank (rcmb_wide_xy_bank_x),
+ .rcmb_wide_xy_addr (rcmb_wide_xy_addr_x),
+ .rcmb_wide_x_dout (rcmb_wide_x_dout_x),
+ .rcmb_wide_y_dout (rcmb_wide_y_dout_x),
+ .rcmb_wide_xy_valid (rcmb_wide_xy_valid_x),
+
+ .rcmb_narrow_xy_bank (rcmb_narrow_xy_bank_x),
+ .rcmb_narrow_xy_addr (rcmb_narrow_xy_addr_x),
+ .rcmb_narrow_x_dout (rcmb_narrow_x_dout_x),
+ .rcmb_narrow_y_dout (rcmb_narrow_y_dout_x),
+ .rcmb_narrow_xy_valid (rcmb_narrow_xy_valid_x),
+
+ .rcmb_xy_bank (rcmb_final_xy_bank_x),
+ .rcmb_xy_addr (rcmb_final_xy_addr_x),
+ .rcmb_x_dout (rcmb_final_x_dout_x),
+ .rcmb_y_dout (rcmb_final_y_dout_x),
+ .rcmb_xy_valid (rcmb_final_xy_valid_x),
+
+ .rdct_ena (rdct_ena_x),
+ .rdct_rdy (rdct_rdy_x)
+ );
+
+ modexpng_mmm_dual mmm_y
+ (
+ .clk (clk),
+ .rst (rst),
+
+ .ena (mmm_ena_y),
+ .rdy (mmm_rdy_y),
+
+ .ladder_mode (mmm_ladder_mode_y),
+ .word_index_last (mmm_word_index_last_y),
+ .word_index_last_minus1 (mmm_word_index_last_minus1_y),
+
+ .sel_wide_in (mmm_sel_wide_in_y),
+ .sel_narrow_in (mmm_sel_narrow_in_y),
+
+ .rd_wide_xy_ena (rd_wide_xy_ena_y),
+ .rd_wide_xy_ena_aux (rd_wide_xy_ena_aux_y),
+ .rd_wide_xy_bank (rd_wide_xy_bank_y),
+ .rd_wide_xy_bank_aux (rd_wide_xy_bank_aux_y),
+ .rd_wide_xy_addr (rd_wide_xy_addr_y),
+ .rd_wide_xy_addr_aux (rd_wide_xy_addr_aux_y),
+ .rd_wide_x_dout (rd_wide_x_dout_y),
+ .rd_wide_y_dout (rd_wide_y_dout_y),
+ .rd_wide_x_dout_aux (rd_wide_x_dout_aux_y),
+ .rd_wide_y_dout_aux (rd_wide_y_dout_aux_y),
+
+ .rd_narrow_xy_ena (rd_narrow_xy_ena_y),
+ .rd_narrow_xy_bank (rd_narrow_xy_bank_y),
+ .rd_narrow_xy_addr (rd_narrow_xy_addr_y),
+ .rd_narrow_x_dout (rd_narrow_x_dout_y),
+ .rd_narrow_y_dout (rd_narrow_y_dout_y),
+
+ .rcmb_wide_xy_bank (rcmb_wide_xy_bank_y),
+ .rcmb_wide_xy_addr (rcmb_wide_xy_addr_y),
+ .rcmb_wide_x_dout (rcmb_wide_x_dout_y),
+ .rcmb_wide_y_dout (rcmb_wide_y_dout_y),
+ .rcmb_wide_xy_valid (rcmb_wide_xy_valid_y),
+
+ .rcmb_narrow_xy_bank (rcmb_narrow_xy_bank_y),
+ .rcmb_narrow_xy_addr (rcmb_narrow_xy_addr_y),
+ .rcmb_narrow_x_dout (rcmb_narrow_x_dout_y),
+ .rcmb_narrow_y_dout (rcmb_narrow_y_dout_y),
+ .rcmb_narrow_xy_valid (rcmb_narrow_xy_valid_y),
+
+ .rcmb_xy_bank (rcmb_final_xy_bank_y),
+ .rcmb_xy_addr (rcmb_final_xy_addr_y),
+ .rcmb_x_dout (rcmb_final_x_dout_y),
+ .rcmb_y_dout (rcmb_final_y_dout_y),
+ .rcmb_xy_valid (rcmb_final_xy_valid_y),
+
+ .rdct_ena (rdct_ena_y),
+ .rdct_rdy (rdct_rdy_y)
+ );
+
+ //
+ // Reductors (X, Y)
+ //
+ reg [ OP_ADDR_W -1:0] rdct_word_index_last_x;
+ reg [ OP_ADDR_W -1:0] rdct_word_index_last_y;
+
+ reg [BANK_ADDR_W -1:0] rdct_sel_wide_out_x;
+ reg [BANK_ADDR_W -1:0] rdct_sel_narrow_out_x;
+
+ reg [BANK_ADDR_W -1:0] rdct_sel_wide_out_y;
+ reg [BANK_ADDR_W -1:0] rdct_sel_narrow_out_y;
+
+ modexpng_reductor reductor_x
+ (
+ .clk (clk),
+ .rst (rst),
+
+ .ena (rdct_ena_x),
+ .rdy (rdct_rdy_x),
+
+ .word_index_last (rdct_word_index_last_x),
+
+ .sel_wide_out (rdct_sel_wide_out_x),
+ .sel_narrow_out (rdct_sel_narrow_out_x),
+
+ .rd_wide_xy_addr_aux (rd_wide_xy_addr_aux_x),
+ .rd_wide_xy_bank_aux (rd_wide_xy_bank_aux_x),
+ .rd_wide_x_dout_aux (rd_wide_x_dout_aux_x),
+ .rd_wide_y_dout_aux (rd_wide_y_dout_aux_x),
+
+ .rcmb_final_xy_bank (rcmb_final_xy_bank_x),
+ .rcmb_final_xy_addr (rcmb_final_xy_addr_x),
+ .rcmb_final_x_dout (rcmb_final_x_dout_x),
+ .rcmb_final_y_dout (rcmb_final_y_dout_x),
+ .rcmb_final_xy_valid (rcmb_final_xy_valid_x),
+
+ .rdct_wide_xy_bank (rdct_wide_xy_bank_x),
+ .rdct_wide_xy_addr (rdct_wide_xy_addr_x),
+ .rdct_wide_x_dout (rdct_wide_x_dout_x),
+ .rdct_wide_y_dout (rdct_wide_y_dout_x),
+ .rdct_wide_xy_valid (rdct_wide_xy_valid_x),
+
+ .rdct_narrow_xy_bank (rdct_narrow_xy_bank_x),
+ .rdct_narrow_xy_addr (rdct_narrow_xy_addr_x),
+ .rdct_narrow_x_dout (rdct_narrow_x_dout_x),
+ .rdct_narrow_y_dout (rdct_narrow_y_dout_x),
+ .rdct_narrow_xy_valid (rdct_narrow_xy_valid_x)
+ );
+
+ modexpng_reductor reductor_y
+ (
+ .clk (clk),
+ .rst (rst),
+
+ .ena (rdct_ena_y),
+ .rdy (rdct_rdy_y),
+
+ .word_index_last (rdct_word_index_last_y),
+
+ .sel_wide_out (rdct_sel_wide_out_y),
+ .sel_narrow_out (rdct_sel_narrow_out_y),
+
+ .rd_wide_xy_addr_aux (rd_wide_xy_addr_aux_y),
+ .rd_wide_xy_bank_aux (rd_wide_xy_bank_aux_y),
+ .rd_wide_x_dout_aux (rd_wide_x_dout_aux_y),
+ .rd_wide_y_dout_aux (rd_wide_y_dout_aux_y),
+
+ .rcmb_final_xy_bank (rcmb_final_xy_bank_y),
+ .rcmb_final_xy_addr (rcmb_final_xy_addr_y),
+ .rcmb_final_x_dout (rcmb_final_x_dout_y),
+ .rcmb_final_y_dout (rcmb_final_y_dout_y),
+ .rcmb_final_xy_valid (rcmb_final_xy_valid_y),
+
+ .rdct_wide_xy_bank (rdct_wide_xy_bank_y),
+ .rdct_wide_xy_addr (rdct_wide_xy_addr_y),
+ .rdct_wide_x_dout (rdct_wide_x_dout_y),
+ .rdct_wide_y_dout (rdct_wide_y_dout_y),
+ .rdct_wide_xy_valid (rdct_wide_xy_valid_y),
+
+ .rdct_narrow_xy_bank (rdct_narrow_xy_bank_y),
+ .rdct_narrow_xy_addr (rdct_narrow_xy_addr_y),
+ .rdct_narrow_x_dout (rdct_narrow_x_dout_y),
+ .rdct_narrow_y_dout (rdct_narrow_y_dout_y),
+ .rdct_narrow_xy_valid (rdct_narrow_xy_valid_y)
+ );
+
+
+ //
+ // uOP Completion Detector
+ //
+ reg uop_exit_from_busy;
+
+ always @* begin
+ //
+ uop_exit_from_busy = 0;
+ //
+ if (uop_opcode_is_io) uop_exit_from_busy = ~io_mgr_ena & io_mgr_rdy;
+ if (uop_opcode_is_mmm) uop_exit_from_busy = ~mmm_ena & mmm_rdy;
+ //if (uop_data_opcode_is_add) uop_exit_from_busy = ~mod_add_ena & mod_add_rdy;
+ //if (uop_data_opcode_is_sub) uop_exit_from_busy = ~mod_sub_ena & mod_sub_rdy;
+ //
+ end
+
+
+ //
+ // uOP Trigger Logic
+ //
+ always @(posedge clk)
+ //
+ if (rst) begin
+ io_mgr_ena <= 1'b0;
+ mmm_ena_x <= 1'b0;
+ mmm_ena_y <= 1'b0;
+ end else begin
+ io_mgr_ena <= uop_fsm_state == UOP_FSM_STATE_DECODE ? uop_opcode_is_io : 1'b0;
+ mmm_ena_x <= uop_fsm_state == UOP_FSM_STATE_DECODE ? uop_opcode_is_mmm : 1'b0;
+ mmm_ena_y <= uop_fsm_state == UOP_FSM_STATE_DECODE ? uop_opcode_is_mmm : 1'b0;
+ end
+
+ //
+ // Parameters
+ //
+ always @(posedge clk)
+ //
+ if (uop_fsm_state == UOP_FSM_STATE_DECODE) begin
+ //
+ io_mgr_opcode <= uop_data_opcode;
+ //
+ case (uop_data_opcode)
+ //
+ UOP_OPCODE_INPUT_TO_WIDE: begin
+ io_mgr_sel_crt <= uop_data_crt;
+ io_mgr_sel_aux <= uop_data_aux;
+ io_mgr_sel_in <= uop_data_sel_narrow_in;
+ io_mgr_sel_out <= uop_data_sel_wide_out;
+ end
+ //
+ UOP_OPCODE_INPUT_TO_NARROW: begin
+ io_mgr_sel_crt <= uop_data_crt;
+ io_mgr_sel_aux <= uop_data_aux;
+ io_mgr_sel_in <= uop_data_sel_narrow_in;
+ io_mgr_sel_out <= uop_data_sel_narrow_out;
+ end
+ //
+ UOP_OPCODE_MODULAR_MULTIPLY: begin
+ //
+ case (uop_data_ladder)
+ UOP_LADDER_00: {mmm_ladder_mode_x, mmm_ladder_mode_y} <= 2'b00;
+ UOP_LADDER_11: {mmm_ladder_mode_x, mmm_ladder_mode_y} <= 2'b11;
+ UOP_LADDER_D: {mmm_ladder_mode_x, mmm_ladder_mode_y} <= 2'bXX;
+ UOP_LADDER_PQ: {mmm_ladder_mode_x, mmm_ladder_mode_y} <= 2'bXX;
+ endcase
+ //
+ {mmm_sel_wide_in_x, mmm_sel_wide_in_y } <= {2{uop_data_sel_wide_in }};
+ {mmm_sel_narrow_in_x, mmm_sel_narrow_in_y } <= {2{uop_data_sel_narrow_in }};
+ {rdct_sel_wide_out_x, rdct_sel_wide_out_y } <= {2{uop_data_sel_wide_out }};
+ {rdct_sel_narrow_out_x, rdct_sel_narrow_out_y} <= {2{uop_data_sel_narrow_out}};
+
+ //
+ end
+ //
+ endcase
+ //
+ end
+
+ //
+ // Length
+ //
+ wire [OP_ADDR_W -1:0] word_index_last_n_minus1 = word_index_last_n - 1'b1;
+ wire [OP_ADDR_W -1:0] word_index_last_pq_minus1 = word_index_last_pq - 1'b1;
+
+ wire uop_npq_is_n = uop_data_npq == UOP_NPQ_N;
+
+ always @(posedge clk)
+ //
+ if (uop_fsm_state == UOP_FSM_STATE_DECODE) begin
+ //
+ case (uop_data_opcode)
+ //
+ UOP_OPCODE_INPUT_TO_WIDE,
+ UOP_OPCODE_INPUT_TO_NARROW: io_mgr_word_index_last <= uop_npq_is_n ? word_index_last_n : word_index_last_pq;
+ //
+ UOP_OPCODE_MODULAR_MULTIPLY: begin
+ {mmm_word_index_last_x, mmm_word_index_last_y } <= {2{uop_npq_is_n ? word_index_last_n : word_index_last_pq }};
+ {mmm_word_index_last_minus1_x, mmm_word_index_last_minus1_y} <= {2{uop_npq_is_n ? word_index_last_n_minus1 : word_index_last_pq_minus1}};
+ {rdct_word_index_last_x, rdct_word_index_last_y } <= {2{uop_npq_is_n ? word_index_last_n : word_index_last_pq }};
+ end
+ //
+ endcase
+ //
+ end
+
+
+
+ //
+ // FSM Process
+ //
+ always @(posedge clk)
+ //
+ if (rst) uop_fsm_state <= UOP_FSM_STATE_IDLE;
+ else uop_fsm_state <= uop_fsm_state_next;
+
+
+ //
+ // FSM Transition Logic
+ //
+ always @* begin
+ //
+ case (uop_fsm_state)
+ UOP_FSM_STATE_IDLE: uop_fsm_state_next = next ? UOP_FSM_STATE_FETCH : UOP_FSM_STATE_IDLE;
+ UOP_FSM_STATE_FETCH: uop_fsm_state_next = UOP_FSM_STATE_DECODE ;
+ UOP_FSM_STATE_DECODE: uop_fsm_state_next = uop_opcode_is_stop ? UOP_FSM_STATE_IDLE : UOP_FSM_STATE_BUSY;
+ UOP_FSM_STATE_BUSY: uop_fsm_state_next = uop_exit_from_busy ? UOP_FSM_STATE_FETCH : UOP_FSM_STATE_BUSY;
+ endcase
+ //
+ end
+
+
+ //
+ // Ready Flag Logic
+ //
+ reg valid_reg = 1'b1;
+ assign valid = valid_reg;
+
+ always @(posedge clk)
+ //
+ if (rst) valid_reg <= 1'b1;
+ else case (uop_fsm_state)
+ UOP_FSM_STATE_IDLE: valid_reg <= ~next;
+ UOP_FSM_STATE_DECODE: valid_reg <= uop_opcode_is_stop;
+ endcase
+
+
+
+ //
+ // BEGIN DEBUG
+ //
+ integer i;
+ always @(posedge clk)
+ //
+ if ((uop_fsm_state == UOP_FSM_STATE_DECODE) && uop_opcode_is_stop) begin
+ //
+ $display("STOP - BANKS DUMP FOLLOWS");
+ //
+ // X.X
+ //
+ $write(" "); for (i=0; i<64; i=i+1) $write("[ %3d ] ", i); $write("\n");
+ $write("X.X.NARROW.A: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_x.mem[0*256+i]); $write("\n");
+ $write("X.X.NARROW.B: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_x.mem[1*256+i]); $write("\n");
+ $write("X.X.NARROW.C: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_x.mem[2*256+i]); $write("\n");
+ $write("X.X.NARROW.D: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_x.mem[3*256+i]); $write("\n");
+ $write("X.X.NARROW.E: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_x.mem[4*256+i]); $write("\n");
+ $write("X.X.NARROW.COEFF: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_x.mem[5*256+i]); $write("\n");
+ $write("X.X.NARROW.Q: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_x.mem[6*256+i]); $write("\n");
+ $write("X.X.NARROW.EXT: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_x.mem[7*256+i]); $write("\n");
+ $write(" "); for (i=0; i<64; i=i+1) $write(" ------ "); $write("\n");
+ $write("X.X.WIDE.A: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_x.mem[0*256+i]); $write("\n");
+ $write("X.X.WIDE.B: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_x.mem[1*256+i]); $write("\n");
+ $write("X.X.WIDE.C: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_x.mem[2*256+i]); $write("\n");
+ $write("X.X.WIDE.D: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_x.mem[3*256+i]); $write("\n");
+ $write("X.X.WIDE.E: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_x.mem[4*256+i]); $write("\n");
+ $write("X.X.WIDE.N: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_x.mem[5*256+i]); $write("\n");
+ $write("X.X.WIDE.L: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_x.mem[6*256+i]); $write("\n");
+ $write("X.X.WIDE.H: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_x.mem[7*256+i]); $write("\n");
+ //
+ // X.Y
+ //
+ $write(" "); for (i=0; i<64; i=i+1) $write("[ %3d ] ", i); $write("\n");
+ $write("X.Y.NARROW.A: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_y.mem[0*256+i]); $write("\n");
+ $write("X.Y.NARROW.B: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_y.mem[1*256+i]); $write("\n");
+ $write("X.Y.NARROW.C: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_y.mem[2*256+i]); $write("\n");
+ $write("X.Y.NARROW.D: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_y.mem[3*256+i]); $write("\n");
+ $write("X.Y.NARROW.E: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_y.mem[4*256+i]); $write("\n");
+ $write("X.Y.NARROW.COEFF: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_y.mem[5*256+i]); $write("\n");
+ $write("X.Y.NARROW.Q: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_y.mem[6*256+i]); $write("\n");
+ $write("X.Y.NARROW.EXT: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.narrow_bram_y.mem[7*256+i]); $write("\n");
+ $write(" "); for (i=0; i<64; i=i+1) $write(" ------ "); $write("\n");
+ $write("X.Y.WIDE.A: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_y.mem[0*256+i]); $write("\n");
+ $write("X.Y.WIDE.B: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_y.mem[1*256+i]); $write("\n");
+ $write("X.Y.WIDE.C: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_y.mem[2*256+i]); $write("\n");
+ $write("X.Y.WIDE.D: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_y.mem[3*256+i]); $write("\n");
+ $write("X.Y.WIDE.E: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_y.mem[4*256+i]); $write("\n");
+ $write("X.Y.WIDE.N: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_y.mem[5*256+i]); $write("\n");
+ $write("X.Y.WIDE.L: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_y.mem[6*256+i]); $write("\n");
+ $write("X.Y.WIDE.H: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_x.gen_wide_bram[0].wide_bram_y.mem[7*256+i]); $write("\n");
+ //
+ // Y.X
+ //
+ $write(" "); for (i=0; i<64; i=i+1) $write("[ %3d ] ", i); $write("\n");
+ $write("Y.X.NARROW.A: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_x.mem[0*256+i]); $write("\n");
+ $write("Y.X.NARROW.B: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_x.mem[1*256+i]); $write("\n");
+ $write("Y.X.NARROW.C: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_x.mem[2*256+i]); $write("\n");
+ $write("Y.X.NARROW.D: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_x.mem[3*256+i]); $write("\n");
+ $write("Y.X.NARROW.E: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_x.mem[4*256+i]); $write("\n");
+ $write("Y.X.NARROW.COEFF: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_x.mem[5*256+i]); $write("\n");
+ $write("Y.X.NARROW.Q: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_x.mem[6*256+i]); $write("\n");
+ $write("Y.X.NARROW.EXT: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_x.mem[7*256+i]); $write("\n");
+ $write(" "); for (i=0; i<64; i=i+1) $write(" ------ "); $write("\n");
+ $write("Y.X.WIDE.A: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_x.mem[0*256+i]); $write("\n");
+ $write("Y.X.WIDE.B: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_x.mem[1*256+i]); $write("\n");
+ $write("Y.X.WIDE.C: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_x.mem[2*256+i]); $write("\n");
+ $write("Y.X.WIDE.D: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_x.mem[3*256+i]); $write("\n");
+ $write("Y.X.WIDE.E: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_x.mem[4*256+i]); $write("\n");
+ $write("Y.X.WIDE.N: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_x.mem[5*256+i]); $write("\n");
+ $write("Y.X.WIDE.L: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_x.mem[6*256+i]); $write("\n");
+ $write("Y.X.WIDE.H: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_x.mem[7*256+i]); $write("\n");
+ //
+ // Y.Y
+ //
+ $write(" "); for (i=0; i<64; i=i+1) $write("[ %3d ] ", i); $write("\n");
+ $write("Y.Y.NARROW.A: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_y.mem[0*256+i]); $write("\n");
+ $write("Y.Y.NARROW.B: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_y.mem[1*256+i]); $write("\n");
+ $write("Y.Y.NARROW.C: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_y.mem[2*256+i]); $write("\n");
+ $write("Y.Y.NARROW.D: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_y.mem[3*256+i]); $write("\n");
+ $write("Y.Y.NARROW.E: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_y.mem[4*256+i]); $write("\n");
+ $write("Y.Y.NARROW.COEFF: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_y.mem[5*256+i]); $write("\n");
+ $write("Y.Y.NARROW.Q: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_y.mem[6*256+i]); $write("\n");
+ $write("Y.Y.NARROW.EXT: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.narrow_bram_y.mem[7*256+i]); $write("\n");
+ $write(" "); for (i=0; i<64; i=i+1) $write(" ------ "); $write("\n");
+ $write("Y.Y.WIDE.A: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_y.mem[0*256+i]); $write("\n");
+ $write("Y.Y.WIDE.B: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_y.mem[1*256+i]); $write("\n");
+ $write("Y.Y.WIDE.C: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_y.mem[2*256+i]); $write("\n");
+ $write("Y.Y.WIDE.D: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_y.mem[3*256+i]); $write("\n");
+ $write("Y.Y.WIDE.E: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_y.mem[4*256+i]); $write("\n");
+ $write("Y.Y.WIDE.N: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_y.mem[5*256+i]); $write("\n");
+ $write("Y.Y.WIDE.L: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_y.mem[6*256+i]); $write("\n");
+ $write("Y.Y.WIDE.H: "); for (i=0; i<64; i=i+1) $write("0x%05x ", storage_block_y.gen_wide_bram[0].wide_bram_y.mem[7*256+i]); $write("\n"); //
+ end
+
+ //
+ // END DEBUG
+ //
endmodule