Fix warnings, mostly from implicitly defined wires or unspecified widths
[debian/gnuradio] / usrp2 / fpga / simple_gemac / simple_gemac_rx.v
1
2
3 module simple_gemac_rx
4   (input reset,
5    input GMII_RX_CLK, input GMII_RX_DV, input GMII_RX_ER, input [7:0] GMII_RXD,
6    output rx_clk, output [7:0] rx_data, output reg rx_valid, output rx_error, output reg rx_ack,
7    input [47:0] ucast_addr, input [47:0] mcast_addr, 
8    input pass_ucast, input pass_mcast, input pass_bcast, input pass_pause, input pass_all,
9    output reg [15:0] pause_quanta_rcvd, output pause_rcvd );
10
11    localparam RX_IDLE             = 0;
12    localparam RX_PREAMBLE         = 1;
13    localparam RX_FRAME            = 2;
14    localparam RX_GOODFRAME        = 3;
15    localparam RX_DO_PAUSE         = 4;
16    localparam RX_ERROR            = 5;
17    localparam RX_DROP             = 6;
18
19    localparam RX_PAUSE            = 16;
20    localparam RX_PAUSE_CHK88      = RX_PAUSE + 5;
21    localparam RX_PAUSE_CHK08      = RX_PAUSE_CHK88 + 1;
22    localparam RX_PAUSE_CHK00      = RX_PAUSE_CHK08 + 1;
23    localparam RX_PAUSE_CHK01      = RX_PAUSE_CHK00 + 1;
24    localparam RX_PAUSE_STORE_MSB  = RX_PAUSE_CHK01 + 1;
25    localparam RX_PAUSE_STORE_LSB  = RX_PAUSE_STORE_MSB + 1;
26    localparam RX_PAUSE_WAIT_CRC   = RX_PAUSE_STORE_LSB + 1;
27    
28    reg [7:0]         rxd_d1;
29    reg rx_dv_d1, rx_er_d1;
30    assign rx_clk     = GMII_RX_CLK;
31    
32    always @(posedge rx_clk)
33      begin
34         rx_dv_d1    <= GMII_RX_DV;
35         rx_er_d1    <= GMII_RX_ER;
36         rxd_d1      <= GMII_RXD;
37      end
38
39    reg [7:0] rx_state;
40    wire [7:0] rxd_del;
41    wire rx_dv_del, rx_er_del;
42    reg go_filt;
43    
44    wire match_crc;
45    wire clear_crc        = rx_state == RX_IDLE;
46    wire calc_crc         = (rx_state == RX_FRAME) | rx_state[7:4]==4'h1;
47
48    localparam DELAY  = 6;
49    delay_line #(.WIDTH(10)) rx_delay
50      (.clk(rx_clk), .delay(DELAY), .din({rx_dv_d1,rx_er_d1,rxd_d1}),.dout({rx_dv_del,rx_er_del,rxd_del}));
51
52    always @(posedge rx_clk)
53      if(reset)
54        rx_ack      <= 0;
55      else
56        rx_ack <= (rx_state == RX_GOODFRAME);
57
58    wire is_ucast, is_bcast, is_mcast, is_pause;
59    wire keep_packet  = (pass_ucast & is_ucast) | (pass_mcast & is_mcast) | 
60         (pass_bcast & is_bcast) | (pass_pause & is_pause) | pass_all;
61    
62    assign rx_data   = rxd_del;
63    assign rx_error  = (rx_state == RX_ERROR);
64
65    always @(posedge rx_clk)
66      if(reset)
67        rx_valid <= 0;
68      else if(keep_packet)
69        rx_valid <= 1;
70      else if((rx_state == RX_IDLE)|(rx_state == RX_ERROR))
71        rx_valid <= 0;
72    
73    address_filter af_ucast (.clk(rx_clk), .reset(reset), .go(go_filt), .data(rxd_d1),
74                             .address(ucast_addr), .match(is_ucast), .done());
75    address_filter af_mcast (.clk(rx_clk), .reset(reset), .go(go_filt), .data(rxd_d1),
76                             .address(mcast_addr), .match(is_mcast), .done());
77    address_filter af_bcast (.clk(rx_clk), .reset(reset), .go(go_filt), .data(rxd_d1),
78                             .address(48'hFFFF_FFFF_FFFF), .match(is_bcast), .done());
79    address_filter af_pause (.clk(rx_clk), .reset(reset), .go(go_filt), .data(rxd_d1),
80                             .address(48'h0180_c200_0001), .match(is_pause), .done());
81
82    always @(posedge rx_clk)
83      go_filt                     <= (rx_state==RX_PREAMBLE) & (rxd_d1 == 8'hD5);
84
85    reg [15:0] pkt_len_ctr;
86    always @(posedge rx_clk)
87      if(reset |(rx_state == RX_IDLE))
88        pkt_len_ctr      <= 0;
89      else
90        pkt_len_ctr      <= pkt_len_ctr + 1;
91
92    localparam MIN_PAUSE_LEN = 71;  // 6
93    wire pkt_long_enough  = (pkt_len_ctr >= MIN_PAUSE_LEN);
94    always @(posedge rx_clk)
95      if(reset)
96        rx_state         <= RX_IDLE;
97      else
98        if(rx_er_d1) // | (~pkt_long_enough & ~rx_dv_d1) & (rx_state != RX_IDLE))
99          rx_state       <= RX_ERROR;
100        else
101          case(rx_state)
102            RX_IDLE :
103              if(rx_dv_d1)
104                if(rxd_d1 == 8'h55)
105                  rx_state   <= RX_PREAMBLE;
106                else
107                  rx_state   <= RX_ERROR;
108            RX_PREAMBLE :
109              if(~rx_dv_d1)
110                rx_state   <= RX_ERROR;
111              else if(rxd_d1 == 8'hD5)
112                rx_state   <= RX_FRAME;
113              else if(rxd_d1 != 8'h55)
114                rx_state   <= RX_ERROR;
115            RX_FRAME :
116              if(is_pause)
117                rx_state <= RX_PAUSE;
118              else if(~rx_dv_d1)
119                if(match_crc)
120                  rx_state <= RX_GOODFRAME;
121                else
122                  rx_state <= RX_ERROR;
123            RX_PAUSE_CHK88 :
124              if(rxd_d1 != 8'h88)
125                rx_state <= RX_DROP;
126              else
127                rx_state <= RX_PAUSE_CHK08;
128            RX_PAUSE_CHK08 :
129              if(rxd_d1 != 8'h08)
130                rx_state <= RX_DROP;
131              else
132                rx_state <= RX_PAUSE_CHK00;
133            RX_PAUSE_CHK00 :
134              if(rxd_d1 != 8'h00)
135                rx_state <= RX_DROP;
136              else
137                rx_state <= RX_PAUSE_CHK01;
138            RX_PAUSE_CHK01 :
139              if(rxd_d1 != 8'h01)
140                rx_state <= RX_DROP;
141              else
142                rx_state <= RX_PAUSE_STORE_MSB;
143            RX_PAUSE_WAIT_CRC :
144              if(pkt_long_enough)
145                if(match_crc)
146                  rx_state <= RX_DO_PAUSE;
147                else
148                  rx_state <= RX_DROP;
149            RX_DO_PAUSE :
150              rx_state <= RX_IDLE;
151            RX_GOODFRAME :
152              rx_state <= RX_IDLE;
153            RX_DROP, RX_ERROR :
154              if(~rx_dv_d1)
155                rx_state <= RX_IDLE;
156            default
157              rx_state <= rx_state + 1;
158          endcase // case (rx_state)
159
160    assign pause_rcvd = (rx_state == RX_DO_PAUSE);
161    crc crc_check(.clk(rx_clk),.reset(reset),.clear(clear_crc),
162                  .data(rxd_d1),.calc(calc_crc),.crc_out(),.match(match_crc));
163
164    always @(posedge rx_clk)
165      if(reset)
166        pause_quanta_rcvd <= 0;
167      else if(rx_state == RX_PAUSE_STORE_MSB)
168        pause_quanta_rcvd[15:8] <= rxd_d1;
169      else if(rx_state == RX_PAUSE_STORE_LSB)
170        pause_quanta_rcvd[7:0] <= rxd_d1;
171    
172    assign rx_clk          = GMII_RX_CLK;
173    
174 endmodule // simple_gemac_rx