⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci_mt.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--------------------------------------------------------------------------------  This file is a part of the GRLIB VHDL IP LIBRARY--  Copyright (C) 2003, Gaisler Research----  This program is free software; you can redistribute it and/or modify--  it under the terms of the GNU General Public License as published by--  the Free Software Foundation; either version 2 of the License, or--  (at your option) any later version.----  This program is distributed in the hope that it will be useful,--  but WITHOUT ANY WARRANTY; without even the implied warranty of--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the--  GNU General Public License for more details.----  You should have received a copy of the GNU General Public License--  along with this program; if not, write to the Free Software--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA ------------------------------------------------------------------------------- Entity: 	pci_mt-- File:	pci_mt.vhd-- Author:	Jiri Gaisler - Gaisler Research-- Modified: 	Alf Vaerneus - Gaisler Research-- Description:	Simple PCI master and target interface------------------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;library grlib;use grlib.amba.all;use grlib.stdlib.all;use grlib.devices.all;library gaisler;use gaisler.pci.all;use gaisler.misc.all;use gaisler.pcilib.all;entity pci_mt is  generic (    hmstndx   : integer := 0;    abits     : integer := 21;    device_id : integer := 0;		-- PCI device ID    vendor_id : integer := 0;	        -- PCI vendor ID    master    : integer := 1; 		-- Enable PCI Master    hslvndx   : integer := 0;    haddr     : integer := 16#F00#;    hmask     : integer := 16#F00#;    ioaddr    : integer := 16#000#;    nsync     : integer range 1 to 2 := 1;	-- 1 or 2 sync regs between clocks    oepol     : integer := 0);   port(      rst       : in std_logic;      clk       : in std_logic;      pciclk    : in std_logic;      pcii      : in  pci_in_type;      pcio      : out pci_out_type;      ahbmi     : in  ahb_mst_in_type;      ahbmo     : out ahb_mst_out_type;      ahbsi     : in  ahb_slv_in_type;      ahbso     : out ahb_slv_out_type);end;architecture rtl of pci_mt isconstant REVISION : amba_version_type := 0;constant hconfig : ahb_config_type := (  0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_PCISBRG, 0, REVISION, 0),  4 => ahb_membar(haddr, '0', '0', hmask),  5 => ahb_iobar (ioaddr, 16#E00#),  others => zero32);constant CSYNC : integer := nsync-1;constant MADDR_WIDTH : integer := abits;constant HADDR_WIDTH : integer := 28;type pci_input_type is record  ad       : std_logic_vector(31 downto 0);  cbe      : std_logic_vector(3 downto 0);  frame    : std_logic;  devsel   : std_logic;  idsel    : std_logic;  trdy     : std_logic;  irdy     : std_logic;  par      : std_logic;  stop 	   : std_logic;  rst  	   : std_logic;  gnt      : std_logic;end record;type ahbs_input_type is record  haddr    : std_logic_vector(HADDR_WIDTH - 1 downto 0);  htrans   : std_logic_vector(1 downto 0);  hwrite   : std_logic;  hsize    : std_logic_vector(1 downto 0);  hburst   : std_logic_vector(2 downto 0);  hwdata   : std_logic_vector(31 downto 0);  hsel     : std_logic;  hiosel     : std_logic;  hready   : std_logic;end record;type pci_target_state_type is (idle, b_busy, s_data, backoff, turn_ar);type pci_master_state_type is (idle, addr, m_data, turn_ar, s_tar, dr_bus);type pci_config_command_type is record  ioen     : std_logic; -- I/O access enable  men      : std_logic; -- Memory access enable  msen     : std_logic; -- Master enable  spcen    : std_logic; -- Special cycle enable  mwie     : std_logic; -- Memory write and invalidate enable  vgaps    : std_logic; -- VGA palette snooping enable  per      : std_logic; -- Parity error response enable  wcc      : std_logic; -- Address stepping enable  serre    : std_logic; -- Enable SERR# driver  fbtbe    : std_logic; -- Fast back-to-back enableend record;type pci_config_status_type is record  c66mhz   : std_logic; -- 66MHz capability  udf      : std_logic; -- UDF supported  fbtbc    : std_logic; -- Fast back-to-back capability  dped     : std_logic; -- Data parity error detected  dst      : std_logic_vector(1 downto 0); -- DEVSEL timing  sta      : std_logic; -- Signaled target abort  rta      : std_logic; -- Received target abort  rma      : std_logic; -- Received master abort  sse      : std_logic; -- Signaled system error  dpe      : std_logic; -- Detected parity errorend record;type pci_reg_type is record  addr     : std_logic_vector(MADDR_WIDTH-1 downto 0);  ad     : std_logic_vector(31 downto 0);  cbe      : std_logic_vector(3 downto 0);  lcbe      : std_logic_vector(3 downto 0);  t_state  : pci_target_state_type; -- PCI target state machine  m_state  : pci_master_state_type; -- PCI master state machine  csel     : std_logic; -- Configuration chip select  msel     : std_logic; -- Memory hit  read     : std_logic;  devsel   : std_logic; -- PCI device select  trdy     : std_logic; -- Target ready  irdy     : std_logic; -- Master ready  stop     : std_logic; -- Target stop request  par      : std_logic; -- PCI bus parity  req      : std_logic; -- Master bus request  oe_par   : std_logic;  oe_ad    : std_logic;  oe_trdy  : std_logic;  oe_devsel: std_logic;  oe_ctrl  : std_logic;  oe_cbe   : std_logic;  oe_stop  : std_logic;  oe_frame : std_logic;  oe_irdy  : std_logic;  oe_req   : std_logic;  noe_par   : std_logic;  noe_ad    : std_logic;  noe_trdy  : std_logic;  noe_devsel: std_logic;  noe_ctrl  : std_logic;  noe_cbe   : std_logic;  noe_stop  : std_logic;  noe_frame : std_logic;  noe_irdy  : std_logic;  noe_req   : std_logic;  request  : std_logic; -- Request from Back-end  frame    : std_logic; -- Master frame  bar0     : std_logic_vector(31 downto MADDR_WIDTH);  page     : std_logic_vector(31 downto MADDR_WIDTH-1);  comm     : pci_config_command_type;  stat     : pci_config_status_type;  laddr    : std_logic_vector(31 downto 0);  ldata    : std_logic_vector(31 downto 0);  pwrite   : std_logic;  hwrite   : std_logic;  start    : std_logic;  hreq     : std_logic;  hreq_ack : std_logic_vector(csync downto 0);  preq     : std_logic_vector(csync downto 0);  preq_ack : std_logic;  rready   : std_logic_vector(csync downto 0);  wready   : std_logic_vector(csync downto 0);  sync     : std_logic_vector(csync downto 0);  pabort   : std_logic;  mcnt     : std_logic_vector(2 downto 0);  maddr    : std_logic_vector(31 downto 0);  mdata    : std_logic_vector(31 downto 0);  stop_req : std_logic;end record;type cpu_master_state_type is (idle, sync1, busy, sync2);type cpu_slave_state_type is (idle, getd, req, sync, read, sync2, t_done);type cpu_reg_type is record  tdata     : std_logic_vector(31 downto 0); -- Target data  maddr     : std_logic_vector(31 downto 0); -- Master data  mdata     : std_logic_vector(31 downto 0); -- Master data  be       : std_logic_vector(3 downto 0);  m_state  : cpu_master_state_type; -- AMBA master state machine  s_state  : cpu_slave_state_type; -- AMBA slave state machine  start    : std_logic_vector(csync downto 0);  hreq     : std_logic_vector(csync downto 0);  hreq_ack : std_logic;  preq     : std_logic;  preq_ack : std_logic_vector(csync downto 0);  sync     : std_logic;  hwrite   : std_logic; -- AHB write on PCI  pabort   : std_logic_vector(csync downto 0);  perror   : std_logic;  rready   : std_logic;  wready   : std_logic;  hrdata   : std_logic_vector(31 downto 0);  hresp    : std_logic_vector(1 downto 0);  pciba    : std_logic_vector(3 downto 0);end record;signal clk_int : std_logic;signal pr : pci_input_type;signal hr : ahbs_input_type;signal r, rin : pci_reg_type;signal r2, r2in : cpu_reg_type;signal dmai : ahb_dma_in_type;signal dmao : ahb_dma_out_type;signal roe_ad, rioe_ad : std_logic_vector(31 downto 0);attribute syn_preserve : boolean;attribute syn_preserve of roe_ad : signal is true; begin-- Back-end state machine (AHB clock domain)  comb : process (rst, r2, r, dmao, hr, ahbsi)  variable vdmai : ahb_dma_in_type;  variable v : cpu_reg_type;  variable request : std_logic;  variable hready : std_logic;  variable hresp, hsize, htrans : std_logic_vector(1 downto 0);  variable p_done : std_logic;  begin    v := r2;    vdmai.start := '0'; vdmai.burst := '0'; vdmai.size := "10";    vdmai.address := r.laddr; v.sync := '1';    vdmai.wdata := r.ldata; vdmai.write := r.pwrite;    v.start(0) := r2.start(csync); v.start(csync) := r.start;    v.hreq(0) := r2.hreq(csync); v.hreq(csync) := r.hreq;    v.pabort(0) := r2.pabort(csync); v.pabort(csync) := r.pabort;    v.preq_ack(0) := r2.preq_ack(csync); v.preq_ack(csync) := r.preq_ack;    hready := '1'; hresp := HRESP_OKAY; request := '0';    hsize := "10"; htrans := "00";    p_done := r2.hreq(0) or r2.pabort(0);---- *** APB register access *** ----    --if (apbi.psel and apbi.penable and apbi.pwrite) = '1' then      --v.pciba := apbi.pwdata(31 downto 28);    --end if;    --apbo.prdata <= r2.pciba & addzero;    if hr.hiosel = '1' then      if hr.hwrite = '1' then v.pciba := ahbsi.hwdata(31 downto 28); end if;      v.hrdata := r2.pciba & addzero;    end if;---- *** AHB MASTER *** ----    case r2.m_state is    when idle =>      v.sync := '0';      if r2.start(0) = '1' then        if  r.pwrite = '1' then v.m_state := sync1; v.wready := '0';        else v.m_state := busy; vdmai.start := '1'; end if;      end if;    when sync1 =>      if r2.start(0) = '0' then v.m_state := busy; vdmai.start := '1'; end if;    when busy =>      if dmao.active = '1' then        if dmao.ready = '1' then          v.rready := not r.pwrite; v.tdata := dmao.rdata; v.m_state := sync2;        end if;      else vdmai.start := '1'; end if;    when sync2 =>      if r2.start(0) = '0' then        v.m_state := idle;  v.wready := '1'; v.rready := '0';      end if;    end case;---- *** AHB MASTER END *** -------- *** AHB SLAVE *** ----    if MASTER = 1 then      if (hr.hready and hr.hsel) = '1' then        hsize := hr.hsize; htrans := hr.htrans;        if (hr.htrans(1) and r.comm.msen) = '1' then request := '1'; end if;      end if;      if (request = '1' and r2.s_state = idle) then  v.maddr := r2.pciba & hr.haddr;  v.hwrite := hr.hwrite;  case hsize is  when "00" => v.be := "1110"; -- Decode byte enable  when "01" => v.be := "1100";  when "10" => v.be := "0000";  when others => v.be := "1111";  end case;      elsif r2.s_state = getd and r2.hwrite = '1' then  v.mdata := hr.hwdata;      end if;      if r2.hreq(0) = '1' then v.hrdata := r.ldata; end if;      if r2.preq_ack(0) = '1' then v.preq := '0'; end if;      if r2.pabort(0) = '1' then v.perror := '1'; end if;      if p_done = '0' then v.hreq_ack := '0'; end if;    -- AHB slave state machine      case r2.s_state is      when idle => if request = '1' then v.s_state := getd; end if;      when getd => v.s_state := req; v.preq := '1';      when req => if r2.preq_ack(0) = '1' then v.s_state := sync; end if;      when sync => if r2.preq_ack(0) = '0' then v.s_state := read; end if;      when read =>        if p_done = '1' then v.hreq_ack := '1'; v.s_state := sync2; end if;      when sync2 => if p_done = '0' then v.s_state := t_done; end if;      when t_done => if request = '1' then v.s_state := idle; end if;      when others => v.s_state := idle;      end case;      if request = '1' then        if r2.s_state = t_done then      if r2.perror = '1' then hresp := HRESP_ERROR;      else hresp := HRESP_OKAY; end if;      v.perror := '0';        else hresp := HRESP_RETRY; end if;      end if;      if r.comm.msen = '0' then hresp := HRESP_ERROR; end if; -- Master disabled      if htrans(1) = '0' then hresp := HRESP_OKAY; end if; -- Response OK for BUSY and IDLE      if (hresp /= HRESP_OKAY and (hr.hready and hr.hsel) = '1') then  -- insert one wait cycle        hready := '0';      end if;      if hr.hready = '0' then hresp := r2.hresp; end if;      v.hresp := hresp;    end if;---- *** AHB SLAVE END *** ----    if rst = '0' then      v.s_state := idle; v.rready := '0'; v.wready := '1';      v.m_state := idle; v.preq := '0'; v.hreq_ack := '0';      v.perror := '0'; v.be := (others => '1');      v.pciba := (others => '0'); v.hresp := (others => '0');    end if;    r2in <= v; dmai <= vdmai;    ahbso.hready <= hready;    ahbso.hresp  <= hresp;    ahbso.hrdata <= r2.hrdata;  end process;  ahbso.hconfig <= hconfig when MASTER = 1 else (others => zero32);  ahbso.hsplit <= (others => '0');  ahbso.hirq   <= (others => '0');  ahbso.hindex <= hslvndx;-- PCI target core (PCI clock domain)  pcicomb : process(pcii.rst, pr, pcii, r, r2, roe_ad)  variable v : pci_reg_type;  variable chit, mhit, hit, ready, cwrite : std_logic;  variable cdata, cwdata : std_logic_vector(31 downto 0);  variable comp : std_logic; -- Last transaction cycle on PCI bus  variable iready : std_logic;  variable mto : std_logic;  variable tad, mad : std_logic_vector(31 downto 0);--	variable cbe : std_logic_vector(3 downto 0);  variable caddr : std_logic_vector(7 downto 2);    variable voe_ad : std_logic_vector(31 downto 0);  variable oe_par   : std_logic;  variable oe_ad    : std_logic;  variable oe_ctrl  : std_logic;  variable oe_trdy  : std_logic;  variable oe_devsel: std_logic;  variable oe_cbe   : std_logic;  variable oe_stop  : std_logic;  variable oe_frame : std_logic;  variable oe_irdy  : std_logic;  variable oe_req   : std_logic;  begin  -- Process defaults    v := r; v.trdy := '1'; v.stop := '1'; v.frame := '1';    v.oe_ad := '1'; v.devsel := '1'; v.oe_frame := '1';    v.irdy := '1'; v.req := '1'; voe_ad := roe_ad;     v.oe_req := '0'; v.oe_cbe := '1'; v.oe_irdy := '1';    v.rready(0) := r.rready(csync); v.rready(csync) := r2.rready;    v.wready(0) := r.wready(csync); v.wready(csync) := r2.wready;    v.sync(0) := r.sync(csync); v.sync(csync) := r2.sync;    v.preq(0) := r.preq(csync); v.preq(csync) := r2.preq;

⌨️ 快捷键说明

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