begin of ethernet RX implementation, so far only test interface to core, does not meet timing
Stefan Schuermans

Stefan Schuermans commited on 2012-02-20 21:16:03
Showing 12 changed files, with 656 additions and 32 deletions.

... ...
@@ -0,0 +1,66 @@
1
+LIBRARY IEEE;
2
+USE IEEE.STD_LOGIC_1164.ALL;
3
+USE IEEE.NUMERIC_STD.ALL;
4
+
5
+ENTITY e_block_crc32 IS
6
+    PORT (
7
+        rst:     IN  std_logic;
8
+        clk:     IN  std_logic;
9
+        i_en:    IN  std_logic;
10
+        i_start: IN  std_logic;
11
+        i_data:  IN  std_logic_vector(7 DOWNTO 0);
12
+        o_crc:   OUT std_logic_vector(31 DOWNTO 0)
13
+    );
14
+END ENTITY e_block_crc32;
15
+
16
+ARCHITECTURE a_block_crc32 OF e_block_crc32 IS
17
+
18
+    TYPE t_xor IS ARRAY(7 DOWNTO 0) of std_logic_vector(31 DOWNTO 0);
19
+
20
+    CONSTANT c_xor: t_xor := (0 => X"77073096",
21
+                              1 => X"EE0E612C",
22
+                              2 => X"076DC419",
23
+                              3 => X"0EDB8832",
24
+                              4 => X"1DB71064",
25
+                              5 => X"3B6E20C8",
26
+                              6 => X"76DC4190",
27
+                              7 => X"EDB88320");
28
+
29
+    SIGNAL r_crc: std_logic_vector(31 DOWNTO 0) := X"FFFFFFFF";
30
+    SIGNAL n_crc: std_logic_vector(31 DOWNTO 0);
31
+
32
+BEGIN
33
+
34
+    p_next: PROCESS(r_crc, i_en, i_start, i_data)
35
+        VARIABLE v_crc:  std_logic_vector(31 DOWNTO 0);
36
+        VARIABLE v_bits: std_logic_vector( 7 DOWNTO 0);
37
+    BEGIN
38
+        v_crc := r_crc;
39
+        IF i_en = '1' THEN
40
+            IF i_start = '1' THEN
41
+                v_crc := X"FFFFFFFF";
42
+            END IF;
43
+            v_bits := v_crc(7 DOWNTO 0) XOR i_data;
44
+            v_crc  := X"00" & v_crc(31 DOWNTO 8);
45
+            FOR i IN 7 DOWNTO 0 LOOP
46
+                IF v_bits(i) = '1' THEN
47
+                    v_crc := v_crc XOR c_xor(i);
48
+                END IF;
49
+            END LOOP;
50
+        END IF;
51
+        n_crc <= v_crc;
52
+    END PROCESS p_next;
53
+
54
+    p_sync: PROCESS(rst, clk)
55
+    BEGIN
56
+        IF rst = '1' THEN
57
+            r_crc <= X"FFFFFFFF";
58
+        ELSIF rising_edge(clk) THEN
59
+            r_crc <= n_crc;
60
+        END IF;
61
+    END PROCESS p_sync;
62
+
63
+    o_crc <= r_crc XOR X"FFFFFFFF";
64
+
65
+END ARCHITECTURE a_block_crc32;
66
+
... ...
@@ -0,0 +1,17 @@
1
+NET "pin_o_eth_nrst" LOC = "D15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
2
+NET "pin_i_eth_rx_clk" LOC = "C12" | IOSTANDARD = LVCMOS33;
3
+NET "pin_i_eth_rxd[0]" LOC = "G7" | IOSTANDARD = LVCMOS33 | PULLUP;
4
+NET "pin_i_eth_rxd[1]" LOC = "G8" | IOSTANDARD = LVCMOS33 | PULLUP;
5
+NET "pin_i_eth_rxd[2]" LOC = "G9" | IOSTANDARD = LVCMOS33 | PULLUP;
6
+NET "pin_i_eth_rxd[3]" LOC = "H9" | IOSTANDARD = LVCMOS33 | PULLUP;
7
+NET "pin_i_eth_rxd[4]" LOC = "G10" | IOSTANDARD = LVCMOS33;
8
+NET "pin_i_eth_rx_dv" LOC = "H10" | IOSTANDARD = LVCMOS33 ;
9
+NET "pin_i_eth_crs" LOC = "H12" | IOSTANDARD = LVCMOS33;
10
+NET "pin_i_eth_col" LOC = "G12" | IOSTANDARD = LVCMOS33 | PULLDOWN;
11
+NET "pin_i_eth_tx_clk" LOC = "E11" | IOSTANDARD = LVCMOS33;
12
+NET "pin_o_eth_txd[0]" LOC = "F8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 4;
13
+NET "pin_o_eth_txd[1]" LOC = "E7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 4;
14
+NET "pin_o_eth_txd[2]" LOC = "E6" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 4;
15
+NET "pin_o_eth_txd[3]" LOC = "F7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 4;
16
+NET "pin_o_eth_tx_en" LOC = "D8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 4;
17
+
... ...
@@ -1,4 +1,4 @@
1
-SRCS=cyc_cnt.c lcd.c leds.c main.c switches.c uart.c
1
+SRCS=cyc_cnt.c eth.c lcd.c leds.c main.c switches.c uart.c
2 2
 
3 3
 PERL=perl
4 4
 CC=mipsel-elf-gcc
