Hello Guys,
I am working since a long time on a VHDL Project which encodes a UDP
packet in Manchester code for transmission over the Ethernet. The packet
was not recognised by wireshark and after investigation on the
Oscilloscope it was found that my encoder is malfunctioning. Here is the
code :
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY TX_PHY_wrapper IS
PORT(
CLK_20Mhz : IN STD_LOGIC;
CLK_1_25Mhz: IN STD_LOGIC; -- Clk 1.25 MHz
Reset : IN STD_LOGIC;
----------------------------------------------------------------
-- Start, stop and data inputs. To tell the frame apart --
----------------------------------------------------------------
start : IN STD_LOGIC;
stop : IN STD_LOGIC;
data : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
----------------------------------------------------------------
-- Output for PHY --------
----------------------------------------------------------------
TXD_M : OUT STD_LOGIC; -- Manchester Output
TXD_N : OUT STD_LOGIC; -- Negated Output (negative)
Debug : OUT STD_LOGIC_VECTOR(1 downto 0)
);
END TX_PHY_wrapper;
ARCHITECTURE Behavioral OF TX_PHY_wrapper IS
TYPE STATES is (between1,between2,between3,first_pulse,GAP,Hold,
Preamble_55, Preamble_D5, Payload, Payload_last, CRC32_1, CRC32_2,
CRC32_3, CRC32_4, ideal, clocking, TP_IDLE);
SIGNAL encode: STD_LOGIC := '0';-- This starts the manchester encoder
SIGNAL TXD : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL busy: std_logic := '0';
SIGNAL rdaddress : INTEGER range 1 to 100 := 1;
BEGIN
Debug(0) <= '0';
Debug(1) <= busy;
------------------------------------------------------------------------
------------
---- The following process is synchronus to 1.25 MHz clock. It needs to
be slow --
---- to allow enough time for the data to be encoded in Manchester
scheme. --
------------------------------------------------------------------------
------------
Clockout_statemachine : Process (CLK_20Mhz, start, rdaddress)
Begin
if rising_edge(CLK_20Mhz) then
case rdaddress is
WHEN 1 => if (start='1') then TXD<= x"55"; encode <='1'; end if;
WHEN 2 => TXD <= x"55";
WHEN 3 => TXD <= x"55";
WHEN 4 => TXD <= x"55";
WHEN 5 => TXD <= x"55";
WHEN 6 => TXD <= x"55";
WHEN 7 => TXD <= x"55";
WHEN 8 => TXD <= x"D5";
WHEN 9 => TXD <= x"00";
WHEN 10=> TXD <= x"10";
WHEN 11=> TXD <= x"A4";
WHEN 12=> TXD <= x"7B";
WHEN 13=> TXD <= x"EA";
WHEN 14=> TXD <= x"80";
WHEN 15=> TXD <= x"00";
WHEN 16=> TXD <= x"12";
WHEN 17=> TXD <= x"34";
WHEN 18 => TXD <= x"56";
WHEN 19 => TXD <= x"78";
WHEN 20 => TXD <= x"90";
WHEN 21 => TXD <= x"08";
WHEN 22 => TXD <= x"00";
WHEN 23 => TXD <= x"45";
WHEN 24 => TXD <= x"00";
WHEN 25 => TXD <= x"00";
WHEN 26 => TXD <= x"2E";
WHEN 27 => TXD <= x"B3";
WHEN 28 => TXD <= x"FE";
WHEN 29 => TXD <= x"00";
WHEN 30 => TXD <= x"00";
WHEN 31 => TXD <= x"80";
WHEN 32 => TXD <= x"11";
WHEN 33 => TXD <= x"05";
WHEN 34 => TXD <= x"40";
WHEN 35 => TXD <= x"C0";
WHEN 36 => TXD <= x"A8";
WHEN 37 => TXD <= x"00";
WHEN 38 => TXD <= x"2C";
WHEN 39 => TXD <= x"C0";
WHEN 40 => TXD <= x"A8";
WHEN 41 => TXD <= x"00";
WHEN 42 => TXD <= x"04";
WHEN 43 => TXD <= x"04";
WHEN 44 => TXD <= x"00";
WHEN 45 => TXD <= x"04";
WHEN 46 => TXD <= x"00";
WHEN 47 => TXD <= x"00";
WHEN 48 => TXD <= x"1A";
WHEN 49 => TXD <= x"2D";
WHEN 50 => TXD <= x"E8";
WHEN 51 => TXD <= x"00";
WHEN 52 => TXD <= x"01";
WHEN 53 => TXD <= x"02";
WHEN 54 => TXD <= x"03";
WHEN 55 => TXD <= x"04";
WHEN 56 => TXD <= x"05";
WHEN 57 => TXD <= x"06";
WHEN 58 => TXD <= x"07";
WHEN 59 => TXD <= x"08";
WHEN 60 => TXD <= x"09";
WHEN 61 => TXD <= x"0A";
WHEN 62 => TXD <= x"0B";
WHEN 63 => TXD <= x"0C";
WHEN 64 => TXD <= x"0D";
WHEN 65 => TXD <= x"0E";
WHEN 66 => TXD <= x"0F";
WHEN 67 => TXD <= x"10";
WHEN 68 => TXD <= x"11";
WHEN 69 => TXD <= x"B3";
WHEN 70 => TXD <= x"31";
WHEN 71 => TXD <= x"88";
WHEN 72 => TXD <= x"1B"; encode <= '0';
WHEN OTHERS => TXD <= x"00";
end case;
end if;
END Process;
-- Manchester encoder, when encode is high it takes TXD and out puts it
on the TXD_M line.
ENCODING: PROCESS (CLK_20Mhz, encode)
variable NLP_counter : INTEGER range 0 to 320010 := 0;
Variable coding_state : STATES := first_pulse;
Variable TP_IDL :INTEGER range 0 to 10 := 0;
Variable first_count : INTEGER range 0 to 1 := 0;
Variable encoder_state : INTEGER range 1 to 20 := 1;
BEGIN
if (Reset = '1') then
coding_state := first_pulse;
TP_IDL := 0;
NLP_counter := 0;
first_count := 0; -- For the first NLP pulse
busy <='0';
encoder_state := 1;
rdaddress <= 1;
elsif(rising_edge(CLK_20Mhz)) then
Case coding_state is
when first_pulse => -- first_pulse is the first NLP_Pulse to be
sent after reset.
TXD_M <= '1';
TXD_N <= '0';
first_count := 1;
if(first_count = 1) then
TXD_M <= '0';
TXD_N <= '0';
coding_state := ideal;
end if;
when ideal =>
if(encode = '1') then
coding_state := clocking;
elsif (NLP_counter > 320000) then
NLP_counter := 0;
TXD_M <= '1';
TXD_N <= '0';
else
NLP_counter := NLP_counter + 1;
TXD_M <= '0';
TXD_N <= '0';
end if;
when clocking =>
NLP_counter := 0;
case encoder_state is
when 1 => TXD_M <= not TXD(7); TXD_N <= TXD(7); encoder_state :=
encoder_state + 1; busy <= not busy;
when 2 => TXD_N <= not TXD(7); TXD_M <= TXD(7); encoder_state :=
encoder_state + 1;
when 3 => TXD_M <= not TXD(6); TXD_N <= TXD(6); encoder_state :=
encoder_state + 1;
when 4 => TXD_N <= not TXD(6); TXD_M <= TXD(6); encoder_state :=
encoder_state + 1;
when 5 => TXD_M <= not TXD(5); TXD_N <= TXD(5); encoder_state :=
encoder_state + 1;
when 6 => TXD_N <= not TXD(5); TXD_M <= TXD(5); encoder_state :=
encoder_state + 1;
when 7 => TXD_M <= not TXD(4); TXD_N <= TXD(4); encoder_state :=
encoder_state + 1;
when 8 => TXD_N <= not TXD(4); TXD_M <= TXD(4); encoder_state :=
encoder_state + 1;
when 9 => TXD_M <= not TXD(3); TXD_N <= TXD(3); encoder_state :=
encoder_state + 1;
when 10 => TXD_N <= not TXD(3); TXD_M <= TXD(3); encoder_state :=
encoder_state + 1;
when 11 => TXD_M <= not TXD(2); TXD_N <= TXD(2); encoder_state :=
encoder_state + 1;
when 12 => TXD_N <= not TXD(2); TXD_M <= TXD(2); encoder_state :=
encoder_state + 1;
when 13 => TXD_M <= not TXD(1); TXD_N <= TXD(1); encoder_state :=
encoder_state + 1;
when 14 => TXD_N <= not TXD(1); TXD_M <= TXD(1); encoder_state :=
encoder_state + 1;
when 15 => TXD_M <= not TXD(0); TXD_N <= TXD(0); encoder_state :=
encoder_state + 1; rdaddress <= rdaddress + 1;
when 16 => TXD_N <= not TXD(0); TXD_M <= TXD(0); encoder_state := 1;
if (rdaddress = 205) then
coding_state := TP_IDLE;
rdaddress <= 1;
end if;
when others => null;
end case;
when TP_IDLE =>
if (TP_IDL = 6) then
TXD_M <= '0';
TXD_N <= '0';
coding_state := ideal;
TP_IDL := 0;
else
TXD_M <= '1';
TXD_N <= '0';
TP_IDL := TP_IDL + 1;
coding_state := TP_IDLE;
end if;
when others => Coding_state := ideal;
end case;
end if;
END PROCESS;
END Behavioral;
The state "clocking" is the one responsible for performing the
Manchester encoding. In fact it works fine but it doesn't go through the
whole encoding states..It stops by 13 and jumps back to the first one. I
don't why but that's what i found on the the Oscilliscope. Hence the
packet is not correctly encoded. I did some modifications on the code
and by setting it back to the original (one above) i get totally another
response on the Oscilloscope. It's driving me crazy....
Any help will be really appreciated. Thanks in advance
Regards,
Saher