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

📄 pci_mtf.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 5 页
字号:
        v.m.request := '1';        rmdone := '0'; v.m.valid := '1';        v.m.fifo.waddr := (others => '0');        v.m.hwrite := r2.s.pcicomm(0);      end if;    end if;    -- Master timeout and DEVSEL timeout    if ((pr.irdy and not pr.frame) or (pr.devsel and not r.pci.oe_frame)) = '1' then      if r.m.cnt /= "000" then v.m.cnt := r.m.cnt - 1;      else mto := '1'; end if;    else v.m.cnt := (others => '1'); end if;    -- Latency counter    if r.pci.frame = '0' then      if r.m.ltim > "00000000" then v.m.ltim := r.m.ltim - '1';      else lto := '1'; end if;    else      v.m.ltim := r.ltim;    end if;    -- Last data    case r2.s.pcicomm is    when MEM_R_MULT | MEM_R_LINE =>      if (r.m.fifo.waddr >= (FIFO_FULL - "10") and r.m.fifo.side = '1') then        comp := '1';      else comp := '0'; end if;    when MEM_WRITE | MEM_W_INV => comp := not r.m.valid;    when others => comp := '1';    end case;    -- Minimun latency    --if lto = '0' then grant := '0'; end if;    if lto = '0' then grant := '0'; -- latency timer bug fix      elsif pcii.gnt = '1' then v.m.lto := '1'; end if;     -- Data parity error detected    if (r.m.fstate /= idle and r.stat.dped = '0') then v.stat.dped := r.comm.per and not pcii.perr; end if;    -- FIFO control state machine    case r.m.fstate is    when idle =>            v.m.lto := '0';       if (r.m.request and bus_idle and not pcii.gnt) = '1' and (r.m.state = idle or r.m.state = dr_bus) then        v.m.fstate := addr; v.m.fifo.waddr := (others => '0'); v.m.fifo.side := '0'; m_request := '1';      end if;    when addr =>            --      if (wsdone = '1' and (r.m.fifo.raddr + '1') = r2.s.fifo.waddr) then v.m.valid := '0'; end if;      if (wsdone = '1' and ((r.m.fifo.raddr + '1') = r2.s.fifo.waddr) and (m_read_side = r2.s.last_side)) then v.m.valid := '0'; end if; --bug fix kc                                                                                                                                                 if fiform_limit = '1' then v.m.fstate := last1;      else v.m.fstate := incr; end if;      v.m.fifo.raddr := r.m.fifo.raddr + r.m.hwrite;      v.m.first := '1'; v.m.firstw := '1';    when incr =>            d_ready := '1';            if r.m.valid = '0' then v.m.lto := '0'; end if; -- dont look at latency timer if done       if data_transfer = '1' then                --if fiform_limit = '1' then v.m.fstate := last1; v.m.split := not backendnr; end if;        if fiform_limit = '1' and r.m.lto = '0' then v.m.fstate := last1; v.m.split := not backendnr; end if; -- bug fix latency timer--        if (wsdone = '1' and (r.m.fifo.raddr + pcii.stop) = r2.s.fifo.waddr) then v.m.valid := '0'; end if;        if (wsdone = '1' and ((r.m.fifo.raddr + pcii.stop) = r2.s.fifo.waddr) and (m_read_side = r2.s.last_side)) then v.m.valid := '0'; end if; --bug fix kc        v.m.fifo.raddr := r.m.fifo.raddr + r.m.hwrite;        v.m.first := '0';      end if;      if data_transfer_r = '1' then        if fifowm_stop = '1' then          if r.m.firstw = '1' then            if (fifowm_limit and pr.stop) = '1' then v.m.fifo.side := not r.m.fifo.side; v.m.firstw := '0'; pstart_ack := pstart; end if;          end if;        end if;        v.m.fifo.waddr := r.m.fifo.waddr + (not r.m.hwrite);      end if;      if pr.stop = '0' then        if targ_abort = '1' then v.m.fstate := abort;        elsif targ_d_w_data = '1' then v.m.fstate := ttermwd;        elsif r.m.first = '1' then v.m.fstate := t_retry;--        else v.m.fstate := ttermnd; end if;        else  -- bug fix *** --           if r.m.fifo.waddr = "0000000" then v.m.rmdone := '1'; end if;           if r.m.fifo.waddr = zero32(FIFO_DEPTH - 2 downto 0) then v.m.rmdone := '1'; end if;           v.m.fstate := ttermnd;        end if;      elsif mto = '1' then v.m.fstate := abort;      --elsif grant = '1' then -- pci_gnt bug fix       --  if r.m.hwrite = '0' then rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; v.m.fstate := done; pstart_ack := pstart;      --  else v.m.fstate := idle; end if;            --elsif (pr.frame and not r.m.first) = '1' then      elsif (pr.frame and not pr.trdy and not r.m.first) = '1' then -- not done if target not ready *** bug fix        if r.m.hwrite = '0' then rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; v.m.fstate := done; pstart_ack := pstart;        --else v.m.fstate := done; pstart_ack := pstart; end if;        else            if r.m.lto = '1' then -- latency timer bug fix              v.m.fifo.raddr := r.m.fifo.raddr - r.m.hwrite;              v.m.fstate := idle;           else              v.m.fstate := done; pstart_ack := pstart;            end if;        end if;      elsif (pr.devsel and not r.m.first) = '1' then        if r.m.hwrite = '0' then rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; v.m.fstate := done; pstart_ack := pstart;        else v.m.fstate := idle; end if;      end if;    when last1 =>      if (pr.trdy and not pr.stop) = '1' then        if targ_abort = '1' then v.m.fstate := abort;        elsif targ_d_w_data = '1' then v.m.fstate := ttermwd;        else v.m.fstate := ttermnd; v.m.valid := '1'; end if;      --elsif (pr.frame and not r.m.first and not r.m.split) = '1' then v.m.fstate := done; rmdone := not r.m.fifo.side; pstart_ack := pstart;      -- not done if target not ready *** bug fix      elsif (pr.frame and not pr.trdy and not r.m.first and not r.m.split) = '1' then v.m.fstate := done; rmdone := not r.m.fifo.side; pstart_ack := pstart;      elsif data_transfer = '1' then        if r.m.valid = '1' then v.m.fstate := sync; pstart_ack := pstart;        else v.m.fstate := done; rmdone := not r.m.fifo.side; pstart_ack := pstart; end if;      else d_ready := '1';      end if;    when sync =>            if pstart = not pstart_ack then        v.m.split := '0';        if ((r.m.split or (pr.trdy and not pr.stop and not r.m.split))  = '1' or r.m.state /= m_data) then v.m.fstate := idle; d_ready := '1';        else          --if (wsdone = '1' and (r.m.fifo.raddr + '1') = r2.s.fifo.waddr) then v.m.valid := '0'; end if;          if (r2.trans(4) = '1' and (r.m.fifo.raddr + '1') = r2.s.fifo.waddr) then v.m.valid := '0'; end if; -- not synced wsdone          v.m.fstate := incr; data_transfer := '1'; v.m.fifo.raddr := r.m.fifo.raddr + r.m.hwrite; d_ready := '1';        end if;      else m_read_side := '1';      end if;    when t_retry =>            v.m.fifo.raddr := r.m.fifo.raddr - r.m.hwrite; v.m.fstate := idle;    when ttermwd =>            if data_transfer = '1' then v.m.fifo.raddr := r.m.fifo.raddr + r.m.hwrite;      elsif pr.trdy = '1' then v.m.fifo.raddr := r.m.fifo.raddr - r.m.hwrite;        if (r.m.hwrite and r.m.valid) = '1' then v.m.fstate := idle;        else v.m.fstate := done; rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; pstart_ack := pstart; end if;      end if;    when ttermnd =>                    if r.m.hwrite = '1' then          v.m.fifo.raddr := r.m.fifo.raddr - '1';--          if (r.m.fifo.raddr /= (r2.s.fifo.waddr + '1') or wsdone = '0') then v.m.valid := '1'; v.m.fstate := idle; -- bug fix ***           if (r.m.fifo.raddr /= (r2.s.fifo.waddr + '1') or wsdone = '0' or r.m.valid = '1') then v.m.valid := '1'; v.m.fstate := idle;          else v.m.fstate := done; rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; pstart_ack := pstart; end if;--        else v.m.fstate := done; rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; pstart_ack := pstart; end if;        else v.m.fstate := done; rmdone := (not r.m.fifo.side or r.m.rmdone); v.m.fifo.side := '1'; pstart_ack := pstart; end if; -- bug fix ***     when abort =>            v.m.fifo.raddr := (others => '0'); v.m.fifo.waddr := (others => '0');      v.m.fstate := done; pstart_ack := pstart; pabort := '1';    when done =>            d_ready := '1'; comp := '1'; v.m.request := '0';      if (pstart or pstart_ack) = '0' then        v.m.fstate := wdone; v.m.fifo.raddr := (others => '0'); v.m.fifo.side := '0'; rmdone := '1';      else pstart_ack := pstart; end if;    when wdone =>            d_ready := '1'; comp := '1';      if (r.m.state = idle or r.m.state = dr_bus) then v.m.fstate := idle; pabort := '0';  end if;    end case;    -- PCI master state machine    case r.m.state is    when idle => -- Master idle      v.m.stopframe := '0';       if (pcii.gnt = '0' and bus_idle = '1') then        if m_request = '1' then v.m.state := addr;        else v.m.state := dr_bus; end if;      end if;    when addr => -- Always one address cycle at the beginning of an transaction      v.m.stopframe := '0';       v.m.state := m_data;    when m_data => -- Master transfers data      if r.pci.frame = '1' then v.m.stopframe := '1'; end if; -- ***       if (r.pci.frame = '0') or ((r.pci.frame and pcii.trdy and pcii.stop and not mto) = '1') then        v.m.state := m_data;        if (r.pci.frame and not d_ready) = '1' then d_ready := '1'; end if;      elsif ((r.pci.frame and (mto or not pcii.stop)) = '1') then        v.m.state := s_tar;        v.m.stop_req := '1';      else v.m.state := turn_ar; end if;    when turn_ar => -- Transaction complete            if pcii.gnt = '0' then        if m_request = '1' then v.m.state := addr;        else v.m.state := dr_bus; end if;      else v.m.state := idle; end if;    when s_tar => -- Stop was asserted            if pcii.gnt = '0' then v.m.state := dr_bus;      else v.m.state := idle; end if;    when dr_bus => -- Drive bus when parked on this agent            if pcii.gnt = '1' then v.m.state := idle;      elsif m_request = '1' then v.m.state := addr; end if;    end case;    -- FIFO write strobe    m_fifo_write := not r.m.hwrite and not pr.irdy and not (pr.trdy and (pr.stop or not r.trans(3))) and not r.pci.oe_irdy;    -- PCI data mux    if v.m.state = addr then      if r.m.hwrite = '1' then mad := (r2.s.maddr + ((((not r2.s.fifo.side) & r.m.fifo.raddr)) & "00"));      else mad := r2.s.maddr; end if;    elsif (r.m.state = addr or data_transfer = '1') then mad := fifo3o.rdata(31 downto 0);    end if;    -- Target abort    if ((pr.devsel and pr.trdy and not pr.gnt and not pr.stop) = '1') then v.stat.rta := '1'; end if;    -- Master abort    if mto = '1' then v.stat.rma := '1'; end if;    -- Drive FRAME# and IRDY#    if (v.m.state = addr or v.m.state = m_data) then v.pci.oe_frame := '0'; end if;    -- Drive CBE#    if (v.m.state = addr or v.m.state = m_data or v.m.state = dr_bus) then v.pci.oe_cbe := '0'; end if;    -- Drive IRDY# (FRAME# delayed one pciclk)    v.pci.oe_irdy := r.pci.oe_frame;    -- FRAME# assert    if (v.m.state = addr or (v.m.state = m_data and mto = '0' and v.m.stopframe = '0'  -- stopframe fix frame when pci_gnt is deasserted        --and ((((pcii.stop or not d_ready) and not (comp or v.m.split or not v.m.valid)) and not grant)) = '1')) -- dont change frame when gnt = 1 if not irdy and trdy or stop        and ((((pcii.stop or not d_ready) and not (comp or v.m.split or not v.m.valid)) and not (grant and not pr.irdy and (not pcii.trdy or not pcii.stop) ) )) = '1'))    then v.pci.frame := '0'; end if;    -- IRDY# assert    if (v.m.state = m_data and ((d_ready or mto or (not r.m.valid) or (v.pci.frame and not r.pci.frame)) = '1'))  then v.pci.irdy := '0'; end if;    -- REQ# assert    if ((v.m.request = '1' and (r.m.fstate = idle or comp = '0')) and (v.m.stop_req or r.m.stop_req) = '0') then v.pci.req := '0'; end if;    -- C/BE# assert    if v.m.state = addr then v.pci.cbe := r2.s.pcicomm; else v.pci.cbe := r2.s.be; end if;  end if;----- *** PCI MASTER END *** ------------- *** SHARED SIGNALS *** -------    -- Default assertions    v.pci.oe_par := r.pci.oe_ad; --Delayed one clock    v.pci.oe_perr := not(r.comm.per and not r.pci.oe_par and not (pr.irdy and pr.trdy)) and (r.pci.oe_perr or r.pci.perr);    v.pci.par := xorv(r.pci.ad & r.pci.cbe); -- Default asserted by master    v.pci.ad := mad;  -- Default asserted by master    v.pci.perr := not (pcii.par xor xorv(pr.ad & pr.cbe)) or pr.irdy or pr.trdy; -- Detect parity error    -- Drive AD    -- Master    if (v.m.state = addr or (v.m.state = m_data and r.m.hwrite = '1') or v.m.state = dr_bus) then      v.pci.oe_ad := '0';    end if;    -- Target    if r.t.read = '1' then      if v.t.state = s_data then        v.pci.oe_ad := '0';        v.pci.ad := tad; end if;      if r.t.state = s_data then        v.pci.par := xorv(r.pci.ad & pcii.cbe);      end if;    end if;    v.noe_ad := not v.pci.oe_ad; v.noe_ctrl := not v.pci.oe_ctrl;    v.noe_par := not v.pci.oe_par; v.noe_req := not v.pci.oe_req;    v.noe_frame := not v.pci.oe_frame; v.noe_cbe := not v.pci.oe_cbe;    v.noe_irdy := not v.pci.oe_irdy; v.noe_perr := not v.pci.oe_perr;      if oepol  = 0 then      voe_ad := (others => v.pci.oe_ad);      oe_ad := r.pci.oe_ad; oe_ctrl := r.pci.oe_ctrl;      oe_par := r.pci.oe_par; oe_req := r.pci.oe_req;      oe_frame := r.pci.oe_frame; oe_cbe := r.pci.oe_cbe;      oe_irdy := r.pci.oe_irdy; oe_perr := r.pci.oe_perr;    else      voe_ad := (others => v.noe_ad);      oe_ad := r.noe_ad; oe_ctrl := r.noe_ctrl;      oe_par := r.noe_par; oe_req := r.noe_req;      oe_frame := r.noe_frame; oe_cbe := r.noe_cbe;      oe_irdy := r.noe_irdy; oe_perr := r.noe_perr;    end if;  ----- *** SHARED SIGNALS END *** -------    v.trans(0) := hstart;    v.trans(1) := pabort;    v.trans(2) := pstart_ack;    v.trans(3) := pcidc;    v.trans(4) := rtdone;    v.trans(5) := rmdone;    if pr.rst = '0' then      v.t.state := idle; v.m.state := idle; v.m.fstate := idle;      v.bar0 := (others => '0'); v.bar0_conf := '0';      v.bar1 := (others => '0'); v.bar1_conf := '0';      v.t.msel := '0'; v.t.csel := '0';      v.t.pending := '0';      v.bt_enable := '1'; -- twisting enabled by default, changed through page0      v.page(31 downto 30) := "01";      v.page(29 downto MADDR_WIDTH-1) := zero32(29 downto MADDR_WIDTH-1);      v.pci.par := '0';      

⌨️ 快捷键说明

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