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

📄 pci_mtf.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 5 页
字号:
    p_done := pstart_ack or pabort;    if r2.m.fifo.raddr = FIFO_FULL then fiform_limit := '1'; else fiform_limit := '0'; end if;    if r2.m.fifo.waddr = FIFO_FULL then fifowm_limit := '1'; else fifowm_limit := '0'; end if;    if r2.s.fifo.raddr = FIFO_FULL then fifors_limit := '1'; else fifors_limit := '0'; end if;    if r2.s.fifo.waddr = FIFO_FULL then fifows_limit := '1'; else fifows_limit := '0'; end if;    if r2.s.fifo.waddr(FIFO_DEPTH - 2 downto 1) = FIFO_FULL(FIFO_DEPTH - 2 downto 1) then fifows_stop := '1'; else fifows_stop := '0'; end if;---- *** APB Control & Status regs *** ----      if (apbi.psel(pindex) and apbi.penable) = '1' then        case apbi.paddr(4 downto 2) is        when "000" =>          if apbi.pwrite = '1' then            v.pciba := apbi.pwdata(31 downto 28);            v.werr := r2.werr and not apbi.pwdata(14);            v.wcomm := apbi.pwdata(10) and r.comm.mwie;            v.rcomm := apbi.pwdata(9);          end if;          prdata := r2.pciba & "00000" & r.ltim & r2.werr & not pr.host & r.comm.msen & r.comm.men & r2.wcomm & r2.rcomm & r2.cfto & r.cline;        when "001" =>          prdata := r.bar0(31 downto MADDR_WIDTH) & addzero(MADDR_WIDTH-1 downto 0);        when "010" =>          prdata := r.page(31 downto MADDR_WIDTH-1) & addzero(MADDR_WIDTH-2 downto 1) & r.bt_enable;        when "011" =>          prdata := r.bar1(31 downto DMAMADDR_WIDTH) & addzero(DMAMADDR_WIDTH-1 downto 0);        when "100" =>          if apbi.pwrite = '1' then            v.dmapage(31 downto DMAMADDR_WIDTH) := apbi.pwdata(31 downto DMAMADDR_WIDTH);          end if;          prdata := r2.dmapage(31 downto DMAMADDR_WIDTH) & addzero(DMAMADDR_WIDTH-1 downto 0);        when "101" =>          if apbi.pwrite = '1' then            v.ioba := apbi.pwdata(31 downto 16);          end if;          prdata := r2.ioba & addzero(15 downto 4) & hstart & hstart_ack & pstart & pstart_ack;        when "110" =>          prdata(1) := r.comm.men; prdata(2) := r.comm.msen;          prdata(4) := r.comm.mwie; prdata(6) := r.comm.per;          prdata(24) := r.stat.dped; prdata(26) := '1';          prdata(27) := r.stat.sta; prdata(28) := r.stat.rta;          prdata(29) := r.stat.rma; prdata(31) := r.stat.dpe;        when others =>        end case;      end if;---- *** AHB MASTER *** ----    -- Burst control    if (r2.m.state = read or r2.m.state = read_w) then      if r.t.lmult = '1' then        comp := fifowm_limit and r2.m.fifo.side;      elsif r.t.lburst = '1' then        if r2.clscnt(8) = '1' then comp := '1';        else v.clscnt := r2.clscnt - (dmao.active and dmao.ready); end if;      else comp := '1'; end if;    else      v.clscnt := '0' & (r.cline - '1'); -- set burst counter to cache line size    end if;    if (rtdone = '1' and (r2.m.fifo.raddr + '1') = r.t.fifo.waddr) then rmvalid := '0'; end if;    --step DMA address    if dmao.ready = '1' then      v.m.dmaddr(31 downto 2) := r2.m.dmaddr(31 downto 2) + '1';    end if;    -- AHB master state machine    case r2.m.state is    when idle =>      v.m.read_half := '0';            if hstart = '1' then        wmdone := '0'; fifowm_limit := '0';         vdmai.start := '1';        v.m.fifo.waddr := (others => '0');        --        if dmao.active = '1' then  -- zero ws fix                if r.t.lwrite = '1'  then          v.m.state := write; v.m.dmaddr := r.t.laddr; --vdmai.busy := '1';          --            if rmvalid = '1' then v.m.state := write;--            else vdmai.start := '0'; v.m.state := stop; end if;                  else v.m.state := read_w; end if;      else v.m.dmaddr := r.t.laddr; end if;      --      end if;          when write =>--      vdmai.start := ((rmvalid and not fiform_limit) or (not dmao.active and not rmvalid));            --if fiform_limit = '1' then      if fiform_limit = '1' and dmao.start = '1' then -- 1k bug fix (store last word in first          v.m.read_half := '1';                        --             fifo half if addr = 0x400 ...)      end if;      -- don't start again until pci side is done filling fifo, bug fix kc      if r2.m.read_half = '1' then        if rtdone = '1' then        vdmai.start :=  ((rmvalid and not fiform_limit) or (not dmao.active and not rmvalid));        end if;      else        --vdmai.start := ((rmvalid and not fiform_limit) or (not dmao.active and not rmvalid));        -- 1k bug fix (store last word in first fifo half if addr = 0x400 ...)        vdmai.start := ((rmvalid and not v.m.read_half) or (not dmao.active and not rmvalid));      end if;            if (dmao.active and dmao.ready) = '1' then        v.m.fifo.raddr := r2.m.fifo.raddr + (rmvalid and not fiform_limit and not dmao.mexc);        if (dmao.mexc = '1' or rmvalid = '0') then          habort := dmao.mexc and not r.t.lwrite; v.werr := r2.werr or (dmao.mexc and r.t.lwrite); v.m.state := stop; end if;      end if;    when read_w =>            vdmai.start := not (comp and dmao.active);      if dmao.mexc = '1' then habort := not r.t.lwrite; v.werr := '1'; v.m.state := stop;      elsif dmao.ready = '1' then        fifom_write := '1'; wmvalid := not (comp or dmao.mexc);        if comp = '1' then v.m.state := stop; v.m.fifo.waddr := r2.m.fifo.waddr + '1';        else v.m.fifo.waddr := r2.m.fifo.waddr + (not fifowm_limit); v.m.state := read; end if;      end if;    when read =>            vdmai.start := not (comp and dmao.active);      fifom_write := dmao.ready; wmvalid := not (comp or dmao.mexc);--      if ((comp and dmao.ready) or dmao.retry) = '1' then      if (comp and dmao.ready) = '1' then        v.m.state := stop; v.m.fifo.waddr := r2.m.fifo.waddr + '1';      elsif (dmao.active and dmao.ready) = '1' then        v.m.fifo.waddr := r2.m.fifo.waddr + (not dmao.mexc and not fifowm_limit);        if dmao.mexc = '1' then habort := not r.t.lwrite; v.werr := r2.werr or r.t.lwrite; v.m.state := stop; end if;      end if;          when stop =>            if hstart = '0' and ((r.t.lwrite and not fiform_limit) = '1' or wmdone = '1') then        v.m.state := idle; hstart_ack := '0';        v.m.fifo.side := '0'; habort := '0';        v.m.fifo.raddr := (others => '0');      else        comp := '1';        fiform_limit := r.t.lwrite;        fifowm_limit := not r.t.lwrite;      end if;    end case;    -- FIFO control    if fifowm_limit = '1' then--      if (((r2.m.fifo.side or hstart_ack or (not hstart)) = '0' and not (dmao.active and not dmao.ready) = '1')      if (((r2.m.fifo.side or hstart_ack or (not hstart)) = '0' and (dmao.ready or comp) = '1')      or ((hstart_ack and not hstart) = '1' and v.m.state = stop)) then        if v.m.state = stop then wmdone := '1';        else v.m.fifo.waddr := (others => '0'); end if;        hstart_ack := '1';        v.m.fifo.side := not r2.m.fifo.side;      end if;    elsif fiform_limit = '1' then--      if dmao.active = '0' then      if dmao.active = '0' and dmai.start = '0' then -- 1k bug fix ***        m_read_side := '1';        hstart_ack := '1';--        v.m.fifo.raddr := (others => hstart);        v.m.fifo.raddr := (others => '0'); -- 1k bug fix ***      end if;    end if;---- *** AHB MASTER END *** -------- *** AHB SLAVE *** ------    if MASTER = 1 then      -- Access decode      if (ahbsi.hready and ahbsi.hsel(hslvndx)) = '1' then        if (ahbsi.hmbsel(0) or ahbsi.hmbsel(1)) = '1' then          hsize := ahbsi.hsize(1 downto 0); v.s.htrans := ahbsi.htrans;          --if (v.s.htrans(1) and r.comm.msen) = '1' then request := '1'; end if;          if (v.s.htrans(1) and r.comm.msen) = '1' then -- fix access control ***               ahb_access := '1';             --if (r2.s.state /= r_wait and r2.s.state /= r_hold) or r2.s.hmaster = ahbsi.hmaster then             --if (r2.s.state = idle or r2.s.state = t_done) or r2.s.hmaster = ahbsi.hmaster then             if (r2.s.state = idle) or r2.s.hmaster = ahbsi.hmaster then               request := '1';             end if;          end if;        end if;      end if;      -- Access latches      if (request = '1' and r2.s.state = idle) then        if ahbsi.hmbsel(1)  = '1' then          if ahbsi.haddr(16) = '1' then -- Configuration cycles            v.s.maddr(31 downto 11) := (others =>'0');            v.s.maddr(conv_integer(ahbsi.haddr(15 downto 11)) + 10) := '1';--            v.s.maddr(10 downto 0) := ahbsi.haddr(10 downto 0);            v.s.maddr(10 downto 0) := ahbsi.haddr(10 downto 2) & "00";            v.s.pcicomm := "101" & ahbsi.hwrite;          else -- I/O space access            v.s.maddr(31 downto 16) := r2.ioba;            v.s.maddr(15 downto 0) := ahbsi.haddr(15 downto 0);            v.s.pcicomm := "001" & ahbsi.hwrite;          end if;        else -- Memory space access          if conv_integer(ahbsi.hmaster) = dmamst then v.s.maddr := ahbsi.haddr;--          else v.s.maddr := r2.pciba & ahbsi.haddr(27 downto 0); end if;           else v.s.maddr := r2.pciba & ahbsi.haddr(27 downto 2) & "00"; end if;           if ahbsi.hwrite = '1' then v.s.pcicomm := r2.wcomm & "111";          else v.s.pcicomm := ahbsi.hburst(0) & '1' & (r2.rcomm or not ahbsi.hburst(0)) & '0'; end if;        end if;                if endian = 0 then -- pci is little endian                    case hsize is            when "00" => -- Decode byte enable              case ahbsi.haddr(1 downto 0) is                when "00" => v.s.be := "1110";                when "01" => v.s.be := "1101";                when "10" => v.s.be := "1011";                when "11" => v.s.be := "0111";                when others => v.s.be := "1111";              end case;            when "01" =>              case ahbsi.haddr(1 downto 0) is                when "00" =>   v.s.be := "1100";                when "10" =>   v.s.be := "0011";                when others => v.s.be := "1111";              end case;            when  "10" => v.s.be := "0000";            when others => v.s.be := "1111";          end case;                                 else     -- pci is big endian                           case hsize is            when "00" => -- Decode byte enable              case ahbsi.haddr(1 downto 0) is                when "00" => v.s.be   := "0111";                when "01" => v.s.be   := "1011";                when "10" => v.s.be   := "1101";                when "11" => v.s.be   := "1110";                when others => v.s.be := "1111";              end case;            when "01" =>              case ahbsi.haddr(1 downto 0) is                when "00" =>   v.s.be := "0011";                when "10" =>   v.s.be := "1100";                when others => v.s.be := "1111";              end case;            when  "10" => v.s.be := "0000";            when others => v.s.be := "1111";          end case;        end if;      end if;      if ((rmdone and not r2.s.pcicomm(0)) = '1' and (r2.s.fifo.raddr + '1' + pcidc) = r.m.fifo.waddr) then rsvalid := '0'; end if;      -- FIFO address counters--      if (r2.s.state = t_data or r2.s.state = w_wait) then      if (r2.s.state = t_data or r2.s.state = w_wait or  -- bug fix ***      (r2.s.state = r_hold and fifors_limit = '0' and ((pstart_ack or pstart) = '0') and request = '1')) then -- (r_hold -> t_data) bug fix ***        v.s.fifos_write := r2.s.pcicomm(0) and r2.s.htrans(1);        v.s.fifo.waddr := r2.s.fifo.waddr + r2.s.fifos_write;        v.s.fifo.raddr := r2.s.fifo.raddr + ((ahbsi.htrans(1) and not r2.s.pcicomm(0) and not fifors_limit and rsvalid) or not ahbsi.hready);      end if;      if pstart_ack = '1' then        if pabort = '1' then          if (r2.s.pcicomm = CONF_WRITE or r2.s.pcicomm = CONF_READ) then v.cfto := '1';          else v.s.perror := '1'; end if;        else v.s.perror := '0'; v.cfto := '0'; end if;      end if;        --        -- AHB slave state machine      case r2.s.state is              when idle =>                if request = '1' and p_done = '0' then          if ahbsi.hwrite = '1' then            v.s.state := w_wait;            v.s.fifo.side := '0';          else            pstart := '1'; v.s.state := r_wait;          end if;          v.s.hmaster := ahbsi.hmaster;         end if;              when w_wait =>                if ((ahbsi.hready and not ahbsi.htrans(0)) = '1') then          v.s.state := w_done; fifows_limit := not wsvalid;        else          v.s.state := t_data;        end if;              when t_data =>                burst_read := ahbsi.htrans(1) and not fifors_limit;                if (fifows_stop and r2.s.fifos_write) = '1' then          if r2.s.fifo.side = '1' then            v.s.state := w_done;          end if;                  elsif ((fifors_limit or not rsvalid) = '1' and v.s.htrans(1) = '1') then          if (r.m.fifo.side = '0') or (rsvalid = '0') then            v.s.state := t_done;          else v.s.state := r_hold; end if;        end if;        

⌨️ 快捷键说明

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