From 904f34f4d4f6c3f5021b0c79830cd23028782ac9 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Mon, 6 Jun 2022 16:45:16 +0200 Subject: [PATCH] vhdl: implement frame number checking --- vhdl/arty_a7.vhdl | 40 +++++++++++++++++++++------------------- vhdl/splink.vhdl | 35 ++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/vhdl/arty_a7.vhdl b/vhdl/arty_a7.vhdl index 5ca9232..e08b9cf 100644 --- a/vhdl/arty_a7.vhdl +++ b/vhdl/arty_a7.vhdl @@ -190,7 +190,8 @@ architecture a of arty_a7 is signal sys_reset : std_logic; - signal frame_done : std_logic; + signal frame_number : unsigned(31 downto 0); + signal prev_frame_number : unsigned(31 downto 0); begin leds_simple <= (others => '0'); led0 <= (others => '0'); @@ -299,27 +300,28 @@ begin pmod_d <= drivers(23 downto 16); sender: process(sys_clk) - variable frame_counter : unsigned(31 downto 0); begin - if sys_reset then - frame_counter := (others => '0'); - elsif rising_edge(sys_clk) then - if pixel_source_valid then - remote_ip_address <= pixel_source_src_ip_address; - remote_port <= pixel_source_src_port; - end if; + if rising_edge(sys_clk) then + if sys_reset then + prev_frame_number <= frame_number; + else + if pixel_source_valid then + remote_ip_address <= pixel_source_src_ip_address; + remote_port <= pixel_source_src_port; + end if; - if frame_done then - pixel_sink_length <= x"0004"; - pixel_sink_data <= std_logic_vector(frame_counter); - pixel_sink_valid <= '1'; - pixel_sink_last <= '1'; + if frame_number /= prev_frame_number then + prev_frame_number <= frame_number; - frame_counter := frame_counter + 1; - end if; + pixel_sink_length <= x"0004"; + pixel_sink_data <= std_logic_vector(frame_number); + pixel_sink_valid <= '1'; + pixel_sink_last <= '1'; + end if; - if pixel_sink_ready and pixel_sink_valid then - pixel_sink_valid <= '0'; + if pixel_sink_ready and pixel_sink_valid then + pixel_sink_valid <= '0'; + end if; end if; end if; end process; @@ -337,7 +339,7 @@ begin udp_last => pixel_source_last, udp_data => pixel_source_data, - frame_done => frame_done, + frame_number => frame_number, drivers => drivers ); diff --git a/vhdl/splink.vhdl b/vhdl/splink.vhdl index 0b5a1da..0c210ee 100644 --- a/vhdl/splink.vhdl +++ b/vhdl/splink.vhdl @@ -15,7 +15,7 @@ entity splink is udp_last : in std_logic; udp_data : in std_logic_vector(31 downto 0); - frame_done : out std_logic; + frame_number : out unsigned(31 downto 0); drivers : out std_logic_vector(NUM_STRANDS-1 downto 0) ); @@ -37,9 +37,14 @@ architecture a of splink is signal active_strand: natural range 0 to NUM_STRANDS-1; signal num_pixels: natural range 1 to MAX_STRAND_LEN; - signal frame_number: unsigned(31 downto 0); + signal current_frame: unsigned(31 downto 0); signal pixels_received: natural range 0 to MAX_STRAND_LEN-1; + signal clear_write_flags : std_logic; + + signal all_strands_written : std_logic; + signal some_strands_written : std_logic; + type receive_state_t is (FRAME_NUM, STRAND_NUM, DATA, DROP); signal receive_state : receive_state_t; begin @@ -85,7 +90,7 @@ begin end if; end if; - if frame_done then + if clear_write_flags then led_data_arr(i).was_written <= '0'; end if; end if; @@ -94,11 +99,14 @@ begin process(led_data_arr) begin - frame_done <= '1'; + all_strands_written <= '1'; + some_strands_written <= '0'; for i in 0 to NUM_STRANDS-1 loop - if not led_data_arr(i).was_written then - frame_done <= '0'; + if led_data_arr(i).was_written then + some_strands_written <= '1'; + else + all_strands_written <= '0'; end if; end loop; end process; @@ -106,8 +114,16 @@ begin fsm: process(clk) begin if rising_edge(clk) then + clear_write_flags <= '0'; + + if all_strands_written then + frame_number <= current_frame; + clear_write_flags <= '1'; + end if; + if reset then receive_state <= STRAND_NUM; + clear_write_flags <= '1'; elsif udp_valid then if udp_last then -- always resynchronize to start of packet @@ -125,7 +141,12 @@ begin receive_state <= FRAME_NUM; when FRAME_NUM => - frame_number <= unsigned(udp_data); + if not some_strands_written then + current_frame <= unsigned(udp_data); + elsif current_frame /= unsigned(udp_data) then + current_frame <= unsigned(udp_data); + clear_write_flags <= '1'; + end if; pixels_received <= 0; receive_state <= DATA;