From 9121ccfdbecb16979991f8bce42ae4793562465a Mon Sep 17 00:00:00 2001 From: Xiretza Date: Sun, 5 Jun 2022 21:34:31 +0200 Subject: [PATCH] vhdl: implement setting LEDs via UDP --- vhdl/arty_a7.vhdl | 36 +++++++++++++++++++++++++++-------- vhdl/splink.vhdl | 48 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/vhdl/arty_a7.vhdl b/vhdl/arty_a7.vhdl index 1a8aebd..061690a 100644 --- a/vhdl/arty_a7.vhdl +++ b/vhdl/arty_a7.vhdl @@ -116,6 +116,16 @@ architecture a of arty_a7 is signal pixel_sink_ready : std_logic; signal pixel_sink_data : std_logic_vector(31 downto 0); + signal pixel_source_src_ip_address : std_logic_vector(31 downto 0); + signal pixel_source_src_port : std_logic_vector(15 downto 0); + + signal pixel_source_length : std_logic_vector(15 downto 0); + signal pixel_source_valid : std_logic; + signal pixel_source_last : std_logic; + signal pixel_source_last_be : std_logic_vector(3 downto 0); + signal pixel_source_ready : std_logic; + signal pixel_source_data : std_logic_vector(31 downto 0); + component PLLE2_BASE generic ( CLKFBOUT_MULT : integer; @@ -232,15 +242,15 @@ begin pixel_sink_data => pixel_sink_data, -- source - pixel_source_src_ip_address => open, - pixel_source_src_port => open, + pixel_source_src_ip_address => pixel_source_src_ip_address, + pixel_source_src_port => pixel_source_src_port, - pixel_source_length => open, - pixel_source_valid => open, - pixel_source_last => open, - pixel_source_last_be => open, - pixel_source_ready => '1', - pixel_source_data => open + pixel_source_length => pixel_source_length, + pixel_source_valid => pixel_source_valid, + pixel_source_last => pixel_source_last, + pixel_source_last_be => pixel_source_last_be, + pixel_source_ready => pixel_source_ready, + pixel_source_data => pixel_source_data ); -- 800 MHz VCO @@ -323,6 +333,16 @@ begin clk => sys_clk, reset => sys_reset, + udp_src_ip_address => pixel_source_src_ip_address, + udp_src_port => pixel_source_src_port, + + udp_length => pixel_source_length, + udp_valid => pixel_source_valid, + udp_last => pixel_source_last, + udp_last_be => pixel_source_last_be, + udp_ready => pixel_source_ready, + udp_data => pixel_source_data, + drivers => drivers ); end architecture; diff --git a/vhdl/splink.vhdl b/vhdl/splink.vhdl index 5462f81..81f6e69 100644 --- a/vhdl/splink.vhdl +++ b/vhdl/splink.vhdl @@ -11,16 +11,34 @@ entity splink is clk : in std_logic; reset : in std_logic; + udp_src_ip_address : in std_logic_vector(31 downto 0); + udp_src_port : in std_logic_vector(15 downto 0); + + udp_length : in std_logic_vector(15 downto 0); + udp_valid : in std_logic; + udp_last : in std_logic; + udp_last_be : in std_logic_vector(3 downto 0); + udp_ready : out std_logic; + udp_data : in std_logic_vector(31 downto 0); + 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 => 20, + NUM_LEDS => MAX_STRAND_LEN, COLOR_ORDER => "GRB", T_CLK => 12.5 ns, @@ -35,15 +53,35 @@ begin n_reset => not reset, clk => clk, - led_addr => open, + led_addr => led_addr, - led_red => x"ff", - led_green => x"00", - led_blue => x"ff", + 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 + 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 + store_counter := 0; + elsif store_counter /= MAX_STRAND_LEN-1 then + store_counter := store_counter + 1; + end if; + end if; + end if; + end process; + + udp_ready <= '1'; end architecture;