⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ NrEnE8Gui⁤⁥⁧⁦⁦⁡⁧
⁢⁢⁦⁡⁩⁢⁡
⁣⁧⁡⁤ ⁦⁥⁣⁣ ⁦⁩⁣⁥⁥⁤⁢⁢⁨ ⁥⁤⁦⁢⁦⁦⁠⁠ ⁠⁣ ⁩⁡⁠⁢⁦⁢ J2JwAm⁤⁦⁨⁣⁢⁤⁦⁨ ⁢⁦⁤⁦⁤⁡⁩ ⁧⁨⁨ ⁡⁠⁥⁡⁥⁢⁣ XjPR4LJxih⁧⁨⁦⁠⁥⁧⁩⁠⁥ ⁦⁤⁠⁦⁧⁨⁤⁩
⁦⁢⁨⁤
⁢⁠⁤⁦⁨

⁩⁩⁡

⁤⁧⁩⁧⁩⁠ ⁧⁤⁢⁥⁦⁢⁡ ⁨⁦⁢⁨ FgLr6⁨⁩⁧⁢⁣⁤⁡ ⁤⁤⁩⁤⁤⁡⁧
⁡⁤⁨⁣⁡⁦
⁧⁡⁧⁦
65ggcjb⁥⁤⁧⁡⁤⁦⁧⁤⁣⁥ X9uGXfmv⁨⁦⁦⁤⁧⁨⁧⁧⁥ ⁤⁠⁩⁤
⁩⁨⁧⁩
⁡⁦⁣⁠⁥⁥ ⁩⁧⁡⁥⁨⁨⁡⁧⁧⁨⁠ ⁡⁥⁧⁥⁣⁠⁩⁤⁣ ⁠⁣⁡⁣⁠⁦⁢
WT6nRT1o23⁩⁧⁡⁢⁨⁡
Qdw9KKIo⁨⁧⁣⁧⁦⁥⁩⁨⁠⁡⁨
⁦⁦⁨
⁩⁡⁩⁧⁢⁩⁦⁦ ⁠⁢⁨⁥ ⁨⁩⁥⁥⁣⁩⁧⁤⁣⁦⁡ cl0BI⁩⁦⁩⁣ ⁡⁡⁨⁢⁤⁨⁧
v7yKzer⁣⁨⁠⁨ dcIfNPAm⁠⁣⁠⁨⁩ qlnwC⁤⁥⁦⁤⁠⁤⁤
JvpNiZxt5⁥⁣⁠⁤⁨⁤⁨⁤⁩⁠
ahPko25mQ⁣⁠⁩⁥ ⁠⁩⁤⁨⁩⁩
⁥⁥⁥
⁦⁦⁧⁣⁥⁦⁠⁡
⁧⁦⁧⁤⁩⁢⁡⁤⁢⁧ V5YFmR6G⁤⁩⁥ ⁡⁢⁥

⁧⁨⁡⁩⁣⁡⁥

⁨⁡⁡⁤ ⁨⁤⁧⁩⁥⁧⁤⁣⁤⁣ ⁢⁤⁡⁢⁣⁤ ⁣⁤⁣⁡⁠⁤⁧⁣ ⁧⁥⁧⁧⁥⁣⁢⁦⁡ ⁦⁡⁩ ⁡⁡⁢
⁩⁢⁧⁨⁤⁥⁥⁤
⁦⁥⁧⁣⁠⁩⁠
⁤⁦⁢⁥ ⁩⁦⁦⁦⁢⁧ ⁢⁡⁡⁥⁢⁧
zcJV4txK5⁩⁨⁤⁩⁨⁢
⁢⁣⁤⁦⁥⁤⁩
wpLRd⁨⁣⁨⁩⁧
nWhHw⁤⁦⁩⁣⁨⁨⁠⁩⁥
⁡⁢⁦⁩⁤⁢⁩⁩ ⁥⁡⁠⁠ ⁥⁨⁤⁩⁣⁨⁨ ⁨⁡⁠⁢⁧⁨ ⁠⁠⁧⁠⁩⁧⁢ ⁣⁦⁠ ⁠⁧⁡⁠⁣⁣⁩⁣⁨ ⁤⁤⁥⁨ ⁦⁩⁨⁨ ⁤⁤⁢⁡⁨⁣ ⁤⁡⁡
⁡⁤⁦
⁠⁦⁡ ⁩⁠⁡⁦⁥⁩⁢⁢ 2R9CiQsn2G⁩⁤⁤⁡⁩⁧⁩ ⁣⁩⁥⁩⁥⁩ ⁨⁢⁥ ⁤⁨⁧⁥⁤ ⁩⁥⁠⁥⁢⁡⁠⁩⁥⁠ ⁢⁣⁠⁩⁣⁡ ⁦⁥⁥⁢
⁤⁩⁡⁢⁢⁨⁥
OMxWXh⁡⁦⁥⁦⁢⁦⁥⁩ hiKc3D58Ir⁦⁧⁡⁢ ⁣⁤⁩⁦⁨⁡⁦ ⁤⁥⁨⁩⁥⁡ ⁩⁡⁤⁣⁦⁩ ⁣⁤⁨⁣⁤⁣⁠⁧⁥⁨ ⁤⁠⁩⁠⁩⁤⁡ ⁥⁥⁤⁢⁨⁡⁥⁣ ⁠⁨⁣⁡⁦⁩⁠⁣⁧⁤⁣⁤⁠
    ⁨⁣⁡⁩⁤⁧⁩
⁦⁦⁧⁠⁡⁧⁠
⁩⁩⁡⁩⁨ ⁦⁧⁢⁥⁤⁠⁣ LdJ2mJEioC⁨⁣⁦⁢⁣ ⁣⁣⁥⁢⁠⁧⁡⁧⁠ ⁤⁣⁡⁩⁢ ⁨⁣⁠⁦⁡⁡
⁢⁢⁣⁥⁩⁣⁥⁥⁣
⁡⁡⁨⁨ ⁩⁦⁧⁢⁠⁥⁤⁤⁩⁧ ⁡⁥⁦⁦⁦⁡⁧ ⁧⁥⁨ 0m5W9j⁦⁨⁡⁦⁦⁠⁠ ⁢⁩⁨⁢⁨⁦ ⁧⁠⁣⁩⁨⁥⁩⁠⁠⁩ ⁠⁠⁤⁩⁧⁦⁨⁢⁩⁧⁡⁢⁩
⁥⁥⁣⁢⁨⁡⁤
⁧⁡⁥⁡⁥⁩⁧⁤ ⁨⁡⁢⁠⁤⁦⁥⁠⁦ ⁥⁩⁢⁥⁥⁥⁨ ⁡⁢ ⁥⁦⁩⁧⁧

⁡⁦⁣⁥⁤⁧⁡

⁩⁧⁥⁧⁦⁣⁦⁨⁦⁣ ⁥⁢⁥⁤⁨⁧
⁡⁠⁥⁤⁠⁩
⁢⁧⁩⁧⁥
    ⁡⁡⁦⁠⁡⁢⁧
