Stefan Schuermans commited on 2012-03-24 16:42:53
              Showing 12 changed files, with 82 additions and 85 deletions.
            
| ... | ... | @@ -30,24 +30,24 @@ struct arp_table | 
| 30 | 30 | */ | 
| 31 | 31 | static void arp_send_request(unsigned char ip[4]) | 
| 32 | 32 |  { | 
| 33 | - struct arp_packet_pad arp_request; | |
| 33 | + struct arp_packet arp_request; | |
| 34 | 34 |  | 
| 35 | 35 | // build ARP request | 
| 36 | - arp_request.p.arp_hdr.hw_type = htons(0x0001); // ethernet | |
| 37 | - arp_request.p.arp_hdr.proto_type = htons(0x0800); // IP | |
| 38 | - arp_request.p.arp_hdr.hw_len = 0x06; // length of a MAC address | |
| 39 | - arp_request.p.arp_hdr.proto_len = 0x04; // length of an IP address | |
| 40 | - arp_request.p.arp_hdr.op = htons(0x0001); // ARP request | |
| 41 | - mac_cpy(arp_request.p.arp_hdr.src_mac, config_mac.mac); // own MAC | |
| 42 | - ip_cpy(arp_request.p.arp_hdr.src_ip, config_ip.ip); // own IP | |
| 43 | - mac_cpy(arp_request.p.arp_hdr.dest_mac, | |
| 36 | + arp_request.arp_hdr.hw_type = htons(0x0001); // ethernet | |
| 37 | + arp_request.arp_hdr.proto_type = htons(0x0800); // IP | |
| 38 | + arp_request.arp_hdr.hw_len = 0x06; // length of a MAC address | |
| 39 | + arp_request.arp_hdr.proto_len = 0x04; // length of an IP address | |
| 40 | + arp_request.arp_hdr.op = htons(0x0001); // ARP request | |
| 41 | + mac_cpy(arp_request.arp_hdr.src_mac, config_mac.mac); // own MAC | |
| 42 | + ip_cpy(arp_request.arp_hdr.src_ip, config_ip.ip); // own IP | |
| 43 | + mac_cpy(arp_request.arp_hdr.dest_mac, | |
| 44 | 44 | "\xFF\xFF\xFF\xFF\xFF\xFF"); // broadcast MAC | 
| 45 | - ip_cpy(arp_request.p.arp_hdr.dest_ip, ip); // requested IP | |
| 45 | + ip_cpy(arp_request.arp_hdr.dest_ip, ip); // requested IP | |
| 46 | 46 |  | 
| 47 | 47 | // send ARP request | 
| 48 | - mac_cpy(arp_request.p.eth_hdr.dest, arp_request.p.arp_hdr.dest_mac); | |
| 49 | - arp_request.p.eth_hdr.type = htons(0x0806); // ethernet packet type: ARP | |
| 50 | - ethernet_send(&arp_request.p, sizeof(arp_request.p)); | |
| 48 | + mac_cpy(arp_request.eth_hdr.dest, arp_request.arp_hdr.dest_mac); | |
| 49 | + arp_request.eth_hdr.type = htons(0x0806); // ethernet packet type: ARP | |
| 50 | + ethernet_send(&arp_request, sizeof(arp_request)); | |
| 51 | 51 | } | 
| 52 | 52 |  | 
| 53 | 53 | /// initialize | 
| ... | ... | @@ -116,26 +116,26 @@ void arp_recv(void *ptr, unsigned int sz) | 
| 116 | 116 | // ARP request for own IP address | 
| 117 | 117 | if (arp_pack->arp_hdr.op == htons(0x0001) && // ARP request | 
| 118 | 118 |        ip_eq(arp_pack->arp_hdr.dest_ip, config_ip.ip)) { // own IP address | 
| 119 | - struct arp_packet_pad arp_reply; | |
| 119 | + struct arp_packet arp_reply; | |
| 120 | 120 |  | 
| 121 | 121 | // build ARP reply | 
| 122 | - arp_reply.p.arp_hdr.hw_type = htons(0x0001); // ethernet | |
| 123 | - arp_reply.p.arp_hdr.proto_type = htons(0x0800); // IP | |
| 124 | - arp_reply.p.arp_hdr.hw_len = 0x06; // length of a MAC address | |
| 125 | - arp_reply.p.arp_hdr.proto_len = 0x04; // length of an IP address | |
| 126 | - arp_reply.p.arp_hdr.op = htons(0x0002); // ARP reply | |
| 127 | - mac_cpy(arp_reply.p.arp_hdr.src_mac, config_mac.mac); // own MAC | |
| 128 | - ip_cpy(arp_reply.p.arp_hdr.src_ip, config_ip.ip); // own IP | |
| 129 | - mac_cpy(arp_reply.p.arp_hdr.dest_mac, | |
| 122 | + arp_reply.arp_hdr.hw_type = htons(0x0001); // ethernet | |
| 123 | + arp_reply.arp_hdr.proto_type = htons(0x0800); // IP | |
| 124 | + arp_reply.arp_hdr.hw_len = 0x06; // length of a MAC address | |
| 125 | + arp_reply.arp_hdr.proto_len = 0x04; // length of an IP address | |
| 126 | + arp_reply.arp_hdr.op = htons(0x0002); // ARP reply | |
| 127 | + mac_cpy(arp_reply.arp_hdr.src_mac, config_mac.mac); // own MAC | |
| 128 | + ip_cpy(arp_reply.arp_hdr.src_ip, config_ip.ip); // own IP | |
| 129 | + mac_cpy(arp_reply.arp_hdr.dest_mac, | |
| 130 | 130 | arp_pack->arp_hdr.src_mac); // requestor's MAC | 
| 131 | - ip_cpy(arp_reply.p.arp_hdr.dest_ip, | |
| 131 | + ip_cpy(arp_reply.arp_hdr.dest_ip, | |
| 132 | 132 | arp_pack->arp_hdr.src_ip); // requestor's IP | 
| 133 | 133 |  | 
| 134 | 134 | // send ARP reply | 
| 135 | - mac_cpy(arp_reply.p.eth_hdr.dest, | |
| 136 | - arp_reply.p.arp_hdr.dest_mac); // ethernet destination address | |
| 137 | - arp_reply.p.eth_hdr.type = htons(0x0806); // ethernet packet type: ARP | |
| 138 | - ethernet_send(&arp_reply.p, sizeof(arp_reply.p)); | |
| 135 | + mac_cpy(arp_reply.eth_hdr.dest, | |
| 136 | + arp_reply.arp_hdr.dest_mac); // ethernet destination address | |
| 137 | + arp_reply.eth_hdr.type = htons(0x0806); // ethernet packet type: ARP | |
| 138 | + ethernet_send(&arp_reply, sizeof(arp_reply)); | |
| 139 | 139 |  | 
| 140 | 140 | return; | 
| 141 | 141 | } | 
| ... | ... | @@ -116,7 +116,7 @@ int eth_rx(void **pptr, unsigned int *psz) | 
| 116 | 116 | */ | 
| 117 | 117 | void eth_tx(const void *ptr, unsigned int sz) | 
| 118 | 118 |  { | 
| 119 | - while(sz < 60 || sz & 3) /* pad with zeros */ | |
| 119 | + while(sz & 3) /* pad with zeros */ | |
| 120 | 120 | ((unsigned char *)ptr)[sz++] = 0; | 
| 121 | 121 | eth_ptr[8] = (unsigned int)ptr; /* start */ | 
| 122 | 122 | eth_ptr[9] = (unsigned int)ptr + sz; /* end */ | 
| ... | ... | @@ -46,7 +46,7 @@ void ethernet_recv(void *ptr, unsigned int sz) | 
| 46 | 46 | * @param[in] ptr pointer to data of packet | 
| 47 | 47 | * @param[in] sz size of packet | 
| 48 | 48 | * | 
| 49 | - * ptr must point to a ethernet_packet of sufficient size (ethernet padding) | |
| 49 | + * ptr must point to a ethernet_packet | |
| 50 | 50 | * with eth_hdr.dest and eth_hdr.type already initialized | 
| 51 | 51 | */ | 
| 52 | 52 | void ethernet_send(void *ptr, unsigned int sz) | 
| ... | ... | @@ -1,19 +1,6 @@ | 
| 1 | 1 | #ifndef ETHERNET_H | 
| 2 | 2 | #define ETHERNET_H | 
| 3 | 3 |  | 
| 4 | -/** padding at end of packet | |
| 5 | - to reach next size divisible by 4 and at least 60 bytes */ | |
| 6 | -#define ETHERNET_PADDING_SIZE(packet) \ | |
| 7 | - (sizeof(struct packet) >= 60 ? 0 : 60 - sizeof(struct packet)) | |
| 8 | -#define ETHERNET_PADDING(packet) \ | |
| 9 | - unsigned char padding[ETHERNET_PADDING_SIZE(packet)] | |
| 10 | -#define ETHERNET_PAD(packet) \ | |
| 11 | - struct packet ## _pad \ | |
| 12 | -        { \ | |
| 13 | - struct packet p; \ | |
| 14 | - ETHERNET_PADDING(packet); \ | |
| 15 | - } __attribute__((packed)) | |
| 16 | - | |
| 17 | 4 | /// header of ethernet packet | 
| 18 | 5 | struct ethernet_header | 
| 19 | 6 |  { | 
| ... | ... | @@ -28,9 +15,6 @@ struct ethernet_packet | 
| 28 | 15 | struct ethernet_header eth_hdr; | 
| 29 | 16 | } __attribute__((packed)); | 
| 30 | 17 |  | 
| 31 | -/// ethernet packet with padding | |
| 32 | -ETHERNET_PAD(ethernet_packet); | |
| 33 | - | |
| 34 | 18 | /** | 
| 35 | 19 | * @brief process a received ethernet packet | 
| 36 | 20 | * @param[in] ptr pointer to data of packet | 
| ... | ... | @@ -43,7 +27,7 @@ void ethernet_recv(void *ptr, unsigned int sz); | 
| 43 | 27 | * @param[in] ptr pointer to data of packet | 
| 44 | 28 | * @param[in] sz size of packet | 
| 45 | 29 | * | 
| 46 | - * ptr must point to a ethernet_packet of sufficient size (ethernet padding) | |
| 30 | + * ptr must point to a ethernet_packet | |
| 47 | 31 | * with eth_hdr.dest and eth_hdr.type already initialized | 
| 48 | 32 | */ | 
| 49 | 33 | void ethernet_send(void *ptr, unsigned int sz); | 
| ... | ... | @@ -10,7 +10,7 @@ | 
| 10 | 10 | * @param[in] ptr pointer to data of packet | 
| 11 | 11 | * @param[in] sz size of packet | 
| 12 | 12 | * | 
| 13 | - * ptr must point to a icmp_packet of sufficient size (ethernet padding) | |
| 13 | + * ptr must point to a icmp_packet | |
| 14 | 14 | * with icmp_hdr.type, icmp_hdr.code and ip_hdr.sest already initialized | 
| 15 | 15 | */ | 
| 16 | 16 | static void icmp_send(void *ptr, unsigned int sz) | 
| ... | ... | @@ -20,9 +20,6 @@ struct icmp_packet | 
| 20 | 20 | struct icmp_header icmp_hdr; | 
| 21 | 21 | } __attribute__((packed)); | 
| 22 | 22 |  | 
| 23 | -/// ICMP packet with padding | |
| 24 | -ETHERNET_PAD(icmp_packet); | |
| 25 | - | |
| 26 | 23 | // header of ICMP echo request/reply packet | 
| 27 | 24 | struct icmp_echo_header | 
| 28 | 25 |  { | 
| ... | ... | @@ -39,9 +36,6 @@ struct icmp_echo_packet | 
| 39 | 36 | struct icmp_echo_header echo_hdr; | 
| 40 | 37 | } __attribute__((packed)); | 
| 41 | 38 |  | 
| 42 | -/// ICMP echo request/reply packet with padding | |
| 43 | -ETHERNET_PAD(icmp_echo_packet); | |
| 44 | - | |
| 45 | 39 | /** | 
| 46 | 40 | * @brief process a received ICMP packet | 
| 47 | 41 | * @param[in] ptr pointer to data of packet | 
| ... | ... | @@ -17,7 +17,6 @@ | 
| 17 | 17 | * - used if MAC is unknown when packet shall be transmitted | 
| 18 | 18 | * - packet is sent when MAC becomes known | 
| 19 | 19 | * - some buffers with different length (packets have different lengths) | 
| 20 | - * - all buffers must be larger than min ethernet frame size (eth padding) | |
| 21 | 20 | */ | 
| 22 | 21 |  //@{ | 
| 23 | 22 | unsigned int ip_buffer0[20]; | 
| ... | ... | @@ -185,7 +184,7 @@ void ip_recv(void *ptr, unsigned int sz) | 
| 185 | 184 | * @param[in] ptr pointer to data of packet | 
| 186 | 185 | * @param[in] sz size of packet | 
| 187 | 186 | * | 
| 188 | - * ptr must point to a ip_packet of sufficient size (ethernet padding) | |
| 187 | + * ptr must point to a ip_packet | |
| 189 | 188 | * with ip_hdr.proto and ip_hdr.dest already initialized | 
| 190 | 189 | */ | 
| 191 | 190 | void ip_send(void *ptr, unsigned int sz) | 
| ... | ... | @@ -25,9 +25,6 @@ struct ip_packet | 
| 25 | 25 | struct ip_header ip_hdr; | 
| 26 | 26 | } __attribute__((packed)); | 
| 27 | 27 |  | 
| 28 | -/// IP packet with padding | |
| 29 | -ETHERNET_PAD(ip_packet); | |
| 30 | - | |
| 31 | 28 | /// initialize | 
| 32 | 29 | void ip_init(void); | 
| 33 | 30 |  | 
| ... | ... | @@ -46,7 +43,7 @@ void ip_recv(void *ptr, unsigned int sz); | 
| 46 | 43 | * @param[in] ptr pointer to data of packet | 
| 47 | 44 | * @param[in] sz size of packet | 
| 48 | 45 | * | 
| 49 | - * ptr must point to a ip_packet of sufficient size (ethernet padding) | |
| 46 | + * ptr must point to a ip_packet | |
| 50 | 47 | * with ip_hdr.proto and ip_hdr.dest already initialized | 
| 51 | 48 | */ | 
| 52 | 49 | void ip_send(void *ptr, unsigned int sz); | 
| ... | ... | @@ -29,7 +29,7 @@ void udp_recv(void *ptr, unsigned int sz) | 
| 29 | 29 | * @param[in] ptr pointer to data of packet | 
| 30 | 30 | * @param[in] sz size of packet | 
| 31 | 31 | * | 
| 32 | - * ptr must point to a udp_packet of sufficient size (ethernet padding) | |
| 32 | + * ptr must point to a udp_packet | |
| 33 | 33 | * with ip_hdr.proto and udp_hdr.src_port, udp_hdr.dest_port, ip_hdr.dest | 
| 34 | 34 | * already initialized | 
| 35 | 35 | */ | 
| ... | ... | @@ -21,9 +21,6 @@ struct udp_packet | 
| 21 | 21 | struct udp_header udp_hdr; | 
| 22 | 22 | } __attribute__((packed)); | 
| 23 | 23 |  | 
| 24 | -/// UDP packet with padding | |
| 25 | -ETHERNET_PAD(udp_packet); | |
| 26 | - | |
| 27 | 24 | /// tick procedure - call every 200ms | 
| 28 | 25 | void udp_tick200(void); | 
| 29 | 26 |  | 
| ... | ... | @@ -39,7 +36,7 @@ void udp_recv(void *ptr, unsigned int sz); | 
| 39 | 36 | * @param[in] ptr pointer to data of packet | 
| 40 | 37 | * @param[in] sz size of packet | 
| 41 | 38 | * | 
| 42 | - * ptr must point to a udp_packet of sufficient size (ethernet padding) | |
| 39 | + * ptr must point to a udp_packet | |
| 43 | 40 | * with ip_hdr.proto and udp_hdr.src_port, udp_hdr.dest_port, ip_hdr.dest | 
| 44 | 41 | * already initialized | 
| 45 | 42 | */ | 
| ... | ... | @@ -19,9 +19,11 @@ END ENTITY e_io_eth_txframe; | 
| 19 | 19 |  | 
| 20 | 20 | ARCHITECTURE a_io_eth_txframe OF e_io_eth_txframe IS | 
| 21 | 21 |  | 
| 22 | - TYPE t_state IS (st_idle, st_sync, st_start, st_data, st_crc, st_gap); | |
| 22 | + TYPE t_state IS (st_idle, st_sync, st_start, st_data, | |
| 23 | + st_pad, st_crc, st_gap); | |
| 23 | 24 |  | 
| 24 | - SUBTYPE t_data_cnt IS natural RANGE 0 TO 255; | |
| 25 | + SUBTYPE t_data_cnt IS natural RANGE 0 TO 3; | |
| 26 | + SUBTYPE t_byte_cnt IS natural RANGE 0 TO 255; | |
| 25 | 27 |  | 
| 26 | 28 | SIGNAL r_state: t_state := st_idle; | 
| 27 | 29 | SIGNAL n_state: t_state; | 
| ... | ... | @@ -29,6 +31,8 @@ ARCHITECTURE a_io_eth_txframe OF e_io_eth_txframe IS | 
| 29 | 31 | SIGNAL n_data_cnt: t_data_cnt; | 
| 30 | 32 | SIGNAL r_data: std_logic_vector(31 DOWNTO 0) := (OTHERS => '0'); | 
| 31 | 33 | SIGNAL n_data: std_logic_vector(31 DOWNTO 0); | 
| 34 | + SIGNAL r_byte_cnt: t_byte_cnt := 0; | |
| 35 | + SIGNAL n_byte_cnt: t_byte_cnt; | |
| 32 | 36 | SIGNAL r_crc_start: std_logic := '0'; | 
| 33 | 37 | SIGNAL n_crc_start: std_logic; | 
| 34 | 38 |  | 
| ... | ... | @@ -60,7 +64,7 @@ BEGIN | 
| 60 | 64 | o_crc => s_crc_crc | 
| 61 | 65 | ); | 
| 62 | 66 |  | 
| 63 | - p_next: PROCESS(r_state, r_data_cnt, r_data, r_crc_start, | |
| 67 | + p_next: PROCESS(r_state, r_data_cnt, r_data, r_byte_cnt, r_crc_start, | |
| 64 | 68 | i_if_data_ack, | 
| 65 | 69 | i_frame_en, i_frame_data, i_frame_data_en, | 
| 66 | 70 | s_crc_crc) | 
| ... | ... | @@ -69,6 +73,7 @@ BEGIN | 
| 69 | 73 | n_state <= r_state; | 
| 70 | 74 | n_data_cnt <= r_data_cnt; | 
| 71 | 75 | n_data <= r_data; | 
| 76 | + n_byte_cnt <= r_byte_cnt; | |
| 72 | 77 | n_crc_start <= '0'; | 
| 73 | 78 | o_if_data <= X"00"; | 
| 74 | 79 | o_if_data_en <= '0'; | 
| ... | ... | @@ -81,14 +86,14 @@ BEGIN | 
| 81 | 86 | WHEN st_idle => | 
| 82 | 87 | IF i_frame_en = '1' THEN | 
| 83 | 88 | n_state <= st_sync; | 
| 84 | - n_data_cnt <= 7; | |
| 89 | + n_byte_cnt <= 0; | |
| 85 | 90 | END IF; | 
| 86 | 91 | WHEN st_sync => | 
| 87 | 92 | IF i_if_data_ack = '1' THEN | 
| 88 | - IF r_data_cnt = 1 THEN | |
| 93 | + IF r_byte_cnt = 6 THEN | |
| 89 | 94 | n_state <= st_start; | 
| 90 | 95 | ELSE | 
| 91 | - n_data_cnt <= r_data_cnt - 1; | |
| 96 | + n_byte_cnt <= r_byte_cnt + 1; | |
| 92 | 97 | END IF; | 
| 93 | 98 | END IF; | 
| 94 | 99 | o_if_data <= X"55"; | 
| ... | ... | @@ -97,62 +102,84 @@ BEGIN | 
| 97 | 102 | IF i_if_data_ack = '1' THEN | 
| 98 | 103 | IF i_frame_data_en = '1' THEN | 
| 99 | 104 | n_state <= st_data; | 
| 100 | - n_data_cnt <= 4; | |
| 105 | + n_data_cnt <= 0; | |
| 101 | 106 | n_data <= i_frame_data; | 
| 107 | + n_byte_cnt <= 0; | |
| 102 | 108 | n_crc_start <= '1'; | 
| 103 | 109 | o_frame_data_ack <= '1'; | 
| 104 | 110 | ELSE | 
| 105 | 111 | n_state <= st_gap; | 
| 106 | - n_data_cnt <= 12 * 8 * 2; -- 12 octets, x2 because of clk | |
| 112 | + n_byte_cnt <= 0; | |
| 107 | 113 | END IF; | 
| 108 | 114 | END IF; | 
| 109 | 115 | o_if_data <= X"D5"; | 
| 110 | 116 | o_if_data_en <= '1'; | 
| 111 | 117 | WHEN st_data => | 
| 112 | 118 | IF i_if_data_ack = '1' THEN | 
| 113 | - IF r_data_cnt = 1 THEN | |
| 119 | + IF r_data_cnt = 3 THEN | |
| 114 | 120 | IF i_frame_data_en = '1' THEN | 
| 115 | 121 | n_state <= st_data; | 
| 116 | - n_data_cnt <= 4; | |
| 122 | + n_data_cnt <= 0; | |
| 117 | 123 | n_data <= i_frame_data; | 
| 118 | 124 | o_frame_data_ack <= '1'; | 
| 119 | 125 | ELSE | 
| 126 | + IF r_byte_cnt = 59 THEN | |
| 120 | 127 | n_state <= st_crc; | 
| 121 | - n_data_cnt <= 4; | |
| 128 | + n_data_cnt <= 0; | |
| 129 | + ELSE | |
| 130 | + n_state <= st_pad; | |
| 131 | + END IF; | |
| 122 | 132 | END IF; | 
| 123 | 133 | ELSE | 
| 124 | - n_data_cnt <= r_data_cnt - 1; | |
| 134 | + n_data_cnt <= r_data_cnt + 1; | |
| 125 | 135 | n_data(23 DOWNTO 0) <= r_data(31 DOWNTO 8); | 
| 126 | 136 | END IF; | 
| 137 | + IF r_byte_cnt /= 59 THEN | |
| 138 | + n_byte_cnt <= r_byte_cnt + 1; | |
| 139 | + END IF; | |
| 127 | 140 | s_crc_en <= '1'; | 
| 128 | 141 | s_crc_start <= r_crc_start; | 
| 129 | 142 | s_crc_data <= r_data(7 DOWNTO 0); | 
| 130 | 143 | END IF; | 
| 131 | 144 | o_if_data <= r_data(7 DOWNTO 0); | 
| 132 | 145 | o_if_data_en <= '1'; | 
| 146 | + WHEN st_pad => | |
| 147 | + IF i_if_data_ack = '1' THEN | |
| 148 | + IF r_byte_cnt = 59 THEN | |
| 149 | + n_state <= st_crc; | |
| 150 | + n_data_cnt <= 0; | |
| 151 | + ELSE | |
| 152 | + n_byte_cnt <= r_byte_cnt + 1; | |
| 153 | + END IF; | |
| 154 | + s_crc_en <= '1'; | |
| 155 | + s_crc_data <= (OTHERS => '0'); | |
| 156 | + END IF; | |
| 157 | + o_if_data <= (OTHERS => '0'); | |
| 158 | + o_if_data_en <= '1'; | |
| 133 | 159 | WHEN st_crc => | 
| 134 | - IF r_data_cnt = 4 THEN | |
| 160 | + IF r_data_cnt = 0 THEN | |
| 135 | 161 | v_data := s_crc_crc; -- get CRC value on first CRC byte | 
| 136 | 162 | ELSE | 
| 137 | 163 | v_data := r_data; | 
| 138 | 164 | END IF; | 
| 139 | 165 | IF i_if_data_ack = '1' THEN | 
| 140 | - IF r_data_cnt = 1 THEN | |
| 166 | + IF r_data_cnt = 3 THEN | |
| 141 | 167 | n_state <= st_gap; | 
| 142 | - n_data_cnt <= 12 * 8 * 2; -- 12 octets, x2 because of clk | |
| 168 | + n_byte_cnt <= 0; | |
| 143 | 169 | ELSE | 
| 144 | - n_data_cnt <= r_data_cnt - 1; | |
| 170 | + n_data_cnt <= r_data_cnt + 1; | |
| 145 | 171 | n_data(23 DOWNTO 0) <= v_data(31 DOWNTO 8); | 
| 146 | 172 | END IF; | 
| 147 | 173 | END IF; | 
| 148 | 174 | o_if_data <= v_data(7 DOWNTO 0); | 
| 149 | 175 | o_if_data_en <= '1'; | 
| 150 | 176 | WHEN st_gap => | 
| 151 | - IF r_data_cnt = 1 THEN | |
| 177 | + -- 12 octets, *2 because of clk, plus async FIFO len | |
| 178 | + IF r_byte_cnt = 12 * 8 * 2 + 16 THEN | |
| 152 | 179 | n_state <= st_idle; | 
| 153 | 180 | o_frame_done <= '1'; | 
| 154 | 181 | ELSE | 
| 155 | - n_data_cnt <= r_data_cnt - 1; | |
| 182 | + n_byte_cnt <= r_byte_cnt + 1; | |
| 156 | 183 | END IF; | 
| 157 | 184 | WHEN OTHERS => NULL; | 
| 158 | 185 | END CASE; | 
| ... | ... | @@ -164,11 +191,13 @@ BEGIN | 
| 164 | 191 | r_state <= st_idle; | 
| 165 | 192 | r_data_cnt <= 0; | 
| 166 | 193 | r_data <= (OTHERS => '0'); | 
| 194 | + r_byte_cnt <= 0; | |
| 167 | 195 | r_crc_start <= '0'; | 
| 168 | 196 | ELSIF rising_edge(clk) THEN | 
| 169 | 197 | r_state <= n_state; | 
| 170 | 198 | r_data_cnt <= n_data_cnt; | 
| 171 | 199 | r_data <= n_data; | 
| 200 | + r_byte_cnt <= n_byte_cnt; | |
| 172 | 201 | r_crc_start <= n_crc_start; | 
| 173 | 202 | END IF; | 
| 174 | 203 | END PROCESS p_sync; | 
| 175 | 204 |