Untitled

 avatar
unknown
plain_text
22 days ago
14 kB
3
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);
        byte_hex_list  : inout CHAR_ARRAY_TYPE(13 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"";
    
    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;
    signal rxData_reg                   : std_logic_vector(7 downto 0) := (others => '0');
    signal txData_reg                   : std_logic_vector(7 downto 0) := (others => '0');
    signal numWordsDigit                : integer range 0 to 2 := 2;
    signal numWordsDigit_state          : std_logic := '0';
    signal isNumber                     : std_logic := '0';
    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 byte_hex_list_reg            : CHAR_ARRAY_TYPE(13 downto 0);
    signal counter_reset                : std_logic;
    signal counter_state                : std_logic;
    signal seqDone_reg                  : std_logic := '0';
    signal reset_seqDone_reg            : std_logic := '0';
    signal pCounter                     : integer range 0 to 2 := 2;
    signal pCounter_reset               : std_logic;
    signal pCounter_dec               : std_logic;

begin
    
    
    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;
    
    process(clk, reset)
    begin
        if reset = '1' then
            curState      <= IDLE;
        elsif rising_edge(clk) then
            curState      <= nextState;
        end if;
    end process;
    
    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;
--                report"reaches state" & state_type'IMAGE(curState);
            end if;   
        end if; 
    end process;
    
    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;
--                report"reaches state" & state_type'IMAGE(curState);
            end if;   
        end if; 
    end process;
    
    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;

    process (seqDone_reg, dataReady, txdone, rxnow, curState, rxData, txData_reg, isNumber, numWordsDigit, numWords_reg, byte, byte_reg, dataResults_reg, maxIndex_reg, pCounter, counter)
    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
        
--------------------------------------------------------------------
			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;


            when TRANSMIT_DATA =>
            if txDone = '1' then
                if txData_reg = "01000001" or txData_reg = "01100001" then -- CMD ANNN or aNNN
                    isNumber <= '1';
                    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;
                elsif (seqDone_reg = '1' and (txData_reg = "01001100" or txData_reg = "01101100")) then -- CMD L or l
                    counter_reset <= '1';
                    nextState <= sendByteL1;
                elsif txData_reg(7 downto 4) = "0011" and isNumber = '1' then
                    numWords_reg(numWordsDigit) <= txData_reg(3 downto 0);
                    if numWordsDigit = 0 then
                        reset_seqDone_reg <= '1';
                        nextState <= cmdA_wait;
                    else
                        numWordsDigit_state <= '1';
                        nextState <= IDLE;
                    end if;
                else
                    isNumber <= '0'; 
                    nextState <= IDLE;
                end if;
            else
                nextState <= TRANSMIT_DATA;
            end if;
-------------------------------------------------------------------- CMDA

            when zeroCheck =>
                if numWords_reg = ("0000","0000","0000") then
                    nextState <= IDLE;
                else
                    nextState <= cmdA_wait;
                end if;          
            
            when cmdA_wait =>
                start <= '1';
                nextState <= cmdA_proc;

            when cmdA_proc =>
                if dataReady = '1' then
                    byte_reg <= byte;
                    nextState <= sendByte1;
                else 
                    nextState <= cmdA_proc;
                end if;

            when sendByte1 =>
                txData_reg <= hexConvert(byte_reg(7 downto 4));
                txNow <= '1';
                nextState <= wait1;

            when wait1 =>
                if txDone = '1' then
                    nextState <= sendByte2;
                else
                    nextState <= wait1;
                end if;
                    
            when sendByte2 =>
                txData_reg <= hexConvert(byte_reg(3 downto 0));
                txNow <= '1';
                nextState <= wait2;
            
            when wait2 =>
                if txDone = '1' then
                    nextState <= sendSpaceA;
                else
                    nextState <= wait2;
                end if;
                 
            when sendSpaceA =>
                txData_reg <= "00100000";
                txNow <= '1';
                nextState <= waitSpaceA;

            when waitSpaceA =>
                if txDone = '1' then
                    nextState <= checkSeqDone;
                else
                    nextState <= waitSpaceA;
                end if;
                
            when checkSeqDone =>
                 if seqDone_reg = '1' then
                    nextState <= IDLE;
                else
                    nextState <= cmdA_wait;
                end if;
-------------------------------------------------------------------- CMDP

            when sendPByte1 =>
                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 =>
                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 =>
                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;
-------------------------------------------------------------------- CMDL         

            when sendByteL1 =>
                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 =>
                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 =>
                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;
    numWords_bcd <= numWords_reg;
    txData <= txData_reg;
end arch;


Editor is loading...
Leave a Comment