sTNINeCG⁢⁦⁥
⁢⁩
⁥⁨⁧
cgBAuISw⁦⁠⁩⁥⁠⁡ ⁦⁣⁢⁢⁢⁧ ⁥⁤⁦ RtObD⁢⁠⁧⁩⁨⁢⁢ ⁢⁡⁥⁧⁩ ⁢⁣⁦⁥
⁦⁦⁠⁧⁡⁧⁡⁥⁣

⁢⁢⁣⁣⁥

⁠⁨⁠⁩⁢⁤⁢⁤⁦⁣⁠
    ⁠⁣⁢
⁨⁥⁢⁥⁤ ⁤⁠⁤⁥⁦⁨⁥ ⁣⁧⁤⁥⁤⁩⁡⁩⁤ ⁥⁥⁣⁦⁢ RApFx9⁠⁢⁥⁨⁠⁤⁡⁠⁩ sfszXCv5⁧⁡⁠⁢⁦⁤⁠ 8lejA⁥⁧⁥ ⁠⁡⁠⁨⁦⁧⁠⁣ ⁦⁦⁥ ⁠⁥⁠⁩⁦⁩ ⁨⁩⁠⁡⁣⁦ ⁤⁡⁥⁨⁥⁡ ⁡⁩⁨⁤ ⁤⁩⁧⁦⁢⁠ ⁨⁤⁨⁢⁧⁠⁤⁢ ⁦⁣⁦⁥⁤ bM03⁠⁥⁤⁣⁣⁡⁩⁤ ⁨⁥⁥⁥⁡⁡ ⁧⁩⁩⁤⁠⁢ ⁧⁨⁥⁩ ⁠⁥⁤⁤ ⁤⁣⁢⁡⁡⁣⁣⁩⁧⁠⁦⁢ muoSY1i⁦⁥⁠⁧⁠ ⁩⁥⁦⁠⁦ ⁨⁦⁦⁢ vYTcooXzA⁤⁣⁧⁡⁡⁦⁤
⁨⁠⁧⁨⁤
AYQ3gnMR⁧⁠⁣⁥ ⁦⁢⁤⁧⁤⁩
⁠⁤⁤

xDsToeNDG7⁥⁠⁢

⁧⁨⁥⁨


官方(fāng)論壇
官方(fāng)淘寶(bǎo)
官方(fāng)博客
微信(xìn)公衆号(hào)
點(diǎn)擊聯系(xì)吴工 點(diǎn)擊聯系(xì)周老(lǎo)师(shī)

【文(wén)章(zhāng)】MDIO接口(kǒu)配置與(yǔ)檢测PHY芯片(piàn)

發(fà)布(bù)时(shí)間(jiān):2021-06-26   作者(zhě):admin 浏覽量(liàng):

摘自(zì):明(míng)德揚网(wǎng)絡班学員陳同(tóng)学博客

https://www.cnblogs.com/moluoqishi/p/9118283.html

一(yī)、前(qián)言

本(běn)文(wén)設計(jì)思(sī)想(xiǎng)采用(yòng)明(míng)德揚至(zhì)簡設計(jì)法。以(yǐ)太网(wǎng)这(zhè)一(yī)高(gāo)效实用(yòng)的(de)數據(jù)傳輸方(fāng)式應(yìng)用(yòng)于(yú)各(gè)个(gè)領域,如(rú)网(wǎng)絡交換設備,高(gāo)速网(wǎng)絡相機(jī)等。虽然各(gè)FPGA廠(chǎng)商都提(tí)供MAC IP核,但大多(duō)收(shōu)費,有(yǒu)时(shí)无法破解(jiě)。不(bù)同(tóng)廠(chǎng)家(jiā)之間(jiān)无法移植,而(ér)且为(wèi)了(le)通(tòng)用(yòng)性(xìng)考慮犧牲了(le)效率,因(yīn)此(cǐ)自(zì)己動(dòng)手(shǒu)写一(yī)个(gè)以(yǐ)太网(wǎng)MAC是(shì)个(gè)不(bù)錯的(de)選擇。

本(běn)博文(wén)讨論通(tòng)过(guò)MDIO接口(kǒu)管(guǎn)理PHY芯片(piàn)来(lái)验(yàn)證其正(zhèng)确工作,为(wèi)在(zài)此(cǐ)基礎上(shàng)設計(jì)MAC邏輯開(kāi)个(gè)头(tóu)。PHY芯片(piàn)采用(yòng)RTL8211EGVB,選用(yòng)GMII接口(kǒu)與(yǔ)MAC連(lián)接。下(xià)面(miàn)我(wǒ)们(men)来(lái)開(kāi)始第(dì)一(yī)步,在(zài)此(cǐ)之前(qián)明(míng)确設計(jì)目的(de):檢测PHY芯片(piàn)是(shì)否完成(chéng)自(zì)動(dòng)協商 鍊(liàn)路(lù)速率是(shì)否达(dá)到(dào)1000M。所(suǒ)以(yǐ)要(yào)從datasheet中(zhōng)了(le)解(jiě)到(dào)芯片(piàn)引脚 寄存器地(dì)址 接口(kǒu)时(shí)序。


二(èr)、設計(jì)分(fēn)析

管(guǎn)理幀格式如(rú)下(xià):

读(dú)写操作时(shí)序:

MDC为(wèi)MAC驅動(dòng)时(shí)鐘(zhōng)信(xìn)号(hào),MDIO是(shì)串行數據(jù)總(zǒng)線(xiàn),需要(yào)連(lián)接上(shàng)拉電(diàn)阻保證idle狀态下(xià)高(gāo)電(diàn)平。其中(zhōng)前(qián)導碼包(bāo)含32个(gè)比特(tè)“1”PHY地(dì)址根(gēn)據(jù)芯片(piàn)引脚連(lián)接而(ér)定(dìng),此(cǐ)处为(wèi)01.turn around域是(shì)为(wèi)了(le)防止读(dú)操作时(shí)數據(jù)沖突,在(zài)读(dú)操作过(guò)程中(zhōng)MAC和(hé)PHY均在(zài)第(dì)1比特(tè)处進(jìn)入(rù)高(gāo)阻态,PHY在(zài)第(dì)2比特(tè)处驅動(dòng)MDIO接口(kǒu)为(wèi)低電(diàn)平以(yǐ)占據(jù)總(zǒng)線(xiàn)控制權。注意(yì)两(liǎng)點(diǎn):第(dì)一(yī)如(rú)果(guǒ)时(shí)鐘(zhōng)信(xìn)号(hào)在(zài)读(dú)写操作後(hòu)停止,时(shí)鐘(zhōng)必須保證至(zhì)少(shǎo)7个(gè)时(shí)鐘(zhōng)周期(qī)持(chí)續翻轉(zhuǎn)且MDIO高(gāo)電(diàn)平從而(ér)保證之前(qián)的(de)操作完成(chéng)。故在(zài)設計(jì)中(zhōng)可(kě)以(yǐ)等待一(yī)段(duàn)时(shí)間(jiān)後(hòu)再拉低时(shí)鐘(zhōng)使能(néng)信(xìn)号(hào)。第(dì)二(èr)两(liǎng)个(gè)操作之間(jiān)至(zhì)少(shǎo)一(yī)个(gè)idle比特(tè)。

