Sign In

Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Regular Visitor
wen119at
Posts: 51
Registered: ‎02-16-2010
0

Re: Connecting a Custom IP to MPMC

Hi,

 

Thank you so much………………

It really helps...

I will try them out...

Really appreciate your kind help...

 

winnie

Regular Visitor
wen119at
Posts: 51
Registered: ‎02-16-2010
0

Re: Connecting a Custom IP to MPMC

Hi,

 

I have a new question related to the mpmc core.

The tutorial said " In the XPS Port Tab, connect all relevant PIM signals as external I/O". I don't understand why I should do this?

When I made those NPI PIM signals external, the MHS looks like this:

 

 PORT DDR2_SDRAM_PIM1_Addr_pin = DDR2_SDRAM_PIM1_Addr, DIR = I, VEC = [31:0]
 PORT DDR2_SDRAM_PIM1_AddrReq_pin = DDR2_SDRAM_PIM1_AddrReq, DIR = I
 PORT DDR2_SDRAM_PIM1_AddrAck_pin = newip_0_XIL_NPI_AddrAck, DIR = O
 PORT DDR2_SDRAM_PIM1_RNW_pin = DDR2_SDRAM_PIM1_RNW, DIR = I
 PORT DDR2_SDRAM_PIM1_Size_pin = DDR2_SDRAM_PIM1_Size, DIR = I, VEC = [3:0]
 PORT DDR2_SDRAM_PIM1_RdModWr_pin = DDR2_SDRAM_PIM1_RdModWr, DIR = I
 PORT DDR2_SDRAM_PIM1_WrFIFO_Data_pin = DDR2_SDRAM_PIM1_WrFIFO_Data, DIR = I, VEC = [63:0]
 PORT DDR2_SDRAM_PIM1_WrFIFO_BE_pin = DDR2_SDRAM_PIM1_WrFIFO_BE, DIR = I, VEC = [7:0]
 PORT DDR2_SDRAM_PIM1_InitDone_pin = newip_0_XIL_NPI_InitDone, DIR = O
 PORT DDR2_SDRAM_PIM1_RdFIFO_Latency_pin = newip_0_XIL_NPI_RDFIFO_Latency, DIR = O, VEC = [1:0]
 PORT DDR2_SDRAM_PIM1_RdFIFO_Flush_pin = DDR2_SDRAM_PIM1_RdFIFO_Flush, DIR = I
 PORT DDR2_SDRAM_PIM1_RdFIFO_Empty_pin = newip_0_XIL_NPI_RdFIFO_Empty, DIR = O
 PORT DDR2_SDRAM_PIM1_WrFIFO_Flush_pin = DDR2_SDRAM_PIM1_WrFIFO_Flush, DIR = I
 PORT DDR2_SDRAM_PIM1_WrFIFO_AlmostFull_pin = newip_0_XIL_NPI_WrFIFO_AlmostFull, DIR = O
 PORT DDR2_SDRAM_PIM1_WrFIFO_Empty_pin = newip_0_XIL_NPI_WrFIFO_Empty, DIR = O
 PORT DDR2_SDRAM_PIM1_RdFIFO_RdWdAddr_pin = newip_0_XIL_NPI_RdFIFO_RdWdAddr, DIR = O, VEC = [3:0]
 PORT DDR2_SDRAM_PIM1_RdFIFO_Pop_pin = DDR2_SDRAM_PIM1_RdFIFO_Pop, DIR = I
 PORT DDR2_SDRAM_PIM1_RdFIFO_Data_pin = newip_0_XIL_NPI_RdFIFO_Data, DIR = O, VEC = [63:0]
 PORT DDR2_SDRAM_PIM1_WrFIFO_Push_pin = DDR2_SDRAM_PIM1_WrFIFO_Push, DIR = I

 

