Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / niu_rdmc_buf_manager.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: niu_rdmc_buf_manager.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
// have any questions.
//
// ========== Copyright Header End ============================================
/*************************************************************************
*
* File Name : niu_rdmc_buf_manager.v
* Author Name : Jeanne Cai
* Description :
* Date Created : 07/18/2004
*
* Copyright (c) 2001, Sun Microsystems, Inc.
* Sun Proprietary and Confidential
*
*
*************************************************************************/
`include "niu_rdmc.h"
module niu_rdmc_buf_manager (
clk,
reset,
wred_enable,
random_num,
dma_chnl_grp_id,
dma_data_offset,
full_header,
dma_en,
dma_reset,
page_valid0,
addr_mask0,
comp_value0,
relo_value0,
page_valid1,
addr_mask1,
comp_value1,
relo_value1,
dma_fatal_err,
rx_log_page_hdl_reg,
rdc_red_param_reg,
rbr_cfig_a_reg,
rbr_cfig_b_reg,
rbr_kick_reg,
rbr_cfig_a_reg_wenu,
rbr_cfig_a_reg_wenl,
rbr_kick_reg_wen,
muxed_pkt_len,
muxed_rdc_num_r,
muxed_drop_pkt_r,
muxed_s_event_r,
sel_buf_en, //it is stage0_en_r, in stage1
pkt_req_cnt_e_done_mod,
pkt_buf_done,
is_hdr_wr_data,
is_jmb1_wr_data,
fetch_desp_req_sm,
fetch_desp_pre_done,
fetch_desp_done,
fetch_desp_resp_vld,
rdmc_resp_data_valid,
cache_start_addr,
cache_end_addr,
cache_buf_rd_gnt,
cache_buf_rd_data,
cache_parity_err,
rcr_curr_qlen,
shadw_curr_space_cnt,
chnl_sel_buf_en_r,
desp_init_valid,
fetch_desp_trig,
fetch_desp_addr,
fetch_desp_num,
cache_read_req,
cache_rd_ptr,
cache_wr_ptr,
drop_pkt,
pkt_buf_gnt,
pkt_buf_size,
pkt_buf_addr,
orig_buf_addr,
pref_buf_used_num,
pkt_trans_len,
desp_curr_addr,
desp_curr_cnt,
desp_addr_not_valid,
buf_addr_not_valid,
rbr_addr_overflow,
desp_curr_cnt_overflow,
rbr_empty,
wred_drop_pkt,
rcr_drop_pkt,
rbr_drop_pkt,
chnl_sel_buf_en,
chnl_cache_parity_err
);
input clk;
input reset;
input wred_enable;
input[15:0] random_num;
input[4:0] dma_chnl_grp_id;
input[1:0] dma_data_offset;
input full_header;
input dma_reset;
input dma_en;
input page_valid0;
input[31:0] addr_mask0;
input[31:0] comp_value0;
input[31:0] relo_value0;
input page_valid1;
input[31:0] addr_mask1;
input[31:0] comp_value1;
input[31:0] relo_value1;
input dma_fatal_err;
input[19:0] rx_log_page_hdl_reg;
input[31:0] rdc_red_param_reg;
input[53:0] rbr_cfig_a_reg;
input[10:0] rbr_cfig_b_reg;
input[15:0] rbr_kick_reg;
input rbr_cfig_a_reg_wenu;
input rbr_cfig_a_reg_wenl;
input rbr_kick_reg_wen;
input[13:0] muxed_pkt_len;
input[4:0] muxed_rdc_num_r;
input muxed_drop_pkt_r;
input muxed_s_event_r;
input sel_buf_en;
input pkt_req_cnt_e_done_mod;
input pkt_buf_done;
input is_hdr_wr_data;
input is_jmb1_wr_data;
input fetch_desp_req_sm;
input fetch_desp_pre_done;
input fetch_desp_done;
input fetch_desp_resp_vld;
input rdmc_resp_data_valid;
input[7:0] cache_start_addr;
input[7:0] cache_end_addr;
input cache_buf_rd_gnt;
input[131:0] cache_buf_rd_data;
input cache_parity_err;
input[15:0] rcr_curr_qlen;
input[7:0] shadw_curr_space_cnt;
output chnl_sel_buf_en_r;
output desp_init_valid;
output fetch_desp_trig;
output[63:0] fetch_desp_addr;
output[4:0] fetch_desp_num;
output cache_read_req;
output[7:0] cache_rd_ptr;
output[7:0] cache_wr_ptr;
output drop_pkt;
output pkt_buf_gnt;
output[1:0] pkt_buf_size;
output[63:0] pkt_buf_addr;
output[35:0] orig_buf_addr;
output[1:0] pref_buf_used_num;
output[13:0] pkt_trans_len;
output[15:0] desp_curr_addr;
output[16:0] desp_curr_cnt;
output desp_addr_not_valid;
output buf_addr_not_valid;
output rbr_addr_overflow;
output desp_curr_cnt_overflow;
output rbr_empty;
output wred_drop_pkt;
output rcr_drop_pkt;
output rbr_drop_pkt;
output chnl_sel_buf_en;
output chnl_cache_parity_err;
reg rbr_cfig_a_reg_wenu_dly2;
reg rbr_cfig_a_reg_wenu_dly;
reg rbr_cfig_a_reg_wenl_dly2;
reg rbr_cfig_a_reg_wenl_dly;
reg rbr_kick_reg_wen_dly;
reg[16:0] rbr_end_addr_r;
always @ (posedge clk)
if (reset)
rbr_cfig_a_reg_wenu_dly <= 1'b0;
else if (dma_reset)
rbr_cfig_a_reg_wenu_dly <= 1'b0;
else
rbr_cfig_a_reg_wenu_dly <= rbr_cfig_a_reg_wenu;
always @ (posedge clk)
if (reset)
rbr_cfig_a_reg_wenu_dly2 <= 1'b0;
else if (dma_reset)
rbr_cfig_a_reg_wenu_dly2 <= 1'b0;
else
rbr_cfig_a_reg_wenu_dly2 <= rbr_cfig_a_reg_wenu_dly;
always @ (posedge clk)
if (reset)
rbr_cfig_a_reg_wenl_dly <= 1'b0;
else if (dma_reset)
rbr_cfig_a_reg_wenl_dly <= 1'b0;
else
rbr_cfig_a_reg_wenl_dly <= rbr_cfig_a_reg_wenl;
always @ (posedge clk)
if (reset)
rbr_cfig_a_reg_wenl_dly2 <= 1'b0;
else if (dma_reset)
rbr_cfig_a_reg_wenl_dly2 <= 1'b0;
else
rbr_cfig_a_reg_wenl_dly2 <= rbr_cfig_a_reg_wenl_dly;
always @ (posedge clk)
if (reset)
rbr_kick_reg_wen_dly <= 1'b0;
else if (dma_reset)
rbr_kick_reg_wen_dly <= 1'b0;
else
rbr_kick_reg_wen_dly <= rbr_kick_reg_wen;
/**********************************************/
//PIO programmed parameters
/**********************************************/
wire[19:0] page_handle = rx_log_page_hdl_reg[19:0];
wire[3:0] wred_window = rdc_red_param_reg[3:0];
wire[11:0] wred_thresh = rdc_red_param_reg[15:4];
wire[3:0] wred_window_syn = rdc_red_param_reg[19:16];
wire[11:0] wred_thresh_syn = rdc_red_param_reg[31:20];
wire[15:0] rbr_max_len = rbr_cfig_a_reg[53:38];
wire[25:0] rbr_base_addr = rbr_cfig_a_reg[37:12];
wire[15:0] rbr_start_addr = {rbr_cfig_a_reg[11:0], 4'b0}; //4 bytes aligned
wire[15:0] rbr_end_addr = rbr_end_addr_r[15:0];
wire rbr_addr_overflow = rbr_end_addr_r[16] & dma_en;
wire[1:0] cache_buf_size_sel = rbr_cfig_b_reg[10:9]; //{00:4k, 01:8k, 10:16k,11:32k}
wire size2_config_valid = rbr_cfig_b_reg[8];
wire[1:0] size2_buf_size_sel = rbr_cfig_b_reg[7:6]; //{00:2k, 01:4k, 10:8k,11:16k}
wire size1_config_valid = rbr_cfig_b_reg[5];
wire[1:0] size1_buf_size_sel = rbr_cfig_b_reg[4:3]; //{00:1k, 01:2k, 10:4k,11:8k}
wire size0_config_valid = rbr_cfig_b_reg[2];
wire[1:0] size0_buf_size_sel = rbr_cfig_b_reg[1:0]; //{00:256, 01:512, 10:1k,11:2k}
/************************/
//descriptor manager
/************************/
reg cal_addr_en;
reg[4:0] addr_cnt; // at most, fetch 16 addresses
reg[15:0] desp_curr_addr_tmp;
reg[15:0] desp_curr_addr; // always on 4 bytes boundry
reg[16:0] desp_curr_cnt; // bit[16] is overflow bit
reg inc_desp_curr_cnt;
reg desp_curr_cnt_overflow_r;
reg[15:0] desp_addr_avail_num;
reg[7:0] cache_space_cnt; //support 255 lines, for most cases, it is 8 lines
reg[7:0] cache_buf_cnt;
reg inc_cache_buf_cnt;
reg cache_buf_empty;
reg cache_buf_full;
reg[4:0] fetch_desp_num;
wire[15:0] rbr_end_addr_sub = rbr_max_len[15:0] - 16'd1;
always @ (posedge clk)
if (reset)
rbr_end_addr_r <= 17'b0;
else if (dma_reset)
rbr_end_addr_r <= 17'b0;
else if (rbr_cfig_a_reg_wenu_dly & (|rbr_max_len))
rbr_end_addr_r <= {1'b0, rbr_end_addr_sub[15:0]};
else if (rbr_cfig_a_reg_wenl_dly2 | rbr_cfig_a_reg_wenu_dly2)
rbr_end_addr_r <= {1'b0, rbr_start_addr[15:0]} + rbr_end_addr_r;
else
rbr_end_addr_r <= rbr_end_addr_r;
always @ (posedge clk)
if (reset)
addr_cnt <= 5'b0;
else if (dma_reset)
addr_cnt <= 5'b0;
else if (cal_addr_en)
addr_cnt <= fetch_desp_num;
else if (addr_cnt != 5'b0)
addr_cnt <= addr_cnt - 5'd1;
else
addr_cnt <= addr_cnt;
always @ (posedge clk)
if (reset)
desp_curr_addr_tmp <= 16'b0;
else if (dma_reset)
desp_curr_addr_tmp <= 16'b0;
else if ((addr_cnt != 5'b0) & (desp_curr_addr_tmp == rbr_end_addr))
desp_curr_addr_tmp <= rbr_start_addr;
else if (addr_cnt != 5'b0)
desp_curr_addr_tmp <= desp_curr_addr_tmp + 16'd1;
else if (cal_addr_en)
desp_curr_addr_tmp <= desp_curr_addr;
else
desp_curr_addr_tmp <= desp_curr_addr_tmp;
always @ (posedge clk)
if (reset)
desp_curr_addr <= 16'b0;
else if (rbr_cfig_a_reg_wenl_dly)
desp_curr_addr <= rbr_start_addr;
else if (fetch_desp_done)
desp_curr_addr <= desp_curr_addr_tmp;
else
desp_curr_addr <= desp_curr_addr;
always @ (posedge clk)
if (reset)
desp_addr_avail_num <= 16'b0;
else if (dma_reset)
desp_addr_avail_num <= 16'b0;
else if (rbr_cfig_a_reg_wenu_dly)
desp_addr_avail_num <= rbr_max_len[15:0];
else if (fetch_desp_pre_done)
desp_addr_avail_num <= rbr_end_addr[15:0] - desp_curr_addr_tmp[15:0];
else if (fetch_desp_done)
desp_addr_avail_num <= desp_addr_avail_num + 16'd1;
else
desp_addr_avail_num <= desp_addr_avail_num;
always @ (posedge clk)
if (reset)
inc_desp_curr_cnt <= 1'b0;
else if (dma_reset)
inc_desp_curr_cnt <= 1'b0;
else if (rbr_kick_reg_wen & !fetch_desp_pre_done | rbr_kick_reg_wen_dly & !inc_desp_curr_cnt)
inc_desp_curr_cnt <= 1'b1;
else
inc_desp_curr_cnt <= 1'b0;
always @ (posedge clk)
if (reset)
desp_curr_cnt <= 17'b0; //pio read only
else if (dma_reset)
desp_curr_cnt <= 17'b0;
else if (desp_curr_cnt[16] | desp_curr_cnt_overflow_r)
desp_curr_cnt <= desp_curr_cnt;
else if (inc_desp_curr_cnt)
desp_curr_cnt <= desp_curr_cnt + {1'b0, rbr_kick_reg[15:0]}; // bit[16] is overflow bit
else if (fetch_desp_done)
desp_curr_cnt <= desp_curr_cnt - {12'b0, fetch_desp_num[4:0]};
else
desp_curr_cnt <= desp_curr_cnt;
wire desp_curr_cnt_overflow = (desp_curr_cnt > {1'b0, rbr_max_len}) & dma_en;
always @ (posedge clk)
if (reset)
desp_curr_cnt_overflow_r <= 1'b0;
else if (dma_reset)
desp_curr_cnt_overflow_r <= 1'b0;
else if (desp_curr_cnt_overflow)
desp_curr_cnt_overflow_r <= 1'b1;
else
desp_curr_cnt_overflow_r <= desp_curr_cnt_overflow_r;
/*****************************/
//request descriptor
/*****************************/
reg[31:0] desp_relo_addr_r;
wire rbr_empty = (|cache_space_cnt[7:2]) & !(|desp_curr_cnt[15:0]) & dma_en;
wire fetch_desp_trig = (cache_space_cnt[7:0] > 8'd4) & (|desp_curr_cnt[15:0]);
wire[4:0] desp_cnt_avail_num = (|desp_curr_cnt[15:4]) ? 5'b10000 : desp_curr_cnt[4:0];
wire[4:0] desp_addr_avail_num1 = (|desp_addr_avail_num[15:4]) ? 5'b10000 : desp_addr_avail_num[4:0];
wire[4:0] fetch_desp_min_num = (desp_addr_avail_num1[4:0] > desp_cnt_avail_num[4:0]) ? desp_cnt_avail_num[4:0] :
desp_addr_avail_num1[4:0];
wire[43:0] desp_full_addr = {rbr_base_addr[25:0], desp_curr_addr[15:0], 2'b0};
wire desp_addr_valid0 = ((desp_full_addr[43:12] & addr_mask0) == (comp_value0 & addr_mask0)) & page_valid0;
wire desp_addr_valid1 = ((desp_full_addr[43:12] & addr_mask1) == (comp_value1 & addr_mask1)) & page_valid1;
wire[31:0] desp_relo_addr0 = (desp_full_addr[43:12] & ~addr_mask0) | (relo_value0 & addr_mask0);
wire[31:0] desp_relo_addr1 = (desp_full_addr[43:12] & ~addr_mask1) | (relo_value1 & addr_mask1);
wire[31:0] desp_relo_addr = desp_addr_valid0 ? desp_relo_addr0 : desp_relo_addr1;
wire[63:0] fetch_desp_addr = {page_handle[19:0], desp_relo_addr_r[31:0], desp_full_addr[11:0]};
wire desp_addr_not_valid = !(desp_addr_valid0 | desp_addr_valid1) & dma_en;
wire desp_init_valid = (desp_addr_valid0 | desp_addr_valid1) & dma_en;
always @ (posedge clk)
if (reset)
cal_addr_en <= 1'b0;
else
cal_addr_en <= fetch_desp_req_sm;
always @ (posedge clk)
if (reset)
desp_relo_addr_r <= 32'b0;
else if (fetch_desp_req_sm)
desp_relo_addr_r <= desp_relo_addr;
else
desp_relo_addr_r <= desp_relo_addr_r;
always @ (posedge clk)
if (reset)
fetch_desp_num <= 5'b0;
else if (fetch_desp_req_sm)
fetch_desp_num <= fetch_desp_min_num;
else
fetch_desp_num <= fetch_desp_num;
/******************************/
//buffer size decode
/******************************/
reg[7:0] cache_buf_size_dec;
reg[7:0] size2_buf_size_dec;
reg[7:0] size1_buf_size_dec;
reg[7:0] size0_buf_size_dec;
reg[7:0] size2_buf_num_dec;
reg[7:0] size1_buf_num_dec;
reg[7:0] size0_buf_num_dec;
reg[7:0] cache_buf_size_pre;
reg[9:0] cache_buf_size1_pre; //one cache - data_offset
reg[10:0] cache_buf_size2_pre; //for two cache buf size - 1 data_offset
reg[10:0] cache_buf_size3_pre; //for three cache buf size - 2 data_offset
reg[7:0] size2_buf_size_pre;
reg[7:0] size1_buf_size_pre;
reg[7:0] size0_buf_size_pre;
reg[7:0] start_size2_buf_num;
reg[7:0] start_size1_buf_num;
reg[7:0] start_size0_buf_num;
wire[7:0] byte_offset = (dma_data_offset[1:0] == 2'b01) ? 8'd64 :
(dma_data_offset[1:0] == 2'b10) ? 8'd128 : 8'd0;
always @(cache_buf_size_sel)
case(cache_buf_size_sel) //synopsys parallel_case full_case
2'd0: cache_buf_size_dec = 8'h10; //4k
2'd1: cache_buf_size_dec = 8'h20; //8k
2'd2: cache_buf_size_dec = 8'h40; //16k
2'd3: cache_buf_size_dec = 8'h80; //32k
default: cache_buf_size_dec = 8'h10;
endcase
always @(size2_buf_size_sel)
case(size2_buf_size_sel) //synopsys parallel_case full_case
2'd0: size2_buf_size_dec = 8'h08; //2k
2'd1: size2_buf_size_dec = 8'h10; //4k
2'd2: size2_buf_size_dec = 8'h20; //8k
2'd3: size2_buf_size_dec = 8'h40; //16k
default: size2_buf_size_dec = 8'h08;
endcase
always @(size1_buf_size_sel)
case(size1_buf_size_sel) //synopsys parallel_case full_case
2'd0: size1_buf_size_dec = 8'h04; //1k
2'd1: size1_buf_size_dec = 8'h08; //2k
2'd2: size1_buf_size_dec = 8'h10; //4k
2'd3: size1_buf_size_dec = 8'h20; //8k
default: size1_buf_size_dec = 8'h04;
endcase
always @(size0_buf_size_sel)
case(size0_buf_size_sel) //synopsys parallel_case full_case
2'd0: size0_buf_size_dec = 8'h01; //256
2'd1: size0_buf_size_dec = 8'h02; //512
2'd2: size0_buf_size_dec = 8'h04; //1k
2'd3: size0_buf_size_dec = 8'h08; //2k
default: size0_buf_size_dec = 8'h01;
endcase
always @(cache_buf_size_sel or size2_buf_size_sel)
case(cache_buf_size_sel) //synopsys parallel_case full_case
2'b00: begin
case(size2_buf_size_sel) //synopsys parallel_case full_case
2'b00: size2_buf_num_dec = 8'd2;
2'b01: size2_buf_num_dec = 8'd1;
2'b10: size2_buf_num_dec = 8'd0;
2'b11: size2_buf_num_dec = 8'd0;
default:size2_buf_num_dec = 8'd0;
endcase
end
2'b01: begin
case(size2_buf_size_sel) //synopsys parallel_case full_case
2'b00: size2_buf_num_dec = 8'd4;
2'b01: size2_buf_num_dec = 8'd2;
2'b10: size2_buf_num_dec = 8'd1;
2'b11: size2_buf_num_dec = 8'd0;
default:size2_buf_num_dec = 8'd0;
endcase
end
2'b10: begin
case(size2_buf_size_sel) //synopsys parallel_case full_case
2'b00: size2_buf_num_dec = 8'd8;
2'b01: size2_buf_num_dec = 8'd4;
2'b10: size2_buf_num_dec = 8'd2;
2'b11: size2_buf_num_dec = 8'd1;
default:size2_buf_num_dec = 8'd1;
endcase
end
2'b11: begin
case(size2_buf_size_sel) //synopsys parallel_case full_case
2'b00: size2_buf_num_dec = 8'd16;
2'b01: size2_buf_num_dec = 8'd8;
2'b10: size2_buf_num_dec = 8'd4;
2'b11: size2_buf_num_dec = 8'd2;
default:size2_buf_num_dec = 8'd2;
endcase
end
default: size2_buf_num_dec = 8'd0;
endcase
always @(cache_buf_size_sel or size1_buf_size_sel)
case(cache_buf_size_sel) //synopsys parallel_case full_case
2'b00: begin
case(size1_buf_size_sel) //synopsys parallel_case full_case
2'b00: size1_buf_num_dec = 8'd4;
2'b01: size1_buf_num_dec = 8'd2;
2'b10: size1_buf_num_dec = 8'd1;
2'b11: size1_buf_num_dec = 8'd0;
default:size1_buf_num_dec = 8'd0;
endcase
end
2'b01: begin
case(size1_buf_size_sel) //synopsys parallel_case full_case
2'b00: size1_buf_num_dec = 8'd8;
2'b01: size1_buf_num_dec = 8'd4;
2'b10: size1_buf_num_dec = 8'd2;
2'b11: size1_buf_num_dec = 8'd1;
default:size1_buf_num_dec = 8'd1;
endcase
end
2'b10: begin
case(size1_buf_size_sel) //synopsys parallel_case full_case
2'b00: size1_buf_num_dec = 8'd16;
2'b01: size1_buf_num_dec = 8'd8;
2'b10: size1_buf_num_dec = 8'd4;
2'b11: size1_buf_num_dec = 8'd2;
default:size1_buf_num_dec = 8'd2;
endcase
end
2'b11: begin
case(size1_buf_size_sel) //synopsys parallel_case full_case
2'b00: size1_buf_num_dec = 8'd32;
2'b01: size1_buf_num_dec = 8'd16;
2'b10: size1_buf_num_dec = 8'd8;
2'b11: size1_buf_num_dec = 8'd4;
default:size1_buf_num_dec = 8'd4;
endcase
end
default: size1_buf_num_dec = 8'd0;
endcase
always @(cache_buf_size_sel or size0_buf_size_sel)
case(cache_buf_size_sel) //synopsys parallel_case full_case
2'b00: begin
case(size0_buf_size_sel) //synopsys parallel_case full_case
2'b00: size0_buf_num_dec = 8'd16;
2'b01: size0_buf_num_dec = 8'd8;
2'b10: size0_buf_num_dec = 8'd4;
2'b11: size0_buf_num_dec = 8'd2;
default:size0_buf_num_dec = 8'd2;
endcase
end
2'b01: begin
case(size0_buf_size_sel) //synopsys parallel_case full_case
2'b00: size0_buf_num_dec = 8'd32;
2'b01: size0_buf_num_dec = 8'd16;
2'b10: size0_buf_num_dec = 8'd8;
2'b11: size0_buf_num_dec = 8'd4;
default:size0_buf_num_dec = 8'd4;
endcase
end
2'b10: begin
case(size0_buf_size_sel) //synopsys parallel_case full_case
2'b00: size0_buf_num_dec = 8'd64;
2'b01: size0_buf_num_dec = 8'd32;
2'b10: size0_buf_num_dec = 8'd16;
2'b11: size0_buf_num_dec = 8'd8;
default:size0_buf_num_dec = 8'd8;
endcase
end
2'b11: begin
case(size0_buf_size_sel) //synopsys parallel_case full_case
2'b00: size0_buf_num_dec = 8'd128;
2'b01: size0_buf_num_dec = 8'd64;
2'b10: size0_buf_num_dec = 8'd32;
2'b11: size0_buf_num_dec = 8'd16;
default:size0_buf_num_dec = 8'd16;
endcase
end
default: size0_buf_num_dec = 8'd0;
endcase
always @ (posedge clk)
if (reset)
cache_buf_size_pre <= 8'b0;
else
cache_buf_size_pre <= cache_buf_size_dec;
wire[15:0] cache_buf_size = {cache_buf_size_pre[7:0], 8'b0};
wire[9:0] cache_buf_size1_in = {cache_buf_size_dec[7:0], 2'b0} - {8'b0, byte_offset[7:6]};
always @ (posedge clk)
if (reset)
cache_buf_size1_pre <= 10'b0;
else
cache_buf_size1_pre <= cache_buf_size1_in;
//wire[15:0] cache_buf_size1 = {cache_buf_size1_pre[9:0], 6'b0};
wire[13:0] cache_buf_size1 = {cache_buf_size1_pre[7:0], 6'b0};
wire[10:0] cache_buf_size2_in = {cache_buf_size_pre[7:0], 3'b0} - {9'b0, byte_offset[7:6]};
always @ (posedge clk)
if (reset)
cache_buf_size2_pre <= 11'b0;
else
cache_buf_size2_pre <= cache_buf_size2_in;
//wire[16:0] cache_buf_size2 = {cache_buf_size2_pre[10:0], 6'b0};
wire[15:0] cache_buf_size2 = {cache_buf_size2_pre[9:0], 6'b0};
wire[10:0] cache_buf_size3_in = cache_buf_size2_pre[10:0] + {1'b0, cache_buf_size1_pre[9:0]};
always @ (posedge clk)
if (reset)
cache_buf_size3_pre <= 11'b0;
else
cache_buf_size3_pre <= cache_buf_size3_in;
wire[16:0] cache_buf_size3 = {cache_buf_size3_pre[10:0], 6'b0};
always @ (posedge clk)
if (reset)
size2_buf_size_pre <= 8'b0;
else
size2_buf_size_pre <= size2_buf_size_dec;
wire[15:0] size2_buf_size = {size2_buf_size_pre[7:0], 8'b0};
always @ (posedge clk)
if (reset)
size1_buf_size_pre <= 8'b0;
else
size1_buf_size_pre <= size1_buf_size_dec;
wire[15:0] size1_buf_size = {size1_buf_size_pre[7:0], 8'b0};
always @ (posedge clk)
if (reset)
size0_buf_size_pre <= 8'b0;
else
size0_buf_size_pre <= size0_buf_size_dec;
wire[15:0] size0_buf_size = {size0_buf_size_pre[7:0], 8'b0};
always @ (posedge clk)
if (reset)
start_size2_buf_num <= 8'b0;
else
start_size2_buf_num <= size2_buf_num_dec;
always @ (posedge clk)
if (reset)
start_size1_buf_num <= 8'b0;
else
start_size1_buf_num <= size1_buf_num_dec;
always @ (posedge clk)
if (reset)
start_size0_buf_num <= 8'b0;
else
start_size0_buf_num <= size0_buf_num_dec;
/*********************************/
// cache memory manager
/*********************************/
reg cache_buf_rd_gnt_dly1;
reg cache_buf_rd_gnt_dly2;
reg cache_buf_rd_gnt_dly3;
reg[7:0] cache_wr_ptr;
reg[7:0] cache_rd_ptr;
reg[2:0] cache_rd_cnt; //at most read 4 addresses
wire cache_buf_wr_gnt = fetch_desp_resp_vld & rdmc_resp_data_valid;
wire last_rd_ptr = (cache_space_cnt == `CACHE_LEN_SUB1);
wire last_wr_ptr = (cache_space_cnt == 8'd1);
wire last_wr_addr = (cache_wr_ptr == cache_end_addr);
wire last_rd_addr = (cache_rd_ptr == cache_end_addr);
always @ (posedge clk)
if (reset)
cache_wr_ptr <= cache_start_addr;
else if (dma_reset)
cache_wr_ptr <= cache_start_addr;
else if (cache_buf_wr_gnt & last_wr_addr)
cache_wr_ptr <= cache_start_addr;
else if (cache_buf_wr_gnt)
cache_wr_ptr <= cache_wr_ptr + 8'd1;
else
cache_wr_ptr <= cache_wr_ptr;
always @ (posedge clk)
if (reset)
cache_rd_ptr <= cache_start_addr;
else if (dma_reset)
cache_rd_ptr <= cache_start_addr;
else if (cache_buf_rd_gnt_dly3 & last_rd_addr)
cache_rd_ptr <= cache_start_addr;
else if (cache_buf_rd_gnt_dly3)
cache_rd_ptr <= cache_rd_ptr + 8'd1;
else
cache_rd_ptr <= cache_rd_ptr;
always @ (posedge clk)
if (reset)
cache_buf_empty <= 1'b1;
else if (dma_reset)
cache_buf_empty <= 1'b1;
else if (cache_buf_wr_gnt)
cache_buf_empty <= 1'b0;
else if (cache_buf_rd_gnt_dly3 & last_rd_ptr)
cache_buf_empty <= 1'b1;
else
cache_buf_empty <= cache_buf_empty;
always @ (posedge clk)
if (reset)
cache_buf_full <= 1'b0;
else if (dma_reset)
cache_buf_full <= 1'b0;
else if (cache_buf_rd_gnt_dly3)
cache_buf_full <= 1'b0;
else if (cache_buf_wr_gnt & last_wr_ptr)
cache_buf_full <= 1'b1;
else
cache_buf_full <= cache_buf_full;
always @ (posedge clk)
if (reset)
cache_space_cnt <= `CACHE_LEN;
else if (dma_reset)
cache_space_cnt <= `CACHE_LEN;
else if (cache_buf_wr_gnt & cache_buf_rd_gnt_dly3)
cache_space_cnt <= cache_space_cnt;
else if (cache_buf_wr_gnt)
cache_space_cnt <= cache_space_cnt - 8'd1;
else if (cache_buf_rd_gnt_dly3)
cache_space_cnt <= cache_space_cnt + 8'd1;
else
cache_space_cnt <= cache_space_cnt;
wire[3:0] cache_rd_valid_bits = cache_buf_rd_data[131:128];
always @ (posedge clk)
if (reset)
cache_buf_rd_gnt_dly1 <= 1'b0;
else if (dma_reset)
cache_buf_rd_gnt_dly1 <= 1'b0;
else
cache_buf_rd_gnt_dly1 <= cache_buf_rd_gnt;
always @ (posedge clk)
if (reset)
begin
cache_buf_rd_gnt_dly2 <= 1'b0;
cache_buf_rd_gnt_dly3 <= 1'b0;
end
else
begin
cache_buf_rd_gnt_dly2 <= cache_buf_rd_gnt_dly1;
cache_buf_rd_gnt_dly3 <= cache_buf_rd_gnt_dly2;
end
always @ (cache_rd_valid_bits)
begin
case (cache_rd_valid_bits) //synopsys parallel_case full_case
4'b0001, 4'b0010, 4'b0100, 4'b1000:
cache_rd_cnt = 3'b001;
4'b0011, 4'b0110, 4'b1100:
cache_rd_cnt = 3'b010;
4'b0111, 4'b1110:
cache_rd_cnt = 3'b011;
4'b1111:
cache_rd_cnt = 3'b100;
default:
cache_rd_cnt = 3'b000;
endcase
end
always @ (posedge clk)
if (reset)
inc_cache_buf_cnt <= 1'b0;
else if (dma_reset)
inc_cache_buf_cnt <= 1'b0;
else if (fetch_desp_pre_done & cache_buf_rd_gnt_dly3)
inc_cache_buf_cnt <= 1'b1;
else
inc_cache_buf_cnt <= 1'b0;
always @ (posedge clk)
if (reset)
cache_buf_cnt <= 8'b0;
else if (dma_reset)
cache_buf_cnt <= 8'b0;
else if (fetch_desp_pre_done & !cache_buf_rd_gnt_dly3 | inc_cache_buf_cnt)
cache_buf_cnt <= cache_buf_cnt + {3'b0, fetch_desp_num[4:0]};
else if (cache_buf_rd_gnt_dly3)
cache_buf_cnt <= cache_buf_cnt - {5'b0, cache_rd_cnt};
else
cache_buf_cnt <= cache_buf_cnt;
/************************/
//Discard pkt
/************************/
reg chnl_sel_buf_en;
reg sel_buf_en_r; //same as chnl_sel_buf_en
reg drop_pkt;
reg wred_drop_pkt;
wire buf_addr_not_valid;
wire rbr_drop_pkt;
wire rcr_drop_pkt;
wire shadow_not_empty = (|shadw_curr_space_cnt);
wire shadow_not_e_empty = (|shadw_curr_space_cnt[7:2]) | (&shadw_curr_space_cnt[1:0]);
wire is_drop_pkt_tmp = wred_drop_pkt | rcr_drop_pkt | muxed_drop_pkt_r | dma_fatal_err | !dma_en;
wire sel_buf_enabled_tmp = chnl_sel_buf_en & !is_drop_pkt_tmp;
wire is_drop_pkt = is_drop_pkt_tmp | rbr_drop_pkt;
wire sel_buf_enabled = chnl_sel_buf_en & !is_drop_pkt;
always @ (posedge clk)
if (reset)
chnl_sel_buf_en <= 1'b0;
else if (dma_reset)
chnl_sel_buf_en <= 1'b0;
else
chnl_sel_buf_en <= sel_buf_en & (muxed_rdc_num_r == dma_chnl_grp_id);
always @ (posedge clk)
if (reset)
sel_buf_en_r <= 1'b0;
else if (dma_reset)
sel_buf_en_r <= 1'b0;
else
sel_buf_en_r <= sel_buf_en & (muxed_rdc_num_r == dma_chnl_grp_id);
always @ (posedge clk)
if (reset)
drop_pkt <= 1'b0;
else if (dma_reset)
drop_pkt <= 1'b0;
else if (chnl_sel_buf_en)
drop_pkt <= (is_drop_pkt | buf_addr_not_valid);
else
drop_pkt <= 1'b0;
/*********************************/
// prefetch buffer manager
/*********************************/
reg[3:0] use_pref_buf; //pkt use pref buf, in stage2
reg[3:0] unload_pref_buf; //size load pref buf, not in stage2
reg is_last_pref_buf;
reg d_pref_buf_valid;
reg t_pref_buf_valid;
reg[127:0] pref_buf_addr_reg;
reg pref_buf0_valid;
reg pref_buf1_valid;
reg pref_buf2_valid;
reg pref_buf3_valid;
reg cache_read_req;
reg size0_buf_req;
reg size1_buf_req;
reg size2_buf_req;
reg[31:0] pref_buf_addr0;
reg[31:0] pref_buf_addr1;
reg[31:0] pref_buf_addr2;
reg[31:0] pref_buf_addr3;
wire get_pkt_pref_buf;
wire pkt_pref_buf_in_use;
wire chnl_cache_parity_err = cache_buf_rd_gnt_dly3 & cache_parity_err;
wire load_pref_buf = cache_buf_rd_gnt_dly3 & !cache_parity_err;
wire[31:0] pref_buf_addr_tmp0 = cache_buf_rd_data[31:0];
wire[31:0] pref_buf_addr_tmp1 = cache_buf_rd_data[63:32];
wire[31:0] pref_buf_addr_tmp2 = cache_buf_rd_data[95:64];
wire[31:0] pref_buf_addr_tmp3 = cache_buf_rd_data[127:96];
always @(cache_buf_size_sel or
pref_buf_addr_tmp0 or pref_buf_addr_tmp1 or
pref_buf_addr_tmp2 or pref_buf_addr_tmp3)
case(cache_buf_size_sel) //synopsys parallel_case full_case
2'b00: begin
pref_buf_addr0 = pref_buf_addr_tmp0[31:0];
pref_buf_addr1 = pref_buf_addr_tmp1[31:0];
pref_buf_addr2 = pref_buf_addr_tmp2[31:0];
pref_buf_addr3 = pref_buf_addr_tmp3[31:0];
end
2'b01: begin
pref_buf_addr0 = {pref_buf_addr_tmp0[31:1], 1'b0};
pref_buf_addr1 = {pref_buf_addr_tmp1[31:1], 1'b0};
pref_buf_addr2 = {pref_buf_addr_tmp2[31:1], 1'b0};
pref_buf_addr3 = {pref_buf_addr_tmp3[31:1], 1'b0};
end
2'b10: begin
pref_buf_addr0 = {pref_buf_addr_tmp0[31:2], 2'b0};
pref_buf_addr1 = {pref_buf_addr_tmp1[31:2], 2'b0};
pref_buf_addr2 = {pref_buf_addr_tmp2[31:2], 2'b0};
pref_buf_addr3 = {pref_buf_addr_tmp3[31:2], 2'b0};
end
2'b11: begin
pref_buf_addr0 = {pref_buf_addr_tmp0[31:3], 3'b0};
pref_buf_addr1 = {pref_buf_addr_tmp1[31:3], 3'b0};
pref_buf_addr2 = {pref_buf_addr_tmp2[31:3], 3'b0};
pref_buf_addr3 = {pref_buf_addr_tmp3[31:3], 3'b0};
end
default: begin
pref_buf_addr0 = pref_buf_addr_tmp0[31:0];
pref_buf_addr1 = pref_buf_addr_tmp1[31:0];
pref_buf_addr2 = pref_buf_addr_tmp2[31:0];
pref_buf_addr3 = pref_buf_addr_tmp3[31:0];
end
endcase
always @ (posedge clk)
if (reset)
pref_buf_addr_reg <= 128'b0;
else if (load_pref_buf)
pref_buf_addr_reg <= {pref_buf_addr3, pref_buf_addr2, pref_buf_addr1, pref_buf_addr0};
else
pref_buf_addr_reg <= pref_buf_addr_reg;
always @ (posedge clk)
if (reset)
pref_buf0_valid <= 1'b0;
else if (dma_reset)
pref_buf0_valid <= 1'b0;
else if (unload_pref_buf[0] | get_pkt_pref_buf & use_pref_buf[0])
pref_buf0_valid <= 1'b0;
else if (load_pref_buf)
pref_buf0_valid <= cache_rd_valid_bits[0];
else
pref_buf0_valid <= pref_buf0_valid;
always @ (posedge clk)
if (reset)
pref_buf1_valid <= 1'b0;
else if (dma_reset)
pref_buf1_valid <= 1'b0;
else if (unload_pref_buf[1] | get_pkt_pref_buf & use_pref_buf[1])
pref_buf1_valid <= 1'b0;
else if (load_pref_buf)
pref_buf1_valid <= cache_rd_valid_bits[1];
else
pref_buf1_valid <= pref_buf1_valid;
always @ (posedge clk)
if (reset)
pref_buf2_valid <= 1'b0;
else if (dma_reset)
pref_buf2_valid <= 1'b0;
else if (unload_pref_buf[2] | get_pkt_pref_buf & use_pref_buf[2])
pref_buf2_valid <= 1'b0;
else if (load_pref_buf)
pref_buf2_valid <= cache_rd_valid_bits[2];
else
pref_buf2_valid <= pref_buf2_valid;
always @ (posedge clk)
if (reset)
pref_buf3_valid <= 1'b0;
else if (dma_reset)
pref_buf3_valid <= 1'b0;
else if (unload_pref_buf[3] | get_pkt_pref_buf & use_pref_buf[3])
pref_buf3_valid <= 1'b0;
else if (load_pref_buf)
pref_buf3_valid <= cache_rd_valid_bits[3];
else
pref_buf3_valid <= pref_buf3_valid;
wire[3:0] pref_buf_valid_bits = {pref_buf3_valid, pref_buf2_valid, pref_buf1_valid, pref_buf0_valid};
wire pref_buf_valid = |pref_buf_valid_bits;
wire[31:0] muxed_pref_buf_addr = pref_buf0_valid ? pref_buf_addr_reg[31:0] :
pref_buf1_valid ? pref_buf_addr_reg[63:32] :
pref_buf2_valid ? pref_buf_addr_reg[95:64] :
pref_buf_addr_reg[127:96];
wire size_buf_req = size0_buf_req | size1_buf_req | size2_buf_req;
always @ (pref_buf_valid_bits)
begin
case (pref_buf_valid_bits) //synopsys parallel_case full_case
4'b0001, 4'b0010, 4'b0100, 4'b1000:
begin
is_last_pref_buf = 1'b1;
d_pref_buf_valid = 1'b0;
t_pref_buf_valid = 1'b0;
end
4'b0011, 4'b0110, 4'b1100:
begin
is_last_pref_buf = 1'b0;
d_pref_buf_valid = 1'b1;
t_pref_buf_valid = 1'b0;
end
4'b0111, 4'b1110:
begin
is_last_pref_buf = 1'b0;
d_pref_buf_valid = 1'b1;
t_pref_buf_valid = 1'b1;
end
4'b1111:
begin
is_last_pref_buf = 1'b0;
d_pref_buf_valid = 1'b1;
t_pref_buf_valid = 1'b1;
end
default:
begin
is_last_pref_buf = 1'b0;
d_pref_buf_valid = 1'b0;
t_pref_buf_valid = 1'b0;
end
endcase
end
always @ (pref_buf_valid_bits or size_buf_req or pkt_pref_buf_in_use)
begin
if (size_buf_req & !pkt_pref_buf_in_use)
begin
if (pref_buf_valid_bits[0])
unload_pref_buf = 4'b0001;
else if (pref_buf_valid_bits[1])
unload_pref_buf = 4'b0010;
else if (pref_buf_valid_bits[2])
unload_pref_buf = 4'b0100;
else if (pref_buf_valid_bits[3])
unload_pref_buf = 4'b1000;
else
unload_pref_buf = 4'b0000;
end
else
unload_pref_buf = 4'b0000;
end
wire cache_buf_rd_gnt_p = cache_buf_rd_gnt | cache_buf_rd_gnt_dly1 |
cache_buf_rd_gnt_dly2 | cache_buf_rd_gnt_dly3;
always @ (posedge clk)
if (reset)
cache_read_req <= 1'b0;
else if (dma_reset)
cache_read_req <= 1'b0;
else if (cache_buf_rd_gnt_p)
cache_read_req <= 1'b0;
else if (!cache_buf_empty & (is_last_pref_buf & (|unload_pref_buf) | !pref_buf_valid))
cache_read_req <= 1'b1;
else
cache_read_req <= cache_read_req;
/*********************************/
// size buffer manager
/*********************************/
reg[2:0] load_size_buf;
reg size0_buf_valid;
reg size1_buf_valid;
reg size2_buf_valid;
reg[7:0] curr_size0_buf_num;
reg[7:0] curr_size1_buf_num;
reg[7:0] curr_size2_buf_num;
reg[35:0] curr_size0_buf_addr_pre;
reg[35:0] curr_size1_buf_addr_pre;
reg[35:0] curr_size2_buf_addr_pre;
wire use_size0_buf;
wire use_size1_buf;
wire use_size2_buf;
wire is_last_size0_buf = sel_buf_enabled & use_size0_buf & (curr_size0_buf_num == 8'h01);
wire is_last_size1_buf = sel_buf_enabled & use_size1_buf & (curr_size1_buf_num == 8'h01);
wire is_last_size2_buf = sel_buf_enabled & use_size2_buf & (curr_size2_buf_num == 8'h01);
always @ (posedge clk)
if (reset)
size0_buf_valid <= 1'b0;
else if (dma_reset)
size0_buf_valid <= 1'b0;
else if (is_last_size0_buf)
size0_buf_valid <= 1'b0;
else if (load_size_buf[0])
size0_buf_valid <= 1'b1;
else
size0_buf_valid <= size0_buf_valid;
always @ (posedge clk)
if (reset)
size1_buf_valid <= 1'b0;
else if (dma_reset)
size1_buf_valid <= 1'b0;
else if (is_last_size1_buf)
size1_buf_valid <= 1'b0;
else if (load_size_buf[1])
size1_buf_valid <= 1'b1;
else
size1_buf_valid <= size1_buf_valid;
always @ (posedge clk)
if (reset)
size2_buf_valid <= 1'b0;
else if (dma_reset)
size2_buf_valid <= 1'b0;
else if (is_last_size2_buf)
size2_buf_valid <= 1'b0;
else if (load_size_buf[2])
size2_buf_valid <= 1'b1;
else
size2_buf_valid <= size2_buf_valid;
always @ (posedge clk)
if (reset)
curr_size0_buf_num <= 8'b0;
else if (dma_reset)
curr_size0_buf_num <= 8'b0;
else if (sel_buf_enabled & use_size0_buf)
curr_size0_buf_num <= curr_size0_buf_num - 8'h01;
else if (load_size_buf[0])
curr_size0_buf_num <= start_size0_buf_num;
else
curr_size0_buf_num <= curr_size0_buf_num;
always @ (posedge clk)
if (reset)
curr_size1_buf_num <= 8'b0;
else if (dma_reset)
curr_size1_buf_num <= 8'b0;
else if (sel_buf_enabled & use_size1_buf)
curr_size1_buf_num <= curr_size1_buf_num - 8'h01;
else if (load_size_buf[1])
curr_size1_buf_num <= start_size1_buf_num;
else
curr_size1_buf_num <= curr_size1_buf_num;
always @ (posedge clk)
if (reset)
curr_size2_buf_num <= 8'b0;
else if (dma_reset)
curr_size2_buf_num <= 8'b0;
else if (sel_buf_enabled & use_size2_buf)
curr_size2_buf_num <= curr_size2_buf_num - 8'h01;
else if (load_size_buf[2])
curr_size2_buf_num <= start_size2_buf_num;
else
curr_size2_buf_num <= curr_size2_buf_num;
wire[43:0] curr_size0_buf_addr = {curr_size0_buf_addr_pre[35:0], 8'b0};
wire[43:0] curr_size1_buf_addr = {curr_size1_buf_addr_pre[35:0], 8'b0};
wire[43:0] curr_size2_buf_addr = {curr_size2_buf_addr_pre[35:0], 8'b0};
wire[7:0] next_size0_buf_addr_tmp = curr_size0_buf_addr_pre[7:0] + size0_buf_size[15:8];
wire[35:0] next_size0_buf_addr = {curr_size0_buf_addr_pre[35:8], next_size0_buf_addr_tmp[7:0]};
wire[7:0] next_size1_buf_addr_tmp = curr_size1_buf_addr_pre[7:0] + size1_buf_size[15:8];
wire[35:0] next_size1_buf_addr = {curr_size1_buf_addr_pre[35:8], next_size1_buf_addr_tmp[7:0]};
wire[7:0] next_size2_buf_addr_tmp = curr_size2_buf_addr_pre[7:0] + size2_buf_size[15:8];
wire[35:0] next_size2_buf_addr = {curr_size2_buf_addr_pre[35:8], next_size2_buf_addr_tmp[7:0]};
always @ (posedge clk)
if (reset)
curr_size0_buf_addr_pre <= 36'b0;
else if (sel_buf_enabled & use_size0_buf)
curr_size0_buf_addr_pre <= next_size0_buf_addr;
else if (load_size_buf[0])
curr_size0_buf_addr_pre <= {muxed_pref_buf_addr, 4'b0};
else
curr_size0_buf_addr_pre <= curr_size0_buf_addr_pre;
always @ (posedge clk)
if (reset)
curr_size1_buf_addr_pre <= 36'b0;
else if (sel_buf_enabled & use_size1_buf)
curr_size1_buf_addr_pre <= next_size1_buf_addr;
else if (load_size_buf[1])
curr_size1_buf_addr_pre <= {muxed_pref_buf_addr, 4'b0};
else
curr_size1_buf_addr_pre <= curr_size1_buf_addr_pre;
always @ (posedge clk)
if (reset)
curr_size2_buf_addr_pre <= 36'b0;
else if (sel_buf_enabled & use_size2_buf)
curr_size2_buf_addr_pre <= next_size2_buf_addr;
else if (load_size_buf[2])
curr_size2_buf_addr_pre <= {muxed_pref_buf_addr, 4'b0};
else
curr_size2_buf_addr_pre <= curr_size2_buf_addr_pre;
/**************************************/
//req for loading new size buffer
/**************************************/
always @ (posedge clk)
if (reset)
size0_buf_req <= 1'b0;
else if (dma_reset)
size0_buf_req <= 1'b0;
else if (load_size_buf[0])
size0_buf_req <= 1'b0;
else if ((is_last_size0_buf | !size0_buf_valid) & size0_config_valid)
size0_buf_req <= 1'b1;
else
size0_buf_req <= size0_buf_req;
always @ (posedge clk)
if (reset)
size1_buf_req <= 1'b0;
else if (dma_reset)
size1_buf_req <= 1'b0;
else if (load_size_buf[1])
size1_buf_req <= 1'b0;
else if ((is_last_size1_buf | !size1_buf_valid) & size1_config_valid)
size1_buf_req <= 1'b1;
else
size1_buf_req <= size1_buf_req;
always @ (posedge clk)
if (reset)
size2_buf_req <= 1'b0;
else if (dma_reset)
size2_buf_req <= 1'b0;
else if (load_size_buf[2])
size2_buf_req <= 1'b0;
else if ((is_last_size2_buf | !size2_buf_valid) & size2_config_valid)
size2_buf_req <= 1'b1;
else
size2_buf_req <= size2_buf_req;
always @ (size0_buf_req or size1_buf_req or
size2_buf_req or pref_buf_valid or pkt_pref_buf_in_use)
begin
if (pref_buf_valid & !pkt_pref_buf_in_use)
begin
if (size2_buf_req)
load_size_buf = 3'b100;
else if (size1_buf_req)
load_size_buf = 3'b010;
else if (size0_buf_req)
load_size_buf = 3'b001;
else
load_size_buf = 3'b000;
end
else load_size_buf = 3'b000;
end
/***********************************************************/
//select proper buffer for incoming pkt
/***********************************************************/
reg chnl_sel_buf_en_r;
reg[7:0] pkt_hdr_byte_r;
reg[13:0] muxed_pkt_len_r;
reg[14:0] full_len_r;
reg[13:0] pkt_len_leftover;
reg[13:0] pkt_trans_len;
reg sel_size0_buf_r;
reg sel_size1_buf_r;
reg sel_size2_buf_r;
reg sel_1pref_buf_r;
reg sel_2pref_buf_r;
reg sel_3pref_buf_r;
reg sel_size_buf_r;
reg sel_size_buf_r1;
reg use_1pref_buf_r;
reg use_2pref_buf_r;
reg use_3pref_buf_r;
reg pkt_buf_gnt;
reg[43:0] buf_new_addr_r;
reg[35:0] buf_addr_r;
reg[1:0] pkt_buf_size;
reg[1:0] pref_buf_used_num_r;
reg jmb_pkt_in_process;
wire[7:0] pkt_hdr_byte = full_header ? (byte_offset + 8'd18) : (byte_offset + 8'd2);
wire[7:0] pkt_hdr_byte1 = full_header ? 8'd18 : 8'd2;
wire[14:0] full_len1 = {1'b0, muxed_pkt_len[13:0]};
wire[14:0] full_len2 = {7'b0, pkt_hdr_byte_r[7:0]};
wire[14:0] full_len = full_len1 + full_len2; //include offset
wire[13:0] real_len = muxed_pkt_len_r[13:0] + {6'b0, pkt_hdr_byte1[7:0]}; //not include offset
wire pkt_len_overflow= full_len_r[14];
wire sel_size0_buf = (size0_buf_size[13:0] >= full_len_r[13:0]);
wire sel_size1_buf = (size1_buf_size[13:0] >= full_len_r[13:0]);
wire sel_size2_buf = (size2_buf_size[14:0] >= {1'b0, full_len_r[13:0]});
wire sel_1pref_buf = (cache_buf_size[15:0] >= {2'b0, full_len_r[13:0]});
wire sel_2pref_buf = (cache_buf_size2[15:0]>= {2'b0, full_len_r[13:0]});
wire sel_3pref_buf = (cache_buf_size3[16:0]>= {3'b0, full_len_r[13:0]});
wire[35:0] orig_buf_addr = buf_addr_r[35:0];
wire get_next_buf;
wire get_last_buf;
always @ (posedge clk)
if (reset)
pkt_hdr_byte_r <= 8'b0;
else
pkt_hdr_byte_r <= pkt_hdr_byte;
always @ (posedge clk)
if (reset)
muxed_pkt_len_r <= 14'b0;
else
muxed_pkt_len_r <= muxed_pkt_len[13:0];
always @ (posedge clk)
if (reset)
full_len_r <= 15'b0;
else
full_len_r <= full_len;
always @ (posedge clk)
if (reset)
pkt_len_leftover <= 14'b0;
else if (sel_buf_en_r)
pkt_len_leftover <= full_len_r[13:0] - cache_buf_size[13:0];
else if (get_next_buf)
pkt_len_leftover <= pkt_len_leftover - cache_buf_size1[13:0];
else
pkt_len_leftover <= pkt_len_leftover;
always @ (posedge clk)
if (reset)
sel_size0_buf_r <= 1'b0;
else
sel_size0_buf_r <= sel_size0_buf;
always @ (posedge clk)
if (reset)
sel_size1_buf_r <= 1'b0;
else
sel_size1_buf_r <= sel_size1_buf;
always @ (posedge clk)
if (reset)
sel_size2_buf_r <= 1'b0;
else
sel_size2_buf_r <= sel_size2_buf;
always @ (posedge clk)
if (reset)
begin
sel_size_buf_r <= 1'b0;
sel_size_buf_r1 <= 1'b0;
end
else
begin
sel_size_buf_r <= (sel_size0_buf | sel_size1_buf | sel_size2_buf);
sel_size_buf_r1 <= sel_size_buf_r;
end
always @ (posedge clk)
if (reset)
sel_1pref_buf_r <= 1'b0;
else
sel_1pref_buf_r <= sel_1pref_buf;
always @ (posedge clk)
if (reset)
sel_2pref_buf_r <= 1'b0;
else
sel_2pref_buf_r <= sel_2pref_buf & !sel_1pref_buf;
always @ (posedge clk)
if (reset)
sel_3pref_buf_r <= 1'b0;
else
sel_3pref_buf_r <= sel_3pref_buf & !(sel_1pref_buf | sel_2pref_buf);
assign use_size0_buf = sel_size0_buf_r & size0_buf_valid;
wire use_size1_buf_tmp = sel_size1_buf_r & size1_buf_valid;
wire use_size2_buf_tmp = sel_size2_buf_r & size2_buf_valid;
assign use_size1_buf = !use_size0_buf & use_size1_buf_tmp;
assign use_size2_buf = !(use_size0_buf | use_size1_buf_tmp) & use_size2_buf_tmp;
wire use_1pref_buf = !sel_size_buf_r & sel_1pref_buf_r & pref_buf_valid;
wire use_2pref_buf = !sel_size_buf_r & sel_2pref_buf_r & (d_pref_buf_valid | pref_buf_valid & !cache_buf_empty);
wire use_3pref_buf = !sel_size_buf_r & sel_3pref_buf_r & (pref_buf_valid & (|cache_buf_cnt[7:1]) |
d_pref_buf_valid & !cache_buf_empty |
t_pref_buf_valid);
wire is_use_pref_buf = (use_1pref_buf | use_2pref_buf | use_3pref_buf) & !pkt_len_overflow;
wire is_use_size_buf = (use_size0_buf | use_size1_buf | use_size2_buf) & !pkt_len_overflow;
wire buf_gnt = (is_use_pref_buf | is_use_size_buf);
wire[1:0] buf_size_in = use_size0_buf ? 2'b00 :
use_size1_buf ? 2'b01 :
use_size2_buf ? 2'b10 :
2'b11;
always @ (posedge clk)
if (reset)
pkt_buf_gnt <= 1'b0;
else if (dma_reset)
pkt_buf_gnt <= 1'b0;
else if (sel_buf_enabled_tmp & !buf_addr_not_valid)
pkt_buf_gnt <= buf_gnt;
else if (pkt_buf_done)
pkt_buf_gnt <= 1'b0;
else
pkt_buf_gnt <= pkt_buf_gnt;
always @ (posedge clk)
if (reset)
pkt_buf_size <= 2'b0;
else if (sel_buf_en_r)
pkt_buf_size <= buf_size_in;
else
pkt_buf_size <= pkt_buf_size;
assign rbr_drop_pkt = !buf_gnt;
assign rcr_drop_pkt = !((sel_size_buf_r | sel_1pref_buf_r) & shadow_not_empty | shadow_not_e_empty);
/*******************************/
//Calculate pkt transfer len
/*******************************/
wire chnl_pkt_cnt_done = pkt_req_cnt_e_done_mod & (muxed_rdc_num_r == dma_chnl_grp_id);
wire jmb_pkt_mode = !(sel_size_buf_r | use_1pref_buf);
wire[1:0] pref_buf_used_num = (sel_size_buf_r1 | use_1pref_buf_r) ? 2'b01 :
use_2pref_buf_r ? 2'b10 :
use_3pref_buf_r ? 2'b11 : 2'b00;
assign get_next_buf = chnl_pkt_cnt_done & is_hdr_wr_data & (&pref_buf_used_num_r);
assign get_last_buf = chnl_pkt_cnt_done & (is_hdr_wr_data & (pref_buf_used_num_r == 2'b10) |
is_jmb1_wr_data & (pref_buf_used_num_r == 2'b11));
wire[13:0] pkt_len_tmp = (jmb_pkt_mode & sel_buf_en_r) ? cache_buf_size1[13:0]:
sel_buf_en_r ? real_len[13:0] :
get_next_buf ? cache_buf_size1[13:0] : pkt_len_leftover;
always @ (posedge clk)
if (reset)
begin
use_1pref_buf_r <= 1'b0;
use_2pref_buf_r <= 1'b0;
use_3pref_buf_r <= 1'b0;
end
else if (sel_buf_en_r)
begin
use_1pref_buf_r <= use_1pref_buf;
use_2pref_buf_r <= use_2pref_buf;
use_3pref_buf_r <= use_3pref_buf;
end
always @ (posedge clk)
if (reset)
chnl_sel_buf_en_r <= 1'b0;
else if (dma_reset)
chnl_sel_buf_en_r <= 1'b0;
else
chnl_sel_buf_en_r <= sel_buf_enabled;
always @ (posedge clk)
if (reset)
pref_buf_used_num_r <= 2'b0;
else if (chnl_sel_buf_en_r)
pref_buf_used_num_r <= pref_buf_used_num;
else
pref_buf_used_num_r <= pref_buf_used_num_r;
always @ (posedge clk)
if (reset)
pkt_trans_len <= 14'b0;
else if (sel_buf_en_r | get_next_buf | get_last_buf)
pkt_trans_len <= pkt_len_tmp;
else
pkt_trans_len <= pkt_trans_len;
/*******************************/
//Calculate pkt transfer addr
/*******************************/
assign get_pkt_pref_buf = sel_buf_enabled_tmp & is_use_pref_buf | get_next_buf | get_last_buf;
assign pkt_pref_buf_in_use = chnl_sel_buf_en | jmb_pkt_in_process;
wire[43:0] buf_addr_tmp1= {44{use_size0_buf}} & curr_size0_buf_addr |
{44{use_size1_buf}} & curr_size1_buf_addr |
{44{use_size2_buf}} & curr_size2_buf_addr ;
wire[43:0] buf_addr_tmp2= is_use_size_buf & sel_buf_en_r ? buf_addr_tmp1 : {muxed_pref_buf_addr, 12'b0};
wire[43:0] buf_addr = (dma_data_offset[1:0] == 2'b01) ? {buf_addr_tmp2[43:8], 8'b0100_0000} :
(dma_data_offset[1:0] == 2'b10) ? {buf_addr_tmp2[43:8], 8'b1000_0000} :
buf_addr_tmp2[43:0];
wire buf_addr_valid0 = ((buf_addr[43:12] & addr_mask0) == (comp_value0 & addr_mask0)) & page_valid0;
wire buf_addr_valid1 = ((buf_addr[43:12] & addr_mask1) == (comp_value1 & addr_mask1)) & page_valid1;
assign buf_addr_not_valid = !(buf_addr_valid0 | buf_addr_valid1) & buf_gnt & chnl_sel_buf_en & dma_en;
wire[31:0] buf_relo_addr0 = (buf_addr[43:12] & ~addr_mask0) | (relo_value0 & addr_mask0);
wire[31:0] buf_relo_addr1 = (buf_addr[43:12] & ~addr_mask1) | (relo_value1 & addr_mask1);
wire[31:0] buf_relo_addr = buf_addr_valid0 ? buf_relo_addr0 : buf_relo_addr1;
wire[43:0] buf_new_addr = {buf_relo_addr, buf_addr[11:0]};
wire[63:0] pkt_buf_addr = {page_handle[19:0], buf_new_addr_r[43:0]};
always @ (pref_buf_valid_bits)
begin
if (pref_buf_valid_bits[0])
use_pref_buf = 4'b0001;
else if (pref_buf_valid_bits[1])
use_pref_buf = 4'b0010;
else if (pref_buf_valid_bits[2])
use_pref_buf = 4'b0100;
else if (pref_buf_valid_bits[3])
use_pref_buf = 4'b1000;
else
use_pref_buf = 4'b0000;
end
always @ (posedge clk)
if (reset)
jmb_pkt_in_process <= 1'b0;
else if (dma_reset)
jmb_pkt_in_process <= 1'b0;
else if (sel_buf_enabled_tmp & (use_2pref_buf | use_3pref_buf))
jmb_pkt_in_process <= 1'b1;
else if (get_last_buf)
jmb_pkt_in_process <= 1'b0;
else
jmb_pkt_in_process <= jmb_pkt_in_process;
always @ (posedge clk)
if (reset)
buf_new_addr_r <= 44'b0;
else if (sel_buf_en_r | get_next_buf | get_last_buf)
buf_new_addr_r <= buf_new_addr;
else
buf_new_addr_r <= buf_new_addr_r;
always @ (posedge clk)
if (reset)
buf_addr_r <= 36'b0;
else if (sel_buf_en_r | get_next_buf | get_last_buf)
buf_addr_r <= buf_addr[43:8];
else
buf_addr_r <= buf_addr_r;
/*************************/
//Weighted RED
/*************************/
reg[15:0] wred_v2_tmp;
reg[16:0] wred_v1;
reg[15:0] wred_v2;
wire[11:0] muxed_wred_thresh = muxed_s_event_r ? wred_thresh_syn : wred_thresh;
wire[3:0] muxed_wred_window = muxed_s_event_r ? wred_window_syn : wred_window;
wire[16:0] wred_v1_tmp = {1'b0, rcr_curr_qlen[15:0]} - {5'b0, muxed_wred_thresh[11:0]};
//wire[15:0] wred_v2_msb = wred_v2_tmp[31:16];
//wire wred_v3_tmp = (wred_v2[15:0] < wred_v1[15:0]) & !wred_v1[16]; //drop pkt when cross (THRSH + WIN);
wire wred_v3_tmp = ((wred_v2[15:0] < wred_v1[15:0]) | (wred_v2[15:0] == wred_v1[15:0])) & !wred_v1[16]; //drop pkt when hit threshold
always @ (muxed_wred_window or random_num)
begin
case (muxed_wred_window) //synopsys parallel_case full_case
/*
4'd0: wred_v2_tmp = {16'b0, random_num};
4'd1: wred_v2_tmp = {15'b0, random_num, 1'b0};
4'd2: wred_v2_tmp = {14'b0, random_num, 2'b0};
4'd3: wred_v2_tmp = {13'b0, random_num, 3'b0};
4'd4: wred_v2_tmp = {12'b0, random_num, 4'b0};
4'd5: wred_v2_tmp = {11'b0, random_num, 5'b0};
4'd6: wred_v2_tmp = {10'b0, random_num, 6'b0};
4'd7: wred_v2_tmp = {9'b0, random_num, 7'b0};
4'd8: wred_v2_tmp = {8'b0, random_num, 8'b0};
4'd9: wred_v2_tmp = {7'b0, random_num, 9'b0};
4'd10: wred_v2_tmp = {6'b0, random_num, 10'b0};
4'd11: wred_v2_tmp = {5'b0, random_num, 11'b0};
4'd12: wred_v2_tmp = {4'b0, random_num, 12'b0};
4'd13: wred_v2_tmp = {3'b0, random_num, 13'b0};
4'd14: wred_v2_tmp = {2'b0, random_num, 14'b0};
4'd15: wred_v2_tmp = {1'b0, random_num, 15'b0};
*/
4'd0: wred_v2_tmp = 16'b0;
4'd1: wred_v2_tmp = {15'b0, random_num[15]};
4'd2: wred_v2_tmp = {14'b0, random_num[15:14]};
4'd3: wred_v2_tmp = {13'b0, random_num[15:13]};
4'd4: wred_v2_tmp = {12'b0, random_num[15:12]};
4'd5: wred_v2_tmp = {11'b0, random_num[15:11]};
4'd6: wred_v2_tmp = {10'b0, random_num[15:10]};
4'd7: wred_v2_tmp = {9'b0, random_num[15:9]};
4'd8: wred_v2_tmp = {8'b0, random_num[15:8]};
4'd9: wred_v2_tmp = {7'b0, random_num[15:7]};
4'd10: wred_v2_tmp = {6'b0, random_num[15:6]};
4'd11: wred_v2_tmp = {5'b0, random_num[15:5]};
4'd12: wred_v2_tmp = {4'b0, random_num[15:4]};
4'd13: wred_v2_tmp = {3'b0, random_num[15:3]};
4'd14: wred_v2_tmp = {2'b0, random_num[15:2]};
4'd15: wred_v2_tmp = {1'b0, random_num[15:1]};
endcase
end
always @ (posedge clk)
if (reset)
begin
wred_v1 <= 17'b0;
wred_v2 <= 16'b0;
end
else
begin
wred_v1 <= wred_v1_tmp[16:0];
wred_v2 <= wred_v2_tmp[15:0];
end
always @ (posedge clk)
if (reset)
wred_drop_pkt <= 1'b0;
else if (dma_reset)
wred_drop_pkt <= 1'b0;
else if (!wred_enable)
wred_drop_pkt <= 1'b0;
else if (sel_buf_en)
wred_drop_pkt <= wred_v3_tmp;
else
wred_drop_pkt <= 1'b0;
endmodule