------------------------------------------------------------------------------- -- Title : Top Level of SPI => WS2812b -- Project : ------------------------------------------------------------------------------- -- File : top.vhd -- Author : Mario Hüttel -- 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;