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
Do you have a testbench for the encoder? That's first before debugging with an oscilloscope...
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
Log in with Google account
No account? Register here.