// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: niu_ipp_load.v
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// ========== Copyright Header End ============================================
/**********************************************************
***********************************************************
File name : niu_ipp_load.v
Module(s) name : niu_ipp_load
Original: : ipp_load.v main.45, label: IPP_VERIF_1.84
Parent modules : niu_ipp.v
Child modules : niu_ipp_lib.v
Author's name : Jonathan Shen, George Chu
Description : This module loads the 64 bit double word data from
MAC/XMAC into ipp fifo. The data will be packed from
64-bit bus to 128-bit bus before loading in IPP Header fifo.
The protocol between IPP, XMAC and IPP, big MAC are
FFLP reads the header part.
************************************************************
***********************************************************/
mac_ipp_req, xmac_ipp_ack,
mac_ipp_data, mac_ipp_tag,
mac_ipp_ctrl, mac_ipp_stat,
// input from ffl_arbiter
ippfifo_rd_wr_ptr_bypass,
ippfifo_wr_ptr_pio_wr_en,
fifo_wr_data_reg_wr_en_pls,
ipp_mac_ack, ipp_xmac_req,
ipp_hfifo_rden, ipp_hfifo_rptr,
// end of output to ipp post
ipp_hfifo_over_run_r, ipp_hfifo_under_run_r,
phase_state_xmac, phase_state,
phase_state_1st_data, mac_ack_fsm_curstate,
cur_pkt_hdr_base_ptr, cur_pkt_ffl_sum_info
input [63:0] mac_ipp_data;
input [22:0] mac_ipp_stat;
input ffl_ipp_ready; // from ffl_top module
input ffl_ipp_dvalid; // from ffl_top module
input [13:0] fflp_ipp_sum; // from ffl_top module
input ffl_arb_ack; // from ffl_arb module
input ippfifo_rd_wr_ptr_bypass; // from slave
input ippfifo_wr_ptr_pio_wr_en; // from slave
input eop_from_hdr_fifo; // from ipp
input [13:0] pio_wr_data;
input [129:0] fifo_wr_data_reg;
input fifo_wr_data_reg_wr_en_pls;
input inc_hfifo_dat_rptr;
input [6:0] ipp_hfifo_dat_rptr;
output ipp_xmac_req; // if fifo not full, always high (xmac)
output ipp_ffl_req; // to ffl_arb module
output ipp_ffl_dvalid; // valid data from ipp to ffl
output ipp_ffl_dvalid_n; // valid data from ipp to ffl for par
output [11:0] ipp_ffl_mac_default; // control inf. to ffl
output ipp_hfifo_dat_empty;
output fifo_wr_en; // to ipp_fifo
output [6:0] fifo_wr_ptr; // to ipp_fifo
output ipp_hfifo_rden; // to ipp_hdr_fifo
output [5:0] ipp_hfifo_rptr; // to ipp_hdr_fifo
output [129:0] fifo_data_in; // to ipp_fifo
output ipp_hfifo_over_run_r;
output ipp_hfifo_under_run_r;
output [2:0] phase_state_xmac;
output [2:0] phase_state;
output phase_state_1st_data;
output [3:0] mac_ack_fsm_curstate;
output [1:0] ipp_ffl_curstate;
output [6:0] cur_pkt_hdr_base_ptr;
output [13:0] cur_pkt_ffl_sum_info;
wire ipp_hfifo_dat_empty;
reg ipp_hfifo_over_run_r;
reg ipp_hfifo_under_run_r;
reg [6:0] cur_pkt_hdr_base_ptr;
reg [13:0] cur_pkt_ffl_sum_info;
wire [6:0] ipp_hfifo_dat_empty_space;
wire ipp_hfifo_over_run, n_ipp_hfifo_over_run;
wire ipp_hfifo_under_run, n_ipp_hfifo_under_run;
wire n_ipp_hfifo_bad_mac_load;
reg ipp_hfifo_bad_mac_load;
reg ipp_mac_ack_d; // use ack delay as internal signal
reg [6:0] wr_base_ptr; // use for rewind pointer like run packet only
wire ipp_ffl_dvalid_n_nxt;
// pipeline register stuff
reg [63:0] mac_ipp_data_reg1;
reg [131:0] mac_ipp_data_reg2;
reg [130:0] xmac_ipp_data_reg2;
reg [63:0] mac_ipp_stat_reg;
reg [11:0] mac_ipp_ctl_reg; // store the mac ctl word
reg mac_ipp_ctrl_reg; // registered the control signal
wire [129:0] fifo_data_in = (ippfifo_rd_wr_ptr_bypass && valid2) ?
mac_ipp_data_reg2[129:0] :
(ippfifo_rd_wr_ptr_bypass && valid2_xmac_pio) ?
xmac_ipp_data_reg2[129:0] :
((xmac_mode == 1'b0) && (load_fifo == 1'b0)) ?
((xmac_mode == 1'b1) && (xload_fifo == 1'b0)) ?
xmac_mode ? xmac_ipp_data_reg2[129:0] :
mac_ipp_data_reg2[129:0];
wire [5:0] ipp_hfifo_hdr_rptr = hdr_rd_ptr_n[5:0]; // to FFL read ptr
wire [5:0] ipp_hfifo_rptr = (n_ipp_unload_idle && !ippfifo_rd_wr_ptr_bypass) ?
ipp_hfifo_hdr_rptr[5:0] : ipp_hfifo_dat_rptr[5:0];
wire ipp_hfifo_rden = ipp_ffl_dvalid_n_nxt || inc_hfifo_dat_rptr ||
ippfifo_rd_wr_ptr_bypass || reset;
wire [2:0] phase_state_xmac;
wire phase_state_1st_data;
wire [3:0] mac_ack_fsm_curstate;
reg [1:0] ipp_ffl_curstate;
wire tag_err_mac = nn_tag_d & ~bmac_ipp_tag;
wire set_tag_err_mac; //geo: from Vega: No load now, leave it for future use
// geo: wire fifo_rdy_4rd;
reg [4:0] hdr_ok_2xfer_cnt, n_hdr_ok_2xfer_cnt;
wire dec_hdr_ok_2xfer_cnt;
wire hdr_ok_2xfer_cnt_gt_eq_1 = |(hdr_ok_2xfer_cnt[4:1]);
assign bmac_ipp_tag = xmac_mode ? 1'b0 : mac_ipp_tag;
assign filtered_tag = xmac_mode ? (mac_ipp_tag & xmac_ipp_ack):
(mac_ipp_tag & ipp_mac_ack_d);
/* filtered_tag equals to the and function of tag and delayed ack
assign valid2 = mac_ipp_data_reg2[130];
assign valid2_xmac = xmac_ack;
assign valid2_xmac_pio = xmac_ipp_data_reg2[130];
assign stat_wr_reg2 = xmac_mode ? (xmac_ipp_data_reg2[128] & fifo_wr_en) :
(mac_ipp_data_reg2[128] & fifo_wr_en);
assign eop_4_fifo = xmac_mode ? xmac_ipp_data_reg2[129:128] :
mac_ipp_data_reg2[129:128];
assign fifo_wr_en = ippfifo_rd_wr_ptr_bypass ? (valid2 || valid2_xmac_pio) :
xmac_mode ? xload_fifo : load_fifo;
//**********************************************************
//***** mac_ipp_data pipe and associated control logic *****
//**********************************************************
// 1st stage mac_ipp_data pipe
wire [63:0] mac_ipp_data_next = (sel == 1'b1) ? mac_ipp_stat_reg[63:0] :
wire xmac_ipp_ack_next = (sel == 1'b1) ? sel :
wire mac_ipp_tag_next = (sel == 1'b1) ? sel :
xmac_ipp_ack_reg1 <= 1'h0;
ipp_mac_ack_reg1 <= 1'h0;
mac_ipp_ctrl_reg <= 1'h0;
mac_ipp_stat_reg <= 64'h0;
//g mac_ipp_ctl_reg <= 12'h0;
mac_ipp_data_reg1 <= 64'h0;
mac_ipp_tag_reg1 <= 1'h0;
xmac_ipp_ack_d <= xmac_ipp_ack_next;
ipp_mac_ack_d <= ipp_mac_ack;
xmac_ipp_ack_reg1 <= xmac_ipp_ack_d;
ipp_mac_ack_reg1 <= ipp_mac_ack_d;
mac_ipp_ctrl_reg <= mac_ipp_ctrl;
if (filtered_tag & xmac_mode)
mac_ipp_stat_reg[63:0] <= {41'b0, mac_ipp_stat[22:0]};
//g mac_ipp_ctl_reg[11:0] <= mac_ipp_stat[11:0];
sel <= (filtered_tag && xmac_mode)? 1'h1 : 1'h0;
mac_ipp_data_reg1[63:0] <= mac_ipp_data_next[63:0];
mac_ipp_tag_reg1 <= mac_ipp_tag_next;
/******** geo ***********************************************************/
always @ (posedge clk) begin
if (reset || mac_ipp_ctrl) begin
mac_ipp_ctl_reg <= mac_ipp_stat[11:0] & {12{!reset}};
mac_ipp_ctl_reg <= mac_ipp_ctl_reg[11:0];
/************************************************************************/
// 2nd stage mac_data_in2 pipe, pack the data from 64-bit to 128-bit
stage0_dout[63:0] <= mac_ipp_data_reg1[63:0];
stage1_dout[63:0] <= stage0_dout[63:0];
stage0_tout <= mac_ipp_tag_reg1;
stage1_tout <= stage0_tout;
xmac_ack <= xmac_ipp_ack_reg1;
bmac_ack <= ipp_mac_ack_reg1;
xstage0_dout[63:0] <= 64'h0;
xstage0_dout[63:0] <= mac_ipp_data_reg1[63:0];
xstage0_dout[63:0] <= xstage0_dout[63:0];
xstage1_dout[63:0] <= 64'h0;
else if (xmac_ipp_ack_reg1)
xstage1_dout[63:0] <= xstage0_dout[63:0];
xstage1_dout[63:0] <= xstage1_dout[63:0];
xmac_ipp_data_reg2[130:0] <= 131'b0;
else if (fifo_wr_data_reg_wr_en_pls && xmac_mode)
xmac_ipp_data_reg2[130:0] <= {1'b1, fifo_wr_data_reg[129:0]};
else if (xmac_ipp_ack_reg1)
xmac_ipp_data_reg2[130:0] <= {1'b0, stage0_tout, stage1_tout, xstage0_dout[63:0], xstage1_dout[63:0]};
else if (xmac_ack & swap) // swap data
xmac_ipp_data_reg2[130:0] <= {1'b0, stage0_tout, stage1_tout, xstage1_dout[63:0], xstage0_dout[63:0]};
xmac_ipp_data_reg2[130:0] <= {1'b0, xmac_ipp_data_reg2[129:0]};
mac_ipp_data_reg2[131:0] <= 132'h0;
else if (fifo_wr_data_reg_wr_en_pls && (xmac_mode == 1'h0))
mac_ipp_data_reg2[131:0] <= {2'b01, fifo_wr_data_reg[129:0]};
else if ((stage0_tout == 1'b0) && (stage1_tout == 1'b1))
mac_ipp_data_reg2[131:0] <= {xmac_ack, bmac_ack, stage0_tout, stage1_tout, 64'h0, stage1_dout[63:0]};
mac_ipp_data_reg2[131:0] <= {xmac_ack, bmac_ack, stage0_tout, stage1_tout, stage0_dout[63:0], stage1_dout[63:0]};
//***** end of mac_data_in pipe *****
//***** phase_sm instantiation *****
phase_sm0 xmac_phase_sm_after_packing (.clk(clk), .reset(reset),
.valid(valid2_xmac & (!ippfifo_rd_wr_ptr_bypass)),
.eop(eop_4_fifo), .swap(swap),
.load_fifo(xload_fifo), .phase_state(phase_state_xmac));
phase_sm bmac_phase_sm_after_packing (.clk(clk), .reset(reset),
.valid(valid2 & (!ippfifo_rd_wr_ptr_bypass)), .eop(eop_4_fifo),
.load_fifo(load_fifo), .phase_state(phase_state));
phase_sm3 phase_sm_1st_data (.clk(clk), .reset(reset),
.valid((valid2 | valid2_xmac) & (!ippfifo_rd_wr_ptr_bypass)),
.eop(stat_wr_reg2), .wr_1st_data(wr_1st_data),
.phase_state(phase_state_1st_data));
//***** ipp_mac_ack shaper *****
mac_ack_fsm mac_ack_fsm_ack (.clk(clk), .reset(reset | ~ipp_enable),
.mac_ipp_req(mac_ipp_req), .mac_tag(bmac_ipp_tag),
.fifo_rdy_4wr(fifo_rdy_4wr),
.tag_err_mac(tag_err_mac),
.n_tag(n_tag), .nn_tag(nn_tag), .set_tag_err_mac(set_tag_err_mac),
.ipp_ack(ipp_ack), .cur_state(mac_ack_fsm_curstate[3:0]));
//***** ack to mac & control signals from mac_ack_fsm *****
if (reset | (~ipp_enable))
//***** end of ack behavior *****
//***** req to xmac *****
if (reset | (~fifo_rdy_4wr) | (~ipp_enable))
ipp_xmac_req <= ipp_xmac_req;
//***** end of req behavior *****
//************************************************
//***** Ipp_hdr_fifo and associated control logic *****
//************************************************
//***** Ipp_hdr_fifo Write Pointer *****
else if (ippfifo_rd_wr_ptr_bypass)
casex (ippfifo_wr_ptr_pio_wr_en)
1'b0: fifo_wr_ptr <= fifo_wr_ptr; // hold the value
1'b1: fifo_wr_ptr <= pio_wr_data[6:0];
fifo_wr_ptr <= wr_base_ptr; // abort packet; rewind pointer
fifo_wr_ptr <= fifo_wr_ptr + 1; // increment
fifo_wr_ptr <= fifo_wr_ptr; // hold the value
//***** Ipp_hdr_fifo Write Base Pointer *****
wr_base_ptr <= fifo_wr_ptr;
wr_base_ptr <= fifo_wr_ptr; // update count
wr_base_ptr <= wr_base_ptr;
//***** Ipp_hdr_fifo Read Pointer *****
input ippfifo_rd_ptr_pio_wr_en; // from slave
else if (ippfifo_rd_wr_ptr_bypass)
casex (ippfifo_rd_ptr_pio_wr_en)
1'b0: fifo_rd_ptr <= fifo_rd_ptr; // hold the value
1'b1: fifo_rd_ptr <= pio_wr_data[6:0];
fifo_rd_ptr <= fifo_rd_ptr_plus1[6:0]; // inc pointer
fifo_rd_ptr <= fifo_rd_ptr; // hold the value
//*** 1K bytes Ipp_hdr_fifo Management (64-bit depth and 16 bytes(128-bit) wide) ***
wire [6:0] fifo_empty_space = (fifo_wr_ptr[6] == fifo_rd_ptr[6]) ?
7'd64 - (fifo_wr_ptr[5:0] - fifo_rd_ptr[5:0]):
(fifo_rd_ptr[5:0] - fifo_wr_ptr[5:0]);
wire fifo_full = (fifo_wr_ptr[6] == (!fifo_rd_ptr[6])) &&
(fifo_wr_ptr[5:0] == fifo_rd_ptr[5:0]);
wire fifo_empty = (fifo_wr_ptr[6:0] == fifo_rd_ptr[6:0]);
wire fifo_over_run = fifo_full & fifo_wr_en & (!ippfifo_rd_wr_ptr_bypass);
wire fifo_under_run = fifo_empty & fifo_rd_en & (!ippfifo_rd_wr_ptr_bypass);
assign ipp_hfifo_dat_empty_space = (fifo_wr_ptr[6] == ipp_hfifo_dat_rptr[6]) ?
7'd64 - {1'b0,(fifo_wr_ptr[5:0] - ipp_hfifo_dat_rptr[5:0])}:
{1'b0,(ipp_hfifo_dat_rptr[5:0] - fifo_wr_ptr[5:0])};
assign ipp_hfifo_dat_full = (fifo_wr_ptr[6] == (!ipp_hfifo_dat_rptr[6]) ) &&
(fifo_wr_ptr[5:0] == ipp_hfifo_dat_rptr[5:0]);
assign ipp_hfifo_dat_empty = (fifo_wr_ptr[6:0] == ipp_hfifo_dat_rptr[6:0]);
assign ipp_hfifo_over_run = (ipp_hfifo_dat_full && fifo_wr_en || ipp_hfifo_bad_mac_load) && !ippfifo_rd_wr_ptr_bypass;
assign ipp_hfifo_under_run = (ipp_hfifo_dat_empty && inc_hfifo_dat_rptr || ipp_hfifo_bad_mac_load) && !ippfifo_rd_wr_ptr_bypass;
assign n_ipp_hfifo_over_run = (reset || clr_ipp_unload) ? 1'b0 :
ipp_hfifo_over_run ? 1'b1 :
assign n_ipp_hfifo_under_run = (reset || clr_ipp_unload) ? 1'b0 :
ipp_hfifo_under_run ? 1'b1 :
assign n_ipp_hfifo_bad_mac_load = xmac_mode && (phase_state_xmac[2:0]==3'h5) || // phase_sm0 ERROR state
!xmac_mode && (phase_state[2:0]==3'h5) || // phase_sm ERROR state
!xmac_mode && (mac_ack_fsm_curstate[3:0]==4'hB); // mac_ack_fsm error state
ipp_hfifo_over_run_r <= n_ipp_hfifo_over_run;
ipp_hfifo_under_run_r <= n_ipp_hfifo_under_run;
ipp_hfifo_bad_mac_load<= n_ipp_hfifo_bad_mac_load;
// assign the sixteen byte data
reg [11:0] sixteen_byte_count;
if (reset | runt | stat_wr_reg2)
sixteen_byte_count <= sixteen_byte_count + 1; // hold
sixteen_byte_count <= sixteen_byte_count; // inc.
if (xmac_ipp_data_reg2[129])
abort_wr <= xmac_ipp_data_reg2[79];
abort_wr <= xmac_ipp_data_reg2[15];
if (mac_ipp_data_reg2[129])
abort_wr <= mac_ipp_data_reg2[79];
abort_wr <= mac_ipp_data_reg2[15];
// definition of runt packet
assign runt = ((sixteen_byte_count < 12'd4) |
((sixteen_byte_count == 12'd4) & abort_wr)) & stat_wr_reg2;
// synopsys translate_off
// For diagnostic purpose
$display("\n -> Warning at sim time = %d, ipp PortID=%d Ipp_hdr_fifo over run occurred.", $stime, port_id);
else if (ipp_hfifo_under_run)
$display("\n -> Warning at sim time = %d, ipp PortID=%d ipp Ipp_hdr_fifo under run occurred.", $stime, port_id);
// geo: wire [6:0] fifo_full_space = 7'd64 - ipp_hfifo_dat_empty_space[6:0];
// there are 5 stages of registers for mac/ipp interface
// As John's request change 5 to 6 (2-3-3)
wire [6:0] hfifo_space = xmac_mode ? 7'd5 : 7'd9; // geo
assign fifo_rdy_4wr = (ipp_hfifo_dat_empty_space[6:0] > hfifo_space);
//***** used by ipp_bmc_ctrl *****
//accumulate to 16-byte data (1)
// geo: assign fifo_rdy_4rd = (fifo_full_space > 7'h0) & ~runt;
//***** Ipp_hdr_fifo Header Read by FFL *****
// oThe2ndTagTime is the status word. Can not count as part of the
// 64 byte payload requirement.
// look inside PktLength field of status word approach.
//wire time_2_xfer_hdr =((fifo_data_in[13:0] == `SIXTY_FOUR) & oThe2ndTagTime)|
// ((sixteen_byte_count == `THIRTY_TWO) & fifo_wr_en & ~oThe2ndTagTime);
// independent ipp approach
wire time_2_xfer_hdr = ((sixteen_byte_count == 12'd4) & // 64-byte
(~abort_wr & stat_wr_reg2)) |
((sixteen_byte_count == 12'd5) & // 80- byte
(~abort_wr & stat_wr_reg2)) |
((sixteen_byte_count == 12'd6) & // 96-byte
(~abort_wr & stat_wr_reg2)) |
((sixteen_byte_count == 12'd7) & //112-byte
(~abort_wr & stat_wr_reg2)) |
((sixteen_byte_count == 12'd8) & //128-byte
((~abort_wr & stat_wr_reg2) |
(fifo_wr_en & ~stat_wr_reg2)));
ipp_puls_gen puls_gen_hdr_xfer (.reset(reset), .clk(clk),
.signal_in(time_2_xfer_hdr), .puls_out(hdr_ok_2xfer));
//*********************************************
//***** header base pointer fifo (7 x 16) *****
//*********************************************
reg [6:0] hdr_base_ptr_fifo [0:15]; // 7-bit by 16 deep
reg [3:0] hdr_base_ptr_wr_ptr;
reg [3:0] hdr_base_ptr_rd_ptr;
//***** write to header base pointer fifo
hdr_base_ptr_fifo[0] <= 7'b0;
hdr_base_ptr_fifo[1] <= 7'b0;
hdr_base_ptr_fifo[2] <= 7'b0;
hdr_base_ptr_fifo[3] <= 7'b0;
hdr_base_ptr_fifo[4] <= 7'b0;
hdr_base_ptr_fifo[5] <= 7'b0;
hdr_base_ptr_fifo[6] <= 7'b0;
hdr_base_ptr_fifo[7] <= 7'b0;
hdr_base_ptr_fifo[8] <= 7'b0;
hdr_base_ptr_fifo[9] <= 7'b0;
hdr_base_ptr_fifo[10] <= 7'b0;
hdr_base_ptr_fifo[11] <= 7'b0;
hdr_base_ptr_fifo[12] <= 7'b0;
hdr_base_ptr_fifo[13] <= 7'b0;
hdr_base_ptr_fifo[14] <= 7'b0;
hdr_base_ptr_fifo[15] <= 7'b0;
hdr_base_ptr_fifo[hdr_base_ptr_wr_ptr] <= fifo_wr_ptr[6:0];
hdr_base_ptr_fifo[hdr_base_ptr_wr_ptr] <= hdr_base_ptr_fifo[hdr_base_ptr_wr_ptr];
//***** header base pointer write pointer *****
hdr_base_ptr_wr_ptr <= 4'h0;
casex ({wr_1st_data, runt})
2'b00: hdr_base_ptr_wr_ptr <= hdr_base_ptr_wr_ptr;
2'b01: hdr_base_ptr_wr_ptr <= hdr_base_ptr_wr_ptr - 4'h1; // rewind
2'b10: hdr_base_ptr_wr_ptr <= hdr_base_ptr_wr_ptr + 4'h1; // increment
2'b11: hdr_base_ptr_wr_ptr <= hdr_base_ptr_wr_ptr;
//***** header base pointer read pointer *****
hdr_base_ptr_rd_ptr <= 4'h0;
else if (hdr_count == 4'd1)
hdr_base_ptr_rd_ptr <= hdr_base_ptr_rd_ptr + 1;
hdr_base_ptr_rd_ptr <= hdr_base_ptr_rd_ptr;
//***** header base pointer
wire [6:0] hdr_base_ptr = hdr_base_ptr_fifo[hdr_base_ptr_rd_ptr];
cur_pkt_hdr_base_ptr <= 7'h0;
else if (hdr_count == 4'd1)
cur_pkt_hdr_base_ptr <= hdr_base_ptr;
cur_pkt_hdr_base_ptr <= cur_pkt_hdr_base_ptr;
//***** end of header base pointer fifo
cur_pkt_ffl_sum_info <= 14'h0;
else if (ffl_ipp_dvalid && !ffl_ipp_dvalid_d)
cur_pkt_ffl_sum_info <= fflp_ipp_sum[13:0];
else if (bypass_ffl && vec_cycle1_wr_en)
cur_pkt_ffl_sum_info <= pio_wr_data[13:0];
cur_pkt_ffl_sum_info <= cur_pkt_ffl_sum_info[13:0];
always @ (start_hdr_xfer or ffl_ipp_ready or ffl_arb_ack or
hdr_count or hdr_rd_ptr or hdr_base_ptr or ipp_ffl_dvalid_n or
// geo: ipp_ffl_dvalid_n = 0;
nex_state = ipp_ffl_curstate;
case(ipp_ffl_curstate) // synopsys parallel_case full_case
if ((start_hdr_xfer) && (~ffl_ipp_ready) && n_ipp_unload_idle)
else if ((start_hdr_xfer) && (ffl_ipp_ready) && n_ipp_unload_idle)
else nex_state = ipp_ffl_curstate;
nex_state = ipp_ffl_curstate;
hdr_rd_ptr_n = hdr_base_ptr;
if (ffl_arb_ack & ffl_ipp_ready)
nex_state = ipp_ffl_curstate;
// geo: ipp_ffl_dvalid_n = ((hdr_count == 3'd0) | (hdr_count == 3'd1) |
// geo: (hdr_count == 3'd2) |
// geo: ((3'd2 < hdr_count) && (hdr_count < 3'd6) &&
// geo: (~eop_from_hdr_fifo))
hdr_count_n = hdr_count + 1;
hdr_rd_ptr_n = hdr_rd_ptr + 1;
nex_state = ipp_ffl_curstate;
hdr_rd_ptr_n = hdr_rd_ptr;
assign ipp_ffl_dvalid_n_nxt = (nex_state==Hdr_xfer) &&
((hdr_count_n == 4'd0) | (hdr_count_n == 4'd1) |
((4'd2 < hdr_count_n) && (hdr_count_n < 4'd8) &&
assign ipp_ffl_dvalid = ipp_ffl_dvalid_n;
always @ (dec_hdr_ok_2xfer_cnt or hdr_ok_2xfer or hdr_ok_2xfer_cnt)
case ({dec_hdr_ok_2xfer_cnt,hdr_ok_2xfer}) // synopsys parallel_case
2'b00: n_hdr_ok_2xfer_cnt = hdr_ok_2xfer_cnt;
2'b01: n_hdr_ok_2xfer_cnt = hdr_ok_2xfer_cnt + 5'h1; // get 1
2'b10: n_hdr_ok_2xfer_cnt = hdr_ok_2xfer_cnt - 5'h1; // consume 1
2'b11: n_hdr_ok_2xfer_cnt = hdr_ok_2xfer_cnt;
default: n_hdr_ok_2xfer_cnt = hdr_ok_2xfer_cnt;
assign dec_hdr_ok_2xfer_cnt = (nex_state == Hdr_xfer) && (ipp_ffl_curstate != Hdr_xfer) && hdr_ok_2xfer_cnt_gt_eq_1;
assign start_hdr_xfer = hdr_ok_2xfer || hdr_ok_2xfer_cnt_gt_eq_1;
//geo ipp_ffl_dvalid <= 1'h0;
ipp_ffl_curstate <= 2'h0;
ipp_ffl_dvalid_n <= 1'h0;
ffl_ipp_dvalid_d <= 1'h0;
hdr_ok_2xfer_cnt <= 5'h0;
ipp_ffl_req <= ipp_ffl_req_n;
//geo ipp_ffl_dvalid <= ipp_ffl_dvalid_n;
hdr_count <= hdr_count_n[3:0];
hdr_rd_ptr <= hdr_rd_ptr_n[6:0];
ipp_ffl_curstate <= nex_state[1:0];
ipp_ffl_dvalid_n <= ipp_ffl_dvalid_n_nxt;
ffl_ipp_dvalid_d <= ffl_ipp_dvalid;
hdr_ok_2xfer_cnt <= n_hdr_ok_2xfer_cnt;
//***********************************************
//***** Control Word FIFO and related logic *****
//***********************************************
// Control word fifo can maintain up to 16 minimum size packet(64 bytes) which
// equals to 1k size fifo.
reg [11:0] ctlfifo [0:15]; // 12-bit by 16 deep
reg [3:0] ctlfifo_wr_ptr;
reg [3:0] ctlfifo_rd_ptr;
assign ctlfifo_wr_en = wr_1st_data;
/******** geo ************************************************************
assign ctlfifo_wr_en = xmac_mode ? (mac_ipp_ctrl_reg & xmac_ipp_ack_d) :
(mac_ipp_ctrl_reg & ipp_mac_ack_d);
*************************************************************************/
//***** write to control word fifo
ctlfifo[ctlfifo_wr_ptr] <= mac_ipp_ctl_reg[11:0];
ctlfifo[ctlfifo_wr_ptr] <= ctlfifo[ctlfifo_wr_ptr];
//***** control word write pointer *****
casex ({ctlfifo_wr_en, runt})
2'b00: ctlfifo_wr_ptr <= ctlfifo_wr_ptr;
2'b01: ctlfifo_wr_ptr <= ctlfifo_wr_ptr - 1; // rewind
2'b10: ctlfifo_wr_ptr <= ctlfifo_wr_ptr + 1; // increment
2'b11: ctlfifo_wr_ptr <= ctlfifo_wr_ptr;
//***** control word read pointer by FFL *****
ipp_falling_edge_puls_gen falling_edge_puls_gen_ctlfifo_rd_dn (.reset(reset),
.clk(clk), .signal_in(ipp_ffl_dvalid),
.puls_out(ctlfifo_rd_dn));
ctlfifo_rd_ptr <= ctlfifo_rd_ptr + 1;
ctlfifo_rd_ptr <= ctlfifo_rd_ptr;
// read from control word
// {2'b00, mac_addr_index(6), defaultQPN(8), mode_bit(1), local_CPU(1),
wire [11:0] ffl_ctl_word = ctlfifo[ctlfifo_rd_ptr];
wire [11:0] ipp_ffl_mac_default = ffl_ctl_word[11:0];
//***** end of control word fifo and related logic *****
nep_spare_ipp spare_ipp_0 (
.di_nd3 ({1'h1, 1'h1, do_q[3]}),
.di_nd2 ({1'h1, 1'h1, do_q[2]}),
.di_nd1 ({1'h1, 1'h1, do_q[1]}),
.di_nd0 ({1'h1, 1'h1, do_q[0]}),
.rst ({reset,reset,reset,reset}),
`ifdef NEP_SIM_MAC_IPP_PKT_CNT
// synopsys translate_off
wire [15:0] mac_ipp_pkt_cnt;
ipp_tag_acked tag_acked_0 (
.filtered_tag (filtered_tag),
.mac_ipp_ctrl (mac_ipp_ctrl),
.xmac_ipp_ack (xmac_ipp_ack),
.ipp_mac_ack (ipp_mac_ack),
.tag2_acked (tag2_acked),
.mac_ipp_pkt_cnt (mac_ipp_pkt_cnt)
endmodule // end of ipp_load
//***** end of main program ************************************************
/**************************************************************************
* mac_ack_fsm: Use this state machine to count phases before packing data.
**************************************************************************/
module mac_ack_fsm (clk, reset, ipp_enable,
mac_ipp_req, mac_tag, fifo_rdy_4wr, tag_err_mac,
n_tag, nn_tag, set_tag_err_mac,
reg [3:0] cur_state, nex_state;
parameter load_bop = 4'h1;
parameter last_detect = 4'h6;
parameter wait_req = 4'h7;
parameter wait_req_stat_1 = 4'h8;
parameter load_stat = 4'h9;
parameter bubble_mac = 4'hA;
always @ (cur_state or mac_tag or tag_err_mac or ipp_enable or fifo_rdy_4wr
casex (cur_state) // synopsys parallel_case full_case
else if (ipp_enable && fifo_rdy_4wr && mac_ipp_req)
nex_state = load_2; // parallel with load_bop
nex_state = wait_req_stat_1;
else if (fifo_rdy_4wr && mac_ipp_req)
nex_state = wait_req_stat_1;
else if (fifo_rdy_4wr && mac_ipp_req)
nex_state = wait_req_stat_1;
/* This state only exists because there is a bug in the big mac which no one
** can fix. The MAC continues to assert request a cycle after the ack has been
** asserted and deasserted. However, it does not want to transfer more data.
** This bubble exists in order to ignore this extraneous request.
/*geo*/ default: nex_state = idle;
endmodule // end of mac_ack_fsm module
/**********************************************************************
* phase_sm0: Use this state machine to count phases after packing data.
and generate the load_fifo for xmac
**********************************************************************/
module phase_sm0 (clk, reset, valid, eop, phase_state, load_fifo, swap);
output [2:0] phase_state;
reg [2:0] nx_phase_state;
parameter WAIT_2ND_TAG = 3'h1;
parameter WAIT_2ND_ACK = 3'h2;
parameter LAST_TAG = 3'h3;
always @ (phase_state or valid or eop)
case (phase_state) // synopsys parallel_case full_case
1'b0: nx_phase_state = phase_state; // stay
nx_phase_state = WAIT_2ND_ACK; // 3'h2
nx_phase_state = WAIT_2ND_TAG; // 3'h1
// $display("Error: wrong state at NO_ACK of phase_sm at simtime = %d", $stime);
nx_phase_state = NO_ACK; // 3'h0
else if ((valid) && (eop == 2'b11))
nx_phase_state = NO_ACK; // 3'h0
// $display("Error: wrong state at WAIT_2ND_TAG of phase_sm at simtime= %d", $stime);
1'b0: nx_phase_state = phase_state; // stay
nx_phase_state = LAST_TAG; // 3'h3
nx_phase_state = NO_ACK; // 3'h0
// $display("Error: wrong state at WAIT_2ND_ACK of phase_sm at simtime = %d", $stime);
nx_phase_state = NO_ACK; // 3'h0
nx_phase_state = phase_state; // stay
nx_phase_state = STATUS; // 3'h4
// $display("Error: wrong state at LAST_TAG of phase_sm at simtime = %d", $stime);
nx_phase_state = NO_ACK; // 3'h0
// $display("E-rror: wrong state at phase_sm at simtime = %d", $stime);
/*geo*/ default: nx_phase_state = NO_ACK;
endcase // case(phase_state)
phase_state <= nx_phase_state;
endmodule // end of phase_sm0 module
/**********************************************************************
* phase_sm: Use this state machine to count phases after packing data.
and generate the load_fifo for bmac
**********************************************************************/
module phase_sm (clk, reset, valid, eop, phase_state, load_fifo);
output [2:0] phase_state;
reg [2:0] nx_phase_state;
parameter WAIT_2ND_TAG = 3'h1;
parameter WAIT_2ND_ACK = 3'h2;
parameter LAST_TAG = 3'h3;
always @ (phase_state or valid or eop)
case (phase_state) // synopsys parallel_case full_case
1'b0: nx_phase_state = phase_state; // stay
nx_phase_state = WAIT_2ND_ACK; // 3'h2
nx_phase_state = WAIT_2ND_TAG; // 3'h1
// $display("Error: wrong state at NO_ACK of phase_sm at simtime = %d", $stime);
nx_phase_state = NO_ACK; // 3'h0
else if ((valid) && (eop == 2'b11))
nx_phase_state = NO_ACK; // 3'h0
// $display("Error: wrong state at WAIT_2ND_TAG of phase_sm at simtime = %d", $stime);
1'b0: nx_phase_state = phase_state; // stay
nx_phase_state = LAST_TAG; // 3'h3
nx_phase_state = NO_ACK; // 3'h0
// $display("Error: wrong state at WAIT_2ND_ACK of phase_sm at simtime = %d", $stime);
nx_phase_state = NO_ACK; // 3'h0
nx_phase_state = phase_state; // stay
nx_phase_state = STATUS; // 3'h4
// $display("Error: wrong state at LAST_TAG of phase_sm at simtime = %d", $stime);
nx_phase_state = NO_ACK; // 3'h0
// $display("Error: wrong state at STATUS of phase_sm at simtime = %d", $stime);
// $display("E-rror: wrong state at phase_sm at simtime = %d", $stime);
/*geo*/ default: nx_phase_state = NO_ACK;
endcase // case(phase_state)
phase_state <= nx_phase_state;
endmodule // end of phase_sm module
/**********************************************************************
* phase_sm3: Use this state machine to generate the wr_1st_data
**********************************************************************/
module phase_sm3 (clk, reset, valid, eop, phase_state, wr_1st_data);
parameter WAIT4TAG = 1'b1;
always @ (phase_state or valid or eop )
case (phase_state) // synopsys parallel_case full_case
1'b0: nx_phase_state = phase_state; // stay
nx_phase_state = WAIT4TAG;
1'b0: nx_phase_state = phase_state; // stay
1'b1: nx_phase_state = IDLE;
endcase // case(phase_state)
phase_state <= nx_phase_state;
endmodule // end of phase_sm3 module
//////////////////////////////////////////////////////////////////
`ifdef NEP_SIM_MAC_IPP_PKT_CNT
output [15:0] mac_ipp_pkt_cnt;
reg [15:0] mac_ipp_pkt_cnt;
wire [15:0] mac_ipp_pkt_cnt_nxt;
reg [1:0] tag_acked_cnt_nxt;
reg inc_mac_ipp_pkt_cnt_nxt;
wire macipp_ack = xmac_mode ? xmac_ipp_ack : ipp_mac_ack;
always @ (filtered_tag or
tag_acked_cnt_nxt = 2'h0;
inc_mac_ipp_pkt_cnt_nxt = 1'h0;
case (tag_acked_cnt) // synopsys parallel_case full_case
inc_mac_ipp_pkt_cnt_nxt = 1'h1;
tag_acked_cnt_nxt = xmac_mode ? 2'h2 : 2'h1;
tag_acked_cnt_nxt = tag_acked_cnt;
tag_acked_cnt_nxt = 2'h2;
tag_acked_cnt_nxt = tag_acked_cnt;
tag_acked_cnt_nxt = 2'h0;
default: tag_acked_cnt_nxt = 2'h0;
assign tag2_acked = tag_acked_cnt_nxt[1];
assign mac_ipp_pkt_cnt_nxt = mac_ipp_pkt_cnt[15:0] + {15'h0,inc_mac_ipp_pkt_cnt};
always @(posedge clk) begin
if (reset || mac_ipp_ctrl && macipp_ack) begin
tag_acked_cnt <= #1 2'h0;
tag_acked_cnt <= #1 tag_acked_cnt_nxt[1:0];
always @(posedge clk) begin
inc_mac_ipp_pkt_cnt <= #1 1'h0;
mac_ipp_pkt_cnt <= #1 16'h0;
inc_mac_ipp_pkt_cnt <= #1 inc_mac_ipp_pkt_cnt_nxt;
mac_ipp_pkt_cnt <= #1 mac_ipp_pkt_cnt_nxt[15:0];