171 lines
3.4 KiB
VHDL
171 lines
3.4 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
library generics;
|
|
library ip;
|
|
|
|
entity top is
|
|
port(
|
|
-- System ports
|
|
clk_hw : in std_logic; -- System clock @ F_CLK
|
|
rst_hw : in std_logic; -- Asynchronous, active low reset
|
|
|
|
-- SPI IF
|
|
spi_cs_n : in std_logic; -- SPI chip select, active low
|
|
spi_sck : in std_logic; -- SPI clock
|
|
spi_mosi : in std_logic; -- SPI data input
|
|
spi_miso : inout std_logic; -- SPI data output
|
|
|
|
-- LEDs
|
|
led_red : out std_logic;
|
|
led_green : out std_logic;
|
|
-- LCD connection
|
|
lcd_data : out std_logic_vector(3 downto 0);
|
|
lcd_clp : out std_logic;
|
|
lcd_load : out std_logic;
|
|
lcd_frp : out std_logic;
|
|
lcd_frmb : out std_logic
|
|
);
|
|
end entity top;
|
|
|
|
architecture RTL of top is
|
|
constant F_CLK : natural := 96_000_000;
|
|
|
|
signal clk : std_logic;
|
|
signal rst : std_logic;
|
|
signal pll_lock : std_logic;
|
|
|
|
signal addr_in : std_logic_vector(12 downto 0);
|
|
signal data_in : std_logic_vector(8 downto 0);
|
|
signal data_we : std_logic;
|
|
signal data_out : std_logic_vector(8 downto 0);
|
|
signal vsync : std_logic;
|
|
signal vsync_rq : std_logic;
|
|
|
|
signal spi_cs_n_sync : std_logic;
|
|
signal spi_sck_sync : std_logic;
|
|
|
|
|
|
begin
|
|
pll0_inst : entity ip.pll0
|
|
port map(
|
|
CLKI => clk_hw,
|
|
CLKOP => clk,
|
|
LOCK => pll_lock
|
|
);
|
|
|
|
rst_sync : process(clk, rst_hw, pll_lock) is
|
|
variable tmp : std_logic;
|
|
|
|
begin
|
|
if (rst_hw = '0' or pll_lock = '0') then
|
|
rst <= '1';
|
|
tmp := '1';
|
|
|
|
elsif rising_edge(clk) then
|
|
rst <= tmp;
|
|
tmp := '0';
|
|
end if;
|
|
end process rst_sync;
|
|
|
|
lmg6202_inst : entity work.lmg6202
|
|
generic map(
|
|
F_CLK => F_CLK
|
|
)
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
addr_in => addr_in,
|
|
data_in => data_in,
|
|
data_we => data_we,
|
|
data_out => data_out,
|
|
vsync_out => vsync,
|
|
vsync_in => vsync_rq,
|
|
lcd_data => lcd_data,
|
|
lcd_clp => lcd_clp,
|
|
lcd_load => lcd_load,
|
|
lcd_frp => lcd_frp,
|
|
lcd_frmb => lcd_frmb
|
|
);
|
|
|
|
spi_if_inst : entity work.spi_if
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
addr => addr_in,
|
|
data_in => data_out,
|
|
data_we => data_we,
|
|
data_out => data_in,
|
|
vsync_rq => vsync_rq,
|
|
spi_cs_n => spi_cs_n_sync,
|
|
spi_sck => spi_sck_sync,
|
|
spi_mosi => spi_mosi,
|
|
spi_miso => spi_miso
|
|
);
|
|
|
|
synchronizer0_inst : entity generics.synchronizer
|
|
generic map(
|
|
INIT => '1'
|
|
)
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
din => spi_cs_n,
|
|
dout => spi_cs_n_sync
|
|
);
|
|
|
|
synchronizer1_inst : entity generics.synchronizer
|
|
generic map(
|
|
INIT => '0'
|
|
)
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
din => spi_sck,
|
|
dout => spi_sck_sync
|
|
);
|
|
|
|
debug : process(clk, rst) is
|
|
constant CMAX : integer := F_CLK / 32;
|
|
variable cnt : integer range 0 to CMAX;
|
|
variable cnt2 : integer range 0 to CMAX;
|
|
|
|
begin
|
|
if rst = '1' then
|
|
led_red <= '1';
|
|
led_green <= '1';
|
|
|
|
cnt := CMAX;
|
|
cnt2 := CMAX;
|
|
|
|
elsif (rising_edge(clk)) then
|
|
if (cnt > 0) then
|
|
cnt := cnt - 1;
|
|
end if;
|
|
if (cnt2 > 0) then
|
|
cnt2 := cnt2 - 1;
|
|
end if;
|
|
|
|
if (data_we = '1') then -- green
|
|
cnt := CMAX;
|
|
end if;
|
|
if (vsync_rq = '1') then -- red
|
|
cnt2 := CMAX;
|
|
end if;
|
|
|
|
if (cnt = 0) then
|
|
led_green <= '1';
|
|
else
|
|
led_green <= '0';
|
|
end if;
|
|
if (cnt2 = 0) then
|
|
led_red <= '1';
|
|
else
|
|
led_red <= '0';
|
|
end if;
|
|
end if;
|
|
end process debug;
|
|
|
|
end architecture RTL;
|