... ...
@@ -0,0 +1,26 @@
1
+#include "eth.h"
2
+
3
+static volatile unsigned char *const eth_ptr =
4
+  (volatile unsigned char *)0x80000400;
5
+
6
+/**
7
+ * @brief check if receiving a character is possible
8
+ * @return if receiving a character is possible
9
+ */
10
+int eth_can_rx(void)
11
+{
12
+  return eth_ptr[0];
13
+}
14
+
15
+/**
16
+ * @brief receive a character
17
+ * @return character received
18
+ */
19
+unsigned char eth_rx(void)
20
+{
21
+  while (!eth_ptr[0]); /* wait for data */
22
+  unsigned char chr = eth_ptr[4]; /* read data */
23
+  eth_ptr[4] = 0; /* remove data from FIFO */
24
+  return chr;
25
+}
26
+
... ...
@@ -0,0 +1,17 @@
1
+#ifndef ETH_H
2
+#define ETH_H
3
+
4
+/**
5
+ * @brief check if receiving a character is possible
6
+ * @return if receiving a character is possible
7
+ */
8
+int eth_can_rx(void);
9
+
10
+/**
11
+ * @brief receive a character
12
+ * @return character received
13
+ */
14
+unsigned char eth_rx(void);
15
+
16
+#endif /* #ifndef ETH_H */
17
+
... ...
@@ -1,10 +1,12 @@
1 1
 #include "cyc_cnt.h"
2
+#include "eth.h"
2 3
 #include "lcd.h"
3 4
 #include "leds.h"
4 5
 #include "uart.h"
5 6
 #include "switches.h"
6 7
 
7 8
 #define CFG_DELAY
9
+#define CFG_ETH
8 10
 #define CFG_LCD
9 11
 #define CFG_UART
10 12
 //#define CFG_UART_CHK
... ...
@@ -43,8 +45,17 @@ void switches(void)
43 45
 void delay(void)
