pci_mtf.vhd
来自「The GRLIB IP Library is an integrated se」· VHDL 代码 · 共 1,463 行 · 第 1/4 页
VHD
1,463 行
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; 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; 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 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.state := m_data; when m_data => -- Master transfers data 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 ((((pcii.stop or not d_ready) and not (comp or v.m.split or not v.m.valid)) and not grant)) = '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.page(31 downto 30) := "01"; v.page(29 downto MADDR_WIDTH-1) := zero32(29 downto MADDR_WIDTH-1); v.pci.par := '0'; v.comm.msen := not pr.host; v.comm.men := '0'; v.comm.mwie := '0'; v.comm.per := '0'; v.stat.rta := '0'; v.stat.rma := '0'; v.stat.sta := '0'; v.stat.dped := '0'; v.stat.dpe := '0'; v.cline := (others => '0'); v.ltim := (others => '0'); v.intline := (others => '0'); v.trans := (others => '0'); v.t.fifo.waddr := (others => '0'); v.t.fifo.raddr := (others => '0'); v.m.fifo.waddr := (others => '0'); v.m.fifo.raddr := (others => '0'); v.t.fifo.side := '0'; v.m.fifo.side := '0'; v.m.request := '0'; v.m.hwrite := '0'; v.m.valid := '1'; v.m.split := '0'; v.m.last := '0'; v.t.last := '0'; end if; fifo2i.wen <= t_fifo_write; fifo2i.waddr <= r.t.fifo.side & r.t.fifo.waddr; fifo2i.wdata <= pr.ad; fifo1i.ren <= '1'; fifo1i.raddr <= t_read_side & (r.t.fifo.raddr + readt_dly); fifo4i.wen <= m_fifo_write; fifo4i.waddr <= r.m.fifo.side & r.m.fifo.waddr; fifo4i.wdata <= pr.ad; fifo3i.ren <= '1'; fifo3i.raddr <= m_read_side & (r.m.fifo.raddr + data_transfer); rin <= v; rioe_ad <= voe_ad; pcio.cbeen <= (others => oe_cbe); pcio.cbe <= r.pci.cbe; pcio.vaden <= roe_ad; pcio.aden <= oe_ad; pcio.ad <= r.pci.ad; pcio.trdy <= r.pci.trdy; pcio.ctrlen <= oe_ctrl; pcio.trdyen <= oe_ctrl; pcio.devselen <= oe_ctrl; pcio.stopen <= oe_ctrl; pcio.stop <= r.pci.stop; pcio.devsel <= r.pci.devsel; pcio.par <= r.pci.par; pcio.paren <= oe_par; pcio.perren <= oe_perr; pcio.perr <= r.pci.perr; pcio.reqen <= oe_req; pcio.req <= r.pci.req; pcio.frameen <= oe_frame; pcio.frame <= r.pci.frame; pcio.irdyen <= oe_irdy; pcio.irdy <= r.pci.irdy; end process; pcir : process (pciclk, pcii.rst) begin if rising_edge (pciclk) then pr.ad <= to_x01(pcii.ad); pr.cbe <= to_x01(pcii.cbe); pr.devsel <= to_x01(pcii.devsel); pr.frame <= to_x01(pcii.frame); pr.idsel <= to_x01(pcii.idsel); pr.irdy <= to_x01(pcii.irdy); pr.trdy <= to_x01(pcii.trdy); pr.par <= to_x01(pcii.par); pr.stop <= to_x01(pcii.stop); pr.rst <= to_x01(pcii.rst); pr.gnt <= to_x01(pcii.gnt); pr.host <= to_x01(pcii.host); r.pci.ad <= rin.pci.ad; r.pci.cbe <= rin.pci.cbe; r.pci.frame <= rin.pci.frame; r.pci.devsel <= rin.pci.devsel; r.pci.trdy <= rin.pci.trdy; r.pci.irdy <= rin.pci.irdy; r.pci.stop <= rin.pci.stop; r.pci.par <= rin.pci.par; r.pci.req <= rin.pci.req; r.pci.perr <= rin.pci.perr; if pcii.rst = '0' then -- asynch reset required r.pci.oe_ad <= '1'; r.pci.oe_ctrl <= '1'; r.pci.oe_par <= '1'; r.pci.oe_req <= '1'; r.pci.oe_frame <= '1'; r.pci.oe_cbe <= '1'; r.pci.oe_irdy <= '1'; r.pci.oe_perr <= '1'; r.noe_ad <= '0'; r.noe_ctrl <= '0'; r.noe_par <= '0'; r.noe_req <= '0'; r.noe_frame <= '0'; r.noe_cbe <= '0'; r.noe_irdy <= '0'; r.noe_perr <= '0'; if oepol = 0 then roe_ad <= (others => '1'); else roe_ad <= (others => '0'); end if; else roe_ad <= rioe_ad; r.pci.oe_ad <= rin.pci.oe_ad; r.pci.oe_ctrl <= rin.pci.oe_ctrl; r.pci.oe_par <= rin.pci.oe_par; r.pci.oe_req <= rin.pci.oe_req; r.pci.oe_frame <= rin.pci.oe_frame; r.pci.oe_cbe <= rin.pci.oe_cbe; r.pci.oe_irdy <= rin.pci.oe_irdy; r.pci.oe_perr <= rin.pci.oe_perr; r.noe_par <= rin.noe_par; r.noe_ad <= rin.noe_ad; r.noe_ctrl <= rin.noe_ctrl; r.noe_cbe <= rin.noe_cbe; r.noe_frame <= rin.noe_frame; r.noe_irdy <= rin.noe_irdy; r.noe_req <= rin.noe_req; r.noe_perr <= rin.noe_perr; end if; r.m <= rin.m; r.t <= rin.t; r.comm <= rin.comm; r.stat <= rin.stat; r.bar0 <= rin.bar0; r.bar1 <= rin.bar1; r.bar0_conf <= rin.bar0_conf; r.bar1_conf <= rin.bar1_conf; r.page <= rin.page; r.ltim <= rin.ltim; r.cline <= rin.cline; r.intline <= rin.intline; r.syncs <= rin.syncs; r.trans <= rin.trans; end if; end process; cpur : process (clk) begin if rising_edge (clk) then r2 <= r2in; end if; end process; oe0 : if oepol = 0 generate pcio.serren <= '1'; pcio.inten <= '1'; pcio.locken <= '1'; end generate; oe1 : if oepol = 1 generate pcio.serren <= '0'; pcio.inten <= '0'; pcio.locken <= '0'; end generate; pcio.serr <= '1'; pcio.int <= '1'; pcio.lock <= '1'; pcio.power_state <= (others => '0'); pcio.pme_enable <= '0'; pcio.pme_clear <= '0'; msttgt : if MASTER = 1 generate ahbmst0 : pciahbmst generic map (hindex => hmstndx, devid => GAISLER_PCIFBRG, incaddr => 1) port map (rst, clk, dmai, dmao, ahbmi, ahbmo); fifo1 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1) port map (pciclk, fifo1i.ren, fifo1i.raddr, fifo1o.rdata, clk, fifo1i.wen, fifo1i.waddr, fifo1i.wdata); fifo2 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1) port map (clk, fifo2i.ren, fifo2i.raddr, fifo2o.rdata, pciclk, fifo2i.wen, fifo2i.waddr, fifo2i.wdata); fifo3 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1) port map (pciclk, fifo3i.ren, fifo3i.raddr, fifo3o.rdata, clk, fifo3i.wen, fifo3i.waddr, fifo3i.wdata); fifo4 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1) port map (clk, fifo4i.ren, fifo4i.raddr, fifo4o.rdata, pciclk, fifo4i.wen, fifo4i.waddr, fifo4i.wdata);-- pragma translate_off bootmsg : report_version generic map ("pci_mtf" & tost(hslvndx) & ": 32-bit PCI/AHB bridge rev " & tost(REVISION) & ", " & tost(2**abits/2**20) & " Mbyte PCI memory BAR, " & tost(2**FIFO_DEPTH) & "-word FIFOs" );-- pragma translate_on end generate; tgtonly : if MASTER = 0 generate ahbmst0 : pciahbmst generic map (hindex => hmstndx, devid => GAISLER_PCIFBRG, incaddr => 1) port map (rst, clk, dmai, dmao, ahbmi, ahbmo); fifo1 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1) port map (pciclk, fifo1i.ren, fifo1i.raddr, fifo1o.rdata, clk, fifo1i.wen, fifo1i.waddr, fifo1i.wdata); fifo2 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1) port map (clk, fifo2i.ren, fifo2i.raddr, fifo2o.rdata, pciclk, fifo2i.wen, fifo2i.waddr, fifo2i.wdata);-- pragma translate_off bootmsg : report_version generic map ("pci_mtf" & tost(hmstndx) & ": 32-bit PCI/AHB bridge rev, target-only, " & tost(REVISION) & ", " & tost(2**abits/2**20) & " Mbyte PCI memory BAR, " & tost(2**FIFO_DEPTH) & "-word FIFOs" );-- pragma translate_on end generate;end;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?