[Cryptech-Commits] [staging/core/comm/eim] 01/01: Rearrange cores.

git at cryptech.is git at cryptech.is
Tue Mar 17 13:13:01 UTC 2015


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch master
in repository staging/core/comm/eim.

commit 755bd6fcfe68a69b035d062b794ea326c30a6de0
Author: Paul Selkirk <pselkirk at isc.org>
Date:   Tue Mar 17 13:48:15 2015 +0100

    Rearrange cores.
---
 src/rtl/cdc_bus_pulse.v   | 145 ++++++++++++++++++++++
 src/rtl/eim.v             |  75 +++++++++++
 src/rtl/eim_arbiter.v     | 309 ++++++++++++++++++++++++++++++++++++++++++++++
 src/rtl/eim_arbiter_cdc.v | 143 +++++++++++++++++++++
 src/rtl/eim_da_phy.v      |  77 ++++++++++++
 src/rtl/eim_indicator.v   |  69 +++++++++++
 src/rtl/eim_regs.v        | 126 +++++++++++++++++++
 7 files changed, 944 insertions(+)

diff --git a/src/rtl/cdc_bus_pulse.v b/src/rtl/cdc_bus_pulse.v
new file mode 100644
index 0000000..cc2d8db
--- /dev/null
+++ b/src/rtl/cdc_bus_pulse.v
@@ -0,0 +1,145 @@
+//======================================================================
+//
+// cdc_bus_pulse.v
+// ---------------
+// Clock Domain Crossing handler for the Cryptech Novena
+// FPGA framework design.
+//
+// This module is based on design suggested on page 27 of the
+// paper 'Clock Domain Crossing (CDC) Design & Verification Techniques
+// Using SystemVerilog' by Clifford E. Cummings (Sunburst Design, Inc.)
+//
+//
+// Author: Pavel Shatov
+// Copyright (c) 2015, 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 cdc_bus_pulse
+  #(parameter   DATA_WIDTH      = 32)     // width of data bus
+   (
+    input wire                   src_clk, // source domain clock
+    input wire [DATA_WIDTH-1:0]  src_din, // data from source clock domain
+    input wire                   src_req, // start transfer pulse from source clock domain
+
+    input wire                   dst_clk, // destination domain clock
+    output wire [DATA_WIDTH-1:0] dst_dout, // data to destination clock domain
+    output wire                  dst_pulse // transfer done pulse to destination clock domain
+    );
+
+   //
+   // Source Side Registers
+   //
+   reg                           src_ff         = 1'b0;                 // transfer request flag
+   reg [DATA_WIDTH-1:0]          src_latch      = {DATA_WIDTH{1'bX}};   // source data buffer
+
+
+   //
+   // Source Request Handler
+   //
+   always @(posedge src_clk)
+     //
+     if (src_req) begin                         // transfer request pulse?
+        src_ff          <= ~src_ff;             // toggle transfer request flag...
+        src_latch       <= src_din;             // ... and capture data in source buffer
+     end
+
+
+   //
+   // Source -> Destination Flag Sync Logic
+   //
+
+   /* ISE may decide to infer SRL here, so we explicitly instantiate slice registers. */
+
+   wire flag_sync_first;        // first FF output
+   wire flag_sync_second;       // second FF output
+   wire flag_sync_third;        // third FF output
+   wire flag_sync_pulse;        // flag toggle detector output
+
+   FDCE ff_sync_first
+     (
+      .C(dst_clk),
+      .D(src_ff),               // capture flag from another clock domain
+      .Q(flag_sync_first),      // metastability can occur here
+      .CLR(1'b0),
+      .CE(1'b1)
+      );
+   FDCE ff_sync_second
+     (
+      .C(dst_clk),
+      .D(flag_sync_first),      // synchronize captured flag to remove metastability
+      .Q(flag_sync_second),     // and pass it to another flip-flop
+      .CLR(1'b0),
+      .CE(1'b1)
+      );
+   FDCE ff_sync_third
+     (
+      .C(dst_clk),
+      .D(flag_sync_second),     // delay synchronized flag in another flip-flip, because we need
+      .Q(flag_sync_third),      // two synchronized flag values (current and delayed) to detect its change
+      .CLR(1'b0),
+      .CE(1'b1)
+      );
+
+   // when delayed flag value differs from its current value, it was changed
+   // by the source side, so there must have been a transfer request
+   assign flag_sync_pulse = flag_sync_second ^ flag_sync_third;
+
+
+   //
+   // Destination Side Registers
+   //
+   reg  dst_pulse_reg   = 1'b0;                         // transfer done flag
+   reg [DATA_WIDTH-1:0] dst_latch = {DATA_WIDTH{1'bX}}; // destination data buffer
+
+   assign dst_pulse     = dst_pulse_reg;
+   assign dst_dout      = dst_latch;
+
+   //
+   // Destination Request Handler
+   //
+   always @(posedge dst_clk) begin
+      //
+      dst_pulse_reg <= flag_sync_pulse; // generate pulse if flag change was detected
+      //
+      if (flag_sync_pulse)
+        dst_latch <= src_latch;
+      /* By the time destination side receives synchronized flag
+       * value, data should be stable, we can safely capture and store
+       * it in the destination buffer.
+       */
+
+   end
+
+
+endmodule
+
+//======================================================================
+// EOF cdc_bus_pulse.v
+//======================================================================
diff --git a/src/rtl/eim.v b/src/rtl/eim.v
new file mode 100644
index 0000000..dcbd226
--- /dev/null
+++ b/src/rtl/eim.v
@@ -0,0 +1,75 @@
+`define USE_EIM
+
+module eim
+  (
+   // EIM interface pins from CPU
+   input wire 	       eim_bclk, // EIM burst clock. Started by the CPU.
+   input wire 	       eim_cs0_n, // Chip select (active low).
+   inout wire [15 : 0] eim_da, // Bidirectional address and data port.
+   input wire [18: 16] eim_a, // MSB part of address port.                     
+   input wire 	       eim_lba_n, // Latch address signal (active low).
+   input wire 	       eim_wr_n, // write enable signal (active low).
+   input wire 	       eim_oe_n, // output enable signal (active low).
+   output wire 	       eim_wait_n, // Data wait signal (active low).
+
+   // system clock and reset
+   input wire 	       sys_clk,
+   input wire 	       sys_rst,
+
+   // EIM interface to cores
+   output wire [16: 0] sys_eim_addr,
+   output wire 	       sys_eim_wr,
+   output wire 	       sys_eim_rd,
+   output wire [31: 0] sys_eim_dout,
+   input wire [31: 0]  sys_eim_din,
+
+   // Novena utility ports
+   output wire 	       led_pin		// LED on edge close to the FPGA.
+   );
+
+   // XXX add NAME0/NAME1/VERSION
+
+   //----------------------------------------------------------------
+   // EIM Arbiter
+   //
+   // EIM arbiter handles EIM access and transfers it into
+   // `sys_clk' clock domain.
+   //----------------------------------------------------------------
+
+   eim_arbiter eim
+     (
+      .eim_bclk(eim_bclk),
+      .eim_cs0_n(eim_cs0_n),
+      .eim_da(eim_da),
+      .eim_a(eim_a),
+      .eim_lba_n(eim_lba_n),
+      .eim_wr_n(eim_wr_n),
+      .eim_oe_n(eim_oe_n),
+      .eim_wait_n(eim_wait_n),
+
+      .sys_clk(sys_clk),
+
+      .sys_addr(sys_eim_addr),
+      .sys_wren(sys_eim_wr),
+      .sys_data_out(sys_eim_dout),
+      .sys_rden(sys_eim_rd),
+      .sys_data_in(sys_eim_din)
+      );
+
+
+   //----------------------------------------------------------------
+   // LED Driver
+   //
+   // A simple utility LED driver that turns on the Novena
+   // board LED when the EIM interface is active.
+   //----------------------------------------------------------------
+   eim_indicator led
+     (
+      .sys_clk(sys_clk),
+      .sys_rst(sys_rst),
+      .eim_active(sys_eim_wr | sys_eim_rd),
+      .led_out(led_pin)
+      );
+
+
+endmodule // eim
diff --git a/src/rtl/eim_arbiter.v b/src/rtl/eim_arbiter.v
new file mode 100644
index 0000000..e9b2c76
--- /dev/null
+++ b/src/rtl/eim_arbiter.v
@@ -0,0 +1,309 @@
+//======================================================================
+//
+// eim_arbiter.v
+// -------------
+// Port arbiter for the EIM interface for the Cryptech
+// Novena FPGA framework.
+//
+//
+// Author: Pavel Shatov
+// Copyright (c) 2015, 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 eim_arbiter
+  (
+   // eim bus
+   input wire          eim_bclk, 
+   input wire          eim_cs0_n,
+   inout wire [15: 0]  eim_da,
+   input wire [18:16]  eim_a,
+   input wire          eim_lba_n,
+   input wire          eim_wr_n,
+   input wire          eim_oe_n,
+   output wire         eim_wait_n,
+
+   // system clock
+   input wire          sys_clk,
+
+   // user bus
+   output wire [16: 0] sys_addr, 
+   output wire         sys_wren,
+   output wire [31: 0] sys_data_out,
+   output wire         sys_rden,
+   input wire [31: 0]  sys_data_in
+   );
+
+
+   //
+   // Data/Address PHY
+   //
+
+   /* PHY is needed to control bi-directional address/data bus. */
+
+   wire [15: 0]        da_ro;   // value read from pins
+   reg [15: 0]         da_di;   // value drives onto pins
+
+   eim_da_phy da_phy
+     (
+      .buf_io(eim_da),          // <-- connect directly top-level port
+      .buf_di(da_di),
+      .buf_ro(da_ro),
+      .buf_t(eim_oe_n)          // <-- driven by EIM directly
+      );
+
+
+   //
+   // FSM
+   //
+   localparam   EIM_FSM_STATE_INIT        = 5'b0_0_000; // arbiter is idle
+
+   localparam   EIM_FSM_STATE_WRITE_START = 5'b1_1_000; // got address to write at
+   localparam   EIM_FSM_STATE_WRITE_LSB   = 5'b1_1_001; // got lower 16 bits of data to write
+   localparam   EIM_FSM_STATE_WRITE_MSB   = 5'b1_1_010; // got upper 16 bits of data to write
+   localparam   EIM_FSM_STATE_WRITE_WAIT  = 5'b1_1_100; // request to user-side logic sent
+   localparam   EIM_FSM_STATE_WRITE_DONE  = 5'b1_1_111; // user-side logic acknowledged transaction
+
+   localparam   EIM_FSM_STATE_READ_START  = 5'b1_0_000; // got address to read from
+   localparam   EIM_FSM_STATE_READ_WAIT   = 5'b1_0_100; // request to user-side logic sent
+   localparam   EIM_FSM_STATE_READ_READY  = 5'b1_0_011; // got acknowledge from user logic
+   localparam   EIM_FSM_STATE_READ_LSB    = 5'b1_0_001; // returned lower 16 bits to master
+   localparam   EIM_FSM_STATE_READ_MSB    = 5'b1_0_010; // returned upper 16 bits to master
+   localparam   EIM_FSM_STATE_READ_DONE   = 5'b1_0_111; // transaction complete
+
+   reg [ 4: 0]  eim_fsm_state   = EIM_FSM_STATE_INIT;   // fsm state
+   reg [16: 0]  eim_addr_latch  = {17{1'bX}};           // transaction address
+   reg [15: 0]  eim_write_lsb_latch = {16{1'bX}};       // lower 16 bits of data to write
+
+   /* These flags are used to wake up from INIT state. */
+   wire         eim_write_start_flag = (eim_lba_n == 1'b0) && (eim_wr_n == 1'b0) && (da_ro[1:0] == 2'b00);
+   wire         eim_read_start_flag  = (eim_lba_n == 1'b0) && (eim_wr_n == 1'b1) && (da_ro[1:0] == 2'b00);
+
+   /* These are transaction response flag and data from user-side logic. */
+   wire         eim_user_ack;
+   wire [31: 0] eim_user_data;
+
+   /* FSM is reset whenever Chip Select is de-asserted. */
+
+   //
+   // FSM Transition Logic
+   //
+   always @(posedge eim_bclk or posedge eim_cs0_n)
+     begin
+        //
+        if (eim_cs0_n == 1'b1)
+          eim_fsm_state <= EIM_FSM_STATE_INIT;
+        //
+        else
+          begin
+             //
+             case (eim_fsm_state)
+               //
+               // INIT -> WRITE, INIT -> READ
+               //
+               EIM_FSM_STATE_INIT:
+                 begin
+                    if (eim_write_start_flag)
+                      eim_fsm_state     <= EIM_FSM_STATE_WRITE_START;
+                    if (eim_read_start_flag)
+                      eim_fsm_state     <= EIM_FSM_STATE_READ_START;
+                 end
+               //
+               // WRITE
+               //
+               EIM_FSM_STATE_WRITE_START:
+                 eim_fsm_state  <= EIM_FSM_STATE_WRITE_LSB;
+               //
+               EIM_FSM_STATE_WRITE_LSB:
+                 eim_fsm_state  <= EIM_FSM_STATE_WRITE_MSB;
+               //
+               EIM_FSM_STATE_WRITE_MSB:
+                 eim_fsm_state  <= EIM_FSM_STATE_WRITE_WAIT;
+               //
+               EIM_FSM_STATE_WRITE_WAIT:
+                 if (eim_user_ack)
+                   eim_fsm_state <= EIM_FSM_STATE_WRITE_DONE;
+               //
+               EIM_FSM_STATE_WRITE_DONE:
+                 eim_fsm_state  <= EIM_FSM_STATE_INIT;
+               //
+               // READ
+               //
+               EIM_FSM_STATE_READ_START:
+                 eim_fsm_state  <= EIM_FSM_STATE_READ_WAIT;
+               //
+               EIM_FSM_STATE_READ_WAIT:
+                 if (eim_user_ack)
+                   eim_fsm_state <= EIM_FSM_STATE_READ_READY;
+               //
+               EIM_FSM_STATE_READ_READY:
+                 eim_fsm_state <= EIM_FSM_STATE_READ_LSB;
+               //
+               EIM_FSM_STATE_READ_LSB:
+                 eim_fsm_state  <= EIM_FSM_STATE_READ_MSB;
+               //
+               EIM_FSM_STATE_READ_MSB:
+                 eim_fsm_state  <= EIM_FSM_STATE_READ_DONE;
+               //
+               EIM_FSM_STATE_READ_DONE:
+                 eim_fsm_state  <= EIM_FSM_STATE_INIT;
+               //
+               //
+               //
+               default:
+                 eim_fsm_state  <= EIM_FSM_STATE_INIT;
+               //
+             endcase
+             //
+          end
+        //
+     end
+
+
+   //
+   // Address Latch
+   //
+   always @(posedge eim_bclk)
+     //
+     if ((eim_fsm_state == EIM_FSM_STATE_INIT) && (eim_write_start_flag || eim_read_start_flag))
+       eim_addr_latch <= {eim_a[18:16], da_ro[15:2]};
+
+
+   //
+   // Additional Write Logic
+   //
+   always @(posedge eim_bclk)
+     //
+     if (eim_fsm_state == EIM_FSM_STATE_WRITE_START)
+       eim_write_lsb_latch <= da_ro;
+
+
+   //
+   // Additional Read Logic
+   //
+
+   /* Note that this stuff operates on falling clock edge, because the cpu
+    * samples our bi-directional data bus on rising clock edge.
+    */
+
+   always @(negedge eim_bclk or posedge eim_cs0_n)
+     //
+     if (eim_cs0_n == 1'b1)                                                                             da_di <= {16{1'bX}};                    // don't care what to drive
+     else begin
+        //
+        if (eim_fsm_state == EIM_FSM_STATE_READ_LSB)
+          da_di <= eim_user_data[15: 0];        // drive lower 16 bits at first...
+        if (eim_fsm_state == EIM_FSM_STATE_READ_MSB)
+          da_di <= eim_user_data[31:16];        // ...then drive upper 16 bits
+        //
+     end
+
+
+   //
+   // Wait Logic
+   //
+
+   /* Note that this stuff operates on falling clock edge, because the cpu
+    *  samples our WAIT_N flag on rising clock edge.
+    */
+
+   reg  eim_wait_reg    = 1'b0;
+
+   always @(negedge eim_bclk or posedge eim_cs0_n)
+     //
+     if (eim_cs0_n == 1'b1)
+       eim_wait_reg     <= 1'b0;                // clear wait
+     else begin
+        //
+        if (eim_fsm_state == EIM_FSM_STATE_WRITE_START)
+          eim_wait_reg  <= 1'b1;                // start waiting for write to complete
+        if (eim_fsm_state == EIM_FSM_STATE_READ_START)
+          eim_wait_reg  <= 1'b1;                // start waiting for read to complete
+        //
+        if (eim_fsm_state == EIM_FSM_STATE_WRITE_DONE)
+          eim_wait_reg  <= 1'b0;                // write transaction done
+        if (eim_fsm_state == EIM_FSM_STATE_READ_READY)
+          eim_wait_reg  <= 1'b0;                // read transaction done
+        //
+        if (eim_fsm_state == EIM_FSM_STATE_INIT)
+          eim_wait_reg  <= 1'b0;                // fsm is idle, no need to wait any more
+        //
+     end
+
+   assign eim_wait_n = ~eim_wait_reg;
+
+
+   /* These flags are used to generate 1-cycle pulses to trigger CDC
+    * transaction.  Note that FSM goes from WRITE_LSB to WRITE_MSB and from
+    * READ_START to READ_WAIT unconditionally, so these flags will always be
+    * active for 1 cycle only, which is exactly what we need.
+    */
+
+   wire arbiter_write_req_pulse = (eim_fsm_state == EIM_FSM_STATE_WRITE_LSB)  ? 1'b1 : 1'b0;
+   wire arbiter_read_req_pulse  = (eim_fsm_state == EIM_FSM_STATE_READ_START) ? 1'b1 : 1'b0;
+
+   //
+   // CDC Block
+   //
+
+   /* This block is used to transfer request data from BCLK clock domain to
+    * SYS_CLK clock domain and then transfer acknowledge from SYS_CLK to BCLK
+    * clock domain in return. Af first 1+1+3+14+32 = 51 bits are transfered,
+    * these are: write flag, read flag, msb part of address, lsb part of address,
+    * write data. During read transaction some bogus write data is passed,
+    * which is not used later anyway. During read requests 32 bits of data are
+    * returned, during write requests 32 bits of bogus data are returned, that
+    * are never used later.
+    */
+
+   eim_arbiter_cdc eim_cdc
+     (
+      .eim_clk(eim_bclk),
+
+      .eim_req(arbiter_write_req_pulse | arbiter_read_req_pulse),
+      .eim_ack(eim_user_ack),
+
+      .eim_din({arbiter_write_req_pulse, arbiter_read_req_pulse,
+                eim_addr_latch, da_ro, eim_write_lsb_latch}),
+      .eim_dout(eim_user_data),
+
+      .sys_clk(sys_clk),
+      .sys_addr(sys_addr),
+      .sys_wren(sys_wren),
+      .sys_data_out(sys_data_out),
+      .sys_rden(sys_rden),
+      .sys_data_in(sys_data_in)
+      );
+
+
+endmodule
+
+//======================================================================
+// EOF eim_arbiter.v
+//======================================================================
diff --git a/src/rtl/eim_arbiter_cdc.v b/src/rtl/eim_arbiter_cdc.v
new file mode 100644
index 0000000..15dc433
--- /dev/null
+++ b/src/rtl/eim_arbiter_cdc.v
@@ -0,0 +1,143 @@
+//======================================================================
+//
+// eim_arbiter_cdc.v
+// -----------------
+// The actual clock domain crossing handler od the EIM arbiter
+// for the Cryptech Novena FPGA framework.
+//
+//
+// Author: Pavel Shatov
+// Copyright (c) 2015, 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 eim_arbiter_cdc
+  (
+   input wire          eim_clk, // eim clock
+   input wire          eim_req, // eim transaction request
+   output wire         eim_ack, // eim transaction acknowledge
+   input wire [50: 0]  eim_din, // data from cpu to fpga (write access)
+   output wire [31: 0] eim_dout, // data from fpga to cpu (read access)
+
+   input wire          sys_clk, // user internal clock
+   output wire [16: 0] sys_addr, // user access address
+   output wire         sys_wren, // user write flag
+   output wire [31: 0] sys_data_out, // user write data
+   output wire         sys_rden, // user read flag
+   input wire [31: 0]  sys_data_in   // user read data
+   );
+
+
+   //
+   // EIM_CLK -> SYS_CLK Request
+   //
+   wire                sys_req;         // request pulse in sys_clk clock domain
+   wire [50: 0]        sys_dout;        // transaction data in sys_clk clock domain
+
+   cdc_bus_pulse #
+     (
+      .DATA_WIDTH(51)   // {write, read, msb addr, lsb addr, data}
+      )
+   cdc_eim_sys
+     (
+      .src_clk(eim_clk),
+      .src_din(eim_din),
+      .src_req(eim_req),
+
+      .dst_clk(sys_clk),
+      .dst_dout(sys_dout),
+      .dst_pulse(sys_req)
+      );
+
+
+   //
+   // Output Registers
+   //
+   reg                 sys_wren_reg     = 1'b0;
+   reg                 sys_rden_reg     = 1'b0;
+   reg [16: 0]         sys_addr_reg     = {17{1'bX}};
+   reg [31: 0]         sys_data_out_reg = {32{1'bX}};
+   
+   assign sys_wren      = sys_wren_reg;
+   assign sys_rden      = sys_rden_reg;
+   assign sys_addr      = sys_addr_reg;
+   assign sys_data_out  = sys_data_out_reg;
+   
+
+   //
+   // System (User) Clock Access Handler
+   //
+   always @(posedge sys_clk)
+     //
+     if (sys_req)                               // request detected?
+       begin
+          sys_wren_reg     <= sys_dout[50];     // set write flag if needed
+          sys_rden_reg     <= sys_dout[49];     // set read flag if needed
+          sys_addr_reg     <= sys_dout[48:32];  // set operation address
+          sys_data_out_reg <= sys_dout[31: 0];  // set data to write
+       end
+     else                                       // no request active
+       begin
+          sys_wren_reg  <=  1'b0;               // clear write flag
+          sys_rden_reg  <=  1'b0;               // clear read flag
+       end
+
+
+   //
+   // System Request 2-cycle delay to compensate registered mux delay in user-side logic
+   //
+   reg  [ 1: 0] sys_req_dly     = 2'b00;
+
+   always @(posedge sys_clk)
+     sys_req_dly <= {sys_req_dly[0], sys_req};
+
+
+   //
+   // SYS_CLK -> EIM_CLK Acknowledge
+   //
+   cdc_bus_pulse #
+     (
+      .DATA_WIDTH(32)
+      )
+   cdc_sys_eim
+     (
+      .src_clk(sys_clk),
+      .src_din(sys_data_in),
+      .src_req(sys_req_dly[1]),
+
+      .dst_clk(eim_clk),
+      .dst_dout(eim_dout),
+      .dst_pulse(eim_ack)
+      );
+
+endmodule
+
+//======================================================================
+// EOF eim_arbiter_cdc.v
+//======================================================================
diff --git a/src/rtl/eim_da_phy.v b/src/rtl/eim_da_phy.v
new file mode 100644
index 0000000..8a4a8d7
--- /dev/null
+++ b/src/rtl/eim_da_phy.v
@@ -0,0 +1,77 @@
+//======================================================================
+//
+// eim_da_phy.v
+// ------------
+// IO buffer module for the EIM DA port.
+//
+//
+// Author: Pavel Shatov
+// Copyright (c) 2015, 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 eim_da_phy
+  #(parameter BUS_WIDTH = 16)
+   (
+    inout wire [BUS_WIDTH-1:0]  buf_io, // connect directly to top-level pins
+    input wire [BUS_WIDTH-1:0]  buf_di, // drive input (value driven onto pins)
+    output wire [BUS_WIDTH-1:0] buf_ro, // receiver output (value read from pins)
+    input wire                  buf_t   // tristate control (driver is disabled during tristate)
+    );
+
+   //
+   // IOBUFs
+   //
+   genvar                       i;
+   generate
+      for (i = 0; i < BUS_WIDTH; i = i+1)
+        begin: eim_da
+           //
+           IOBUF #
+               (
+                .IOSTANDARD("LVCMOS33"),
+                .DRIVE(12),
+                .SLEW("FAST")
+                )
+           IOBUF_inst
+               (
+                .IO(buf_io[i]),
+                .O(buf_ro[i]),
+                .I(buf_di[i]),
+                .T(buf_t)
+                );
+           //
+        end
+   endgenerate
+
+endmodule
+
+//======================================================================
+// EOF eim_da_phy.v
+//======================================================================
diff --git a/src/rtl/eim_indicator.v b/src/rtl/eim_indicator.v
new file mode 100644
index 0000000..cf9751d
--- /dev/null
+++ b/src/rtl/eim_indicator.v
@@ -0,0 +1,69 @@
+//======================================================================
+//
+// eim_indicator.v
+// ---------------
+// A simple LED indicator to show that the EIM is alive.
+//
+//
+// Author: Pavel Shatov
+// Copyright (c) 2015, 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 eim_indicator
+  (
+   input wire  sys_clk,
+   input wire  sys_rst,
+   input wire  eim_active,
+   output wire led_out
+   );
+
+   //
+   // Parameters
+   //
+   localparam   CNT_BITS                = 24;   // led will be dim for 2**(24-1) = 8388608 ticks, which is ~100 ms @ 80 MHz.
+
+   //
+   // Counter
+   //
+   reg [CNT_BITS-1:0] cnt;
+
+   always @(posedge sys_clk)
+     //
+     if (sys_rst)                       cnt <= {CNT_BITS{1'b0}};
+     else if (cnt > {CNT_BITS{1'b0}})   cnt <= cnt - 1'b1;
+     else if (eim_active)               cnt <= {CNT_BITS{1'b1}};
+
+   assign led_out = ~cnt[CNT_BITS-1];
+
+endmodule
+
+//======================================================================
+// EOF eim_indicator.v
+//======================================================================
diff --git a/src/rtl/eim_regs.v b/src/rtl/eim_regs.v
new file mode 100644
index 0000000..09a51dc
--- /dev/null
+++ b/src/rtl/eim_regs.v
@@ -0,0 +1,126 @@
+//======================================================================
+//
+// eim.v
+// ------
+// Configuration registers for the eim core.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2014, SUNET
+// 
+// Redistribution and use in source and binary forms, with or 
+// without modification, are permitted provided that the following 
+// conditions are met: 
+// 
+// 1. Redistributions of source code must retain the above copyright 
+//    notice, this list of conditions and the following disclaimer. 
+// 
+// 2. 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. 
+// 
+// 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 OWNER 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 comm_regs
+  (
+   input wire           clk,
+   input wire           rst,
+
+   input wire           cs,
+   input wire           we,
+
+   input wire [ 7 : 0]  address,
+   input wire [31 : 0]  write_data,
+   output wire [31 : 0] read_data
+   );
+
+
+   //----------------------------------------------------------------
+   // Internal constant and parameter definitions.
+   //----------------------------------------------------------------
+   // API addresses.
+   localparam ADDR_CORE_NAME0   = 8'h00;
+   localparam ADDR_CORE_NAME1   = 8'h01;
+   localparam ADDR_CORE_VERSION = 8'h02;
+   localparam ADDR_DUMMY_REG    = 8'hFF;    // general-purpose register
+
+   // Core ID constants.
+   localparam CORE_NAME0   = 32'h65696d20;  // "eim "
+   localparam CORE_NAME1   = 32'h20202020;  // "    "
+   localparam CORE_VERSION = 32'h302e3130;  // "0.10"
+
+
+   //----------------------------------------------------------------
+   // Wires.
+   //----------------------------------------------------------------
+   reg [31: 0]          tmp_read_data;
+
+   // dummy register to check that you can actually write something
+   reg [31: 0] 		reg_dummy;
+
+   
+   //----------------------------------------------------------------
+   // Concurrent connectivity for ports etc.
+   //----------------------------------------------------------------
+   assign read_data = tmp_read_data;
+   
+
+   //----------------------------------------------------------------
+   // Access Handler
+   //----------------------------------------------------------------
+   always @(posedge clk)
+     //
+     if (rst)
+       reg_dummy <= {32{1'b0}};
+     else if (cs) begin
+        //
+        if (we) begin
+           //
+           // WRITE handler
+           //
+           case (address)
+             ADDR_DUMMY_REG:
+               reg_dummy <= write_data;
+           endcase
+           //
+        end else begin
+           //
+           // READ handler
+           //
+           case (address)
+             ADDR_CORE_NAME0:
+               tmp_read_data <= CORE_NAME0;
+             ADDR_CORE_NAME1:
+               tmp_read_data <= CORE_NAME1;
+             ADDR_CORE_VERSION:
+               tmp_read_data <= CORE_VERSION;
+             ADDR_DUMMY_REG:
+               tmp_read_data <= reg_dummy;
+             //
+             default:
+               tmp_read_data <= {32{1'b0}};  // read non-existent locations as zeroes
+           endcase
+           //
+        end
+        //
+     end
+
+endmodule
+
+//======================================================================
+// EOF eim_regs.v
+//======================================================================



More information about the Commits mailing list