Module ip_mac_rx_hash_g

pi_resetlogicpi_f_clocklogicpi_g_clocklogicpi_hash_addr[8:0]logicpi_dest_addr[47:0]logicpi_new_matchlogicpi_abortlogicpi_hash_nfixlogicpi_inverselogicpi_multicastlogicpi_pass_multilogicpi_promisclogicpi_pass_alllogicpi_rd_data[47:0]logicpo_en_clockregpo_rd_addrreg[3:0]po_err_matchregpo_matchregpo_fc_matchreg

Block Diagram of ip_mac_rx_hash_g

Imperfect filtering The EMAC Receive Hash/Exact Mach module is responsible for received frame filtering. For any incoming multicast frame, the EMAC applies the standard Ethernet cyclic redundancy check (CRC) function to the first 6 bytes that contain the destination address, then, if the hash filtering type is selected, the EMAC Receive Hash/Exact Mach module uses the most significant 9 bits (for a 512 bit hash table) of the result as a bit index into a table. If the indexed bit is set, the multicast frame is accepted. If the bit is cleared, the multicast frame is rejected. This filtering mode is called imperfect because frames not addressed to this station may slip through, but it still decreases the number of frames that the host can receive.

Perfect filtering The EMAC interprets a setup frame buffer in perfect filtering mode if the configuration bits are set accordingly. The EMAC can store 16 (programmable) destination addresses (full 48-bit Ethernet addresses). The EMAC compares the addresses of any incoming frame to these addresses, and also tests the status of the inverse filtering. It rejects addresses that:

  • Do not match if inverse filtering
  • Match if perfect filtering is set The setup frame must supply all 16 (programmable) addresses. Any mix of physical and multicast addresses can be used. Unused addresses should duplicate one of the valid addresses.
Ports

Name

Type

Direction

Description

pi_reset

wire logic

input

Global Software/Hardware Reset (receive clock domain)

pi_f_clock

wire logic

input

Free Receive GMII/MII 125/25/2.5 MHz clock (from Clock Manager)

pi_g_clock

wire logic

input

Gated Receive GMII/MII 125/25/2.5 MHz clock (from Clock Manager)

po_en_clock

reg

output

Receive GMII/MII 125/25/2.5 MHz clock gated clock enable

pi_hash_addr

wire logic [8 : 0]

input

From Receive EMAC Hash table index (9-MSB of CRC calculation over 48-bit destination address)

pi_dest_addr

wire logic [47 : 0]

input

Exact match (destination address of the frame)

pi_new_match

wire logic

input

Start a new search (match address, or hash filtering, toggle signal when new match should be prformed)

pi_abort

wire logic

input

Abort search (due to errors)

pi_hash_nfix

wire logic

input

Configuration Hash filtering + 1 Address match / 16 Address match

pi_inverse

wire logic

input

Inverse match

pi_multicast

wire logic

input

When asserted the imperfect filtering refers only for multicast addressees

pi_pass_multi

wire logic

input

Pass all multicast addresses

pi_promisc

wire logic

input

Promiscuos Mode (no DA filter)

pi_pass_all

wire logic

input

Pass all frames (bad or good)

pi_rd_data

wire logic [47 : 0]

input

Hash Table Memory access Memory (hash table) read data

po_rd_addr

reg [3 : 0]

output

Memory (hash table) read address

po_err_match

reg

output

Match Address Hit Address match output error

po_match

reg

output

Address match output

po_fc_match

reg

output

Address match output (control frame address)

Always Blocks

always @ ( posedge pi_g_clock or negedge pi_reset )

Filtering FSM

always @ ( posedge pi_g_clock or negedge pi_reset )

Assign New Match Process

always @ ( posedge pi_f_clock or negedge pi_reset )

Gated Clock Enable

