Untitled
unknown
plain_text
18 days ago
11 kB
4
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 behavioural of dataConsume is --All signals declared type state_cmd is (WAIT_S, INIT, OUTPUT_STATE, INIT_START, PENDING, START_P, WAIT_START,PEAK_STAGE_1, PEAK_STAGE_2, PEAK_STAGE_3, FINISHED); signal curState : state_cmd := INIT; signal nextState : state_cmd := INIT; signal reg_numWords : integer := 0; signal reg_dataResult : CHAR_ARRAY_TYPE(0 to 5); signal dataResults_current, dataResults_next : CHAR_ARRAY_TYPE(0 to RESULT_BYTE_NUM-1); signal reg_Count : integer := 0; signal reg_Start : std_logic; signal ctrlIn_delayed, ctrlIn_detected : std_logic; signal reg_OUTPUT_STATE : std_logic; signal reg_peak : integer := 0; --signal maxIndex_current, maxIndex_next : BCD_ARRAY_TYPE(2 downto 0); --this is new to try to reduce latches, but ignore this as it caused more issues ------------------------------- -- Converts Decimal to Binary using a BCD conversion ------------------------------- function DecToBCD(input_dec : integer) return BCD_ARRAY_TYPE is variable bcd : BCD_ARRAY_TYPE(2 downto 0); begin bcd := (others => (others => '0')); -- Initialize bcd to 0 -- Convert thousands digit bcd(2) := std_logic_vector(to_unsigned(input_dec / 100, 4)); -- Convert hundreds digit bcd(1) := std_logic_vector(to_unsigned((input_dec mod 100) / 10, 4)); -- Convert tens digit bcd(0) := std_logic_vector(to_unsigned((input_dec mod 100) mod 10, 4)); return bcd; end DecToBCD; begin--This is the begin statement for the whole process ------------------------------- -- Stores the previous value of ctrlIn that is used in moving states -- Part of the two-phase handshaking protocol ------------------------------- delay_CtrlIn: process(clk) begin if rising_edge(clk) then ctrlIn_delayed <= ctrlIn; end if; end process; -- ctrlIn_detected stays 0 if the same value is detected. --It only changes to '1' when ctrlIn changes its value. ctrlIn_detected <= ctrlIn xor ctrlIn_delayed; ------------------------------- -- Where the next state is decided depending on the current state ------------------------------- combi_nextState : process(curState, reg_Start, ctrlIn_detected, reg_Count, reg_numWords) -- registers referenced begin case curState is when INIT => -- set defaults here if reg_Start = '1' then nextState <= OUTPUT_STATE; else nextState <= INIT; end if; when OUTPUT_STATE => nextState <= INIT_START; when INIT_START => if ctrlIn_detected = '1' then nextState <= PENDING; else nextState <= INIT_START; end if; when PENDING => nextState <= START_P; when START_P => if reg_Count < reg_numWords then nextState <= WAIT_START; else nextState <= PEAK_STAGE_1; end if; when PEAK_STAGE_1 => nextState <= PEAK_STAGE_2; when PEAK_STAGE_2 => nextState <= PEAK_STAGE_3; when PEAK_STAGE_3 => nextState <= FINISHED; when WAIT_START => if reg_Start = '1' then nextState <= OUTPUT_STATE; else nextState <= WAIT_START; end if; when FINISHED => nextState <= WAIT_S; when WAIT_S => nextState <= INIT; when others => nextState <= INIT; end case; end process; ------------------------------- -- Use to control the value of signal register of OUTPUT_STATE, depending on the current state -- Part of the two-phased handshake protocol. ------------------------------- combi_assignCtr : process(clk) begin if clk'event and clk ='1' then if curState = INIT then reg_OUTPUT_STATE <= '0'; elsif curState = OUTPUT_STATE then reg_OUTPUT_STATE <= not reg_OUTPUT_STATE; end if; end if; end process; ------------------------------- -- Assigns values for signals declared depending on what the current state is -- The signals are used for moving from one state to another depending on the value --Good to Go: 17/02/2025 used MUX protocol ------------------------------- combi_storeReg : process(clk) variable reg_peak : integer := 0; begin if rising_edge(clk) then case curState is when INIT => dataResults_next <= (others => (others => '0')); reg_peak := -128; maxIndex <= (others => (others => '0')); when OUTPUT_STATE => dataResults_next <= dataResults_current; when PENDING => dataResults_next(0) <= data; dataResults_next(1 to 6) <= dataResults_current(0 to 5); when START_P => if signed(dataResults_current(3)) > reg_peak then dataResults_next <= dataResults_current; maxIndex <= DecToBCD(reg_Count - 4); --bcd convert count reg_peak := to_integer(signed(dataResults_current(3))); end if; when PEAK_STAGE_1 => if signed(dataResults_current(2)) > reg_peak and reg_Count = reg_numWords then reg_peak := to_integer(signed(dataResults_current(2))); dataResults_next <= (others => (others => '0')); dataResults_next(1 to 6) <= dataResults_current(0 to 5); maxIndex <= DecToBCD(reg_Count - 3); end if; when PEAK_STAGE_2 => if signed(dataResults_current(1)) > reg_peak and reg_Count = reg_numWords then reg_peak := to_integer(signed(dataResults_current(1))); dataResults_next <= (others => (others => '0')); dataResults_next(2 to 6) <= dataResults_current(0 to 4); maxIndex <= DecToBCD(reg_Count - 2); end if; when PEAK_STAGE_3 => if signed(dataResults_current(0)) > reg_peak and reg_Count = reg_numWords then reg_peak := to_integer(signed(dataResults_current(0))); dataResults_next <= (others => (others => '0')); dataResults_next(3 to 6) <= dataResults_current(0 to 3); maxIndex <= DecToBCD(reg_Count - 2); end if; when others => null; end case; end if; end process; ------------------------------- -- Assigned values to the output signals seqDone, dataReady and byte depending on the current state ------------------------------- assign_byte : process(clk) begin if rising_edge(clk) then case curState is when FINISHED => seqDone <= '1'; dataReady <= '0'; when START_P => dataReady <= '1'; when others => seqDone <= '0'; dataReady <= '0'; end case; end if; end process; ------------------------------- -- Increases the value of the signal reg_Count or sets it to 0 depending on what the current state is ------------------------------- combi_Counter : process(clk) begin if rising_edge(clk) then if curState = INIT_START and nextState = PENDING then reg_Count <= reg_Count + 1; elsif curState = FINISHED then reg_Count <= 0; -- Reset properly end if; end if; end process; ------------------------------- -- Converts the binary in the array numWords to decimal using a BCD conversion -- Stores the output in the signal reg_numwords when in the INIT state. ------------------------------- combi_numWords_bcd : process(clk) begin if rising_edge(clk) then if curState = INIT then reg_numWords <= to_integer(unsigned(numWords_bcd(2))) * 100 + to_integer(unsigned(numWords_bcd(1))) * 10 + to_integer(unsigned(numWords_bcd(0))); elsif curState = FINISHED then reg_numWords <= 0; -- Properly reset the value end if; end if; end process; ------------------------------- -- Clock process is used to move from the current state to the next state. Causes a synchronous process -- Updates the start register with start and ctrlOut with the ctrlOut register -- Part of the two-phased handshake protocol ------------------------------- rising_edge_detection: process (clk, reset) begin if rising_edge(clk) then if reset = '1' then curState <= INIT; dataResults_current <= (others => (others => '0')); -- maxIndex_current <= (others => (others => '0'));IGNORE else curState <= nextState; reg_Start <= start; ctrlOut <= reg_OUTPUT_STATE; dataResults_current <= dataResults_next; -- maxIndex_current <= maxIndex_next; IGNORE end if; end if; end process rising_edge_detection; byte <= data; dataResults <= dataResults_current; -- maxIndex <= maxIndex_current; IGNORE end behavioural;
Editor is loading...
Leave a Comment