BEGIN mpmc
 PARAMETER INSTANCE = DDR2_SDRAM
 PARAMETER C_NUM_PORTS = 2
 PARAMETER C_NUM_IDELAYCTRL = 3
 PARAMETER C_IDELAYCTRL_LOC = IDELAYCTRL_X0Y6-IDELAYCTRL_X0Y2-IDELAYCTRL_X0Y1
 PARAMETER C_MEM_PARTNO = mt4htf3264h-53e
 PARAMETER C_MEM_ODT_TYPE = 1
 PARAMETER C_MEM_CLK_WIDTH = 2
 PARAMETER C_MEM_ODT_WIDTH = 2
 PARAMETER C_MEM_CE_WIDTH = 1
 PARAMETER C_MEM_CS_N_WIDTH = 1
 PARAMETER C_DDR2_DQSN_ENABLE = 1
 PARAMETER C_PIM0_BASETYPE = 2
 PARAMETER HW_VER = 5.04.a
 PARAMETER C_PIM1_BASETYPE = 4
 PARAMETER C_MPMC_BASEADDR = 0xd0000000
 PARAMETER C_MPMC_HIGHADDR = 0xdfffffff
 BUS_INTERFACE SPLB0 = mb_plb
 BUS_INTERFACE MPMC_PIM1 = newip_0_XIL_NPI
 PORT MPMC_Clk0 = clk_200_0000MHzPLL0
 PORT MPMC_Clk0_DIV2 = clk_100_0000MHzPLL0
 PORT MPMC_Clk90 = clk_200_0000MHz90PLL0
 PORT MPMC_Clk_200MHz = clk_200_0000MHzPLL0
 PORT MPMC_Rst = sys_periph_reset
 PORT DDR2_Clk = fpga_0_DDR2_SDRAM_DDR2_Clk_pin
 PORT DDR2_Clk_n = fpga_0_DDR2_SDRAM_DDR2_Clk_n_pin
 PORT DDR2_CE = fpga_0_DDR2_SDRAM_DDR2_CE_pin
 PORT DDR2_CS_n = fpga_0_DDR2_SDRAM_DDR2_CS_n_pin
 PORT DDR2_ODT = fpga_0_DDR2_SDRAM_DDR2_ODT_pin
 PORT DDR2_RAS_n = fpga_0_DDR2_SDRAM_DDR2_RAS_n_pin
 PORT DDR2_CAS_n = fpga_0_DDR2_SDRAM_DDR2_CAS_n_pin
 PORT DDR2_WE_n = fpga_0_DDR2_SDRAM_DDR2_WE_n_pin
 PORT DDR2_BankAddr = fpga_0_DDR2_SDRAM_DDR2_BankAddr_pin
 PORT DDR2_Addr = fpga_0_DDR2_SDRAM_DDR2_Addr_pin
 PORT DDR2_DQ = fpga_0_DDR2_SDRAM_DDR2_DQ_pin
 PORT DDR2_DM = fpga_0_DDR2_SDRAM_DDR2_DM_pin
 PORT DDR2_DQS = fpga_0_DDR2_SDRAM_DDR2_DQS_pin
 PORT DDR2_DQS_n = fpga_0_DDR2_SDRAM_DDR2_DQS_n_pin
 PORT PIM1_Addr = DDR2_SDRAM_PIM1_Addr
 PORT PIM1_AddrReq = DDR2_SDRAM_PIM1_AddrReq
 PORT PIM1_RNW = DDR2_SDRAM_PIM1_RNW
 PORT PIM1_Size = DDR2_SDRAM_PIM1_Size
 PORT PIM1_RdModWr = DDR2_SDRAM_PIM1_RdModWr
 PORT PIM1_WrFIFO_Data = DDR2_SDRAM_PIM1_WrFIFO_Data
 PORT PIM1_WrFIFO_BE = DDR2_SDRAM_PIM1_WrFIFO_BE
 PORT PIM1_RdFIFO_Flush = DDR2_SDRAM_PIM1_RdFIFO_Flush
 PORT PIM1_WrFIFO_Flush = DDR2_SDRAM_PIM1_WrFIFO_Flush
 PORT PIM1_RdFIFO_Pop = DDR2_SDRAM_PIM1_RdFIFO_Pop
 PORT PIM1_WrFIFO_Push = DDR2_SDRAM_PIM1_WrFIFO_Push

END 

 

I really don't understand what does this mean... If I don't make these signals external, what would be affected?

Do i need to make those signals in my ip external as well?

sorry for trouble you again...

 

winnie

Regular Visitor
yasirmahmoodqureshi
Posts: 29
Registered: ‎09-03-2009
0

Re: Connecting a Custom IP to MPMC

YOu don't need to make them external!!
Regular Visitor
wen119at
Posts: 51
Registered: ‎02-16-2010
0

Re: Connecting a Custom IP to MPMC

Hi,

 

That's great~ Then, do you think that "make external" means connect the signal to a pin?

As to the protocol you mentioned, do you think that they should be written in the toplevel of my ip between

 "architecture of newip is

begin

...

end"

?

just like the plb protocol?

 

really sory for trouble you so much ....

Regular Visitor
yasirmahmoodqureshi
Posts: 29
Registered: ‎09-03-2009
0

Re: Connecting a Custom IP to MPMC

yes , making external means to connect the sugnla to pins, you aren't required to do that, as it is aumatically done by BSB if you include mpmc initially while making the project.

 

 i don't understand your your 2nd question, pl clarify?

Regular Visitor
wen119at
Posts: 51
Registered: ‎02-16-2010
0

Re: Connecting a Custom IP to MPMC

Hi,

 

