aboutsummaryrefslogtreecommitdiff
path: root/rtl/modexpng_io_block.v
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/modexpng_io_block.v')
-rw-r--r--rtl/modexpng_io_block.v158
1 files changed, 158 insertions, 0 deletions
diff --git a/rtl/modexpng_io_block.v b/rtl/modexpng_io_block.v
new file mode 100644
index 0000000..68d13c4
--- /dev/null
+++ b/rtl/modexpng_io_block.v
@@ -0,0 +1,158 @@
+module modexpng_io_block
+(
+ clk, clk_bus, rst,
+
+ bus_cs,
+ bus_we,
+ bus_addr,
+ bus_data_wr,
+ bus_data_rd,
+
+ in_1_en,
+ in_1_addr,
+ in_1_dout,
+
+ in_2_en,
+ in_2_addr,
+ in_2_dout,
+
+ out_en,
+ out_we,
+ out_addr,
+ out_din
+);
+
+ //
+ // Headers
+ //
+ `include "modexpng_parameters.vh"
+
+
+ //
+ // Ports
+ //
+ input clk;
+ input clk_bus;
+ input rst;
+
+ 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;
+
+ input in_1_en;
+ input [ BANK_ADDR_W + OP_ADDR_W -1:0] in_1_addr;
+ output [ WORD_W -1:0] in_1_dout;
+
+ input in_2_en;
+ input [ BANK_ADDR_W + OP_ADDR_W -1:0] in_2_addr;
+ output [ WORD_W -1:0] in_2_dout;
+
+ input out_en;
+ input out_we;
+ input [ BANK_ADDR_W + OP_ADDR_W -1:0] out_addr;
+ input [ WORD_W -1:0] out_din;
+
+
+ //
+ // Internal Registers
+ //
+ reg in_1_reg_en = 1'b0;
+ reg in_2_reg_en = 1'b0;
+
+ always @(posedge clk)
+ //
+ if (rst) begin
+ in_1_reg_en <= 1'b0;
+ in_2_reg_en <= 1'b0;
+ end else begin
+ in_1_reg_en <= in_1_en;
+ in_2_reg_en <= in_2_en;
+ end
+
+
+ //
+ // INPUT, OUTPUT Storage Buffers
+ //
+ wire [ 2 -1:0] bus_addr_msb = bus_addr[BANK_ADDR_W + BUS_OP_ADDR_W +: 2];
+ wire [BANK_ADDR_W + BUS_OP_ADDR_W -1:0] bus_addr_lsb = bus_addr[BANK_ADDR_W + BUS_OP_ADDR_W -1:0];
+ reg [ 2 -1:0] bus_addr_msb_dly;
+ wire [ BUS_DATA_W -1:0] bus_data_rd_input_1;
+ wire [ BUS_DATA_W -1:0] bus_data_rd_output;
+
+ wire bus_data_wr_input_1 = bus_data_wr && (bus_addr_msb == 2'd0);
+ wire bus_data_wr_input_2 = bus_data_wr && (bus_addr_msb == 2'd1);
+
+ /* INPUT_1 */
+ modexpng_tdp_36k_x16_x32_wrapper bram_input_1
+ (
+ .clk (clk), // core clock
+ .clk_bus (clk_bus), // bus clock
+
+ .ena (bus_cs), // bus side read-write
+ .wea (bus_data_wr_input_1), //
+ .addra (bus_addr_lsb), //
+ .dina (bus_data_wr), //
+ .douta (bus_data_rd_input_1), //
+
+ .enb (in_1_en), // core side read-only
+ .regceb (in_1_reg_en), //
+ .addrb (in_1_addr), //
+ .doutb (in_1_dout) //
+ );
+
+
+ /* INPUT_2 */
+ modexpng_sdp_36k_x16_x32_wrapper bram_input_2
+ (
+ .clk (clk), // core clock
+ .clk_bus (clk_bus), // bus clock
+
+ .ena (bus_cs), // bus side write-only
+ .wea (bus_data_wr_input_2), //
+ .addra (bus_addr_lsb), //
+ .dina (bus_data_wr), //
+
+ .enb (in_2_en), // core side read-only
+ .regceb (in_2_reg_en), //
+ .addrb (in_2_addr), //
+ .doutb (in_2_dout) //
+ );
+
+
+ /* OUTPUT */
+ modexpng_sdp_36k_x32_x16_wrapper bram_output
+ (
+ .clk (clk), // core clock
+ .clk_bus (clk_bus), // bus clock
+
+ .ena (out_en), // core side write-only
+ .wea (out_we), //
+ .addra (out_addr), //
+ .dina (out_din), //
+
+ .enb (bus_cs), // bus side read-only
+ .addrb (bus_addr_lsb), //
+ .doutb (bus_data_rd_output) //
+ );
+
+ reg [31: 0] bus_data_rd_mux;
+ assign bus_data_rd = bus_data_rd_mux;
+
+ always @(posedge clk_bus)
+ bus_addr_msb_dly <= bus_addr_msb;
+
+ always @(*)
+ //
+ case (bus_addr_msb_dly)
+ //
+ 2'd0: bus_data_rd_mux = bus_data_rd_input_1;
+ 2'd1: bus_data_rd_mux = 32'hDEADC0DE;
+ 2'd2: bus_data_rd_mux = bus_data_rd_output;
+ 2'd3: bus_data_rd_mux = 32'hDEADC0DE;
+ //
+ endcase
+
+endmodule
+