lw35-upgrade/display/fpga/design/top.vhd

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;