ReonV/lib/gaisler/spi/spictrl.vhd

316 lines
12 KiB
VHDL

------------------------------------------------------------------------------
-- This file is a part of the GRLIB VHDL IP LIBRARY
-- Copyright (C) 2003 - 2008, Gaisler Research
-- Copyright (C) 2008 - 2014, Aeroflex Gaisler
-- Copyright (C) 2015 - 2017, Cobham Gaisler
--
-- 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.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-------------------------------------------------------------------------------
-- Entity: spictrl
-- File: spictrl.vhd
-- Author: Jan Andersson - Aeroflex Gaisler AB
-- Contact: support@gaisler.com
-- Description: Wrapper for SPICTRL core
-------------------------------------------------------------------------------
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
library techmap;
use techmap.gencomp.all;
use techmap.netcomp.all;
library grlib;
use grlib.amba.all;
use grlib.devices.all;
use grlib.stdlib.all;
library gaisler;
use gaisler.spi.all;
entity spictrl is
generic (
-- APB generics
pindex : integer := 0; -- slave bus index
paddr : integer := 0; -- APB address
pmask : integer := 16#fff#; -- APB mask
pirq : integer := 0; -- interrupt index
-- SPI controller configuration
fdepth : integer range 1 to 7 := 1; -- FIFO depth is 2^fdepth
slvselen : integer range 0 to 1 := 0; -- Slave select register enable
slvselsz : integer range 1 to 32 := 1; -- Number of slave select signals
oepol : integer range 0 to 1 := 0; -- Output enable polarity
odmode : integer range 0 to 1 := 0; -- Support open drain mode, only
-- set if pads are i/o or od pads.
automode : integer range 0 to 1 := 0; -- Enable automated transfer mode
acntbits : integer range 1 to 32 := 32; -- # Bits in am period counter
aslvsel : integer range 0 to 1 := 0; -- Automatic slave select
twen : integer range 0 to 1 := 1; -- Enable three wire mode
maxwlen : integer range 0 to 15 := 0; -- Maximum word length
netlist : integer := 0; -- Use netlist (tech)
syncram : integer range 0 to 1 := 1; -- Use SYNCRAM for buffers
memtech : integer := 0; -- Memory technology
ft : integer range 0 to 2 := 0; -- Fault-Tolerance
scantest : integer range 0 to 1 := 0; -- Scan test support
syncrst : integer range 0 to 1 := 0; -- Use only sync reset
automask0 : integer := 0; -- Mask 0 for automated transfers
automask1 : integer := 0; -- Mask 1 for automated transfers
automask2 : integer := 0; -- Mask 2 for automated transfers
automask3 : integer := 0; -- Mask 3 for automated transfers
ignore : integer range 0 to 1 := 0; -- Ignore samples
prot : integer range 0 to 2 := 0 -- 0: Legacy, 1: dual, 2: quad
);
port (
rstn : in std_ulogic;
clk : in std_ulogic;
-- APB signals
apbi : in apb_slv_in_type;
apbo : out apb_slv_out_type;
-- SPI signals
spii : in spi_in_type;
spio : out spi_out_type;
slvsel : out std_logic_vector((slvselsz-1) downto 0)
);
end entity spictrl;
architecture rtl of spictrl is
-----------------------------------------------------------------------------
-- Constants
-----------------------------------------------------------------------------
constant SPICTRL_REV : integer := 6;
constant PCONFIG : apb_config_type := (
0 => ahb_device_reg(VENDOR_GAISLER, GAISLER_SPICTRL, 0, SPICTRL_REV, pirq),
1 => apb_iobar(paddr, pmask));
-----------------------------------------------------------------------------
-- Component
-----------------------------------------------------------------------------
component spictrlx
generic (
rev : integer := 0;
fdepth : integer range 1 to 7 := 1;
slvselen : integer range 0 to 1 := 0;
slvselsz : integer range 1 to 32 := 1;
oepol : integer range 0 to 1 := 0;
odmode : integer range 0 to 1 := 0;
automode : integer range 0 to 1 := 0;
acntbits : integer range 1 to 32 := 32;
aslvsel : integer range 0 to 1 := 0;
twen : integer range 0 to 1 := 1;
maxwlen : integer range 0 to 15 := 0;
syncram : integer range 0 to 1 := 1;
memtech : integer range 0 to NTECH := 0;
ft : integer range 0 to 2 := 0;
scantest : integer range 0 to 1 := 0;
syncrst : integer range 0 to 1 := 0;
automask0 : integer := 0;
automask1 : integer := 0;
automask2 : integer := 0;
automask3 : integer := 0;
ignore : integer range 0 to 1 := 0;
prot : integer range 0 to 2 := 0);
port (
rstn : in std_ulogic;
clk : in std_ulogic;
-- APB signals
apbi_psel : in std_ulogic;
apbi_penable : in std_ulogic;
apbi_paddr : in std_logic_vector(31 downto 0);
apbi_pwrite : in std_ulogic;
apbi_pwdata : in std_logic_vector(31 downto 0);
apbi_testen : in std_ulogic;
apbi_testrst : in std_ulogic;
apbi_scanen : in std_ulogic;
apbi_testoen : in std_ulogic;
apbo_prdata : out std_logic_vector(31 downto 0);
apbo_pirq : out std_ulogic;
-- SPI signals
spii_miso : in std_ulogic;
spii_mosi : in std_ulogic;
spii_sck : in std_ulogic;
spii_spisel : in std_ulogic;
spii_astart : in std_ulogic;
spii_cstart : in std_ulogic;
spii_ignore : in std_ulogic;
spii_io2 : in std_ulogic;
spii_io3 : in std_ulogic;
spio_miso : out std_ulogic;
spio_misooen : out std_ulogic;
spio_mosi : out std_ulogic;
spio_mosioen : out std_ulogic;
spio_sck : out std_ulogic;
spio_sckoen : out std_ulogic;
spio_enable : out std_ulogic;
spio_astart : out std_ulogic;
spio_aready : out std_ulogic;
spio_io2 : out std_ulogic;
spio_io2oen : out std_ulogic;
spio_io3 : out std_ulogic;
spio_io3oen : out std_ulogic;
slvsel : out std_logic_vector((slvselsz-1) downto 0));
end component;
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal apbo_pirq : std_ulogic;
begin
ctrl_rtl : if netlist = 0 generate
rtlc : spictrlx
generic map (
rev => SPICTRL_REV,
fdepth => fdepth,
slvselen => slvselen,
slvselsz => slvselsz,
oepol => oepol,
odmode => odmode,
automode => automode,
acntbits => acntbits,
aslvsel => aslvsel,
twen => twen,
maxwlen => maxwlen,
syncram => syncram,
memtech => memtech,
ft => ft,
scantest => scantest,
syncrst => syncrst,
automask0 => automask0,
automask1 => automask1,
automask2 => automask2,
automask3 => automask3,
ignore => ignore,
prot => prot)
port map (
rstn => rstn,
clk => clk,
-- APB signals
apbi_psel => apbi.psel(pindex),
apbi_penable => apbi.penable,
apbi_paddr => apbi.paddr,
apbi_pwrite => apbi.pwrite,
apbi_pwdata => apbi.pwdata,
apbi_testen => apbi.testen,
apbi_testrst => apbi.testrst,
apbi_scanen => apbi.scanen,
apbi_testoen => apbi.testoen,
apbo_prdata => apbo.prdata,
apbo_pirq => apbo_pirq,
-- SPI signals
spii_miso => spii.miso,
spii_mosi => spii.mosi,
spii_sck => spii.sck,
spii_spisel => spii.spisel,
spii_astart => spii.astart,
spii_cstart => spii.cstart,
spii_ignore => spii.ignore,
spii_io2 => spii.io2,
spii_io3 => spii.io3,
spio_miso => spio.miso,
spio_misooen => spio.misooen,
spio_mosi => spio.mosi,
spio_mosioen => spio.mosioen,
spio_sck => spio.sck,
spio_sckoen => spio.sckoen,
spio_enable => spio.enable,
spio_astart => spio.astart,
spio_aready => spio.aready,
spio_io2 => spio.io2,
spio_io2oen => spio.io2oen,
spio_io3 => spio.io3,
spio_io3oen => spio.io3oen,
slvsel => slvsel);
end generate ctrl_rtl;
ctrl_netlist : if netlist /= 0 generate
netlc : spictrl_net
generic map (
tech => netlist,
fdepth => fdepth,
slvselen => slvselen,
slvselsz => slvselsz,
oepol => oepol,
odmode => odmode,
automode => automode,
acntbits => acntbits,
aslvsel => aslvsel,
twen => twen,
maxwlen => maxwlen,
automask0 => automask0,
automask1 => automask1,
automask2 => automask2,
automask3 => automask3)
port map (
rstn => rstn,
clk => clk,
-- APB signals
apbi_psel => apbi.psel(pindex),
apbi_penable => apbi.penable,
apbi_paddr => apbi.paddr,
apbi_pwrite => apbi.pwrite,
apbi_pwdata => apbi.pwdata,
apbi_testen => apbi.testen,
apbi_testrst => apbi.testrst,
apbi_scanen => apbi.scanen,
apbi_testoen => apbi.testoen,
apbo_prdata => apbo.prdata,
apbo_pirq => apbo_pirq,
-- SPI signals
spii_miso => spii.miso,
spii_mosi => spii.mosi,
spii_sck => spii.sck,
spii_spisel => spii.spisel,
spii_astart => spii.astart,
spii_cstart => spii.cstart,
spio_miso => spio.miso,
spio_misooen => spio.misooen,
spio_mosi => spio.mosi,
spio_mosioen => spio.mosioen,
spio_sck => spio.sck,
spio_sckoen => spio.sckoen,
spio_enable => spio.enable,
spio_astart => spio.astart,
spio_aready => spio.aready,
slvsel => slvsel);
end generate ctrl_netlist;
irqgen : process(apbo_pirq)
variable irq : std_logic_vector(NAHBIRQ-1 downto 0);
begin
irq := (others => '0'); irq(pirq) := apbo_pirq;
apbo.pirq <= irq;
end process;
apbo.pconfig <= PCONFIG;
apbo.pindex <= pindex;
-- Boot message
-- pragma translate_off
bootmsg : report_version
generic map (
"spictrl" & tost(pindex) & ": SPI controller, rev " &
tost(SPICTRL_REV) & ", irq " & tost(pirq));
-- pragma translate_on
end architecture rtl;