URL
https://opencores.org/ocsvn/ethmac10g/ethmac10g/trunk
Subversion Repositories ethmac10g
[/] [ethmac10g/] [trunk/] [rtl/] [verilog/] [tx_engine/] [TransmitTop.v] - Rev 72
Compare with Previous | Blame | View Log
///////////////////////////////////////////////////////////////////////////// // // Name of module // 23/1/06 - So far Mentor Precision indicates the current system runs as 101 MHz. // ///////////////////////////////////////////////////////////////////////////// module TRANSMIT_TOP( TX_DATA, TX_DATA_VALID, TX_CLK, RESET, TX_START, TX_ACK, TX_UNDERRUN, TX_IFG_DELAY, RXTXLINKFAULT, LOCALLINKFAULT, TX_STATS_VALID, TXSTATREGPLUS, TXD, TXC, FC_TRANS_PAUSEDATA, FC_TRANS_PAUSEVAL, FC_TX_PAUSEDATA, FC_TX_PAUSEVALID, TX_CFG_REG_VALUE, TX_CFG_REG_VALID ); ///////////////////////////////////////////////////////////////////////////// // // Input and output ports definitions // ///////////////////////////////////////////////////////////////////////////// //Input from user logic input [63:0] TX_DATA; input [7:0] TX_DATA_VALID; // To accept the data valid to be available input TX_CLK; input RESET; input TX_START; // This signify the first frame of data input TX_UNDERRUN; // this will cause an error to be injected into the data input [7:0] TX_IFG_DELAY; // this will cause a delay in the ack signal //input to transmit fault signals input RXTXLINKFAULT; input LOCALLINKFAULT; input [31:0] TX_CFG_REG_VALUE; input TX_CFG_REG_VALID; //output to stat register output TX_STATS_VALID; output [24:0] TXSTATREGPLUS; // a pulse for each reg for stats //output to user logic output TX_ACK; //Generated by a counter //output to XGMII output [63:0] TXD; output [7:0] TXC; //output [15:0] BYTE_COUNTER_OUT; //Pause inputs //Transmit pause frames input [15:0] FC_TRANS_PAUSEDATA; //pause frame data input FC_TRANS_PAUSEVAL; //pulse signal to indicate a pause frame to be sent //apply pause timing input [15:0] FC_TX_PAUSEDATA; input FC_TX_PAUSEVALID; ///////////////////////////////////////////////////////////////////////////// // // Definitions and parameters // ///////////////////////////////////////////////////////////////////////////// //possibility to put this in a package. //opcode definitions parameter PAUSE_OPCODE = 16'b1000100000001000; //8808 parameter VLAN_OPCODE = 16'b1000000100000000; //8100 //frame size definitions parameter VLAN_FRAME_SIZE = 16'b0000010111110010;//1522 bytes parameter JUMBO_FRAME_SIZE = 16'b0010001100101000;//9000 bytes parameter NORMAL_FRAME_SIZE = 16'b0000010111101110;//1518 bytes parameter MIN_FRAME_SIZE = 16'b0000000000111100; //60 bytes //Frame definition parameter IDLE_FRAME = 8'b00000111; //only six preambles as the first preamble is converted into a start flag parameter IDLE_FRAME_8BYTES = 64'b0000011100000111000001110000011100000111000001110000011100000111; parameter START_SEQ = 64'b1010101110101010101010101010101010101010101010101010101011111011; parameter LOCAL_FAULT_SEQ = 64'b0000000100000000000000000000000000000001000000000000000000000000; parameter REMOTE_FAULT_SEQ = 64'b0000001000000000000000000000000000000010000000000000000000000000; parameter START_FRAME = 8'b11111011; //only valid in frame 0 parameter TERMINATE_FRAME = 8'b11111101; parameter SFD_FRAME = 8'b10101011; parameter PREAMBLE_FRAME = 8'b10101010; parameter ERROR_FRAME = 8'b11111110; parameter SOURCE_ADDR = 48'h010101010101; parameter DEST_ADDR = 48'h101010101010; parameter PAUSE_FRAME_LENGTH = 8'h02; //need a parameter for min frame gap. //Link fault signalling // send lane 0 ///////////////////////////////////////////////////////////////////////////// // // Registers and wires // ///////////////////////////////////////////////////////////////////////////// wire TX_ACK; reg [24:0] TXSTATREGPLUS; reg TX_STATS_VALID; reg FRAME_START; wire reset_int; reg [15:0] DELAY_ACK; reg [7:0] TX_DATA_VALID_REG; reg [7:0] TX_DATA_VALID_DEL1; reg [7:0] TX_DATA_VALID_DEL2; reg [7:0] TX_DATA_VALID_DEL3; reg [7:0] TX_DATA_VALID_DEL4; reg [7:0] TX_DATA_VALID_DEL5; reg [7:0] TX_DATA_VALID_DEL6; reg [7:0] TX_DATA_VALID_DEL7; reg [7:0] TX_DATA_VALID_DEL8; reg [7:0] TX_DATA_VALID_DEL9; reg [7:0] TX_DATA_VALID_DEL10; reg [7:0] TX_DATA_VALID_DEL11; reg [7:0] TX_DATA_VALID_DEL12; reg [7:0] TX_DATA_VALID_DEL13; reg [7:0] TX_DATA_VALID_DEL14; reg [7:0] TX_DATA_VALID_DEL15; reg [63:0] TX_DATA_DEL1; reg [63:0] TX_DATA_DEL2; reg [63:0] TX_DATA_DEL3; reg [63:0] TX_DATA_DEL4; reg [63:0] TX_DATA_DEL5; reg [63:0] TX_DATA_DEL6; reg [63:0] TX_DATA_DEL7; reg [63:0] TX_DATA_DEL8; reg [63:0] TX_DATA_DEL9; reg [63:0] TX_DATA_DEL10; reg [63:0] TX_DATA_DEL11; reg [63:0] TX_DATA_DEL12; reg [63:0] TX_DATA_DEL13; reg [63:0] TX_DATA_DEL14; reg [63:0] TX_DATA_DEL15; reg [7:0] OVERFLOW_VALID; reg [63:0] OVERFLOW_DATA; reg [63:0] TXD; reg [7:0] TXC; reg [63:0] TX_DATA_REG, TX_DATA_VALID_DELAY; wire [31:0] CRC_32_64; wire [15:0] BYTE_COUNTER; reg frame_start_del; reg transmit_pause_frame_del, transmit_pause_frame_del2, transmit_pause_frame, append_start_pause, append_start_pause_del , transmit_pause_frame_valid, reset_err_pause, load_CRC8, transmit_pause_frame_del3; reg [7:0] tx_data_int; reg start_CRC8, START_CRC8_DEL; reg append_end_frame; reg insert_error; reg [7:0] store_tx_data_valid; reg [63:0] store_tx_data; reg [31:0] store_CRC64; reg [7:0] store_valid; reg load_final_CRC; reg [15:0] final_byte_count, byte_count_reg; wire [31:0] CRC_OUT; reg [9:0] append_reg; reg [15:0] length_register; reg tx_undderrun_int; reg [15:0] MAX_FRAME_SIZE; reg vlan_enabled_int; reg jumbo_enabled_int; reg tx_enabled_int; reg fcs_enabled_int; reg reset_tx_int; reg read_ifg_int; reg apply_pause_delay; reg [15:0] store_pause_frame; reg [63:0] TXD_PAUSE_DEL0; reg [63:0] TXD_PAUSE_DEL1; reg [63:0] TXD_PAUSE_DEL2; reg [7:0] TXC_PAUSE_DEL0; reg [7:0] TXC_PAUSE_DEL1; reg [7:0] TXC_PAUSE_DEL2; reg PAUSEVAL_DEL; reg PAUSEVAL_DEL1; reg PAUSEVAL_DEL2; wire RESET_ERR_PAUSE; reg set_pause_stats; reg [15:0] store_transmit_pause_value; reg [3:0] pause_frame_counter; reg [63:0] shift_pause_data; reg [7:0] shift_pause_valid; reg [7:0] shift_pause_valid_del; reg [14:0] byte_count_stat; reg [24:0] txstatplus_int; ///////////////////////////////////////////////////////////////////////////// // // Start of code // ///////////////////////////////////////////////////////////////////////////// //TODO //RX side. need to be able to receive data and calculate the CRC switching between 64 and 8 bit datapath. //Therefore, the data need to be counted correctly. //ERROR checking module or process will be needed. This will check if frame is correct length. //Need to be able to remove redundant frames or columns and also padding. The error module will //also check the tx_underrun signal as well. //need to be able to cut-off bytes. //Need to add the link fault signalling and config registers. //TX side. need to be able to insert the CRC with the data. //need to define the first column of txd which is START 6 PRE and SFD. //need to be able invert data_valid for txc. //need to be able to transmit IDLEs. //Format of output //IDLE 07, START FB TERMINATE FD SFD 10101011 PREAMBLE 10101010 ERROR FE. //IDLE START PREAMBLE SFD DA SA L/T DATA TERMINATE IDLE ///////////////////////////////////////////////////////////////////////////// // // Ack counter // ///////////////////////////////////////////////////////////////////////////// //Ack counter. need to be able to load the frame length, pause frame inter frame delay into the ack counter // as this will delay the ack signal. The ack signal will initiate the rest of the data transmission from the // user logic. //need to stop the ack signal from transmitting when a PAUSE frame is transmitting // Connect DUT to test bench ack_counter U_ACK_CNT( .clock(TX_CLK), .reset(reset_int | reset_tx_int), .ready(FRAME_START | transmit_pause_frame), .tx_start(TX_START), .max_count(DELAY_ACK), .tx_ack(TX_ACK) ); //CRC for 64 bit data //This seem to be one of the culprit for the timing violation CRC32_D64 U_CRC64( .DATA_IN(TX_DATA_REG), //need to swap between pause data .CLK(TX_CLK), .RESET(reset_int | TX_ACK | append_start_pause), .START(frame_start_del | transmit_pause_frame_valid), .CRC_OUT(CRC_32_64) //need to switch to output some how for a pause frame ); //CRC for 8 bit data CRC32_D8 U_CRC8( .DATA_IN(tx_data_int), //8bit data .CLK(TX_CLK), .RESET(reset_int), .START(start_CRC8), //this signal will be use to start .LOAD(load_CRC8), //use this to load first .CRC_IN(CRC_32_64), .CRC_OUT(CRC_OUT) ); //The start signal need to be high for the count //This seem to be one of the culprit for the timing violation byte_count_module U_byte_count_module( .CLK(TX_CLK), .RESET(reset_int | TX_ACK), .START(frame_start_del & FRAME_START), .BYTE_COUNTER(BYTE_COUNTER) ); ///////////////////////////////////////////////////////////////////////////// // // PAUSE FRAME // ///////////////////////////////////////////////////////////////////////////// always @(posedge TX_CLK) begin PAUSEVAL_DEL <= FC_TRANS_PAUSEVAL; PAUSEVAL_DEL1 <= PAUSEVAL_DEL; PAUSEVAL_DEL2 <= PAUSEVAL_DEL1; end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin transmit_pause_frame <= 0; end else if (PAUSEVAL_DEL2) begin transmit_pause_frame <= 1; end else if (pause_frame_counter == 8) begin transmit_pause_frame <= 0; end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin set_pause_stats <= 0; end else if (PAUSEVAL_DEL2) begin set_pause_stats <= 1; end else if (append_end_frame) begin set_pause_stats <= 0; end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin TXD_PAUSE_DEL0 <= 0; TXD_PAUSE_DEL1 <= 0; TXD_PAUSE_DEL2 <= 0; TXC_PAUSE_DEL0 <= 0; TXC_PAUSE_DEL1 <= 0; TXC_PAUSE_DEL2 <= 0; store_transmit_pause_value <= 0; end else if (FC_TRANS_PAUSEVAL) begin store_transmit_pause_value <= FC_TRANS_PAUSEDATA; TXD_PAUSE_DEL1 <= {DEST_ADDR, SOURCE_ADDR[47:32]}; TXD_PAUSE_DEL2 <= {SOURCE_ADDR[31:0], PAUSE_FRAME_LENGTH, PAUSE_OPCODE, FC_TRANS_PAUSEDATA}; TXC_PAUSE_DEL1 <= 8'hff; TXC_PAUSE_DEL2 <= 8'hff; end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin pause_frame_counter <= 0; end else if (transmit_pause_frame & !FRAME_START) begin pause_frame_counter <= pause_frame_counter + 1; end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin shift_pause_data <= 0; shift_pause_valid_del <= 0; shift_pause_valid <= 0; end else if (transmit_pause_frame & !FRAME_START) begin if (pause_frame_counter == 0) begin shift_pause_data <= TXD_PAUSE_DEL1; end else if (pause_frame_counter == 1) begin shift_pause_data <= TXD_PAUSE_DEL2; end else begin shift_pause_data <= 0; end if (pause_frame_counter == 7) begin shift_pause_valid <= 8'h0f; end else if (pause_frame_counter < 7) begin shift_pause_valid <= 8'hff; end else begin shift_pause_valid <= 0; end shift_pause_valid_del <= shift_pause_valid; end else begin shift_pause_data <= 0; shift_pause_valid <= 0; shift_pause_valid_del <= shift_pause_valid; end end always @(posedge reset_int or posedge TX_CLK) begin if (reset_int) begin FRAME_START <= 0; end else if (TX_ACK) begin FRAME_START <= 1; end else if ((TX_DATA_VALID_REG != 8'hff) & (BYTE_COUNTER != 0)) begin FRAME_START <= 0; end end assign reset_int = RESET; //TXSTATREGPLUS[24:0] //24 pause_frame transmitted - count when pause flag is set //23 to 20 bytes valid //19 vlan frame - asserted if previous frame was a VLAN - just check if VLAN been set //18 to 5 last frame length count in bytes stick to 16383 when jumbo frame is greater than value - just load the byte count //4 if last frame has control type code 88-08 in the length type field - pause frame - check if pause flag is set //3 underrun frame - check if underrun is set //2 multicast frame - 01-80-C2-00-00-01 use for pause frame //1 broadcast frame - al ones //0 sucessful frame - check if error occurred -use insert error flag //TX_STATS_VALID - need to be driving after a frame transmission - use load_overflow signal always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin txstatplus_int <= 0; end else if (load_final_CRC) begin if (insert_error) begin txstatplus_int[3] <= 1; end if (set_pause_stats) begin txstatplus_int[24] <= 1; txstatplus_int[4] <= 1; txstatplus_int[2] <= 1; txstatplus_int[1] <= 1; txstatplus_int[18:5] <= 512; end if (vlan_enabled_int) begin txstatplus_int[19] <= 1; end else begin if (final_byte_count[15] == 1) begin txstatplus_int[18:5] <= 16383; end else begin txstatplus_int[18:5] <= byte_count_stat; end end end else begin txstatplus_int <= 0; end end always @(posedge TX_CLK) begin TXSTATREGPLUS <= txstatplus_int; TX_STATS_VALID <= append_end_frame; end //input [31:0] TX_CFG_REG_VALUE; //24:0 reserved //25 default to 0 - min frame - 1 adjust frame delay by reading inter-frame gap delay reg - DELAY_ACK signal //26 WAN - not used //27 VLAN enable default to 0, 1 enabled //28 default to 1 - transmitter enbaled, 0 - transmitter disabled - possibly used to reset //29 default to 0 FCS enabled, 1 FCS disabled //30 default to 0, 1 - Jumbo frame enabled //31 deafult to 0, 1 - reset transmitter //input TX_CFG_REG_VALID; always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin vlan_enabled_int <= 0; jumbo_enabled_int <= 0; tx_enabled_int <= 0; fcs_enabled_int <= 1; reset_tx_int <= 0; read_ifg_int <= 0; end else if (TX_CFG_REG_VALID) begin vlan_enabled_int <= TX_CFG_REG_VALUE[27]; jumbo_enabled_int <= TX_CFG_REG_VALUE[30]; tx_enabled_int <= TX_CFG_REG_VALUE[28]; // Stop ack from generated, hold reset fcs_enabled_int <= TX_CFG_REG_VALUE[29]; reset_tx_int <= TX_CFG_REG_VALUE[31]; read_ifg_int <= TX_CFG_REG_VALUE[25]; end end //Load the delay value for the acknowledge signal always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin DELAY_ACK <= 16'h0001; end else if (apply_pause_delay) begin DELAY_ACK <= store_pause_frame; end else if (read_ifg_int) begin DELAY_ACK <= TX_IFG_DELAY; end end //Need to expand to be setup by the config register //1514 with out FCS added, 1518 when FCS is added //1518 without FCS added, 1522 when FCS is added always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin MAX_FRAME_SIZE <= 1514; end else begin if (vlan_enabled_int) begin if (fcs_enabled_int) begin MAX_FRAME_SIZE <= 1522; end else begin MAX_FRAME_SIZE <= 1518; end end else if (jumbo_enabled_int) begin if (fcs_enabled_int) begin MAX_FRAME_SIZE <= 1518; end else begin MAX_FRAME_SIZE <= 1514; end end else begin if (fcs_enabled_int) begin MAX_FRAME_SIZE <= 1518; end else begin MAX_FRAME_SIZE <= 1514; end end end end always @(posedge TX_CLK) begin if (reset_int) begin tx_undderrun_int <= 0; end else if (append_end_frame)begin tx_undderrun_int <= 0; end else if (TX_UNDERRUN) begin tx_undderrun_int <= 1; end end //Indicate an error always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin insert_error <= 0; end else if (append_end_frame | reset_err_pause) begin insert_error <= 0; end else if (load_CRC8) begin if (tx_undderrun_int == 1) begin insert_error <= 1; end else begin if (length_register == final_byte_count) begin if (final_byte_count <= MAX_FRAME_SIZE) begin insert_error <= 0; end else begin insert_error <= 1; end end else if (length_register < MIN_FRAME_SIZE) begin if (final_byte_count == 64) begin insert_error <= 0; end else begin insert_error <= 1; end end else begin insert_error <= 1; end end end end //use for delaying the ack signal when pause is required always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin apply_pause_delay <= 0; store_pause_frame <= 0; end else if (TX_ACK) begin apply_pause_delay <= 0; store_pause_frame <= 0; end else if (FC_TX_PAUSEVALID) begin apply_pause_delay <= 1; store_pause_frame <= FC_TX_PAUSEDATA; end end always @(posedge TX_CLK) begin if (TX_START) begin TX_DATA_VALID_DELAY <= IDLE_FRAME_8BYTES; end else begin TX_DATA_VALID_DELAY <= TX_DATA; end end //Shift valid into the system and also ensuring min frame is achieved always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin TX_DATA_VALID_REG <= 0; end else if (FRAME_START) begin if (BYTE_COUNTER < 48) begin TX_DATA_VALID_REG <= 8'b11111111; end else if (BYTE_COUNTER == 48) begin if (TX_START) begin TX_DATA_VALID_REG <= 8'b00001111; end else begin TX_DATA_VALID_REG <= 8'b00001111 | TX_DATA_VALID; end end else begin if (TX_START) begin TX_DATA_VALID_REG <= 0; end else begin TX_DATA_VALID_REG <= TX_DATA_VALID; end end end else if (transmit_pause_frame_del) begin TX_DATA_VALID_REG <= shift_pause_valid_del; end else begin TX_DATA_VALID_REG <= 0; end end //Shifting data to the system. Also ensuring min frame is achieved always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin TX_DATA_REG <= IDLE_FRAME_8BYTES; end else if (FRAME_START) begin if (BYTE_COUNTER < 56) begin case (TX_DATA_VALID_REG) 8'b00000000 : begin TX_DATA_REG <= TX_DATA_VALID_DELAY; end 8'b00000001 : begin TX_DATA_REG <= {56'h00000000000000, TX_DATA_VALID_DELAY[7:0]}; end 8'b00000011 : begin TX_DATA_REG <= {48'h000000000000, TX_DATA_VALID_DELAY[15:0]}; end 8'b00000111 : begin TX_DATA_REG <= {40'h0000000000, TX_DATA_VALID_DELAY[23:0]}; end 8'b00001111 : begin TX_DATA_REG <= {32'h00000000, TX_DATA_VALID_DELAY[31:0]}; end 8'b00011111 : begin TX_DATA_REG <= {24'h000000, TX_DATA_VALID_DELAY[39:0]}; end 8'b00111111 : begin TX_DATA_REG <= {16'h0000, TX_DATA_VALID_DELAY[47:0]}; end 8'b01111111 : begin TX_DATA_REG <= {8'h00, TX_DATA_VALID_DELAY[55:0]}; end 8'b11111111 : begin TX_DATA_REG <= TX_DATA_VALID_DELAY; end endcase end else begin TX_DATA_REG <= TX_DATA_VALID_DELAY; end end else if (transmit_pause_frame_valid) begin TX_DATA_REG <= shift_pause_data; end else begin if (TX_ACK | append_start_pause) begin TX_DATA_REG <= START_SEQ; end else begin TX_DATA_REG <= IDLE_FRAME_8BYTES; end end end //Use for shifting data to CRC and loading start value for CRC always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin frame_start_del <= 0; transmit_pause_frame_del <= 0; transmit_pause_frame_del2 <= 0; transmit_pause_frame_del3 <= 0; append_start_pause <= 0; append_start_pause_del <= 0; transmit_pause_frame_valid <= 0; reset_err_pause <= 0; load_CRC8 <= 0; end else begin frame_start_del <= FRAME_START; transmit_pause_frame_del <= transmit_pause_frame; transmit_pause_frame_del2 <= transmit_pause_frame_del; transmit_pause_frame_del3 <= transmit_pause_frame_del2; append_start_pause <= (!transmit_pause_frame_del & transmit_pause_frame); append_start_pause_del <= append_start_pause; transmit_pause_frame_valid <= (transmit_pause_frame_del & transmit_pause_frame); reset_err_pause <= (transmit_pause_frame_del & !transmit_pause_frame); load_CRC8 <= (frame_start_del & !FRAME_START) | (transmit_pause_frame_del3 & !transmit_pause_frame_del2); end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin TX_DATA_VALID_DEL1 <= 0; TX_DATA_VALID_DEL2 <= 0; TX_DATA_VALID_DEL3 <= 0; TX_DATA_VALID_DEL4 <= 0; TX_DATA_VALID_DEL5 <= 0; TX_DATA_VALID_DEL6 <= 0; TX_DATA_VALID_DEL7 <= 0; TX_DATA_VALID_DEL8 <= 0; TX_DATA_VALID_DEL9 <= 0; TX_DATA_VALID_DEL10 <= 0; TX_DATA_VALID_DEL11 <= 0; TX_DATA_VALID_DEL12 <= 0; TX_DATA_VALID_DEL13 <= 0; TX_DATA_VALID_DEL14 <= 0; TX_DATA_VALID_DEL15 <= 0; OVERFLOW_VALID <= 0; end else begin TX_DATA_VALID_DEL1 <= TX_DATA_VALID_REG; TX_DATA_VALID_DEL2 <= TX_DATA_VALID_DEL1; TX_DATA_VALID_DEL3 <= TX_DATA_VALID_DEL2; TX_DATA_VALID_DEL4 <= TX_DATA_VALID_DEL3; TX_DATA_VALID_DEL5 <= TX_DATA_VALID_DEL4; TX_DATA_VALID_DEL6 <= TX_DATA_VALID_DEL5; TX_DATA_VALID_DEL7 <= TX_DATA_VALID_DEL6; TX_DATA_VALID_DEL8 <= TX_DATA_VALID_DEL7; TX_DATA_VALID_DEL9 <= TX_DATA_VALID_DEL8; TX_DATA_VALID_DEL10 <= TX_DATA_VALID_DEL9; TX_DATA_VALID_DEL11 <= TX_DATA_VALID_DEL10; TX_DATA_VALID_DEL12 <= TX_DATA_VALID_DEL11; TX_DATA_VALID_DEL13 <= TX_DATA_VALID_DEL12; TX_DATA_VALID_DEL14 <= TX_DATA_VALID_DEL13; if (load_final_CRC) begin case (TX_DATA_VALID_DEL13) 8'b00000000 : begin if (fcs_enabled_int) begin TX_DATA_VALID_DEL14 <= 8'b00001111; end else begin TX_DATA_VALID_DEL14 <= 8'b00001111; end OVERFLOW_VALID <= 8'b00000000; end 8'b00000001 : begin if (fcs_enabled_int) begin TX_DATA_VALID_DEL14 <= 8'b00011111; end OVERFLOW_VALID <= 8'b00000000; end 8'b00000011 : begin if (fcs_enabled_int) begin TX_DATA_VALID_DEL14 <= 8'b00111111; end OVERFLOW_VALID <= 8'b00000000; end 8'b00000111 : begin if (fcs_enabled_int) begin TX_DATA_VALID_DEL14 <= 8'b01111111; end OVERFLOW_VALID <= 8'b00000000; end 8'b00001111 : begin if (fcs_enabled_int) begin TX_DATA_VALID_DEL14 <= 8'b11111111; end OVERFLOW_VALID <= 8'b00000000; end 8'b00011111 : begin if (fcs_enabled_int) begin TX_DATA_VALID_DEL14 <= 8'b11111111; OVERFLOW_VALID <= 8'b00000001; end else begin OVERFLOW_VALID <= 8'b00000000; end end 8'b00111111 : begin if (fcs_enabled_int) begin TX_DATA_VALID_DEL14 <= 8'b11111111; OVERFLOW_VALID <= 8'b00000011; end else begin OVERFLOW_VALID <= 8'b00000000; end end 8'b01111111 : begin if (fcs_enabled_int) begin TX_DATA_VALID_DEL14 <= 8'b11111111; OVERFLOW_VALID <= 8'b00000111; end else begin OVERFLOW_VALID <= 8'b00000000; end end endcase end else if (append_end_frame) begin TX_DATA_VALID_DEL14 <= OVERFLOW_VALID; end TX_DATA_VALID_DEL15 <= TX_DATA_VALID_DEL14; TXC <= TX_DATA_VALID_DEL15; end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin TX_DATA_DEL1 <= 0; TX_DATA_DEL2 <= 0; TX_DATA_DEL3 <= 0; TX_DATA_DEL4 <= 0; TX_DATA_DEL5 <= 0; TX_DATA_DEL6 <= 0; TX_DATA_DEL7 <= 0; TX_DATA_DEL8 <= 0; TX_DATA_DEL9 <= 0; TX_DATA_DEL10 <= 0; TX_DATA_DEL11 <= 0; TX_DATA_DEL12 <= 0; TX_DATA_DEL13 <= 0; TX_DATA_DEL14 <= 0; TX_DATA_DEL15 <= 0; OVERFLOW_DATA <= IDLE_FRAME_8BYTES; end else begin TX_DATA_DEL1 <= TX_DATA_REG; TX_DATA_DEL2 <= TX_DATA_DEL1; TX_DATA_DEL3 <= TX_DATA_DEL2; TX_DATA_DEL4 <= TX_DATA_DEL3; TX_DATA_DEL5 <= TX_DATA_DEL4; TX_DATA_DEL6 <= TX_DATA_DEL5; TX_DATA_DEL7 <= TX_DATA_DEL6; TX_DATA_DEL8 <= TX_DATA_DEL7; TX_DATA_DEL9 <= TX_DATA_DEL8; TX_DATA_DEL10 <= TX_DATA_DEL9; TX_DATA_DEL11 <= TX_DATA_DEL10; TX_DATA_DEL12 <= TX_DATA_DEL11; TX_DATA_DEL13 <= TX_DATA_DEL12; TX_DATA_DEL14 <= TX_DATA_DEL13; if (load_final_CRC) begin case (TX_DATA_VALID_DEL13) 8'b00000000 : begin if (fcs_enabled_int) begin TX_DATA_DEL14[31:0] <= CRC_OUT[31:0]; if (insert_error) begin TX_DATA_DEL14[39:32] <= ERROR_FRAME; TX_DATA_DEL14[47:40] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14[39:32] <= TERMINATE_FRAME; TX_DATA_DEL14[47:40] <= IDLE_FRAME; end TX_DATA_DEL14[55:48] <= IDLE_FRAME; TX_DATA_DEL14[63:56] <= IDLE_FRAME; end else begin if (insert_error) begin TX_DATA_DEL14[7:0] <= ERROR_FRAME; TX_DATA_DEL14[15:8] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14[7:0] <= TERMINATE_FRAME; TX_DATA_DEL14[15:8] <= IDLE_FRAME; end TX_DATA_DEL14[23:16] <= IDLE_FRAME; TX_DATA_DEL14[31:24] <= IDLE_FRAME; TX_DATA_DEL14[39:32] <= IDLE_FRAME; TX_DATA_DEL14[47:40] <= IDLE_FRAME; TX_DATA_DEL14[55:48] <= IDLE_FRAME; TX_DATA_DEL14[63:56] <= IDLE_FRAME; end OVERFLOW_DATA <= IDLE_FRAME_8BYTES; end 8'b00000001 : begin if (fcs_enabled_int) begin TX_DATA_DEL14[7:0] <= TX_DATA_DEL13[7:0]; TX_DATA_DEL14[39:8] <= CRC_OUT[31:0]; if (insert_error) begin TX_DATA_DEL14[47:40] <= ERROR_FRAME; TX_DATA_DEL14[55:48] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14[47:40] <= TERMINATE_FRAME; TX_DATA_DEL14[55:48] <= IDLE_FRAME; end TX_DATA_DEL14[63:56] <= IDLE_FRAME; TX_DATA_DEL14 <= TX_DATA_DEL13; end else begin TX_DATA_DEL14[7:0] <= TX_DATA_DEL13[7:0]; if (insert_error) begin TX_DATA_DEL14[15:8] <= ERROR_FRAME; TX_DATA_DEL14[23:16] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14[15:8] <= TERMINATE_FRAME; TX_DATA_DEL14[23:16] <= IDLE_FRAME; end TX_DATA_DEL14[31:24] <= IDLE_FRAME; TX_DATA_DEL14[39:32] <= IDLE_FRAME; TX_DATA_DEL14[47:40] <= IDLE_FRAME; TX_DATA_DEL14[55:48] <= IDLE_FRAME; TX_DATA_DEL14[63:56] <= IDLE_FRAME; TX_DATA_DEL14 <= TX_DATA_DEL13; end OVERFLOW_DATA <= IDLE_FRAME_8BYTES; end 8'b00000011 : begin if (fcs_enabled_int) begin TX_DATA_DEL14[15:0] <= TX_DATA_DEL13[15:0]; TX_DATA_DEL14[47:16] <= CRC_OUT[31:0]; if (insert_error) begin TX_DATA_DEL14[55:48] <= ERROR_FRAME; TX_DATA_DEL14[63:56] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14[55:48] <= TERMINATE_FRAME; TX_DATA_DEL14[63:56] <= IDLE_FRAME; end end else begin TX_DATA_DEL14[15:0] <= TX_DATA_DEL13[15:0]; if (insert_error) begin TX_DATA_DEL14[23:16] <= ERROR_FRAME; TX_DATA_DEL14[31:24] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14[23:16] <= TERMINATE_FRAME; TX_DATA_DEL14[31:24] <= IDLE_FRAME; end TX_DATA_DEL14[39:32] <= IDLE_FRAME; TX_DATA_DEL14[47:40] <= IDLE_FRAME; TX_DATA_DEL14[55:48] <= IDLE_FRAME; TX_DATA_DEL14[63:56] <= IDLE_FRAME; end OVERFLOW_DATA <= IDLE_FRAME_8BYTES; end 8'b00000111 : begin if (fcs_enabled_int) begin TX_DATA_DEL14[23:0] <= TX_DATA_DEL13[23:0]; TX_DATA_DEL14[55:24] <= CRC_OUT[31:0]; OVERFLOW_DATA <= IDLE_FRAME_8BYTES; if (insert_error) begin TX_DATA_DEL14[63:56] <= ERROR_FRAME; OVERFLOW_DATA[7:0] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14[63:56] <= TERMINATE_FRAME; end end else begin TX_DATA_DEL14[23:0] <= TX_DATA_DEL13[23:0]; TX_DATA_DEL14[55:24] <= CRC_OUT[31:0]; OVERFLOW_DATA <= IDLE_FRAME_8BYTES; if (insert_error) begin TX_DATA_DEL14[31:24] <= ERROR_FRAME; TX_DATA_DEL14[39:32] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14[31:24] <= TERMINATE_FRAME; TX_DATA_DEL14[39:32] <= IDLE_FRAME; end TX_DATA_DEL14[47:40] <= IDLE_FRAME; TX_DATA_DEL14[55:48] <= IDLE_FRAME; TX_DATA_DEL14[63:56] <= IDLE_FRAME; end end 8'b00001111 : begin if (fcs_enabled_int) begin TX_DATA_DEL14[31:0] <= TX_DATA_DEL13[31:0]; TX_DATA_DEL14[63:32]<= CRC_OUT[31:0]; if (insert_error) begin OVERFLOW_DATA [7:0] <= ERROR_FRAME; OVERFLOW_DATA[15:8] <= TERMINATE_FRAME; end else begin OVERFLOW_DATA [7:0]<= TERMINATE_FRAME; OVERFLOW_DATA [15:8]<= IDLE_FRAME; end OVERFLOW_DATA [23:16]<= IDLE_FRAME; OVERFLOW_DATA [31:24]<= IDLE_FRAME; OVERFLOW_DATA [39:32]<= IDLE_FRAME; OVERFLOW_DATA [47:40]<= IDLE_FRAME; OVERFLOW_DATA [55:48]<= IDLE_FRAME; OVERFLOW_DATA [63:56]<= IDLE_FRAME; end else begin TX_DATA_DEL14[31:0] <= TX_DATA_DEL13[31:0]; OVERFLOW_DATA <= IDLE_FRAME_8BYTES; if (insert_error) begin TX_DATA_DEL14 [39:32] <= ERROR_FRAME; TX_DATA_DEL14[47:40] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14 [39:32]<= TERMINATE_FRAME; TX_DATA_DEL14 [47:40]<= IDLE_FRAME; end TX_DATA_DEL14[55:48] <= IDLE_FRAME; TX_DATA_DEL14[63:56] <= IDLE_FRAME; end end 8'b00011111 : begin if (fcs_enabled_int) begin TX_DATA_DEL14[39:0] <= TX_DATA_DEL13[39:0]; TX_DATA_DEL14[63:40] <= CRC_OUT[23:0]; OVERFLOW_DATA [7:0]<= CRC_OUT[31:24]; if (insert_error) begin OVERFLOW_DATA [15:8]<= ERROR_FRAME; OVERFLOW_DATA [23:16]<= TERMINATE_FRAME; end else begin OVERFLOW_DATA [15:8]<= TERMINATE_FRAME; OVERFLOW_DATA [23:16]<= IDLE_FRAME; end OVERFLOW_DATA [31:24]<= IDLE_FRAME; OVERFLOW_DATA [39:32]<= IDLE_FRAME; OVERFLOW_DATA [47:40]<= IDLE_FRAME; OVERFLOW_DATA [55:48]<= IDLE_FRAME; OVERFLOW_DATA [63:56]<= IDLE_FRAME; end else begin TX_DATA_DEL14[39:0] <= TX_DATA_DEL13[39:0]; OVERFLOW_DATA <= IDLE_FRAME_8BYTES; if (insert_error) begin TX_DATA_DEL14 [47:40] <= ERROR_FRAME; TX_DATA_DEL14[55:48] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14 [47:40]<= TERMINATE_FRAME; TX_DATA_DEL14 [55:48]<= IDLE_FRAME; end TX_DATA_DEL14[63:56] <= IDLE_FRAME; end end 8'b00111111 : begin if (fcs_enabled_int) begin TX_DATA_DEL14[47:0] <= TX_DATA_DEL13[47:0]; TX_DATA_DEL14[63:48] <= CRC_OUT[15:0]; OVERFLOW_DATA [15:0]<= CRC_OUT[31:16]; if (insert_error) begin OVERFLOW_DATA [23:16]<= ERROR_FRAME; OVERFLOW_DATA [31:24]<= TERMINATE_FRAME; end else begin OVERFLOW_DATA [23:16]<= TERMINATE_FRAME; OVERFLOW_DATA [31:24]<= IDLE_FRAME; end OVERFLOW_DATA [39:32]<= IDLE_FRAME; OVERFLOW_DATA [47:40]<= IDLE_FRAME; OVERFLOW_DATA [55:48]<= IDLE_FRAME; OVERFLOW_DATA [63:56]<= IDLE_FRAME; end else begin TX_DATA_DEL14[47:0] <= TX_DATA_DEL13[47:0]; if (insert_error) begin TX_DATA_DEL14 [55:48] <= ERROR_FRAME; TX_DATA_DEL14[63:56] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14 [55:48]<= TERMINATE_FRAME; TX_DATA_DEL14 [63:56]<= IDLE_FRAME; end end end 8'b01111111 : begin if (fcs_enabled_int) begin TX_DATA_DEL14[55:0] <= TX_DATA_DEL13[55:0]; TX_DATA_DEL14[63:56] <= CRC_OUT[7:0]; OVERFLOW_DATA [23:0]<= CRC_OUT[31:8]; if (insert_error) begin OVERFLOW_DATA [31:24]<= ERROR_FRAME; OVERFLOW_DATA [39:32]<= TERMINATE_FRAME; end else begin OVERFLOW_DATA [31:24]<= TERMINATE_FRAME; OVERFLOW_DATA [39:32]<= IDLE_FRAME; end OVERFLOW_DATA [47:40]<= IDLE_FRAME; OVERFLOW_DATA [55:48]<= IDLE_FRAME; OVERFLOW_DATA [63:56]<= IDLE_FRAME; end else begin TX_DATA_DEL14[55:0] <= TX_DATA_DEL13[55:0]; OVERFLOW_DATA <= IDLE_FRAME_8BYTES; if (insert_error) begin TX_DATA_DEL14 [63:56] <= ERROR_FRAME; OVERFLOW_DATA[7:0] <= TERMINATE_FRAME; end else begin TX_DATA_DEL14 [63:56]<= TERMINATE_FRAME; OVERFLOW_DATA [7:0]<= IDLE_FRAME; end end end endcase end else if (append_end_frame) begin TX_DATA_DEL14 <= OVERFLOW_DATA; end TX_DATA_DEL15 <= TX_DATA_DEL14; TXD <= TX_DATA_DEL15; end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin store_tx_data_valid <= 0; store_tx_data <= 0; store_CRC64 <= 0; tx_data_int <= 0; end else if (load_CRC8) begin store_tx_data_valid <= TX_DATA_VALID_DEL2; store_tx_data <= TX_DATA_DEL2; store_CRC64 <= CRC_32_64; end else begin store_tx_data_valid[6:0] <= store_tx_data_valid[7:1]; tx_data_int <= store_tx_data[7:0]; store_tx_data[55:0] <= store_tx_data[63:8]; end end //Start CRC8 and load CRC8 always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin start_CRC8 <= 0; START_CRC8_DEL <= 0; end else begin start_CRC8 <= store_tx_data_valid[0]; START_CRC8_DEL <= start_CRC8; end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin byte_count_reg <= 0; end else begin byte_count_reg <= BYTE_COUNTER; end end //Use for determining the number of bytes in the data always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin final_byte_count <= 0; end else if (load_CRC8) begin if (BYTE_COUNTER == 64) begin final_byte_count <= 60; end else begin final_byte_count <= byte_count_reg; end end else if (start_CRC8) begin final_byte_count <= final_byte_count + 1; end end always @(posedge TX_CLK) begin if (transmit_pause_frame) begin byte_count_stat = 512; end else begin byte_count_stat = final_byte_count; end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin append_reg <= 0; load_final_CRC <= 0; append_end_frame <= 0; end else begin append_reg[0] <= load_CRC8; append_reg[9:1] <= append_reg[8:0]; load_final_CRC <= append_reg[9]; append_end_frame <= load_final_CRC; end end // //always @(posedge TX_CLK or posedge reset_int) //begin // if (reset_int) begin // vlan_enabled_int <= 0; // end //end // VLAN field - 8100 at second 64 bit data at 32:47 and V1 V2 is at 48:63 // length field at third 64 bit data at 0:15 always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin length_register <= 0; end else if (vlan_enabled_int & BYTE_COUNTER == 16) begin length_register <= TX_DATA_REG[15:0]; end else begin if (BYTE_COUNTER == 8) begin length_register <= TX_DATA_REG[47:32]; end end end always @(posedge TX_CLK or posedge reset_int) begin if (reset_int) begin set_pause_stats <= 0; end else if (PAUSEVAL_DEL2) begin set_pause_stats <= 1; end else if (append_end_frame) begin set_pause_stats <= 0; end end endmodule