Untitled
unknown
plain_text
18 days ago
16 kB
2
Indexable
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.common_pack.all; entity cmdProc is port ( clk : in std_logic; reset : in std_logic; rxnow : in std_logic; rxData : in std_logic_vector (7 downto 0); txData : out std_logic_vector (7 downto 0); rxdone : out std_logic; ovErr : in std_logic; framErr : in std_logic; txnow : out std_logic; txdone : in std_logic; start : out std_logic; numWords_bcd : out BCD_ARRAY_TYPE(2 downto 0); dataReady : in std_logic; byte : in std_logic_vector(7 downto 0); maxIndex : in BCD_ARRAY_TYPE(2 downto 0); dataResults : in CHAR_ARRAY_TYPE(0 to RESULT_BYTE_NUM-1); seqDone : in std_logic ); end cmdProc; architecture arch of cmdProc is -- constant A: std_logic_vector(7 downto 0) := X""; -- Convert hexadecimal to ascii function hexConvert(nibble: std_logic_vector(3 downto 0)) return std_logic_vector is begin case nibble is when "0000" => return "00110000"; -- '0' when "0001" => return "00110001"; -- '1' when "0010" => return "00110010"; -- '2' when "0011" => return "00110011"; -- '3' when "0100" => return "00110100"; -- '4' when "0101" => return "00110101"; -- '5' when "0110" => return "00110110"; -- '6' when "0111" => return "00110111"; -- '7' when "1000" => return "00111000"; -- '8' when "1001" => return "00111001"; -- '9' when "1010" => return "01100001"; -- 'a' when "1011" => return "01100010"; -- 'b' when "1100" => return "01100011"; -- 'c' when "1101" => return "01100100"; -- 'd' when "1110" => return "01100101"; -- 'e' when others => return "01100110"; -- 'f' end case; end function; type state_type is (IDLE, cmdA_proc, START_TRANSMIT, TRANSMIT_DATA, sendByte1, sendByte2, sendSpaceA, wait1, wait2, cmdA_proc_wait, waitP1, waitP2, waitP3, waitP4, waitP5, sendPByte1, sendPByte2, sendSpaceP, printPDecimal, sendByteL1, waitL1, sendByteL2, waitL2, sendSpaceL, waitL3, cmdA_Wait, checkSeqDone, waitSpaceA, zeroCheck); signal curState, nextState : state_type; signal numWords_reg : BCD_ARRAY_TYPE(2 downto 0) := (others => (others => '0')); signal counter : integer range 0 to 7 := 0; -- Index to loop through dataresults for L command signal txData_reg : std_logic_vector(7 downto 0) := (others => '0'); -- Latches used to alter the value in combinatorial logic signal numWordsDigit : integer range 0 to 2 := 2; -- Index for inputting numWords_bcd values signal numWordsDigit_state : std_logic := '0'; -- Decrease numWordsDigit by 1 signal isNumber : std_logic := '0'; -- Goes high when recieved rx byte is a valid digit signal numWordsDigit_reset : std_logic := '0'; signal byte_reg : std_logic_vector(7 downto 0); signal dataResults_reg : CHAR_ARRAY_TYPE(0 to RESULT_BYTE_NUM-1) := (others => (others => '1')); signal maxIndex_reg : BCD_ARRAY_TYPE(2 downto 0); signal counter_reset : std_logic; -- resets counter for command l signal counter_state : std_logic; -- increases counter for command l by 1 signal seqDone_reg : std_logic := '0'; signal reset_seqDone_reg : std_logic := '0'; signal pCounter : integer range 0 to 2 := 2; -- counter acting as index for p digit printing signal pCounter_reset : std_logic; -- counter signal pCounter_dec : std_logic; -- decrease the pCounter begin -- Process for capturing seqDone, dataResults, maxIndex from the data proc process(clk, reset) begin if reset='1' then seqDone_reg <= '0'; elsif rising_edge(clk) then if reset_seqDone_reg = '1' then seqDone_reg <= '0'; elsif seqDone = '1' then dataResults_reg <= dataResults; maxIndex_reg <= maxIndex; seqDone_reg <= '1'; end if; end if; end process; -- Main transition logic on rising edge of clock process(clk, reset) begin if reset = '1' then curState <= IDLE; elsif rising_edge(clk) then curState <= nextState; end if; end process; -- Processing of the indexing for numWords_reg input process(clk, reset) begin if reset = '1' then numWordsDigit <= 2; elsif rising_edge(clk) then if numWordsDigit_reset = '1' then numWordsDigit <= 2; elsif numWordsDigit_state = '1' then numWordsDigit <= numWordsDigit - 1; end if; end if; end process; -- Handling of decimal print counter for p command process(clk, reset) begin if reset = '1' then pCounter <= 2; elsif rising_edge(clk) then if pCounter_reset = '1' then pCounter <= 2; elsif pCounter_dec = '1' then pCounter <= pCounter - 1; end if; end if; end process; -- processing for counter of L command process(clk, reset) begin if reset = '1' then counter <= 0; elsif rising_edge(clk) then if counter_reset = '1' then counter <= 0; elsif counter_state = '1' then counter <= counter + 1; end if; end if; end process; -- Capture byte form data proc when data is available process(clk) begin if rising_edge(clk) then if dataReady = '1' then byte_reg <= byte; end if; end if; end process; -- Sequential process for storing the incoming digit from rx into numWords_reg process(clk, reset) begin if reset = '1' then numWords_reg <= (others => (others => '0')); -- reset to default value elsif rising_edge(clk) then if curState = TRANSMIT_DATA and txDone = '1' and txData_reg(7 downto 4) = "0011" and isNumber = '1' then numWords_reg(numWordsDigit) <= txData_reg(3 downto 0); end if; end if; end process; -- Handling of check for the number, sequential process(clk, reset) begin if reset = '1' then isNumber <= '0'; -- Reset to default value elsif rising_edge(clk) then -- Default value (maintain previous unless explicitly changed) if curState = TRANSMIT_DATA and txDone = '1' then if txData_reg = "01000001" or txData_reg = "01100001" then -- A or a isNumber <= '1'; elsif txData_reg(7 downto 4) /= "0011" then -- Not a digit isNumber <= '0'; end if; end if; end if; end process; process (seqDone_reg, dataReady, txdone, rxnow, curState, rxData, txData_reg, isNumber, numWordsDigit, -- sensitivity list byte, byte_reg, dataResults_reg, maxIndex_reg, pCounter, counter, isNumber) begin -- default values txnow <= '0'; rxdone <= '0'; start <= '0'; numWordsDigit_state <= '0'; numWordsDigit_reset <= '0'; counter_state <= '0'; counter_reset <= '0'; reset_seqDone_reg <= '0'; pCounter_dec <= '0'; pCounter_reset <= '0'; -- case curState is -------------------------------------------------------------------- Initial Phase (data echo and command pattern recogniser) when IDLE => if rxNow = '1' then nextState <= START_TRANSMIT; else nextState <= IDLE; end if; when START_TRANSMIT => txData_reg <= rxData; txNow <= '1'; rxDone <= '1'; nextState <= TRANSMIT_DATA; -- Detect command when TRANSMIT_DATA => if txDone = '1' then -- check if byte have been printed if txData_reg = "01000001" or txData_reg = "01100001" then -- CMD ANNN or aNNN numWordsDigit_reset <= '1'; nextState <= IDLE; elsif (seqDone_reg = '1' and (txData_reg = "01010000" or txData_reg = "01110000")) then -- CMD P or p pCounter_reset <= '1'; nextState <= sendPByte1; -- start p command processing elsif (seqDone_reg = '1' and (txData_reg = "01001100" or txData_reg = "01101100")) then -- CMD L or l counter_reset <= '1'; nextState <= sendByteL1; -- start l command processing elsif txData_reg(7 downto 4) = "0011" and isNumber = '1' then if numWordsDigit = 0 then reset_seqDone_reg <= '1'; nextState <= cmdA_wait; else numWordsDigit_state <= '1'; nextState <= IDLE; end if; else nextState <= IDLE; end if; else nextState <= TRANSMIT_DATA; end if; -------------------------------------------------------------------- Command A when cmdA_wait => -- send start to data proc start <= '1'; nextState <= cmdA_proc; when cmdA_proc => -- wait for having the data ready if dataReady = '1' then nextState <= sendByte1; else nextState <= cmdA_proc; end if; when sendByte1 => -- send first nibble of the byte captured from the data proc txData_reg <= hexConvert(byte_reg(7 downto 4)); txNow <= '1'; nextState <= wait1; when wait1 => -- wait for tx to finish printing if txDone = '1' then nextState <= sendByte2; else nextState <= wait1; end if; when sendByte2 => -- send the second nibble txData_reg <= hexConvert(byte_reg(3 downto 0)); txNow <= '1'; nextState <= wait2; when wait2 => -- wait for tx stop printing if txDone = '1' then nextState <= sendSpaceA; else nextState <= wait2; end if; when sendSpaceA => -- send space into the putty terminal to make the incoming bytes readable txData_reg <= "00100000"; txNow <= '1'; nextState <= waitSpaceA; when waitSpaceA => -- wait until the space is sent if txDone = '1' then nextState <= checkSeqDone; else nextState <= waitSpaceA; end if; when checkSeqDone => -- check if data has processed all requested bytes as defined in numWords_reg, if yes then echo the last byte and move back to initial step, -- if not, continue capturing and outputting the bytes from data proc if seqDone_reg = '1' then nextState <= IDLE; else nextState <= cmdA_wait; end if; -------------------------------------------------------------------- Command p when sendPByte1 => -- send the first nibble of peak value as ascii into the terminal txData_reg <= hexConvert(dataResults_reg(3)(7 downto 4)); txNow <= '1'; nextState <= waitP1; when waitP1 => if txDone = '1' then nextState <= sendPByte2; else nextState <= waitP1; end if; when sendPByte2 => -- send the second nibble of peak value as ascii into the terminal txData_reg <= hexConvert(dataResults_reg(3)(3 downto 0)); txNow <= '1'; nextState <= waitP2; when waitP2 => if txDone = '1' then nextState <= sendSpaceP; else nextState <= waitP2; end if; when sendSpaceP => txData_reg <= "00100000"; txNow <= '1'; nextState <= waitP3; when waitP3 => if txDone = '1' then nextState <= printPDecimal; else nextState <= waitP3; end if; when printPDecimal => -- loop printing the 3 decimals (maxIndex), representing the index value of the peak txData_reg <= hexConvert(maxIndex_reg(pCounter)); txNow <= '1'; if pCounter = 0 then nextState <= waitP5; else pCounter_dec <= '1'; nextState <= waitP4; end if; when waitP4 => if txDone = '1' then nextState <= printPDecimal; else nextState <= waitP4; end if; when waitP5 => if txDone = '1' then nextState <= IDLE; else nextState <= waitP5; end if; -------------------------------------------------------------------- Command L when sendByteL1 => -- print the first nibble of the current byte in dataResults reg txData_reg <= hexConvert(dataResults_reg(counter)(7 downto 4)); txNow <= '1'; nextState <= waitL1; when waitL1 => if txDone = '1' then nextState <= sendByteL2; else nextState <= waitL1; end if; when sendByteL2 => -- print second nibble txData_reg <= hexConvert(dataResults_reg(counter)(3 downto 0)); txNow <= '1'; nextState <= waitL2; when waitL2 => if txDone = '1' then nextState <= sendSpaceL; else nextState <= waitL2; end if; when sendSpaceL => txData_reg <= "00100000"; txNow <= '1'; counter_state <= '1'; nextState <= waitL3; when waitL3 => -- loop the process until all of dataResults has been printed if txDone = '1' then if counter = 7 then nextState <= IDLE; else nextState <= sendByteL1; end if; else nextState <= waitL3; end if; when others => nextState <= IDLE; end case; end process; -- direct assingments to ensure crisp and accurate assingment and timing numWords_bcd <= numWords_reg; txData <= txData_reg; end arch;
Editor is loading...
Leave a Comment