正(zhèng)确驅動(dòng)接口(kǒu)时(shí)序需要(yào)關(guān)注AC characterisics.

很明(míng)顯MAC驅動(dòng)總(zǒng)線(xiàn)时(shí),在(zài)MDC下(xià)降沿更(gèng)新數據(jù)。而(ér)PHY驅動(dòng)總(zǒng)線(xiàn)时(shí),MDC上(shàng)升(shēng)沿後(hòu)更(gèng)新數據(jù)。根(gēn)據(jù)datasheet中(zhōng)的(de)timing參數設定(dìng)MDC时(shí)鐘(zhōng)周期(qī)是(shì)800nsMAC接收(shōu)PHY數據(jù)时(shí)下(xià)降沿采樣(yàng)。

接下(xià)来(lái)關(guān)注要(yào)訪問(wèn)的(de)內(nèi)部(bù)寄存器地(dì)址,首先(xiān)读(dú)取(qǔ)PHY寄存器數據(jù)以(yǐ)檢测其工作狀态,若發(fà)現(xiàn)异(yì)常再考慮写入(rù)數據(jù)。这(zhè)里(lǐ)读(dú)取(qǔ)基本(běn)模式狀态寄存器0X01的(de)bit5,若为(wèi)1说(shuō)明(míng)自(zì)動(dòng)協商完成(chéng)。第(dì)二(èr)个(gè)寄存器是(shì)PHY特(tè)定(dìng)狀态寄存器0X11中(zhōng)的(de)[15:14]和(hé)13,分(fēn)别是(shì)當前(qián)速率和(hé)全(quán)/半双(shuāng)工通(tòng)信(xìn)模式。若檢测到(dào)自(zì)動(dòng)協商完成(chéng),且工作在(zài)1000M全(quán)双(shuāng)工模式下(xià),说(shuō)明(míng)工作正(zhèng)确。


三(sān)、硬(yìng)件(jiàn)架構與(yǔ)狀态機(jī)設計(jì)

所(suǒ)有(yǒu)準備工作完成(chéng),現(xiàn)在(zài)開(kāi)始設計(jì)。按照自(zì)頂向(xiàng)下(xià)設計(jì)原則,規劃(huà)好(hǎo)整體(tǐ)結構和(hé)模块(kuài)間(jiān)接口(kǒu),再設計(jì)內(nèi)部(bù)狀态機(jī)一(yī)步步实現(xiàn)邏輯功能(néng)。

Mdio_ctrl模块(kuài)負責完成(chéng)PHY芯片(piàn)的(de)配置與(yǔ)檢测邏輯,Mdio接口(kǒu)模块(kuài)完成(chéng)读(dú)写操作时(shí)序。此(cǐ)处僅通(tòng)过(guò)读(dú)操作簡單檢测PHY狀态,暫不(bù)進(jìn)行配置,故两(liǎng)模块(kuài)工作狀态跳轉(zhuǎn)如(rú)图(tú)所(suǒ)示:

剩下(xià)的(de)工作就(jiù)是(shì)把两(liǎng)个(gè)狀态機(jī)实現(xiàn)出(chū)来(lái),非(fēi)常簡單。有(yǒu)需要(yào)的(de)朋友可(kě)以(yǐ)參考一(yī)下(xià),關(guān)于(yú)芯片(piàn)的(de)具體(tǐ)參數詳見(jiàn):Realtek RTL8211E(G)-VB(VL)-CG Datasheet 1.8.上(shàng)代(dài)碼!


四(sì)、代(dài)碼編写