44 46
 {
45 47
   unsigned int i;
48
+  unsigned char chr;
46 49
   for (i = 0; i < 10; ++i) {
47 50
     switches();
51
+#ifdef CFG_ETH
52
+  while (eth_can_rx()) {
53
+    chr = eth_rx();
54
+#ifdef CFG_UART
55
+  uart_tx(chr);
56
+#endif
57
+  }
58
+#endif
48 59
 #ifdef CFG_DELAY
49 60
     cyc_cnt_delay_ms(20);
50 61
 #endif
... ...
@@ -0,0 +1,156 @@
1
+LIBRARY IEEE;
2
+USE IEEE.STD_LOGIC_1164.ALL;
3
+USE IEEE.NUMERIC_STD.ALL;
4
+
5
+ENTITY e_io_eth IS
6
+    PORT (
7
+        rst:          IN  std_logic;
8
+        clk:          IN  std_logic;
9
+        i_addr:       IN  std_logic_vector( 1 DOWNTO 0);
10
+        o_rd_data:    OUT std_logic_vector(31 DOWNTO 0);
11
+        i_wr_data:    IN  std_logic_vector(31 DOWNTO 0);
12
+        i_wr_en:      IN  std_logic_vector( 3 DOWNTO 0);
13
+        pin_o_nrst:   OUT std_logic;
14
+        pin_i_rx_clk: IN  std_logic;
15
+        pin_i_rxd:    IN  std_logic_vector(4 DOWNTO 0);
16
+        pin_i_rx_dv:  IN  std_logic;
17
+        pin_i_crs:    IN  std_logic;
18
+        pin_i_col:    IN  std_logic;
19
+        pin_i_tx_clk: IN  std_logic;
20
+        pin_o_txd:    OUT std_logic_vector(3 DOWNTO 0);
21
+        pin_o_tx_en:  OUT std_logic
22
+    );
23
+END ENTITY e_io_eth;
24
+
25
+ARCHITECTURE a_io_eth OF e_io_eth IS
26
+
27
+    SIGNAL s_rx_data:    std_logic_vector(7 DOWNTO 0);
28
+    SIGNAL s_rx_data_en: std_logic;
29
+    SIGNAL s_rx_done:    std_logic;
30
+    SIGNAL s_rx_err:     std_logic;
31
+
32
+    -- so far only for testing
33
+    SIGNAL s_rx_fifo_wr_rdy:  std_logic;
34
+    SIGNAL s_rx_fifo_wr_data: std_logic_vector(7 DOWNTO 0);
35
+    SIGNAL s_rx_fifo_wr_en:   std_logic;
36
+    SIGNAL s_rx_fifo_rd_rdy:  std_logic;
37
+    SIGNAL s_rx_fifo_rd_data: std_logic_vector(7 DOWNTO 0);
38
+    SIGNAL s_rx_fifo_rd_en:   std_logic;
39
+
40
+    COMPONENT e_io_eth_rst IS
41
+        PORT (
42
+            rst:        IN  std_logic;
43
+            clk:        IN  std_logic;
44
+            pin_o_nrst: OUT std_logic
45
+        );
46
+    END COMPONENT e_io_eth_rst;
47
+
48
+    COMPONENT e_io_eth_rxif IS
49
+        PORT (
50
+            rst:          IN  std_logic;
51
+            clk:          IN  std_logic;
52
+            o_data:       OUT std_logic_vector(7 DOWNTO 0);
53
+            o_data_en:    OUT std_logic;
54
+            o_done:       OUT std_logic;
55
+            o_err:        OUT std_logic;
56
+            pin_i_rx_clk: IN  std_logic;
57
+            pin_i_rxd:    IN  std_logic_vector(4 DOWNTO 0);
58
+            pin_i_rx_dv:  IN  std_logic;
59
+            pin_i_crs:    IN  std_logic;
60
+            pin_i_col:    IN  std_logic
61
+        );
62
+    END COMPONENT e_io_eth_rxif;
63
+
64
+    -- so far only for testing
65
+    COMPONENT e_block_fifo IS
66
+        GENERIC (
67
+            addr_width: natural;
68
+            data_width: natural
69
+        );
70
+        PORT (
71
+            rst:       IN  std_logic;
72
+            clk:       IN  std_logic;
73
+            o_wr_rdy:  OUT std_logic;
74
+            i_wr_data: IN  std_logic_vector(data_width - 1 DOWNTO 0);
75
+            i_wr_en:   IN  std_logic;
76
+            o_rd_rdy:  OUT std_logic;
77
+            o_rd_data: OUT std_logic_vector(data_width - 1 DOWNTO 0);
78
+            i_rd_en:   IN  std_logic
79
+        );
80
+    END COMPONENT e_block_fifo;
81
+
82
+BEGIN
83
+
84
+    reset: e_io_eth_rst
85
+        PORT MAP (
86
+            rst        => rst,
87
+            clk        => clk,
88
+            pin_o_nrst => pin_o_nrst
89
+        );
90
+
91
+    rxif: e_io_eth_rxif
92
+        PORT MAP (
93
+            rst          => rst,
94
+            clk          => clk,
95
+            o_data       => s_rx_data,
96
+            o_data_en    => s_rx_data_en,
97
+            o_done       => s_rx_done,
98
+            o_err        => s_rx_err,
99
+            pin_i_rx_clk => pin_i_rx_clk,
100
+            pin_i_rxd    => pin_i_rxd,
101
+            pin_i_rx_dv  => pin_i_rx_dv,
102
+            pin_i_crs    => pin_i_crs,
103
+            pin_i_col    => pin_i_col
104
+        );
105
+
106
+    -- so far only for testing
107
+    p_rx_if2fifo: PROCESS (s_rx_data, s_rx_data_en, s_rx_done, s_rx_err)
108
+    BEGIN
109
+        IF s_rx_err = '1' THEN
110
+            s_rx_fifo_wr_data <= X"EE";
111
+        ELSIF s_rx_done = '1' THEN
112
+            s_rx_fifo_wr_data <= X"DD";
113
+        ELSE
114
+            s_rx_fifo_wr_data <= s_rx_data;
115
+        END IF;
116
+        s_rx_fifo_wr_en <= s_rx_data_en OR s_rx_done OR s_rx_err;
117
+    END PROCESS p_rx_if2fifo;
118
+
119
+    -- so far only for testing
120
+    rx_fifo: e_block_fifo
121
+        GENERIC MAP (
122
+            addr_width => 11,
123
+            data_width => 8
124
+        )
125
+        PORT MAP (
126
+            rst       => rst,
127
+            clk       => clk,
128
+            o_wr_rdy  => s_rx_fifo_wr_rdy,
129
+            i_wr_data => s_rx_fifo_wr_data,
130
+            i_wr_en   => s_rx_fifo_wr_en,
131
+            o_rd_rdy  => s_rx_fifo_rd_rdy,
132
+            o_rd_data => s_rx_fifo_rd_data,
133
+            i_rd_en   => s_rx_fifo_rd_en
134
+        );
135
+
136
+    -- so far only for testing
137
+    p_rx_test: PROCESS (i_addr, i_wr_data, i_wr_en,
138
+                        s_rx_fifo_rd_rdy, s_rx_fifo_rd_data)
139
+    BEGIN
140
+        o_rd_data       <= X"00000000";
141
+        s_rx_fifo_rd_en <= '0';
142
+        IF i_addr = "00" THEN
143
+            o_rd_data(0) <= s_rx_fifo_rd_rdy;
144
+        ELSIF i_addr = "01" THEN
145
+            o_rd_data(7 DOWNTO 0) <= s_rx_fifo_rd_data;
146
+            IF i_wr_en(0) = '1' THEN
147
+                s_rx_fifo_rd_en <= '1';
148
+            END IF;
149
+        END IF;
150
+    END PROCESS p_rx_test;
151
+
152
+    pin_o_txd   <= "0000";
153
+    pin_o_tx_en <= '0';
154
+
155
+END ARCHITECTURE a_io_eth;
156
+
... ...
@@ -0,0 +1,40 @@
1
+LIBRARY IEEE;
2
+USE IEEE.STD_LOGIC_1164.ALL;
3
+USE IEEE.NUMERIC_STD.ALL;
4
+
5
+ENTITY e_io_eth_rst IS
6
+    PORT (
7
+        rst:        IN  std_logic;
8
+        clk:        IN  std_logic;
9
+        pin_o_nrst: OUT std_logic
10
+    );
11
+END ENTITY e_io_eth_rst;
12
+
13
+ARCHITECTURE a_io_eth_rst OF e_io_eth_rst IS
14
+
15
+    CONSTANT c_rst_dur: natural := 5000;
16
+
17
+    SIGNAL r_rst_cnt: natural RANGE 0 TO c_rst_dur - 1 := 0;
18
+
19
+    SIGNAL r_nrst: std_logic := '0';
20
+
21
+BEGIN
22
+
23
+    p_rst: PROCESS(rst, clk)
24
+    BEGIN
25
+        IF rst = '1' THEN
26
+            r_rst_cnt <= 0;
27
+            r_nrst    <= '0';
28
+        ELSIF rising_edge(clk) THEN
29
+            IF r_rst_cnt = c_rst_dur - 1 THEN
30
+                r_nrst <= '1';
31
+            ELSE
32
+                r_rst_cnt <= r_rst_cnt + 1;
33
+            END IF;
34
+        END IF;
35
+    END PROCESS p_rst;
36
+
37
+    pin_o_nrst <= r_nrst;
38
+
39
+END ARCHITECTURE a_io_eth_rst;
40
+
... ...
@@ -0,0 +1,192 @@
1
+LIBRARY IEEE;
2
+USE IEEE.STD_LOGIC_1164.ALL;
3
+USE IEEE.NUMERIC_STD.ALL;
4
+
5
+ENTITY e_io_eth_rxif IS
6
+    PORT (
7
+        rst:          IN  std_logic;
8
+        clk:          IN  std_logic;
9
+        o_data:       OUT std_logic_vector(7 DOWNTO 0);
10
+        o_data_en:    OUT std_logic;
11
+        o_done:       OUT std_logic;
12
+        o_err:        OUT std_logic;
13
+        pin_i_rx_clk: IN  std_logic;
14
+        pin_i_rxd:    IN  std_logic_vector(4 DOWNTO 0);
15
+        pin_i_rx_dv:  IN  std_logic;
16
+        pin_i_crs:    IN  std_logic;
17
+        pin_i_col:    IN  std_logic
18
+    );
19
+END ENTITY e_io_eth_rxif;
20
+
21
+ARCHITECTURE a_io_eth_rxif OF e_io_eth_rxif IS
22
+
23
+    TYPE t_in_state IS (in_idle, in_nibble, in_data, in_pre_done, in_done,
24
+                        in_pre_err, in_err, in_post_err);
25
+
26
+    SIGNAL r_in_state: t_in_state                   := in_idle;
27
+    SIGNAL r_in_data:  std_logic_vector(7 DOWNTO 0) := X"00";
28
+
29
+    TYPE t_if_event IS (if_data, if_done, if_err);
30
+
31
+    SIGNAL r_if_rx_clk_trigger: std_logic                    := '0';
32
+    SIGNAL r_if_rx_clk_event:   t_if_event                   := if_data;
33
+    SIGNAL r_if_rx_clk_data:    std_logic_vector(7 DOWNTO 0) := X"00";
34
+
35
+    SIGNAL r_if_clk_trigger: std_logic                    := '0';
36
+    SIGNAL r_if_clk_event:   t_if_event                   := if_data;
37
+    SIGNAL r_if_clk_data:    std_logic_vector(7 DOWNTO 0) := X"00";
38
+    SIGNAL r_if_clk_en:      std_logic                    := '0';
39
+
40
+    SIGNAL r_out_data:    std_logic_vector(7 DOWNTO 0) := X"00";
41
+    SIGNAL r_out_data_en: std_logic                    := '0';
42
+    SIGNAL r_out_done:    std_logic                    := '0';
43
+    SIGNAL r_out_err:     std_logic                    := '0';
44
+
45
+BEGIN
46
+
47
+    p_in: PROCESS(rst, pin_i_rx_clk)
48
+    BEGIN
49
+        IF rst = '1' THEN
50
+            r_in_state <= in_idle;
51
+            r_in_data  <= X"00";
52
+        ELSIF rising_edge(pin_i_rx_clk) THEN
53
+            CASE r_in_state IS
54
+                WHEN in_idle =>
55
+                    IF pin_i_col = '1' THEN
56
+                        r_in_state <= in_pre_err;
57
+                    ELSIF pin_i_crs = '1' AND pin_i_rx_dv = '1' THEN
58
+                        IF pin_i_rxd(4) = '1' THEN -- rxd(4) is rx_err
59
+                            r_in_state <= in_pre_err;
60
+                        ELSE
61
+                            r_in_state <= in_nibble;
62
+                            r_in_data(3 DOWNTO 0) <= pin_i_rxd(3 DOWNTO 0);
63
+                        END IF;
64
+                    END IF;
65
+                WHEN in_nibble =>
66
+                    IF pin_i_col = '1' THEN
67
+                        r_in_state <= in_err;
68
+                    ELSIF pin_i_crs = '0' OR pin_i_rx_dv = '0' THEN
69
+                        r_in_state <= in_err;
70
+                    ELSIF pin_i_rxd(4) = '1' THEN -- rxd(4) is rx_err
71
+                        r_in_state <= in_err;
72
+                    ELSE
73
+                        r_in_state <= in_data;
74
+                        r_in_data(7 DOWNTO 4) <= pin_i_rxd(3 DOWNTO 0);
75
+                    END IF;
76
+                WHEN in_data =>
77
+                    IF pin_i_col = '1' THEN
78
+                        r_in_state <= in_pre_err;
79
+                    ELSIF pin_i_crs = '0' OR pin_i_rx_dv = '0' THEN
80
+                        r_in_state <= in_pre_done;
81
+                    ELSIF pin_i_rxd(4) = '1' THEN -- rxd(4) is rx_err
82
+                        r_in_state <= in_pre_err;
83
+                    ELSE
84
+                        r_in_state <= in_nibble;
85
+                        r_in_data(3 DOWNTO 0) <= pin_i_rxd(3 DOWNTO 0);
86
+                    END IF;
87
+                WHEN in_pre_done =>
88
+                    IF pin_i_col = '1' THEN
89
+                        r_in_state <= in_err;
90
+                    ELSIF pin_i_crs = '1' AND pin_i_rx_dv = '1' THEN
91
+                        r_in_state <= in_err;
92
+                    ELSE
93
+                        r_in_state <= in_done;
94
+                    END IF;
95
+                WHEN in_done =>
96
+                    IF pin_i_col = '1' THEN
97
+                        r_in_state <= in_pre_err;
98
+                    ELSIF pin_i_crs = '1' AND pin_i_rx_dv = '1' THEN
99
+                        r_in_state <= in_err;
100
+                    ELSE
101
+                        r_in_state <= in_idle;
102
+                    END IF;
103
+                WHEN in_pre_err =>
104
+                    r_in_state <= in_err;
105
+                WHEN in_err =>
106
+                    r_in_state <= in_post_err;
107
+                WHEN in_post_err =>
108
+                    IF pin_i_col = '0' AND pin_i_crs = '0'
109
+                                       AND pin_i_rx_dv = '0' THEN
110
+                        r_in_state <= in_idle;
111
+                    END IF;
112
+                WHEN OTHERS => NULL;
113
+            END CASE;
114
+        END IF;
115
+    END PROCESS p_in;
116
+
117
+    p_if_rx_clk: PROCESS(rst, pin_i_rx_clk)
118
+    BEGIN
119
+        IF rst = '1' THEN
120
+            r_if_rx_clk_trigger <= '0';
121
+            r_if_rx_clk_event   <= if_data;
122
+            r_if_rx_clk_data    <= X"00";
123
+        ELSIF rising_edge(pin_i_rx_clk) THEN
124
+            CASE r_in_state IS
125
+                WHEN in_data =>
126
+                    r_if_rx_clk_trigger <= NOT r_if_rx_clk_trigger;
127
+                    r_if_rx_clk_event   <= if_data;
128
+                    r_if_rx_clk_data    <= r_in_data;
129
+                WHEN in_done =>
130
+                    r_if_rx_clk_trigger <= NOT r_if_rx_clk_trigger;
131
+                    r_if_rx_clk_event   <= if_done;
132
+                WHEN in_err =>
133
+                    r_if_rx_clk_trigger <= NOT r_if_rx_clk_trigger;
134
+                    r_if_rx_clk_event   <= if_err;
135
+                WHEN OTHERS => NULL;
136
+            END CASE;
137
+        END IF;
138
+    END PROCESS p_if_rx_clk;
139
+
140
+    p_if_clk: PROCESS(rst, clk)
141
+    BEGIN
142
+        IF rst = '1' THEN
143
+            r_if_clk_trigger <= '0';
144
+            r_if_clk_event   <= if_data;
145
+            r_if_clk_data    <= X"00";
146
+            r_if_clk_en      <= '0';
147
+        ELSIF rising_edge(clk) THEN
148
+            IF r_if_rx_clk_trigger /= r_if_clk_trigger THEN
149
+                r_if_clk_trigger <= NOT r_if_clk_trigger;
150
+                r_if_clk_event   <= r_if_rx_clk_event;
151
+                r_if_clk_data    <= r_if_rx_clk_data;
152
+                r_if_clk_en      <= '1';
153
+            ELSE
154
+                r_if_clk_en      <= '0';
155
+            END IF;
156
+        END IF;
157
+    END PROCESS p_if_clk;
158
+
159
+    p_out: PROCESS(rst, clk)
160
+    BEGIN
161
+        IF rst = '1' THEN
162
+            r_out_data    <= X"00";
163
+            r_out_data_en <= '0';
164
+            r_out_done    <= '0';
165
+            r_out_err     <= '0';
166
+        ELSIF rising_edge(clk) THEN
167
+            r_out_data    <= X"00";
168
+            r_out_data_en <= '0';
169
+            r_out_done    <= '0';
170
+            r_out_err     <= '0';
171
+            IF r_if_clk_en = '1' THEN
172
+                CASE r_if_clk_event IS
173
+                    WHEN if_data =>
174
+                        r_out_data    <= r_if_clk_data;
175
+                        r_out_data_en <= '1';
176
+                    WHEN if_done =>
177
+                        r_out_done    <= '1';
178
+                    WHEN if_err =>
179
+                        r_out_err     <= '1';
180
+                    WHEN OTHERS => NULL;
181
+                END CASE;
182
+            END IF;
183
+        END IF;
184
+    END PROCESS p_out;
185
+
186
+    o_data    <= r_out_data;
187
+    o_data_en <= r_out_data_en;
188
+    o_done    <= r_out_done;
189
+    o_err     <= r_out_err;
190
+
191
+END ARCHITECTURE a_io_eth_rxif;
192
+
... ...
@@ -28,8 +28,8 @@
28 28
       <association xil_pn:name="Implementation" xil_pn:seqID="9"/>
29 29
     </file>
30 30
     <file xil_pn:name="mips/core.vhd" xil_pn:type="FILE_VHDL">
31
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="13"/>
32
-      <association xil_pn:name="Implementation" xil_pn:seqID="13"/>
31
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="15"/>
32
+      <association xil_pn:name="Implementation" xil_pn:seqID="15"/>
33 33
     </file>
34 34
     <file xil_pn:name="mips/regs.vhd" xil_pn:type="FILE_VHDL">
35 35
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="4"/>
... ...
@@ -52,22 +52,22 @@
52 52
       <association xil_pn:name="Implementation" xil_pn:seqID="5"/>
53 53
     </file>
54 54
     <file xil_pn:name="system/system.vhd" xil_pn:type="FILE_VHDL">
55
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="24"/>
56
-      <association xil_pn:name="Implementation" xil_pn:seqID="24"/>
55
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="27"/>
56
+      <association xil_pn:name="Implementation" xil_pn:seqID="27"/>
57 57
     </file>
58 58
     <file xil_pn:name="test/testbed.vhd" xil_pn:type="FILE_VHDL">
59
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="25"/>
59
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="28"/>
60 60
       <association xil_pn:name="PostMapSimulation" xil_pn:seqID="128"/>
61 61
       <association xil_pn:name="PostRouteSimulation" xil_pn:seqID="128"/>
62 62
       <association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="128"/>
63 63
     </file>
64 64
     <file xil_pn:name="fw/rom.vhd" xil_pn:type="FILE_VHDL">
65
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="19"/>
66
-      <association xil_pn:name="Implementation" xil_pn:seqID="19"/>
65
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="22"/>
66
+      <association xil_pn:name="Implementation" xil_pn:seqID="22"/>
67 67
     </file>
68 68
     <file xil_pn:name="io/leds.vhd" xil_pn:type="FILE_VHDL">
69
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="16"/>
70
-      <association xil_pn:name="Implementation" xil_pn:seqID="16"/>
69
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="18"/>
70
+      <association xil_pn:name="Implementation" xil_pn:seqID="18"/>
71 71
     </file>
72 72
     <file xil_pn:name="constraints/leds.ucf" xil_pn:type="FILE_UCF">
73 73
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
... ...
@@ -76,12 +76,12 @@
76 76
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
77 77
     </file>
78 78
     <file xil_pn:name="io/cyc_cnt.vhd" xil_pn:type="FILE_VHDL">
79
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="18"/>
80
-      <association xil_pn:name="Implementation" xil_pn:seqID="18"/>
79
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="21"/>
80
+      <association xil_pn:name="Implementation" xil_pn:seqID="21"/>
81 81
     </file>
82 82
     <file xil_pn:name="io/lcd.vhd" xil_pn:type="FILE_VHDL">
83
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="17"/>
84
-      <association xil_pn:name="Implementation" xil_pn:seqID="17"/>
83
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="19"/>
84
+      <association xil_pn:name="Implementation" xil_pn:seqID="19"/>
85 85
     </file>
86 86
     <file xil_pn:name="io/lcd_pins.vhd" xil_pn:type="FILE_VHDL">
87 87
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="11"/>
... ...
@@ -91,47 +91,66 @@
91 91
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
92 92
     </file>
93 93
     <file xil_pn:name="fw/ram.0.vhd" xil_pn:type="FILE_VHDL">
94
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="23"/>
95
-      <association xil_pn:name="Implementation" xil_pn:seqID="23"/>
94
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="26"/>
95
+      <association xil_pn:name="Implementation" xil_pn:seqID="26"/>
96 96
     </file>
97 97
     <file xil_pn:name="fw/ram.1.vhd" xil_pn:type="FILE_VHDL">
98
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="22"/>
99
-      <association xil_pn:name="Implementation" xil_pn:seqID="22"/>
98
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="25"/>
99
+      <association xil_pn:name="Implementation" xil_pn:seqID="25"/>
100 100
     </file>
101 101
     <file xil_pn:name="fw/ram.2.vhd" xil_pn:type="FILE_VHDL">
102
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="21"/>
103
-      <association xil_pn:name="Implementation" xil_pn:seqID="21"/>
102
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="24"/>
103
+      <association xil_pn:name="Implementation" xil_pn:seqID="24"/>
104 104
     </file>
105 105
     <file xil_pn:name="fw/ram.3.vhd" xil_pn:type="FILE_VHDL">
106
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="20"/>
107
-      <association xil_pn:name="Implementation" xil_pn:seqID="20"/>
106
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="23"/>
107
+      <association xil_pn:name="Implementation" xil_pn:seqID="23"/>
108 108
     </file>
109 109
     <file xil_pn:name="io/switches_pins.vhd" xil_pn:type="FILE_VHDL">
110 110
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="10"/>
111 111
       <association xil_pn:name="Implementation" xil_pn:seqID="10"/>
112 112
     </file>
113 113
     <file xil_pn:name="io/switches.vhd" xil_pn:type="FILE_VHDL">
114
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="15"/>
115
-      <association xil_pn:name="Implementation" xil_pn:seqID="15"/>
114
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="17"/>
115
+      <association xil_pn:name="Implementation" xil_pn:seqID="17"/>
116 116
     </file>
117 117
     <file xil_pn:name="constraints/switches.ucf" xil_pn:type="FILE_UCF">
118 118
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
119 119
     </file>
120 120
     <file xil_pn:name="io/uart.vhd" xil_pn:type="FILE_VHDL">
121
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="14"/>
122
-      <association xil_pn:name="Implementation" xil_pn:seqID="14"/>
121
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="16"/>
122
+      <association xil_pn:name="Implementation" xil_pn:seqID="16"/>
123 123
     </file>
124 124
     <file xil_pn:name="constraints/uart.ucf" xil_pn:type="FILE_UCF">
125 125
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
126 126
     </file>
127 127
     <file xil_pn:name="blocks/fifo.vhd" xil_pn:type="FILE_VHDL">
128
-      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="12"/>
129
-      <association xil_pn:name="Implementation" xil_pn:seqID="12"/>
128
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="14"/>
129
+      <association xil_pn:name="Implementation" xil_pn:seqID="14"/>
130 130
     </file>
131 131
     <file xil_pn:name="blocks/rwram.vhd" xil_pn:type="FILE_VHDL">
132 132
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="3"/>
133 133
       <association xil_pn:name="Implementation" xil_pn:seqID="3"/>
134 134
     </file>
135
+    <file xil_pn:name="io/eth/eth.vhd" xil_pn:type="FILE_VHDL">
136
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="20"/>
137
+      <association xil_pn:name="Implementation" xil_pn:seqID="20"/>
138
+    </file>
139
+    <file xil_pn:name="io/eth/rst.vhd" xil_pn:type="FILE_VHDL">
140
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="13"/>
141
+      <association xil_pn:name="Implementation" xil_pn:seqID="13"/>
142
+    </file>
143
+    <file xil_pn:name="io/eth/rxif.vhd" xil_pn:type="FILE_VHDL">
144
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="12"/>
145
+      <association xil_pn:name="Implementation" xil_pn:seqID="12"/>
146
+    </file>
147
+    <file xil_pn:name="constraints/eth.ucf" xil_pn:type="FILE_UCF">
148
+      <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
149
+    </file>
150
+    <file xil_pn:name="blocks/crc32.vhd" xil_pn:type="FILE_VHDL">
151
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/>
152
+      <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
153
+    </file>
135 154
   </files>
136 155
 
137 156
   <properties>
... ...
@@ -279,7 +298,7 @@
279 298
     <property xil_pn:name="Number of Clock Buffers" xil_pn:value="24" xil_pn:valueState="default"/>
280 299
     <property xil_pn:name="Number of Paths in Error/Verbose Report" xil_pn:value="3" xil_pn:valueState="default"/>
281 300
     <property xil_pn:name="Number of Paths in Error/Verbose Report Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
282
-    <property xil_pn:name="Optimization Effort" xil_pn:value="Normal" xil_pn:valueState="default"/>
301
+    <property xil_pn:name="Optimization Effort" xil_pn:value="High" xil_pn:valueState="non-default"/>
283 302
     <property xil_pn:name="Optimization Goal" xil_pn:value="Speed" xil_pn:valueState="default"/>
284 303
     <property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Speed" xil_pn:valueState="non-default"/>
285 304
     <property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/>
... ...
@@ -449,6 +468,7 @@
449 468
     <binding xil_pn:location="/e_system" xil_pn:name="constraints/lcd.ucf"/>
450 469
     <binding xil_pn:location="/e_system" xil_pn:name="constraints/switches.ucf"/>
451 470
     <binding xil_pn:location="/e_system" xil_pn:name="constraints/uart.ucf"/>
471
+    <binding xil_pn:location="/e_system" xil_pn:name="constraints/eth.ucf"/>
452 472
   </bindings>
453 473
 
454 474
   <libraries/>
... ...
@@ -11,7 +11,16 @@ ENTITY e_system IS
11 11
         pin_o_lcd:        OUT t_io_lcd_pins;
12 12
         pin_i_switches:   IN  t_io_switches_pins;
13 13
         pin_i_uart_rx:    IN  std_logic;
14
-        pin_o_uart_tx:  OUT std_logic
14
+        pin_o_uart_tx:    OUT std_logic;
15
+        pin_o_eth_nrst:   OUT std_logic;
16
+        pin_i_eth_rx_clk: IN  std_logic;
17
+        pin_i_eth_rxd:    IN  std_logic_vector(4 DOWNTO 0);
18
+        pin_i_eth_rx_dv:  IN  std_logic;
19
+        pin_i_eth_crs:    IN  std_logic;
20
+        pin_i_eth_col:    IN  std_logic;
21
+        pin_i_eth_tx_clk: IN  std_logic;
22
+        pin_o_eth_txd:    OUT std_logic_vector(3 DOWNTO 0);
23
+        pin_o_eth_tx_en:  OUT std_logic
15 24
     );
16 25
 END ENTITY e_system;
17 26
 
... ...
@@ -44,6 +53,10 @@ ARCHITECTURE a_system OF e_system IS
44 53
     SIGNAL s_uart_rd_data: std_logic_vector(31 DOWNTO 0);
45 54
     SIGNAL s_uart_wr_data: std_logic_vector(31 DOWNTO 0);
46 55
     SIGNAL s_uart_wr_en:   std_logic_vector( 3 DOWNTO 0);
56
+    SIGNAL s_eth_addr:    std_logic_vector( 3 DOWNTO 0);
57
+    SIGNAL s_eth_rd_data: std_logic_vector(31 DOWNTO 0);
58
+    SIGNAL s_eth_wr_data: std_logic_vector(31 DOWNTO 0);
59
+    SIGNAL s_eth_wr_en:   std_logic_vector( 3 DOWNTO 0);
47 60
     SIGNAL s_cyc_cnt_rd_data: std_logic_vector(31 DOWNTO 0);
48 61
     SIGNAL s_cyc_cnt_wr_data: std_logic_vector(31 DOWNTO 0);
49 62
     SIGNAL s_cyc_cnt_wr_en:   std_logic;
... ...
@@ -170,6 +183,26 @@ ARCHITECTURE a_system OF e_system IS
170 183
         );
