-- VHDL Entity Board.morse_ebs3.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 08:06:36 08.05.2023
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY morse_ebs3 IS
    PORT( 
        RxD           : IN     std_ulogic;
        clock         : IN     std_ulogic;
        morseIn       : IN     std_uLogic;
        reset_n       : IN     std_ulogic;
        RxD_synch     : OUT    std_ulogic;
        TxD           : OUT    std_ulogic;
        morseEnvelope : OUT    std_ulogic;
        morseOut      : OUT    std_ulogic
    );

-- Declarations

END morse_ebs3 ;





-- VHDL Entity Board.inverterIn.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 13:07:14 02/19/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY inverterIn IS
    PORT( 
        in1  : IN     std_uLogic;
        out1 : OUT    std_uLogic
    );

-- Declarations

END inverterIn ;





ARCHITECTURE sim OF inverterIn IS
BEGIN

  out1 <= NOT in1;

END ARCHITECTURE sim;





-- VHDL Entity Board.DFF.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 13:07:05 02/19/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY DFF IS
    PORT( 
        CLK : IN     std_uLogic;
        CLR : IN     std_uLogic;
        D   : IN     std_uLogic;
        Q   : OUT    std_uLogic
    );

-- Declarations

END DFF ;





ARCHITECTURE sim OF DFF IS
BEGIN

  process(clk, clr)
  begin
    if clr = '1' then
      q <= '0';
    elsif rising_edge(clk) then
      q <= d;
    end if;
  end process;

END ARCHITECTURE sim;





-- VHDL Entity Morse.morseDecoder.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 09:13:01 03/29/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY morseDecoder IS
    GENERIC( 
        clockFrequency : real     := 100.0E6;
        uartBaudRate   : real     := 115.2E3;
        uartDataBitNb  : positive := 8;
        unitDuration   : real     := 100.0E-3;
        toneFrequency  : real     := 300.0;
        deglitchBitNb  : natural  := 8
    );
    PORT( 
        morseCode     : IN     std_ulogic;
        clock         : IN     std_ulogic;
        reset         : IN     std_ulogic;
        TxD           : OUT    std_ulogic;
        morseEnvelope : OUT    std_ulogic
    );

-- Declarations

END morseDecoder ;





-- VHDL Entity Memory.FIFO_bram.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 13:45:15 08/28/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY FIFO_bram IS
    GENERIC( 
        dataBitNb : positive := 8;
        depth     : positive := 8
    );
    PORT( 
        write   : IN     std_ulogic;
        clock   : IN     std_ulogic;
        reset   : IN     std_ulogic;
        dataOut : OUT    std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        read    : IN     std_ulogic;
        dataIn  : IN     std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        empty   : OUT    std_ulogic;
        full    : OUT    std_ulogic
    );

-- Declarations

END FIFO_bram ;





--------------------------------------------------------------------------------
-- Copyright 2012 HES-SO Valais Wallis (www.hevs.ch)
--------------------------------------------------------------------------------
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program IS distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License along with
-- this program. If not, see <http://www.gnu.org/licenses/>
-- -----------------------------------------------------------------------------
-- Common Lib
--
-- -----------------------------------------------------------------------------
--  Authors:
--    cof: [François Corthay](francois.corthay@hevs.ch)
--    guo: [Oliver A. Gubler](oliver.gubler@hevs.ch)
-- -----------------------------------------------------------------------------
-- Changelog:
--   2016-06 : guo
--     added function sel
--   2015-06 : guo
--     added counterBitNb
--     added documentation
-- -----------------------------------------------------------------------------
library IEEE;
  use IEEE.std_logic_1164.all;
  use IEEE.numeric_std.all;

PACKAGE CommonLib IS

  ------------------------------------------------------------------------------
  -- Returns the number of bits needed to represent the given val
  -- Examples:
  --   requiredBitNb(1) = 1   (1)
  --   requiredBitNb(2) = 2   (10)
  --   requiredBitNb(3) = 2   (11)
  function requiredBitNb(val : integer) return integer;

  ------------------------------------------------------------------------------
  -- Returns the number of bits needed to count val times (0 to val-1)
  -- Examples:
  --   counterBitNb(1) = 1    (0)
  --   counterBitNb(2) = 1    (0->1)
  --   counterBitNb(3) = 2    (0->1->10)
  function counterBitNb(val : integer) return integer;

  ------------------------------------------------------------------------------
  -- Functions to return one or the other input based on a boolean.
  -- Can be used to build conditional constants.
  -- Example:
  --   constant bonjour_c : string := sel(ptpRole = master, "fpga20", "fpga02");
  function sel(Cond : BOOLEAN; If_True, If_False : integer)
                                            return integer;
  function sel(Cond : BOOLEAN; If_True, If_False : string)
                                            return string;
  function sel(Cond : BOOLEAN; If_True, If_False : std_ulogic_vector)
                                            return std_ulogic_vector;
  function sel(Cond : BOOLEAN; If_True, If_False : unsigned)
                                            return unsigned;
  function sel(Cond : BOOLEAN; If_True, If_False : signed)
                                            return signed;

END CommonLib;




--------------------------------------------------------------------------------
-- Copyright 2012 HES-SO Valais Wallis (www.hevs.ch)
--------------------------------------------------------------------------------
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program IS distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License along with
-- this program. If not, see <http://www.gnu.org/licenses/>
-- -----------------------------------------------------------------------------
-- Often used functions
--
-- -----------------------------------------------------------------------------
--  Authors:
--    cof: [François Corthay](francois.corthay@hevs.ch)
--    guo: [Oliver A. Gubler](oliver.gubler@hevs.ch)
-- -----------------------------------------------------------------------------
-- Changelog:
--   2016-06 : guo
--     added function sel
--   2015-06 : guo
--     added counterBitNb
-- -----------------------------------------------------------------------------
PACKAGE BODY CommonLib IS

  function requiredBitNb (val : integer) return integer is
    variable powerOfTwo, bitNb : integer;
  begin
    powerOfTwo := 1;
    bitNb := 0;
    while powerOfTwo <= val loop
      powerOfTwo := 2 * powerOfTwo;
      bitNb := bitNb + 1;
    end loop;
    return bitNb;
  end requiredBitNb;

  function counterBitNb (val : integer) return integer is
    variable powerOfTwo, bitNb : integer;
  begin
    powerOfTwo := 1;
    bitNb := 0;
    while powerOfTwo < val loop
      powerOfTwo := 2 * powerOfTwo;
      bitNb := bitNb + 1;
    end loop;
    return bitNb;
  end counterBitNb;

  function sel(Cond : BOOLEAN; If_True, If_False : integer)
                                            return integer is
  begin
    if (Cond = TRUE) then
      return (If_True);
    else
      return (If_False);
    end if;
  end function sel;

  function sel(Cond : BOOLEAN; If_True, If_False : string)
                                            return string is
  begin
    if (Cond = TRUE) then
      return (If_True);
    else
      return (If_False);
    end if;
  end function sel;

  function sel(Cond : BOOLEAN; If_True, If_False : std_ulogic_vector)
                                            return std_ulogic_vector is
  begin
    if (Cond = TRUE) then
      return (If_True);
    else
      return (If_False);
    end if;
  end function sel;

  function sel(Cond : BOOLEAN; If_True, If_False : unsigned)
                                            return unsigned is
  begin
    if (Cond = TRUE) then
      return (If_True);
    else
      return (If_False);
    end if;
  end function sel;

  function sel(Cond : BOOLEAN; If_True, If_False : signed)
                                            return signed is
  begin
    if (Cond = TRUE) then
      return (If_True);
    else
      return (If_False);
    end if;
  end function sel;

END CommonLib;




-- library Common;
  use work.CommonLib.all;