You told me that the NPI protocol should be written in VHDL. In fact , i am not quite clear about this...

Actually...so far,what i've done is to add the generic and ports of NPI to the toplevel of my own created ip...and active the NPI port of MPMC...

I thought what you mean by saying write NPI protocol using VHDL is add the sentences famaliar with the follows to the toplevel of my ip as well...If not...what should i do...really confused... Is it the case that the communication between the NPI port of mpmc to DDR has been done by mpmc automatically?

 

architecture arc_my_ip of my_npi is

type state_type is (RST, IDLE, TX_DATA, TX_ADDR, RX_ADDR, RX_WAIT_NOT_EMPTY,

RX_WAIT_RXFIFO_LAT2, RX_WAIT_RXFIFO_LAT1, RX_POP);

signal npi_cs, npi_ns : state_type;

signal gen_data : std_logic := '0';

signal npi_wrfifo_push_i : std_logic := '0';

signal npi_req_set : std_logic := '0';

signal npi_rnw_i : std_logic := '0';

signal npi_wrfifo_be_i : std_logic_vector(C_PI_BE_WIDTH-1 downto 0) := (others => '0');

signal data : std_logic_vector(C_PI_DATA_WIDTH-1 downto 0) := (others => '0');

signal npi_size_i : std_logic_vector(3 downto 0) := (others => '0');

signal npi_addrreq_int : std_logic := '0';

signal initdone : std_logic := '0';

signal compare_enable : std_logic := '0';

signal npi_rdfifo_pop_i : std_logic := '0';

signal compare_error_i : std_logic := '0';

begin

 

-- Internally used outputs

XIL_NPI_RdFIFO_Pop <= npi_rdfifo_pop_i;

-- Basic pipeline for write path signals

PIPE : process (XIL_NPI_Clk)

begin

if rising_edge(XIL_NPI_Clk) then

initdone <= XIL_NPI_InitDone;

XIL_NPI_WrFIFO_Push <= npi_wrfifo_push_i;

XIL_NPI_WrFIFO_BE <= npi_wrfifo_be_i;

XIL_NPI_WrFIFO_Data <= data;

end if;

end process;

-- Upon address ack, clear address qualifiers

ADDRACK_PIPE : process (XIL_NPI_Clk, XIL_NPI_AddrAck)

begin

if rising_edge(XIL_NPI_Clk) then

if XIL_NPI_AddrAck = '1' then

XIL_NPI_RNW <= '0';

XIL_NPI_Size <= "0000";

else

XIL_NPI_RNW <= npi_rnw_i;

XIL_NPI_Size <= npi_size_i;

end if;

end if;

end process;

-- Address ack pipeline

-- Deassert address request

NPI_REQ_PIPE : process (XIL_NPI_Clk, XIL_NPI_AddrAck, npi_req_set)

begin

if rising_edge(XIL_NPI_Clk) then

if XIL_NPI_AddrAck = '1' then

npi_addrreq_int <= '0';

elsif npi_req_set = '1' then

npi_addrreq_int <= '1';

else

npi_addrreq_int <= npi_addrreq_int;

end if;

end if;

end process;

XIL_NPI_AddrReq <= npi_addrreq_int;

-- Data testbench generator

-- a simple counter for each NPI beat

-- activated for both writes and reads (to verify returned data)

DATA_GEN : process (XIL_NPI_Clk, XIL_NPI_Rst, gen_data)

begin -- process

if rising_edge(XIL_NPI_Clk) then

if XIL_NPI_Rst = '1' then

data <= (others => '0');

elsif (gen_data = '1' or compare_enable = '1') then

data <= data + 1;

else

data <= (others => '0');

end if;

end if;

end process;

-- Testbench compare logic

COMPARE : process (XIL_NPI_Clk, XIL_NPI_Rst, compare_enable, XIL_NPI_RdFIFO_Data, data)

begin -- process

if rising_edge(XIL_NPI_Clk) then

if XIL_NPI_Rst = '1' then

compare_error_i <= '0';

elsif (compare_enable = '1') and (XIL_NPI_RdFIFO_Data /= data) then

-- If data does not match during a valid read, set error flag

compare_error_i <= '1';

else

compare_error_i <= compare_error_i;

end if;

end if;

end process;

Compare_Error <= compare_error_i;

-- State machine to sequence through NPI transactions

-- It will perform a cacheline write to address 0 and then perform a

-- cacheline read to the same address

-- Typically, this would be broken into separate read and write processes

-- with some local arbitration for the NPI address request, and each read

-- and write FIFOs operating independently of each other

NPI_STATE_NS : process (npi_cs, data, XIL_NPI_AddrAck, XIL_NPI_RdFIFO_Latency, XIL_NPI_RdFIFO_Empty)

