summaryrefslogtreecommitdiffhomepage
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/mac.v160
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

Highly Recommended Verilog Books