千兆网(2):数据的发送与接收测试

难点:
多时钟的切换
相位偏移的数据同步
原语的使用


RTL结构视图与时钟网络

这里写图片描述

工程文件的路径:

这里写图片描述

这里写图片描述

其中RGMII_tx_ctrl模块为FPGA测试发送数据模块,依赖于仿真
RGMII_tx_ctrl的原语调用:

module RGMII_tx_ctrl(
                input wire sclk,//125M
                input wire rst_n,
                //
                input wire [7:0] tx_d,//仿真提供的数据输入data_in
                input wire tx_en,//使能信号
                input wire tx_c,//相移时钟
                //
                output [3:0]tx_data,
                output tx_dv,//en
                output tx_clk//PHY采集数据时钟
                );

    //tx_clk
    ODDR2 #(
        .DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
        .INIT(1'b0), // Sets initial state of the Q output to 1’b0 or 1’b1
        .SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
    ) 
    ODDR2_TXC(
        .Q(tx_clk), // 1-bit DDR output data
        .C0(tx_c), // 1-bit clock input
        .C1(~tx_c), // 1-bit clock input
        .CE(1'b1), // 1-bit clock enable input
        .D0(1'b1), // 1-bit data input (associated with C0)
        .D1(1'b0), // 1-bit data input (associated with C1)
        .R(1'b0), // 1-bit reset input
        .S(~rst_n) // 1-bit set input
    );  

    //tx_data
    genvar i;
    generate
        for(i=0;i<4;i=i+1)begin
            ODDR2 #(
                .DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
                .INIT(1'b0), // Sets initial state of the Q output to 1’b0 or 1’b1
                .SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
            ) 
            ODDR2_TDATA(
                //tx_data是和sclk同步的
                .Q(tx_data[i]), // 1-bit DDR output data
                .C0(sclk), // 1-bit clock input
                .C1(~sclk), // 1-bit clock input
                //
                .CE(1'b1), // 1-bit clock enable input
                .D0(tx_d[i]), // 1-bit data input (associated with C0)
                .D1(tx_d[i+4]), // 1-bit data input (associated with C1)
                .R(1'b0), // 1-bit reset input
                .S(~rst_n) // 1-bit set input
            );
        end
    endgenerate

    //tx_dv
    ODDR2 #(
        .DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
        .INIT(1'b0), // Sets initial state of the Q output to 1’b0 or 1’b1
        .SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
    ) 
    ODDR2_TXEN(
        .Q(tx_dv), // 1-bit DDR output data
        .C0(sclk), // 1-bit clock input
        .C1(~sclk), // 1-bit clock input
        .CE(1'b1), // 1-bit clock enable input
        .D0(tx_en), // 1-bit data input (associated with C0)
        .D1(tx_en), // 1-bit data input (associated with C1)
        .R(1'b0), // 1-bit reset input
        .S(~rst_n) // 1-bit set input
    );

endmodule
module top_RGMII(
                input wire sclk,
                input wire rst_n,
                //
                input wire rx_clk,
                input wire rx_dv,
                input wire [3:0]rx_data,

                output wire phy_rst_n
                //output wire tout
                );

    reg [21:0]rst_cnt;
    wire [7:0]o_data,rd_data;
    wire rx_en;
    wire clk_50M,clk_125M,clk_125M_90;
    wire rd_flag_r;

    //assign tout = rx_en|(&o_data);//for test
    //----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
    gen_clk gen_clk_inst
   (// Clock in ports
    .clkin(sclk),      // IN
    // Clock out ports
    .clk_125M(clk_125M),     // OUT
    .clk_125M_90(clk_125M_90),     // OUT
    .clk_50M(clk_50M)
     );    // OUT
    // INST_TAG_END ------ End INSTANTIATION Template ---------

    always @(posedge clk_125M)//clk_50M
    if(!rst_n)
        rst_cnt <= 'd0;
    else if(rst_cnt[21]== 'd0)//
        rst_cnt <= rst_cnt + 'd1;

    assign phy_rst_n = rst_cnt[21];//上电复位延时大于4ms

    RGMII_rx_ctrl RGMII_rx_ctrl_inst(
                    //from phy
                    .rx_clk(rx_clk),   //125M 
                    .rst_n(rst_n),
                    .rx_dv(rx_dv),//千兆网同步有效信号,双沿采样  上升沿=dv 下降沿=deer
                    .rx_data(rx_data),

                    .rx_en(rx_en),
                    .o_data(o_data)//单沿采样数据
                );

    SYNC_ctrl SYNC_ctrl_inst(
        .rx_clk(rx_clk),
        .ddr_clk(clk_125M),
        .rst_n(rst_n),
    //
        .rx_en(rx_en),
        .data_in(o_data),//o_d=ata
    //
        .rd_data(rd_data),
        .rd_flag_r(rd_flag_r)
    );

endmodule

测试模块

module tb_RGMII();

    reg     sclk,rst_n;
    wire        rx_clk;
    wire        rx_dv;
    wire    [3:0]   rx_data;
    wire        phy_rst_n;

    reg     clk;
    reg     tx_c;
    reg [7:0]   tx_d;
    reg     tx_en;
    wire [3:0]tx_data;

    initial begin
        sclk =0;
        rst_n =0;
        #1000 
        rst_n=1;
    end
    always #10 sclk = ~sclk;

    initial begin
        force clk = top_RGMII_inst.clk_125M;
        force tx_c = top_RGMII_inst.clk_125M_90;
    end

    initial begin
        tx_d=0;
        tx_en =0;
        gen_frame();
    end

    RGMII_tx_ctrl RGMII_tx_ctrl_inst(
                .sclk(clk),
                .rst_n(rst_n),

                .tx_d(tx_d),//仿真提供的数据输入data_in
                .tx_en(tx_en),//使能信号
                .tx_c(tx_c),//相移时钟

                .tx_data(tx_data),
                .tx_dv(tx_dv),//en
                .tx_clk(tx_clk)//PHY采集数据时钟
                );

    top_RGMII top_RGMII_inst(
                .sclk(sclk),
                .rst_n(rst_n),

                .rx_clk(tx_clk),
                .rx_dv(tx_dv),
                .rx_data(tx_data),

                .phy_rst_n(phy_rst_n),
                .tout(tout)
                );

    task gen_frame();
        integer i;
        begin
            @(posedge phy_rst_n);
            for(i =0 ; i<128 ;i=i+1)
            begin
                @(posedge clk);
                tx_en <= 1'b1;
                if(i<7)
                    tx_d <= 8'h55;
                else if(i==7)
                    tx_d <= 8'hd5;
                else 
                    tx_d <= i-8;
            end
            @(posedge clk)
                tx_en <= 1'b0;
                tx_d <= 'd0; 
        end
    endtask

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值