fpga_feixiang 发表于 2020-12-30 13:48:39

gerif_cpuctrl

// $Id: gerif_cpuctrl.v,v 1.1 2015-02-11 12:51:21+08Exp $
//=============================================================================
//
//
// Filename         : gerif_cpuctrl.v
// Created On         : 2010-08-31 16:58
// Last Modified      : 2011-10-11 17:57
// Description      :
//                     
//                     
//=============================================================================

module gerif_cpuctrl (        //系统接口   system interface.
                        sys_clk,                        //<<I
                        sys_rst,                        //<<I       
                        system_en,                      //<<I

                        //GEMAC的接口                interface with GEMAC.
                        gmac_data_gectrl,               //<<I
                        gmac_vld_1_0_gectrl,            //<<I
                        gmac_byte_sel_gectrl,         //<<I
                        gmac_crc_err_gectrl,            //<<I
                        gmac_fifo_over_gectrl,          //<<I
                        gectrl_rd_ack_gmac,             //>>O

                        //RXFIFO的接口                        interface with RXFIFO.
                        gectrl_wr_en_rxfifo,            //>>O
                        gectrl_wr_data_rxfifo,          //>>O
                        rxfifo_full_gectrl,             //<<I

                        //CIFIFO的接口                        interface with CIFIFO.
                        gectrl_wr_en_cififo,            //>>O
                        gectrl_cell_eof_cififo,         //>>O
                        gectrl_cell_info_cififo,      //>>O

                        //探针PROBE接口interface with PROBE.
                        prb_mtchvld_gectrl,             //<<I
                        prb_info_gectrl,                //<<I
                        gectrl_rd_ack_prb,            //>>O

                        //cc的接口                interface with CC.
                        reg_gport_vlan_tag,             //<<I
                        reg_gport_remap_pri,            //<<I
                        reg_max_length_gport,         //<<I      
                        reg_min_length_gport,         //<<I
                        reg_cell_length_sel             //<<I
                  );
                       
//系统参数        System Parameter
parameter        D = 2;
parameter        RST = 1'b0;

                       
//用于FRAME_LEN_CTRL子模块for the FRAME_LEN_CTRL sub-module.
parameter        IN_DATA_WIDTH= 32;       //定义输入数据总线的宽度                define the input data bus width.
parameter        OUT_DATA_WIDTH = 128;      //定义输出数据总线的宽度                define the output data bus width.
parameter        CELL_WIDTH   = 36;       //定义单元格信息总线宽度                define cell info bus width.
parameter        PRB_INFO_WIDTH = 32;       //定义单元格信息总线宽度                define cell info bus width.
parameter        VLAN_INFO_WIDTH= 15;                   //虚拟局域网信息宽度                                        vlan info width.
parameter        MAX_FRAME_WIDTH= 14;       //最大帧长宽度                                        the max frame length width.
parameter        MIN_FRAME_WIDTH= 7;                          //最小帧长宽度                                        the min frame length width.
parameter        FRAME_LEN_WIDTH= 14;                          //最小帧长宽度                                        the min frame length width.

//用于CELL_GEN_CTRL子模块                for the CELL_GEN_CTRL sub-module.
parameter        NO_ERR          = 2'b00;
parameter        CRC_ERR          = 2'b00;
parameter        MAX_ERR          = 2'b01;
parameter        MIN_ERR          = 2'b10;
parameter        FIFO_ERR    = 2'b11;

//系统接口信号定义                system interface signal define.
input                                sys_clk;
input                                sys_rst;
input                                system_en;

input                reg_gport_vlan_tag;   //port default vlan tag.
input                                reg_gport_remap_pri;//port remap 802.1p or not.
input                reg_max_length_gport; //the max frame length.
input                reg_min_length_gport; //the min frame length.
input                                reg_cell_length_sel;


//用GMAC定义接口信号                        define the interface signal with GMAC.
input                gmac_data_gectrl;
input                                gmac_vld_1_0_gectrl;
input                                gmac_byte_sel_gectrl;
input                                gmac_crc_err_gectrl;
input                                gmac_fifo_over_gectrl;

output                                gectrl_rd_ack_gmac;

//使用RXFIFO定义接口信号                define the interface signal with RXFIFO.
input                                rxfifo_full_gectrl;
output                                gectrl_wr_en_rxfifo;
output                gectrl_wr_data_rxfifo;

//使用CIFIFO定义接口信号                define the interface signal with CIFIFO.
output                                gectrl_wr_en_cififo;
output                                gectrl_cell_eof_cififo;
output                gectrl_cell_info_cififo;

//使用PROBE定义接口信号                define the interface signal with PROBE.
input                                prb_mtchvld_gectrl;
input                prb_info_gectrl;

output                                gectrl_rd_ack_prb;


