3248 lines
95 KiB
VHDL
3248 lines
95 KiB
VHDL
|
-- 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<61>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<61>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;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|