diff options
-rw-r--r-- | source/mac.v | 160 |
1 files changed, 72 insertions, 88 deletions
diff --git a/source/mac.v b/source/mac.v index d408301..b5b980a 100644 --- a/source/mac.v +++ b/source/mac.v @@ -1,7 +1,7 @@ /* * mac.v * - * Copyright 2018, 2019, 2020 Mind Chasers Inc. + * Copyright 2018, 2019, 2020, 2021 Mind Chasers Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,27 +25,27 @@ module mac( input clk, input tap_port, + // PCS / SERDES health + input rx_lsm, + input rx_cv_err, + input rx_disp_err, + input rx_cdr_lol, + input rx_los, + // AN input [1:0] phy_type, // SGMII==0, SX=1, SMA=3 input pulse_1_6ms, // SGMII input pulse_10ms, // SX input [1:0] fixed_speed, input an_disable, - output reg an_duplex, - output reg phy_up, + output an_duplex, + output phy_up, output reg mode_100Mbit, // Switch I/F input [2:0] tx_mode, output reg tx_f, - // PCS / SERDES health - input rx_lsm, - input rx_cv_err, - input rx_disp_err, - input rx_cdr_lol, - input rx_los, - // PCS data I/F input rx_k, input [7:0] rx_data, @@ -53,11 +53,6 @@ module mac( output reg [7:0] tx_data, output reg tx_disp_correct, - // Flags and Interrupts - output reg rx_enet_bcast, - output reg rx_ipv4_arp, - output keep, - // TX FCS output reg fcs_init, output reg fcs_enable, @@ -69,11 +64,14 @@ module mac( output rx_fifo_we, output [8:0] rx_fifo_d, output reg rx_error, + output rx_keep, output reg rx_wr_done, output reg [10:0] rx_byte_cnt, + output [1:0] rx_mode, // MAC TX / FIFO Read input [10:0] tx_byte_cnt_i, + input [2:0] tx_src_sel, output reg tx_fifo_re, input [8:0] tx_fifo_d, input tx_fifo_empty, @@ -93,14 +91,16 @@ module mac( output reg[7:0] rx_data_m3, output reg[7:0] rx_data_m4, - // Param RAM for TAP port + // Param RAM output [10:0] dpr_ad, output dpr_we, output dpr_ce, input [8:0] dpr_di, output [8:0] dpr_do, - // Metrics and Interrupts + // Flags, Metrics, Interrupts, and Debug + output reg rx_enet_bcast, + output reg rx_ipv4_arp, output reg mac_int, output reg rx_sop, // start of packet output reg rx_eop, @@ -108,8 +108,6 @@ module mac( output reg tx_eop, output reg metrics_start, input [8:0] metrics_d, - - // Debug output reg rx_active, output reg tx_active ); @@ -121,19 +119,11 @@ localparam PHY_TYPE_SGMII = 2'b00, PHY_TYPE_SX = 2'b01, PHY_TYPE_RSVD = 2'b10, PHY_TYPE_SMA = 2'b11; - - + localparam AN_TX_CONFIG_HI = 8'h00, AN_TX_CONFIG_HI_ACK = 8'h40, - AN_TX_CONFIG_LO = 8'h01; + AN_TX_CONFIG_LO = 8'h21; -localparam AN_TYPE_SX = 1'b0, - AN_TYPE_SGMII = 1'b1; - -localparam AN_ST_DISABLE=4'h0, AN_ST_ENABLE=4'h1, AN_ST_RESTART=4'h2, - AN_ST_ABILITY_DETECT=4'h3, AN_ST_ACK_DETECT=4'h4, - AN_ST_COMPLETE_ACK=4'h5, AN_ST_IDLE_DETECT=4'h6, AN_ST_LINK_OK=4'h7; - localparam RX_ST_IDLE=4'h0, RX_ST_SOP=4'h1, RX_ST_PREAMBLE=4'h2, RX_ST_SFD=4'h3, RX_ST_MAC_ADDR=4'h4, RX_ST_MAC_TYPE0=4'h5, RX_ST_MAC_TYPE1=4'h6, RX_ST_DATA=4'h7, RX_ST_DATA_DONE0=4'h8, RX_ST_DATA_DONE1=4'h9, RX_ST_DATA_DONE2=4'ha; @@ -143,23 +133,15 @@ localparam TX_ST_0=4'h0, TX_ST_1=4'h1, TX_ST_2=4'h2, TX_ST_3=4'h3, TX_ST_8=4'h8, TX_ST_9=4'h9, TX_ST_A=4'ha, TX_ST_B=4'hb, TX_ST_C=4'hc, TX_ST_D=4'hd, TX_ST_E=4'he, TX_ST_F=4'hf; -reg [3:0] rx_cnt_100mbit, tx_cnt_100mbit; +// AN +wire [15:0] tx_config_reg; +wire [1:0] an_speed; +reg [3:0] rx_cnt_100mbit, tx_cnt_100mbit; wire tx_sample, tx_sample_re; wire rx_packet_complete; wire mode_1Gbit; - -// AN -reg [2:0] an_state; -reg [1:0] an_speed; -wire an_ability_detect; -wire an_link_timer_pulse; -reg rx_config_detect; -reg [15:0] rx_config_reg, tx_config_reg; -reg [1:0] rx_config_cnt; // use to count consecutive rx config_regs -reg an_link_up; - reg [3:0] rx_state; reg [10:0] rx_pkt_length; reg [15:0] rx_l3_proto; @@ -196,6 +178,9 @@ reg [15:0] tx_ipv4_length; // layer 4 TX support reg [15:0] tx_udp_length; +wire tx_finished; +wire tx_temp; + /* * RX DIRECTION @@ -231,49 +216,37 @@ always @(posedge clk or negedge rstn) end end -/* - * SGMII Auto Negotiation State Machine - * Look for configuration /C/ ordered set - * /C/ is Alternating /C1/ and /C2/ - * /C1/: /K28.5/D21.5(0xb5)/Config_Reg - * /C2/: /K28.5/D2.2(0x42)/Config_Reg - * Config Reg: Low High - */ -always @(posedge clk or negedge rstn) - if (!rstn) - begin - an_link_up <= 1'b0; - an_duplex <= 1'b0; - an_speed <= SGMII_SPEED_RSVD; - phy_up <= 1'b0; - end - else if ( !phy_resetn ) - begin - an_link_up <= 1'b0; - an_duplex <= 1'b0; - an_speed <= SGMII_SPEED_RSVD; - phy_up <= 1'b0; - end - else if ( an_disable ) - begin - phy_up <= 1'b1; - end - // D21.5 is part of config ( M2 has low, M1 has high ) - else if (!rx_k_m1 && !rx_k_m2 && !rx_k_m3 && rx_data_m3 == D21_5 && rx_k_m4 && rx_data_m4 == K28_5 ) - begin - an_link_up <= rx_data_m1[7]; - an_duplex <= rx_data_m1[4]; - an_speed <= rx_data_m1[3:2]; - phy_up <= 1'b0; - end - // IDLE2 1:0xBC, 0:0x50 - else if ( !rx_k_m1 && rx_data_m1 == D16_2 && rx_k_m2 == 1'b1 && rx_data_m2 == K28_5 ) - phy_up <= 1'b1; +// Auto Negotiation +an an_inst ( + .rstn(rstn), + .phy_resetn(phy_resetn), + .clk(clk), + // AN + .phy_type(phy_type), + .pulse_1_6ms(pulse_1_6ms), + .pulse_10ms(pulse_10ms), + .fixed_speed(fixed_speed), + .an_disable(an_disable), + .an_duplex(an_duplex), + .an_speed(an_speed), + .an_link_up(an_link_up), + .tx_config_reg(tx_config_reg), + .phy_up(phy_up), + + .rx_k_m1(rx_k_m1), + .rx_k_m2(rx_k_m2), + .rx_k_m3(rx_k_m3), + .rx_k_m4(rx_k_m4), + + .rx_data_m1(rx_data_m1), + .rx_data_m2(rx_data_m2), + .rx_data_m3(rx_data_m3), + .rx_data_m4(rx_data_m4) + ); // 100 MBit Support. There are no plans to support 10 MBit, so 100 MBit inactive is the same as 1GBit active // if/else encodes the priority -// TODO: possibly add more logic here to create an error condition if 10MBit is detected always @(*) if (fixed_speed == SGMII_SPEED_100MBIT) mode_100Mbit = 1'b1; @@ -341,6 +314,9 @@ always @(posedge clk, negedge rstn) */ assign rx_fifo_we = ( rx_sample && ( rx_state >= RX_ST_SFD && rx_state <= RX_ST_DATA_DONE1 ) ) ? 1'b1 : 1'b0; +// rx_mode +assign rx_mode = 2'b00; + /* * Detect Ethernet Broadcast (destination address = ff:ff:ff:ff:ff:ff) @@ -401,15 +377,11 @@ always @(posedge clk, negedge rstn) rx_ipv4_arp <= 1'b0; /* - * keep flag + * rx_keep flag * signals must be one shot * */ -`ifdef PASSTHROUGH - assign keep = rx_enet_bcast | rx_ipv4_arp; - `else - assign keep = 1'b0; -`endif + assign rx_keep = rx_enet_bcast | rx_ipv4_arp; /* rx_error * TODO: should be one shot? @@ -651,6 +623,13 @@ always @(*) end +/* + * TX Finished Logic + */ +assign tx_temp = (tx_mode==TX_MODE_XMT_CUSTOM && tx_byte_cnt==tx_ipv4_length+SZ_ETH_HEADER); +assign tx_finished = tx_last_byte || (tx_mode==TX_MODE_XMT_CUSTOM && tx_byte_cnt==(tx_ipv4_length+SZ_ETH_HEADER)); + + /* @@ -678,9 +657,9 @@ always @(posedge clk, negedge rstn) tx_state <= TX_ST_3; // preamble 0x55, assert tx_fifo_re, reset tx_byte_cnt TX_ST_3: if ( tx_sample ) tx_state <= TX_ST_4; // preamble 0xD5 - TX_ST_4: if ( tx_sample && tx_last_byte && tx_byte_cnt < 60 ) // check if we need to pad? + TX_ST_4: if ( tx_sample && tx_finished && tx_byte_cnt < 60 ) // check if we need to pad? tx_state <= TX_ST_5; - else if ( tx_sample && tx_last_byte) // check if we're done + else if ( tx_sample && tx_finished) // check if we're done tx_state <= TX_ST_6; TX_ST_5: if ( tx_sample && tx_byte_cnt >= 60 ) // pad state, test for sufficient frame size tx_state <= TX_ST_6; @@ -751,6 +730,10 @@ always @(*) tx_data_pkt = tx_ipv4_cksum[7:0]; fcs_dout = tx_ipv4_cksum[7:0]; end + else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd38) begin + tx_data_pkt = 8'h0 + tx_src_sel[2]; // UDP destination port + fcs_dout = 8'h0 + tx_src_sel[2]; + end else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd39) begin tx_data_pkt = tx_udp_length[15:8]; fcs_dout = tx_udp_length[15:8]; @@ -924,6 +907,7 @@ always @(posedge clk or negedge rstn) assign dpr_we = 1'b0; assign dpr_ce = 1'b1; assign dpr_ad = param_addr; +assign dpr_do = 9'd0; /* * tx_sop, K27_7, 0xFB /S/ Start_of_Packet |