...
-- Assumed inputs are:
Data_Recieved_From_Uart = std_ulogic that is active on the clock cycle when there is valid input from the UART
Uart_Data = std_logic_vector(7 downto 0) which is the byte of ASCII data received from the UART
...
signal Int_Accumulate natural range 0 to 9999; -- Assumes you will only have four digits. If not, then change the upper end of the range
signal Int_Out natural range 0 to 9999; -- Ditto
...
process(Clock)
begin
if rising_edge(Clock) then
Output_Valid <= '0'; -- Default unless overridden below
if (Data_Recieved_From_Uart = '1') then
if (Uart_Data = Start_Character) then -- You need to decide on a start character
Int_Accumulate <= 0;
-- You might be OK with using the ! not only as an 'end' character but to
-- also initialize for the next go round. If that's the case, then delete
-- the following statement and combine this branch with the next branch.
-- All the next statement is doing is giving you an initial value prior
-- to the very first number that comes in.
Int_Out <= 0;
elsif (Uart_Data = End_Character) then -- i.e. the "!" that you mentioned
Output_Valid <= '1';
Int_Out <= Int_Accumulate;
Int_Accumulate <= 0; -- This statement would be important if "!" does double duty as both start and end character
else
-- The following assumes the Uart data is valid...i.e. 0-9. If you want to
-- add checking so that you're not adding up invalid characters like the
-- alphabet, then add a check here
Int_Accumulate <= 10 * Int_Accumulate + unsigned(Uart_Data(3 downto 0);
end if;
end if;
end if;
end process;