Untitled
unknown
plain_text
25 days ago
11 kB
2
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, OUTPUT_BYTE, DONE ); signal curState, nextState : fsm_state := IDLE; -- bcd to int conversion 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; -- registers signal dataReady_reg : std_logic := '0'; signal seqDone_reg : std_logic := '0'; signal byte_reg : std_logic_vector(7 downto 0) := (others => '0'); signal maxIndex_reg : BCD_ARRAY_TYPE(2 downto 0) := (others => (others => '0')); signal results_reg : CHAR_ARRAY_TYPE(0 to RESULT_BYTE_NUM - 1) := (others => (others => '0')); signal updateCounter : boolean := false; signal byte_out : boolean := false; signal detectPeak : boolean := false; -- 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; function decimal_to_bcd(input_decimal : integer) return BCD_ARRAY_TYPE is variable bcd : BCD_ARRAY_TYPE(2 downto 0); begin bcd(2) := std_logic_vector(to_unsigned(input_decimal / 100, 4)); bcd(1) := std_logic_vector(to_unsigned((input_decimal mod 100) / 10, 4)); bcd(0) := std_logic_vector(to_unsigned(input_decimal mod 10, 4)); return bcd; 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 if counter < nWords then nextState <= DATA_READY_PULSE; -- if more words avail go back else nextState <= DONE; end if; when DATA_READY_PULSE => nextState <= REQUEST_BYTE; when DONE => nextState <= IDLE; when others => nextState <= IDLE; end case; end process; ---------------------------------------------------------------------------- -- 4) Synchronous data-path updates ---------------------------------------------------------------------------- process(clk) begin if rising_edge(clk) then if reset = '1' then nWords <= 0; updateCounter <= false; peak_value <= (others => '0'); peak_index <= 0; prev_samples <= (others => (others => '0')); post_count <= 0; seqDone <= '0'; dataReady <= '0'; maxIndex_reg <= (others => (others => '0')); results_reg <= (others => (others => '0')); --? else peak_value <= (others => '0'); peak_index <= 0; prev_samples <= (others => (others => '0')); post_count <= 0; results_reg <= (others => (others => '0')); maxIndex_reg <= (others => (others => '0')); seqDone <= '0'; dataReady <= '0'; case curState is when IDLE => -- do nothing when SETUP => -- convert BCD->int nWords <= bcd_to_int(numWords_bcd); when REQUEST_BYTE => --nothing when WAIT_CTRL => --nothing when LATCH_DATA => -- read the data detectPeak <= true; updateCounter <= true; when OUTPUT_BYTE => byte_out <= true; when DATA_READY_PULSE => dataReady <= '1'; when DONE => if (counter >= nWords) then seqDone <= '1'; end if; when others => null; end case; end if; end if; end process; ----helper functions: process(clk) begin if rising_edge(clk) then if (reset = '1') then byte <= (others => '0'); elsif byte_out then byte <= data; end if; end if; end process; process(clk) begin if rising_edge(clk) then if reset = '1' then counter <= 0; elsif updateCounter then counter <= counter + 1; end if; end if; end process; process(clk) begin if rising_edge(clk) then if reset = '1' then peak_index <= 0; peak_value <= (others => '0'); prev_samples <= (others => (others => '0')); post_count <= 0; results_reg <= (others => (others => '0')); elsif detectPeak then if post_count > 0 then results_reg(post_count-1) <= data; post_count <= post_count - 1; end if; if (counter = 0) or (signed(data) > peak_value) then peak_value <= signed(data); peak_index <= counter; results_reg(6) <= std_logic_vector(prev_samples(2)); results_reg(5) <= std_logic_vector(prev_samples(1)); results_reg(4) <= std_logic_vector(prev_samples(0)); results_reg(3) <= data; results_reg(2) <= (others => '0'); results_reg(1) <= (others => '0'); results_reg(0) <= (others => '0'); post_count <= 3; end if; prev_samples(2) <= prev_samples(1); prev_samples(1) <= prev_samples(0); prev_samples(0) <= signed(data); end if; end if; end process; ---------------------------------------------------------------------------- -- 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) 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; dataResults <= results_reg; maxIndex <= decimal_to_bcd(peak_index); end architecture Behavioral;
Editor is loading...
Leave a Comment