From 2c92500715a13e017ae7e792ba8283c91a716b7d Mon Sep 17 00:00:00 2001
From: "Pavel V. Shatov (Meister)" <meisterpaul1@yandex.ru>
Date: Wed, 1 Jun 2016 10:44:54 +0300
Subject: Ported ModExpS6 core to the new Alpha platform, hence the core now
 becomes ModExpA7.

Note, that the core takes advantage of built-in DSP slices available in 7-Series FPGAs.
This considerably speeds up computations, because the core can operate in 32-bit-word-serial
mode instead of just bit-serial mode. The core directly instantiates DSP slices instead of
using IP wizard to avoid using CoreGen during console bitstream builds.
---
 rtl/modexpa7_wrapper.v | 211 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 211 insertions(+)
 create mode 100644 rtl/modexpa7_wrapper.v

(limited to 'rtl/modexpa7_wrapper.v')

diff --git a/rtl/modexpa7_wrapper.v b/rtl/modexpa7_wrapper.v
new file mode 100644
index 0000000..271cb20
--- /dev/null
+++ b/rtl/modexpa7_wrapper.v
@@ -0,0 +1,211 @@
+//======================================================================
+//
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+module modexpa7_wrapper
+  (
+   input wire          clk,
+   input wire          reset_n,
+
+   input wire          cs,
+   input wire          we,
+
+   input wire [9: 0]   address,
+   input wire [31: 0]  write_data,
+   output wire [31: 0] read_data
+   );
+
+
+   //
+   // Address Decoder
+   //
+   localparam ADDR_MSB_REGS     = 1'b0;
+   localparam ADDR_MSB_CORE     = 1'b1;
+   wire                address_msb = address[9];
+   wire [8: 0]         address_lsb = address[8:0];
+
+
+   //
+   // Output Mux
+   //
+   wire [31: 0]        read_data_regs;
+   wire [31: 0]        read_data_core;
+
+
+   //
+   // Registers
+   //
+   localparam ADDR_NAME0        = 9'h000;
+   localparam ADDR_NAME1        = 9'h001;
+   localparam ADDR_VERSION      = 9'h002;
+
+   localparam ADDR_CONTROL      = 9'h008;               // {next, init}
+   localparam ADDR_STATUS       = 9'h009;               // {valid, ready}
+   localparam ADDR_MODE         = 9'h010;               // 0 = slow secure, 1 = fast unsafe (public)
+   localparam ADDR_MODULUS_BITS = 9'h011;               //
+   localparam ADDR_EXPONENT_BITS = 9'h012;              //
+   localparam ADDR_GPIO_REG     = 9'h020;               //
+
+   localparam CONTROL_INIT_BIT  = 0;
+   localparam CONTROL_NEXT_BIT  = 1;
+
+   localparam STATUS_READY_BIT  = 0;
+   localparam STATUS_VALID_BIT  = 1;
+
+   localparam CORE_NAME0        = 32'h6D6F6465; // "mode"
+   localparam CORE_NAME1        = 32'h78706137; // "xpa7"
+   localparam CORE_VERSION      = 32'h302E3130; // "0.10"
+
+
+   //
+   // Registers
+   //
+   reg [1: 0]          reg_control;
+   reg                 reg_mode;
+   reg [12: 0]         reg_modulus_width;
+   reg [12: 0]         reg_exponent_width;
+   reg [31: 0]         reg_gpio;
+
+
+   //
+   // Wires
+   //
+   wire [1: 0]         reg_status;
+
+
+   //
+   // ModExpA7
+   //
+   modexpa7_top #
+     (
+      .MAX_MODULUS_WIDTH        (4096)
+      )
+   modexpa7_core
+     (
+      .clk                      (clk),
+
+      .init                     (reg_control[CONTROL_INIT_BIT]),
+      .ready                    (reg_status[STATUS_READY_BIT]),
+      .next                     (reg_control[CONTROL_NEXT_BIT]),
+      .valid                    (reg_status[STATUS_VALID_BIT]),
+
+      .modulus_width            (reg_modulus_width),
+      .exponent_width           (reg_exponent_width),
+
+      .fast_public_mode         (reg_mode),
+
+      .bus_cs                   (cs && (address_msb == ADDR_MSB_CORE)),
+      .bus_we                   (we),
+      .bus_addr                 (address_lsb),
+      .bus_data_wr              (write_data),
+      .bus_data_rd              (read_data_core)
+      );
+
+
+   //
+   // Read Latch
+   //
+   reg [31: 0]         tmp_read_data;
+
+
+   //
+   // Read/Write Interface
+   //
+   always @(posedge clk)
+     //
+     if (!reset_n) begin
+        //
+        reg_control             <= 2'b00;
+        reg_mode                <= 1'b0;
+        reg_modulus_width       <= 13'd1024;
+        reg_exponent_width      <= 13'd1024;
+        //
+     end else if (cs && (address_msb == ADDR_MSB_REGS)) begin
+        //
+        if (we) begin
+           //
+           // Write Handler
+           //
+           case (address_lsb)
+             //
+             ADDR_CONTROL:      reg_control             <= write_data[1: 0];
+             ADDR_MODE:         reg_mode                <= write_data[0];
+             ADDR_MODULUS_BITS: reg_modulus_width       <= write_data[12: 0];
+             ADDR_EXPONENT_BITS: reg_exponent_width     <= write_data[12: 0];
+             ADDR_GPIO_REG:     reg_gpio                <= write_data;
+             //
+           endcase
+           //
+        end else begin
+           //
+           // Read Handler
+           //
+           case (address)
+             //
+             ADDR_NAME0:        tmp_read_data <= CORE_NAME0;
+             ADDR_NAME1:        tmp_read_data <= CORE_NAME1;
+             ADDR_VERSION:      tmp_read_data <= CORE_VERSION;
+             ADDR_CONTROL:      tmp_read_data <= {{30{1'b0}}, reg_control};
+             ADDR_STATUS:       tmp_read_data <= {{30{1'b0}}, reg_status};
+             ADDR_MODE:         tmp_read_data <= {{31{1'b0}}, reg_mode};
+             ADDR_MODULUS_BITS: tmp_read_data <= {{19{1'b0}}, reg_modulus_width};
+             ADDR_EXPONENT_BITS: tmp_read_data <= {{19{1'b0}}, reg_exponent_width};
+             ADDR_GPIO_REG:     tmp_read_data <= reg_gpio;
+             //
+             default:           tmp_read_data <= 32'h00000000;
+             //
+           endcase
+           //
+        end
+        //
+     end
+
+
+   //
+   // Register / Core Memory Selector
+   //
+   reg address_msb_last;
+   always @(posedge clk) address_msb_last = address_msb;
+
+   reg [31: 0] read_data_mux;
+   assign read_data = read_data_mux;
+
+   always @(*)
+     //
+     case (address_msb_last)
+       //
+       ADDR_MSB_REGS:           read_data_mux = tmp_read_data;
+       ADDR_MSB_CORE:           read_data_mux = read_data_core;
+       //
+     endcase
+
+
+endmodule
-- 
cgit v1.2.3