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

来源:互联网 发布:js trigger事件 编辑:程序博客网 时间:2024/05/16 09:29

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


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    endtaskendmodule
0 0
原创粉丝点击