//将输出信号定义为寄存器类型                define the output singal as register type.
wire                                gectrl_rd_ack_gmac;
reg                                gectrl_wr_en_rxfifo;
reg                gectrl_wr_data_rxfifo;
wire                                gectrl_wr_en_cififo_reg;
reg                                gectrl_cell_eof_cififo;
reg                gectrl_cell_info_cififo;
wire                                gectrl_rd_ack_prb;


//定义内部寄存器子模块和子模块                        define inner register sub-module and sub-module.
// RV_DATA_CTRL ->FRAME_LEN_CTRL
reg                gmac_data_gectrl_f1;                               
reg                                gmac_data_vld_gectrl_f1;
reg                                gmac_byte_sel_gectrl_f1;
reg                                gmac_sof_gectrl_f1;
reg                                gmac_eof_gectrl_f1;
reg                                gmac_crc_err_gectrl_f1;
reg                                gmac_fifo_over_gectrl_f1;

//FRAME_LEN_CTRL -> CELL_GEN_CTRL
reg                gectrl_frame_len_inner;
reg                gectrl_frame_row_inner;// likethe len count, but is a row count
reg                                gectrl_err_stat_inner;
wire                        gectrl_tag_info_inner;   
reg                                gectrl_max_frame_inner;
reg                                gectrl_min_frame_inner;

reg                reg_max_len_add4_ge; //the max frame length.
reg                reg_min_len_add4_ge; //the min frame length.

//FRAME_LEN_CTRL -> WR_FIFO_CTRL
reg                gmac_data_gectrl_f2;               
reg                                gmac_data_vld_gectrl_f2;      
reg                                gmac_eof_gectrl_f2;            

//CELL_GEN_CTRL -> WR_CELL_CTRL
reg                                gectrl_cell_vld_inner;
wire                                gectrl_rd_ack_cell;

reg            gectrl_wr_en_cififo;
reg            gectrl_wr_en_rxfifo_pre;

//**********************************************************************************
//                Delay system_en register 延时寄存器
//**********************************************************************************
//编译指示保护                pragma protect
//编译指示保护开始                pragma protect begin

//****************************************************************************
//                        Public Assign wires        公共分配线
//****************************************************************************
reg        /**/        gectrl_flen_inner;
reg                                gectrl_sof_inner;
reg                                gectrl_eof_inner;
reg                                gectrl_pvid_inner;        //默认端口虚拟网络标签                default port vlan tag.
reg                                gectrl_tagged_inner;
reg                                gectrl_drop_inner;
reg                                gectrl_drop_code_inner;
wire        /**/        gectrl_cell_info_inner;

assign   gectrl_cell_info_inner = {gectrl_flen_inner,
                                   1'b0,
                                   gectrl_sof_inner,
                                   gectrl_eof_inner,
                                   gectrl_pvid_inner,
                                   gectrl_tagged_inner,
                                   gectrl_drop_inner,
                                   gectrl_drop_code_inner};

//******************************************************************************
// frame cell information bit table.       
//        dctrl_cell_info_cctrl        = "gecell_frame_length";
//        dctrl_cell_info_cctrl        = "gecell_SOF";
//        dctrl_cell_info_cctrl        = "gecell_EOF";
//        dctrl_cell_info_cctrl        = "gecell_PVID";
//        dctrl_cell_info_cctrl        = "gecell_tag_info";
//        dctrl_cell_info_cctrl        = "gecell_drop_valid";
//        dctrl_cell_info_cctrl        = "gecell_drop_reason";
//******************************************************************************


//******************************************************************************
//                       子模块   Sub-module:         RV_DATA_CTRL
//                       Function:
//                               1.接收来自GEMAC的数据       Receive the data from GEMAC.
//******************************************************************************

//******************************************************************************
//:gmac_data_vld_gectrl:    ..11111.............111.......11111........    <<I
//:gmac_data_gectrl:      ..AAAAA.............BBB.......CCCCC........    <<I
//:gectrl_rd_ctrl_inner:    .1...1...1...1...1...1...1...1...1...1...1.    >>O
//:gectrl_rd_ack_gmac:      ......1...............1...........1........    >>O
//:gmac_data_vld_gectrl_f1: ......1...............1...........1........    >>O
//:gmac_data_gectrl_f1:   ......A...............B...........C........    >>O
//
//Read the data from GMAC: gmac_data_vld_gectrl_f1;
//从GMAC读取数据: gmac_data_vld_gectrl_f1gmac_data_gectrl_f1;
//******************************************************************************

////------------------------------------------------------------------------------
////*                     Usage:                 125MHz.
////*                  inner signal:        gectrl_rd_ctrl_inner         
////------------------------------------------------------------------------------
//wire                gectrl_rd_ctrl_inner;
//reg                gectrl_rd_cnt;
//
////generate the plus for ...1...1...1...1..
//always @(posedge sys_clk or negedge sys_rst) begin
//   if(sys_rst==RST)
//           gectrl_rd_cnt <= #D 4'b0001;
//   else
//           gectrl_rd_cnt <= #D {gectrl_rd_cnt,gectrl_rd_cnt};
//end
//
//assign        gectrl_rd_ctrl_inner = gectrl_rd_cnt;
       
