Untitled
unknown
plain_text
7 months ago
16 kB
5
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