171 184
     END COMPONENT e_io_uart;
172 185
 
186
+    COMPONENT e_io_eth IS
187
+        PORT (
188
+            rst:          IN  std_logic;
189
+            clk:          IN  std_logic;
190
+            i_addr:       IN  std_logic_vector( 1 DOWNTO 0);
191
+            o_rd_data:    OUT std_logic_vector(31 DOWNTO 0);
192
+            i_wr_data:    IN  std_logic_vector(31 DOWNTO 0);
193
+            i_wr_en:      IN  std_logic_vector( 3 DOWNTO 0);
194
+            pin_o_nrst:   OUT std_logic;
195
+            pin_i_rx_clk: IN  std_logic;
196
+            pin_i_rxd:    IN  std_logic_vector(4 DOWNTO 0);
197
+            pin_i_rx_dv:  IN  std_logic;
198
+            pin_i_crs:    IN  std_logic;
199
+            pin_i_col:    IN  std_logic;
200
+            pin_i_tx_clk: IN  std_logic;
201
+            pin_o_txd:    OUT std_logic_vector(3 DOWNTO 0);
202
+            pin_o_tx_en:  OUT std_logic
203
+        );
204
+    END COMPONENT e_io_eth;
205
+
173 206
     COMPONENT e_io_cyc_cnt IS
