185 lines
5.0 KiB
VHDL
185 lines
5.0 KiB
VHDL
-------------------------------------------------------------------------------
|
|
-- Title : Top Level of SPI => WS2812b
|
|
-- Project :
|
|
-------------------------------------------------------------------------------
|
|
-- File : top.vhd
|
|
-- Author : Mario Hüttel <mario.huettel@gmx.net>
|
|
-- Company :
|
|
-- Created : 2018-04-15
|
|
-- Last update: 2018-04-15
|
|
-- Platform :
|
|
-- Standard : VHDL'93/02
|
|
-------------------------------------------------------------------------------
|
|
-- Description:
|
|
-------------------------------------------------------------------------------
|
|
-- Copyright (c) 2018 GPLv2
|
|
-------------------------------------------------------------------------------
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
entity top is
|
|
|
|
port (
|
|
clk : in std_logic;
|
|
rst_hw : in std_logic;
|
|
sck : in std_logic;
|
|
mosi : in std_logic;
|
|
cs : in std_logic;
|
|
ready : out std_logic; -- goes high when at least 10 LEDs can
|
|
-- be accepted
|
|
ws_out : out std_logic);
|
|
|
|
end entity top;
|
|
|
|
architecture RTL of top is
|
|
constant FIFO_DEPTH : positive := 20;
|
|
|
|
signal rst : std_logic;
|
|
signal fifo_empty : std_logic;
|
|
signal fifo_full : std_logic;
|
|
signal fifo_wr : std_logic;
|
|
signal fifo_rd : std_logic;
|
|
signal fifo_i : std_logic_vector(23 downto 0);
|
|
signal fifo_o : std_logic_vector(23 downto 0);
|
|
signal spi_dat_o : std_logic_vector(23 downto 0);
|
|
signal spi_dat_o_strb : std_logic;
|
|
signal fifo_fill_cnt : integer range 0 to FIFO_DEPTH;
|
|
signal ws_strb : std_logic;
|
|
signal red : unsigned(7 downto 0);
|
|
signal green : unsigned(7 downto 0);
|
|
signal blue : unsigned(7 downto 0);
|
|
signal ws_busy : std_logic;
|
|
signal fifo_inc : std_logic;
|
|
signal fifo_dec : std_logic;
|
|
signal fifo_data_req : std_logic;
|
|
signal fifo_data_avail : std_logic;
|
|
begin -- architecture RTL
|
|
|
|
reset_sync : process (clk, rst_hw) is
|
|
begin -- process reset_sync
|
|
if rst_hw = '1' then -- asynchronous reset (active high)
|
|
rst <= '1';
|
|
elsif rising_edge(clk) then -- rising clock edge
|
|
rst <= rst_hw;
|
|
end if;
|
|
end process reset_sync;
|
|
|
|
STD_FIFO_1 : entity work.STD_FIFO
|
|
generic map (
|
|
DATA_WIDTH => 24,
|
|
FIFO_DEPTH => FIFO_DEPTH) -- 20 LEDs FIFO depth
|
|
port map (
|
|
CLK => clk,
|
|
RST => rst,
|
|
WriteEn => fifo_wr,
|
|
DataIn => fifo_i,
|
|
ReadEn => fifo_rd,
|
|
DataOut => fifo_o,
|
|
Empty => fifo_empty,
|
|
Full => fifo_full);
|
|
|
|
spi_slave_1 : entity work.spi_slave
|
|
generic map (
|
|
DAT_WIDTH => 24)
|
|
port map (
|
|
clk => clk,
|
|
rst => rst,
|
|
cs => cs,
|
|
sck => sck,
|
|
miso => open,
|
|
mosi => mosi,
|
|
dat_o => spi_dat_o,
|
|
dat_i => (others => '0'),
|
|
dat_o_strb => spi_dat_o_strb,
|
|
dat_i_ack => open);
|
|
|
|
ws2812bphy_1 : entity work.ws2812bphy
|
|
generic map (
|
|
HIGH1 => 40,
|
|
LOW1 => 23,
|
|
HIGH0 => 20,
|
|
LOW0 => 43)
|
|
port map (
|
|
clk => clk,
|
|
rst => rst,
|
|
busy => ws_busy,
|
|
ws_out => ws_out,
|
|
strb => ws_strb,
|
|
red => red,
|
|
green => green,
|
|
blue => blue);
|
|
|
|
fill_cnt_proc : process (clk, rst) is
|
|
variable inc_dec : std_logic_vector(1 downto 0);
|
|
begin -- process fill_cnt_proc
|
|
if rst = '1' then -- asynchronous reset (active high)
|
|
fifo_fill_cnt <= 0;
|
|
elsif rising_edge(clk) then -- rising clock edge
|
|
inc_dec := fifo_inc & fifo_dec;
|
|
if inc_dec = "10" then
|
|
fifo_fill_cnt <= fifo_fill_cnt + 1;
|
|
elsif inc_dec = "01" then
|
|
fifo_fill_cnt <= fifo_fill_cnt -1;
|
|
end if;
|
|
end if;
|
|
end process fill_cnt_proc;
|
|
|
|
ready <= '1' when fifo_fill_cnt <= 10 else '0';
|
|
|
|
spi2fifo_proc : process (clk, rst) is
|
|
begin -- process spi2fifo_proc
|
|
if rst = '1' then -- asynchronous reset (active high)
|
|
fifo_inc <= '0';
|
|
fifo_wr <= '0';
|
|
fifo_i <= (others => '0');
|
|
elsif rising_edge(clk) then -- rising clock edge
|
|
fifo_wr <= '0';
|
|
fifo_inc <= '0';
|
|
if spi_dat_o_strb = '1' and fifo_full /= '1' then
|
|
fifo_wr <= '1';
|
|
fifo_i <= spi_dat_o;
|
|
fifo_inc <= '1';
|
|
end if;
|
|
end if;
|
|
end process spi2fifo_proc;
|
|
|
|
fifo2ws_proc : process (clk, rst) is
|
|
begin -- process fifo2ws_proc
|
|
if rst = '1' then -- asynchronous reset (active high)
|
|
fifo_rd <= '0';
|
|
fifo_dec <= '0';
|
|
ws_strb <= '0';
|
|
red <= x"00";
|
|
blue <= x"00";
|
|
green <= x"00";
|
|
fifo_data_req <= '0';
|
|
fifo_data_avail <= '0';
|
|
elsif rising_edge(clk) then -- rising clock edge
|
|
fifo_rd <= '0';
|
|
ws_strb <= '0';
|
|
fifo_dec <= '0';
|
|
-- TODO: Write following lines as statemachine
|
|
if fifo_empty = '0' and fifo_data_req = '0' and fifo_data_avail = '0' then
|
|
fifo_data_req <= '1';
|
|
fifo_rd <= '1';
|
|
fifo_dec <= '1';
|
|
end if;
|
|
if fifo_data_req = '1' then
|
|
fifo_data_avail <= '1';
|
|
fifo_data_req <= '0';
|
|
end if;
|
|
if ws_busy = '0' and ws_strb = '0' and fifo_data_avail = '1' then
|
|
red <= unsigned(fifo_o(23 downto 16));
|
|
green <= unsigned(fifo_o(15 downto 8));
|
|
blue <= unsigned(fifo_o(7 downto 0));
|
|
ws_strb <= '1';
|
|
fifo_data_avail <= '0';
|
|
end if;
|
|
end if;
|
|
end process fifo2ws_proc;
|
|
|
|
end architecture RTL;
|
|
|
|
|