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

📄 pci_mtf.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 5 页
字号:
    -- Config space write access    cwdata := pr.ad;    if pr.cbe(3) = '1' then cwdata(31 downto 24) := cdata(31 downto 24); end if;    if pr.cbe(2) = '1' then cwdata(23 downto 16) := cdata(23 downto 16); end if;    if pr.cbe(1) = '1' then cwdata(15 downto  8) := cdata(15 downto  8); end if;    if pr.cbe(0) = '1' then cwdata( 7 downto  0) := cdata( 7 downto  0); end if;    if (r.t.csel and write_access) = '1' then      case r.t.addr(7 downto 2) is      when "000001" =>      -- 0x04, status & command        v.comm.men := cwdata(1);        if MASTER = 1 then v.comm.msen := cwdata(2); end if;        v.comm.mwie := cwdata(4); v.comm.per := cwdata(6);        v.stat.dped := r.stat.dped and not cwdata(24); -- Sticky bit        v.stat.sta := r.stat.sta and not cwdata(27); -- Sticky bit        v.stat.rta := r.stat.rta and not cwdata(28); -- Sticky bit        v.stat.rma := r.stat.rma and not cwdata(29); -- Sticky bit        v.stat.dpe := r.stat.dpe and not cwdata(31); -- Sticky bit      when "000011" =>      -- 0x0c, latency & cacheline size        if FIFO_DEPTH <= 7 then v.cline(FIFO_DEPTH - 1 downto 0) := cwdata(FIFO_DEPTH - 1 downto 0);        else v.cline := cwdata(7 downto 0); end if;        v.ltim := cwdata(15 downto 8);      when "000100" =>      -- 0x10, BAR0        v.bar0 := cwdata(31 downto MADDR_WIDTH);        if v.bar0 = zero(31 downto MADDR_WIDTH) then v.bar0_conf := '0'; else v.bar0_conf := '1'; end if;      when "000101" =>      -- 0x14, BAR1        v.bar1 := cwdata(31 downto DMAMADDR_WIDTH);        if v.bar1 = zero(31 downto DMAMADDR_WIDTH) then v.bar1_conf := '0'; else v.bar1_conf := '1'; end if;      when "001111" =>  -- 0x3C, Interrupts & Latency timer settings        v.intline := cwdata(7 downto 0); -- Interrupt line      when others =>      end case;    end if;    -- Page bar write    if (r.t.psel and write_access) = '1' then      v.page := pr.ad(31 downto MADDR_WIDTH - 1);      v.bt_enable := pr.ad(0);    end if;    -- Command and address decode    case pr.cbe is    when CONF_READ | CONF_WRITE =>      if pr.ad(1 downto 0) = "00" then chit := '1'; end if;      if pr.host = '0' then --Active low        if pr.ad(31 downto 11) = "000000000000000000000" then hosthit := '1'; end if;      end if;    when MEM_READ | MEM_WRITE =>      if pr.ad(31 downto MADDR_WIDTH) = r.bar0 then        phit := r.bar0_conf and pr.ad(MADDR_WIDTH - 1);        mhit0 := r.bar0_conf and not pr.ad(MADDR_WIDTH - 1);      elsif pr.ad(31 downto DMAMADDR_WIDTH) = r.bar1 then        mhit1 := r.bar1_conf;      end if;    when MEM_R_MULT | MEM_R_LINE | MEM_W_INV =>      if pr.ad(31 downto MADDR_WIDTH - 1) = r.bar0 & '0' then mhit0 := r.bar0_conf;      elsif pr.ad(31 downto DMAMADDR_WIDTH) = r.bar1 then mhit1 := r.bar1_conf; end if;    when others => phit := '0'; mhit0 := '0'; chit := '0'; mhit1 := '0';    end case;    -- Hit detect    hit := r.t.csel or r.t.msel or r.t.psel;    if (hstart and r.pci.devsel) = '1' then      if (r.t.pending or r.t.lwrite) = '0' then        hstart := not hstart_ack;        v.t.fifo.raddr := (others => '0');      end if;    end if;    -- Ready to transfer data      if ((r.t.csel and not readt_dly) or r.t.psel) = '1'       or ((((memwrite and not r.pci.devsel) = '1')       or (memread = '1' and not (hstart_ack and v.t.wdel) = '1')) and ben_err = '0')       then ready := '1'; else ready := '0'; t_read_side := r.t.read and not hstart; end if;    -- Target timeout counter    --if (hit and pr.trdy and not (pr.frame and pr.irdy)) = '1' then     --if (hit and pr.trdy and not (pr.frame and pr.irdy) and v.t.wdel) = '1' then     if (hit and pr.trdy and not (pr.frame and pr.irdy) and not ready) = '1' then      if r.t.cnt /= "000" then v.t.cnt := r.t.cnt - 1;      else tto := '1'; end if;    else v.t.cnt := (0 => '0', others => '1'); end if;--    -- Ready to transfer data--    if ((r.t.csel and not readt_dly) or r.t.psel) = '1'--       or ((((memwrite and not r.pci.devsel) = '1')--       or (memread = '1' and not (hstart_ack and v.t.wdel) = '1')) and ben_err = '0')--       then ready := '1'; else ready := '0'; t_read_side := r.t.read and not hstart; end if;    -- Terminate current transaction    if (((r.t.fifo.waddr >= (FIFO_FULL - "10") and r.t.fifo.side = '1')    or (t_valid = '0') or r.pci.stop = '0') and pcii.frame = '0')    or ((r.t.read xor r.t.lwrite) = '0' and r.pci.devsel = '0')    or (tto = '1') or (ben_err = '1')    then term := '1'; else term := '0'; end if;    -- Retry transfer    if r.t.state = b_busy then      if not ((r.t.read and not r.t.lwrite and hstart_ack and read_match) = '1'      or (r.t.read or hstart or hstart_ack) = '0'      or ((r.t.csel or r.t.psel) and not hstart and not hstart_ack) = '1')      then retry := '1'; end if;    end if;    -- target state machine    case r.t.state is    when idle  =>            if pr.frame = '0' then v.t.state := b_busy; end if; -- !HIT ?      v.t.addr := pr.ad;      if readpref = 1 then v.t.burst := '1';      else v.t.burst := pr.cbe(3); end if;      v.t.read := not pr.cbe(0); v.t.mult := not pr.cbe(1);      v.t.csel := (pr.idsel or hosthit) and chit; v.t.psel := phit;      v.t.msel := r.comm.men and (mhit0 or mhit1); v.t.barsel := mhit1;    when turn_ar =>            if pr.frame = '1' then          v.t.state := idle;         v.t.fifo.raddr := (others => '0'); -- fix reset fifo read address       else v.t.state := b_busy; end if; -- !HIT ?      v.t.addr := pr.ad; v.t.wdel := '1';      if readpref = 1 then v.t.burst := '1';      else v.t.burst := pr.cbe(3); end if;      v.t.read := not pr.cbe(0); v.t.mult := not pr.cbe(1);      v.t.csel := (pr.idsel or hosthit) and chit; v.t.psel := phit;      v.t.msel := r.comm.men and (mhit0 or mhit1); v.t.barsel := mhit1;    when b_busy  =>      if (pr.frame and pr.irdy) = '1' then        v.t.state := idle;      elsif hit = '1' then        v.t.state := s_data;        v.t.fifo.raddr := r.t.fifo.raddr + (r.t.read and r.t.msel);        readt_dly := '1';                if r.t.pending = '0' then          v.t.pending := retry and not hstart_ack;        end if;              end if;--      else v.t.state := backoff; end if;--      We should not go to back off if the access wasn't to us          when s_data  =>            if r.t.pending = '1' then v.t.pending := not ((habort or not r.pci.trdy) and read_match); end if;      if (pcii.frame = '0' and r.pci.stop ='0' and (r.pci.trdy or not pcii.irdy) = '1') then        v.t.state := backoff;        if r.t.last = '0' then v.t.last := r.t.msel and r.t.lwrite and v.t.wdel; end if;        v.t.fifo.raddr := r.t.fifo.raddr - (r.t.read and r.t.msel and not fifort_limit);--      elsif (pcii.frame = '1' and (r.pci.trdy = '0' or r.pci.stop = '0')) then      elsif (pcii.frame = '1' and (r.t.trdy_del = '0' or r.pci.stop = '0')) then -- (send last word in fifo) bug fix ***         v.t.state := turn_ar;        if r.t.last = '0' then v.t.last := r.t.msel and r.t.lwrite and v.t.wdel; end if;        v.t.fifo.raddr := r.t.fifo.raddr - (r.t.read and r.t.msel and not fifort_limit);      end if;    when backoff =>            if pcii.frame = '1' then v.t.state := turn_ar; end if;    end case;    -- #TRDY assert    if (v.t.state = s_data and habort = '0' and ready = '1' and retry = '0') then v.pci.trdy := '0'; end if;    -- #STOP assert    if (v.t.state = backoff or (v.t.state = s_data and ((tabort or ((term or retry) and not habort)) = '1'))) then      v.pci.stop := '0'; end if;    -- #DEVSEL assert    if (((v.t.state = backoff and r.pci.devsel = '0') or v.t.state = s_data) and (read_match and tabort) = '0') then v.pci.devsel := '0'; end if;    -- Enable #TRDY, #STOP and #DEVSEL    if (v.t.state = s_data) or (v.t.state = backoff) or (v.t.state = turn_ar) then      v.pci.oe_ctrl := not hit;    else v.pci.oe_ctrl := '1'; end if;    -- Signaled target abort    if (r.pci.devsel and not (r.pci.stop or r.pci.oe_ctrl)) = '1' then v.stat.sta := '1'; end if;    if r.t.state = s_data and v.t.state = s_data and r.pci.trdy = '0'        and v.pci.trdy = '1' and v.t.wdel = '1' and pcii.frame = '0' then -- (send last word in fifo) bug fix ***        v.t.trdy_del := '0';    else       v.t.trdy_del := v.pci.trdy;    end if;    if r.t.state = s_data and r.pci.trdy = '1' and v.pci.trdy = '0' and pcii.frame = '0' then -- bug fix ***        readt_dly := '1';       v.t.fifo.raddr := r.t.fifo.raddr + (r.t.read and not fifort_limit and t_valid);    end if;    -- Latched signals to AHB backend--     if (r.t.state = b_busy) then--       if (hstart or hstart_ack) = '0' then -- must be idle--         v.t.lwrite := not r.t.read;--         case pr.cbe is--         when "0000" => v.t.lsize := "10";--         when "1100" => v.t.lsize := "01";--         when "1110" => v.t.lsize := "00";--         when others => v.t.lsize := "10";--         end case;--         if r.t.msel = '1' then--           v.t.lburst := r.t.burst;--           if r.t.barsel = '0' then v.t.laddr := r.page & r.t.addr(MADDR_WIDTH-2 downto 0);--           else  v.t.laddr := r2.dmapage & r.t.addr(DMAMADDR_WIDTH-1 downto 0); end if;--           v.t.lmult :=  r.t.mult;--           rtdone := '0'; v.t.fifo.waddr := (others => '0');--           hstart := r.t.read and r.t.msel;--         end if;--       end if;--     end if;    -- Latched signals to AHB backend    if (r.t.state = b_busy) then      if (hstart or hstart_ack) = '0' then -- must be idle        v.t.lwrite := not r.t.read;                if endian = 0 then -- pci is little endian                    case pr.cbe is            when "0000" =>       -- 32 bit access              v.t.lsize := "10";  byteaddr  := "00";            when "1100" =>       -- 16 bit               v.t.lsize := "01";  byteaddr  := "00";            when "0011" =>              v.t.lsize := "01";  byteaddr  := "10";            when "1110" =>       -- 8 bit              v.t.lsize := "00";  byteaddr  := "00";            when "1101" =>              v.t.lsize := "00";  byteaddr  := "01";            when "1011" =>              v.t.lsize := "00";  byteaddr  := "10";            when "0111" =>              v.t.lsize := "00";  byteaddr  := "11";                      when others => v.t.lsize := "10";          end case;        else -- big endian          case pr.cbe is            when "0000" =>       -- 32 bit access              v.t.lsize := "10";  byteaddr  := "00";            when "0011" =>       -- 16 bit               v.t.lsize := "01";  byteaddr  := "00";            when "1100" =>              v.t.lsize := "01";  byteaddr  := "10";            when "0111" =>       -- 8 bit              v.t.lsize := "00";  byteaddr  := "00";            when "1011" =>              v.t.lsize := "00";  byteaddr  := "01";            when "1101" =>              v.t.lsize := "00";  byteaddr  := "10";            when "1110" =>              v.t.lsize := "00";  byteaddr  := "11";                      when others => v.t.lsize := "10";          end case;        end if;                if r.t.msel = '1' then          v.t.lburst := r.t.burst;          v.t.lcbe := pr.cbe;           if r.t.barsel = '0' then v.t.laddr := r.page & r.t.addr(MADDR_WIDTH-2 downto 2) & byteaddr;          else  v.t.laddr := r2.dmapage & r.t.addr(DMAMADDR_WIDTH-1 downto 2) & byteaddr; end if;          v.t.lmult :=  r.t.mult;          rtdone := '0'; v.t.fifo.waddr := (others => '0');          hstart := r.t.read and r.t.msel;        end if;      end if;    end if;        -- Read data mux    if r.t.csel = '1' then tad := cdata;    elsif r.t.psel = '1' then      tad(31 downto MADDR_WIDTH-1) := r.page;      tad(MADDR_WIDTH-2 downto 0) := zero32(MADDR_WIDTH-2 downto 1) & r.bt_enable;--    elsif (r.t.state = b_busy or (r.pci.trdy or pcii.irdy) = '0') then tad := fifo1o.rdata(31 downto 0);    elsif (r.t.state = b_busy or (r.pci.trdy or pcii.irdy) = '0' or r.t.wdel = '1') then tad := fifo1o.rdata(31 downto 0); -- bug fix ***     end if;    -- FIFO controller    if ((fifowt_limit and write_access) = '1' or (r.t.last or rtdone) = '1') then      if hstart = hstart_ack then        if rtdone = '0' then hstart := not hstart_ack; v.t.fifo.side := hstart; end if;        if r.t.last = '1' then rtdone := '1'; v.t.last := '0';        else v.t.fifo.waddr := (others => '0');          if rtdone = '1' then            rtdone := '0'; hstart := '0'; v.t.fifo.side := '0';          end if;        end if;      end if;    end if;    if (fifort_limit and v.t.wdel) = '1' then      if hstart_ack = '1' then hstart := '0'; v.t.fifo.raddr := (others => '0');      else v.t.fifo.raddr := (others => '0'); end if;    end if;----- *** PCI TARGET END*** ------------- *** PCI MASTER *** --------  if MASTER = 1 then    bus_idle := pcii.frame and pcii.irdy;    data_transfer := not (pcii.trdy or r.pci.irdy);    data_transfer_r := not (pr.trdy or pr.irdy);    data_phase := not ((pcii.trdy and pcii.stop) or r.pci.irdy);    targ_d_w_data := not (pr.stop or pr.trdy);    targ_abort := pr.devsel and not pr.stop;    -- Request from AHB backend to start PCI transaction    if (pstart and not pstart_ack) = '1' then      if (r.m.fstate = idle and r.m.request = '0') then

⌨️ 快捷键说明

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