174 207
         PORT (
175 208
             rst:       IN  std_logic;
... ...
@@ -211,6 +244,7 @@ BEGIN
211 244
                     s_lcd_rd_data,
212 245
                     s_switches_rd_data,
213 246
                     s_uart_rd_data,
247
+                    s_eth_rd_data,
214 248
                     s_cyc_cnt_rd_data)
215 249
         VARIABLE v_wr_en_word: std_logic;
216 250
     BEGIN
... ...
@@ -228,6 +262,9 @@ BEGIN
228 262
         s_uart_addr    <= (OTHERS => '0');
229 263
         s_uart_wr_data <= (OTHERS => '0');
230 264
         s_uart_wr_en   <= (OTHERS => '0');
265
+        s_eth_addr    <= (OTHERS => '0');
266
+        s_eth_wr_data <= (OTHERS => '0');
267
+        s_eth_wr_en   <= (OTHERS => '0');
231 268
         s_cyc_cnt_wr_data <= (OTHERS => '0');
232 269
         s_cyc_cnt_wr_en   <= '0';
233 270
         IF s_dbus_addr(31) = '0' THEN
... ...
@@ -253,6 +290,11 @@ BEGIN
253 290
                     s_uart_addr    <= s_dbus_addr(3 DOWNTO 0);