architecture RTL of FIFO_bram is

  subtype register_type is std_ulogic_vector(dataIn'high downto 0);
  type memory_type is array (0 to depth-1) of register_type;

  signal writeCounter: unsigned(requiredBitNb(depth-1)-1 downto 0);
  signal readCounter: unsigned(writeCounter'range);
  signal memoryArray: memory_type;

  type fifoStateType is (
    sEmpty, sFull,
    sRead, sWrite, sWriteFirst,
    sReadWrite, sWait
  );
  signal fifoState: fifoStateType;
  signal emptyCondition, fullCondition, empty_int: std_ulogic;

begin
  ------------------------------------------------------------------------------
                                                      -- read and write counters
  updateWriteCounter: process(reset, clock)
  begin
    if reset = '1' then
      writeCounter <= (others => '0');
    elsif rising_edge(clock) then
      if (write = '1') and  (fullCondition = '0') then
        writeCounter <= writeCounter + 1;
      end if;
    end if;
  end process updateWriteCounter;

  updateReadCounter: process(reset, clock)
  begin
    if reset = '1' then
      readCounter <= (others => '0');
    elsif rising_edge(clock) then
      if (read = '1') and  (empty_int = '0') then
        readCounter <= readCounter + 1;
      end if;
    end if;
  end process updateReadCounter;

  ------------------------------------------------------------------------------
                                                                -- memory access
  writeMem: process(clock)
  begin
    if rising_edge(clock) then
      if (write = '1') and (fullCondition = '0') then
        memoryArray(to_integer(writeCounter)) <= dataIn;
      end if;
    end if;
  end process writeMem;

  readMem: process(reset, clock)
  begin
    if reset = '1' then
      dataOut <= (others => '0');
    elsif rising_edge(clock) then
      if (read = '0') or (empty_int = '1') then
        dataOut <= memoryArray(to_integer(readCounter));
      else
        dataOut <= memoryArray(to_integer(readCounter+1));
      end if;
    end if;
  end process readMem;

  ------------------------------------------------------------------------------
                                                                     -- controls
  emptyCondition <= '1' when
      ( (fifoState = sRead) and (writeCounter = readCounter) ) or
        (fifoState = sEmpty)
    else '0';

  fullCondition <= '1' when
      ( (fifoState = sWrite) and (writeCounter = readCounter) ) or
        (fifoState = sFull)
    else '0';


  fifoControl: process(reset, clock)
  begin
    if reset = '1' then
      fifoState <= sEmpty;
    elsif rising_edge(clock) then
      case fifoState is
        when sEmpty =>
          if write = '1' then
            fifoState <= sWriteFirst;
          end if;
        when sFull =>
          if (read = '1') then
            fifoState <= sRead;
          end if;
        when sRead =>
          if (read = '1') and (write = '1') then
            fifoState <= sReadWrite;
          elsif write = '1' then
            fifoState <= sWrite;
		      elsif emptyCondition = '1' then
            fifoState <= sEmpty;
          elsif read = '1' then
            fifoState <= sRead;
          else
            fifoState <= sWait;
          end if;
        when sWriteFirst =>
          if (read = '1') and (write = '1') then
            fifoState <= sReadWrite;
          elsif write = '1' then
            fifoState <= sWrite;
          elsif read = '1' then
            fifoState <= sRead;
          else
            fifoState <= sWait;
          end if;
        when sWrite =>
          if (read = '1') and (write = '1') then
            fifoState <= sReadWrite;
          elsif read = '1' then
            fifoState <= sRead;
		      elsif fullCondition = '1' then
            fifoState <= sFull;
          elsif write = '1' then
            fifoState <= sWrite;
          else
            fifoState <= sWait;
          end if;
        when sReadWrite =>
          if (read = '0') and (write = '0') then
            fifoState <= sWait;
          elsif (read = '1') and (write = '0') then
            fifoState <= sRead;
          elsif (write = '1') and (read = '0') then
            fifoState <= sWrite;
          end if;
        when sWait =>
          if (read = '1') and (write = '1') then
            fifoState <= sReadWrite;
          elsif read = '1' then
            fifoState <= sRead;
          elsif write = '1' then
            fifoState <= sWrite;
          end if;
        when others => null;
      end case;
    end if;
  end process fifoControl;
  

  full <= '1' when 
        (fifoState = sFull) or
        (fullCondition = '1')
    else '0';

  empty_int <= '1' when
        (fifoState = sEmpty) or
        (fifoState = sWriteFirst) or
        ( (emptyCondition = '1') and (fifoState = sRead) )
    else '0';
  empty <= empty_int;
  
end RTL;




-- VHDL Entity Morse.morseToCharDecoder.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 09:13:01 03/29/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY morseToCharDecoder IS
    GENERIC( 
        unitCountDivide : positive := 100;
        unitCountBitNb  : positive := 2;
        characterBitNb  : positive := 8
    );
    PORT( 
        clock          : IN     std_ulogic;
        reset          : IN     std_ulogic;
        charValid      : OUT    std_ulogic;
        symbolDuration : IN     unsigned (unitCountBitNb-1 DOWNTO 0);
        symbolValid    : IN     std_ulogic;
        symbolValue    : IN     std_ulogic;
        charOut        : OUT    std_ulogic_vector (characterBitNb-1 DOWNTO 0)
    );

-- Declarations

END morseToCharDecoder ;





ARCHITECTURE masterVersion OF morseToCharDecoder IS

  constant shortDuration : positive := 1;
  constant longDuration : positive := 3;
  constant veryLongDuration : positive := 5;
  signal isShort, isLong, isVeryLong : std_ulogic;

  type decoderStateType is (
    idle,
    atA, atB, atC, atD, atE, atF, atG, atH, atI, atJ,
    atK, atL, atM, atN, atO, atP, atQ, atR, atS, atT,
    atU, atV, atW, atX, atY, atZ,
    atO1, atO2, atU2,
    at0, at1, at2, at3, at4, at5, at6, at7, at8, at9,
    endOfCharacter, endOfWord
  );
  signal decoderState : decoderStateType;

BEGIN
                                                        -- decode symbol lengths
  isShort <= '1' when symbolDuration = shortDuration else '0';
  isLong <= '1' when symbolDuration = longDuration else '0';
  isVeryLong <= '1' when symbolDuration = veryLongDuration else '0';
                                                            -- decode Morse Code
  updateState: process(reset, clock)
  begin
    if reset = '1' then
      decoderState <= idle;
    elsif rising_edge(clock) then
      if symbolValid = '1' then
        case decoderState is
          when idle =>
            if symbolValue = '1' then
              if isShort = '1' then
                decoderState <= atE;
              else
                decoderState <= atT;
              end if;
            end if;
          when atA =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atR;
              else
                decoderState <= atW;
              end if;
            end if;
          when atB =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= at6;
              else
                decoderState <= idle;
              end if;
            end if;
          when atC =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              decoderState <= idle;
            end if;
          when atD =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atB;
              else
                decoderState <= atX;
              end if;
            end if;
          when atE =>
            if symbolValue = '0' then
              if isLong = '1' then  -- end of character
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then  -- end of word
                decoderState <= endOfWord;
              end if;
            else  -- next character symbol
              if isShort = '1' then
                decoderState <= atI;
              else
                decoderState <= atA;
              end if;
            end if;
          when atF =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              decoderState <= idle;
            end if;
          when atG =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atZ;
              else
                decoderState <= atQ;
              end if;
            end if;
          when atH =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= at5;
              else
                decoderState <= at4;
              end if;
            end if;
          when atI =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atS;
              else
                decoderState <= atU;
              end if;
            end if;
          when atJ =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= idle;
              else
                decoderState <= at1;
              end if;
            end if;
          when atK =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atC;
              else
                decoderState <= atY;
              end if;
            end if;
          when atL =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              decoderState <= idle;
            end if;
          when atM =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atG;
              else
                decoderState <= atO;
              end if;
            end if;
          when atN =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atD;
              else
                decoderState <= atK;
              end if;
            end if;
          when atO =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atO1;
              else
                decoderState <= atO2;
              end if;
            end if;
          when atO1 =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= at8;
              else
                decoderState <= idle;
              end if;
            end if;
          when atO2 =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= at9;
              else
                decoderState <= at0;
              end if;
            end if;
          when atP =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              decoderState <= idle;
            end if;
          when atQ =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              decoderState <= idle;
            end if;
          when atR =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atL;
              else
                decoderState <= idle;
              end if;
            end if;
          when atS =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atH;
              else
                decoderState <= atV;
              end if;
            end if;
          when atT =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atN;
              else
                decoderState <= atM;
              end if;
            end if;
          when atU =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atF;
              else
                decoderState <= atU2;
              end if;
            end if;
          when atU2 =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= idle;
              else
                decoderState <= at2;
              end if;
            end if;
          when atV =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= idle;
              else
                decoderState <= at3;
              end if;
            end if;
          when atW =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= atP;
              else
                decoderState <= atJ;
              end if;
            end if;
          when atX =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              decoderState <= idle;
            end if;
          when atY =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              decoderState <= idle;
            end if;
          when atZ =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              if isShort = '1' then
                decoderState <= at7;
              else
                decoderState <= idle;
              end if;
            end if;
          when at0 | at1 | at2 | at3 | at4 | at5 | at6 | at7 | at8 | at9 =>
            if symbolValue = '0' then
              if isLong = '1' then
                decoderState <= endOfCharacter;
              elsif isVeryLong = '1' then
                decoderState <= endOfWord;
              end if;
            else
              decoderState <= idle;
            end if;
          when others => null;
        end case;
      else
        case decoderState is
          when endOfCharacter => decoderState <= idle;
          when endOfWord      => decoderState <= idle;
          when others         => null;
        end case;
      end if;
    end if;
  end process updateState;
                                                            -- provide character
  provideCharacter: process(reset, clock)
    -- could be combinatorial, but made sequential for easier debug
  begin
    if reset = '1' then
      charValid <= '0';
      charOut <= (others => '0');
    elsif rising_edge(clock) then
      charValid <= '0';
      if (symbolValid = '1') and (symbolValue = '0') then
        if (isLong = '1') or (isVeryLong = '1') then
          charValid <= '1';
          case decoderState is
            when atA =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('a'), charOut'length));
            when atB =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('b'), charOut'length));
            when atC =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('c'), charOut'length));
            when atD =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('d'), charOut'length));
            when atE =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('e'), charOut'length));
            when atF =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('f'), charOut'length));
            when atG =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('g'), charOut'length));
            when atH =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('h'), charOut'length));
            when atI =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('i'), charOut'length));
            when atJ =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('j'), charOut'length));
            when atK =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('k'), charOut'length));
            when atL =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('l'), charOut'length));
            when atM =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('m'), charOut'length));
            when atN =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('n'), charOut'length));
            when atO =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('o'), charOut'length));
            when atP =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('p'), charOut'length));
            when atQ =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('q'), charOut'length));
            when atR =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('r'), charOut'length));
            when atS =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('s'), charOut'length));
            when atT =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('t'), charOut'length));
            when atU =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('u'), charOut'length));
            when atV =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('v'), charOut'length));
            when atW =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('w'), charOut'length));
            when atX =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('x'), charOut'length));
            when atY =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('y'), charOut'length));
            when atZ =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('z'), charOut'length));
            when at0 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('0'), charOut'length));
            when at1 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('1'), charOut'length));
            when at2 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('2'), charOut'length));
            when at3 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('3'), charOut'length));
            when at4 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('4'), charOut'length));
            when at5 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('5'), charOut'length));
            when at6 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('6'), charOut'length));
            when at7 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('7'), charOut'length));
            when at8 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('8'), charOut'length));
            when at9 =>
              charOut <= std_ulogic_vector(to_unsigned(character'pos('9'), charOut'length));
            when others => charOut <= (others => '-');
          end case;
        end if;
      elsif decoderState = endOfWord then
        charValid <= '1';
        charOut <= std_ulogic_vector(to_unsigned(character'pos(' '), charOut'length));
      end if;
    end if;
  end process provideCharacter;
 
END ARCHITECTURE masterVersion;




-- VHDL Entity Morse.envelopeRetreiver.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 09:13:01 03/29/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY envelopeRetreiver IS
    GENERIC( 
        toneDivide    : positive := 100E3;
        deglitchBitNb : positive := 8
    );
    PORT( 
        clock         : IN     std_ulogic;
        reset         : IN     std_ulogic;
        morseWithTone : IN     std_ulogic;
        morseEnvelope : OUT    std_ulogic
    );

-- Declarations

END envelopeRetreiver ;





-- library Common;
  use work.CommonLib.all;

ARCHITECTURE masterVersion OF envelopeRetreiver IS

  signal morseDelayed, morseRising : std_ulogic;
  constant toneCounterBitNb: positive := requiredBitNb(toneDivide-1) + 1;
  signal toneCounter, tonePeriod: unsigned(toneCounterBitNb-1 downto 0);
  constant triggerShift : positive := 3;
  constant triggerMin : positive := toneDivide - toneDivide/2**triggerShift;
  constant triggerMax : positive := toneDivide + toneDivide/2**triggerShift;
  signal morseTriggered : std_ulogic;
  signal deglitchCounter: unsigned(deglitchBitNb-1 downto 0);

BEGIN
                                                       -- find input rising edge
  delayMorseIn: process(reset, clock)
  begin
    if reset = '1' then
      morseDelayed <= '1';
    elsif rising_edge(clock) then
      morseDelayed <= morseWithTone;
    end if;
  end process delayMorseIn;

  morseRising <= '1' when (morseWithTone = '1') and (morseDelayed = '0')
    else '0';
                                              -- count period of incoming signal
  countInputPeriod: process(reset, clock)
  begin
    if reset = '1' then
      toneCounter <= (others => '0');
      tonePeriod <= (others => '0');
    elsif rising_edge(clock) then
      if morseRising = '1' then
        toneCounter <= (others => '0');
        tonePeriod <= toneCounter;
      elsif toneCounter+1 /= 0 then
        toneCounter <= toneCounter + 1;
      end if;
    end if;
  end process countInputPeriod;
                                                         -- trigger morse signal
  triggerMorse: process(tonePeriod, toneCounter)
  begin
    morseTriggered <= '1';
    if tonePeriod < triggerMin then
      morseTriggered <= '0';
    end if;
    if tonePeriod > triggerMax then
      morseTriggered <= '0';
    end if;
    if toneCounter > triggerMax then
      morseTriggered <= '0';
    end if;
  end process triggerMorse;
                                                        -- deglitch morse signal
  countDeglitchDuration: process(reset, clock)
  begin
    if reset = '1' then
      deglitchCounter <= (others => '0');
    elsif rising_edge(clock) then
      if morseTriggered = '1' then
        if deglitchCounter+1 /= 0 then
          deglitchCounter <= deglitchCounter + 1;
        end if;
      else
        if deglitchCounter /= 0 then
          deglitchCounter <= deglitchCounter - 1;
        end if;
      end if;
    end if;
  end process countDeglitchDuration;

  trigDeglitchCounter: process(reset, clock)
  begin
    if reset = '1' then
      morseEnvelope <= '0';
    elsif rising_edge(clock) then
      if deglitchCounter+1 = 0 then
        morseEnvelope <= '1';
      end if;
      if deglitchCounter = 0 then
        morseEnvelope <= '0';
      end if;
    end if;
  end process trigDeglitchCounter;

END ARCHITECTURE masterVersion;




-- VHDL Entity Morse.symbolLengthCounter.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 09:13:01 03/29/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY symbolLengthCounter IS
    GENERIC( 
        unitCountDivide : positive := 100;
        unitCountBitNb  : positive := 2
    );
    PORT( 
        clock          : IN     std_ulogic;
        reset          : IN     std_ulogic;
        morseCode      : IN     std_ulogic;
        symbolDuration : OUT    unsigned (unitCountBitNb-1 DOWNTO 0);
        symbolValid    : OUT    std_ulogic;
        symbolValue    : OUT    std_ulogic
    );

-- Declarations

END symbolLengthCounter ;





-- library Common;
  use work.CommonLib.all;

ARCHITECTURE masterVersion OF symbolLengthCounter IS

  signal morseDelayed, morseChanged : std_ulogic;
  signal unitCounter : unsigned(requiredBitNb(unitCountDivide/2-1)-1 downto 0);
  signal unitDone : std_ulogic;
  signal durationCounter : unsigned(unitCountBitNb+1-1 downto 0);
  constant shortDuration : positive := 1;
  constant longDuration : positive := 3;
  constant veryLongDuration : positive := 5;

BEGIN
                                                            -- find input change
  delayMorseCode: process(reset, clock)
  begin
    if reset = '1' then
      morseDelayed <= '1';
    elsif rising_edge(clock) then
      morseDelayed <= morseCode;
    end if;
  end process delayMorseCode;

  morseChanged <= '1' when morseDelayed /= morseCode
    else '0';
                                                     -- count half unit duration
  countHalfUnitPeriod: process(reset, clock)
  begin
    if reset = '1' then
      unitCounter <= (others => '0');
    elsif rising_edge(clock) then
      if morseChanged = '1' then
        unitCounter <= (others => '0');
      elsif unitDone = '1' then
        unitCounter <= (others => '0');
      else
        unitCounter <= unitCounter + 1;
      end if;
    end if;
  end process countHalfUnitPeriod;

  unitDone <= '1' when unitCounter = unitCountDivide/2-1
    else '0';
                                                            -- count unit number
  countUnitNumber: process(reset, clock)
  begin
    if reset = '1' then
      durationCounter <= (others => '0');
    elsif rising_edge(clock) then
      if morseChanged = '1' then
        durationCounter <= (others => '0');
      elsif unitDone = '1' then
        if durationCounter+1 /= 0 then
          durationCounter <= durationCounter + 1;
        end if;
      end if;
    end if;
  end process countUnitNumber;
                                                   -- provide symbol information
  provideSymbolInformation: process(reset, clock)
    -- could be combinatorial, but made sequential for easier debug
  begin
    if reset = '1' then
      symbolValid <= '0';
      symbolValue <= '0';
      symbolDuration <= (others => '0');
    elsif rising_edge(clock) then
      symbolValid <= '0';
      if morseChanged = '1' then
        symbolValue <= not morseCode;
        symbolValid <= '0';
        symbolDuration <= (others => '0');
        if  (durationCounter >= 2*shortDuration-1) and
            (durationCounter <= 2*shortDuration+1) then
          symbolValid <= '1';
          symbolDuration <= to_unsigned(shortDuration, symbolDuration'length);
        end if;
        if  (durationCounter >= 2*longDuration-1) and
            (durationCounter <= 2*longDuration+1) then
          symbolValid <= '1';
          symbolDuration <= to_unsigned(longDuration, symbolDuration'length);
        end if;
      end if;
      if (durationCounter = 2*veryLongDuration-1) and (unitDone = '1') then
        symbolValue <= morseCode;
        symbolValid <= '1';
        symbolDuration <= to_unsigned(
          veryLongDuration, symbolDuration'length
        );
      end if;
    end if;
  end process provideSymbolInformation;

END ARCHITECTURE masterVersion;




-- VHDL Entity RS232.serialPortTransmitter.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 13:45:48 08/28/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY serialPortTransmitter IS
    GENERIC( 
        dataBitNb      : positive := 8;
        baudRateDivide : positive := 2083
    );
    PORT( 
        TxD    : OUT    std_ulogic;
        clock  : IN     std_ulogic;
        reset  : IN     std_ulogic;
        dataIn : IN     std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        send   : IN     std_ulogic;
        busy   : OUT    std_ulogic
    );

-- Declarations

END serialPortTransmitter ;





-- library Common;
  use work.CommonLib.all;

architecture RTL of serialPortTransmitter is

  signal dividerCounter: unsigned(requiredBitNb(baudRateDivide)-1 downto 0);
  signal dividerCounterReset: std_uLogic;
  signal txData: std_ulogic_vector(dataBitNb-1 downto 0);
  signal send1: std_uLogic;
  signal txShiftEnable: std_uLogic;
  signal txShiftReg: std_ulogic_vector(dataBitNb+1 downto 0);
  signal txSendingByte: std_uLogic;
  signal txSendingByteAndStop: std_uLogic;

begin

  divide: process(reset, clock)
  begin
    if reset = '1' then
      dividerCounter <= (others => '0');
    elsif rising_edge(clock) then
      if dividerCounterReset = '1' then
        dividerCounter <= to_unsigned(1, dividerCounter'length);
      else
        dividerCounter <= dividerCounter + 1;
      end if;
    end if;
  end process divide;

  endOfCount: process(dividerCounter, send1)
  begin
    if dividerCounter = baudRateDivide then
      dividerCounterReset <= '1';
    elsif send1 = '1' then
      dividerCounterReset <= '1';
    else
      dividerCounterReset <= '0';
    end if;
  end process endOfCount;

  txShiftEnable <= dividerCounterReset;

  storeData: process(reset, clock)
  begin
    if reset = '1' then
      txData <= (others => '1');
    elsif rising_edge(clock) then
      if send = '1' then
        txData <= dataIn;
      end if;
    end if;
  end process storeData;

  delaySend: process(reset, clock)
  begin
    if reset = '1' then
      send1 <= '0';
    elsif rising_edge(clock) then
      send1 <= send;
    end if;
  end process delaySend;

  shiftReg: process(reset, clock)
  begin
    if reset = '1' then
      txShiftReg <= (others => '1');
    elsif rising_edge(clock) then
      if txShiftEnable = '1' then
        if send1 = '1' then
          txShiftReg <= '0' & txData & '0';
        else
          txShiftReg(txShiftReg'high-1 downto 0) <= txShiftReg(txShiftReg'high downto 1);
          txShiftReg(txShiftReg'high) <= '1';
        end if;
      end if;
    end if;
  end process shiftReg;

  txSendingByte <= '1' when (txShiftReg(txShiftReg'high downto 1) /= (txShiftReg'high downto 1 => '1'))
    else '0';

  txSendingByteAndStop <= '1' when txShiftReg /= (txShiftReg'high downto 0 => '1')
    else '0';

  TxD <= txShiftReg(0) when txSendingByte = '1' else '1';
  busy <= txSendingByteAndStop  or send1 or send;

end RTL;





--
-- VHDL Architecture Morse.morseDecoder.struct
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 08:02:13 08.05.2023
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

-- LIBRARY Memory;
-- LIBRARY Morse;
-- LIBRARY RS232;

ARCHITECTURE struct OF morseDecoder IS

    -- Architecture declarations
    constant unitCountBitNb: positive := 3;
    constant fifoDepth : positive := 8;

    -- Internal signal declarations
    SIGNAL symbolValue    : std_ulogic;
    SIGNAL symbolValid    : std_ulogic;
    SIGNAL symbolDuration : unsigned(unitCountBitNb-1 DOWNTO 0);
    SIGNAL charValid      : std_ulogic;
    SIGNAL charOut        : std_ulogic_vector(uartDataBitNb-1 DOWNTO 0);
    SIGNAL txWord         : std_ulogic_vector(uartDataBitNb-1 DOWNTO 0);
    SIGNAL txBusy         : std_ulogic;
    SIGNAL txSend         : std_ulogic;
    SIGNAL txFifoEmpty    : std_ulogic;

    -- Implicit buffer signal declarations
    SIGNAL morseEnvelope_internal : std_ulogic;


    -- Component Declarations
    COMPONENT FIFO_bram
    GENERIC (
        dataBitNb : positive := 8;
        depth     : positive := 8
    );
    PORT (
        write   : IN     std_ulogic ;
        clock   : IN     std_ulogic ;
        reset   : IN     std_ulogic ;
        dataOut : OUT    std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        read    : IN     std_ulogic ;
        dataIn  : IN     std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        empty   : OUT    std_ulogic ;
        full    : OUT    std_ulogic 
    );
    END COMPONENT;
    COMPONENT envelopeRetreiver
    GENERIC (
        toneDivide    : positive := 100E3;
        deglitchBitNb : positive := 8
    );
    PORT (
        clock         : IN     std_ulogic ;
        reset         : IN     std_ulogic ;
        morseWithTone : IN     std_ulogic ;
        morseEnvelope : OUT    std_ulogic 
    );
    END COMPONENT;
    COMPONENT morseToCharDecoder
    GENERIC (
        unitCountDivide : positive := 100;
        unitCountBitNb  : positive := 2;
        characterBitNb  : positive := 8
    );
    PORT (
        clock          : IN     std_ulogic ;
        reset          : IN     std_ulogic ;
        charValid      : OUT    std_ulogic ;
        symbolDuration : IN     unsigned (unitCountBitNb-1 DOWNTO 0);
        symbolValid    : IN     std_ulogic ;
        symbolValue    : IN     std_ulogic ;
        charOut        : OUT    std_ulogic_vector (characterBitNb-1 DOWNTO 0)
    );
    END COMPONENT;
    COMPONENT symbolLengthCounter
    GENERIC (
        unitCountDivide : positive := 100;
        unitCountBitNb  : positive := 2
    );
    PORT (
        clock          : IN     std_ulogic ;
        reset          : IN     std_ulogic ;
        morseCode      : IN     std_ulogic ;
        symbolDuration : OUT    unsigned (unitCountBitNb-1 DOWNTO 0);
        symbolValid    : OUT    std_ulogic ;
        symbolValue    : OUT    std_ulogic 
    );
    END COMPONENT;
    COMPONENT serialPortTransmitter
    GENERIC (
        dataBitNb      : positive := 8;
        baudRateDivide : positive := 2083
    );
    PORT (
        TxD    : OUT    std_ulogic ;
        clock  : IN     std_ulogic ;
        reset  : IN     std_ulogic ;
        dataIn : IN     std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        send   : IN     std_ulogic ;
        busy   : OUT    std_ulogic 
    );
    END COMPONENT;

    -- Optional embedded configurations
    -- pragma synthesis_off
--     FOR ALL : FIFO_bram USE ENTITY Memory.FIFO_bram;
--     FOR ALL : envelopeRetreiver USE ENTITY Morse.envelopeRetreiver;
--     FOR ALL : morseToCharDecoder USE ENTITY Morse.morseToCharDecoder;
--     FOR ALL : serialPortTransmitter USE ENTITY RS232.serialPortTransmitter;
--     FOR ALL : symbolLengthCounter USE ENTITY Morse.symbolLengthCounter;
    -- pragma synthesis_on


BEGIN
    -- Architecture concurrent statements
    -- HDL Embedded Text Block 2 eb2
    process(reset, clock)
      begin
        if reset = '1' then
          txSend <= '0';
        elsif rising_edge(clock) then
          if ( (txFifoEmpty = '0') and (txBusy = '0') ) then
            txSend <= '1';
          else
            txSend <= '0';
          end if;
        end if;
      end process;
          


    -- Instance port mappings.
    I0 : FIFO_bram
        GENERIC MAP (
            dataBitNb => uartDataBitNb,
            depth     => fifoDepth
        )
        PORT MAP (
            write   => charValid,
            clock   => clock,
            reset   => reset,
            dataOut => txWord,
            read    => txSend,
            dataIn  => charOut,
            empty   => txFifoEmpty,
            full    => OPEN
        );
    I_env : envelopeRetreiver
        GENERIC MAP (
            toneDivide    => integer(clockFrequency/toneFrequency + 0.5),
            deglitchBitNb => deglitchBitNb
        )
        PORT MAP (
            clock         => clock,
            reset         => reset,
            morseWithTone => morseCode,
            morseEnvelope => morseEnvelope_internal
        );
    I_dec : morseToCharDecoder
        GENERIC MAP (
            unitCountDivide => integer(clockFrequency*unitDuration + 0.5),
            unitCountBitNb  => unitCountBitNb,
            characterBitNb  => uartDataBitNb
        )
        PORT MAP (
            clock          => clock,
            reset          => reset,
            charValid      => charValid,
            symbolDuration => symbolDuration,
            symbolValid    => symbolValid,
            symbolValue    => symbolValue,
            charOut        => charOut
        );
    I_len : symbolLengthCounter
        GENERIC MAP (
            unitCountDivide => integer(clockFrequency*unitDuration + 0.5),
            unitCountBitNb  => unitCountBitNb
        )
        PORT MAP (
            clock          => clock,
            reset          => reset,
            morseCode      => morseEnvelope_internal,
            symbolDuration => symbolDuration,
            symbolValid    => symbolValid,
            symbolValue    => symbolValue
        );
    I_tx : serialPortTransmitter
        GENERIC MAP (
            dataBitNb      => uartDataBitNb,
            baudRateDivide => integer(clockFrequency/uartBaudRate + 0.5)
        )
        PORT MAP (
            TxD    => TxD,
            clock  => clock,
            reset  => reset,
            dataIn => txWord,
            send   => txSend,
            busy   => txBusy
        );

    -- Implicit buffered output assignments
    morseEnvelope <= morseEnvelope_internal;

END struct;




-- VHDL Entity Morse.morseEncoder.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 09:13:01 03/29/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY morseEncoder IS
    GENERIC( 
        clockFrequency : real     := 100.0E6;
        uartBaudRate   : real     := 115.2E3;
        uartDataBitNb  : positive := 8;
        unitDuration   : real     := 100.0E-3;
        toneFrequency  : real     := 300.0
    );
    PORT( 
        morseCode : OUT    std_ulogic;
        clock     : IN     std_ulogic;
        reset     : IN     std_ulogic;
        RxD       : IN     std_ulogic
    );

-- Declarations

END morseEncoder ;





-- VHDL Entity Morse.charToMorse.symbol
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 14:49:52 28.04.2023
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY charToMorse IS
    GENERIC( 
        characterBitNb  : positive := 8;
        unitCountDivide : positive := 10E3
    );
    PORT( 
        morseOut     : OUT    std_ulogic;
        clock        : IN     std_ulogic;
        reset        : IN     std_ulogic;
        charIn       : IN     std_ulogic_vector (characterBitNb-1 DOWNTO 0);
        readChar     : OUT    std_ulogic;
        charNotReady : IN     std_ulogic
    );

-- Declarations

END charToMorse ;





-- VHDL Entity Morse.unitCounter.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 09:13:01 03/29/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY unitCounter IS
    GENERIC( 
        unitCountDivide : positive := 10E3;
        unitCountBitNb  : positive := 3
    );
    PORT( 
        clock        : IN     std_ulogic;
        reset        : IN     std_ulogic;
        startCounter : IN     std_ulogic;
        unitNb       : IN     unsigned (unitCountBitNb-1 DOWNTO 0);
        done         : OUT    std_ulogic
    );

-- Declarations

END unitCounter ;





-- library Common;
  use work.CommonLib.all;

ARCHITECTURE masterVersion OF unitCounter IS

  signal unitCounter: unsigned(requiredBitNb(unitCountDivide)-1 downto 0);
  signal unitCountDone: std_ulogic;
  signal unitNbCounter: unsigned(unitnB'range);
  signal unitNbCountDone: std_ulogic;

BEGIN
                                                       -- count unit base period
  countUnitDuration: process(reset, clock)
  begin
    if reset = '1' then
      unitCounter <= (others => '0');
    elsif rising_edge(clock) then
      if unitCounter = 0 then
        if (startCounter = '1') or (unitNbCounter > 0) then
          unitCounter <= unitCounter + 1;
        end if;
      else
        if unitCountDone = '0' then
          unitCounter <= unitCounter + 1;
        else
          unitCounter <= (others => '0');
        end if;
      end if;
    end if;
  end process countUnitDuration;

  unitCountDone <= '1' when unitCounter = unitCountDivide
    else '0';
                                                     -- count unit period number
  countPeriods: process(reset, clock)
  begin
    if reset = '1' then
      unitNbCounter <= (others => '0');
    elsif rising_edge(clock) then
      if unitNbCounter = 0 then
        if startCounter = '1' then
          unitNbCounter <= unitNbCounter + 1;
        end if;
      else
        if unitNbCountDone = '0' then
          if unitCountDone = '1' then
            unitNbCounter <= unitNbCounter + 1;
          end if;
        else
          unitNbCounter <= (others => '0');
        end if;
      end if;
    end if;
  end process countPeriods;

  unitNbCountDone <= '1' when (unitNbCounter = unitNb) and (unitCountDone = '1')
    else '0';

  done <= unitNbCountDone;

END ARCHITECTURE masterVersion;




-- VHDL Entity Morse.charToMorseController.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 09:13:01 03/29/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY charToMorseController IS
    GENERIC( 
        characterBitNb : positive := 8;
        unitCountBitNb : positive := 3
    );
    PORT( 
        morseOut     : OUT    std_ulogic;
        clock        : IN     std_ulogic;
        reset        : IN     std_ulogic;
        charNotReady : IN     std_ulogic;
        char         : IN     std_ulogic_vector (characterBitNb-1 DOWNTO 0);
        startCounter : OUT    std_ulogic;
        unitNb       : OUT    unsigned (unitCountBitNb-1 DOWNTO 0);
        counterDone  : IN     std_ulogic;
        readChar     : OUT    std_ulogic
    );

-- Declarations

END charToMorseController ;





ARCHITECTURE masterVersion OF charToMorseController IS
                                                      -- sequence for characters
  type characterStateType is (
    idle, waitReg,
    sA, sB, sC, sD, sE, sF, sG, sH, sI, sJ, sK, sL, sM, sN, sO, sP,
    sQ, sR, sS, sT, sU, sV, sW, sX, sY, sZ,
    s0, s1, s2, s3, s4, s5, s6, s7, s8, s9,
    s2a, s8a, s9a,
    popChar, waitEndOfChar
  );
  signal characterState : characterStateType;
  signal isA, isB, isC, isD, isE, isF, isG, isH,
         isI, isJ, isK, isL, isM, isN, isO, isP,
         isQ, isR, isS, isT, isU, isV, isW, isX,
         isY, isZ,
         is0, is1, is2, is3, is4, is5, is6, is7,
         is8, is9 : std_ulogic;
  signal gotoE, gotoI, gotoS, gotoH, goto5,
         gotoF,
         gotoL, gotoR,
         gotoP,
         gotoN, gotoD, gotoB, goto6,
         gotoC,
         gotoG, gotoZ, goto7,
         goto8,
         goto9,
         gotoT : std_ulogic;
                                                         -- inter-FSM signalling
  signal sendDot, sendDash, sendSeparator, sendDotDashDone: std_ulogic;
                                                     -- sequence for morse units
  type sequencerStateType is (
    idle,
    startDot, sendingDot, startDash, sendingDash,
    startSeparator, waitingSeparator, startSeparator2, waitingSeparator2,
    dotDashDone
  );
  signal sequencerState : sequencerStateType;

BEGIN
  ------------------------------------------------------------------------------
                                                   -- conditions for morse units
  isA <= '1' when std_match(unsigned(char), "1-0" & x"1") else '0';
  isB <= '1' when std_match(unsigned(char), "1-0" & x"2") else '0';
  isC <= '1' when std_match(unsigned(char), "1-0" & x"3") else '0';
  isD <= '1' when std_match(unsigned(char), "1-0" & x"4") else '0';
  isE <= '1' when std_match(unsigned(char), "1-0" & x"5") else '0';
  isF <= '1' when std_match(unsigned(char), "1-0" & x"6") else '0';
  isG <= '1' when std_match(unsigned(char), "1-0" & x"7") else '0';
  isH <= '1' when std_match(unsigned(char), "1-0" & x"8") else '0';
  isI <= '1' when std_match(unsigned(char), "1-0" & x"9") else '0';
  isJ <= '1' when std_match(unsigned(char), "1-0" & x"A") else '0';
  isK <= '1' when std_match(unsigned(char), "1-0" & x"B") else '0';
  isL <= '1' when std_match(unsigned(char), "1-0" & x"C") else '0';
  isM <= '1' when std_match(unsigned(char), "1-0" & x"D") else '0';
  isN <= '1' when std_match(unsigned(char), "1-0" & x"E") else '0';
  isO <= '1' when std_match(unsigned(char), "1-0" & x"F") else '0';
  isP <= '1' when std_match(unsigned(char), "1-1" & x"0") else '0';
  isQ <= '1' when std_match(unsigned(char), "1-1" & x"1") else '0';
  isR <= '1' when std_match(unsigned(char), "1-1" & x"2") else '0';
  isS <= '1' when std_match(unsigned(char), "1-1" & x"3") else '0';
  isT <= '1' when std_match(unsigned(char), "1-1" & x"4") else '0';
  isU <= '1' when std_match(unsigned(char), "1-1" & x"5") else '0';
  isV <= '1' when std_match(unsigned(char), "1-1" & x"6") else '0';
  isW <= '1' when std_match(unsigned(char), "1-1" & x"7") else '0';
  isX <= '1' when std_match(unsigned(char), "1-1" & x"8") else '0';
  isY <= '1' when std_match(unsigned(char), "1-1" & x"9") else '0';
  isZ <= '1' when std_match(unsigned(char), "1-1" & x"A") else '0';
  is0 <= '1' when std_match(unsigned(char), "011" & x"0") else '0';
  is1 <= '1' when std_match(unsigned(char), "011" & x"1") else '0';
  is2 <= '1' when std_match(unsigned(char), "011" & x"2") else '0';
  is3 <= '1' when std_match(unsigned(char), "011" & x"3") else '0';
  is4 <= '1' when std_match(unsigned(char), "011" & x"4") else '0';
  is5 <= '1' when std_match(unsigned(char), "011" & x"5") else '0';
  is6 <= '1' when std_match(unsigned(char), "011" & x"6") else '0';
  is7 <= '1' when std_match(unsigned(char), "011" & x"7") else '0';
  is8 <= '1' when std_match(unsigned(char), "011" & x"8") else '0';
  is9 <= '1' when std_match(unsigned(char), "011" & x"9") else '0';
  goto5 <= is5;
  gotoH <= ish or goto5 or is4;
  gotoS <= isS or gotoH or isV or is3;
  gotoF <= isF;
  gotoI <= isI or gotoS or isU or gotoF or is2;
  gotoL <= isL;
  gotoR <= isR or gotoL;
  gotoP <= isP;
  gotoE <= isE or gotoI or isA or gotoR or isW or gotoP or isJ or is1;
  goto6 <= is6;
  gotoB <= isB or goto6;
  gotoD <= isD or gotoB or isX;
  gotoC <= isC;
  gotoN <= isN or gotoD or isK or gotoC or isY;
  goto7 <= is7;
  gotoZ <= isZ or goto7;
  gotoG <= isG or gotoZ or isQ;
  goto8 <= is8;
  goto9 <= is9;
  gotoT <= isT or gotoN or isM or gotoG or isO or goto8 or goto9 or is0;
                                                     -- sequence for morse units
  sendCharacterState: process(reset, clock)
  begin
    if reset = '1' then
      characterState <= idle;
    elsif rising_edge(clock) then
      case characterState is
                                                                        -- start
        when idle =>
          if charnotReady = '0' then
            characterState <= waitReg;
          end if;
        when waitReg =>
          if gotoE = '1' then
            characterState <= sE;
          elsif gotoT = '1' then
            characterState <= sT;
          else
            characterState <= popChar;
          end if;
                                                                      -- level 1
        when sE =>
          if sendDotDashDone = '1' then
            if isE = '1' then
              characterState <= popChar;
            elsif gotoI = '1' then
              characterState <= sI;
            else
              characterState <= sA;
            end if;
          end if;
        when sT =>
          if sendDotDashDone = '1' then
            if isT = '1' then
              characterState <= popChar;
            elsif gotoN = '1' then
              characterState <= sN;
            else
              characterState <= sM;
            end if;
          end if;
                                                                      -- level 2
        when sI =>
          if sendDotDashDone = '1' then
            if isI = '1' then
              characterState <= popChar;
            elsif gotoS = '1' then
              characterState <= sS;
            else
              characterState <= sU;
            end if;
          end if;
        when sA =>
          if sendDotDashDone = '1' then
            if isA = '1' then
              characterState <= popChar;
            elsif gotoR = '1' then
              characterState <= sR;
            else
              characterState <= sW;
            end if;
          end if;
        when sN =>
          if sendDotDashDone = '1' then
            if isN = '1' then
              characterState <= popChar;
            elsif gotoD = '1' then
              characterState <= sD;
            else
              characterState <= sK;
            end if;
          end if;
        when sM =>
          if sendDotDashDone = '1' then
            if isM = '1' then
              characterState <= popChar;
            elsif gotoG = '1' then
              characterState <= sG;
            else
              characterState <= sO;
            end if;
          end if;
                                                                     -- level 3a
        when sS =>
          if sendDotDashDone = '1' then
            if isS = '1' then
              characterState <= popChar;
            elsif gotoH = '1' then
              characterState <= sH;
            else
              characterState <= sV;
            end if;
          end if;
        when sU =>
          if sendDotDashDone = '1' then
            if isU = '1' then
              characterState <= popChar;
            elsif gotoF = '1' then
              characterState <= sF;
            else
              characterState <= s2a;
            end if;
          end if;
        when sR =>
          if sendDotDashDone = '1' then
            if isR = '1' then
              characterState <= popChar;
            elsif gotoL = '1' then
              characterState <= sL;
            else
              characterState <= popChar;
            end if;
          end if;
        when sW =>
          if sendDotDashDone = '1' then
            if isW = '1' then
              characterState <= popChar;
            elsif gotoP = '1' then
              characterState <= sP;
            else
              characterState <= sJ;
            end if;
          end if;
                                                                     -- level 3b
        when sD =>
          if sendDotDashDone = '1' then
            if isD = '1' then
              characterState <= popChar;
            elsif gotoB = '1' then
              characterState <= sB;
            else
              characterState <= sX;
            end if;
          end if;
        when sK =>
          if sendDotDashDone = '1' then
            if isK = '1' then
              characterState <= popChar;
            elsif gotoC = '1' then
              characterState <= sC;
            else
              characterState <= sY;
            end if;
          end if;
        when sG =>
          if sendDotDashDone = '1' then
            if isG = '1' then
              characterState <= popChar;
            elsif gotoZ = '1' then
              characterState <= sZ;
            else
              characterState <= sQ;
            end if;
          end if;
        when sO =>
          if sendDotDashDone = '1' then
            if isO = '1' then
              characterState <= popChar;
            elsif goto8 = '1' then
              characterState <= s8a;
            else
              characterState <= s9a;
            end if;
          end if;
                                                                     -- level 4a
        when sH =>
          if sendDotDashDone = '1' then
            if isH = '1' then
              characterState <= popChar;
            elsif goto5 = '1' then
              characterState <= s5;
            else
              characterState <= s4;
            end if;
          end if;
        when sV =>
          if sendDotDashDone = '1' then
            if isV = '1' then
              characterState <= popChar;
            else
              characterState <= s3;
            end if;
          end if;
        when sF =>
          if sendDotDashDone = '1' then
            characterState <= popChar;
          end if;
        when s2a =>
          if sendDotDashDone = '1' then
            characterState <= s2;
          end if;
                                                                     -- level 4b
        when sL =>
          if sendDotDashDone = '1' then
            characterState <= popChar;
          end if;
        when sP =>
          if sendDotDashDone = '1' then
            characterState <= popChar;
          end if;
        when sJ =>
          if sendDotDashDone = '1' then
            if isJ = '1' then
              characterState <= popChar;
            else
              characterState <= s1;
            end if;
          end if;
                                                                     -- level 4c
        when sB =>
          if sendDotDashDone = '1' then
            if isB = '1' then
              characterState <= popChar;
            elsif goto6 = '1' then
              characterState <= s6;
            else
              characterState <= popChar;
            end if;
          end if;
        when sX =>
          if sendDotDashDone = '1' then
            characterState <= popChar;
          end if;
        when sC =>
          if sendDotDashDone = '1' then
            characterState <= popChar;
          end if;
        when sY =>
          if sendDotDashDone = '1' then
            characterState <= popChar;
          end if;
                                                                     -- level 4d
        when sZ =>
          if sendDotDashDone = '1' then
            if isZ = '1' then
              characterState <= popChar;
            elsif goto7 = '1' then
              characterState <= s7;
            else
              characterState <= popChar;
            end if;
          end if;
        when sQ =>
          if sendDotDashDone = '1' then
            characterState <= popChar;
          end if;
        when s8a =>
          if sendDotDashDone = '1' then
            characterState <= s8;
          end if;
        when s9a =>
          if sendDotDashDone = '1' then
            if goto9 = '1' then
              characterState <= s9;
            else
              characterState <= s0;
            end if;
          end if;
                                                                      -- level 5
        when s5 | s4 | s3 | s2 | s1 | s6 | s7 | s8 | s9 | s0 =>
          if sendDotDashDone = '1' then
            characterState <= popChar;
          end if;
                                                             -- end of character
        when popChar => characterState <= waitEndOfChar;
        when waitEndOfChar =>
          if sendDotDashDone = '1' then
            characterState <= idle;
          end if;
        when others => characterState <= idle;
      end case;
    end if;
  end process sendCharacterState;

  sendCharacterOutput: process(characterState)
  begin
    sendDot <= '0';
    sendDash <= '0';
    sendSeparator <= '0';
    readChar <= '0';
    case characterState is
                                                                      -- level 1
      when sE =>
        sendDot <= '1';
      when sT =>
        sendDash <= '1';
                                                                      -- level 2
      when sI =>
        sendDot <= '1';
      when sA =>
        sendDash <= '1';
      when sN =>
        sendDot <= '1';
      when sM =>
        sendDash <= '1';
                                                                     -- level 3a
      when sS =>
        sendDot <= '1';
      when sU =>
        sendDash <= '1';
      when sR =>
        sendDot <= '1';
      when sW =>
        sendDash <= '1';
                                                                     -- level 3b
      when sD =>
        sendDot <= '1';
      when sK =>
        sendDash <= '1';
      when sG =>
        sendDot <= '1';
      when sO =>
        sendDash <= '1';
                                                                     -- level 4a
      when sH =>
        sendDot <= '1';
      when sV =>
        sendDash <= '1';
      when sF =>
        sendDot <= '1';
      when s2a =>
        sendDash <= '1';
                                                                     -- level 4b
      when sL =>
        sendDot <= '1';
      when sP =>
        sendDot <= '1';
      when sJ =>
        sendDash <= '1';
                                                                     -- level 4c
      when sB =>
        sendDot <= '1';
      when sX =>
        sendDash <= '1';
      when sC =>
        sendDot <= '1';
      when sY =>
        sendDash <= '1';
                                                                     -- level 4d
      when sZ =>
        sendDot <= '1';
      when sQ =>
        sendDash <= '1';
      when s8a =>
        sendDot <= '1';
      when s9a =>
        sendDash <= '1';
                                                                      -- level 5
      when s5 =>
        sendDot <= '1';
      when s4 =>
        sendDash <= '1';
      when s3 =>
        sendDash <= '1';
      when s2 =>
        sendDash <= '1';
      when s1 =>
        sendDash <= '1';
      when s6 =>
        sendDot <= '1';
      when s7 =>
        sendDot <= '1';
      when s8 =>
        sendDot <= '1';
      when s9 =>
        sendDot <= '1';
      when s0 =>
        sendDash <= '1';
                                                             -- end of character
      when popChar =>
        readChar <= '1';
        sendSeparator <= '1';
      when others => null;
    end case;
  end process sendCharacterOutput;

  ------------------------------------------------------------------------------
                                                     -- sequence for morse units
  sendDotDashState: process(reset, clock)
  begin
    if reset = '1' then
      sequencerState <= idle;
    elsif rising_edge(clock) then
      case sequencerState is
                                                                         -- idle
        when idle =>
          if sendDot = '1' then
            sequencerState <= startDot;
          elsif sendDash = '1' then
            sequencerState <= startDash;
          elsif sendSeparator = '1' then
            sequencerState <= startSeparator2;
          end if;
                                                                          -- dot
        when startDot =>
          sequencerState <= sendingDot;
        when sendingDot =>
          if counterDone = '1' then
            sequencerState <= startSeparator;
          end if;
                                                                         -- dash
        when startDash =>
          sequencerState <= sendingDash;
        when sendingDash =>
          if counterDone = '1' then
            sequencerState <= startSeparator;
          end if;
                                                       -- morse symbol separator
        when startSeparator =>
          sequencerState <= waitingSeparator;
        when waitingSeparator =>
          if counterDone = '1' then
            sequencerState <= dotDashDone;
          end if;
                                                          -- character separator
        when startSeparator2 =>
          sequencerState <= waitingSeparator2;
        when waitingSeparator2 =>
          if counterDone = '1' then
            sequencerState <= dotDashDone;
          end if;
                                                                         -- done
        when dotDashDone =>
          sequencerState <= idle;
      end case;
    end if;
  end process sendDotDashState;

  sendDotDashOutput: process(sequencerState)
  begin
    startCounter <= '0';
    unitNb <= (others => '-');
    sendDotDashDone <= '0';
    morseOut <= '0';
    case sequencerState is
      when startDot | startDash =>
        startCounter <= '1';
        morseOut <= '1';
      when sendingDot =>
        morseOut <= '1';
        unitNb <= to_unsigned(1, unitNb'length);
      when sendingDash =>
        morseOut <= '1';
        unitNb <= to_unsigned(3, unitNb'length);
      when startSeparator =>
        startCounter <= '1';
      when waitingSeparator =>
        unitNb <= to_unsigned(1, unitNb'length);
      when startSeparator2 =>
        startCounter <= '1';
      when waitingSeparator2 =>
        unitNb <= to_unsigned(2, unitNb'length);
      when dotDashDone =>
        sendDotDashDone <= '1';
      when others => null;
    end case;
  end process sendDotDashOutput;

END ARCHITECTURE masterVersion;




--
-- VHDL Architecture Morse.charToMorse.struct
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 14:49:52 28.04.2023
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

-- LIBRARY Morse;

ARCHITECTURE struct OF charToMorse IS

    -- Architecture declarations
    constant unitCountBitNb: positive := 3;

    -- Internal signal declarations
    SIGNAL startCounter : std_ulogic;
    SIGNAL done         : std_ulogic;
    SIGNAL unitNb       : unsigned(unitCountBitNb-1 DOWNTO 0);


    -- Component Declarations
    COMPONENT charToMorseController
    GENERIC (
        characterBitNb : positive := 8;
        unitCountBitNb : positive := 3
    );
    PORT (
        morseOut     : OUT    std_ulogic ;
        clock        : IN     std_ulogic ;
        reset        : IN     std_ulogic ;
        charNotReady : IN     std_ulogic ;
        char         : IN     std_ulogic_vector (characterBitNb-1 DOWNTO 0);
        startCounter : OUT    std_ulogic ;
        unitNb       : OUT    unsigned (unitCountBitNb-1 DOWNTO 0);
        counterDone  : IN     std_ulogic ;
        readChar     : OUT    std_ulogic 
    );
    END COMPONENT;
    COMPONENT unitCounter
    GENERIC (
        unitCountDivide : positive := 10E3;
        unitCountBitNb  : positive := 3
    );
    PORT (
        clock        : IN     std_ulogic ;
        reset        : IN     std_ulogic ;
        startCounter : IN     std_ulogic ;
        unitNb       : IN     unsigned (unitCountBitNb-1 DOWNTO 0);
        done         : OUT    std_ulogic 
    );
    END COMPONENT;

    -- Optional embedded configurations
    -- pragma synthesis_off
--     FOR ALL : charToMorseController USE ENTITY Morse.charToMorseController;
--     FOR ALL : unitCounter USE ENTITY Morse.unitCounter;
    -- pragma synthesis_on


BEGIN

    -- Instance port mappings.
    I_ctl : charToMorseController
        GENERIC MAP (
            characterBitNb => characterBitNb,
            unitCountBitNb => unitCountBitNb
        )
        PORT MAP (
            morseOut     => morseOut,
            clock        => clock,
            reset        => reset,
            charNotReady => charNotReady,
            char         => charIn,
            startCounter => startCounter,
            unitNb       => unitNb,
            counterDone  => done,
            readChar     => readChar
        );
    I_cnt : unitCounter
        GENERIC MAP (
            unitCountDivide => unitCountDivide,
            unitCountBitNb  => unitCountBitNb
        )
        PORT MAP (
            clock        => clock,
            reset        => reset,
            startCounter => startCounter,
            unitNb       => unitNb,
            done         => done
        );

END struct;




-- VHDL Entity Morse.toneGenerator.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 09:13:01 03/29/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY toneGenerator IS
    GENERIC( 
        toneDivide : positive := 100E3
    );
    PORT( 
        tone  : OUT    std_ulogic;
        clock : IN     std_ulogic;
        reset : IN     std_ulogic
    );

-- Declarations

END toneGenerator ;





-- library Common;
  use work.CommonLib.all;

ARCHITECTURE masterVersion OF toneGenerator IS

  constant toneCounterBitNb: positive := requiredBitNb(toneDivide-1);
  signal toneCounter: unsigned(toneCounterBitNb-1 downto 0);
  constant toneMin : natural := (2**toneCounterBitNb - toneDivide) / 2;
  constant toneMax : natural := toneMin + toneDivide;

BEGIN

  divide: process(reset, clock)
  begin
    if reset = '1' then
      toneCounter <= to_unsigned(toneMin, toneCounter'length);
    elsif rising_edge(clock) then
      if toneCounter = toneMax then
        toneCounter <= to_unsigned(toneMin, toneCounter'length);
      else
        toneCounter <= toneCounter + 1;
      end if;
    end if;
  end process divide;

  tone <= toneCounter(toneCounter'high);

END ARCHITECTURE masterVersion;




-- VHDL Entity RS232.serialPortReceiver.symbol
--
-- Created:
--          by - francois.francois (Aphelia)
--          at - 13:45:48 08/28/19
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

ENTITY serialPortReceiver IS
    GENERIC( 
        dataBitNb      : positive := 8;
        baudRateDivide : positive := 2083
    );
    PORT( 
        RxD       : IN     std_ulogic;
        clock     : IN     std_ulogic;
        reset     : IN     std_ulogic;
        dataOut   : OUT    std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        dataValid : OUT    std_ulogic
    );

-- Declarations

END serialPortReceiver ;





-- library Common;
  use work.CommonLib.all;

architecture RTL of serialPortReceiver is

  signal dividerCounter: unsigned(requiredBitNb(baudRateDivide-1)-1 downto 0);
  signal dividerCounterReset: std_uLogic;
  signal rxDelayed: std_uLogic;
  signal dividerCounterSynchronize: std_uLogic;
  signal rxSample: std_uLogic;
  signal rxShiftReg: std_ulogic_vector(dataBitNb-1 downto 0);
  signal rxReceiving: std_uLogic;
  signal rxDataValid: std_uLogic;
  signal rxCounter: unsigned(requiredBitNb(dataBitNb)-1 downto 0);

begin

  divide: process(reset, clock)
  begin
    if reset = '1' then
      dividerCounter <= (others => '0');
    elsif rising_edge(clock) then
      if dividerCounterSynchronize = '1' then
        dividerCounter <= to_unsigned(baudRateDivide/2, dividerCounter'length);
      elsif dividerCounterReset = '1' then
        dividerCounter <= (others => '0');
      else
        dividerCounter <= dividerCounter + 1;
      end if;
    end if;
  end process divide;

  endOfCount: process(dividerCounter)
  begin
    if dividerCounter = baudRateDivide-1 then
      dividerCounterReset <= '1';
    else
      dividerCounterReset <= '0';
    end if;
  end process endOfCount;

  delayRx: process(reset, clock)
  begin
    if reset = '1' then
      rxDelayed <= '0';
    elsif rising_edge(clock) then
      rxDelayed <= RxD;
    end if;
  end process delayRx;

  rxSynchronize: process(RxD, rxDelayed)
  begin
    if RxD /= rxDelayed then
      dividerCounterSynchronize <= '1';
    else
      dividerCounterSynchronize <= '0';
    end if;
  end process rxSynchronize;

  rxSample <= dividerCounterReset and not dividerCounterSynchronize;

  shiftReg: process(reset, clock)
  begin
    if reset = '1' then
      rxShiftReg <= (others => '0');
    elsif rising_edge(clock) then
      if rxSample = '1' then
        rxShiftReg(rxShiftReg'high-1 downto 0) <= rxShiftReg(rxShiftReg'high downto 1);
        rxShiftReg(rxShiftReg'high) <= RxD;
      end if;
    end if;
  end process shiftReg;

  detectReceive: process(reset, clock)
  begin
    if reset = '1' then
      rxReceiving <= '0';
      rxDataValid <= '0';
    elsif rising_edge(clock) then
      if rxSample = '1' then
        if rxCounter = dataBitNb-1 then
          rxDataValid <= '1';
        elsif RxD = '0' then
          rxReceiving <= '1';
        end if;
      elsif rxDataValid = '1' then
        rxReceiving <= '0';
        rxDataValid <= '0';
      end if;
    end if;
  end process detectReceive;

  countRxBitNb: process(reset, clock)
  begin
    if reset = '1' then
      rxCounter <= (others => '0');
    elsif rising_edge(clock) then
      if rxSample = '1' then
        if rxReceiving = '1' then
          rxCounter <= rxCounter + 1;
        else
          rxCounter <= (others => '0');
        end if;
      end if;
    end if;
  end process countRxBitNb;

  dataOut <= rxShiftReg;
  dataValid <= rxDataValid;

end RTL;





--
-- VHDL Architecture Morse.morseEncoder.struct
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 14:50:20 28.04.2023
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

-- LIBRARY Memory;
-- LIBRARY Morse;
-- LIBRARY RS232;

ARCHITECTURE struct OF morseEncoder IS

    -- Architecture declarations
    constant fifoDepth : positive := 100;

    -- Internal signal declarations
    SIGNAL characterReg   : std_ulogic_vector(uartDataBitNb-1 DOWNTO 0);
    SIGNAL characterIn    : std_ulogic_vector(uartDataBitNb-1 DOWNTO 0);
    SIGNAL characterValid : std_ulogic;
    SIGNAL morseOut       : std_ulogic;
    SIGNAL tone           : std_ulogic;
    SIGNAL charNotReady   : std_ulogic;
    SIGNAL readChar       : std_ulogic;


    -- Component Declarations
    COMPONENT FIFO_bram
    GENERIC (
        dataBitNb : positive := 8;
        depth     : positive := 8
    );
    PORT (
        write   : IN     std_ulogic ;
        clock   : IN     std_ulogic ;
        reset   : IN     std_ulogic ;
        dataOut : OUT    std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        read    : IN     std_ulogic ;
        dataIn  : IN     std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        empty   : OUT    std_ulogic ;
        full    : OUT    std_ulogic 
    );
    END COMPONENT;
    COMPONENT charToMorse
    GENERIC (
        characterBitNb  : positive := 8;
        unitCountDivide : positive := 10E3
    );
    PORT (
        morseOut     : OUT    std_ulogic ;
        clock        : IN     std_ulogic ;
        reset        : IN     std_ulogic ;
        charIn       : IN     std_ulogic_vector (characterBitNb-1 DOWNTO 0);
        readChar     : OUT    std_ulogic ;
        charNotReady : IN     std_ulogic 
    );
    END COMPONENT;
    COMPONENT toneGenerator
    GENERIC (
        toneDivide : positive := 100E3
    );
    PORT (
        tone  : OUT    std_ulogic ;
        clock : IN     std_ulogic ;
        reset : IN     std_ulogic 
    );
    END COMPONENT;
    COMPONENT serialPortReceiver
    GENERIC (
        dataBitNb      : positive := 8;
        baudRateDivide : positive := 2083
    );
    PORT (
        RxD       : IN     std_ulogic ;
        clock     : IN     std_ulogic ;
        reset     : IN     std_ulogic ;
        dataOut   : OUT    std_ulogic_vector (dataBitNb-1 DOWNTO 0);
        dataValid : OUT    std_ulogic 
    );
    END COMPONENT;

    -- Optional embedded configurations
    -- pragma synthesis_off
--     FOR ALL : FIFO_bram USE ENTITY Memory.FIFO_bram;
--     FOR ALL : charToMorse USE ENTITY Morse.charToMorse;
--     FOR ALL : serialPortReceiver USE ENTITY RS232.serialPortReceiver;
--     FOR ALL : toneGenerator USE ENTITY Morse.toneGenerator;
    -- pragma synthesis_on


BEGIN
    -- Architecture concurrent statements
    -- HDL Embedded Text Block 1 eb1
    morseCode <= morseOut and tone;


    -- Instance port mappings.
    I_FIFO : FIFO_bram
        GENERIC MAP (
            dataBitNb => uartDataBitNb,
            depth     => fifoDepth
        )
        PORT MAP (
            write   => characterValid,
            clock   => clock,
            reset   => reset,
            dataOut => characterReg,
            read    => readChar,
            dataIn  => characterIn,
            empty   => charNotReady,
            full    => OPEN
        );
    I_enc : charToMorse
        GENERIC MAP (
            characterBitNb  => uartDataBitNb,
            unitCountDivide => integer(clockFrequency*unitDuration + 0.5)
        )
        PORT MAP (
            morseOut     => morseOut,
            clock        => clock,
            reset        => reset,
            charNotReady => charNotReady,
            charIn       => characterReg,
            readChar     => readChar
        );
    I_tone : toneGenerator
        GENERIC MAP (
            toneDivide => integer(clockFrequency/toneFrequency + 0.5)
        )
        PORT MAP (
            tone  => tone,
            clock => clock,
            reset => reset
        );
    I_UART : serialPortReceiver
        GENERIC MAP (
            dataBitNb      => uartDataBitNb,
            baudRateDivide => integer(clockFrequency/uartBaudRate + 0.5)
        )
        PORT MAP (
            RxD       => RxD,
            clock     => clock,
            reset     => reset,
            dataOut   => characterIn,
            dataValid => characterValid
        );

END struct;




-- VHDL netlist generated by SCUBA Diamond (64-bit) 3.12.1.454
-- Module  Version: 5.7
--C:\lscc\diamond\3.12\ispfpga\bin\nt64\scuba.exe -w -n pll -lang vhdl -synth synplify -bus_exp 7 -bb -arch sa5p00 -type pll -fin 100.00 -fclkop 60 -fclkop_tol 10.0 -fclkos 75 -fclkos_tol 10.0 -phases 0 -fclkos2 50 -fclkos2_tol 10.0 -phases2 0 -fclkos3 10 -fclkos3_tol 10.0 -phases3 0 -phase_cntl STATIC -enable_s -enable_s2 -enable_s3 -pllLocked -fb_mode 1 -fdc C:/temp/clocker/pll/pll.fdc 

-- Offers 10MHz, 50MHz, 60MHz and 75MHz clocks

library IEEE;
  use IEEE.std_logic_1164.all;
library ECP5U;
  use ECP5U.components.all;

ENTITY pll IS
    PORT( 
        clkIn100M : IN     std_ulogic;
        en75M     : IN     std_ulogic;
        en50M     : IN     std_ulogic;
        en10M     : IN     std_ulogic;
        clk60MHz  : OUT    std_ulogic;
        clk75MHz  : OUT    std_ulogic;
        clk50MHz  : OUT    std_ulogic;
        clk10MHz  : OUT    std_ulogic;
        pllLocked : OUT    std_ulogic
    );

-- Declarations

END pll ;

architecture rtl of pll is

    -- internal signal declarations
    signal REFCLK: std_logic;
    signal CLKOS3_t: std_logic;
    signal CLKOS2_t: std_logic;
    signal CLKOS_t: std_logic;
    signal CLKOP_t: std_logic;
    signal scuba_vhi: std_logic;
    signal scuba_vlo: std_logic;

    attribute FREQUENCY_PIN_CLKOS3 : string; 
    attribute FREQUENCY_PIN_CLKOS2 : string; 
    attribute FREQUENCY_PIN_CLKOS : string; 
    attribute FREQUENCY_PIN_CLKOP : string; 
    attribute FREQUENCY_PIN_CLKI : string; 
    attribute ICP_CURRENT : string; 
    attribute LPF_RESISTOR : string; 
    attribute FREQUENCY_PIN_CLKOS3 of PLLInst_0 : label is "10.000000";
    attribute FREQUENCY_PIN_CLKOS2 of PLLInst_0 : label is "50.000000";
    attribute FREQUENCY_PIN_CLKOS of PLLInst_0 : label is "75.000000";
    attribute FREQUENCY_PIN_CLKOP of PLLInst_0 : label is "60.000000";
    attribute FREQUENCY_PIN_CLKI of PLLInst_0 : label is "100.000000";
    attribute ICP_CURRENT of PLLInst_0 : label is "5";
    attribute LPF_RESISTOR of PLLInst_0 : label is "16";
    attribute syn_keep : boolean;
    attribute NGD_DRC_MASK : integer;
    attribute NGD_DRC_MASK of rtl : architecture is 1;

begin
    -- component instantiation statements
    scuba_vhi_inst: VHI
        port map (Z=>scuba_vhi);

    scuba_vlo_inst: VLO
        port map (Z=>scuba_vlo);

    PLLInst_0: EHXPLLL
        generic map (PLLRST_ENA=> "DISABLED", INTFB_WAKE=> "DISABLED", 
        STDBY_ENABLE=> "DISABLED", DPHASE_SOURCE=> "DISABLED", 
        CLKOS3_FPHASE=>  0, CLKOS3_CPHASE=>  59, CLKOS2_FPHASE=>  0, 
        CLKOS2_CPHASE=>  11, CLKOS_FPHASE=>  0, CLKOS_CPHASE=>  7, 
        CLKOP_FPHASE=>  0, CLKOP_CPHASE=>  9, PLL_LOCK_MODE=>  0, 
        CLKOS_TRIM_DELAY=>  0, CLKOS_TRIM_POL=> "FALLING", 
        CLKOP_TRIM_DELAY=>  0, CLKOP_TRIM_POL=> "FALLING", 
        OUTDIVIDER_MUXD=> "DIVD", CLKOS3_ENABLE=> "DISABLED", 
        OUTDIVIDER_MUXC=> "DIVC", CLKOS2_ENABLE=> "DISABLED", 
        OUTDIVIDER_MUXB=> "DIVB", CLKOS_ENABLE=> "DISABLED", 
        OUTDIVIDER_MUXA=> "DIVA", CLKOP_ENABLE=> "ENABLED", CLKOS3_DIV=>  60, 
        CLKOS2_DIV=>  12, CLKOS_DIV=>  8, CLKOP_DIV=>  10, CLKFB_DIV=>  3, 
        CLKI_DIV=>  5, FEEDBK_PATH=> "CLKOP")
        port map (CLKI=>clkIn100M, CLKFB=>CLKOP_t, PHASESEL1=>scuba_vlo, 
            PHASESEL0=>scuba_vlo, PHASEDIR=>scuba_vlo, 
            PHASESTEP=>scuba_vlo, PHASELOADREG=>scuba_vlo, 
            STDBY=>scuba_vlo, PLLWAKESYNC=>scuba_vlo, RST=>scuba_vlo, 
            ENCLKOP=>scuba_vlo, ENCLKOS=>en75M, ENCLKOS2=>en50M, 
            ENCLKOS3=>en10M, CLKOP=>CLKOP_t, CLKOS=>CLKOS_t, 
            CLKOS2=>CLKOS2_t, CLKOS3=>CLKOS3_t, LOCK=>pllLocked, 
            INTLOCK=>open, REFCLK=>REFCLK, CLKINTFB=>open);

    clk10MHz <= CLKOS3_t;
    clk50MHz <= CLKOS2_t;
    clk75MHz <= CLKOS_t;
    clk60MHz <= CLKOP_t;
end rtl;




--
-- VHDL Architecture Board.morse_ebs3.struct
--
-- Created:
--          by - axel.amand.UNKNOWN (WE7860)
--          at - 08:06:36 08.05.2023
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2019.2 (Build 5)
--
LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.numeric_std.all;

-- LIBRARY Board;
-- LIBRARY Lattice;
-- LIBRARY Morse;

ARCHITECTURE struct OF morse_ebs3 IS

    -- Architecture declarations
    constant clockFrequency: real := 60.0E6;
    constant uartBaudRate: real := 9.6E3;
    constant uartDataBitNb: positive := 7;
    constant morseUnitDuration: real := 100.0E-3;  -- 1/2 * 10 Hz
    constant morseToneFrequency: real := 3135.96;  -- sol 3eme octave
    constant deglitchBitNb: positive := 16;

    -- Internal signal declarations
    SIGNAL clk_sys       : std_ulogic;
    SIGNAL logic0        : std_ulogic;
    SIGNAL logic1        : std_uLogic;
    SIGNAL morseIn_synch : std_uLogic;
    SIGNAL reset1        : std_ulogic;
    SIGNAL resetSynch    : std_ulogic;
    SIGNAL resetSynch_n  : std_ulogic;

    -- Implicit buffer signal declarations
    SIGNAL RxD_synch_internal : std_ulogic;


    -- Component Declarations
    COMPONENT DFF
    PORT (
        CLK : IN     std_uLogic ;
        CLR : IN     std_uLogic ;
        D   : IN     std_uLogic ;
        Q   : OUT    std_uLogic 
    );
    END COMPONENT;
    COMPONENT inverterIn
    PORT (
        in1  : IN     std_uLogic ;
        out1 : OUT    std_uLogic 
    );
    END COMPONENT;
    COMPONENT pll
    PORT (
        clkIn100M : IN     std_ulogic ;
        en75M     : IN     std_ulogic ;
        en50M     : IN     std_ulogic ;
        en10M     : IN     std_ulogic ;
        clk60MHz  : OUT    std_ulogic ;
        clk75MHz  : OUT    std_ulogic ;
        clk50MHz  : OUT    std_ulogic ;
        clk10MHz  : OUT    std_ulogic ;
        pllLocked : OUT    std_ulogic 
    );
    END COMPONENT;
    COMPONENT morseDecoder
    GENERIC (
        clockFrequency : real     := 100.0E6;
        uartBaudRate   : real     := 115.2E3;
        uartDataBitNb  : positive := 8;
        unitDuration   : real     := 100.0E-3;
        toneFrequency  : real     := 300.0;
        deglitchBitNb  : natural  := 8
    );
    PORT (
        morseCode     : IN     std_ulogic ;
        clock         : IN     std_ulogic ;
        reset         : IN     std_ulogic ;
        TxD           : OUT    std_ulogic ;
        morseEnvelope : OUT    std_ulogic 
    );
    END COMPONENT;
    COMPONENT morseEncoder
    GENERIC (
        clockFrequency : real     := 100.0E6;
        uartBaudRate   : real     := 115.2E3;
        uartDataBitNb  : positive := 8;
        unitDuration   : real     := 100.0E-3;
        toneFrequency  : real     := 300.0
    );
    PORT (
        morseCode : OUT    std_ulogic ;
        clock     : IN     std_ulogic ;
        reset     : IN     std_ulogic ;
        RxD       : IN     std_ulogic 
    );
    END COMPONENT;

    -- Optional embedded configurations
    -- pragma synthesis_off
--     FOR ALL : DFF USE ENTITY Board.DFF;
--     FOR ALL : inverterIn USE ENTITY Board.inverterIn;
--     FOR ALL : morseDecoder USE ENTITY Morse.morseDecoder;
--     FOR ALL : morseEncoder USE ENTITY Morse.morseEncoder;
--     FOR ALL : pll USE ENTITY Lattice.pll;
    -- pragma synthesis_on


BEGIN
    -- Architecture concurrent statements
    -- HDL Embedded Text Block 6 eb6
    logic1 <= '1';

    -- HDL Embedded Text Block 7 eb7
    logic0 <= '0';


    -- Instance port mappings.
    I7 : DFF
        PORT MAP (
            CLK => clk_sys,
            CLR => resetSynch,
            D   => RxD,
            Q   => RxD_synch_internal
        );
    I8 : DFF
        PORT MAP (
            CLK => clock,
            CLR => reset1,
            D   => logic1,
            Q   => resetSynch_n
        );
    I9 : DFF
        PORT MAP (
            CLK => clk_sys,
            CLR => resetSynch,
            D   => morseIn,
            Q   => morseIn_synch
        );
    I3 : inverterIn
        PORT MAP (
            in1  => reset_n,
            out1 => reset1
        );
    I4 : inverterIn
        PORT MAP (
            in1  => resetSynch_n,
            out1 => resetSynch
        );
    I_pll : pll
        PORT MAP (
            clkIn100M => clock,
            en75M     => logic0,
            en50M     => logic0,
            en10M     => logic0,
            clk60MHz  => clk_sys,
            clk75MHz  => OPEN,
            clk50MHz  => OPEN,
            clk10MHz  => OPEN,
            pllLocked => OPEN
        );
    I_dec : morseDecoder
        GENERIC MAP (
            clockFrequency => clockFrequency,
            uartBaudRate   => uartBaudRate,
            uartDataBitNb  => uartDataBitNb,
            unitDuration   => morseUnitDuration,
            toneFrequency  => morseToneFrequency,
            deglitchBitNb  => deglitchBitNb
        )
        PORT MAP (
            morseCode     => morseIn_synch,
            clock         => clk_sys,
            reset         => resetSynch,
            TxD           => TxD,
            morseEnvelope => morseEnvelope
        );
    I_enc : morseEncoder
        GENERIC MAP (
            clockFrequency => clockFrequency,
            uartBaudRate   => uartBaudRate,
            uartDataBitNb  => uartDataBitNb,
            unitDuration   => morseUnitDuration,
            toneFrequency  => morseToneFrequency
        )
        PORT MAP (
            morseCode => morseOut,
            clock     => clk_sys,
            reset     => resetSynch,
            RxD       => RxD_synch_internal
        );

    -- Implicit buffered output assignments
    RxD_synch <= RxD_synch_internal;

END struct;




