集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1086|回复: 1

gerif_cpuctrl

[复制链接]
fpga_feixiang 发表于 2020-12-30 13:48:39 | 显示全部楼层 |阅读模式
// $Id: gerif_cpuctrl.v,v 1.1 2015-02-11 12:51:21+08  Exp $
//=============================================================================
//
//
// 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        [VLAN_INFO_WIDTH-1:0]        reg_gport_vlan_tag;   //port default vlan tag.
input                                reg_gport_remap_pri;  //port remap 802.1p or not.
input        [MAX_FRAME_WIDTH-1:0]        reg_max_length_gport; //the max frame length.
input        [MIN_FRAME_WIDTH-1:0]        reg_min_length_gport; //the min frame length.
input                                reg_cell_length_sel;


//用GMAC定义接口信号                        define the interface signal with GMAC.
input        [IN_DATA_WIDTH-1:0]        gmac_data_gectrl;
input        [1:0]                        gmac_vld_1_0_gectrl;
input        [1:0]                        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        [OUT_DATA_WIDTH-1:0]        gectrl_wr_data_rxfifo;

//使用CIFIFO定义接口信号                define the interface signal with CIFIFO.
output                                gectrl_wr_en_cififo;
output                                gectrl_cell_eof_cififo;
output        [CELL_WIDTH-1:0]        gectrl_cell_info_cififo;

//使用PROBE定义接口信号                define the interface signal with PROBE.
input                                prb_mtchvld_gectrl;
input        [PRB_INFO_WIDTH-1:0]        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        [OUT_DATA_WIDTH-1:0]        gectrl_wr_data_rxfifo;
wire                                gectrl_wr_en_cififo_reg;
reg                                gectrl_cell_eof_cififo;
reg        [CELL_WIDTH-1:0]        gectrl_cell_info_cififo;
wire                                gectrl_rd_ack_prb;


//定义内部寄存器子模块和子模块                        define inner register sub-module and sub-module.
// RV_DATA_CTRL ->FRAME_LEN_CTRL
reg        [IN_DATA_WIDTH-1:0]        gmac_data_gectrl_f1;                               
reg                                gmac_data_vld_gectrl_f1;
reg        [1:0]                        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        [FRAME_LEN_WIDTH-1:0]        gectrl_frame_len_inner;
reg        [FRAME_LEN_WIDTH-1:0]        gectrl_frame_row_inner;  // like  the len count, but is a row count
reg        [1:0]                        gectrl_err_stat_inner;
wire                        gectrl_tag_info_inner;   
reg                                gectrl_max_frame_inner;  
reg                                gectrl_min_frame_inner;  

reg        [FRAME_LEN_WIDTH:0]        reg_max_len_add4_ge; //the max frame length.
reg        [FRAME_LEN_WIDTH-1:0]        reg_min_len_add4_ge; //the min frame length.

//FRAME_LEN_CTRL -> WR_FIFO_CTRL
reg        [IN_DATA_WIDTH-1:0]        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        [FRAME_LEN_WIDTH-1:0]/*[13:0]*/        gectrl_flen_inner;
reg                                gectrl_sof_inner;
reg                                gectrl_eof_inner;
reg        [14:0]                        gectrl_pvid_inner;        //默认端口虚拟网络标签                default port vlan tag.
reg                                gectrl_tagged_inner;
reg                                gectrl_drop_inner;
reg        [1:0]                        gectrl_drop_code_inner;
wire        [CELL_WIDTH-1:0]/*[35:0]*/        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[34:21]        = "gecell_frame_length";
//        dctrl_cell_info_cctrl[20]        = "gecell_SOF";
//        dctrl_cell_info_cctrl[19]        = "gecell_EOF";
//        dctrl_cell_info_cctrl[18:4]        = "gecell_PVID";
//        dctrl_cell_info_cctrl[3]        = "gecell_tag_info";
//        dctrl_cell_info_cctrl[2]        = "gecell_drop_valid";
//        dctrl_cell_info_cctrl[1:0]        = "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_f1  gmac_data_gectrl_f1;
//******************************************************************************

////------------------------------------------------------------------------------
////*                     Usage:                 125MHz.
////*                  inner signal:        gectrl_rd_ctrl_inner           
////------------------------------------------------------------------------------
//wire                gectrl_rd_ctrl_inner;
//reg        [3:0]        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[0],gectrl_rd_cnt[3:1]};
//end
//
//assign        gectrl_rd_ctrl_inner = gectrl_rd_cnt[3];
       
//------------------------------------------------------------------------------
//*                     Usage:                 100MHz.
//*                  inner signal:        gectrl_rd_ctrl_inner           
//------------------------------------------------------------------------------
wire                gectrl_rd_ctrl_inner;
reg        [1:0]        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[0],gectrl_rd_cnt[1]};
end

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

//******************************************************************************
//**                  信号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       <= #D  gectrl_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[13:2]==0)? 15'h0: {1'b0,reg_max_length_gport}-15'h4 ;
                reg_min_len_add4_ge <= #D (reg_min_length_gport[6:2]==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        [OUT_DATA_WIDTH-1:0]        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[3:2])
                2'b01:        reg_gport_data                <= #D        {gmac_data_gectrl_f2, reg_gport_data[95:64], reg_gport_data[63:32], reg_gport_data[31:0]};
                2'b10:        reg_gport_data                <= #D        {reg_gport_data[127:96], gmac_data_gectrl_f2, reg_gport_data[63:32], reg_gport_data[31:0]};
                2'b11:        reg_gport_data                <= #D        {reg_gport_data[127:96], reg_gport_data[95:64], gmac_data_gectrl_f2, reg_gport_data[31:0]};
                2'b00:        reg_gport_data                <= #D        {reg_gport_data[127:96], reg_gport_data[95:64], reg_gport_data[63:32], 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[3] && !gectrl_frame_len_inner[2]
                || 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        [1:0]        temp_drop_code;

//******************************************************************************
//**                  signal:        gectrl_cell_vld_inner         
//**                  signal:        gectrl_cell_info_inner         
//******************************************************************************
assign temp_drop_valid = gectrl_err_stat_inner[0] |
                         gectrl_err_stat_inner[1] |
                         gectrl_max_frame_inner   |
                         gectrl_min_frame_inner;

assign temp_drop_code = (gectrl_err_stat_inner[0])? CRC_ERR  :
                        (gectrl_err_stat_inner[1])? 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[13:6]!=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[13:6]==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[5:0]==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[13:7]!=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[13:7]==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[6:0]==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;
//
//******************************************************************************
//[Notes]: 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        [4:0]        curr_stat;
reg        [4:0]        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-02el 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[19];
        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 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2025-4-19 09:31 , Processed in 0.069029 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表