254 291
                     s_uart_wr_data <= s_dbus_wr_data;
255 292
                     s_uart_wr_en   <= s_dbus_wr_en;
293
+                WHEN X"04" =>
294
+                    s_dbus_rd_data <= s_eth_rd_data;
295
+                    s_eth_addr     <= s_dbus_addr(3 DOWNTO 0);
296
+                    s_eth_wr_data  <= s_dbus_wr_data;
297
+                    s_eth_wr_en    <= s_dbus_wr_en;
256 298
                 WHEN X"10" =>
257 299
                     s_dbus_rd_data    <= s_cyc_cnt_rd_data;
258 300
                     s_cyc_cnt_wr_data <= s_dbus_wr_data;
... ...
@@ -351,6 +393,25 @@ BEGIN
351 393
             pin_o_tx  => pin_o_uart_tx
352 394
         );
353 395
 
396
+    eth: e_io_eth
397
+        PORT MAP (
398
+            rst          => rst,
399
+            clk          => clk,
400
+            i_addr       => s_eth_addr(3 DOWNTO 2),
401
+            o_rd_data    => s_eth_rd_data,
402
+            i_wr_data    => s_eth_wr_data,
403
+            i_wr_en      => s_eth_wr_en,
404
+            pin_o_nrst   => pin_o_eth_nrst,
405
+            pin_i_rx_clk => pin_i_eth_rx_clk,
406
+            pin_i_rxd    => pin_i_eth_rxd,
407
+            pin_i_rx_dv  => pin_i_eth_rx_dv,
408
+            pin_i_crs    => pin_i_eth_crs,
409
+            pin_i_col    => pin_i_eth_col,
410
+            pin_i_tx_clk => pin_i_eth_tx_clk,
411
+            pin_o_txd    => pin_o_eth_txd,
412
+            pin_o_tx_en  => pin_o_eth_tx_en
413
+        );
414
+
354 415
     cyc_cnt: e_io_cyc_cnt
