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

📄 pci_mtf.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 5 页
字号:
        if ((ahbsi.hready and not ahbsi.htrans(0)) = '1') then          if r2.s.pcicomm(0) = '1' then            --v.s.state := w_done; wsvalid := '0';            v.s.state := w_done;             if ahbsi.htrans /= "00" then wsvalid := '0'; end if; -- fix dont set wsvalid if amba idle          else                                                   -- (if wsvalid = 0 side is changed before last write             v.s.state := t_done;                                 -- to fifo if hrans = 00)                    wsvalid := '0'; -- Bug fix, must give RETRY here! /KC          end if;        end if;              when r_hold =>                s_read_side := '1';        if fifors_limit = '0' and ((pstart_ack or pstart) = '0') and request = '1' then          if rmdone = '0' then -- bug fix ***             v.s.state := t_data;            burst_read := ahbsi.htrans(1) and not fifors_limit; -- bug fix ***          else            v.s.state := t_done;            end if;        elsif (ahbsi.hready = '1' and ahbsi.htrans = "00" and r2.s.hresp = HRESP_OKAY) then -- (idle -> t_done) bug fix ***           v.s.state := t_done;        else v.s.hold := '1'; end if;      when r_wait =>                s_read_side := '0';        if (pstart_ack and request) = '1' then          v.s.state := t_data; hready := '0';        end if;        if r2.s.hmaster /= ahbsi.hmaster and conv_integer(ahbsi.hmaster) = dmamst and pstart_ack = '1' then -- if pcidma cancel read             v.s.state := t_done;        end if;      when w_done =>                v.s.state := t_done; wsvalid := '0';--        if (r2.s.htrans(1) or not fifows_limit) = '1' then--        if (r2.s.htrans(1) and fifows_limit) = '1' then          v.s.fifo.waddr := r2.s.fifo.waddr + r2.s.fifos_write;        --          end if;        fifows_limit := '1';       when t_done =>                wsvalid := '0';        fifors_limit := not r2.s.pcicomm(0);        if (pstart or pstart_ack) = '0' then          v.s.state := idle; v.s.perror := '0';          v.s.fifo.waddr := (others => '0'); wsdone := '0'; fifows_limit := '0';          v.s.pcicomm := (0 => '1', others => '0'); -- default write        else fifows_limit := r2.s.pcicomm(0); end if;      end case;      -- Respond encoder        if v.s.state = t_data        or (v.s.state = r_hold and v.s.hold = '0') -- bug fix ***        or (v.s.state = t_done and r2.s.state = t_data) -- (end of trans) bug fix ***        or (v.s.state = w_wait and ahbsi.hwrite = '1') then          if r2.s.perror = '1' then hresp := HRESP_ERROR;          elsif wsvalid = '1' then hresp := HRESP_OKAY;          else hresp := HRESP_RETRY; end if;          v.s.perror := '0';        else hresp := HRESP_RETRY; end if;      if r.comm.msen = '0' then hresp := HRESP_ERROR; end if; -- Master disabled      --if (v.s.htrans(1) and request) = '0' then hresp := HRESP_OKAY; end if; -- Response OK for BUSY and IDLE      if (v.s.htrans(1) and ahb_access) = '0' then hresp := HRESP_OKAY; end if; -- Response OK for BUSY and IDLE -- *** access control fix      if (hresp /= HRESP_OKAY or hready = '0') then v.s.hready := '0'; else v.s.hready := '1'; end if;      -- Dont change hresp during wait states      if ahbsi.hready = '0' then hresp := r2.s.hresp; end if;      v.s.hresp := hresp;      -- FIFO controller      if fifows_limit = '1' then        if (r2.s.fifos_write or not wsvalid) = '1' and (r2.s.fifo.side = '0' or pstart_ack = '1')   then          --if wsvalid = '0' then wsdone := '1';          if wsvalid = '0' or v.s.state = w_done then wsdone := '1'; -- fix set wsdone and pstart at the same time          else v.s.fifo.waddr := (others => '0'); end if;          pstart := not pstart_ack;          v.s.fifo.side := pstart;        end if;      elsif ((r2.s.state = t_done or r2.s.state = r_hold) and fifors_limit = '1') then        if pstart_ack = '1' then pstart := '0'; v.s.fifo.raddr := (others => '0');        else v.s.fifo.raddr := (others => '0'); end if;      end if;       -- Set last fifo side written so that PCI master knows when to stop       if (r2.s.fifos_write = '1') then         v.s.last_side := r2.s.fifo.side;       end if;--    end if;---- *** AHB SLAVE END *** -------- *** Sync Regs *** ----    v.trans(0) := pstart;    v.trans(1) := habort;    v.trans(2) := hstart_ack;    v.trans(3) := fifows_limit;    v.trans(4) := wsdone;    v.trans(5) := wmdone;    vdmai.address := r2.m.dmaddr;    -- input data for write accesses    if r2.s.pcicomm(0) = '1' then v.s.mdata := ahbsi.hwdata; end if;    -- output data for read accesses--    if (ahbsi.htrans(1) and not r2.s.hold and not r2.s.pcicomm(0)) = '1' then v.s.mdata := fifo4o.rdata(31 downto 0); end if;    if (ahbsi.htrans(1) and not r2.s.pcicomm(0)) = '1' then v.s.mdata := fifo4o.rdata(31 downto 0); end if; -- bug fix ***    -- irq    apbo.pirq <= (others => '0');    if irq /= 0 then      if to_x01(pcii.host) = '0' then--        v.pciirq := r2.pciirq(0) & orv((not pcii.int) and conv_std_logic_vector(irqmask,4));--        apbo.pirq(irq) <= not r2.pciirq(1) and r2.pciirq(0);  -- only generate irq on falling edges of pcii.int        apbo.pirq(irq) <= orv((not pcii.int) and conv_std_logic_vector(irqmask,4));      end if;    end if;        if rst = '0' then      v.s.state := idle;      v.m.state := idle;      v.s.perror := '0';      v.pciba := (others => '0');      v.trans := (others => '0');      v.m.fifo.waddr := (others => '0');      v.m.fifo.raddr := (others => '0');      v.s.fifo.waddr := (others => '0');      v.s.fifo.raddr := (others => '0');      v.m.fifo.side := '0';      v.s.fifo.side := '0';      v.wcomm := '0';      v.rcomm := '0';      v.werr := '0';      v.cfto := '0';      v.dmapage := (others => '0');      v.ioba := (others => '0');      v.pciirq := "11";    end if;    r2in <= v; dmai <= vdmai;    apbo.prdata  <= prdata;    ahbso.hready <= r2.s.hready;    ahbso.hresp  <= r2.s.hresp;    ahbso.hrdata <= byte_twist(r2.s.mdata, r.bt_enable);    ahbso.hindex <= hslvndx;    fifo1i.wen   <= fifom_write;    fifo1i.waddr <= r2.m.fifo.side & r2.m.fifo.waddr;    fifo1i.wdata <= byte_twist(dmao.rdata, r.bt_enable);    fifo2i.ren   <= '1';    fifo2i.raddr <= m_read_side & (r2.m.fifo.raddr + dmao.ready);    fifo3i.wen   <= r2.s.fifos_write;    fifo3i.waddr <= r2.s.fifo.side & r2.s.fifo.waddr;    fifo3i.wdata <= byte_twist(r2.s.mdata, r.bt_enable);    fifo4i.ren   <= '1';    fifo4i.raddr <= s_read_side & (r2.s.fifo.raddr + burst_read);  end process;  ahbso.hconfig <= hconfig when MASTER = 1 else (others => zero32);  ahbso.hcache  <= '0';  apbo.pconfig  <= pconfig;  apbo.pindex   <= pindex;  ahbso.hsplit  <= (others => '0');  ahbso.hirq    <= (others => '0');-- PCI core (PCI clock domain)  pcicomb : process(pr, pcii, r, r2, fifo1o, fifo3o, roe_ad)  variable v : pci_reg_type;  variable chit, mhit0, mhit1, phit, hit, hosthit, ready, cwrite, retry : std_logic;  variable cdata, cwdata : std_logic_vector(31 downto 0);  variable comp : std_logic; -- Last transaction cycle on PCI bus  variable mto, tto, term, ben_err, lto : std_logic;  variable i : integer range 0 to NO_PCI_REGS;  variable tad, mad : std_logic_vector(31 downto 0);  variable byteaddr : std_logic_vector(1 downto 0);  variable pstart, habort, hstart_ack, wsdone, wmdone : std_logic;  variable hstart, pabort, pstart_ack, pcidc, rtdone, rmdone : std_logic;  variable fifort_limit, fifowt_limit, fiform_limit, fifowm_limit, fifowm_stop, t_valid : std_logic;  variable d_ready, tabort, backendnr : std_logic;  variable m_fifo_write, t_fifo_write, grant : std_logic;  variable write_access, memwrite, memread, read_match, m_read_side, t_read_side : std_logic;  variable readt_dly : std_logic; -- 1 turnaround cycle  variable bus_idle, data_transfer, data_transfer_r, data_phase, targ_d_w_data, targ_abort, m_request : std_logic;  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_cbe   : std_logic;  variable oe_frame : std_logic;  variable oe_irdy  : std_logic;  variable oe_req   : std_logic;  variable oe_perr  : std_logic;  begin  -- Process defaults    v := r; v.pci.trdy := '1'; v.pci.stop := '1'; v.pci.frame := '1';    v.pci.oe_ad := '1'; v.pci.devsel := '1'; v.pci.oe_frame := '1';    v.pci.irdy := '1'; v.pci.req := '1'; hosthit := '0'; m_request := '0';    v.pci.oe_req := '0'; v.pci.oe_cbe := '1'; v.pci.oe_irdy := '1';    mto := '0'; tto := '0'; v.m.stop_req := '0'; lto := '0';    cdata := (others => '0'); retry := '0'; t_fifo_write := '0';    chit := '0'; phit := '0'; mhit0 := '0'; mhit1 := '0'; tabort := '0';    readt_dly := '0'; m_fifo_write := '0'; voe_ad := roe_ad;     tad := r.pci.ad; mad := r.pci.ad; grant := pcii.gnt; d_ready := '0';    m_read_side := not r2.s.fifo.side; t_read_side := not r2.m.fifo.side;    v.m.rmdone := '0';    byteaddr := "00";        write_access := not r.t.read and not pr.irdy and not pr.trdy;    memwrite := r.t.msel and r.t.lwrite and not r.t.read;    memread := r.t.msel and not r.t.lwrite and r.t.read;    -- Synch registers    hstart := r.trans(0);    pabort := r.trans(1);    pstart_ack := r.trans(2);    pcidc := r.trans(3);    rtdone := r.trans(4);    rmdone := r.trans(5);    for i in 0 to NO_PCI_REGS - 1 loop      v.syncs(i)(csync) := r2.trans(i);     if csync /= 0 then v.syncs(i)(0) := r.syncs(i)(csync); end if;    end loop;    pstart     := r.syncs(0)(0);    habort     := r.syncs(1)(0);    hstart_ack := r.syncs(2)(0);    backendnr  := r.syncs(3)(0);    wsdone     := r.syncs(4)(0);    wmdone     := r.syncs(5)(0);    -- FIFO limit detector    if r.t.fifo.raddr = FIFO_FULL then fifort_limit := '1'; else fifort_limit := '0'; end if;    if r.t.fifo.waddr = FIFO_FULL then fifowt_limit := '1'; else fifowt_limit := '0'; end if;    if r.m.fifo.raddr = FIFO_FULL then fiform_limit := '1'; else fiform_limit := '0'; end if;    if r.m.fifo.waddr = FIFO_FULL then fifowm_limit := '1'; else fifowm_limit := '0'; end if;    if r.m.fifo.waddr(FIFO_DEPTH - 2 downto 1) = FIFO_FULL(FIFO_DEPTH - 2 downto 1) then fifowm_stop := '1'; else fifowm_stop := '0'; end if;    -- useful control variables    --if (r.t.laddr = r.page & r.t.addr(MADDR_WIDTH-2 downto 0) or r.t.laddr = r2.dmapage & r.t.addr(DMAMADDR_WIDTH-1 downto 0))    if (r.t.laddr(31 downto 2) = r.page & r.t.addr(MADDR_WIDTH-2 downto 2) -- bug fix match if byte access         or r.t.laddr(31 downto 2) = r2.dmapage & r.t.addr(DMAMADDR_WIDTH-1 downto 2))     and (r.t.lcbe = pr.cbe) -- bug fix match byte access    and (r.t.lburst = r.t.burst) then read_match := r.t.pending; else read_match := r.t.csel or r.t.psel; end if;--    if (pr.cbe = "0000" and r.t.lsize = "10") or (pr.cbe = "1100" and r.t.lsize = "01") or (pr.cbe = "1110" and r.t.lsize = "00")-- pragma translate_off--    or (pr.cbe = "XXXX") -- For simulation purposes-- pragma translate_on--    then ben_err := '0'; else ben_err := '1'; end if;    ben_err := '0';        if r.stat.dpe = '0' then v.stat.dpe := not r.pci.perr; end if;----- *** PCI TARGET *** --------        -- Data valid?    if ((wmdone and not r.t.lwrite) = '1' and (r.t.fifo.raddr + '1') = r2.m.fifo.waddr) then t_valid := '0';    else t_valid := not fifowt_limit or not r.t.fifo.side; end if;    -- Step addresses    if (r.t.state = s_data or r.t.state = turn_ar or r.t.state = backoff) then      if (pcii.irdy or r.pci.trdy) = '0' then        v.t.addr := r.t.addr + ((r.t.csel and r.t.read) & "00");        readt_dly := '1';        if r.t.msel = '1' then          v.t.wdel := (fifort_limit and r2.m.fifo.side) or r.t.lwrite;          v.t.fifo.raddr := r.t.fifo.raddr + (r.t.read and not fifort_limit and t_valid);        end if;      end if;      if write_access = '1' then        v.t.fifo.waddr := r.t.fifo.waddr + (r.t.msel and not r.t.read and not ben_err);        t_fifo_write := r.t.msel;        v.t.addr := r.t.addr + ((r.t.csel and not r.t.read) & "00");      end if;      tabort := habort;    else v.t.wdel := '0'; end if;    -- Config space read access    case r.t.addr(7 downto 2) is    when "000000" =>      -- 0x00, device & vendor id      cdata := conv_std_logic_vector(DEVICE_ID, 16) &      conv_std_logic_vector(VENDOR_ID, 16);    when "000001" =>      -- 0x04, status & command      cdata(1) := r.comm.men; cdata(2) := r.comm.msen;      cdata(4) := r.comm.mwie; cdata(6) := r.comm.per;      cdata(24) := r.stat.dped; cdata(26) := '1';      cdata(27) := r.stat.sta; cdata(28) := r.stat.rta;      cdata(29) := r.stat.rma; cdata(31) := r.stat.dpe;    when "000010" =>      -- 0x08, class code & revision      cdata(31 downto 8) := conv_std_logic_vector(16#0B4000#,24);    when "000011" =>      -- 0x0C, latency & cacheline size      cdata(7 downto 0) := r.cline;      cdata(15 downto 8) := r.ltim;    when "000100" =>      -- 0x10, BAR0      cdata(31 downto MADDR_WIDTH) := r.bar0;    when "000101" =>      -- 0x14, BAR1      cdata(31 downto DMAMADDR_WIDTH) := r.bar1;    when "001111" =>      -- 0x3C, Interrupts & Latency timer settings      cdata(7 downto 0) := r.intline; -- Interrupt line      cdata(8) := '1'; -- Use interrupt pin INTA#      if fifodepth < 11 then cdata(fifodepth+13) := '1'; end if; --Define wanted burst period    when others =>    end case;

⌨️ 快捷键说明

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