To create an NPI Core, you must create a custom Pcore using the following steps and directory structure:
NPI Limitations
In general, custom master user logic should be created to interface to the PLBv46 bus via the PLBv46 IPIF cores, or to the Xilinx LocalLink standard via the SDMA PIM. Custom cores using these standards have the most compatibility for future Xilinx cores and devices. The NPI interface is specific to the MPMC and is unlikely to be added to any future Xilinx memory cores and might change in any MPMC release.
The SDMA provides Scatter Gather DMA services. The PLBv46 master IPIF core provides general master support, including bursting and up to a 128-bit data width.
The PLBv46 IPIF and SDMA PIM both also support unaligned addressing, whereas all MPMC NPI transactions must be address-aligned to the size of the NPI burst length by user logic.
If these limitations are acceptable, or absolute lowest latency/highest memory utilization is required, an NPI interface should be used to access the MPMC.
Creating a Master NPI Core
NOTE: Before starting this process, consult the Platform Specification Format Reference Manual, accessible at:
http://www.xilinx.com/ise/embedded/edk_docs.htm
To access this manual, select "Platform Specification Format" under Tools and IP Reference Guides.
For the purpose of this example, assume that your file is named my_npi and the top level of the module is also named my_npi. MPMC2 users should replace XIL_NPI with NPI in the following directions:
1. Create a Pcore directory structure:
<project_directory>/
--pcores/
----my_npi_v1_00_a/ <-- This is the name that will appear in the IP Repository
------data/ <-- This is where the Xilinx configuration files will go
------hdl/
--------<verilog|vhdl>/ <-- This is where your source files will go
2. Below are simple examples of both a Verilog module and a VHDL entity, both with an input bus from a source and an NPI interface to the MPMC. Use the example in the language that you are using.
a. Place your source code in the "pcores/my_npi_v1_00_a/hdl/<verilog|vhdl>" directory.
b. Open a "Launch EDK Shell" found in Start -> All Programs -> Xilinx Platform Studio -> Accessories -> Launch EDK Shell.
c. Change directories to your "<project_directory>/pcores/my_npi_v1_00_a."
d. Create the Microprocessor Peripheral Definition (MPD) file in the data directory.
e. The Platform Specification Utility, psfutil, elaborates all the code so that all modules that are instantiated must be indicated to the utility. Information for this command is available in Chapter 6 in the Embedded Systems Tools Reference Manual, accessible at:
http://www.xilinx.com/ise/embedded/edk_docs.htm
To access this manual, select "Embedded Systems Tools Guide" under Tools and IP Reference Guides.
For a single file:
Verilog: psfutil -hdl2mpd hdl/verilog/my_npi.v -lang ver -top my_npi -p2pbus XIL_NPI XIL_NPI initiator -o data/my_npi
VHDL: psfutil -hdl2mpd hdl/vhdl/my_npi.vhd -lang vhdl -top my_npi -p2pbus XIL_NPI XIL_NPI initiator -o data/my_npi
For multiple files:
You must create a project file that lists the files required for compile. In this case, the file will be named my_files.prj. Xilinx suggests that my_files.prj be created in the <project_directory>/pcores/my_npi_v1_00_a directory. The format of my_files.prj file is as follows:
'include "hdl/<verilog|vhdl>/my_npi.<v|vhd>"
'include "hdl/<verilog|vhdl>/my_other_file.<v|vhd>"
To generate the MPD file:
Verilog: psfutil -hdl2mpd my_files.prj -lang ver -top my_npi -p2pbus XIL_NPI XIL_NPI initiator -o data/my_npi
VHDL: psfutil -hdl2mpd my_files.prj -lang vhdl -top my_npi -p2pbus XIL_NPI XIL_NPI initiator -o data/my_npi
Once the MPD file is created, you must modify the MPD file to make it work with XPS. In the port listing for the BUS = XIL_NPI, a name must be provided in the empty quotation marks. For this example, remove the XIL_NPI_ prefix from the PORT listing.
For example:
PORT XIL_NPI_Addr = "", DIR = O, VEC = [(C_PI_ADDR_WIDTH-1):0], BUS = XIL_NPI
should be replaced with:
PORT XIL_NPI_Addr = "Addr", DIR = O, VEC = [(C_PI_ADDR_WIDTH-1):0], BUS = XIL_NPI
f. Create the Peripheral Analyze Order (PAO) file. This file must be located in the <project_directory>/pcores/my_npi_v1_00_a/data directory. Unfortunately, there is no tool available for generating this file. However, it is not complicated to generate. An example PAO file is shown below:
my_npi_v2_1_0.pao
-----------------
#FORMAT: lib <lib_name = IP Repository Name> <source file> <language>
lib my_npi_v1_00_a my_npi.v verilog
lib my_npi_v1_00_a my_other_file.vhd vhdl
Verilog Code Example
my_npi.v
--------
module my_npi (
strm_clk, // I
strm_rst, // I
strm_di, // I [63:0]
strm_do, // O [63:0]
strm_di_valid, // I
strm_do_valid, // O
XIL_NPI_Addr, // O [C_PI_ADDR_WIDTH-1:0]
XIL_NPI_AddrReq, // O
XIL_NPI_AddrAck, // I
XIL_NPI_RNW, // O
XIL_NPI_Size, // O [3:0]
XIL_NPI_WrFIFO_Data, // O [C_PI_DATA_WIDTH-1:0]
XIL_NPI_WrFIFO_BE, // O [C_PI_BE_WIDTH-1:0]
XIL_NPI_WrFIFO_Push, // O
XIL_NPI_RdFIFO_Data, // I [C_PI_DATA_WIDTH-1:0]
XIL_NPI_RdFIFO_Pop, // O
XIL_NPI_RdFIFO_RdWdAddr, // I [C_PI_RDWDADDR_WIDTH-1:0]
XIL_NPI_WrFIFO_Empty, //I
XIL_NPI_WrFIFO_AlmostFull, // I
XIL_NPI_WrFIFO_Flush, // O
// NPI_RdFIFO_DataAvailable, // I Only used for MPMC2 connections
XIL_NPI_RdFIFO_Empty, // I
XIL_NPI_RdFIFO_Flush, // O
XIL_NPI_RdFIFO_Latency, // I [1:0]
XIL_NPI_RdModWr, // O
XIL_NPI_InitDone // I
);
parameter C_PI_ADDR_WIDTH = 32;
parameter C_PI_DATA_WIDTH = 64;
parameter C_PI_BE_WIDTH = 8;
parameter C_PI_RDWDADDR_WIDTH = 4;
///////////////////////////////////////////////////////////////////////////////
// Fictitious Stream interface - bus is prefixed with strm_
input strm_clk;
input strm_rst;
input [63:0] strm_di;
output [63:0] strm_do;
input strm_di_valid;
output strm_do_valid;
///////////////////////////////////////////////////////////////////////////////
// MPMC Port Interface - Bus is prefixed with NPI_
output [C_PI_ADDR_WIDTH-1:0] NPI_Addr;
output XIL_NPI_AddrReq;
input XIL_NPI_AddrAck;
output XIL_NPI_RNW;
output [3:0] XIL_NPI_Size;
output [C_PI_DATA_WIDTH-1:0] XIL_NPI_WrFIFO_Data;
output [C_PI_BE_WIDTH-1:0] XIL_NPI_WrFIFO_BE;
output XIL_NPI_WrFIFO_Push;
input [C_PI_DATA_WIDTH-1:0] XIL_NPI_RdFIFO_Data;
output XIL_NPI_RdFIFO_Pop;
input [C_PI_RDWDADDR_WIDTH-1:0] XIL_NPI_RdFIFO_RdWdAddr;
input XIL_NPI_WrFIFO_Empty,
input XIL_NPI_WrFIFO_AlmostFull;
output XIL_NPI_WrFIFO_Flush;
// input NPI_RdFIFO_DataAvailable; //Only used for MPMC2 designs
input XIL_NPI_RdFIFO_Empty;
output XIL_NPI_RdFIFO_Flush;
input [1:0] XIL_NPI_RdFIFO_Latency;
output XIL_NPI_RdModWr;
input XIL_NPI_InitDone;
///////////////////////////////////////////////////////////////////////////////
// Fictitious Stream interface
reg [63:0] strm_do;
reg strm_do_valid;
///////////////////////////////////////////////////////////////////////////////
// MPMC Port Interface
reg [C_PI_ADDR_WIDTH-1:0] XIL_NPI_Addr;
reg XIL_NPI_AddrReq;
reg XIL_NPI_RNW;
reg [3:0] XIL_NPI_Size;
reg [C_PI_DATA_WIDTH-1:0] XIL_NPI_WrFIFO_Data;
reg [C_PI_BE_WIDTH-1:0] XIL_NPI_WrFIFO_BE;
reg XIL_NPI_WrFIFO_Push;
reg XIL_NPI_RdFIFO_Pop;
reg XIL_NPI_WrFIFO_Flush;
reg XIL_NPI_RdFIFO_Flush;
reg XIL_NPI_RdModWr;
endmodule
VHDL Code Example -
my_npi.vhd
--------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity my_npi is
generic(
C_PI_ADDR_WIDTH : integer := 32;
C_PI_DATA_WIDTH : integer := 64;
C_PI_BE_WIDTH : integer := 8;
C_PI_RDWDADDR_WIDTH: integer := 4
);
port(
--///////////////////////////////////////////////////////////////////////////////
--// Fictitious Stream interface - bus is prefixed with strm_
strm_clk : in std_logic;
strm_rst : in std_logic;
strm_di : in std_logic_vector(63 downto 0);
strm_do : out std_logic_vector(63 downto 0);
strm_di_valid : in std_logic;
strm_do_valid : out std_logic;
--///////////////////////////////////////////////////////////////////////////////
--// MPMC Port Interface - Bus is prefixed with NPI_
XIL_NPI_Addr : out std_logic_vector(C_PI_ADDR_WIDTH-1 downto 0);
XIL_NPI_AddrReq : out std_logic;
XIL_NPI_AddrAck : in std_logic;
XIL_NPI_RNW : out std_logic;
XIL_NPI_Size : out std_logic_vector(3 downto 0);
XIL_NPI_WrFIFO_Data : out std_logic_vector(C_PI_DATA_WIDTH-1 downto 0);
XIL_NPI_WrFIFO_BE : out std_logic_vector(C_PI_BE_WIDTH-1 downto 0);
XIL_NPI_WrFIFO_Push : out std_logic;
XIL_NPI_RdFIFO_Data : in std_logic_vector(C_PI_DATA_WIDTH-1 downto 0);
XIL_NPI_RdFIFO_Pop : out std_logic;
XIL_NPI_RdFIFO_RdWdAddr: in std_logic_vector(C_PI_RDWDADDR_WIDTH-1 downto 0);
XIL_NPI_WrFIFO_Empty: in std_logic;
XIL_NPI_WrFIFO_AlmostFull: in std_logic;
XIL_NPI_WrFIFO_Flush: out std_logic;
-- NPI_RdFIFO_DataAvailable: in std_logic; --Only used for MPMC2 designs
XIL_NPI_RdFIFO_Empty: in std_logic;
XIL_NPI_RdFIFO_Flush: out std_logic;
XIL_NPI_RdFIFO_Latency: in std_logic_vector(1 downto 0);
XIL_NPI_RdModWr: out std_logic;
XIL_NPI_InitDone: in std_logic
);
end entity;
architecture arc_my_npi OF my_npi IS
begin
end arc_my_npi;
An example VHDL NPI pcore is available below:
http://www.xilinx.com/txpatches/pub/applications/misc/ar24912.zip