355 416
         PORT MAP (
356 417
             rst       => rst,
... ...
@@ -17,7 +17,15 @@ ARCHITECTURE a_testbed OF e_testbed IS
17 17
             pin_o_lcd:        OUT t_io_lcd_pins;
18 18
             pin_i_switches:   IN  t_io_switches_pins;
19 19
             pin_i_uart_rx:    IN  std_logic;
20
-            pin_o_uart_tx:  OUT std_logic
20
+            pin_o_uart_tx:    OUT std_logic;
21
+            pin_i_eth_rx_clk: IN  std_logic;
22
+            pin_i_eth_rxd:    IN  std_logic_vector(4 DOWNTO 0);
23
+            pin_i_eth_rx_dv:  IN  std_logic;
24
+            pin_i_eth_crs:    IN  std_logic;
25
+            pin_i_eth_col:    IN  std_logic;
26
+            pin_i_eth_tx_clk: IN  std_logic;
27
+            pin_o_eth_txd:    OUT std_logic_vector(3 DOWNTO 0);
28
+            pin_o_eth_tx_en:  OUT std_logic
21 29
         );
22 30
     END COMPONENT e_system;
23 31
 
... ...
@@ -25,6 +33,8 @@ ARCHITECTURE a_testbed OF e_testbed IS
25 33
     SIGNAL pin_leds:          std_logic_vector(7 DOWNTO 0);
