FPGA进阶教程15 使用mdio接口定义百兆以太网

我们接上一讲,要搞懂这一节的内容需要仔细分析一下mdio_ctrl的代码,在百兆以太网中,我们使用的YT8511芯片是需要关闭自协商模式的,也就是寄存器地址为0X00的第12位要置为0,寄存器定义如下图所示:

其次,在第13位上,通过芯片手册可以了解到,百兆网络的寄存器设置是如下所示的:

也就是将第6位设置为0,第13位设置为1

这个过程也是想教大家学会如何看芯片手册

设置的代码如下所示:

if(rst_trig_flag) begin        //开始对MDIO接口进行软复位
                    op_exec <= 1'b1; 
                    op_rh_wl <= 1'b0; 		   //低电平是写信号,代表开始写数据
					op_addr <= 5'h0;
                    op_wr_data <= 16'hA100;    //Bit[15]=1'b1,表示软复位
                    flow_cnt <= 3'd1;
                end

如上述代码所示,op_addr是设置寄存器地址为0x00,也就是下图的寄存器

        然后将op_wr_data设置为A100,二进制就是1010 0001 0000 0000,可以看到,第6位和第13位分别是0和1,第12位为0,第15位是软复位,默认为1,这样就可以将以太网设置为百兆,时钟频率就为25MHZ了。

修改后的mdio_ctrl完整代码如下,其他模块的代码基本没有改动:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/07/29 17:34:16
// Design Name: 
// Module Name: mdio_ctrl
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
module mdio_ctrl(
    input                clk           ,
    input                rst_n         ,
    input                soft_rst_trig , //软复位触发信号 按键按下代表软复位触发
    input                op_done       , //读写完成
    input        [15:0]  op_rd_data    , //读出的数据
    input                op_rd_ack     , //读应答信号 0:应答 1:未应答
    output  reg          op_exec       , //触发开始信号
    output  reg          op_rh_wl      , //低电平写,高电平读
    output  reg  [4:0]   op_addr       , //寄存器地址
    output  reg  [15:0]  op_wr_data    , //写入寄存器的数据
    output       [1:0]   led           , //LED灯指示以太网连接状态
	
	//test
	output				 timer_cnt	   ,
	output               timer_done	   ,
	output        [2:0]	 flow_cnt  ,
	output 				 pos_rst_trig,
	output 		  [1:0]	 speed_status,
	output 				 link_error
    );

parameter TIME_CNT = 24'd1_000_000;
//reg define
reg          rst_trig_d0;    
reg          rst_trig_d1;  
reg			 rst_trig_d2; 
reg          rst_trig_flag;   //soft_rst_trig信号触发标志
reg  [23:0]  timer_cnt;       //定时计数器 
reg          timer_done;      //定时完成信号
reg          start_next;      //开始读下一个寄存器标致
reg          read_next;       //处于读下一个寄存器的过程
reg          link_error;      //链路断开或者自协商未完成
reg  [2:0]   flow_cnt;        //流程控制计数器 
reg  [1:0]   speed_status;    //连接速率 

//wire define
wire         pos_rst_trig;    //soft_rst_trig信号上升沿
//采soft_rst_trig信号上升沿
assign pos_rst_trig = ~rst_trig_d2 & rst_trig_d1;
//未连接或连接失败时led赋值11
// 10:10Mbps  01:100Mbps  00:1000Mbps 11:其他情况
assign led = speed_status;
//对soft_rst_trig信号延时打拍
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rst_trig_d0 <= 1'b0;
        rst_trig_d1 <= 1'b0;
		rst_trig_d2 <= 1'b0;
    end
    else begin
        rst_trig_d0 <= soft_rst_trig;
        rst_trig_d1 <= rst_trig_d0;
		rst_trig_d2 <= rst_trig_d1;
    end
end

//定时计数
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        timer_cnt <= 1'b0;
        timer_done <= 1'b0;
    end
    else begin
        if(timer_cnt == TIME_CNT - 1'b1) begin
            timer_done <= 1'b1;
            timer_cnt <= 1'b0;
        end
        else begin
            timer_done <= 1'b0;
            timer_cnt <= timer_cnt + 1'b1;
        end
    end
end    

//根据软复位信号对MDIO接口进行软复位,并定时读取以太网的连接状态
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        flow_cnt <= 3'd0;
        rst_trig_flag <= 1'b0;
        speed_status <= 2'b00;
        op_exec <= 1'b0; 
        op_rh_wl <= 1'b0; 
        op_addr <= 5'h0; 
        op_wr_data <= 16'h0; 
        start_next <= 1'b0; 
        read_next <= 1'b0; 
        //link_error <= 1'b0;
    end
    else begin
        op_exec <= 1'b0; 
        if(pos_rst_trig)                      
            rst_trig_flag <= 1'b1;             //拉高软复位触发标志
        case(flow_cnt)
            2'd0 : begin
                if(rst_trig_flag) begin        //开始对MDIO接口进行软复位
                    op_exec <= 1'b1; 
                    op_rh_wl <= 1'b0; 		   //低电平是写信号,代表开始写数据
					op_addr <= 5'h0;
                    op_wr_data <= 16'hA100;    //Bit[15]=1'b1,表示软复位
                    flow_cnt <= 3'd1;
                end
                else if(timer_done) begin      //定时完成,获取以太网连接状态
                    op_exec <= 1'b1; 
                    op_rh_wl <= 1'b1;
					//op_addr <= 5'h05; 		   //用于仿真
					op_addr <= 5'h01; 		//地址
                    flow_cnt <= 3'd2;
                end
                else if(start_next) begin      //开始读下一个寄存器,获取以太网通信速度
                    op_exec <= 1'b1; 
                    op_rh_wl <= 1'b1; 
					op_addr <= 5'h11;		   //寄存器地址
					//op_addr <= 5'h06;		   //用于仿真
                    flow_cnt <= 3'd2;
                    start_next <= 1'b0; 
                    read_next <= 1'b1; 
                end
            end    
            2'd1 : begin
                if(op_done) begin              //MDIO接口软复位完成
                    flow_cnt <= 3'd0;
                    rst_trig_flag <= 1'b0;
                end
            end
            2'd2 : begin                       
                if(op_done) begin              //MDIO接口读操作完成
                    if(op_rd_ack == 1'b0 && read_next == 1'b0) //读第一个寄存器,接口成功应答,
                        flow_cnt <= 3'd3;                      
                    else if(op_rd_ack == 1'b0 && read_next == 1'b1)begin //读下一个寄存器,接口成功应答
                        read_next <= 1'b0;
                        flow_cnt <= 3'd4;
                    end
                    else begin
                        flow_cnt <= 3'd0;
                     end
                end    
            end
            2'd3 : begin                     
                flow_cnt <= 3'd0;          //链路正常
                //if(op_rd_data[5] == 1'b1 && op_rd_data[2] == 1'b1)begin
				start_next <= 1;
				//link_error <= 0;
                //end
                //else begin
                //    link_error <= 1;  
               //end           
            end
            3'd4: begin
                flow_cnt <= 3'd0;
                if(op_rd_data[15:14] == 2'b10)
                    speed_status <= 2'b00; //1000Mbps
                else if(op_rd_data[15:14] == 2'b01) 
                    speed_status <= 2'b01; //100Mbps 
                else if(op_rd_data[15:14] == 2'b00) 
                    speed_status <= 2'b10; //10Mbps
                else
                    speed_status <= 2'b11; //其他情况  
            end
        endcase
    end    
end    

endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值