// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
//
|
//
|
// Revision Control Information
|
// Revision Control Information
|
//
|
//
|
// $RCSfile: ethmon_32.v,v $
|
// $RCSfile: ethmon_32.v,v $
|
// $Source: /ipbu/cvs/sio/projects/TriSpeedEthernet/src/testbench/models/verilog/ethernet_model/mon/ethmon_32.v,v $
|
// $Source: /ipbu/cvs/sio/projects/TriSpeedEthernet/src/testbench/models/verilog/ethernet_model/mon/ethmon_32.v,v $
|
//
|
//
|
// $Revision: #1 $
|
// $Revision: #1 $
|
// $Date: 2011/11/10 $
|
// $Date: 2012/06/21 $
|
// Check in by : $Author: max $
|
// Check in by : $Author: swbranch $
|
// Author : SKNg/TTChong
|
// Author : SKNg/TTChong
|
//
|
//
|
// Project : Triple Speed Ethernet - 10/100/1000 MAC
|
// Project : Triple Speed Ethernet - 10/100/1000 MAC
|
//
|
//
|
// Description : (Simulation only)
|
// Description : (Simulation only)
|
//
|
//
|
// Ethernet Traffic Monitor/Decoder for 32 bit MAC Atlantic client interface
|
// Ethernet Traffic Monitor/Decoder for 32 bit MAC Atlantic client interface
|
// Instantiated in top_ethmonitor32 (top_ethmon32.v)
|
// Instantiated in top_ethmonitor32 (top_ethmon32.v)
|
//
|
//
|
//
|
//
|
// ALTERA Confidential and Proprietary
|
// ALTERA Confidential and Proprietary
|
// Copyright 2006 (c) Altera Corporation
|
// Copyright 2006 (c) Altera Corporation
|
// All rights reserved
|
// All rights reserved
|
//
|
//
|
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
|
|
`timescale 1 ns / 10 ps // timescale for following modules
|
`timescale 1 ns / 10 ps // timescale for following modules
|
|
|
|
|
module ethmonitor_32 (
|
module ethmonitor_32 (
|
|
|
reset,
|
reset,
|
tx_clk,
|
tx_clk,
|
txd,
|
txd,
|
tx_dv,
|
tx_dv,
|
tx_er,
|
tx_er,
|
dst,
|
dst,
|
src,
|
src,
|
prmble_len,
|
prmble_len,
|
pquant,
|
pquant,
|
vlan_ctl,
|
vlan_ctl,
|
len,
|
len,
|
frmtype,
|
frmtype,
|
payload,
|
payload,
|
payload_vld,
|
payload_vld,
|
is_vlan,
|
is_vlan,
|
is_stack_vlan,
|
is_stack_vlan,
|
is_pause,
|
is_pause,
|
crc_err,
|
crc_err,
|
prmbl_err,
|
prmbl_err,
|
len_err,
|
len_err,
|
payload_err,
|
payload_err,
|
frame_err,
|
frame_err,
|
pause_op_err,
|
pause_op_err,
|
pause_dst_err,
|
pause_dst_err,
|
mac_err,
|
mac_err,
|
end_err,
|
end_err,
|
jumbo_en,
|
jumbo_en,
|
data_only,
|
data_only,
|
frm_rcvd);
|
frm_rcvd);
|
|
|
parameter ENABLE_SHIFT16 = 1'b 0;
|
parameter ENABLE_SHIFT16 = 1'b 0;
|
|
|
input reset; // active high
|
input reset; // active high
|
input tx_clk;
|
input tx_clk;
|
input [7:0] txd;
|
input [7:0] txd;
|
input tx_dv;
|
input tx_dv;
|
input tx_er;
|
input tx_er;
|
output [47:0] dst; // destination address
|
output [47:0] dst; // destination address
|
output [47:0] src; // source address
|
output [47:0] src; // source address
|
output [13:0] prmble_len; // length of preamble
|
output [13:0] prmble_len; // length of preamble
|
output [15:0] pquant; // Pause Quanta value
|
output [15:0] pquant; // Pause Quanta value
|
output [15:0] vlan_ctl; // VLAN control info
|
output [15:0] vlan_ctl; // VLAN control info
|
output [15:0] len; // Length of payload
|
output [15:0] len; // Length of payload
|
output [15:0] frmtype; // if non-null: type field instead length
|
output [15:0] frmtype; // if non-null: type field instead length
|
output [7:0] payload;
|
output [7:0] payload;
|
output payload_vld;
|
output payload_vld;
|
output is_vlan;
|
output is_vlan;
|
output is_stack_vlan;
|
output is_stack_vlan;
|
output is_pause;
|
output is_pause;
|
output crc_err;
|
output crc_err;
|
output prmbl_err;
|
output prmbl_err;
|
output len_err;
|
output len_err;
|
output payload_err;
|
output payload_err;
|
output frame_err;
|
output frame_err;
|
output pause_op_err;
|
output pause_op_err;
|
output pause_dst_err;
|
output pause_dst_err;
|
output mac_err;
|
output mac_err;
|
output end_err;
|
output end_err;
|
input jumbo_en;
|
input jumbo_en;
|
input data_only;
|
input data_only;
|
output frm_rcvd;
|
output frm_rcvd;
|
// GMII transmit interface: To be connected to MAC TX
|
// GMII transmit interface: To be connected to MAC TX
|
wire [47:0] dst;
|
wire [47:0] dst;
|
reg [47:0] src;
|
reg [47:0] src;
|
wire [13:0] prmble_len;
|
wire [13:0] prmble_len;
|
reg [15:0] pquant;
|
reg [15:0] pquant;
|
reg [15:0] vlan_ctl;
|
reg [15:0] vlan_ctl;
|
wire [15:0] len;
|
wire [15:0] len;
|
wire [15:0] frmtype;
|
wire [15:0] frmtype;
|
reg [7:0] payload;
|
reg [7:0] payload;
|
// Indicators
|
// Indicators
|
reg payload_vld;
|
reg payload_vld;
|
wire is_vlan;
|
wire is_vlan;
|
wire is_stack_vlan;
|
wire is_stack_vlan;
|
wire is_pause;
|
wire is_pause;
|
reg crc_err;
|
reg crc_err;
|
reg prmbl_err;
|
reg prmbl_err;
|
reg len_err;
|
reg len_err;
|
reg payload_err;
|
reg payload_err;
|
reg frame_err;
|
reg frame_err;
|
reg pause_op_err;
|
reg pause_op_err;
|
reg pause_dst_err;
|
reg pause_dst_err;
|
reg mac_err;
|
reg mac_err;
|
// Control
|
// Control
|
reg end_err;
|
reg end_err;
|
reg frm_rcvd;
|
reg frm_rcvd;
|
reg [13:0] iprmble_len; // length of preamble
|
reg [13:0] iprmble_len; // length of preamble
|
reg [15:0] ifrmtype;
|
reg [15:0] ifrmtype;
|
reg [15:0] ilen;
|
reg [15:0] ilen;
|
reg [47:0] idst;
|
reg [47:0] idst;
|
reg iis_vlan;
|
reg iis_vlan;
|
reg iis_stack_vlan;
|
reg iis_stack_vlan;
|
reg iis_pause;
|
reg iis_pause;
|
// internal
|
// internal
|
|
|
// TYPE state_typ:
|
// TYPE state_typ:
|
parameter state_typ_s_idle = 0;
|
parameter state_typ_s_idle = 0;
|
parameter state_typ_s_prmbl = 1;
|
parameter state_typ_s_prmbl = 1;
|
parameter state_typ_s_dst = 2;
|
parameter state_typ_s_dst = 2;
|
parameter state_typ_s_src = 3;
|
parameter state_typ_s_src = 3;
|
parameter state_typ_s_typelen = 4;
|
parameter state_typ_s_typelen = 4;
|
parameter state_typ_s_pause = 5;
|
parameter state_typ_s_pause = 5;
|
parameter state_typ_s_tag = 6;
|
parameter state_typ_s_tag = 6;
|
parameter state_typ_s_len = 7;
|
parameter state_typ_s_len = 7;
|
parameter state_typ_s_data = 8;
|
parameter state_typ_s_data = 8;
|
parameter state_typ_s_pad = 9;
|
parameter state_typ_s_pad = 9;
|
parameter state_typ_s_crc = 10;
|
parameter state_typ_s_crc = 10;
|
parameter state_typ_s_abort = 11;
|
parameter state_typ_s_abort = 11;
|
parameter state_typ_s_utype = 12;
|
parameter state_typ_s_utype = 12;
|
parameter state_typ_s_Dword32Aligned = 13;
|
parameter state_typ_s_Dword32Aligned = 13;
|
|
|
|
|
reg [3:0] state;
|
reg [3:0] state;
|
reg [3:0] last_state;
|
reg [3:0] last_state;
|
reg last_tx_dv; // follows tx_dv with one cycle delay
|
reg last_tx_dv; // follows tx_dv with one cycle delay
|
reg [31:0] crc32;
|
reg [31:0] crc32;
|
reg [31:0] count;
|
reg [31:0] count;
|
reg [31:0] poscnt; // position in frame starts at first dst byte
|
reg [31:0] poscnt; // position in frame starts at first dst byte
|
reg [7:0] datacnt; // counter to verify payload
|
reg [7:0] datacnt; // counter to verify payload
|
reg [7:0] datainc; // counter increment
|
reg [7:0] datainc; // counter increment
|
wire tx_sof; // start of frame indicator for 1 clk cycle with 1st byte
|
wire tx_sof; // start of frame indicator for 1 clk cycle with 1st byte
|
reg tx_dst; // start of frame indicator for 1 clk cycle with 1st byte
|
reg tx_dst; // start of frame indicator for 1 clk cycle with 1st byte
|
// connect permanent port signals
|
// connect permanent port signals
|
// ------------------------------
|
// ------------------------------
|
reg [31:0] process_3_crctmp;
|
reg [31:0] process_3_crctmp;
|
reg [3:0] V2V_process_3_i;
|
reg [3:0] V2V_process_3_i;
|
integer process_8_ix;
|
integer process_8_ix;
|
integer process_9_ix;
|
integer process_9_ix;
|
reg process_9_ln;
|
reg process_9_ln;
|
integer process_12_ix;
|
integer process_12_ix;
|
integer process_10_ix;
|
integer process_10_ix;
|
integer process_11_hi;
|
integer process_11_hi;
|
integer process_11_lo;
|
integer process_11_lo;
|
reg [31:0] process_11_cnttmp;
|
reg [31:0] process_11_cnttmp;
|
integer process_11_i;
|
integer process_11_i;
|
integer process_11_flen;
|
integer process_11_flen;
|
|
|
assign prmble_len = iprmble_len;
|
assign prmble_len = iprmble_len;
|
assign frmtype = ifrmtype;
|
assign frmtype = ifrmtype;
|
assign len = ilen;
|
assign len = ilen;
|
assign dst = idst;
|
assign dst = idst;
|
assign is_vlan = iis_vlan;
|
assign is_vlan = iis_vlan;
|
assign is_stack_vlan = iis_stack_vlan;
|
assign is_stack_vlan = iis_stack_vlan;
|
assign is_pause = iis_pause;
|
assign is_pause = iis_pause;
|
// generate tx start pulse
|
// generate tx start pulse
|
// ----------------------
|
// ----------------------
|
assign tx_sof = ~last_tx_dv & tx_dv; // pulse with first byte 0 to 1 change
|
assign tx_sof = ~last_tx_dv & tx_dv; // pulse with first byte 0 to 1 change
|
// generate pulse start of destination address
|
// generate pulse start of destination address
|
// --------------------
|
// --------------------
|
always @(last_state or state)
|
always @(last_state or state)
|
begin : process_1
|
begin : process_1
|
if (last_state != state_typ_s_dst & state == state_typ_s_dst)
|
if (last_state != state_typ_s_dst & state == state_typ_s_dst)
|
begin
|
begin
|
tx_dst <= 1'b 1;
|
tx_dst <= 1'b 1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
tx_dst <= 1'b 0;
|
tx_dst <= 1'b 0;
|
end
|
end
|
end
|
end
|
// ------------------------------------------
|
// ------------------------------------------
|
// capture tx_er indicator
|
// capture tx_er indicator
|
// ------------------------------------------
|
// ------------------------------------------
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_2
|
begin : process_2
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
mac_err <= 1'b 0;
|
mac_err <= 1'b 0;
|
last_tx_dv <= 1'b 0;
|
last_tx_dv <= 1'b 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (tx_sof == 1'b 1)
|
if (tx_sof == 1'b 1)
|
begin
|
begin
|
mac_err <= 1'b 0; // reset indicator at start of new receive
|
mac_err <= 1'b 0; // reset indicator at start of new receive
|
end
|
end
|
else if (tx_er == 1'b 1 )
|
else if (tx_er == 1'b 1 )
|
begin
|
begin
|
mac_err <= 1'b 1; // capture one or many
|
mac_err <= 1'b 1; // capture one or many
|
end
|
end
|
last_tx_dv <= tx_dv;
|
last_tx_dv <= tx_dv;
|
end
|
end
|
end
|
end
|
// ----------------------------------------------
|
// ----------------------------------------------
|
// CRC calculation over all bytes except preamble
|
// CRC calculation over all bytes except preamble
|
// ----------------------------------------------
|
// ----------------------------------------------
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_3
|
begin : process_3
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
crc32 <= {32{1'b 1}};
|
crc32 <= {32{1'b 1}};
|
crc_err <= 1'b 0;
|
crc_err <= 1'b 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// need it ahead
|
// need it ahead
|
if (tx_dst == 1'b 1 | state != state_typ_s_idle &
|
if (tx_dst == 1'b 1 | state != state_typ_s_idle &
|
state != state_typ_s_prmbl & state != state_typ_s_utype |
|
state != state_typ_s_prmbl & state != state_typ_s_utype |
|
state == state_typ_s_utype & tx_dv == 1'b 1)
|
state == state_typ_s_utype & tx_dv == 1'b 1)
|
begin
|
begin
|
// push all inclusive CRC bytes
|
// push all inclusive CRC bytes
|
// preset CRC or load current value
|
// preset CRC or load current value
|
if (tx_dst == 1'b 1)
|
if (tx_dst == 1'b 1)
|
begin
|
begin
|
// first data, preset CRC
|
// first data, preset CRC
|
process_3_crctmp = {32{1'b 1}};
|
process_3_crctmp = {32{1'b 1}};
|
end
|
end
|
else
|
else
|
begin
|
begin
|
process_3_crctmp = crc32;
|
process_3_crctmp = crc32;
|
end
|
end
|
// calculate next step
|
// calculate next step
|
|
|
for (V2V_process_3_i = 0; V2V_process_3_i <= 7; V2V_process_3_i = V2V_process_3_i + 1)
|
for (V2V_process_3_i = 0; V2V_process_3_i <= 7; V2V_process_3_i = V2V_process_3_i + 1)
|
begin
|
begin
|
if ((txd[V2V_process_3_i] ^ process_3_crctmp[31]) == 1'b 1)
|
if ((txd[V2V_process_3_i] ^ process_3_crctmp[31]) == 1'b 1)
|
begin
|
begin
|
process_3_crctmp = (process_3_crctmp << 1); // shift in a 0, will be xor'ed to 1 by the polynom
|
process_3_crctmp = (process_3_crctmp << 1); // shift in a 0, will be xor'ed to 1 by the polynom
|
process_3_crctmp = process_3_crctmp ^ 32'h 04C11DB7;
|
process_3_crctmp = process_3_crctmp ^ 32'h 04C11DB7;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
process_3_crctmp = (process_3_crctmp << 1); // shift in a 0
|
process_3_crctmp = (process_3_crctmp << 1); // shift in a 0
|
end
|
end
|
end
|
end
|
// process all bits we have here
|
// process all bits we have here
|
crc32 <= process_3_crctmp; // remember current value
|
crc32 <= process_3_crctmp; // remember current value
|
// check if CRC is valid
|
// check if CRC is valid
|
if (process_3_crctmp == 32'h C704DD7B)
|
if (process_3_crctmp == 32'h C704DD7B)
|
begin
|
begin
|
crc_err <= 1'b 0;
|
crc_err <= 1'b 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
crc_err <= 1'b 1;
|
crc_err <= 1'b 1;
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
// ----------------------------------------------
|
// ----------------------------------------------
|
// Extract RX Payload on payload bus and check payload errors:
|
// Extract RX Payload on payload bus and check payload errors:
|
// * first byte is counter initialization
|
// * first byte is counter initialization
|
// * second byte is counter increment
|
// * second byte is counter increment
|
// * data begins from 3rd byte on
|
// * data begins from 3rd byte on
|
// ----------------------------------------------
|
// ----------------------------------------------
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_4
|
begin : process_4
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
payload <= {8{1'b 0}};
|
payload <= {8{1'b 0}};
|
payload_vld <= 1'b 0;
|
payload_vld <= 1'b 0;
|
payload_err <= 1'b 0;
|
payload_err <= 1'b 0;
|
datacnt <= 0;
|
datacnt <= 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (state == state_typ_s_typelen)
|
if (state == state_typ_s_typelen)
|
begin
|
begin
|
payload_err <= 1'b 0; // reset as a frame of length 0 will not get into S_DATA.
|
payload_err <= 1'b 0; // reset as a frame of length 0 will not get into S_DATA.
|
end
|
end
|
if (state == state_typ_s_data)
|
if (state == state_typ_s_data)
|
begin
|
begin
|
payload <= txd;
|
payload <= txd;
|
payload_vld <= 1'b 1;
|
payload_vld <= 1'b 1;
|
if (count == 0)
|
if (count == 0)
|
begin
|
begin
|
datacnt <= ({1'b 0, txd}); // load counter
|
datacnt <= ({1'b 0, txd}); // load counter
|
payload_err <= 1'b 0;
|
payload_err <= 1'b 0;
|
end
|
end
|
else if (count == 1 )
|
else if (count == 1 )
|
begin
|
begin
|
datainc <= ({1'b 0, txd}); // load increment
|
datainc <= ({1'b 0, txd}); // load increment
|
// verify payload contents
|
// verify payload contents
|
end
|
end
|
else
|
else
|
begin
|
begin
|
datacnt <= (datacnt + datainc) % 256;
|
datacnt <= (datacnt + datainc) % 256;
|
if (datacnt != ({1'b 0, txd}))
|
if (datacnt != ({1'b 0, txd}))
|
begin
|
begin
|
payload_err <= 1'b 1;
|
payload_err <= 1'b 1;
|
end
|
end
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
payload <= {8{1'b 0}};
|
payload <= {8{1'b 0}};
|
payload_vld <= 1'b 0;
|
payload_vld <= 1'b 0;
|
end
|
end
|
end
|
end
|
end
|
end
|
// ----------------------------------------------
|
// ----------------------------------------------
|
// Position Counter: Starts with first octet of destination address
|
// Position Counter: Starts with first octet of destination address
|
// ----------------------------------------------
|
// ----------------------------------------------
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_5
|
begin : process_5
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
poscnt <= 0;
|
poscnt <= 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (tx_dst == 1'b 1)
|
if (tx_dst == 1'b 1)
|
begin
|
begin
|
// reset at start of DST
|
// reset at start of DST
|
poscnt <= 1;
|
poscnt <= 1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (poscnt < 65535)
|
if (poscnt < 65535)
|
begin
|
begin
|
poscnt <= poscnt + 1'b 1;
|
poscnt <= poscnt + 1'b 1;
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
// ----------------------------------------------
|
// ----------------------------------------------
|
// End of Frame:
|
// End of Frame:
|
// change from non-idle to idle indicates something was received
|
// change from non-idle to idle indicates something was received
|
// if dv is still asserted this is an end error
|
// if dv is still asserted this is an end error
|
// ----------------------------------------------
|
// ----------------------------------------------
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_6
|
begin : process_6
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
frm_rcvd <= 1'b 0;
|
frm_rcvd <= 1'b 0;
|
end_err <= 1'b 0;
|
end_err <= 1'b 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (last_state != state_typ_s_idle & state == state_typ_s_idle)
|
if (last_state != state_typ_s_idle & state == state_typ_s_idle)
|
begin
|
begin
|
frm_rcvd <= 1'b 1;
|
frm_rcvd <= 1'b 1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
frm_rcvd <= 1'b 0;
|
frm_rcvd <= 1'b 0;
|
end
|
end
|
if (tx_sof == 1'b 1)
|
if (tx_sof == 1'b 1)
|
begin
|
begin
|
end_err <= 1'b 0;
|
end_err <= 1'b 0;
|
end
|
end
|
else if (last_state != state_typ_s_idle & state == state_typ_s_idle &
|
else if (last_state != state_typ_s_idle & state == state_typ_s_idle &
|
tx_dv == 1'b 1 )
|
tx_dv == 1'b 1 )
|
begin
|
begin
|
end_err <= 1'b 1; // dv still asserted even after nothing more expected
|
end_err <= 1'b 1; // dv still asserted even after nothing more expected
|
end
|
end
|
end
|
end
|
end
|
end
|
// ----------------------------------------------
|
// ----------------------------------------------
|
// Preamble check
|
// Preamble check
|
// ----------------------------------------------
|
// ----------------------------------------------
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_7
|
begin : process_7
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
prmbl_err <= 1'b 0;
|
prmbl_err <= 1'b 0;
|
iprmble_len <= 0;
|
iprmble_len <= 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (tx_sof == 1'b 1)
|
if (tx_sof == 1'b 1)
|
begin
|
begin
|
if (txd != 8'h 55)
|
if (txd != 8'h 55)
|
begin
|
begin
|
prmbl_err <= 1'b 1;
|
prmbl_err <= 1'b 1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
prmbl_err <= 1'b 0; // reset usually
|
prmbl_err <= 1'b 0; // reset usually
|
end
|
end
|
if (data_only == 1'b 1)
|
if (data_only == 1'b 1)
|
begin
|
begin
|
iprmble_len <= 0;
|
iprmble_len <= 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
iprmble_len <= 1;
|
iprmble_len <= 1;
|
end
|
end
|
end
|
end
|
else if (state == state_typ_s_prmbl )
|
else if (state == state_typ_s_prmbl )
|
begin
|
begin
|
if (txd != 8'h 55 & txd != 8'h D5)
|
if (txd != 8'h 55 & txd != 8'h D5)
|
begin
|
begin
|
prmbl_err <= 1'b 1;
|
prmbl_err <= 1'b 1;
|
end
|
end
|
iprmble_len <= iprmble_len + 1'b 1;
|
iprmble_len <= iprmble_len + 1'b 1;
|
end
|
end
|
end
|
end
|
end
|
end
|
// ----------------------------------------------
|
// ----------------------------------------------
|
// Extract Source and Destination addresses
|
// Extract Source and Destination addresses
|
// ----------------------------------------------
|
// ----------------------------------------------
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_8
|
begin : process_8
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
idst <= {48{1'b 0}};
|
idst <= {48{1'b 0}};
|
src <= {48{1'b 0}};
|
src <= {48{1'b 0}};
|
end
|
end
|
else
|
else
|
begin
|
begin
|
process_8_ix = count * 8;
|
process_8_ix = count * 8;
|
|
|
if (tx_sof == 1'b 1 & data_only == 1'b 1 & state == state_typ_s_Dword32Aligned & ENABLE_SHIFT16 == 1'b1)
|
if (tx_sof == 1'b 1 & data_only == 1'b 1 & state == state_typ_s_Dword32Aligned & ENABLE_SHIFT16 == 1'b1)
|
begin
|
begin
|
case (count)
|
case (count)
|
1'b 0 : ;
|
1'b 0 : ;
|
1'b 1 : ;
|
1'b 1 : ;
|
default:;
|
default:;
|
endcase
|
endcase
|
end
|
end
|
if (tx_sof == 1'b 0 & data_only == 1'b 1 & ENABLE_SHIFT16 == 1'b1 & state == state_typ_s_dst)
|
if (tx_sof == 1'b 0 & data_only == 1'b 1 & ENABLE_SHIFT16 == 1'b1 & state == state_typ_s_dst)
|
begin
|
begin
|
case (count)
|
case (count)
|
1'b 0:
|
1'b 0:
|
begin
|
begin
|
idst[7:0] <= txd[7:0];
|
idst[7:0] <= txd[7:0];
|
end
|
end
|
1'b 1:
|
1'b 1:
|
begin
|
begin
|
idst[15:8] <= txd[7:0];
|
idst[15:8] <= txd[7:0];
|
end
|
end
|
2'b 10:
|
2'b 10:
|
begin
|
begin
|
idst[23:16] <= txd[7:0];
|
idst[23:16] <= txd[7:0];
|
end
|
end
|
2'b 11:
|
2'b 11:
|
begin
|
begin
|
idst[31:24] <= txd[7:0];
|
idst[31:24] <= txd[7:0];
|
end
|
end
|
3'b 100:
|
3'b 100:
|
begin
|
begin
|
idst[39:32] <= txd[7:0];
|
idst[39:32] <= txd[7:0];
|
end
|
end
|
3'b 101:
|
3'b 101:
|
begin
|
begin
|
idst[47:40] <= txd[7:0];
|
idst[47:40] <= txd[7:0];
|
end
|
end
|
default:
|
default:
|
;
|
;
|
endcase end
|
endcase end
|
|
|
|
|
if (tx_sof == 1'b 1 & data_only == 1'b 1 & ENABLE_SHIFT16 == 1'b0 | state == state_typ_s_dst)
|
if (tx_sof == 1'b 1 & data_only == 1'b 1 & ENABLE_SHIFT16 == 1'b0 | state == state_typ_s_dst)
|
begin
|
begin
|
case (count)
|
case (count)
|
1'b 0:
|
1'b 0:
|
begin
|
begin
|
idst[7:0] <= txd[7:0];
|
idst[7:0] <= txd[7:0];
|
end
|
end
|
1'b 1:
|
1'b 1:
|
begin
|
begin
|
idst[15:8] <= txd[7:0];
|
idst[15:8] <= txd[7:0];
|
end
|
end
|
2'b 10:
|
2'b 10:
|
begin
|
begin
|
idst[23:16] <= txd[7:0];
|
idst[23:16] <= txd[7:0];
|
end
|
end
|
2'b 11:
|
2'b 11:
|
begin
|
begin
|
idst[31:24] <= txd[7:0];
|
idst[31:24] <= txd[7:0];
|
end
|
end
|
3'b 100:
|
3'b 100:
|
begin
|
begin
|
idst[39:32] <= txd[7:0];
|
idst[39:32] <= txd[7:0];
|
end
|
end
|
3'b 101:
|
3'b 101:
|
begin
|
begin
|
idst[47:40] <= txd[7:0];
|
idst[47:40] <= txd[7:0];
|
end
|
end
|
default:
|
default:
|
;
|
;
|
endcase end
|
endcase end
|
if (state == state_typ_s_src)
|
if (state == state_typ_s_src)
|
begin
|
begin
|
case (count)
|
case (count)
|
1'b 0:
|
1'b 0:
|
begin
|
begin
|
src[7:0] <= txd[7:0];
|
src[7:0] <= txd[7:0];
|
end
|
end
|
1'b 1:
|
1'b 1:
|
begin
|
begin
|
src[15:8] <= txd[7:0];
|
src[15:8] <= txd[7:0];
|
end
|
end
|
2'b 10:
|
2'b 10:
|
begin
|
begin
|
src[23:16] <= txd[7:0];
|
src[23:16] <= txd[7:0];
|
end
|
end
|
2'b 11:
|
2'b 11:
|
begin
|
begin
|
src[31:24] <= txd[7:0];
|
src[31:24] <= txd[7:0];
|
end
|
end
|
3'b 100:
|
3'b 100:
|
begin
|
begin
|
src[39:32] <= txd[7:0];
|
src[39:32] <= txd[7:0];
|
end
|
end
|
3'b 101:
|
3'b 101:
|
begin
|
begin
|
src[47:40] <= txd[7:0];
|
src[47:40] <= txd[7:0];
|
end
|
end
|
default:
|
default:
|
;
|
;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
// ----------------------------------------------
|
// ----------------------------------------------
|
// Extract Length/Type field and VLAN Tag identifier
|
// Extract Length/Type field and VLAN Tag identifier
|
// ----------------------------------------------
|
// ----------------------------------------------
|
|
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_12
|
begin : process_12
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
ilen <= {16{1'b 0}};
|
ilen <= {16{1'b 0}};
|
ifrmtype <= {16{1'b 0}};
|
ifrmtype <= {16{1'b 0}};
|
vlan_ctl <= {16{1'b 0}};
|
vlan_ctl <= {16{1'b 0}};
|
iis_vlan <= 1'b 0;
|
iis_vlan <= 1'b 0;
|
len_err <= 1'b 0;
|
len_err <= 1'b 0;
|
iis_stack_vlan <= 1'b0;
|
iis_stack_vlan <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
process_12_ix = 4'b 1000 - count * 8;
|
process_12_ix = 4'b 1000 - count * 8;
|
// if( tx_sof_d = '1' ) then -- clear all on start of every frame
|
// if( tx_sof_d = '1' ) then -- clear all on start of every frame
|
//
|
//
|
// ilen <= (others => '0');
|
// ilen <= (others => '0');
|
// ifrmtype <= (others => '0');
|
// ifrmtype <= (others => '0');
|
// vlan_ctl <= (others => '0');
|
// vlan_ctl <= (others => '0');
|
// iis_vlan <= '0';
|
// iis_vlan <= '0';
|
//
|
//
|
// end if;
|
// end if;
|
if (state == state_typ_s_typelen)
|
if (state == state_typ_s_typelen)
|
begin
|
begin
|
// if in type/len set both
|
// if in type/len set both
|
case (count)
|
case (count)
|
1'b 0:
|
1'b 0:
|
begin
|
begin
|
ifrmtype[15:8] <= txd;
|
ifrmtype[15:8] <= txd;
|
ilen[15:8] <= txd;
|
ilen[15:8] <= txd;
|
end
|
end
|
1'b 1:
|
1'b 1:
|
begin
|
begin
|
ifrmtype[7:0] <= txd;
|
ifrmtype[7:0] <= txd;
|
ilen[7:0] <= txd;
|
ilen[7:0] <= txd;
|
end
|
end
|
default:
|
default:
|
;
|
;
|
endcase
|
endcase
|
vlan_ctl <= {16{1'b 0}}; // clear at start of new frame (at SOF it is too early)
|
vlan_ctl <= {16{1'b 0}}; // clear at start of new frame (at SOF it is too early)
|
iis_vlan <= 1'b 0;
|
iis_vlan <= 1'b 0;
|
len_err <= 1'b 0;
|
len_err <= 1'b 0;
|
end
|
end
|
|
|
if(state==state_typ_s_typelen)
|
if(state==state_typ_s_typelen)
|
begin
|
begin
|
|
|
iis_stack_vlan <= 1'b0 ;
|
iis_stack_vlan <= 1'b0 ;
|
|
|
end
|
end
|
else if (last_state == state_typ_s_len & state == state_typ_s_tag)
|
else if (last_state == state_typ_s_len & state == state_typ_s_tag)
|
begin
|
begin
|
|
|
iis_stack_vlan <= 1'b1 ;
|
iis_stack_vlan <= 1'b1 ;
|
|
|
end
|
end
|
|
|
else if (state == state_typ_s_len )
|
else if (state == state_typ_s_len )
|
begin
|
begin
|
// in len again, set len independently
|
// in len again, set len independently
|
case (count)
|
case (count)
|
1'b 0:
|
1'b 0:
|
begin
|
begin
|
ifrmtype[15:8] <= txd;
|
ifrmtype[15:8] <= txd;
|
ilen[15:8] <= txd;
|
ilen[15:8] <= txd;
|
end
|
end
|
1'b 1:
|
1'b 1:
|
begin
|
begin
|
ifrmtype[7:0] <= txd;
|
ifrmtype[7:0] <= txd;
|
ilen[7:0] <= txd;
|
ilen[7:0] <= txd;
|
end
|
end
|
default:
|
default:
|
;
|
;
|
endcase
|
endcase
|
end
|
end
|
else if (state == state_typ_s_tag )
|
else if (state == state_typ_s_tag )
|
begin
|
begin
|
iis_vlan <= 1'b 1;
|
iis_vlan <= 1'b 1;
|
case (count)
|
case (count)
|
1'b 0:
|
1'b 0:
|
begin
|
begin
|
vlan_ctl[15:8] <= txd; // ilen(ix+7 downto ix) <= txd;
|
vlan_ctl[15:8] <= txd; // ilen(ix+7 downto ix) <= txd;
|
end
|
end
|
1'b 1:
|
1'b 1:
|
begin
|
begin
|
vlan_ctl[7:0] <= txd;
|
vlan_ctl[7:0] <= txd;
|
end
|
end
|
default:
|
default:
|
;
|
;
|
endcase end
|
endcase end
|
// verify length at end of frame for normal frames (length 46... max and not a type)
|
// verify length at end of frame for normal frames (length 46... max and not a type)
|
if (last_state == state_typ_s_crc & state == state_typ_s_idle &
|
if (last_state == state_typ_s_crc & state == state_typ_s_idle &
|
iis_pause == 1'b 0 & (iis_vlan == 1'b 0 &
|
iis_pause == 1'b 0 & (iis_vlan == 1'b 0 &
|
ilen > 45 | iis_vlan == 1'b 1 &
|
ilen > 45 | iis_vlan == 1'b 1 &
|
ilen > 41))
|
ilen > 41))
|
begin
|
begin
|
// verify integrity of length field
|
// verify integrity of length field
|
if (tx_dv == 1'b 1 |
|
if (tx_dv == 1'b 1 |
|
iis_stack_vlan == 1'b 1 & ilen != poscnt - 5'b 11010 |
|
iis_stack_vlan == 1'b 1 & ilen != poscnt - 5'b 11010 |
|
(iis_vlan == 1'b 1 & iis_stack_vlan == 1'b 0) & ilen != poscnt - 5'b 10110 |
|
(iis_vlan == 1'b 1 & iis_stack_vlan == 1'b 0) & ilen != poscnt - 5'b 10110 |
|
iis_vlan == 1'b 0 & ilen != poscnt - 5'b 10010)
|
iis_vlan == 1'b 0 & ilen != poscnt - 5'b 10010)
|
begin
|
begin
|
len_err <= 1'b 1;
|
len_err <= 1'b 1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
len_err <= 1'b 0;
|
len_err <= 1'b 0;
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
// ----------------------------------------------
|
// ----------------------------------------------
|
// Extract Pause frame indication,
|
// Extract Pause frame indication,
|
// opcode error,
|
// opcode error,
|
// destination address error,
|
// destination address error,
|
// and Pause Quanta
|
// and Pause Quanta
|
// ----------------------------------------------
|
// ----------------------------------------------
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_13
|
begin : process_13
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
pquant <= {16{1'b 0}};
|
pquant <= {16{1'b 0}};
|
iis_pause <= 1'b 0;
|
iis_pause <= 1'b 0;
|
pause_op_err <= 1'b 0;
|
pause_op_err <= 1'b 0;
|
pause_dst_err <= 1'b 0;
|
pause_dst_err <= 1'b 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (tx_sof == 1'b 1)
|
if (tx_sof == 1'b 1)
|
begin
|
begin
|
iis_pause <= 1'b 0; // clear at start of frame
|
iis_pause <= 1'b 0; // clear at start of frame
|
pause_op_err <= 1'b 0;
|
pause_op_err <= 1'b 0;
|
pause_dst_err <= 1'b 0;
|
pause_dst_err <= 1'b 0;
|
end
|
end
|
if (state == state_typ_s_pause)
|
if (state == state_typ_s_pause)
|
begin
|
begin
|
iis_pause <= 1'b 1;
|
iis_pause <= 1'b 1;
|
//if (count >= 2)
|
//if (count >= 2)
|
//begin
|
//begin
|
// pick octets after opcode
|
// pick octets after opcode
|
case (count)
|
case (count)
|
2'b 11:
|
2'b 11:
|
begin
|
begin
|
pquant[15:8] <= txd;
|
pquant[15:8] <= txd;
|
end
|
end
|
1'b 0:
|
1'b 0:
|
begin
|
begin
|
pquant[7:0] <= txd;
|
pquant[7:0] <= txd;
|
end
|
end
|
default:
|
default:
|
;
|
;
|
endcase
|
endcase
|
//end
|
//end
|
if (count == 0 & txd != 8'h 00 |
|
if (count == 0 & txd != 8'h 00 |
|
count == 1 & txd != 8'h 01 )
|
count == 1 & txd != 8'h 01 )
|
begin
|
begin
|
pause_op_err <= 1'b 1;
|
pause_op_err <= 1'b 1;
|
end
|
end
|
if (idst != 48'h 010000c28001)
|
if (idst != 48'h 010000c28001)
|
begin
|
begin
|
// 01-80-c2-00-00-01 is standard !
|
// 01-80-c2-00-00-01 is standard !
|
pause_dst_err <= 1'b 1;
|
pause_dst_err <= 1'b 1;
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
// ----------------------------------------------
|
// ----------------------------------------------
|
// Monitor State Machine
|
// Monitor State Machine
|
// ----------------------------------------------
|
// ----------------------------------------------
|
always @(posedge tx_clk or posedge reset)
|
always @(posedge tx_clk or posedge reset)
|
begin : process_11
|
begin : process_11
|
if (reset == 1'b 1)
|
if (reset == 1'b 1)
|
begin
|
begin
|
state <= state_typ_s_idle;
|
state <= state_typ_s_idle;
|
last_state <= state_typ_s_idle;
|
last_state <= state_typ_s_idle;
|
count <= 0;
|
count <= 0;
|
frame_err <= 1'b 0; // state machine abort indicator
|
frame_err <= 1'b 0; // state machine abort indicator
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// remember last state and increment internal counter
|
// remember last state and increment internal counter
|
last_state <= state;
|
last_state <= state;
|
if (count < 65535)
|
if (count < 65535)
|
begin
|
begin
|
process_11_cnttmp = count + 1'b 1;
|
process_11_cnttmp = count + 1'b 1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
process_11_cnttmp = count;
|
process_11_cnttmp = count;
|
end
|
end
|
// Abort detection: If enable goes low in middle of frame
|
// Abort detection: If enable goes low in middle of frame
|
if (state != state_typ_s_idle & state != state_typ_s_abort &
|
if (state != state_typ_s_idle & state != state_typ_s_abort &
|
state != state_typ_s_utype & tx_dv == 1'b 0)
|
state != state_typ_s_utype & tx_dv == 1'b 0)
|
begin
|
begin
|
state <= state_typ_s_abort;
|
state <= state_typ_s_abort;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
case (state)
|
case (state)
|
state_typ_s_abort:
|
state_typ_s_abort:
|
begin
|
begin
|
if (tx_dv == 1'b 1)
|
if (tx_dv == 1'b 1)
|
begin
|
begin
|
if (last_tx_dv == 1'b 0 & data_only == 1'b 1)
|
if (last_tx_dv == 1'b 0 & data_only == 1'b 1)
|
begin
|
begin
|
// only 1 clock cycle inbetween
|
// only 1 clock cycle inbetween
|
if (ENABLE_SHIFT16 == 1'b0)
|
if (ENABLE_SHIFT16 == 1'b0)
|
state <= state_typ_s_dst;
|
state <= state_typ_s_dst;
|
else
|
else
|
state <= state_typ_s_Dword32Aligned;
|
state <= state_typ_s_Dword32Aligned;
|
|
|
process_11_cnttmp = 1'b 1;
|
process_11_cnttmp = 1'b 1;
|
frame_err <= 1'b 0;
|
frame_err <= 1'b 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
state <= state_typ_s_abort; // wait til tx stops transmission
|
state <= state_typ_s_abort; // wait til tx stops transmission
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
state <= state_typ_s_idle;
|
state <= state_typ_s_idle;
|
end
|
end
|
frame_err <= 1'b 1;
|
frame_err <= 1'b 1;
|
end
|
end
|
state_typ_s_idle:
|
state_typ_s_idle:
|
begin
|
begin
|
if (tx_sof == 1'b 1)
|
if (tx_sof == 1'b 1)
|
begin
|
begin
|
// we miss the very first !
|
// we miss the very first !
|
process_11_cnttmp = 1'b 1; // therefore need to count to 1 immediately
|
process_11_cnttmp = 1'b 1; // therefore need to count to 1 immediately
|
frame_err <= 1'b 0;
|
frame_err <= 1'b 0;
|
if (data_only == 1'b 1)
|
if (data_only == 1'b 1)
|
begin
|
begin
|
// no preamble checking ?
|
// no preamble checking ?
|
if (ENABLE_SHIFT16 == 1'b0)
|
if (ENABLE_SHIFT16 == 1'b0)
|
state <= state_typ_s_dst;
|
state <= state_typ_s_dst;
|
else
|
else
|
state <= state_typ_s_Dword32Aligned;
|
state <= state_typ_s_Dword32Aligned;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
state <= state_typ_s_prmbl;
|
state <= state_typ_s_prmbl;
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
process_11_cnttmp = 1'b 0; // keep it to zero always
|
process_11_cnttmp = 1'b 0; // keep it to zero always
|
end
|
end
|
end
|
end
|
state_typ_s_prmbl:
|
state_typ_s_prmbl:
|
begin
|
begin
|
if (txd == 8'h D5)
|
if (txd == 8'h D5)
|
begin
|
begin
|
state <= state_typ_s_dst;
|
state <= state_typ_s_dst;
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
end
|
end
|
end
|
end
|
|
|
state_typ_s_Dword32Aligned:
|
state_typ_s_Dword32Aligned:
|
begin
|
begin
|
if (count == 1)
|
if (count == 1)
|
begin
|
begin
|
state <= state_typ_s_dst;
|
state <= state_typ_s_dst;
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
end
|
end
|
end
|
end
|
|
|
state_typ_s_dst:
|
state_typ_s_dst:
|
begin
|
begin
|
if (count == 5)
|
if (count == 5)
|
begin
|
begin
|
state <= state_typ_s_src;
|
state <= state_typ_s_src;
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
end
|
end
|
end
|
end
|
state_typ_s_src:
|
state_typ_s_src:
|
begin
|
begin
|
if (count == 5)
|
if (count == 5)
|
begin
|
begin
|
state <= state_typ_s_typelen;
|
state <= state_typ_s_typelen;
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
end
|
end
|
end
|
end
|
state_typ_s_typelen:
|
state_typ_s_typelen:
|
begin
|
begin
|
if (count != 0)
|
if (count != 0)
|
begin
|
begin
|
// second half of 2-octet field
|
// second half of 2-octet field
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
process_11_flen = ({1'b 0, ilen[15:8], txd}); // need it NOW
|
process_11_flen = ({1'b 0, ilen[15:8], txd}); // need it NOW
|
if (jumbo_en == 1'b 1 & process_11_flen <= 9000 |
|
if (jumbo_en == 1'b 1 & process_11_flen <= 9000 |
|
process_11_flen <= 1500)
|
process_11_flen <= 1500)
|
begin
|
begin
|
// ok normal user frame. check if data or 0 length
|
// ok normal user frame. check if data or 0 length
|
if (process_11_flen != 0)
|
if (process_11_flen != 0)
|
begin
|
begin
|
state <= state_typ_s_data;
|
state <= state_typ_s_data;
|
// no data, PAD or finished
|
// no data, PAD or finished
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (data_only == 1'b 1)
|
if (data_only == 1'b 1)
|
begin
|
begin
|
state <= state_typ_s_idle; // Ok, we are done dont expect anything more
|
state <= state_typ_s_idle; // Ok, we are done dont expect anything more
|
end
|
end
|
else
|
else
|
begin
|
begin
|
state <= state_typ_s_pad; // zero-length frame needs padding
|
state <= state_typ_s_pad; // zero-length frame needs padding
|
end
|
end
|
end
|
end
|
// not normal frame
|
// not normal frame
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (process_11_flen == 16'h 8808)
|
if (process_11_flen == 16'h 8808)
|
begin
|
begin
|
state <= state_typ_s_pause;
|
state <= state_typ_s_pause;
|
end
|
end
|
else if (process_11_flen == 16'h 8100 )
|
else if (process_11_flen == 16'h 8100 )
|
begin
|
begin
|
state <= state_typ_s_tag;
|
state <= state_typ_s_tag;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
state <= state_typ_s_utype; // S_ABORT; -- unknown type
|
state <= state_typ_s_utype; // S_ABORT; -- unknown type
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
state_typ_s_pause:
|
state_typ_s_pause:
|
begin
|
begin
|
if (count >= 3)
|
if (count >= 3)
|
begin
|
begin
|
// need to overread opcode
|
// need to overread opcode
|
state <= state_typ_s_pad;
|
state <= state_typ_s_pad;
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
end
|
end
|
end
|
end
|
state_typ_s_tag:
|
state_typ_s_tag:
|
begin
|
begin
|
if (count >= 1)
|
if (count >= 1)
|
begin
|
begin
|
state <= state_typ_s_len;
|
state <= state_typ_s_len;
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
end
|
end
|
end
|
end
|
state_typ_s_len:
|
state_typ_s_len:
|
begin
|
begin
|
if (count >= 1)
|
if (count >= 1)
|
begin
|
begin
|
// Length after VLAN TAG
|
// Length after VLAN TAG
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
process_11_flen = ({1'b 0, ilen[15:8], txd}); // need it NOW
|
process_11_flen = ({1'b 0, ilen[15:8], txd}); // need it NOW
|
|
|
if ( process_11_flen == 16'h8100)
|
if ( process_11_flen == 16'h8100)
|
begin
|
begin
|
|
|
state <= state_typ_s_tag;
|
state <= state_typ_s_tag;
|
|
|
end
|
end
|
else if (process_11_flen != 0 & (jumbo_en == 1'b 1 &
|
else if (process_11_flen != 0 & (jumbo_en == 1'b 1 &
|
process_11_flen > 9000 | jumbo_en == 1'b 0 &
|
process_11_flen > 9000 | jumbo_en == 1'b 0 &
|
process_11_flen > 1500))
|
process_11_flen > 1500))
|
begin
|
begin
|
state <= state_typ_s_utype;
|
state <= state_typ_s_utype;
|
end
|
end
|
else if (process_11_flen != 0 )
|
else if (process_11_flen != 0 )
|
begin
|
begin
|
state <= state_typ_s_data;
|
state <= state_typ_s_data;
|
// no data, PAD or finished
|
// no data, PAD or finished
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (data_only == 1'b 1)
|
if (data_only == 1'b 1)
|
begin
|
begin
|
state <= state_typ_s_idle; // Ok, we are done dont expect CRC
|
state <= state_typ_s_idle; // Ok, we are done dont expect CRC
|
end
|
end
|
else
|
else
|
begin
|
begin
|
state <= state_typ_s_pad;
|
state <= state_typ_s_pad;
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
state_typ_s_data:
|
state_typ_s_data:
|
begin
|
begin
|
if (count >= ilen - 1'b 1)
|
if (count >= ilen - 1'b 1)
|
begin
|
begin
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
if (data_only == 1'b 1)
|
if (data_only == 1'b 1)
|
begin
|
begin
|
// no PAD and no CRC ?
|
// no PAD and no CRC ?
|
state <= state_typ_s_idle;
|
state <= state_typ_s_idle;
|
end
|
end
|
else if (poscnt < 6'b 111100 - 1'b 1 )
|
else if (poscnt < 6'b 111100 - 1'b 1 )
|
begin
|
begin
|
// expect padding ?
|
// expect padding ?
|
state <= state_typ_s_pad;
|
state <= state_typ_s_pad;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
state <= state_typ_s_crc;
|
state <= state_typ_s_crc;
|
end
|
end
|
end
|
end
|
end
|
end
|
state_typ_s_pad:
|
state_typ_s_pad:
|
begin
|
begin
|
if (poscnt >= 6'b 111100 - 1'b 1)
|
if (poscnt >= 6'b 111100 - 1'b 1)
|
begin
|
begin
|
state <= state_typ_s_crc;
|
state <= state_typ_s_crc;
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
end
|
end
|
end
|
end
|
state_typ_s_crc:
|
state_typ_s_crc:
|
begin
|
begin
|
if (count >= 3)
|
if (count >= 3)
|
begin
|
begin
|
state <= state_typ_s_idle;
|
state <= state_typ_s_idle;
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
end
|
end
|
end
|
end
|
state_typ_s_utype:
|
state_typ_s_utype:
|
begin
|
begin
|
if (tx_dv == 1'b 0)
|
if (tx_dv == 1'b 0)
|
begin
|
begin
|
// unknown type... wait for end of frame
|
// unknown type... wait for end of frame
|
state <= state_typ_s_idle;
|
state <= state_typ_s_idle;
|
process_11_cnttmp = 1'b 0;
|
process_11_cnttmp = 1'b 0;
|
end
|
end
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
// abort
|
// abort
|
// load the counter with the new value
|
// load the counter with the new value
|
count <= process_11_cnttmp;
|
count <= process_11_cnttmp;
|
end
|
end
|
end
|
end
|
|
|
// port signals internally reused
|
// port signals internally reused
|
|
|
endmodule // module ethmonitor_32
|
endmodule // module ethmonitor_32
|
|
|
|
|