//------------------------------------------------------------------------------
//*                     Usage:                 100MHz.
//*                  inner signal:        gectrl_rd_ctrl_inner         
//------------------------------------------------------------------------------
wire                gectrl_rd_ctrl_inner;
reg                gectrl_rd_cnt;

//generate the plus for ...1...1...1...1..
always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                   gectrl_rd_cnt <= #D 2'b01;
        else if(system_en==1'b0)
                   gectrl_rd_cnt <= #D 2'b01;
        else
                   gectrl_rd_cnt <= #D {gectrl_rd_cnt,gectrl_rd_cnt};
end

assign        gectrl_rd_ctrl_inner = gectrl_rd_cnt;//相当于做了个分频
       

//******************************************************************************
//**                  信号signal:        gectrl_rd_ack_gmac            
//******************************************************************************
reg gectrl_rd_ack_1allow; // 允许ack为1 allow ack to 1
// assign gectrl_rd_ack_gmac = gmac_data_vld_gectrl_f1;// gchen change
assign        gectrl_rd_ack_gmac = (rxfifo_full_gectrl)? 1'b0:

                        (gectrl_rd_ctrl_inner && gmac_vld_1_0_gectrl!=2'b0) ?
                       
                        (( gmac_vld_1_0_gectrl==2'b1 ) ? gectrl_rd_ack_1allow : 1'b1 ) :1'b0;// gchen 080121 add one more cycle for 1, maybe 2 or 3 cycle ack to 1   为1增加一个循环,可能为1增加2或3个循环ack

always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                   gectrl_rd_ack_1allow <= #D 1'b0;
        else
                   gectrl_rd_ack_1allow <= #D ( gmac_vld_1_0_gectrl==2'b1 ) && (gectrl_rd_ctrl_inner == 1'b0) ;
end

//always@(posedge sys_clk or negedge sys_rst) begin
//   if(sys_rst == RST)
//           gectrl_rd_ack_gmac <= #D 1'b0;
//   else
//           gectrl_rd_ack_gmac <= #D (rxfifo_full_gectrl)? 1'b0:
//                                 (gectrl_rd_ctrl_inner && gmac_vld_1_0_gectrl!=2'b0)? 1'b1:1'b0;
//end

//******************************************************************************
//**                  signal:        gmac_data_gectrl_f1;             
//**                  signal:        gmac_data_vld_gectrl_f1;      
//**                  signal:        gmac_byte_sel_gectrl_f1;      
//**                  signal:        gmac_sof_gectrl_f1;            
//**                  signal:        gmac_eof_gectrl_f1;            
//**                  signal:        gmac_crc_err_gectrl_f1;      
//**                  signal:        gmac_fifo_over_gectrl_f1;      
//******************************************************************************
//-------------------------------------------------------------------
//                Remap 802.1p
//-------------------------------------------------------------------
reg                        gmac_sof_flag_tmp;

always@(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst == RST)
                   gmac_data_vld_gectrl_f1 <= #D 1'b0;
        else if(system_en==1'b0)
                   gmac_data_vld_gectrl_f1 <= #D 1'b0;
        else
                   gmac_data_vld_gectrl_f1 <= #D gectrl_rd_ack_gmac ;
// gchen 101112                            (rxfifo_full_gectrl)? 1'b0:
// gchen 101112                         (gectrl_rd_ctrl_inner && gmac_vld_1_0_gectrl!=2'b0)? 1'b1:1'b0;
end


always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                gmac_data_gectrl_f1 <= #D 32'h0;
           else
                gmac_data_gectrl_f1 <= #D gmac_data_gectrl;          
end
//与gmac_data_gectrl延迟了4

always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                gmac_sof_flag_tmp <= #D 1'b1;
        else if(gectrl_rd_ctrl_inner && !rxfifo_full_gectrl)
                gmac_sof_flag_tmp <= #D        (gmac_vld_1_0_gectrl==2'b10)? ~gmac_sof_flag_tmp:
          //gchen 101112         (gmac_vld_1_0_gectrl!=2'b0)? 1'b0 : gmac_sof_flag_tmp;
                                               ((gmac_vld_1_0_gectrl==2'b01) && gectrl_rd_ack_gmac) ? 1'b0 : gmac_sof_flag_tmp;
end


always@(posedge sys_clk or negedge sys_rst) begin
   if(sys_rst==RST) begin
      gmac_byte_sel_gectrl_f1<= #D 2'b0;
      gmac_sof_gectrl_f1       <= #D 1'b0;
      gmac_eof_gectrl_f1       <= #D 1'b0;
      gmac_crc_err_gectrl_f1   <= #D 1'b0;
      gmac_fifo_over_gectrl_f1 <= #D 1'b0;
   end
   else begin
        gmac_byte_sel_gectrl_f1<= #D gmac_byte_sel_gectrl;
        // gchen 101112 gmac_sof_gectrl_f1       <= #D (gmac_vld_1_0_gectrl!=2'b0 &&
        // gchen 101112                                 gectrl_rd_ctrl_inner &&
        // gchen 101112                              !rxfifo_full_gectrl)? gmac_sof_flag_tmp:1'b0;      
        gmac_sof_gectrl_f1       <= #Dgectrl_rd_ack_gmac ? gmac_sof_flag_tmp:1'b0;

        gmac_eof_gectrl_f1       <= #D (gmac_vld_1_0_gectrl==2'b10 &&
                                        gectrl_rd_ctrl_inner &&
                                     !rxfifo_full_gectrl)? ~gmac_sof_flag_tmp:1'b0;      
        gmac_crc_err_gectrl_f1   <= #D gmac_crc_err_gectrl;
        gmac_fifo_over_gectrl_f1 <= #D gmac_fifo_over_gectrl;
   end
end

//******************************************************************************
//                          Sub-module:         FRAME_LEN_CTRL
//                       Function:
//          1. 数帧长度。                   1. Count Frame Length.
//               2。VLAN标记检查。                         2. VLAN TAG Checking.
//                      3。最大帧长度检查。                         3. MAX Frame length checking.
//                      4。最小帧长校验,        4. MIN Frame length checking,
//******************************************************************************

//******************************************************************************
//:gmac_data_vld_gectrl_f1: ......1.....1.....1.....1.....1......1.....    <<I
//:gmac_sof_gectrl_f1:      ......1..............................1.....    <<I
//:gmac_eof_gectrl_f1:      ..............................1............    <<I
//:gmac_data_gectrl_f1:   ......A.....B.....C.....D.....E......F.....    <<I
//:gectrl_frame_len_inner:.......LLLLLLMMMMMMNNNNNNOOOOOOPPPPPPPQQQQQ    >>O
//:gectrl_err_stat_inner:   ...............................E...........    >>O
//:gectrl_tag_info_inner:   .........................1111111111111.....    >>O
//:gectrl_max_frame_inner:...............................1...........    >>O
//:gectrl_min_frame_inner:...............................1...........    >>O
//:gmac_data_vld_gectrl_f2: .......1.....1.....1.....1.....1......1....    >>O
//:gmac_eof_gectrl_f2:      ...............................1...........    >>O
//:gmac_data_gectrl_f2:   .......A.....B.....C.....D.....E......F....    >>O
//
//Generate the cell and frame info;
//             
//******************************************************************************

//******************************************************************************
//**                     signal name: gectrl_frame_len_inner;
//******************************************************************************
always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST) begin
                gectrl_frame_row_inner <= #D 14'h0;
                gectrl_frame_len_inner <= #D 14'h0;
        end
        else if(gmac_data_vld_gectrl_f1 && gmac_sof_gectrl_f1) begin
                gectrl_frame_row_inner <= #D 14'h4;
                gectrl_frame_len_inner <= #D 14'h4;
        end
        else if(gmac_data_vld_gectrl_f1 && !gmac_sof_gectrl_f1
                && !gmac_eof_gectrl_f1 ) begin
                gectrl_frame_row_inner <= #D gectrl_frame_row_inner +4;
                gectrl_frame_len_inner <= #D gectrl_frame_len_inner +4;
        end
        else if(gmac_data_vld_gectrl_f1 && gmac_eof_gectrl_f1) begin
                gectrl_frame_len_inner <= #D gectrl_frame_len_inner + gmac_byte_sel_gectrl_f1+1;
                gectrl_frame_row_inner <= #D gectrl_frame_row_inner + 4;
        end
end

//******************************************************************************
//**                     signal name: gectrl_tag_info_inner;
//******************************************************************************
assign        gectrl_tag_info_inner = 1'b1;

//******************************************************************************
//**                     signal name: gectrl_max_frame_inner;
//**                     signal name: gectrl_min_frame_inner;
//******************************************************************************

always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST) begin
                reg_max_len_add4_ge <= #D 15'h0;
                reg_min_len_add4_ge <= #D 14'h0;
        end
        else begin
                reg_max_len_add4_ge <= #D (reg_max_length_gport==0)? 15'h0: {1'b0,reg_max_length_gport}-15'h4 ;
                reg_min_len_add4_ge <= #D (reg_min_length_gport==0)? 14'h0: {7'h0,reg_min_length_gport}-14'h4 ;
        end
end

always @(gmac_data_vld_gectrl_f2 or gmac_eof_gectrl_f2 or gectrl_frame_len_inner
        or reg_max_len_add4_ge)
        gectrl_max_frame_inner = (gectrl_frame_len_inner>reg_max_len_add4_ge)?
                               (gmac_data_vld_gectrl_f2 & gmac_eof_gectrl_f2):0;

always @(gmac_data_vld_gectrl_f2 or gmac_eof_gectrl_f2 or gectrl_frame_len_inner
        or reg_min_len_add4_ge)
        gectrl_min_frame_inner = (gectrl_frame_len_inner<reg_min_len_add4_ge)?
                               (gmac_data_vld_gectrl_f2 & gmac_eof_gectrl_f2):0;


//******************************************************************************
//**                     signal name: gmac_data_vld_gectrl_f2;
//**                     signal name: gmac_data_gectrl_f2;      
//**                     signal name: gmac_eof_gectrl_f2;      
//**                     signal name: gmac_err_stat_gectrl;
//******************************************************************************
always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                gmac_data_vld_gectrl_f2 <= #D 1'b0;
        else
                gmac_data_vld_gectrl_f2 <= #D gmac_data_vld_gectrl_f1;
end

always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                gmac_data_gectrl_f2 <= #D 32'h0;
        else if(gmac_data_vld_gectrl_f1)
                gmac_data_gectrl_f2 <= #D gmac_data_gectrl_f1;
end

always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                gmac_eof_gectrl_f2 <= #D 1'b0;
        else
                gmac_eof_gectrl_f2 <= #D gmac_eof_gectrl_f1;
end

always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                gectrl_err_stat_inner <= #D 2'b0;
        else
                gectrl_err_stat_inner <= #D {gmac_fifo_over_gectrl_f1,
                                           gmac_crc_err_gectrl_f1};
end





//******************************************************************************
//                          Sub-module:         WR_FIFO_CTRL
//                       Function:
//                               1. 32 bits data translate to 64 bits data.
//                               2. Generate write RXFIFO enable.
//                               3. Generate write RXFIFO data.
//******************************************************************************

//******************************************************************************
//:gmac_data_vld_gectrl_f2: ......1.....1.....1.....1.....1......1.....    <<I
//:gmac_eof_gectrl_f2:      ..............................1............    <<I
//:gmac_data_gectrl_f2:   ......A.....B.....C.....D.....E......F.....    <<I
//:gectrl_frame_len_inner:......LLLLLLMMMMMMNNNNNNOOOOOOPPPPPPPQQQQQQ    <<I
//:gectrl_wr_en_rxfifo_pre:   ............1...........1.....1............    >>O
//:gectrl_wr_data_rxfifo:   .............S...........M.....N...........    >>O
//
//Generate write RXFIFO data and enable;
//             
//******************************************************************************

//temp save the 64bits data from the gmac.
reg                reg_gport_data;

reg        length_error;       
//******************************************************************************
//**                signal name: reg_gport_data
//******************************************************************************
always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST) begin
                length_error                <= #D        1'b0;
                reg_gport_data                <= #D        128'h0;
        end
        else if (gmac_data_vld_gectrl_f2 == 1'b1) begin
                case (gectrl_frame_row_inner)
                2'b01:        reg_gport_data                <= #D        {gmac_data_gectrl_f2, reg_gport_data, reg_gport_data, reg_gport_data};
                2'b10:        reg_gport_data                <= #D        {reg_gport_data, gmac_data_gectrl_f2, reg_gport_data, reg_gport_data};
                2'b11:        reg_gport_data                <= #D        {reg_gport_data, reg_gport_data, gmac_data_gectrl_f2, reg_gport_data};
                2'b00:        reg_gport_data                <= #D        {reg_gport_data, reg_gport_data, reg_gport_data, gmac_data_gectrl_f2};
                endcase
        end
end


//******************************************************************************
//**                signal name: gectrl_wr_en_rxfifo_pre
//******************************************************************************
always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                gectrl_wr_en_rxfifo_pre <= #D 1'b0;
        else if(gmac_data_vld_gectrl_f2 && (!gectrl_frame_len_inner && !gectrl_frame_len_inner
                || gmac_eof_gectrl_f2 ))
                gectrl_wr_en_rxfifo_pre <= #D 1'b1;
        else
                gectrl_wr_en_rxfifo_pre <= #D 1'b0;
end

//******************************************************************************
//**                signal name: gectrl_wr_data_rxfifo                                 
//******************************************************************************
always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                gectrl_wr_data_rxfifo <= #D 128'h0;
        else if(gectrl_wr_en_rxfifo_pre )
                gectrl_wr_data_rxfifo <= #D reg_gport_data;
end



//******************************************************************************
//                          Sub-module:         CELL_GEN_CTRL
//                       Function:
//                               1. Generate Frame cell info.
//******************************************************************************

//******************************************************************************
//:gmac_data_vld_gectrl_f2: .......1.....1.....1.....1.....1......1....    <<I
//:gmac_eof_gectrl_f2:      ...............................1...........    <<I
//:gectrl_frame_len_inner:.......LLLLLLMMMMMMNNNNNNOOOOOOPPPPPPPQQQQQ    <<I
//:gectrl_err_stat_inner:   ...............................E...........    <<I
//:gectrl_tag_info_inner:   .........................1111111111111.....    <<I
//:gectrl_max_frame_inner:...............................1...........    <<I
//:gectrl_min_frame_inner:...............................1...........    <<I
//:gectrl_cell_vld_inner:   ........1111..1111..1111..111...111111.....    >>O
//:gectrl_cell_info_inner:........AAAA..BBBB..CCCC..DDD...EEEEEE.....    >>O
//:gectrl_rd_ack_cell:      ...........1.....1.....1....1........1.....    >>O
//
//生成单元格和框架信息                Generate the cell and frame info;
//             
//******************************************************************************

wire                temp_drop_valid;
wire                temp_drop_code;

//******************************************************************************
//**                  signal:        gectrl_cell_vld_inner         
//**                  signal:        gectrl_cell_info_inner         
//******************************************************************************
assign temp_drop_valid = gectrl_err_stat_inner |
                         gectrl_err_stat_inner |
                       gectrl_max_frame_inner   |
                       gectrl_min_frame_inner;

assign temp_drop_code = (gectrl_err_stat_inner)? CRC_ERR:
                        (gectrl_err_stat_inner)? FIFO_ERR :
                        (gectrl_max_frame_inner)? MAX_ERR:
                        (gectrl_min_frame_inner)? MIN_ERR: NO_ERR;


always @(posedge sys_clk or negedge sys_rst) begin
   if(sys_rst==RST) begin
             gectrl_cell_vld_inner<= #D 0;
          gectrl_flen_inner      <= #D 0;
          gectrl_sof_inner       <= #D 0;
          gectrl_eof_inner       <= #D 0;   
          gectrl_pvid_inner      <= #D 0;
          gectrl_tagged_inner    <= #D 0;
          gectrl_drop_inner      <= #D 0;
          gectrl_drop_code_inner <= #D 0;
   end
   
   //***************** cell is 64 bytes length *******************
   //when it is > 64bytes frame (end of frame)
   else if(!reg_cell_length_sel&& gmac_data_vld_gectrl_f2
             && gmac_eof_gectrl_f2 && gectrl_frame_len_inner!=0
             && gectrl_frame_len_inner !=64) begin
          gectrl_cell_vld_inner<= #D 1'b1;
          gectrl_flen_inner      <= #D gectrl_frame_len_inner;
          gectrl_sof_inner       <= #D 1'b0;
          gectrl_eof_inner       <= #D 1'b1;
          gectrl_pvid_inner      <= #D reg_gport_vlan_tag;
          gectrl_tagged_inner    <= #D gectrl_tag_info_inner;
          gectrl_drop_inner      <= #D temp_drop_valid;
          gectrl_drop_code_inner <= #D temp_drop_code;
   end
   
   //when it is <= 64bytes frame (end of frame)
   else if(!reg_cell_length_sel&& gmac_data_vld_gectrl_f2
             && gmac_eof_gectrl_f2 && (gectrl_frame_len_inner==0
             || gectrl_frame_len_inner ==64)) begin
          gectrl_cell_vld_inner<= #D 1'b1;
          gectrl_flen_inner      <= #D gectrl_frame_len_inner;
          gectrl_sof_inner       <= #D 1'b1;
          gectrl_eof_inner       <= #D 1'b1;
          gectrl_pvid_inner      <= #D reg_gport_vlan_tag;
          gectrl_tagged_inner    <= #D gectrl_tag_info_inner;
          gectrl_drop_inner      <= #D temp_drop_valid;
          gectrl_drop_code_inner <= #D temp_drop_code;
   end
   
   //when it is the start of frame.
   else if(!reg_cell_length_sel && gmac_data_vld_gectrl_f2 &&
             !gmac_eof_gectrl_f2 && gectrl_frame_len_inner == 64) begin
          gectrl_cell_vld_inner<= #D 1'b1;
          gectrl_flen_inner      <= #D gectrl_frame_len_inner;
          gectrl_sof_inner       <= #D 1'b1;
          gectrl_eof_inner       <= #D 1'b0;
          gectrl_pvid_inner      <= #D 'h0;
          gectrl_tagged_inner    <= #D 'h0;
          gectrl_drop_inner      <= #D 'h0;
          gectrl_drop_code_inner <= #D 'h0;
   end
               
   //when it is the midddle of frame and a cell(==64bytes).
   else if(!reg_cell_length_sel   && gmac_data_vld_gectrl_f2
             && !gmac_eof_gectrl_f2 && gectrl_frame_len_inner != 64
             && gectrl_frame_len_inner==0) begin
          gectrl_cell_vld_inner<= #D 1'b1;
          gectrl_flen_inner      <= #D gectrl_frame_len_inner;
          gectrl_sof_inner       <= #D 'b0;
          gectrl_eof_inner       <= #D 'b0;
          gectrl_pvid_inner      <= #D 'h0;
          gectrl_tagged_inner    <= #D 'h0;
          gectrl_drop_inner      <= #D 'h0;
          gectrl_drop_code_inner <= #D 'h0;
   end

   //when receiving read ack signal from WR_CELL_CTRL, the cell is not valid
   else if(!reg_cell_length_sel && gectrl_rd_ack_cell) begin
             gectrl_cell_vld_inner<= #D 0;
          gectrl_flen_inner      <= #D 0;
          gectrl_sof_inner       <= #D 0;
          gectrl_eof_inner       <= #D 0;   
          gectrl_pvid_inner      <= #D 0;
          gectrl_tagged_inner    <= #D 0;
          gectrl_drop_inner      <= #D 0;
          gectrl_drop_code_inner <= #D 0;
   end

   //***************** cell is 128 bytes length *******************
   //when it is > 128bytes frame (end of frame)
   else if(reg_cell_length_sel&& gmac_data_vld_gectrl_f2
             && gmac_eof_gectrl_f2 && gectrl_frame_len_inner!=0
             && gectrl_frame_len_inner !=128) begin
          gectrl_cell_vld_inner<= #D 1'b1;
          gectrl_flen_inner      <= #D gectrl_frame_len_inner;
          gectrl_sof_inner       <= #D 1'b0;
          gectrl_eof_inner       <= #D 1'b1;
          gectrl_pvid_inner      <= #D reg_gport_vlan_tag;
          gectrl_tagged_inner    <= #D gectrl_tag_info_inner;
          gectrl_drop_inner      <= #D temp_drop_valid;
          gectrl_drop_code_inner <= #D temp_drop_code;
   end
   
   //when it is <= 128bytes frame (end of frame)
   else if(reg_cell_length_sel&& gmac_data_vld_gectrl_f2
             && gmac_eof_gectrl_f2 && (gectrl_frame_len_inner==0
             || gectrl_frame_len_inner ==128)) begin
          gectrl_cell_vld_inner<= #D 1'b1;
          gectrl_flen_inner      <= #D gectrl_frame_len_inner;
          gectrl_sof_inner       <= #D 1'b1;
          gectrl_eof_inner       <= #D 1'b1;
          gectrl_pvid_inner      <= #D reg_gport_vlan_tag;
          gectrl_tagged_inner    <= #D gectrl_tag_info_inner;
          gectrl_drop_inner      <= #D temp_drop_valid;
          gectrl_drop_code_inner <= #D temp_drop_code;
   end
   
   //when it is the start of frame.
   else if(reg_cell_length_sel && gmac_data_vld_gectrl_f2 &&
             !gmac_eof_gectrl_f2 && gectrl_frame_len_inner == 128) begin
          gectrl_cell_vld_inner<= #D 1'b1;
          gectrl_flen_inner      <= #D gectrl_frame_len_inner;
          gectrl_sof_inner       <= #D 1'b1;
          gectrl_eof_inner       <= #D 1'b0;
          gectrl_pvid_inner      <= #D 'h0;
          gectrl_tagged_inner    <= #D 'h0;
          gectrl_drop_inner      <= #D 'h0;
          gectrl_drop_code_inner <= #D 'h0;
   end
               
   //when it is the midddle of frame and a cell(==128bytes).
   else if(reg_cell_length_sel   && gmac_data_vld_gectrl_f2
             && !gmac_eof_gectrl_f2 && gectrl_frame_len_inner != 128
             && gectrl_frame_len_inner==0) begin
          gectrl_cell_vld_inner<= #D 1'b1;
          gectrl_flen_inner      <= #D gectrl_frame_len_inner;
          gectrl_sof_inner       <= #D 'b0;
          gectrl_eof_inner       <= #D 'b0;
          gectrl_pvid_inner      <= #D 'h0;
          gectrl_tagged_inner    <= #D 'h0;
          gectrl_drop_inner      <= #D 'h0;
          gectrl_drop_code_inner <= #D 'h0;
   end

   //when receiving read ack signal from WR_CELL_CTRL, the cell is not valid
   else if(reg_cell_length_sel && gectrl_rd_ack_cell) begin
             gectrl_cell_vld_inner<= #D 0;
          gectrl_flen_inner      <= #D 0;
          gectrl_sof_inner       <= #D 0;
          gectrl_eof_inner       <= #D 0;   
          gectrl_pvid_inner      <= #D 0;
          gectrl_tagged_inner    <= #D 0;
          gectrl_drop_inner      <= #D 0;
          gectrl_drop_code_inner <= #D 0;
   end
end




//******************************************************************************
//                          Sub-module:         WR_CELL_CTRL (State Machine)
//                       Function:
//                               1. Receive the data from GEMAC.
//******************************************************************************

//******************************************************************************
//:gectrl_cell_vld_inner:   ........1111..1111..1111..111...111111.....    <<I
//:gectrl_cell_info_inner:........AAAA..BBBB..CCCC..DDD...EEEEEE.....    <<I
//:gectrl_cell_eof_inner:   ..........................111..............    <<I
//:gectrl_rd_ack_cell:      ...........1.....1.....1....1....1...1.....    >>O
//:gectrl_wr_en_cififo:   ...........1.....1.....1....1....1...1.....    >>O
//:gectrl_cell_info_cififo: ............A.....B.....C....D....P...E....    <<I
//
//Generate the write CIFIFO cell and CIFIFO write enable signal;
//
//******************************************************************************
//: the gectrl_wr_en_cififo is after 1 cycle of gectrl_wr_en_rxfifo_pre.             
//******************************************************************************

//******************************************************************************
//**                  state_machine:wr_cell_ctrl;                                       
//******************************************************************************
parameter        IDLE_USUAL= 5'b01000;
parameter        WR_PRB_IDLE = 5'b10000;
parameter        WR_MID_CELL = 5'b00001;
parameter        WR_END_CELL = 5'b00010;
parameter        WR_PRB_INFO = 5'b00100;

reg                curr_stat;
reg                next_stat;

wire                temp_cell_eof;

assign        temp_cell_eof = gectrl_eof_inner;

always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                   curr_stat <= #D IDLE_USUAL;
        else
                   curr_stat <= #D next_stat;
end

always @(curr_stat or gectrl_cell_vld_inner or temp_cell_eof or prb_mtchvld_gectrl) begin
        case(curr_stat)
                IDLE_USUAL : next_stat = (!gectrl_cell_vld_inner)? IDLE_USUAL :
                                       (temp_cell_eof)? WR_END_CELL : WR_MID_CELL;
                WR_MID_CELL: next_stat = IDLE_USUAL;
        //Changed By lxia@2011-08-02:Del the PRB function;So the write FSM can not
        //go to WR_PRB_INFO or WR_PRB_IDLE;
        //        WR_END_CELL: next_stat = (prb_mtchvld_gectrl)? WR_PRB_INFO : WR_PRB_IDLE;
      WR_END_CELL: next_stat = IDLE_USUAL;
          WR_PRB_INFO: next_stat = (!gectrl_cell_vld_inner)? IDLE_USUAL:
                                            (temp_cell_eof)? WR_END_CELL:WR_MID_CELL;
                WR_PRB_IDLE: next_stat = (prb_mtchvld_gectrl)? WR_PRB_INFO:WR_PRB_IDLE;
                default:   next_stat = IDLE_USUAL;
        endcase
end

assign gectrl_rd_ack_prb= (next_stat==WR_PRB_INFO)? 1'b1 :1'b0;   
assign gectrl_rd_ack_cell = (next_stat==WR_MID_CELL)? 1'b1:
                            (next_stat==WR_END_CELL)? 1'b1 : 1'b0;
assign gectrl_wr_en_cififo_pre= (next_stat!=IDLE_USUAL && next_stat!=WR_PRB_IDLE)? 1'b1 : 1'b0;

always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                gectrl_cell_eof_cififo <= #D 1'b0;
        else if(next_stat==WR_MID_CELL || next_stat==WR_END_CELL)
                gectrl_cell_eof_cififo <= #D gectrl_cell_info_inner;
        else
                gectrl_cell_eof_cififo <= #D 1'b0;
end

always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
                   gectrl_cell_info_cififo <= #D 36'b0;
        else if(next_stat==WR_MID_CELL || next_stat==WR_END_CELL)
                gectrl_cell_info_cififo <= #D gectrl_cell_info_inner;   
        else if(next_stat==WR_PRB_INFO)
                gectrl_cell_info_cififo <= #D {prb_info_gectrl,4'b0};
        else
                   gectrl_cell_info_cififo <= #D 36'b0;
end
//pragma protect end
always @(posedge sys_clk or negedge sys_rst) begin
        if(sys_rst==RST)
        begin
          gectrl_wr_en_cififo <= #D 1'b0;
          gectrl_wr_en_rxfifo <= #D 1'b0;
        end
        else
        begin
          gectrl_wr_en_cififo <= #D gectrl_wr_en_cififo_pre;
          gectrl_wr_en_rxfifo <= #D gectrl_wr_en_rxfifo_pre ;
        end
end

endmodule
页: [1]
查看完整版本: gerif_cpuctrl