`IDLE `IDLE = 3'd0 `WAIT `WAIT = 3'd1 `MATCH_1 `MATCH_1 = 3'd3 `HASH `HASH = 3'd2 `MATCH_2 `MATCH_2 = 3'd4 1 [(!(~ pi_reset) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_dest_addr == 48'h0180C2000001) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_promisc == 1'b1 || pi_pass_all == 1'b1) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_pass_multi == 1'b1 && pi_dest_addr[40] == 1'b1) && (pi_abort == 1'b0 && new_match == 1'b1 && pi_hash_nfix == 1'b1))] 2 [(!(~ pi_reset) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_dest_addr == 48'h0180C2000001) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_promisc == 1'b1 || pi_pass_all == 1'b1) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_pass_multi == 1'b1 && pi_dest_addr[40] == 1'b1) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_hash_nfix == 1'b1) && (pi_abort == 1'b0 && new_match == 1'b1))] 3 [(!(~ pi_reset) && (pi_abort == 1'b1))] 4 [(!(~ pi_reset) && !(pi_abort == 1'b1))] 5 [(!(~ pi_reset) && (pi_abort == 1'b1)), (!(~ pi_reset) && !(pi_abort == 1'b1) && (pi_rd_data == pi_dest_addr)), (!(~ pi_reset) && !(pi_abort == 1'b1) && !(pi_rd_data == pi_dest_addr) && (po_rd_addr == 4'h0))] 7 [(!(~ pi_reset) && !(pi_abort == 1'b1) && !(pi_rd_data[hash_idx] == 1'b1 && pi_dest_addr[40] == 1'b1 || pi_multicast == 1'b0))] 6 [(!(~ pi_reset) && (pi_abort == 1'b1)), (!(~ pi_reset) && !(pi_abort == 1'b1) && (pi_rd_data[hash_idx] == 1'b1 && pi_dest_addr[40] == 1'b1 || pi_multicast == 1'b0))] 8 [(!(~ pi_reset) && (pi_abort == 1'b1)), (!(~ pi_reset) && (po_rd_addr == 4'he) && !(pi_rd_data[47 : 32] == pi_dest_addr[47 : 32])), (!(~ pi_reset) && (po_rd_addr == 4'hf) && !(pi_rd_data[47 : 32] == pi_dest_addr[31 : 16])), (!(~ pi_reset) && (po_rd_addr == 4'h0) && (pi_rd_data[47 : 32] == pi_dest_addr[15 : 0])), (!(~ pi_reset) && (po_rd_addr == 4'h0) && !(pi_rd_data[47 : 32] == pi_dest_addr[15 : 0]))]
FSM Transitions for fsm_hash_st

#

Current State

Next State

Condition

Comment

1

`IDLE

`WAIT

[(!(~ pi_reset) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_dest_addr == 48'h0180C2000001) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_promisc == 1'b1 || pi_pass_all == 1'b1) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_pass_multi == 1'b1 && pi_dest_addr[40] == 1'b1) && (pi_abort == 1'b0 && new_match == 1'b1 && pi_hash_nfix == 1'b1))]

2

`IDLE

`MATCH_1

[(!(~ pi_reset) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_dest_addr == 48'h0180C2000001) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_promisc == 1'b1 || pi_pass_all == 1'b1) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_pass_multi == 1'b1 && pi_dest_addr[40] == 1'b1) && !(pi_abort == 1'b0 && new_match == 1'b1 && pi_hash_nfix == 1'b1) && (pi_abort == 1'b0 && new_match == 1'b1))]

3

`WAIT

`IDLE

[(!(~ pi_reset) && (pi_abort == 1'b1))]

4

`WAIT

`HASH

[(!(~ pi_reset) && !(pi_abort == 1'b1))]

5

`MATCH_1

`IDLE

[(!(~ pi_reset) && (pi_abort == 1'b1)), (!(~ pi_reset) && !(pi_abort == 1'b1) && (pi_rd_data == pi_dest_addr)), (!(~ pi_reset) && !(pi_abort == 1'b1) && !(pi_rd_data == pi_dest_addr) && (po_rd_addr == 4'h0))]

6

`HASH

`IDLE

[(!(~ pi_reset) && (pi_abort == 1'b1)), (!(~ pi_reset) && !(pi_abort == 1'b1) && (pi_rd_data[hash_idx] == 1'b1 && pi_dest_addr[40] == 1'b1 || pi_multicast == 1'b0))]

7

`HASH

`MATCH_2

[(!(~ pi_reset) && !(pi_abort == 1'b1) && !(pi_rd_data[hash_idx] == 1'b1 && pi_dest_addr[40] == 1'b1 || pi_multicast == 1'b0))]

8

`MATCH_2

`IDLE

[(!(~ pi_reset) && (pi_abort == 1'b1)), (!(~ pi_reset) && (po_rd_addr == 4'he) && !(pi_rd_data[47 : 32] == pi_dest_addr[47 : 32])), (!(~ pi_reset) && (po_rd_addr == 4'hf) && !(pi_rd_data[47 : 32] == pi_dest_addr[31 : 16])), (!(~ pi_reset) && (po_rd_addr == 4'h0) && (pi_rd_data[47 : 32] == pi_dest_addr[15 : 0])), (!(~ pi_reset) && (po_rd_addr == 4'h0) && !(pi_rd_data[47 : 32] == pi_dest_addr[15 : 0]))]

Instances