📄 pci_mtf.vhd
字号:
------------------------------------------------------------------------------ This file is a part of the GRLIB VHDL IP LIBRARY-- Copyright (C) 2004 GAISLER RESEARCH---- This program is free software; you can redistribute it and/or modify-- it under the terms of the GNU General Public License as published by-- the Free Software Foundation; either version 2 of the License, or-- (at your option) any later version.---- See the file COPYING for the full details of the license.--------------------------------------------------------------------------------- Entity: pci_mtf-- File: pci_mtf.vhd-- Author: Jiri Gaisler - Gaisler Research-- Modified: Alf Vaerneus - Gaisler Research-- Description: PCI master and target interface------------------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;library grlib;use grlib.amba.all;use grlib.stdlib.all;use grlib.devices.all;library techmap;use techmap.gencomp.all;library gaisler;use gaisler.pci.all;use gaisler.pcilib.all;use gaisler.misc.all;entity pci_mtf is generic ( memtech : integer := DEFMEMTECH; hmstndx : integer := 0; dmamst : integer := NAHBMST; readpref : integer := 0; abits : integer := 21; dmaabits : integer := 26; fifodepth : integer := 3; -- FIFO depth device_id : integer := 0; -- PCI device ID vendor_id : integer := 0; -- PCI vendor ID master : integer := 1; -- Enable PCI Master hslvndx : integer := 0; pindex : integer := 0; paddr : integer := 0; pmask : integer := 16#fff#; haddr : integer := 16#F00#; hmask : integer := 16#F00#; ioaddr : integer := 16#000#; irq : integer := 0; irqmask : integer := 0; nsync : integer range 1 to 2 := 2; -- 1 or 2 sync regs between clocks oepol : integer := 0; endian : integer := 0 -- 0 little, 1 big); port( rst : in std_logic; clk : in std_logic; pciclk : in std_logic; pcii : in pci_in_type; pcio : out pci_out_type; apbi : in apb_slv_in_type; apbo : out apb_slv_out_type; ahbmi : in ahb_mst_in_type; ahbmo : out ahb_mst_out_type; ahbsi : in ahb_slv_in_type; ahbso : out ahb_slv_out_type);end;architecture rtl of pci_mtf isconstant REVISION : amba_version_type := 0;constant CSYNC : integer := nsync-1;constant HADDR_WIDTH : integer := 28;constant MADDR_WIDTH : integer := abits;constant DMAMADDR_WIDTH : integer := dmaabits;constant FIFO_DEPTH : integer := fifodepth;constant FIFO_FULL : std_logic_vector(FIFO_DEPTH - 2 downto 0) := (others => '1');constant FIFO_DATA_BITS : integer := 32; -- One valid bitconstant NO_CPU_REGS : integer := 6;constant NO_PCI_REGS : integer := 6;constant pconfig : apb_config_type := ( 0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_PCIFBRG, 0, REVISION, irq), 1 => apb_iobar(paddr, pmask));constant hconfig : ahb_config_type := ( 0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_PCIFBRG, 0, REVISION, 0), 4 => ahb_membar(haddr, '0', '0', hmask), 5 => ahb_iobar (ioaddr, 16#E00#), others => zero32);function byte_twist(di : in std_logic_vector(31 downto 0); enable : in std_logic) return std_logic_vector is variable do : std_logic_vector(31 downto 0);begin if enable = '1' then for i in 0 to 3 loop do(31-i*8 downto 24-i*8) := di(31-(3-i)*8 downto 24-(3-i)*8); end loop; else do := di; end if; return do; end function;type pci_input_type is record ad : std_logic_vector(31 downto 0); cbe : std_logic_vector(3 downto 0); frame : std_logic; devsel : std_logic; idsel : std_logic; trdy : std_logic; irdy : std_logic; par : std_logic; stop : std_logic; rst : std_logic; gnt : std_logic; host : std_logic;end record;type pci_fifo_in_type is record ren : std_logic; raddr : std_logic_vector(FIFO_DEPTH - 1 downto 0); wen : std_logic; waddr : std_logic_vector(FIFO_DEPTH - 1 downto 0); wdata : std_logic_vector(FIFO_DATA_BITS - 1 downto 0);end record;type pci_fifo_out_type is record rdata : std_logic_vector(FIFO_DATA_BITS - 1 downto 0);end record;type fifo_type is record side : std_logic; -- Owner access side. Receiver accesses the other side raddr : std_logic_vector(FIFO_DEPTH - 2 downto 0); waddr : std_logic_vector(FIFO_DEPTH - 2 downto 0);end record;type pci_target_state_type is (idle, b_busy, s_data, backoff, turn_ar);type pci_master_state_type is (idle, addr, m_data, turn_ar, s_tar, dr_bus);type pci_master_fifo_state_type is (idle, addr, incr, last1, sync, t_retry, ttermwd, ttermnd, abort, done, wdone);type pci_target_type is record state : pci_target_state_type; cnt : std_logic_vector(2 downto 0); csel : std_logic; -- Configuration chip select msel : std_logic; -- Memory hit barsel : std_logic; -- Memory hit psel : std_logic; -- Page hit addr : std_logic_vector(31 downto 0); laddr : std_logic_vector(31 downto 0); lsize : std_logic_vector(1 downto 0); lcbe : std_logic_vector(3 downto 0); lwrite : std_logic; lburst : std_logic; lmult : std_logic; mult : std_logic; read : std_logic; -- PCI target read burst : std_logic; pending : std_logic; wdel : std_logic; last : std_logic; fifo : fifo_type; trdy_del : std_logic; -- (delay trdy to send last word in fifo) bug fix *** end record;type pci_master_type is record state : pci_master_state_type; fstate : pci_master_fifo_state_type; cnt : std_logic_vector(2 downto 0); ltim : std_logic_vector(7 downto 0); -- Latency timer request : std_logic; hwrite : std_logic; stop_req : std_logic; last : std_logic; valid : std_logic; split : std_logic; first : std_logic; firstw : std_logic; fifo : fifo_type; rmdone : std_logic; -- bug fix *** stopframe: std_logic; lto : std_logic; -- bug fix latency timer timeoutend record;type pci_sync_regs is array (0 to NO_PCI_REGS - 1) of std_logic_vector(csync downto 0);type pci_reg_type is record pci : pci_sigs_type; noe_par : std_logic; noe_ad : std_logic; noe_ctrl : std_logic; noe_cbe : std_logic; noe_frame : std_logic; noe_irdy : std_logic; noe_req : std_logic; noe_perr : std_logic; m : pci_master_type; t : pci_target_type; comm : pci_config_command_type; -- Command register stat : pci_config_status_type; -- Status register bar0 : std_logic_vector(31 downto MADDR_WIDTH); -- Base Address register 0 bar1 : std_logic_vector(31 downto DMAMADDR_WIDTH); -- Base Address register 1 bar0_conf : std_logic; bar1_conf : std_logic; page : std_logic_vector(31 downto MADDR_WIDTH-1); -- AHB page bt_enable : std_logic; -- Byte twist enable, page0 bit 0 ltim : std_logic_vector(7 downto 0); -- Latency timer cline : std_logic_vector(7 downto 0); -- Cache Line Size intline : std_logic_vector(7 downto 0); -- Interrupt Line syncs : pci_sync_regs; trans : std_logic_vector(NO_CPU_REGS - 1 downto 0);end record;type cpu_master_state_type is (idle, write, read_w, read, stop);type cpu_slave_state_type is (idle, w_wait, t_data, r_hold, r_wait, w_done, t_done);type cpu_master_type is record state : cpu_master_state_type; -- AMBA master state machine dmaddr : std_logic_vector(31 downto 0); fifo : fifo_type; read_half : std_logic;end record;type cpu_slave_type is record state : cpu_slave_state_type; -- AMBA slave state machine maddr : std_logic_vector(31 downto 0); mdata : std_logic_vector(31 downto 0); be : std_logic_vector(3 downto 0); perror : std_logic; hresp : std_logic_vector(1 downto 0); hready : std_logic; htrans : std_logic_vector(1 downto 0); hmaster : std_logic_vector(3 downto 0); pcicomm : std_logic_vector(3 downto 0); hold : std_logic; fifos_write : std_logic; fifo : fifo_type; last_side : std_logic;end record;type cpu_sync_regs is array (0 to NO_CPU_REGS - 1) of std_logic_vector(csync downto 0);type cpu_reg_type is record m : cpu_master_type; s : cpu_slave_type; syncs : cpu_sync_regs; trans : std_logic_vector(NO_PCI_REGS - 1 downto 0); pciba : std_logic_vector(3 downto 0); cfto : std_logic; wcomm : std_logic; rcomm : std_logic; werr : std_logic; clscnt : std_logic_vector(8 downto 0); dmapage : std_logic_vector(31 downto DMAMADDR_WIDTH); -- DMA page ioba : std_logic_vector(15 downto 0); pciirq : std_logic_vector(1 downto 0);end record;signal clk_int : std_logic;signal pr : pci_input_type;signal r, rin : pci_reg_type;signal r2, r2in : cpu_reg_type;signal dmai : ahb_dma_in_type;signal dmao : ahb_dma_out_type;signal fifo1i, fifo2i, fifo3i, fifo4i : pci_fifo_in_type;signal fifo1o, fifo2o, fifo3o, fifo4o : pci_fifo_out_type;signal roe_ad, rioe_ad : std_logic_vector(31 downto 0); attribute syn_preserve : boolean;attribute syn_preserve of roe_ad : signal is true; begin-- Back-end state machine (AHB clock domain) comb : process (rst, r2, r, dmao, ahbsi, fifo2o, fifo4o, apbi) variable vdmai : ahb_dma_in_type; variable v : cpu_reg_type; variable hready : std_logic; variable hresp, hsize : std_logic_vector(1 downto 0); variable p_done, wsdone, wmdone, rtdone, rmdone : std_logic; variable pstart, habort, hstart_ack : std_logic; variable hstart, pabort, pstart_ack, pcidc : std_logic; variable i : integer range 0 to NO_CPU_REGS; variable fifom_write, fifos_write : std_logic; variable prdata : std_logic_vector(31 downto 0); variable wmvalid, wsvalid, rmvalid, rsvalid, burst_read, hold : std_logic; variable fifors_limit, fifows_limit,fiform_limit, fifowm_limit, fifows_stop : std_logic; variable comp, request, s_read_side, m_read_side : std_logic; variable ahb_access : std_logic; -- *** access control fix begin v := r2; vdmai.start := '0'; vdmai.size := r.t.lsize; vdmai.irq := '0'; vdmai.busy := '0'; vdmai.burst := '1'; vdmai.wdata := byte_twist(fifo2o.rdata(31 downto 0), r.bt_enable); vdmai.write := r.t.lwrite; rmvalid := '1'; wmvalid := '1'; request := '0'; hold := '0'; rsvalid := '1'; wsvalid := '1'; burst_read := '0'; hready := '1'; hresp := HRESP_OKAY; hsize := "10"; fifom_write := '0'; v.s.fifos_write := '0'; comp := '0'; prdata := (others => '0'); v.s.hold := '0'; s_read_side := not r.m.fifo.side; m_read_side := not r.t.fifo.side; ahb_access := '0'; -- *** access control fix -- Synch registers pstart := r2.trans(0); habort := r2.trans(1); hstart_ack := r2.trans(2);-- fifows_limit := r2.trans(3); wsdone := r2.trans(4); wmdone := r2.trans(5); for i in 0 to NO_CPU_REGS - 1 loop v.syncs(i)(csync) := r.trans(i); if csync /= 0 then v.syncs(i)(0) := r2.syncs(i)(csync); end if; end loop; hstart := r2.syncs(0)(0); pabort := r2.syncs(1)(0); pstart_ack := r2.syncs(2)(0); pcidc := r2.syncs(3)(0); rtdone := r2.syncs(4)(0); rmdone := r2.syncs(5)(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -