Untitled
unknown
plain_text
a month ago
9.0 kB
3
Indexable
library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; use work.common_pack.all; entity dataConsume is port ( clk : in std_logic; reset : in std_logic; start : in std_logic; numWords_bcd: in BCD_ARRAY_TYPE(2 downto 0); ctrlIn : in std_logic; ctrlOut : out std_logic; data : in std_logic_vector(7 downto 0); dataReady : out std_logic; byte : out std_logic_vector(7 downto 0); seqDone : out std_logic; maxIndex : out BCD_ARRAY_TYPE(2 downto 0); dataResults : out CHAR_ARRAY_TYPE(0 to RESULT_BYTE_NUM-1) ); end dataConsume; architecture Behavioral of dataConsume is -- Additional or revised states, preserving your original ones. type fsm_state is ( IDLE, SETUP, REQUEST_BYTE, WAIT_CTRL, LATCH_DATA, DATA_READY_PULSE, DONE ); signal curState, nextState : fsm_state := IDLE; -- Internal signals signal nWords : integer range 0 to 999 := 0; signal counter : integer range 0 to 999 := 0; -- ctrlOut handshake signal ctrlOut_reg : std_logic := '0'; -- ctrlIn rising/falling detection signal ctrlIn_prev : std_logic := '0'; signal edgeDetect : std_logic := '0'; -- Peak detection signal peak_value : signed(7 downto 0) := (others => '0'); signal peak_index : integer range 0 to 999 := 0; -- Rolling buffer for last 3 samples type rolling_array is array (0 to 2) of signed(7 downto 0); signal prev_samples : rolling_array := (others => (others => '0')); signal post_count : integer range 0 to 3 := 0; -- BCD convert function function bcd_to_int(bcd3: BCD_ARRAY_TYPE(2 downto 0)) return integer is variable tmp : integer := 0; begin tmp := to_integer(unsigned(bcd3(2))) * 100 + to_integer(unsigned(bcd3(1))) * 10 + to_integer(unsigned(bcd3(0))); return tmp; end function; begin ---------------------------------------------------------------------------- -- 1) fsm transitions ---------------------------------------------------------------------------- process(clk, reset) begin if rising_edge(clk) then if reset = '1' then curState <= IDLE; else curState <= nextState; end if; end if; end process; ---------------------------------------------------------------------------- -- 3) Combinational FSM: next-state logic ---------------------------------------------------------------------------- process(curState, start, counter, nWords, edgeDetect) begin case curState is -------------------------------------------------------------------- when IDLE => if start = '1' then nextState <= SETUP; else nextState <= IDLE; end if; -------------------------------------------------------------------- when SETUP => -- Once BCD->int is done in sequential path, we request first byte nextState <= REQUEST_BYTE; -------------------------------------------------------------------- when REQUEST_BYTE => -- We'll do the toggling of ctrlOut in the sequential process nextState <= WAIT_CTRL; -- wait for ctrlIn to go high -------------------------------------------------------------------- when WAIT_CTRL => -- We want a rising edge: edgeDetect='1' AND ctrlIn='1' if edgeDetect = '1' then nextState <= LATCH_DATA; else nextState <= WAIT_CTRL; end if; -------------------------------------------------------------------- when LATCH_DATA => -- do your data lat when DONE => if counter < nWords then nextState <= REQUEST_BYTE; -- if more words avail go back else nextState <= DONE; end if; when others => nextState <= IDLE; end case; end process; ---------------------------------------------------------------------------- -- 4) Synchronous data-path updates ---------------------------------------------------------------------------- process(clk) variable new_sample : signed(7 downto 0); begin if rising_edge(clk) then dataReady <= '0'; seqDone <= '0'; if reset = '1' then nWords <= 0; counter <= 0; ctrlOut_reg <= '0'; peak_value <= (others => '0'); peak_index <= 0; prev_samples <= (others => (others => '0')); post_count <= 0; dataResults <= (others => (others => '0')); maxIndex <= (others => (others => '0')); else case curState is when IDLE => -- do nothing when SETUP => -- convert BCD->int nWords <= bcd_to_int(numWords_bcd); counter <= 0; peak_value <= (others => '0'); peak_index <= 0; prev_samples <= (others => (others => '0')); post_count <= 0; dataResults <= (others => (others => '0')); when LATCH_DATA => -- read the data new_sample := signed(data); if post_count > 0 then -- store next few samples dataResults(post_count-1) <= data; post_count <= post_count - 1; end if; -- Peak detection if (counter=0) or (new_sample>peak_value) then peak_value <= new_sample; peak_index <= counter; maxIndex(0) <= std_logic_vector(to_unsigned(peak_index mod 10, 4)); maxIndex(1) <= std_logic_vector(to_unsigned((peak_index / 10) mod 10, 4)); maxIndex(2) <= std_logic_vector(to_unsigned((peak_index / 100) mod 10, 4)); -- store the 3 samples before the new peak dataResults(6) <= std_logic_vector(prev_samples(2)); dataResults(5) <= std_logic_vector(prev_samples(1)); dataResults(4) <= std_logic_vector(prev_samples(0)); dataResults(3) <= data; -- new peak dataResults(2) <= (others => '0'); dataResults(1) <= (others => '0'); dataResults(0) <= (others => '0'); post_count <= 3; counter <= counter + 1; byte <= data; end if; prev_samples(2) <= prev_samples(1); prev_samples(1) <= prev_samples(0); prev_samples(0) <= new_sample; when DONE => dataReady <= '1'; if (counter >= nWords) then seqDone <= '1'; end if; when others => null; end case; end if; end if; end process; ----helper functions: ---------------------------------------------------------------------------- -- detection of ctrlIn edges ---------------------------------------------------------------------------- process(clk, ctrlIn, ctrlIn_prev) begin if rising_edge(clk) then ctrlIn_prev <= ctrlIn; end if; edgeDetect <= ctrlIn xor ctrlIn_prev; end process; process(clk, reset, ctrlOut_reg) begin if rising_edge(clk) then if reset = '1' then ctrlOut_reg <= '0'; elsif (curState = REQUEST_BYTE) then ctrlOut_reg <= not ctrlOut_reg; end if; end if ; ctrlOut <= ctrlOut_reg; end process; end architecture Behavioral;
Editor is loading...
Leave a Comment