361 lines
8.9 KiB
VHDL
361 lines
8.9 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all,
|
|
ieee.numeric_std.all;
|
|
|
|
entity arty_a7 is
|
|
generic (
|
|
IS_SIMULATION : std_logic := '0'
|
|
);
|
|
port (
|
|
n_reset : in std_logic;
|
|
buttons : in std_logic_vector(3 downto 0);
|
|
switches : in std_logic_vector(3 downto 0);
|
|
leds_simple : out std_logic_vector(3 downto 0);
|
|
led0, led1, led2, led3 : out std_logic_vector(2 downto 0);
|
|
|
|
-- Pmod connectors - A+D standard, B+C high-speed.
|
|
-- Defined as inputs by default for safety, change
|
|
-- when necessary
|
|
pmod_a : in std_logic_vector(7 downto 0);
|
|
pmod_b : in std_logic_vector(7 downto 0);
|
|
pmod_c : in std_logic_vector(7 downto 0);
|
|
pmod_d : out std_logic_vector(7 downto 0);
|
|
|
|
clock_100mhz : in std_logic;
|
|
|
|
uart_rx : in std_logic;
|
|
uart_tx : out std_logic;
|
|
|
|
mii_clk_25mhz : out std_logic;
|
|
mii_n_reset : out std_logic;
|
|
mii_mdio : inout std_logic;
|
|
mii_mdc : out std_logic;
|
|
mii_rx_clk : in std_logic;
|
|
mii_rx_er : in std_logic;
|
|
mii_rx_dv : in std_logic;
|
|
mii_rx_data : in std_logic_vector(3 downto 0);
|
|
mii_tx_clk : in std_logic;
|
|
mii_tx_en : out std_logic;
|
|
mii_tx_data : out std_logic_vector(3 downto 0);
|
|
mii_col : in std_logic;
|
|
mii_crs : in std_logic;
|
|
|
|
ck_dig_l : inout std_logic_vector(13 downto 0);
|
|
ck_dig_h : inout std_logic_vector(41 downto 26)
|
|
);
|
|
end arty_a7;
|
|
|
|
architecture a of arty_a7 is
|
|
constant NUM_DRIVERS: positive := 16;
|
|
signal drivers: std_logic_vector(NUM_DRIVERS-1 downto 0);
|
|
|
|
component liteeth_core is
|
|
port (
|
|
sys_clock : in std_logic;
|
|
sys_reset : in std_logic;
|
|
|
|
mii_eth_clocks_tx : in std_logic;
|
|
mii_eth_clocks_rx : in std_logic;
|
|
mii_eth_rst_n : out std_logic;
|
|
mii_eth_mdio : inout std_logic;
|
|
mii_eth_mdc : out std_logic;
|
|
mii_eth_rx_dv : in std_logic;
|
|
mii_eth_rx_er : in std_logic;
|
|
mii_eth_rx_data : in std_logic_vector(3 downto 0);
|
|
mii_eth_tx_en : out std_logic;
|
|
mii_eth_tx_data : out std_logic_vector(3 downto 0);
|
|
mii_eth_col : in std_logic;
|
|
mii_eth_crs : in std_logic;
|
|
|
|
ip_address : in std_logic_vector(31 downto 0);
|
|
|
|
--== DHCP PORT ==--
|
|
dhcp_ip_address : in std_logic_vector(31 downto 0);
|
|
|
|
dhcp_sink_valid : in std_logic;
|
|
dhcp_sink_last : in std_logic;
|
|
dhcp_sink_ready : out std_logic;
|
|
dhcp_sink_data : in std_logic_vector(31 downto 0);
|
|
|
|
dhcp_source_valid : out std_logic;
|
|
dhcp_source_last : out std_logic;
|
|
dhcp_source_ready : in std_logic;
|
|
dhcp_source_data : out std_logic_vector(31 downto 0);
|
|
|
|
--== PIXEL DATA PORT ==--
|
|
pixel_bind_port : in std_logic_vector(15 downto 0);
|
|
|
|
-- sink
|
|
pixel_sink_dst_ip_address : in std_logic_vector(31 downto 0);
|
|
pixel_sink_dst_port : in std_logic_vector(15 downto 0);
|
|
|
|
pixel_sink_length : in std_logic_vector(15 downto 0);
|
|
pixel_sink_valid : in std_logic;
|
|
pixel_sink_last : in std_logic;
|
|
pixel_sink_last_be : in std_logic_vector(3 downto 0);
|
|
pixel_sink_ready : out std_logic;
|
|
pixel_sink_data : in std_logic_vector(31 downto 0);
|
|
|
|
-- source
|
|
pixel_source_src_ip_address : out std_logic_vector(31 downto 0);
|
|
pixel_source_src_port : out std_logic_vector(15 downto 0);
|
|
|
|
pixel_source_length : out std_logic_vector(15 downto 0);
|
|
pixel_source_valid : out std_logic;
|
|
pixel_source_last : out std_logic;
|
|
pixel_source_last_be : out std_logic_vector(3 downto 0);
|
|
pixel_source_ready : in std_logic;
|
|
pixel_source_data : out std_logic_vector(31 downto 0)
|
|
);
|
|
end component;
|
|
|
|
signal pixel_sink_length : std_logic_vector(15 downto 0);
|
|
signal pixel_sink_valid : std_logic;
|
|
signal pixel_sink_last : std_logic;
|
|
signal pixel_sink_last_be : std_logic_vector(3 downto 0);
|
|
signal pixel_sink_ready : std_logic;
|
|
signal pixel_sink_data : std_logic_vector(31 downto 0);
|
|
|
|
component PLLE2_BASE
|
|
generic (
|
|
CLKFBOUT_MULT : integer;
|
|
DIVCLK_DIVIDE : integer;
|
|
|
|
CLKIN1_PERIOD : real;
|
|
|
|
CLKOUT0_DIVIDE : integer := 0;
|
|
CLKOUT0_DUTY_CYCLE : real := 0.5;
|
|
CLKOUT0_PHASE : real := 0.0;
|
|
|
|
CLKOUT1_DIVIDE : integer := 0;
|
|
CLKOUT1_DUTY_CYCLE : real := 0.5;
|
|
CLKOUT1_PHASE : real := 0.0;
|
|
|
|
CLKOUT2_DIVIDE : integer := 0;
|
|
CLKOUT2_DUTY_CYCLE : real := 0.5;
|
|
CLKOUT2_PHASE : real := 0.0;
|
|
|
|
CLKOUT3_DIVIDE : integer := 0;
|
|
CLKOUT3_DUTY_CYCLE : real := 0.5;
|
|
CLKOUT3_PHASE : real := 0.0;
|
|
|
|
CLKOUT4_DIVIDE : integer := 0;
|
|
CLKOUT4_DUTY_CYCLE : real := 0.5;
|
|
CLKOUT4_PHASE : real := 0.0;
|
|
|
|
CLKOUT5_DIVIDE : integer := 0;
|
|
CLKOUT5_DUTY_CYCLE : real := 0.5;
|
|
CLKOUT5_PHASE : real := 0.0
|
|
);
|
|
port (
|
|
RST : in std_logic;
|
|
PWRDWN : in std_logic;
|
|
LOCKED : out std_logic;
|
|
|
|
CLKIN1 : in std_logic;
|
|
|
|
CLKFBIN : in std_logic;
|
|
CLKFBOUT : out std_logic;
|
|
|
|
CLKOUT0 : out std_logic;
|
|
CLKOUT1 : out std_logic;
|
|
CLKOUT2 : out std_logic;
|
|
CLKOUT3 : out std_logic;
|
|
CLKOUT4 : out std_logic;
|
|
CLKOUT5 : out std_logic
|
|
);
|
|
end component PLLE2_BASE;
|
|
|
|
signal pll_feedback : std_logic;
|
|
signal pll_locked : std_logic;
|
|
signal unbuf_clk_sys : std_logic;
|
|
signal clk_sys : std_logic;
|
|
|
|
component BUFG
|
|
port (
|
|
I : in std_logic;
|
|
O : out std_logic
|
|
);
|
|
end component BUFG;
|
|
|
|
signal sys_reset : std_logic;
|
|
begin
|
|
--leds_simple <= (others => '0');
|
|
led0 <= (others => '0');
|
|
led1 <= (others => '0');
|
|
led2 <= (others => '0');
|
|
led3 <= (others => '0');
|
|
|
|
uart_tx <= '0';
|
|
|
|
ck_dig_l <= (others => 'Z');
|
|
ck_dig_h <= (others => 'Z');
|
|
|
|
leds_simple <= drivers(3 downto 0);
|
|
|
|
liteeth_inst: liteeth_core port map (
|
|
sys_clock => clk_sys,
|
|
sys_reset => sys_reset,
|
|
|
|
mii_eth_clocks_tx => mii_tx_clk,
|
|
mii_eth_clocks_rx => mii_rx_clk,
|
|
mii_eth_rst_n => mii_n_reset,
|
|
mii_eth_mdio => mii_mdio,
|
|
mii_eth_mdc => mii_mdc,
|
|
mii_eth_rx_dv => mii_rx_dv,
|
|
mii_eth_rx_er => mii_rx_er,
|
|
mii_eth_rx_data => mii_rx_data,
|
|
mii_eth_tx_en => mii_tx_en,
|
|
mii_eth_tx_data => mii_tx_data,
|
|
mii_eth_col => mii_col,
|
|
mii_eth_crs => mii_crs,
|
|
|
|
ip_address => x"0a141e28", -- 10.20.30.40
|
|
|
|
dhcp_ip_address => x"0a141e29", -- 10.20.30.41
|
|
dhcp_sink_valid => '0',
|
|
dhcp_sink_last => '1',
|
|
dhcp_sink_data => x"cafebebe",
|
|
|
|
dhcp_source_ready => '1',
|
|
|
|
--== PIXEL DATA PORT ==--
|
|
pixel_bind_port => x"effd", -- port 61437 - "PIXEL"
|
|
|
|
-- sink
|
|
pixel_sink_dst_ip_address => x"0a141e29",
|
|
pixel_sink_dst_port => x"303a", -- port 12346
|
|
|
|
pixel_sink_length => pixel_sink_length,
|
|
pixel_sink_valid => pixel_sink_valid,
|
|
pixel_sink_last => pixel_sink_last,
|
|
pixel_sink_last_be => pixel_sink_last_be,
|
|
pixel_sink_ready => pixel_sink_ready,
|
|
pixel_sink_data => pixel_sink_data,
|
|
|
|
-- source
|
|
pixel_source_src_ip_address => open,
|
|
pixel_source_src_port => open,
|
|
|
|
pixel_source_length => open,
|
|
pixel_source_valid => open,
|
|
pixel_source_last => open,
|
|
pixel_source_last_be => open,
|
|
pixel_source_ready => '1',
|
|
pixel_source_data => open
|
|
);
|
|
|
|
-- 800 MHz VCO
|
|
-- 80 MHz system clock
|
|
-- 25 MHz MII clock
|
|
pll_inst: PLLE2_BASE
|
|
generic map (
|
|
CLKFBOUT_MULT => 8,
|
|
DIVCLK_DIVIDE => 1,
|
|
|
|
CLKIN1_PERIOD => 10.0,
|
|
|
|
CLKOUT0_DIVIDE => 10,
|
|
CLKOUT1_DIVIDE => 32,
|
|
CLKOUT2_DIVIDE => 10,
|
|
CLKOUT3_DIVIDE => 10,
|
|
CLKOUT4_DIVIDE => 10,
|
|
CLKOUT5_DIVIDE => 10
|
|
)
|
|
port map (
|
|
RST => '0',
|
|
PWRDWN => '0',
|
|
LOCKED => pll_locked,
|
|
|
|
CLKIN1 => clock_100mhz,
|
|
|
|
CLKFBIN => pll_feedback,
|
|
CLKFBOUT => pll_feedback,
|
|
|
|
CLKOUT0 => unbuf_clk_sys,
|
|
CLKOUT1 => mii_clk_25mhz
|
|
);
|
|
|
|
bufg_clk_sys: BUFG
|
|
port map (
|
|
I => unbuf_clk_sys,
|
|
O => clk_sys
|
|
);
|
|
|
|
sys_reset <= not pll_locked or not n_reset;
|
|
|
|
ws2812_inst: entity work.ws2812
|
|
generic map (
|
|
NUM_LEDS => 20,
|
|
COLOR_ORDER => "GRB",
|
|
T_CLK => 12.5 ns,
|
|
|
|
T0H => 0.35 us,
|
|
T0L => 0.8 us,
|
|
T1H => 0.7 us,
|
|
T1L => 0.6 us,
|
|
|
|
T_RES => 80 us
|
|
)
|
|
port map (
|
|
n_reset => not sys_reset,
|
|
clk => clk_sys,
|
|
|
|
led_addr => open,
|
|
|
|
led_red => x"ff",
|
|
led_green => x"00",
|
|
led_blue => x"ff",
|
|
|
|
dout => pmod_d(3)
|
|
);
|
|
|
|
-- https://github.com/YosysHQ/yosys/issues/3360
|
|
pmod_d(0) <= '0';
|
|
pmod_d(1) <= '0';
|
|
pmod_d(2) <= '0';
|
|
pmod_d(4) <= '0';
|
|
pmod_d(5) <= '0';
|
|
pmod_d(6) <= '0';
|
|
pmod_d(7) <= '0';
|
|
|
|
sender: process(clk_sys)
|
|
constant COUNTER_MAX: natural := 80000000;
|
|
variable counter: natural range 0 to COUNTER_MAX;
|
|
|
|
constant NUM_WORDS: natural := 10;
|
|
variable words_sent: natural range 0 to NUM_WORDS;
|
|
begin
|
|
if rising_edge(clk_sys) then
|
|
if counter = COUNTER_MAX then
|
|
pixel_sink_length <= std_logic_vector(to_unsigned(NUM_WORDS, 16));
|
|
pixel_sink_data <= std_logic_vector(to_unsigned(16#30# + words_sent, 32));
|
|
pixel_sink_valid <= '1';
|
|
|
|
pixel_sink_last <= '1' when words_sent = NUM_WORDS-1 else '0';
|
|
|
|
if words_sent = NUM_WORDS then
|
|
pixel_sink_valid <= '0';
|
|
counter := 0;
|
|
words_sent := 0;
|
|
elsif pixel_sink_ready then
|
|
words_sent := words_sent + 1;
|
|
end if;
|
|
else
|
|
counter := counter + 1;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
pixel_sink_last_be <= (pixel_sink_last, others => '0');
|
|
|
|
splink: entity work.splink
|
|
generic map (
|
|
NUM_DRIVERS => NUM_DRIVERS
|
|
)
|
|
port map (
|
|
clk => clk_sys,
|
|
reset => sys_reset,
|
|
|
|
drivers => drivers
|
|
);
|
|
end architecture;
|