ping.vhd

来自「xilinx官方PCIcore 有详细说明文档」· VHDL 代码 · 共 594 行 · 第 1/2 页

VHD
594
字号
  WRITE_MY_MEM_REG:  process(RST, CLK)  begin      if RST = '1' then my_mem_reg <= "00110010001100100011001000110010";    elsif (CLK'event and CLK = '1') then      if S_DATA_VLD = '1' and bar1_wr_cs = '1' then         if S_CBE(0) = '0' then my_mem_reg( 7 downto  0) <= ADIO( 7 downto  0);        end if;          if S_CBE(1) = '0' then my_mem_reg(15 downto  8) <= ADIO(15 downto  8);        end if;          if S_CBE(2) = '0' then my_mem_reg(23 downto 16) <= ADIO(23 downto 16);        end if;          if S_CBE(3) = '0' then my_mem_reg(31 downto 24) <= ADIO(31 downto 24);        end if;        end if;    end if;   end process;   oe_mem_reg <= bar1_rd_cs and S_DATA;  ADIO(31 downto 0) <= my_mem_reg when (oe_mem_reg = '1') else (others=>'Z');  -----------------------------------------------------------------------   -- This section contains the MEM64 implementation.     -----------------------------------------------------------------------     WRITE_MY_WIDE_REG:   process(RST, CLK)   begin       if RST = '1' then my_wide_reg <= "01100100011001000110010001100100" &                                     "01100100011001000110010001100100";    elsif (CLK'event and CLK = '1') then       if S_DATA_VLD = '1' and bar2_wr_cs = '1' then           if S_CBE(0) = '0' then my_wide_reg( 7 downto  0) <= ADIO( 7 downto  0);         end if;           if S_CBE(1) = '0' then my_wide_reg(15 downto  8) <= ADIO(15 downto  8);         end if;           if S_CBE(2) = '0' then my_wide_reg(23 downto 16) <= ADIO(23 downto 16);         end if;           if S_CBE(3) = '0' then my_wide_reg(31 downto 24) <= ADIO(31 downto 24);         end if;            if S_CBE(4) = '0' then my_wide_reg(39 downto 32) <= ADIO(39 downto 32);         end if;           if S_CBE(5) = '0' then my_wide_reg(47 downto 40) <= ADIO(47 downto 40);         end if;           if S_CBE(6) = '0' then my_wide_reg(55 downto 48) <= ADIO(55 downto 48);         end if;           if S_CBE(7) = '0' then my_wide_reg(63 downto 56) <= ADIO(63 downto 56);         end if;        end if;     end if;    end process;     oe_wide_reg <= bar2_rd_cs and S_DATA;   ADIO(63 downto 0) <= my_wide_reg when (oe_wide_reg = '1') else (others=>'Z');  -----------------------------------------------------------------------   -- This section contains the initiator logic.  -----------------------------------------------------------------------   -- Bus addresses are obtained from the MEM32 register.  -- Direction is from IO32(31) and burst length is IO32(3:0).  -- A general purpose register file is used for the source  -- or destination depending on the data transfer direction.  PING_FSM:  process(ping_state, start32, start64, mdata_fell, dir)  begin    case ping_state is      -- IDLE_S is the idle state.  If the state machine is      -- signaled to start, proceed to the next state.      when IDLE_S =>        if start64 = '1' and dir = '1' then nxt_ping_state <= WRITE64_S;        elsif start64 = '1' and dir = '0' then nxt_ping_state <= READ64_S;        elsif start32 = '1' and dir = '1' then nxt_ping_state <= WRITE32_S;        elsif start32 = '1' and dir = '0' then nxt_ping_state <= READ32_S;        else nxt_ping_state <= IDLE_S;        end if;      -- WRITE64_S stays put until it sees a deassertion of      -- the M_DATA signal indicating that a transfer is over.      -- More elaborate FSMs may check error conditions at      -- the time mdata_fell is asserted.      when WRITE64_S =>        if mdata_fell = '1' then nxt_ping_state <= IDLE_S;        else nxt_ping_state <= WRITE64_S;        end if;      -- WRITE32_S stays put until it sees a deassertion of      -- the M_DATA signal indicating that a transfer is over.      -- More elaborate FSMs may check error conditions at      -- the time mdata_fell is asserted.      when WRITE32_S =>        if mdata_fell = '1' then nxt_ping_state <= IDLE_S;        else nxt_ping_state <= WRITE32_S;        end if;      -- READ64_S stays put until it sees a deassertion of      -- the M_DATA signal indicating that a transfer is over.      -- More elaborate FSMs may check error conditions at      -- the time mdata_fell is asserted.      when READ64_S =>        if mdata_fell = '1' then nxt_ping_state <= IDLE_S;        else nxt_ping_state <= READ64_S;        end if;      -- READ32_S stays put until it sees a deassertion of      -- the M_DATA signal indicating that a transfer is over.      -- More elaborate FSMs may check error conditions at      -- the time mdata_fell is asserted.      when READ32_S =>        if mdata_fell = '1' then nxt_ping_state <= IDLE_S;        else nxt_ping_state <= READ32_S;        end if;       -- Include a default state just in case we have any      -- accidents with the state machine.      when others =>        nxt_ping_state <= IDLE_S;    end case;  end process;   PING_FSM_SEQ:  process(RST, CLK)  begin    if RST = '1' then ping_state <= IDLE_S;    elsif (CLK'event and CLK = '1') then ping_state <= nxt_ping_state;    end if;  end process;  -- Need a delayed version of M_DATA and also  -- a delayed version of the transfer length  -- counter load signal.  MISC_SIGNALS:  process(RST, CLK)  begin    if RST = '1' then      mdata_delay <= '0';      xfer_load_delay <= '0';      pre_done <= '0';      reg_preq32 <= '0';      reg_preq64 <= '0';    elsif (CLK'event and CLK = '1') then      mdata_delay <= M_DATA;      xfer_load_delay <= xfer_load;      pre_done <= ns_done;      reg_preq32 <= PING_REQUEST32;      reg_preq64 <= PING_REQUEST64;    end if;   end process;  -- This is the "set/reset" implementation  -- for the COMPLETE logic.  HOLD_IT:  process(RST, CLK)  begin    if RST = '1' then feedback <= '0';    elsif (CLK'event and CLK = '1') then      if mdata_fell = '1' then feedback <= '0';      elsif assert_complete = '1' then feedback <= '1';      end if;    end if;  end process;  -- This is the transfer length counter.  -- Transfer lengths may be anywhere from  -- one to sixteen data phases.  TRANSFER_COUNTER:  process(RST, CLK)  begin    if RST = '1' then xfer_len <= "0000";    elsif (CLK'event and CLK = '1') then      if xfer_load = '1' then xfer_len <= my_io_reg(3 downto 0);      elsif M_DATA_VLD = '1' then xfer_len <= xfer_len - 1;      end if;    end if;  end process;  -- Decode some things for the complete logic.  cnt3 <= '1' when (xfer_len = "0011") else '0';  cnt2 <= '1' when (xfer_len = "0010") else '0';  cnt1 <= '1' when (xfer_len = "0001") else '0';  fin3 <= cnt3 and M_DATA_VLD;  fin2 <= cnt2 and mdata_delay;  fin1 <= cnt1 and xfer_load_delay;  -- Generate some internal signals.  start32 <= reg_preq32;  start64 <= reg_preq64;  dir <= my_io_reg(31);  mdata_fell <= not M_DATA and mdata_delay;  xfer_load <= (start32 or start64) when (ping_state = IDLE_S) else '0';  assert_complete <= fin1 or fin2 or fin3;  hold_complete <= feedback;  ns_done <= mdata_fell when (ping_state /= IDLE_S) else '0';  -- Drive outputs to the PCI interface.  M_WRDN <= dir;  REQUEST <= start32 when (ping_state = IDLE_S) else '0';  REQUEST64 <= start64 when (ping_state = IDLE_S) else '0';  COMPLETE <= assert_complete or hold_complete;  ADIO(63 downto 0) <= ("00000000000000000000000000000000" & my_mem_reg)                       when (M_ADDR_N = '0') else (others =>'Z');  M_CBE(7 downto 0) <= ("0000" & my_io_reg(7 downto 5) & dir)                       when (M_ADDR_N = '0') else (others =>'0');  PING_DONE <= pre_done;  -- A simple 64-bit register for data transfer.  xlr <= '1' when ((ping_state=READ32_S) or (ping_state=READ64_S)) else '0';  xlw <= '1' when ((ping_state=WRITE32_S) or (ping_state=WRITE64_S)) else '0';  xhr <= '1' when (ping_state = READ64_S) else '0';    WRITE_MY_INIT_REG:   process(RST, CLK)   begin       if RST = '1' then my_init_reg <= "00000000000000000000000000000000" &                                     "00000000000000000000000000000000";    elsif (CLK'event and CLK = '1') then       if M_DATA_VLD = '1' then           if xlr = '1' then my_init_reg( 7 downto  0) <= ADIO( 7 downto  0);         end if;           if xlr = '1' then my_init_reg(15 downto  8) <= ADIO(15 downto  8);         end if;           if xlr = '1' then my_init_reg(23 downto 16) <= ADIO(23 downto 16);         end if;           if xlr = '1' then my_init_reg(31 downto 24) <= ADIO(31 downto 24);         end if;            if xhr = '1' then my_init_reg(39 downto 32) <= ADIO(39 downto 32);         end if;           if xhr = '1' then my_init_reg(47 downto 40) <= ADIO(47 downto 40);         end if;           if xhr = '1' then my_init_reg(55 downto 48) <= ADIO(55 downto 48);         end if;           if xhr = '1' then my_init_reg(63 downto 56) <= ADIO(63 downto 56);         end if;        end if;     end if;    end process;     oe_init_reg <= M_DATA and xlw;  ADIO(63 downto 0) <= my_init_reg when (oe_init_reg = '1') else (others=>'Z');  -----------------------------------------------------------------------   -- This section contains unused signals.  -----------------------------------------------------------------------   C_TERM <= '1';  C_READY <= '1';  KEEPOUT <= '0';  CFG_SELF <= '0';  REQUESTHOLD <= '0';  SUB_DATA <= "00000000000000000000000000000000";  DONT_OPTIMIZE_PLEASE:  process(RST, CLK)  begin    if RST = '1' then      intr_n_reg <= '0';      s_term_reg <= '1';      s_ready_reg <= '0';      m_ready_reg <= '0';    elsif (CLK'event and CLK = '1') then      intr_n_reg <= '1';      s_term_reg <= '0';      s_ready_reg <= '1';      m_ready_reg <= '1';    end if;  end process;   INTR_N <= intr_n_reg;  S_TERM <= s_term_reg;  S_READY <= s_ready_reg;  S_ABORT <= S_CYCLE64 and ADDR(2);  M_READY <= m_ready_reg;  SLOT64 <= not my_cfg_reg(0);end rtl;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?