library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity splink is generic ( NUM_STRANDS : positive; MAX_STRAND_LEN : positive := 256 ); port ( clk : in std_logic; reset : in std_logic; udp_valid : in std_logic; udp_last : in std_logic; udp_data : in std_logic_vector(31 downto 0); frame_done : out std_logic; drivers : out std_logic_vector(NUM_STRANDS-1 downto 0) ); end entity; architecture a of splink is signal driver_out : std_logic; constant BITS_PER_LED: natural := 24; subtype color_t is std_logic_vector(BITS_PER_LED-1 downto 0); type strand_store_t is array(0 to MAX_STRAND_LEN) of color_t; signal strand_store: strand_store_t; signal led_addr : std_logic_vector(7 downto 0); signal current_color : color_t; begin ws2812_inst: entity work.ws2812 generic map ( NUM_LEDS => MAX_STRAND_LEN, 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 reset, clk => clk, led_addr => led_addr, led_red => current_color(7 downto 0), led_green => current_color(15 downto 8), led_blue => current_color(23 downto 16), dout => driver_out ); -- https://github.com/YosysHQ/yosys/issues/3360 drivers <= (19 => driver_out, others => '0'); writer: process(clk) variable store_counter: natural range 0 to MAX_STRAND_LEN-1; begin if rising_edge(clk) then frame_done <= '0'; current_color <= strand_store(to_integer(unsigned(led_addr))); if udp_valid then strand_store(store_counter) <= udp_data(23 downto 0); if udp_last then frame_done <= '1'; store_counter := 0; elsif store_counter /= MAX_STRAND_LEN-1 then store_counter := store_counter + 1; end if; end if; end if; end process; end architecture;