Prev: BPSK modulation on Xilinx FPGA
Next: EDK Simulation
From: Nju Njoroge on 2 Mar 2006 01:13 Hello Mich, The master IPIF has a slave IPIF attachment, which interacts with master IPIF accesses. It is important to understand how it operates because the master won't function. For instance, for a: Master Read -- Assert IP2Bus_MstReq. You'll see that the read data returns through the slave attachment, appearing like a write-request to your "local target memory" (some register or BRAM inside your pcore) with Bus2IP_WrReq going high and Bus2IP_WrCE[x] as well (if you chose to use CEs). For proper functionality, you have to acknowledge this slave-attachment write with a IP2Bus_WrAck. Then, you will receive Bus2IP_MstRdAck some cycles later to confirm that your master read has been completed by the master IPIF. At this point, you can de-assert IP2Bus_MstRdReq. Master Write -- Raise IP2Bus_MstWrReq. The slave attachment will respond saying that it is ready to "read" your write data by asserting Bus2IP_RdReq (and Bus2IP_RdCE[x] if you have enabled CE's in IPIF). Once you have your write data ready, you issue IP2Bus_RdAck, which tells the slave attachment to read the data and push it to the master IPIF. Once the master IPIF is done writing the data, you'll receive Bus2IP_MstWrAck, at which point you can de-assert IP2Bus_MstWrReq. Pretty confusing if you ask me...but that's what is provided.... Good luck! NN Mich wrote: > Hi > > I 'm also trying to use a master ip on the PLB bus and I also use the > IPIF interface from the "Create Peripheral" wizard in EDK's XPS. > Like you I have some troubels with writhing and reading (I want to > write and read to/from a BRAM on the PLB-Bus) > You say that the slave attachment is also used for the master > trasaction. When I look at the timing diagram on pg 116 of the > plb_ipif.pdf > (http://www.xilinx.com/bvdocs/ipcenter/data_sheet/plb_ipif.pdf) it say > that when you read you will get a Bus2IP_WrReq is this correct, because > you want to read and not write. Is this correct? > > I have made a small FSM to test a single read and write (at the bottom > of the message is my VHDL-code) > > I have a state (PrepareWr_State and PrepareRd_State) to make sure all > the addresses are correct > I have a state (ReqWr_State and ReqRd_State) for the request => > IP2Bus_MstWrReq and IP2Bus_MstRdReq > I have a state (AckWr_State and AckRd_State) for the ack that the IPIF > can read/write from/to my ip => IP2Bus_WrAck and IP2Bus_RdAck > I have a state (OkWr_State and OkRd_State) so I know everything went > well > > But there must be something wrong because it doesn't work, when I want > to write something, my FSM stays in the ReqWr_State, and when I want to > read something it also doesn't do what it should do (or atleast what I > think it should do) > > Can you help me please? > > Mich > > > > -- TRANSITION_STATE_LOGIC > > STATE_TRANSITION_LOGIC: process (ACTUAL_STATE, pushR, pushL, pushU, > pushD, Bus2IP_MstLastAck, Bus2IP_WrReq, Bus2IP_RdReq) > variable counter_Rd : integer range 0 to 15; > variable counter_Wr : integer range 0 to 15; > begin > > case ACTUAL_STATE is > when idle => > if (pushR = '0') then -- pushR is active low > NEXT_STATE <= PrepareWr_State; > counter_Wr := 10; > elsif (pushL = '0') then -- pushL is actief laag > NEXT_STATE <= PrepareRd_State; > counter_Rd := 10; > else > NEXT_STATE <= idle; > end if; > > when PrepareWr_State => > if (counter_Wr = 0) then > NEXT_STATE <= ReqWr_State; > else > NEXT_STATE <= PrepareWr_State; > counter_Wr := counter_Wr - 1; > end if; > > when ReqWr_State => > if (Bus2IP_MstLastAck = '1') then > NEXT_STATE <= AckWr_State; > else > NEXT_STATE <= ReqWr_State; > end if; > > when AckWr_State => > if (Bus2IP_MstLastAck = '1') then > NEXT_STATE <= OkWr_State; > else > NEXT_STATE <= AckWr_State; > end if; > > when OkWr_State => -- Writing is ok > if (pushU = '0') then -- PusU is active Low > NEXT_STATE <= idle; > else > NEXT_STATE <= OkWr_State; > end if; > > when PrepareRd_State => > if (counter_Rd = 0) then > NEXT_STATE <= ReqRd_State; > else > NEXT_STATE <= PrepareRd_State; > counter_Rd := counter_Rd - 1; > end if; > > when ReqRd_State => > if (Bus2IP_WrReq = '1') then > NEXT_STATE <= AckRd_State; > else > NEXT_STATE <= ReqRd_State; > end if; > > when AckRd_State => > if (Bus2IP_MstLastAck = '1') then > NEXT_STATE <= OkRd_State; > else > NEXT_STATE <= AckRd_State; > end if; > > when OkRd_State => -- Reading is ok > if (pushD = '0') then -- pushD is actief laag > NEXT_STATE <= idle; > else > NEXT_STATE <= OkRd_State; > end if; > > when others => NEXT_STATE <= idle; > end case; > > end process STATE_TRANSITION_LOGIC; > -- TRANSITION_STATE_LOGIC > > -- OUTPUT_LOGIC > OUTPUT_LOGIC: process (ACTUAL_STATE) > begin > case ACTUAL_STATE is > when idle => > led <= "1110"; > IP2Bus_Data(0 to 3) <= schakelaar; > IP2Bus_RdAck <= '0'; > IP2Bus_WrAck <= '0'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "11111111"; > IP2Bus_MstRdReq <= '0'; > IP2Bus_MstWrReq <= '0'; > > when PrepareWr_State => > led <= "0001"; > IP2Bus_Data(0 to 3) <= D_out; > IP2Bus_RdAck <= '0'; > IP2Bus_WrAck <= '0'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "11111111"; > IP2Bus_MstRdReq <= '0'; > IP2Bus_MstWrReq <= '0'; > > when ReqWr_State => > led <= "0010"; > IP2Bus_Data(0 to 3) <= D_out; > IP2Bus_RdAck <= '0'; > IP2Bus_WrAck <= '0'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "11111111"; > IP2Bus_MstRdReq <= '0'; > IP2Bus_MstWrReq <= '1'; > > when AckWr_State => > led <= "0011"; > IP2Bus_Data(0 to 3) <= D_out; > IP2Bus_RdAck <= '1'; > IP2Bus_WrAck <= '0'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "11111111"; > IP2Bus_MstRdReq <= '0'; > IP2Bus_MstWrReq <= '1'; > > when OkWr_State => > led <= "0100"; > IP2Bus_Data(0 to 3) <= schakelaar; > IP2Bus_RdAck <= '0'; > IP2Bus_WrAck <= '0'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "11111111"; > IP2Bus_MstRdReq <= '0'; > IP2Bus_MstWrReq <= '0'; > > when PrepareRd_State => > led <= "1000"; > IP2Bus_Data(0 to 3) <= D_out; > IP2Bus_RdAck <= '0'; > IP2Bus_WrAck <= '0'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "11111111"; > IP2Bus_MstRdReq <= '0'; > IP2Bus_MstWrReq <= '0'; > > when ReqRd_State => > led <= "1001"; > IP2Bus_Data(0 to 3) <= D_out; > IP2Bus_RdAck <= '0'; > IP2Bus_WrAck <= '0'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "11111111"; > IP2Bus_MstRdReq <= '1'; > IP2Bus_MstWrReq <= '0'; > > when AckRd_State => > led <= "1010"; > IP2Bus_Data(0 to 3) <= D_out; > IP2Bus_RdAck <= '0'; > IP2Bus_WrAck <= '1'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "11111111"; > IP2Bus_MstRdReq <= '1'; > IP2Bus_MstWrReq <= '0'; > > when OkRd_State => > if (D_out = Bus2IP_Data(0 to 3)) then > led <= "1011"; > else > led <= "1100"; > end if; > IP2Bus_Data(0 to 3) <= schakelaar; > IP2Bus_RdAck <= '0'; > IP2Bus_WrAck <= '0'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "11111111"; > IP2Bus_MstRdReq <= '0'; > IP2Bus_MstWrReq <= '0'; > > when others => > led <= "1111"; > IP2Bus_Data(0 to 3) <= schakelaar; > IP2Bus_RdAck <= '0'; > IP2Bus_WrAck <= '0'; > IP2Bus_Addr <= C_Memory_Addr; > IP2Bus_MstBE <= "00000000"; > IP2Bus_MstRdReq <= '0'; > IP2Bus_MstWrReq <= '0'; > end case; > > end process OUTPUT_LOGIC; > -- OUTPUT_LOGIC |