MDIO控制模块(kuài):


  1 `timescale 1ns / 1ps
  2
  3 module mdio_ctrl(
  4     input           clk,//100M
  5     input           rst_n,
  6
  7     input           en,
  8     output reg          chk_result =0,
  9     output reg          chk_vld =0,
 10
 11     input           rdy,    
 12     output reg          rd_en =0,
 13     output reg [5-1:0]  phy_addr =0,
 14     output reg [5-1:0]  reg_addr =0,
 15     input  [16-1:0] rd_data,
 16     input           rd_vld
 17 );
 18
 19 parameter MS_CYC = 100_000;
 20
 21
 22 localparam  IDLE = 0 ;
 23 localparam  WAIT = 1 ;
 24 localparam  RD_PHY = 2 ;
 25 localparam  CHECK = 3 ;
 26
 27 localparam WAIT_MS = 10;  
 28       
 29 localparam BMSR = 5'h01,
 30            PHYSR = 5'h11;
 31
 32 reg [4-1:0] state_c = 0,state_n = 0;
 33 wire idle2wait,wait2rd_phy,rd_phy2check,check2idle,check2wait;
 34 wire link_up;
 35 reg [16-1:0] rd_memory [0:1];
 36 reg [ (17-1):0]  ms_cnt =0    ;
 37 wire        add_ms_cnt ;
 38 wire        end_ms_cnt ;
 39 reg [ (4-1):0]  wait_cnt  =0    ;
 40 wire        add_wait_cnt ;
 41 wire        end_wait_cnt ;
 42 reg [ (2-1):0]  rd_cnt  =0    ;
 43 wire        add_rd_cnt ;
 44 wire        end_rd_cnt ;
 45 reg [ (2-1):0]  rdata_cnt  =0    ;
 46 wire        add_rdata_cnt ;
 47 wire        end_rdata_cnt ;  
 48 wire [5*2-1:0] registers;    
 49 reg rd_finish = 0;
 50
 51 initial begin
 52     rd_memory[0] = 0;
 53     rd_memory[1] = 0;
 54 end
 55
 56 always @(posedge clk or negedge rst_n) begin 
 57     if (rst_n==0) begin
 58         state_c <= IDLE ;
 59     end
 60     else begin
 61         state_c <= state_n;
 62    end
 63 end
 64
 65 always @(*) begin 
 66     case(state_c)  
 67         IDLE :begin
 68             if(idle2wait) 
 69                 state_n = WAIT ;
 70             else 
 71                 state_n = state_c ;
 72         end
 73         WAIT :begin
 74             if(wait2rd_phy) 
 75                 state_n = RD_PHY ;
 76             else 
 77                 state_n = state_c ;
 78         end
 79         RD_PHY :begin
 80             if(rd_phy2check) 
 81                 state_n = CHECK ;
 82             else 
 83                 state_n = state_c ;
 84         end
 85         CHECK :begin
 86             if(check2idle) 
 87                 state_n = IDLE ;
 88             else if(check2wait) 
 89                 state_n = WAIT ;
 90             else 
 91                 state_n = state_c ;
 92         end
 93         default : state_n = IDLE ;
 94     endcase
 95 end
 96
 97 assign idle2wait    = state_c==IDLE && (en);
 98 assign wait2rd_phy  = state_c==WAIT && (end_wait_cnt);
 99 assign rd_phy2check = state_c==RD_PHY && (end_rdata_cnt);
100 assign check2idle   = state_c==CHECK && (link_up);
101 assign check2wait   = state_c==CHECK && (!link_up);
102
103
104 assign link_up = rd_memory[0][5] == 1'b1 && rd_memory[1][15:13] == 3'b10_1;//auto_nego && gigabit && full_duplex
105
106
107 //計(jì)數器
108 always @(posedge clk or negedge rst_n) begin 
109     if (rst_n==0) begin
110         ms_cnt <= 0; 
111     end
112     else if(add_ms_cnt) begin
113         if(end_ms_cnt)
114             ms_cnt <= 0; 
115         else
116             ms_cnt <= ms_cnt+1 ;
117    end
118 end
119 assign add_ms_cnt = (state_c == WAIT);
120 assign end_ms_cnt = add_ms_cnt  && ms_cnt == (MS_CYC)-1 ;//100MHZ时(shí)鐘(zhōng)100_000
121
122 always @(posedge clk or negedge rst_n) begin 
123     if (rst_n==0) begin
124         wait_cnt <= 0; 
125     end
126     else if(add_wait_cnt) begin
127         if(end_wait_cnt)
128             wait_cnt <= 0; 
129         else
130             wait_cnt <= wait_cnt+1 ;
131    end
132 end
133 assign add_wait_cnt = (end_ms_cnt);
134 assign end_wait_cnt = add_wait_cnt  && wait_cnt == (WAIT_MS)-1 ;
135
136 always @(posedge clk or negedge rst_n) begin 
137     if (rst_n==0) begin
138         rd_cnt <= 0; 
139     end
140     else if(add_rd_cnt) begin
141         if(end_rd_cnt)
142             rd_cnt <= 0; 
143         else
144             rd_cnt <= rd_cnt+1 ;
145    end
146 end
147 assign add_rd_cnt = (state_c == RD_PHY && rdy && !rd_finish);
148 assign end_rd_cnt = add_rd_cnt  && rd_cnt == (2)-1 ;
149
150 always  @(posedge clk or negedge rst_n)begin
151     if(rst_n==1'b0)begin
152         rd_finish <= 0;
153     end
154     else if(end_rd_cnt)begin
155         rd_finish <= 1'b1;
156     end
157     else if(state_c == CHECK)
158         rd_finish <= 0;
159 end
160
161
162 always @(posedge clk or negedge rst_n) begin 
163     if (rst_n==0) begin
164         rdata_cnt <= 0; 
165     end
166     else if(add_rdata_cnt) begin
167         if(end_rdata_cnt)
168             rdata_cnt <= 0; 
169         else
170             rdata_cnt <= rdata_cnt+1 ;
171    end
172 end
173 assign add_rdata_cnt = (rd_vld);
174 assign end_rdata_cnt = add_rdata_cnt  && rdata_cnt == (2)-1 ;
175
176 //接口(kǒu)信(xìn)号(hào)邏輯
177 always  @(posedge clk or negedge rst_n)begin
178     if(rst_n==1'b0)begin
179         rd_en <= 0;
180         phy_addr <= 0;
181         reg_addr <= 0;
182     end
183     else if(add_rd_cnt)begin
184         rd_en <= 1'b1;
185         phy_addr <= 5'b00001;
186         reg_addr <= registers[10-5*rd_cnt-1 -:5];
187     end
188     else begin
189         rd_en <= 0;
190         phy_addr <= 0;
191         reg_addr <= 0;
192     end
193 end
194
195 assign registers = {BMSR,PHYSR};//5'h01,5'h11
196
197 always  @(posedge clk or negedge rst_n)begin
198     if(rst_n==1'b0)begin
199         rd_memory[0] <= 0;
200         rd_memory[1] <= 0;
201     end
202     else if(add_rdata_cnt)begin
203         rd_memory[rdata_cnt] <= rd_data;
204     end
205 end
206
207 //用(yòng)戶側輸出(chū)檢测結果(guǒ)
208 always  @(posedge clk or negedge rst_n)begin
209     if(rst_n==1'b0)begin
210         chk_vld <= 0;
211     end
212     else if(state_c == CHECK)begin
213         chk_vld <= 1'b1;
214     end
215     else
216         chk_vld <= 0;
217 end
218
219 always  @(posedge clk or negedge rst_n)begin
220     if(rst_n==1'b0)begin
221         chk_result <= 0;
222     end
223     else if(check2idle)begin
224         chk_result <= 1'b1;
225     end
226     else if(check2wait)
227         chk_result <= 0;
228 end
229
230 endmodule
231

MDIO时(shí)序接口(kǒu)模块(kuài):

>   1 `timescale 1ns / 1ps
  2
  3 module mdio_interface#(parameter MDC_CYC = 800)//ns
  4 (
  5     input                   clk,//100M时(shí)鐘(zhōng)
  6     input                   rst_n,
  7
  8     input                   rd_en,
  9     input       [5-1:0]     phy_addr,
 10     input       [5-1:0]     reg_addr,
 11     output reg  [16-1:0]    rd_data =0,
 12     output reg              rd_vld =0,
 13     output reg              rdy =0,
 14
 15     output reg              mdo =1,
 16     output reg              mdo_en =0,
 17     input                   mdi,
 18     output reg              mdc =1
 19     );
 20
 21     localparam N = MDC_CYC/10;
 22
 23
 24 localparam  IDLE = 0 ;
 25 localparam  WRI_COM = 1 ;
 26 localparam  RD_DATA = 2 ;
 27
 28 localparam PRE      = 32'hffff_ffff,
 29            START    = 2'b01,
 30            OP       = 2'b10,
 31            TA       = 2'b11;
 32
 33 reg [3-1:0] state_c =0,state_n =0;
 34 wire idle2wri_com,wri_com2rd_data,rd_data2idle;
 35 reg [ (7-1):0]  div_cnt  =0    ;
 36 wire        add_div_cnt ;
 37 wire        end_div_cnt ;
 38 reg [ (6-1):0]  bit_cnt  =0    ;
 39 wire        add_bit_cnt ;
 40 wire        end_bit_cnt ;
 41 reg [6-1:0] M =0;
 42 wire [48-1:0] command;
 43 reg   rd_flag  =0    ;
 44 reg [5-1:0] phy_addr_tmp = 0;
 45 reg [5-1:0] reg_addr_tmp = 0;
 46
 47
 48 //寄存地(dì)址
 49 always  @(posedge clk or negedge rst_n)begin
 50     if(rst_n==1'b0)begin
 51         phy_addr_tmp <= 0;
 52         reg_addr_tmp <= 0;
 53     end
 54     else if(rd_en)begin
 55         phy_addr_tmp <= phy_addr;
 56         reg_addr_tmp <= reg_addr;
 57     end
 58 end
 59
 60
 61 always@(*)begin
 62     if(state_c == IDLE && !rd_en && !rd_flag)
 63         rdy <= 1;
 64     else
 65         rdy <= 0;
 66 end
 67
 68 always @(posedge clk or negedge rst_n) begin 
 69     if (rst_n==0) begin
 70         state_c <= IDLE ;
 71     end
 72     else begin
 73         state_c <= state_n;
 74    end
 75 end
 76
 77 always @(*) begin 
 78     case(state_c)  
 79         IDLE :begin
 80             if(idle2wri_com) 
 81                 state_n = WRI_COM ;
 82             else 
 83                 state_n = state_c ;
 84         end
 85         WRI_COM :begin
 86             if(wri_com2rd_data) 
 87                 state_n = RD_DATA ;
 88             else 
 89                 state_n = state_c ;
 90         end
 91         RD_DATA :begin
 92             if(rd_data2idle) 
 93                 state_n = IDLE ;
 94             else 
 95                 state_n = state_c ;
 96         end
 97         default : state_n = IDLE ;
 98     endcase
 99 end
100
101
102 assign idle2wri_com     = state_c==IDLE     && end_div_cnt && (rd_flag || rd_en);
103 assign wri_com2rd_data  = state_c==WRI_COM  && end_bit_cnt;
104 assign rd_data2idle     = state_c==RD_DATA  && end_bit_cnt;
105
106
107 always @(posedge clk or negedge rst_n )begin 
108     if(rst_n==0) begin
109         rd_flag <= (0)  ;
110     end
111     else if(state_c == IDLE && rd_en)begin
112         rd_flag <= (1'b1)  ;
113     end 
114     else if(state_c == WRI_COM)
115         rd_flag <= 0;
116 end
117
118
119 //分(fēn)頻計(jì)數器
120 always @(posedge clk or negedge rst_n) begin 
121     if (rst_n==0) begin
122         div_cnt <= 0; 
123     end
124     else if(add_div_cnt) begin
125         if(end_div_cnt)
126             div_cnt <= 0; 
127         else
128             div_cnt <= div_cnt+1 ;
129    end
130 end
131 assign add_div_cnt = (1);
132 assign end_div_cnt = add_div_cnt  && div_cnt == (N)-1 ;
133
134 //比特(tè)計(jì)數器
135 always @(posedge clk or negedge rst_n) begin 
136     if (rst_n==0) begin
137         bit_cnt <= 0; 
138     end
139     else if(add_bit_cnt) begin
140         if(end_bit_cnt)
141             bit_cnt <= 0; 
142         else
143             bit_cnt <= bit_cnt+1 ;
144    end
145 end
146 assign add_bit_cnt = (end_div_cnt && state_c != IDLE);
147 assign end_bit_cnt = add_bit_cnt  && bit_cnt == (M)-1 ;
148
149 always@(*)begin
150     case(state_c)
151         WRI_COM:M = 48;
152         RD_DATA:M = 16;
153         default:M = 10;
154     endcase
155 end
156
157 //mdc时(shí)鐘(zhōng)
158 always @(posedge clk or negedge rst_n )begin 
159     if(rst_n==0) begin
160         mdc <= (1'b1)  ;
161     end
162     else if(add_div_cnt && div_cnt == (N>>1) - 1)begin
163         mdc <= (1'b1)  ;
164     end 
165     else if(end_div_cnt)
166         mdc <= 0;
167 end
168
169
170 //mdio輸出(chū)
171 always @(posedge clk or negedge rst_n )begin 
172     if(rst_n==0) begin
173         mdo <= (1'b1)  ;
174     end
175     else if(add_bit_cnt && state_c == WRI_COM)begin
176         mdo <= command[48-1-bit_cnt]  ;
177     end 
178     else if(state_c != WRI_COM)
179         mdo <= 1'b1;
180 end
181
182 assign command = {PRE,START,OP,phy_addr_tmp,reg_addr_tmp,TA};
183
184 always @(posedge clk or negedge rst_n )begin 
185     if(rst_n==0) begin
186         mdo_en <= (0)  ;
187     end
188     else if(state_c == WRI_COM && add_bit_cnt)
189         case(bit_cnt)
190             0: mdo_en <= 1'b1;
191             46:mdo_en <= 0;
192             default:;
193         endcase
194 end
195
196 //mdio輸入(rù)
197 always @(posedge clk or negedge rst_n )begin 
198     if(rst_n==0) begin
199         rd_data <= (0)  ;
200     end
201     else if(add_bit_cnt && state_c == RD_DATA)begin
202         rd_data[16-1-bit_cnt] <= (mdi)  ;
203     end 
204 end
205
206 always @(posedge clk or negedge rst_n )begin 
207     if(rst_n==0) begin
208         rd_vld <= (0)  ;
209     end
210     else if(rd_data2idle)begin
211         rd_vld <= (1'b1)  ;
212     end 
213     else
214         rd_vld <= 0;
215 end
216
217
218 endmodule
219
220 mdio_interface
221

頂层封(fēng)裝(zhuāng):

>  1 `timescale 1ns / 1ps
 2
 3 module phy_manage(
 4     input   clk,
 5     input   rst_n,
 6
 7     input   mdio_en,
 8     output  link_up,
 9     output  chk_done,
10
11     output  mdc,
12     inout   mdio
13     );
14
15 wire rdy;
16 wire rd_en;
17 wire [5-1:0] phy_addr;
18 wire [5-1:0] reg_addr;
19 (*DONT_TOUCH = "TRUE"*)wire [16-1:0] rd_data;
20 wire rd_vld;
21 wire mdo_en,mdo,mdi;
22
23
24     mdio_ctrl mdio_ctrl(
25     .clk       (clk) ,//100M
26     .rst_n     (rst_n) ,
27
28     .en        (mdio_en) ,
29     .chk_result(link_up) ,
30     .chk_vld   (chk_done) ,
31
32     .rdy       (rdy) ,    
33     .rd_en     (rd_en) ,
34     .phy_addr  (phy_addr) ,
35     .reg_addr  (reg_addr) ,
36     .rd_data   (rd_data) ,
37     .rd_vld    (rd_vld) 
38 );
39
40 mdio_interface#(.MDC_CYC(800))//ns
41 mdio_interface
42 (
43     .clk      (clk) ,//100M时(shí)鐘(zhōng)
44     .rst_n    (rst_n) ,
45
46     .rd_en    (rd_en) ,
47     .phy_addr (phy_addr) ,
48     .reg_addr (reg_addr) ,
49     .rd_data  (rd_data) ,
50     .rd_vld   (rd_vld) ,
51     .rdy      (rdy) ,
52
53     .mdo      (mdo) ,
54     .mdo_en   (mdo_en) ,
55     .mdi      (mdi) ,
56     .mdc      (mdc)
57     );
58
59     //三(sān)态門(mén)
60     assign mdio = mdo_en ? mdo : 1'bz;
61     assign mdi = mdio; 
62
63 endmodule
64
65 phy_manage
66

五(wǔ)、功能(néng)仿真(zhēn)

之後(hòu)編写testbench進(jìn)行行为(wèi)仿真(zhēn):

>   1 `timescale 1 ns/1 ps
  2
  3 `define BIT_CNT uut.mdio_interface.bit_cnt
  4
  5 module phy_manage_tb();
  6
  7 //时(shí)鐘(zhōng)和(hé)複位
  8 reg clk  ;
  9 reg rst_n;
 10
 11 //uut的(de)輸入(rù)信(xìn)号(hào)
 12 reg mdio_en;
 13
 14 //uut的(de)輸出(chū)信(xìn)号(hào)
 15 wire link_up;
 16 wire chk_done;
 17 wire mdc;
 18 wire mdio;
 19 wire [16-1:0] back_data1,back_data2;
 20
 21         //时(shí)鐘(zhōng)周期(qī),單位为(wèi)ns,可(kě)在(zài)此(cǐ)修改时(shí)鐘(zhōng)周期(qī)。
 22         parameter CYCLE    = 10;
 23
 24         //複位时(shí)間(jiān),此(cǐ)时(shí)表(biǎo)示複位3个(gè)时(shí)鐘(zhōng)周期(qī)的(de)时(shí)間(jiān)。
 25         parameter RST_TIME = 2 ;
 26
 27         defparam uut.mdio_ctrl.MS_CYC = 100;
 28
 29         //待测試的(de)模块(kuài)例化(huà)
 30        phy_manage uut(
 31        .clk       (clk) ,
 32        .rst_n     (rst_n) ,
 33
 34        .mdio_en   (mdio_en) ,
 35        .link_up   (link_up) ,
 36        .chk_done  (chk_done) ,
 37
 38        .mdc       (mdc) ,
 39        .mdio      (mdio) 
 40     );
 41
 42
 43      //生(shēng)成(chéng)本(běn)地(dì)时(shí)鐘(zhōng)50M
 44      initial begin
 45          clk = 1;
 46          forever
 47          #(CYCLE/2)
 48          clk=~clk;
 49      end
 50
 51      //産生(shēng)複位信(xìn)号(hào)
 52      initial begin
 53          rst_n = 1;
 54          #1;
 55          rst_n = 0;
 56          #(CYCLE*RST_TIME);
 57          rst_n = 1;
 58      end
 59
 60      //輸入(rù)信(xìn)号(hào)din0賦值方(fāng)式
 61      initial begin
 62          #1;
 63          //賦初值
 64          mdio_en = 0;
 65          #(10*CYCLE);
 66          mdio_en = 1;
 67          #(1*CYCLE);
 68          mdio_en = 0;
 69          //開(kāi)始賦值
 70         #100_000;
 71         $stop;
 72      end
 73     
 74      //模拟PHY響應(yìng)
 75
 76     //data
 77     assign back_data1 = {16'b0000_0000_0010_0000};
 78     assign back_data2 = {16'b1010_0000_0000_0000};
 79
 80     integer i = 0,j = 0;
 81     initial begin
 82         forever begin
 83             wait(uut.mdio_interface.state_c == 1 && `BIT_CNT == 47 );
 84             @(posedge mdc);
 85             force mdio = 0;
 86             @(posedge mdc);
 87             j = j+1;
 88             if(j == 1)
 89                 force mdio = back_data1[16-1-i+1];
 90             else
 91                 force mdio = back_data2[16-1-i+1];
 92
 93             wait(uut.mdio_interface.state_c == 0);
 94             @(posedge mdc);
 95             release mdio;
 96         end
 97     end
 98
 99     initial begin
100         forever begin
101             @(posedge mdc);
102             if(uut.mdio_interface.state_c == 2)begin
103                 #10;
104                 i = i+1;
105             end
106             else 
107                 i = 0;
108         end
109     end
110
111
112  endmodule
113
114 phy_manage_tb
115

testbench中(zhōng)利用(yòng)force強(qiáng)迫更(gèng)新mdio双(shuāng)向(xiàng)端口(kǒu)方(fāng)式模拟PHY芯片(piàn)響應(yìng)。仿真(zhēn)波(bō)形上(shàng)半部(bù)分(fēn)为(wèi)MDIO控制模块(kuài)信(xìn)号(hào),下(xià)半部(bù)分(fēn)則是(shì)MDIO时(shí)序接口(kǒu)模块(kuài)信(xìn)号(hào)。可(kě)見(jiàn)當读(dú)取(qǔ)寄存器數值滿足PHY工作需求时(shí),link_up信(xìn)号(hào)拉高(gāo),證明(míng)此(cǐ)时(shí)MAC可(kě)以(yǐ)傳輸數據(jù)給(gěi)PHY


六(liù)、板級調試

完整的(de)設計(jì),板級調試是(shì)必不(bù)可(kě)少(shǎo)的(de)。真(zhēn)正(zhèng)地(dì)将接口(kǒu)調通(tòng),PHY芯片(piàn)正(zhèng)确響應(yìng)才能(néng)说(shuō)明(míng)达(dá)到(dào)設計(jì)目的(de)。頂层封(fēng)裝(zhuāng)测試工程,內(nèi)部(bù)例化(huà):差分(fēn)时(shí)鐘(zhōng)緩沖原語(yǔ)、PLLPHY管(guǎn)理頂层封(fēng)裝(zhuāng)以(yǐ)及(jí)VIO ILA調試IP。我(wǒ)们(men)来(lái)看(kàn)下(xià)原理图(tú)頂层:

测試工程頂层:

> >  1 `timescale 1ns / 1ps
 2
 3
 4 module mdio_test(
 5     input sys_clk_p,
 6     input sys_clk_n,
 7     input rst_n,
 8
 9     output mdc,
10     inout mdio,
11
12     output phy_reset//PHY芯片(piàn)複位信(xìn)号(hào) 低有(yǒu)效
13     );
14
15
16 wire sys_clk_ibufg;
17 wire clk;
18 wire en;
19 wire chk_done;
20 wire link_up;
21
22 assign phy_reset = 1'b1;//始終(zhōng)不(bù)複位
23
24 IBUFGDS #
25 (
26 .DIFF_TERM ("FALSE"),
27 .IBUF_LOW_PWR ("FALSE")
28 )
29 u_ibufg_sys_clk
30 (
31 .I (sys_clk_p), //差分(fēn)时(shí)鐘(zhōng)的(de)正(zhèng)端輸入(rù),需要(yào)和(hé)頂层模块(kuài)的(de)端口(kǒu)直(zhí)接連(lián)接
32 .IB (sys_clk_n), // 差分(fēn)时(shí)鐘(zhōng)的(de)負端輸入(rù),需要(yào)和(hé)頂层模块(kuài)的(de)端口(kǒu)直(zhí)接連(lián)接
33 .O (sys_clk_ibufg) //时(shí)鐘(zhōng)緩沖輸出(chū)
34 );
35
36  clk_wiz_0 u_clk
37    (
38     // Clock out ports
39     .clk_out1(clk),     // output clk_out1 100Mhz
40    // Clock in ports
41     .clk_in1(sys_clk_ibufg));      // input clk_in1
42
43  vio_0 u_vio (
44   .clk(clk),                // input wire clk
45   .probe_out0(en)  // output wire [0 : 0] probe_out0
46 );
47
48 phy_manage phy_manage(
49     .clk      (clk)  ,
50     .rst_n    (rst_n)  ,
51
52     .mdio_en  (en)  ,
53     .link_up  (link_up)  ,
54     .chk_done (chk_done)  ,
55
56     .mdc      (mdc)  ,
57     .mdio     (mdio)  
58     );
59
60
61 endmodule
62
63 mdio_test
64

时(shí)鐘(zhōng)引脚約束(shù)文(wén)件(jiàn):

> > >  1 create_clock -period 5.000 [get_ports sys_clk_p]
 2 set_property PACKAGE_PIN R4 [get_ports sys_clk_p]
 3 set_property IOSTANDARD DIFF_SSTL15 [get_ports sys_clk_p]
 4
 5 set_property PACKAGE_PIN T6 [get_ports rst_n]
 6 set_property IOSTANDARD LVCMOS15 [get_ports rst_n]
 7
 8 set_property PACKAGE_PIN W10 [get_ports mdc]
 9 set_property IOSTANDARD LVCMOS33 [get_ports mdc]
10
11 set_property PACKAGE_PIN V10 [get_ports mdio]
12 set_property IOSTANDARD LVCMOS33 [get_ports mdio]
13
14 set_property PACKAGE_PIN L15 [get_ports phy_reset]
15 set_property IOSTANDARD LVCMOS33 [get_ports phy_reset]
16
17 clk_pin
18

有(yǒu)一(yī)點(diǎn)相信(xìn)調試过(guò)以(yǐ)太网(wǎng)的(de)人(rén)大多(duō)都跳过(guò)一(yī)个(gè)坑:沒(méi)有(yǒu)驅動(dòng)PHY的(de)複位輸入(rù)信(xìn)号(hào)。本(běn)人(rén)也(yě)在(zài)此(cǐ)处栽过(guò)跟头(tóu),这(zhè)里(lǐ)直(zhí)接連(lián)續賦值拉高(gāo)PHY芯片(piàn)複位信(xìn)号(hào)。關(guān)于(yú)板級調試還(huán)有(yǒu)个(gè)小技巧,根(gēn)據(jù)高(gāo)亞军老(lǎo)师(shī)的(de)書(shū)籍得知,将set up debug生(shēng)成(chéng)的(de)ILA探針(zhēn)相關(guān)約束(shù)命令單独放(fàng)入(rù)一(yī)个(gè)約束(shù)文(wén)件(jiàn)便于(yú)調試IP的(de)管(guǎn)理和(hé)修改,debug約束(shù)文(wén)件(jiàn)就(jiù)不(bù)贴出(chū)来(lái)了(le)。

查看(kàn)debug波(bō)形,MDIO时(shí)序接口(kǒu)模块(kuài)在(zài)釋放(fàng)MDIO串行總(zǒng)線(xiàn)时(shí),由(yóu)于(yú)存在(zài)上(shàng)拉電(diàn)阻为(wèi)高(gāo)電(diàn)平,下(xià)一(yī)个(gè)MDC时(shí)鐘(zhōng)上(shàng)升(shēng)沿时(shí)刻,PHY拉低MDIO信(xìn)号(hào)響應(yìng)并得到(dào)總(zǒng)線(xiàn)控制權,開(kāi)始輸出(chū)數據(jù)。

得到(dào)读(dú)取(qǔ)的(de)两(liǎng)个(gè)寄存器數據(jù),根(gēn)據(jù)數值分(fēn)析滿足:PHY自(zì)動(dòng)協商完成(chéng),且工作在(zài)全(quán)双(shuāng)工1000Mbps速率下(xià)。

最(zuì)終(zhōng)RJ45接口(kǒu)綠(lǜ)色(sè)指示燈(dēng)常亮(liàng),表(biǎo)明(míng)自(zì)動(dòng)協商完成(chéng),网(wǎng)絡連(lián)接正(zhèng)确。到(dào)此(cǐ)簡易的(de)PHY芯片(piàn)檢测管(guǎn)理模块(kuài)設計(jì)完成(chéng)。


- 沒(méi)落(là)騎士 - 博客園(yuán)

   拓展(zhǎn)閱读(dú)
⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ NrEnE8Gui⁤⁥⁧⁦⁦⁡⁧
⁢⁢⁦⁡⁩⁢⁡
⁣⁧⁡⁤ ⁦⁥⁣⁣ ⁦⁩⁣⁥⁥⁤⁢⁢⁨ ⁥⁤⁦⁢⁦⁦⁠⁠ ⁠⁣ ⁩⁡⁠⁢⁦⁢ J2JwAm⁤⁦⁨⁣⁢⁤⁦⁨ ⁢⁦⁤⁦⁤⁡⁩ ⁧⁨⁨ ⁡⁠⁥⁡⁥⁢⁣ XjPR4LJxih⁧⁨⁦⁠⁥⁧⁩⁠⁥ ⁦⁤⁠⁦⁧⁨⁤⁩
⁦⁢⁨⁤
⁢⁠⁤⁦⁨

⁩⁩⁡

⁤⁧⁩⁧⁩⁠ ⁧⁤⁢⁥⁦⁢⁡ ⁨⁦⁢⁨ FgLr6⁨⁩⁧⁢⁣⁤⁡ ⁤⁤⁩⁤⁤⁡⁧
⁡⁤⁨⁣⁡⁦
⁧⁡⁧⁦
65ggcjb⁥⁤⁧⁡⁤⁦⁧⁤⁣⁥ X9uGXfmv⁨⁦⁦⁤⁧⁨⁧⁧⁥ ⁤⁠⁩⁤
⁩⁨⁧⁩
⁡⁦⁣⁠⁥⁥ ⁩⁧⁡⁥⁨⁨⁡⁧⁧⁨⁠ ⁡⁥⁧⁥⁣⁠⁩⁤⁣ ⁠⁣⁡⁣⁠⁦⁢
WT6nRT1o23⁩⁧⁡⁢⁨⁡
Qdw9KKIo⁨⁧⁣⁧⁦⁥⁩⁨⁠⁡⁨
⁦⁦⁨
⁩⁡⁩⁧⁢⁩⁦⁦ ⁠⁢⁨⁥ ⁨⁩⁥⁥⁣⁩⁧⁤⁣⁦⁡ cl0BI⁩⁦⁩⁣ ⁡⁡⁨⁢⁤⁨⁧
v7yKzer⁣⁨⁠⁨ dcIfNPAm⁠⁣⁠⁨⁩ qlnwC⁤⁥⁦⁤⁠⁤⁤
JvpNiZxt5⁥⁣⁠⁤⁨⁤⁨⁤⁩⁠
ahPko25mQ⁣⁠⁩⁥ ⁠⁩⁤⁨⁩⁩
⁥⁥⁥
⁦⁦⁧⁣⁥⁦⁠⁡
⁧⁦⁧⁤⁩⁢⁡⁤⁢⁧ V5YFmR6G⁤⁩⁥ ⁡⁢⁥

⁧⁨⁡⁩⁣⁡⁥

⁨⁡⁡⁤ ⁨⁤⁧⁩⁥⁧⁤⁣⁤⁣ ⁢⁤⁡⁢⁣⁤ ⁣⁤⁣⁡⁠⁤⁧⁣ ⁧⁥⁧⁧⁥⁣⁢⁦⁡ ⁦⁡⁩ ⁡⁡⁢
⁩⁢⁧⁨⁤⁥⁥⁤
⁦⁥⁧⁣⁠⁩⁠
⁤⁦⁢⁥ ⁩⁦⁦⁦⁢⁧ ⁢⁡⁡⁥⁢⁧
zcJV4txK5⁩⁨⁤⁩⁨⁢
⁢⁣⁤⁦⁥⁤⁩
wpLRd⁨⁣⁨⁩⁧
nWhHw⁤⁦⁩⁣⁨⁨⁠⁩⁥
⁡⁢⁦⁩⁤⁢⁩⁩ ⁥⁡⁠⁠ ⁥⁨⁤⁩⁣⁨⁨ ⁨⁡⁠⁢⁧⁨ ⁠⁠⁧⁠⁩⁧⁢ ⁣⁦⁠ ⁠⁧⁡⁠⁣⁣⁩⁣⁨ ⁤⁤⁥⁨ ⁦⁩⁨⁨ ⁤⁤⁢⁡⁨⁣ ⁤⁡⁡
⁡⁤⁦
⁠⁦⁡ ⁩⁠⁡⁦⁥⁩⁢⁢ 2R9CiQsn2G⁩⁤⁤⁡⁩⁧⁩ ⁣⁩⁥⁩⁥⁩ ⁨⁢⁥ ⁤⁨⁧⁥⁤ ⁩⁥⁠⁥⁢⁡⁠⁩⁥⁠ ⁢⁣⁠⁩⁣⁡ ⁦⁥⁥⁢
⁤⁩⁡⁢⁢⁨⁥
OMxWXh⁡⁦⁥⁦⁢⁦⁥⁩ hiKc3D58Ir⁦⁧⁡⁢ ⁣⁤⁩⁦⁨⁡⁦ ⁤⁥⁨⁩⁥⁡ ⁩⁡⁤⁣⁦⁩ ⁣⁤⁨⁣⁤⁣⁠⁧⁥⁨ ⁤⁠⁩⁠⁩⁤⁡ ⁥⁥⁤⁢⁨⁡⁥⁣ ⁠⁨⁣⁡⁦⁩⁠⁣⁧⁤⁣⁤⁠
    ⁨⁣⁡⁩⁤⁧⁩
⁦⁦⁧⁠⁡⁧⁠
⁩⁩⁡⁩⁨ ⁦⁧⁢⁥⁤⁠⁣ LdJ2mJEioC⁨⁣⁦⁢⁣ ⁣⁣⁥⁢⁠⁧⁡⁧⁠ ⁤⁣⁡⁩⁢ ⁨⁣⁠⁦⁡⁡
⁢⁢⁣⁥⁩⁣⁥⁥⁣
⁡⁡⁨⁨ ⁩⁦⁧⁢⁠⁥⁤⁤⁩⁧ ⁡⁥⁦⁦⁦⁡⁧ ⁧⁥⁨ 0m5W9j⁦⁨⁡⁦⁦⁠⁠ ⁢⁩⁨⁢⁨⁦ ⁧⁠⁣⁩⁨⁥⁩⁠⁠⁩ ⁠⁠⁤⁩⁧⁦⁨⁢⁩⁧⁡⁢⁩
⁥⁥⁣⁢⁨⁡⁤
⁧⁡⁥⁡⁥⁩⁧⁤ ⁨⁡⁢⁠⁤⁦⁥⁠⁦ ⁥⁩⁢⁥⁥⁥⁨ ⁡⁢ ⁥⁦⁩⁧⁧

⁡⁦⁣⁥⁤⁧⁡

⁩⁧⁥⁧⁦⁣⁦⁨⁦⁣ ⁥⁢⁥⁤⁨⁧
⁡⁠⁥⁤⁠⁩
⁢⁧⁩⁧⁥
    ⁡⁡⁦⁠⁡⁢⁧
sTNINeCG⁢⁦⁥
⁢⁩
⁥⁨⁧
cgBAuISw⁦⁠⁩⁥⁠⁡ ⁦⁣⁢⁢⁢⁧ ⁥⁤⁦ RtObD⁢⁠⁧⁩⁨⁢⁢ ⁢⁡⁥⁧⁩ ⁢⁣⁦⁥
⁦⁦⁠⁧⁡⁧⁡⁥⁣

⁢⁢⁣⁣⁥

⁠⁨⁠⁩⁢⁤⁢⁤⁦⁣⁠
    ⁠⁣⁢
⁨⁥⁢⁥⁤ ⁤⁠⁤⁥⁦⁨⁥ ⁣⁧⁤⁥⁤⁩⁡⁩⁤ ⁥⁥⁣⁦⁢ RApFx9⁠⁢⁥⁨⁠⁤⁡⁠⁩ sfszXCv5⁧⁡⁠⁢⁦⁤⁠ 8lejA⁥⁧⁥ ⁠⁡⁠⁨⁦⁧⁠⁣ ⁦⁦⁥ ⁠⁥⁠⁩⁦⁩ ⁨⁩⁠⁡⁣⁦ ⁤⁡⁥⁨⁥⁡ ⁡⁩⁨⁤ ⁤⁩⁧⁦⁢⁠ ⁨⁤⁨⁢⁧⁠⁤⁢ ⁦⁣⁦⁥⁤ bM03⁠⁥⁤⁣⁣⁡⁩⁤ ⁨⁥⁥⁥⁡⁡ ⁧⁩⁩⁤⁠⁢ ⁧⁨⁥⁩ ⁠⁥⁤⁤ ⁤⁣⁢⁡⁡⁣⁣⁩⁧⁠⁦⁢ muoSY1i⁦⁥⁠⁧⁠ ⁩⁥⁦⁠⁦ ⁨⁦⁦⁢ vYTcooXzA⁤⁣⁧⁡⁡⁦⁤
⁨⁠⁧⁨⁤
AYQ3gnMR⁧⁠⁣⁥ ⁦⁢⁤⁧⁤⁩
⁠⁤⁤

xDsToeNDG7⁥⁠⁢

⁧⁨⁥⁨