summaryrefslogtreecommitdiff
path: root/netfpga10g/hdl/eth_tx.vhd
blob: cf0081dc1b1c61686d3f5b34b909ab171be5acd6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity eth_tx is port (
        clk : in std_logic;

        rd_en : out  std_logic;
        rd_data : in  std_logic_vector (63 downto 0);
        rd_valid : in  std_logic;

        xgmii_txd : out std_logic_vector(63 downto 0);
        xgmii_txc : out std_logic_vector(7 downto 0)
);
end eth_tx;

architecture arch of eth_tx is
        constant IDLE : std_logic_vector(7 downto 0) := x"07";
        constant START : std_logic_vector(7 downto 0) := x"FB";
        constant TERMINATE : std_logic_vector(7 downto 0) := x"FD";

        constant PREAMBLE : std_logic_vector(7 downto 0) := "01010101";
        constant SFD : std_logic_vector(7 downto 0) := "11010101";

        type lanes_t is array (0 to 7) of std_logic_vector(7 downto 0);
        signal lanes : lanes_t := (others => IDLE);
        signal control : std_logic_vector(7 downto 0) := (others => '1');

        type state_t is (state_idle, state_data);
        signal state : state_t := state_idle;
begin
        lanes_gen : for i in 0 to 7 generate
                xgmii_txd(7+8*i downto 8*i) <= lanes(i);
                xgmii_txc(i) <= control(i);
        end generate lanes_gen;
        
        rd_en <= '1' when state = state_data else '0';

        process (clk)
        begin
                if rising_edge(clk) then
                        lanes <= (others => IDLE);
                        control <= (others => '1');

                        if state = state_idle then
                                if rd_valid = '1' then
                                        state <= state_data;
                                        lanes(0) <= START;
                                        lanes(1 to 6) <= (others => PREAMBLE);
                                        lanes(7) <= SFD;
                                        control(7 downto 1) <= (others => '0');
                                end if;

                        elsif state = state_data then
                                if rd_valid = '1' then
                                        for i in 0 to 7 loop
                                                lanes(i) <= rd_data(63-8*i downto 56-8*i);
                                                control(i) <= '0';
                                        end loop;
                                else
                                        state <= state_idle;
                                        lanes(0) <= TERMINATE;
                                end if;
                        end if;
                end if;
        end process;
end arch;