begin

--default signal values if not overriden by current state

npi_ns <= npi_cs;

gen_data <= '0';

npi_wrfifo_push_i <= '0';

npi_req_set <= '0';

npi_rnw_i <= '0';

npi_size_i <= "0000";

npi_wrfifo_be_i <= "00000000";

case (npi_cs) is

when RST =>

npi_ns <= IDLE;

when IDLE =>

-- Start pushing data into write FIFO

npi_ns <= TX_DATA;

gen_data <= '1';

npi_wrfifo_push_i <= '1';

npi_wrfifo_be_i <= "11111111";

when TX_DATA =>

-- Continue to fill write FIFO until entire burst is in FIFO

-- This is conservative, a more agressive approach is to rate-

-- match with memory single data rate relative to NPI rate enough

-- to prevent underflow of write FIFO

if (data = "0100") then

npi_wrfifo_push_i <= '0';

npi_wrfifo_be_i <= "00000000";

gen_data <= '0';

-- Start address phase

npi_ns <= TX_ADDR;

npi_req_set <= '1';

npi_rnw_i <= '0';

npi_size_i <= "0010";

else

-- Continue to push data into WrFIFO

npi_ns <= TX_DATA;

npi_wrfifo_push_i <= '1';

npi_wrfifo_be_i <= "11111111";

gen_data <= '1';

end if;

when TX_ADDR =>

-- Hold qualifiers active until transaction accepted

-- into MPMC control path

if XIL_NPI_AddrAck = '1' then

-- Start read, which starts with the address phase first

npi_ns <= RX_ADDR;

npi_req_set <= '1';

npi_rnw_i <= '1';

npi_size_i <= "0010";

else

npi_ns <= TX_ADDR;

npi_req_set <= '1';

npi_rnw_i <= '0';

npi_size_i <= "0010";

end if;

when RX_ADDR =>

if XIL_NPI_AddrAck = '1' then

-- Assuming at least one cycle DDR turnaround latency

-- to simplify logic

-- Then wait until FIFO reports that it is non-empty

npi_ns <= RX_WAIT_NOT_EMPTY;

npi_req_set <= '0';

npi_rnw_i <= '0';

npi_size_i <= "0000";

else

npi_ns <= RX_ADDR;

npi_req_set <= '1';

npi_rnw_i <= '1';

npi_size_i <= "0010";

end if;

when RX_WAIT_NOT_EMPTY =>

-- Depending on Rd_FIFO_Latency, wait before popping read FIFO

if XIL_NPI_RdFIFO_Empty = '0' then

if XIL_NPI_RdFIFO_Latency = "10" then

npi_ns <= RX_WAIT_RXFIFO_LAT2;

npi_rdfifo_pop_i <= '1';

elsif XIL_NPI_RdFIFO_Latency = "01" then

npi_ns <= RX_WAIT_RXFIFO_LAT1;

npi_rdfifo_pop_i <= '1';

else

-- Data can be popped now, start compare logic

npi_ns <= RX_POP;

compare_enable <= '1';

npi_rdfifo_pop_i <= '1';

end if;

else

npi_ns <= RX_WAIT_NOT_EMPTY;

end if;

when RX_WAIT_RXFIFO_LAT2 =>

-- First wait state for Latency = 2

if XIL_NPI_RdFIFO_Empty = '1' then

npi_ns <= RX_WAIT_RXFIFO_LAT2;

else

npi_ns <= RX_WAIT_RXFIFO_LAT1;

end if;

when RX_WAIT_RXFIFO_LAT1 =>

-- Second wait state for Latency = 2

-- First wait state for Latency = 1

if XIL_NPI_RdFIFO_Empty = '1' then

npi_ns <= RX_WAIT_RXFIFO_LAT1;

else

-- Data can be popped now, start compare logic

npi_ns <= RX_POP;

compare_enable <= '1';

npi_rdfifo_pop_i <= '1';

end if;

when RX_POP =>

-- Continue to pop data until read FIFO empty

if XIL_NPI_RdFIFO_Empty = '0' then

npi_ns <= RX_POP;

compare_enable <= '1';

npi_rdfifo_pop_i <= '1';

else

-- Start over with another write/read

npi_ns <= IDLE;

npi_rdfifo_pop_i <= '0';

compare_enable <= '0';

end if;

end case;

end process;

-- State machine synchronous logic

NPI_STATE_SYNC : process (XIL_NPI_Clk, XIL_NPI_Rst, initdone)

begin

if rising_edge(XIL_NPI_Clk) then

if ((XIL_NPI_Rst = '1') or (initdone = '0')) then

npi_cs <= RST;

else

npi_cs <= npi_ns;

end if;

end if;

end process;

end arc_my_npi;