From 82649fcd2d8c87f153249f983ea6883c68588e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Sat, 27 Jun 2015 08:39:39 +0200 Subject: Adding block memory with internal address generator as used in modexp_core, but with 64 bit internal data width for the modexp_core. Adding a README to explain the purpose of the contents of the support source and what the files are for. --- src/support/rtl/README.md | 18 ++++ src/support/rtl/blockmem_rw32ptr_r64.v | 155 +++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 src/support/rtl/README.md create mode 100644 src/support/rtl/blockmem_rw32ptr_r64.v diff --git a/src/support/rtl/README.md b/src/support/rtl/README.md new file mode 100644 index 0000000..7ccd111 --- /dev/null +++ b/src/support/rtl/README.md @@ -0,0 +1,18 @@ +This directory contains support RTL code for the modexp core. The code +here is not directly part of the core RTL. + +montprod_wrapper.v + A simple wrapper to mux together inputs and outputs from the montprod + module. Used for test builds of versions of montprod with different + (64, 128,2 256 bits) operand widths which means that the interface + from the montprod can contain a huge number of bits and thus pins. + + +blockmem_rw32ptr_r64.v + A synchronous block memory with two separate ports and internal + address generator as used in the modex_core to implement the exponent, + modulus and message memories. This version sports a 64 bit wide data + port for core internal read access while the API facing interface uses + 32 bit wide data. When the modexp is set to use 64 bit operands, this + module should be included into the src/rtl dir to be used in the + modexp_core instantiation of the block memory. diff --git a/src/support/rtl/blockmem_rw32ptr_r64.v b/src/support/rtl/blockmem_rw32ptr_r64.v new file mode 100644 index 0000000..4f0315c --- /dev/null +++ b/src/support/rtl/blockmem_rw32ptr_r64.v @@ -0,0 +1,155 @@ +//====================================================================== +// +// blockmem_rw32ptr_r64.v +// ---------------------- +// Synchronous block memory with two separate ports. Port one is +// called the api port and port two is called the internal port. +// +// The api port contains its own address generator and the api port +// uses 32 bit data width. The address is automatically increased when +// the cs signal is set. The address is reset to zero when the rst +// signal is asserted. +// +// The second data port is called the internal port. The internal +// port uses 64 bit data width. +// +// and an internal port. The api port contains apointer +// and 32 bit data width. The internal port +// For port 1 the address is implicit and instead given by the +// internal pointer. +// 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 blockmem_rw32ptr_r64( + input wire clk, + input wire reset_n, + + input wire api_rst, + input wire api_cs, + input wire api_wr, + input wire [31 : 0] api_wr_data, + output wire [31 : 0] api_rd_data, + + input wire [06 : 0] internal_addr, + output wire [63 : 0] internal_rd_data + ); + + + //---------------------------------------------------------------- + // Regs and memories. + //---------------------------------------------------------------- + reg [31 : 0] mem0 [0 : 127]; + wire mem0_we; + + reg [31 : 0] mem1 [0 : 127]; + wire mem1_we; + + reg [7 : 0] ptr_reg; + reg [7 : 0] ptr_new; + reg ptr_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [31 : 0] tmp0_api_rd_data; + reg [31 : 0] tmp1_api_rd_data; + reg [31 : 0] tmp0_int_rd_data; + reg [31 : 0] tmp1_int_rd_data; + + + //---------------------------------------------------------------- + // Assignments. + //---------------------------------------------------------------- + assign api_rd_data = ptr_reg[0] ? tmp1_api_rd_data : tmp0_api_rd_data; + assign internal_rd_data = {tmp1_int_rd_data, tmp0_int_rd_data}; + + assign mem0_we = api_wr & ~ptr_reg[0]; + assign mem1_we = api_wr & ptr_reg[0]; + + + //---------------------------------------------------------------- + // mem0_updates + //---------------------------------------------------------------- + always @ (posedge clk) + begin : update_mem0 + if (mem0_we) + mem0[ptr_reg[7 : 1]] <= api_wr_data; + + tmp0_api_rd_data <= mem0[ptr_reg[7 : 1]]; + tmp0_int_rd_data <= mem0[internal_addr]; + end + + always @ (posedge clk) + begin : update_mem1 + if (mem1_we) + mem1[ptr_reg[7 : 1]] <= api_wr_data; + + tmp1_api_rd_data <= mem1[ptr_reg[7 : 1]]; + tmp1_int_rd_data <= mem1[internal_addr]; + end + + + //---------------------------------------------------------------- + // reg_update + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin : reg_update + if (!reset_n) + ptr_reg <= 8'h00; + else + if (ptr_we) + ptr_reg <= ptr_new; + end + + + //---------------------------------------------------------------- + // ptr_logic + //---------------------------------------------------------------- + always @* + begin : ptr_logic + ptr_new = 8'h00; + ptr_we = 1'b0; + + if (api_rst) + begin + ptr_new = 8'h00; + ptr_we = 1'b1; + end + + if (api_cs) + begin + ptr_new = ptr_reg + 1'b1; + ptr_we = 1'b1; + end + end + +endmodule // blockmem_rw32ptr_r64 + +//====================================================================== +// EOF blockmem_rw32ptr_r64 +//====================================================================== -- cgit v1.2.3