From c8b273c80abe98e53828f46079a187975938a56a Mon Sep 17 00:00:00 2001 From: Private Island Networks Date: Mon, 1 Sep 2025 12:34:17 -0400 Subject: rename source to src --- source/mac.v | 973 ----------------------------------------------------------- 1 file changed, 973 deletions(-) delete mode 100644 source/mac.v (limited to 'source/mac.v') diff --git a/source/mac.v b/source/mac.v deleted file mode 100644 index b5b980a..0000000 --- a/source/mac.v +++ /dev/null @@ -1,973 +0,0 @@ -/* - * mac.v - * - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * function: Ethernet MAC Layer - * - */ - -module mac( - input rstn, - input phy_resetn, // The external PHY has its reset signal asserted - 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 an_duplex, - output phy_up, - output reg mode_100Mbit, - - // Switch I/F - input [2:0] tx_mode, - output reg tx_f, - - // PCS data I/F - input rx_k, - input [7:0] rx_data, - output reg tx_k, - output reg [7:0] tx_data, - output reg tx_disp_correct, - - // TX FCS - output reg fcs_init, - output reg fcs_enable, - output reg [1:0] fcs_addr, - output reg [7:0] fcs_dout, - input [7:0] fcs_din, - - // MAC RX / FIFO Write - 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, - - // Packet Filter - output rx_sample, - output reg ipv4_pkt_start, - output reg trigger, - - output reg rx_k_m1, - output reg rx_k_m2, - output reg rx_k_m3, - output reg rx_k_m4, - - output reg[7:0] rx_data_m1, - output reg[7:0] rx_data_m2, - output reg[7:0] rx_data_m3, - output reg[7:0] rx_data_m4, - - // Param RAM - output [10:0] dpr_ad, - output dpr_we, - output dpr_ce, - input [8:0] dpr_di, - output [8:0] dpr_do, - - // 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, - output reg tx_sop, - output reg tx_eop, - output reg metrics_start, - input [8:0] metrics_d, - output reg rx_active, - output reg tx_active -); - -`include "sgmii_params.v" -`include "ethernet_params.v" - -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'h21; - -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; - -localparam TX_ST_0=4'h0, TX_ST_1=4'h1, TX_ST_2=4'h2, TX_ST_3=4'h3, - TX_ST_4=4'h4, TX_ST_5=4'h5, TX_ST_6=4'h6, TX_ST_7=4'h7, - 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; - -// 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; - -reg [3:0] rx_state; -reg [10:0] rx_pkt_length; -reg [15:0] rx_l3_proto; - -// TODO: consider reorganizing state machines to reuse registers. -reg [7:0] tx_data_an, tx_data_idle, tx_data_pkt; -reg tx_k_an, tx_k_idle, tx_k_pkt; - -// Transmit Registers and Wires -reg [3:0] tx_state; // transmit state machine -reg [10:0] tx_byte_cnt; -reg [10:0] param_addr; - -reg tx_f_an, tx_f_idle, tx_f_pkt; -reg i_tx_disp_correct; -reg tx_last_byte; - -// FIFOs: -reg [8:0] tx_fifo_d_m1; - -// FCS -reg fcs_addr_e; - -// pipeline the param RAM for timing -reg [8:0] dpr_di_reg; - -// counter for detecting Ethernet broadcast, only needs to count to 6 -reg [2:0] rx_enet_bcast_cnt; - -// layer 3 TX support -reg [18:0] tx_ipv4_cksum; -reg [15:0] tx_ipv4_length; - -// layer 4 TX support -reg [15:0] tx_udp_length; - -wire tx_finished; -wire tx_temp; - - -/* - * RX DIRECTION - * - */ - -/* - * A shallow pool of RX registers for analysis - */ -always @(posedge clk or negedge rstn) - begin - if (!rstn) - begin - rx_k_m1 <= 1'b0; - rx_k_m2 <= 1'b0; - rx_k_m3 <= 1'b0; - rx_k_m4 <= 1'b0; - rx_data_m1 <= 8'h0; - rx_data_m2 <= 8'h0; - rx_data_m3 <= 8'h0; - rx_data_m4 <= 8'h0; - end - else if (mode_1Gbit || rx_sample || rx_state == RX_ST_IDLE || rx_state == RX_ST_DATA_DONE2 ) - begin - rx_k_m1 <= rx_k; - rx_k_m2 <= rx_k_m1; - rx_k_m3 <= rx_k_m2; - rx_k_m4 <= rx_k_m3; - rx_data_m1 <= rx_data; - rx_data_m2 <= rx_data_m1; - rx_data_m3 <= rx_data_m2; - rx_data_m4 <= rx_data_m3; - end - end - -// 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 -always @(*) - if (fixed_speed == SGMII_SPEED_100MBIT) - mode_100Mbit = 1'b1; - else if (fixed_speed == SGMII_SPEED_1GBIT) - mode_100Mbit = 1'b0; - else if (an_speed == SGMII_SPEED_100MBIT ) - mode_100Mbit = 1'b1; - else - mode_100Mbit = 1'b0; - -assign mode_1Gbit = ~mode_100Mbit; - -// RX 100 Mbit support -assign rx_sample = (rx_cnt_100mbit == 4'd9 && mode_100Mbit) || !mode_100Mbit ? 1'b1 : 1'b0; -always @(posedge clk or negedge rstn) - if (!rstn) - rx_cnt_100mbit <= 4'b0; - else if ( rx_cnt_100mbit == 4'd9 || rx_sop ) - rx_cnt_100mbit <= 4'b0; - else - rx_cnt_100mbit <= rx_cnt_100mbit + 4'd1; - - -/* - * rx_state machine - * capture the Ethernet MAC header + packet. - * - */ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_state <= RX_ST_IDLE; - else if ( rx_eop || !phy_resetn ) // EOP will reset state machine - rx_state <= RX_ST_IDLE; - else if ( phy_up ) - case ( rx_state ) - RX_ST_IDLE: if (rx_data_m1 == K27_7 && rx_k_m1 ) // Found /S/ - rx_state <= RX_ST_SOP; - RX_ST_SOP: if ( rx_sample ) // Capture /S/ - rx_state <= RX_ST_PREAMBLE; - RX_ST_PREAMBLE: if ( rx_sample && rx_data_m1 == 8'hd5 ) // 0xd5 preamble - rx_state <= RX_ST_SFD; - RX_ST_SFD: if ( rx_sample ) - rx_state <= RX_ST_MAC_ADDR; - RX_ST_MAC_ADDR: if ( rx_sample && rx_byte_cnt == 12 ) // Use this state transition to signal end of ethernet header and start of packet - rx_state <= RX_ST_MAC_TYPE0; - RX_ST_MAC_TYPE0: if ( rx_sample ) - rx_state <= RX_ST_MAC_TYPE1; // Capture ethertype - RX_ST_MAC_TYPE1: if ( rx_sample ) - rx_state <= RX_ST_DATA; // - RX_ST_DATA: if ( rx_sample && rx_packet_complete ) // write into FIFO until pkt length - rx_state <= RX_ST_DATA_DONE0; - RX_ST_DATA_DONE0: if ( rx_sample ) - rx_state <= RX_ST_DATA_DONE1; // write an extra byte into the FIFO - RX_ST_DATA_DONE1: if ( rx_sample ) - rx_state <= RX_ST_DATA_DONE2; // write an extra byte into the FIFO - RX_ST_DATA_DONE2: if ( rx_sample ) - rx_state <= rx_state; // waiting for /T/ - default: rx_state <= rx_state; - endcase - else - rx_state <= RX_ST_IDLE; - -/* - * rx_fifo_we -*/ -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) - * TODO: Add state information to only trigger on DEST ADDRESS - * - */ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_enet_bcast_cnt <= 3'h0; - else if ( rx_sample ) - if (rx_data_m1 == 9'hff) - rx_enet_bcast_cnt <= rx_enet_bcast_cnt + 1; - else - rx_enet_bcast_cnt <= 3'h0; - -/* Ethernet Broadcast Dest Address, must be a one shot */ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_enet_bcast <= 1'b0; - else if ( rx_sample ) - if ( rx_enet_bcast_cnt == 3'h6 ) - rx_enet_bcast <= 1'b1; - else - rx_enet_bcast <= 1'b0; - -/* - create a one shot that will assert during RX_ST_DATA_DONE1 so external logic can know - that the FIFO write has come to an end ( reset pointers, etc. ) - - For 100Mbit, since the states change 10 clocks apart, set it during RX_ST_DATA_DONE1 -*/ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_wr_done <= 1'b0; - else if ( mode_1Gbit && rx_state == RX_ST_DATA_DONE0 ) - rx_wr_done <= 1'b1; - else if ( mode_100Mbit && rx_sample && rx_state == RX_ST_DATA_DONE1 ) - rx_wr_done <= 1'b1; - else - rx_wr_done <= 1'b0; - -/* capture layer 3 protocol (e.g., ipv4 or ipv6) */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - rx_l3_proto <= 0; - else if ( rx_sop ) - rx_l3_proto <= 0; - else if ( rx_sample && rx_state == RX_ST_MAC_TYPE0 ) - rx_l3_proto <= { rx_data_m2, rx_data_m1 }; - -// assert ipv4 ARP flag for filtering operations -always @(posedge clk, negedge rstn) - if (!rstn) - rx_ipv4_arp <= 1'b0; - else if ( rx_sample && rx_state == RX_ST_MAC_TYPE1 && rx_l3_proto == ETHER_TYPE_ARP) - rx_ipv4_arp <= 1'b1; - else - rx_ipv4_arp <= 1'b0; - -/* - * rx_keep flag - * signals must be one shot - * - */ - assign rx_keep = rx_enet_bcast | rx_ipv4_arp; - -/* rx_error - * TODO: should be one shot? - * */ -always @(*) - if ( rx_sample && rx_state >= RX_ST_DATA && ( rx_l3_proto != ETHER_TYPE_IPV4 && rx_l3_proto != ETHER_TYPE_IPV6 && rx_l3_proto != ETHER_TYPE_ARP) ) - rx_error = 1; - else - rx_error = 0; - -/* rx_byte_cnt */ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_byte_cnt <= 'h0; - else if (rx_sample) - if ( rx_state == RX_ST_IDLE || rx_state == RX_ST_PREAMBLE ) - rx_byte_cnt <= 'h0; - else if ( rx_state == RX_ST_MAC_TYPE0 ) - rx_byte_cnt <= 'h1; - else - rx_byte_cnt <= rx_byte_cnt + 1; - -/* rx_pkt_length */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - rx_pkt_length <= 0; - else if ( rx_sop ) - rx_pkt_length <= 0; - else if (rx_sample) - if ( rx_l3_proto == ETHER_TYPE_IPV4 && rx_state == RX_ST_DATA && rx_byte_cnt == 'h4 ) - rx_pkt_length <= { rx_data_m2[2:0], rx_data_m1 }; - else if ( rx_l3_proto == ETHER_TYPE_IPV6 && rx_state == RX_ST_DATA && rx_byte_cnt == 'h6 ) - rx_pkt_length <= { rx_data_m2[2:0], rx_data_m1 } + 'd40; - else if ( rx_l3_proto == ETHER_TYPE_ARP && rx_state == RX_ST_DATA ) - rx_pkt_length <= 'd46; - -/* ipv4 flag */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - ipv4_pkt_start <= 1'b0; - else if ( rx_sample && rx_l3_proto == ETHER_TYPE_IPV4 && rx_state == RX_ST_MAC_TYPE1 ) - ipv4_pkt_start <= 1; - else - ipv4_pkt_start <= 0; - -assign rx_packet_complete = ( rx_sample && rx_state >= RX_ST_DATA && rx_pkt_length == rx_byte_cnt ) ? 1 : 0; - -// FIFO data interface -assign rx_fifo_d[7:0] = rx_data_m1; -assign rx_fifo_d[8] = rx_packet_complete; - - -/* - * rx_sop, K27_7, 0xFB /S/ Start_of_Packet - */ -always @(posedge clk or negedge rstn) - if (!rstn) - rx_sop <=1'b0; - else if ( rx_data_m1 == K27_7 && rx_k_m1 == 1'b1 ) - rx_sop <= 1'b1; - else - rx_sop <= 1'b0; - -/* - * rx_eop, K29_7, 0xFD, /T/ End_of_Packet - */ -always @(posedge clk or negedge rstn) - if (!rstn) - rx_eop <=1'b0; - else if ( rx_data_m1 == K29_7 && rx_k_m1 == 1'b1 ) - rx_eop <= 1'b1; - else - rx_eop <= 1'b0; - -/* MAC Interrupt - * Create one shot interrupt while interrupt source is active - * Rely on interrupt controller to latch & clear - */ -always @(posedge clk or negedge rstn) - if (!rstn) - mac_int <=1'b0; - else if ( !rx_lsm || rx_cv_err || rx_cdr_lol || rx_los ) - mac_int <= 1'b1; - else - mac_int <= 1'b0; - - -/* Debug RX */ -always @(posedge clk or negedge rstn) - if (!rstn) - rx_active <=1'b0; - else if ( rx_state != 0 ) - rx_active <= 1'b1; - else - rx_active <= 1'b0; - - - -/* - * TX DIRECTION - * - */ - - -// TX 100 Mbit support -assign tx_sample_re = (tx_cnt_100mbit == 4'd8 && mode_100Mbit) || !mode_100Mbit; -assign tx_sample = (tx_cnt_100mbit == 4'd9 && mode_100Mbit) || !mode_100Mbit; - -always @(posedge clk or negedge rstn) - if (!rstn) - tx_cnt_100mbit <= 4'b0; - else if ( tx_state == TX_ST_0 ) - tx_cnt_100mbit <= 4'b1; // steal a bit here during preamble so we keep an even bit count - else if ( tx_cnt_100mbit == 4'd9 ) - tx_cnt_100mbit <= 4'b0; - else - tx_cnt_100mbit <= tx_cnt_100mbit + 1; - - -/* -* -* Transmit Mux -*/ -always @(posedge clk or negedge rstn) - if (!rstn) begin - tx_data <= 8'h00; - tx_k <= 1'b0; - tx_disp_correct <= 1'b0; - end - else begin - case(tx_mode) - TX_MODE_AN: - begin - tx_data <= tx_data_an; - tx_k <= tx_k_an; - tx_disp_correct <= i_tx_disp_correct; - end - TX_MODE_IDLE: - begin - tx_data <= tx_data_idle; - tx_k <= tx_k_idle; - tx_disp_correct <= i_tx_disp_correct; - end - default: - begin - tx_data <= tx_data_pkt; - tx_k <= tx_k_pkt; - tx_disp_correct <= i_tx_disp_correct; - end - endcase - end - -// tx_f mux -always @(*) - case(tx_mode) - TX_MODE_AN: tx_f <= tx_f_an; - TX_MODE_IDLE: tx_f <= tx_f_idle; - default : tx_f <= tx_f_pkt; - endcase - - -/* - * CONFIG SM -* During SGMII auto negotiation, send /C1/ and /C2/ ordered sets -* C1: /K28.5/D21.5/Config Regs -* C2: /K28.5/D2.2/Config Regs -*/ -always @(*) - begin - tx_f_an = 1'b0; - tx_k_an = 1'b0; - case(tx_byte_cnt[2:0]) - 3'd0: - begin - tx_data_an = K28_5; - tx_k_an = 1'b1; - end - 3'd1: - tx_data_an = D21_5; - 3'd2: - tx_data_an = AN_TX_CONFIG_LO; - 3'd3: - if (!an_link_up) - tx_data_an = AN_TX_CONFIG_HI; - else - tx_data_an = AN_TX_CONFIG_HI_ACK; - 3'd4: - begin - tx_data_an = K28_5; - tx_k_an = 1'b1; - end - 3'd5: - tx_data_an = D2_2; - 3'd6: - tx_data_an = AN_TX_CONFIG_LO; - 3'd7: - if (!an_link_up) - begin - tx_f_an = 1'b1; - tx_data_an = AN_TX_CONFIG_HI; - end - else - begin - tx_f_an = 1'b1; - tx_data_an = AN_TX_CONFIG_HI_ACK; - end - default: - begin - tx_data_an = K_ERROR; - tx_k_an = 1'b1; - tx_f_an = 1'b1; - end - endcase - end - -/* IDLE2 SM */ -always @(*) - begin - tx_f_idle = 1'b0; - case(tx_byte_cnt[1:0]) - 3'd0: - begin - tx_data_idle = K28_5; - tx_k_idle = 1'b1; - end - 3'd1: - begin - tx_data_idle = D16_2; - tx_k_idle = 1'b0; - tx_f_idle = 1'b1; - end - default: - begin - tx_data_idle = K_ERROR; - tx_k_idle = 1'b1; - tx_f_idle = 1'b1; - end - endcase - 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)); - - - - -/* -* Transmit Packet State Machine -* -* -* Note: the first /I/ following a transmitted frame or Configuration ordered set -* restores the current positive or negative running disparity to a -* negative value. -* -*/ -always @(posedge clk, negedge rstn) - begin - if ( !rstn ) - tx_state <= TX_ST_0; - else if ( !phy_resetn ) - tx_state <= TX_ST_0; - else - case(tx_state) - TX_ST_0: if ( tx_mode >= TX_MODE_XMT_PKT && !tx_f_pkt ) // /S/ - tx_state <= TX_ST_1; - TX_ST_1: if ( tx_sample && tx_byte_cnt == 8'h5 ) // preamble 0x55 - tx_state <= TX_ST_2; - TX_ST_2: if ( tx_sample ) - 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_finished && tx_byte_cnt < 60 ) // check if we need to pad? - tx_state <= TX_ST_5; - 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; - TX_ST_6: if ( tx_sample && fcs_addr == 2'b10 ) // Start FCS - tx_state <= TX_ST_7; - TX_ST_7: if (tx_sample && fcs_addr == 2'b11 ) // Finish FCS - tx_state <= TX_ST_8; - TX_ST_8: tx_state <= TX_ST_9; // EOP /T/ - TX_ST_9: if ( tx_byte_cnt[0] && !mode_100Mbit) // test for odd # of code words when in Gig mode for extra /R/ insertion - tx_state <= TX_ST_A; - else - tx_state <= TX_ST_B; - TX_ST_A: tx_state <= TX_ST_B; // 2nd /R/ if necessary ( odd position ) - TX_ST_B: tx_state <= TX_ST_C; // I2, K28.5 - TX_ST_C: tx_state <= TX_ST_0; // I2, D16.2 - - default: tx_state <= tx_state; - endcase - end - -/* -* tx related data mux and control signals -* TODO: add additional states for stuffing header values -* TODO: this will need to be registered at some point -* -*/ -always @(*) - begin - tx_f_pkt = 1'b0; - tx_k_pkt = 1'b0; - i_tx_disp_correct = 1'b0; - tx_last_byte = 1'b0; - fcs_init = 1'b0; - fcs_addr_e = 1'b0; - fcs_dout = tx_fifo_d_m1[7:0]; - metrics_start = 1'b0; - case(tx_state) - TX_ST_0: - begin - tx_data_pkt = K27_7; // start of packet - tx_k_pkt = 1'b1; - fcs_init = 1'b1; - end - TX_ST_1: begin - tx_data_pkt = 8'h55; // preamble, we need 6 bytes total of 0x55 - end - TX_ST_2: begin - tx_data_pkt = 8'h55; // preamble, single byte of 0x55 and assert fifo_re - end - TX_ST_3: begin - tx_data_pkt = 8'hD5; // preamble, single byte of 0xd5 completes the preamble) - end - TX_ST_4: - begin - if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd17) begin - tx_data_pkt = tx_ipv4_length[15:8]; - fcs_dout = tx_ipv4_length[15:8]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd18) begin - tx_data_pkt = tx_ipv4_length[7:0]; - fcs_dout = tx_ipv4_length[7:0]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd25) begin - tx_data_pkt = tx_ipv4_cksum[15:8]; - fcs_dout = tx_ipv4_cksum[15:8]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd26) begin - 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]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd40) begin - tx_data_pkt = tx_udp_length[7:0]; - fcs_dout = tx_udp_length[7:0]; - end - else if ( (tx_mode == TX_MODE_XMT_METRICS || tx_mode == TX_MODE_XMT_CUSTOM) - && tx_byte_cnt <= SZ_ETH_HEADER + SZ_IPV4_HEADER + SZ_UDP_HEADER ) - begin - tx_data_pkt = dpr_di_reg[7:0]; // packet headers - fcs_dout = dpr_di_reg[7:0]; - metrics_start = 1'b1; // keeps the metrics counters in reset - end - else if ( tx_mode == TX_MODE_XMT_METRICS ) - begin - tx_data_pkt = metrics_d; // packet content - fcs_dout = metrics_d[7:0]; - tx_last_byte = metrics_d[8]; - end - else - begin - tx_data_pkt = tx_fifo_d_m1[7:0]; // read data from FIFO - tx_last_byte = tx_fifo_d_m1[8]; - end - end - TX_ST_5: - begin - tx_data_pkt = 8'h00; // pad - fcs_dout = 8'h00; - end - TX_ST_6: begin - tx_data_pkt = fcs_din; // read from fcs - fcs_addr_e = 1'b1; - end - TX_ST_7: begin - tx_data_pkt = fcs_din; // read from fcs - fcs_addr_e = 1'b1; - end - TX_ST_8: - begin - tx_data_pkt = K29_7; // end of packet - tx_k_pkt = 1'b1; - end - TX_ST_9: - begin - tx_data_pkt = K23_7; // carrier extend - tx_k_pkt = 1'b1; - end - TX_ST_A: - begin - tx_data_pkt = K23_7; // carrier extend - tx_k_pkt = 1'b1; - end - TX_ST_B: - begin - tx_data_pkt = K28_5; // 1st idle code - tx_k_pkt = 1'b1; - end - TX_ST_C: - begin - tx_data_pkt = D16_2; // 2nd idle code - i_tx_disp_correct = 1'b1; // PCS may convert D16.2 to a D5.6 for I2 to flip disparity - tx_f_pkt = 1'b1; - end - default: - begin - tx_data_pkt = K_ERROR; - tx_k_pkt = 1'b1; - tx_f_pkt = 1'b1; - end - endcase -end - -/* - * tx_fifo_re - * - * The use of the read fifo is different between 1Gbit and 100Mbit. - * - */ -always @(*) - if ( tx_mode == TX_MODE_XMT_PKT ) - if ( mode_1Gbit && tx_state >= TX_ST_2 && tx_state <= TX_ST_4 ) - tx_fifo_re = 1'b1; - else if ( mode_100Mbit && tx_sample_re && tx_state > TX_ST_2 && tx_state <= TX_ST_4 ) - tx_fifo_re = 1'b1; - else if ( mode_100Mbit && tx_state == TX_ST_8 ) // we need an extra FIFO strobe at 100MBit for a single 1G clk - tx_fifo_re = 1'b1; - else - tx_fifo_re = 1'b0; - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_state == TX_ST_4 && tx_byte_cnt > SZ_ETH_HEADER + SZ_IPV4_HEADER + SZ_UDP_HEADER - 2) - tx_fifo_re = 1'b1; - else - tx_fifo_re = 1'b0; - - -always @(posedge clk, negedge rstn) - if (!rstn) - param_addr <= 'h0; - else if (tx_sample) - if ( mode_100Mbit && tx_state == TX_ST_1 && tx_byte_cnt == 'h5 ) - param_addr <= 'h0; - else if ( mode_1Gbit && tx_state == TX_ST_1 && tx_byte_cnt == 'h2 ) - param_addr <= 'h0; - else - param_addr <= param_addr + 1; - -/* - tx_byte_cnt - - Increment at pcs clock rate for PCS layer data (e.g., /I1/, /C/, /S/, etc. - - Increment at sample rate for Ethernet data - -*/ -always @(posedge clk, negedge rstn) - if (!rstn) - tx_byte_cnt <= 'h0; - else if (tx_sample || tx_state == TX_ST_0 || tx_state > TX_ST_7 || tx_mode < TX_MODE_XMT_PKT ) - if (tx_f) - tx_byte_cnt <= 'h0; - else if ( tx_state == TX_ST_2 ) - tx_byte_cnt <= 'h0; // start counting the Ethernet Frame after preamble - else - tx_byte_cnt <= tx_byte_cnt + 1; - -/* - * pipeline data from FIFO - */ -always @(posedge clk or negedge rstn) -begin - if ( !rstn ) - tx_fifo_d_m1 <= 9'h0; - else if ( tx_sample ) - tx_fifo_d_m1 <= tx_fifo_d; -end - -/* -* FCS -*/ -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - fcs_addr <= 2'b00; - else if (tx_sample) - if ( !fcs_addr_e ) - fcs_addr <= 2'b00; - else - fcs_addr <= fcs_addr + 1; - end - -always @(*) - if (mode_1Gbit && (tx_state == TX_ST_4 || tx_state == TX_ST_5) ) - fcs_enable = 1'b1; - else if ( mode_100Mbit && tx_sample && (tx_state == TX_ST_4 || tx_state == TX_ST_5) ) - fcs_enable = 1'b1; - else - fcs_enable = 1'b0; - -/* -* DPRAM, param ram Control for TAP port -*/ -always @(posedge clk or negedge rstn) - if ( !rstn ) - dpr_di_reg <= 9'h0; - else if (tx_sample) - dpr_di_reg <= dpr_di; - - -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 - * We choose to not include TX_MODE_CUSTOM_PKT for this metric - */ -always @(posedge clk or negedge rstn) - if (!rstn) - tx_sop <=1'b0; - else if ( tx_state == TX_ST_0 && tx_mode >= TX_MODE_XMT_PKT ) - tx_sop <= 1'b1; - else - tx_sop <= 1'b0; - - /* - * tx_eop, K29_7, 0xFD, /T/ End_of_Packet - */ -always @(posedge clk or negedge rstn) - if (!rstn) - tx_eop <=1'b0; - else if ( tx_state == TX_ST_7 ) - tx_eop <= 1'b1; - else - tx_eop <= 1'b0; - -// Layer 3 TX Support -always @(posedge clk or negedge rstn) - if (!rstn) - tx_ipv4_length <= 16'h0000; - else if ( tx_state == TX_ST_1 ) - tx_ipv4_length <= {5'h00, tx_byte_cnt_i} +SZ_IPV4_HEADER + SZ_UDP_HEADER; - -// tx_ipv4_cksum -always @(posedge clk or negedge rstn) - if (!rstn) - tx_ipv4_cksum <= 18'h00000; - else if ( tx_state == TX_ST_2 ) - tx_ipv4_cksum <= {10'h000, dpr_di_reg[7:0]}; - else if ( tx_state == TX_ST_3 ) - tx_ipv4_cksum <= {2'b00, dpr_di_reg[7:0], tx_ipv4_cksum[7:0]}; - else if (tx_state == TX_ST_4 && tx_byte_cnt == 'd1) - tx_ipv4_cksum <= tx_ipv4_cksum + tx_ipv4_length; - else if (tx_state == TX_ST_4 && tx_byte_cnt == 'd2) - tx_ipv4_cksum <= {2'b00,tx_ipv4_cksum[15:0]} + {16'h0000,tx_ipv4_cksum[17:16]}; - else if (tx_state == TX_ST_4 && tx_byte_cnt == 'd3) - tx_ipv4_cksum <= {2'b00, ~tx_ipv4_cksum[15:0]}; - -// Layer 4 TX Support -always @(posedge clk or negedge rstn) - if (!rstn) - tx_udp_length <= 16'h0000; - else if ( tx_state == TX_ST_1 ) - tx_udp_length <= {5'h00, tx_byte_cnt_i} + SZ_UDP_HEADER; - -/* Debug TX */ -always @(posedge clk or negedge rstn) - if (!rstn) - tx_active <=1'b0; - else if ( tx_state == TX_ST_1 ) - tx_active <= 1'b1; - else - tx_active <= 1'b0; - -endmodule -- cgit v1.2.3-8-gadcc