EmbDev.net

Forum: FPGA, VHDL & Verilog Help with Manchester encoder


von Saher S. (s-salem)


Rate this post
useful
not useful
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

von lkmiller (Guest)


Rate this post
useful
not useful
Do you have a testbench for the encoder? That's first before debugging 
with an oscilloscope...

von Saher (Guest)


Rate this post
useful
not useful
yes i did a test bench and it went perfectly...but as you know 
simulations always work but when you come to implementations on FPGA 
then fun starts

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.