26 34
     SIGNAL pin_lcd:           t_io_lcd_pins;
27 35
     SIGNAL pin_uart_loopback: std_logic;
36
+    SIGNAL pin_eth_txd:       std_logic_vector(3 DOWNTO 0);
37
+    SIGNAL pin_eth_tx_en:     std_logic;
28 38
 
29 39
 BEGIN
30 40
 
... ...
@@ -35,7 +45,15 @@ BEGIN
35 45
             pin_o_lcd        => pin_lcd,
36 46
             pin_i_switches   => (sw => (OTHERS => '0'), OTHERS => '0'),
37 47
             pin_i_uart_rx    => pin_uart_loopback,
38
-            pin_o_uart_tx  => pin_uart_loopback
48
+            pin_o_uart_tx    => pin_uart_loopback,
49
+            pin_i_eth_rx_clk => '0',
50
+            pin_i_eth_rxd    => "00000",
51
+            pin_i_eth_rx_dv  => '0',
52
+            pin_i_eth_crs    => '0',
53
+            pin_i_eth_col    => '0',
54
+            pin_i_eth_tx_clk => '0',
55
+            pin_o_eth_txd    => pin_eth_txd,
56
+            pin_o_eth_tx_en  => pin_eth_tx_en
39 57
         );
40 58
 
41 59
     p_rst_clk: PROCESS
42 60