⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ 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ī)
您的(de)當前(qián)位置:主(zhǔ)页(yè) > FPGA行業資訊 >

FPGA卷(juǎn)積神經(jīng)网(wǎng)絡加速器-明(míng)德揚科教(minyingyiyuan.com)

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








高(gāo)水(shuǐ)平的(de)設計(jì)



在(zài)高(gāo)級設計(jì)中(zhōng),我(wǒ)们(men)将使用(yòng)HPS導入(rù)图(tú)像并对(duì)其進(jìn)行解(jiě)碼。我(wǒ)们(men)還(huán)使用(yòng)HPS加载VGG16重(zhòng)量(liàng)。然後(hòu)我(wǒ)们(men)将它(tā)们(men)輸入(rù)FPGA。FPGA将采用(yòng)計(jì)算部(bù)分(fēn)。經(jīng)过(guò)計(jì)算,FPGA会(huì)将結果(guǒ)輸出(chū)到(dào)HPS。結果(guǒ)将是(shì)图(tú)像的(de)特(tè)征。HPS将顯示通(tòng)过(guò)VGA監控的(de)功能(néng)。对(duì)于(yú)图(tú)像輸入(rù),我(wǒ)们(men)使用(yòng)MATLAB对(duì)其進(jìn)行預处理。提(tí)取(qǔ)RGB值,然後(hòu)計(jì)算它(tā)们(men)的(de)平均值并從原始數據(jù)中(zhōng)減去(qù)它(tā)们(men)。減去(qù)數據(jù)集意(yì)味着用(yòng)于(yú)“居中(zhōng)”數據(jù),因(yīn)此(cǐ)具有(yǒu)更(gèng)好(hǎo)的(de)学習速度(dù)。在(zài)这(zhè)个(gè)項目中(zhōng),我(wǒ)们(men)采用(yòng)16:1:7:8的(de)定(dìng)點(diǎn)格式。在(zài)这(zhè)種(zhǒng)格式中(zhōng),精度(dù)可(kě)以(yǐ)达(dá)到(dào)0.00390625,整數部(bù)分(fēn)的(de)範圍是(shì)-127到(dào)127。輸入(rù)數據(jù)在(zài)-127到(dào)127之間(jiān),并且所(suǒ)有(yǒu)權重(zhòng)都相对(duì)較小(通(tòng)常为(wèi)0.03-0.3)。輸入(rù)和(hé)預訓練權重(zhòng)的(de)轉(zhuǎn)換由(yóu)MATLAB中(zhōng)的(de)sfi函(hán)數完成(chéng)。HPS是(shì)FPGA的(de)主(zhǔ)要(yào)控制。它(tā)将發(fà)送FPGA的(de)命令和(hé)數據(jù),以(yǐ)实現(xiàn)和(hé)接收(shōu)FPGA中(zhōng)結果(guǒ)緩沖區(qū)的(de)結果(guǒ)。为(wèi)了(le)实現(xiàn)預先(xiān)訓練的(de)VGG16模型,我(wǒ)们(men)需要(yào)通(tòng)过(guò)命令load_mem加载表(biǎo)示FPGA中(zhōng)三(sān)行輸入(rù)的(de)三(sān)个(gè)寄存器。然後(hòu)我(wǒ)们(men)通(tòng)过(guò)命令load_fil将前(qián)16个(gè)濾波(bō)器加载到(dào)FPGA中(zhōng)的(de)濾波(bō)器寄存器。輸入(rù)就(jiù)緒後(hòu),卷(juǎn)積計(jì)算将对(duì)輸入(rù)文(wén)件(jiàn)的(de)前(qián)三(sān)行執行,并通(tòng)过(guò)命令計(jì)算執行前(qián)16次(cì)过(guò)濾。然後(hòu)我(wǒ)们(men)通(tòng)过(guò)命令getresult從这(zhè)16个(gè)过(guò)濾器中(zhōng)读(dú)取(qǔ)結果(guǒ)并将它(tā)们(men)保存在(zài)本(běn)地(dì)文(wén)件(jiàn)中(zhōng)。接下(xià)来(lái)将加载16个(gè)过(guò)濾器,我(wǒ)们(men)重(zhòng)複該过(guò)程,直(zhí)到(dào)处理完所(suǒ)有(yǒu)过(guò)濾器。最(zuì)後(hòu),我(wǒ)们(men)加载一(yī)个(gè)新行并反(fǎn)複重(zhòng)複所(suǒ)有(yǒu)內(nèi)容,直(zhí)到(dào)輸入(rù)文(wén)件(jiàn)中(zhōng)的(de)所(suǒ)有(yǒu)行都被(bèi)所(suǒ)有(yǒu)过(guò)濾器相乘。

the_compelixity_of_VGG16
VGG 16神經(jīng)网(wǎng)絡的(de)複雜性(xìng)(来(lái)自(zì)[5]作者(zhě):李媛媛)

卷(juǎn)積計(jì)算



卷(juǎn)積层是(shì)CNN中(zhōng)最(zuì)重(zhòng)要(yào)的(de)部(bù)分(fēn),與(yǔ)整个(gè)网(wǎng)絡相比,其計(jì)算量(liàng)超过(guò)90%。卷(juǎn)積計(jì)算公式如(rú)下(xià)所(suǒ)示:

通(tòng)用(yòng)占位符图(tú)像

x(t)和(hé)f(α)被(bèi)稱为(wèi)輸入(rù)和(hé)權重(zhòng)函(hán)數。輸出(chū)稱为(wèi)特(tè)征映射。对(duì)于(yú)我(wǒ)们(men)的(de)項目,我(wǒ)们(men)使用(yòng)了(le)2D空間(jiān),过(guò)濾器也(yě)是(shì)2D。我(wǒ)们(men)的(de)卷(juǎn)積层以(yǐ)三(sān)个(gè)輸入(rù)和(hé)一(yī)个(gè)輸出(chū)開(kāi)始。三(sān)个(gè)輸入(rù)表(biǎo)示RGB值。每个(gè)輸入(rù)代(dài)表(biǎo)一(yī)个(gè)通(tòng)道(dào),每个(gè)通(tòng)道(dào)與(yǔ)濾波(bō)器相關(guān)。然後(hòu),bias是(shì)一(yī)个(gè)唯一(yī)的(de)标(biāo)量(liàng)值,它(tā)被(bèi)添加到(dào)每个(gè)像素的(de)卷(juǎn)積层輸出(chū)中(zhōng)。我(wǒ)们(men)得到(dào)了(le)VGG16預訓練數據(jù)集的(de)所(suǒ)有(yǒu)權重(zhòng)和(hé)偏差。每个(gè)輸入(rù)與(yǔ)相應(yìng)的(de)濾波(bō)器相乘,求和(hé)産生(shēng)輸出(chū)結果(guǒ)。下(xià)图(tú)可(kě)以(yǐ)更(gèng)好(hǎo)地(dì)解(jiě)釋卷(juǎn)積計(jì)算的(de)工作原理。

通(tòng)用(yòng)占位符图(tú)像 
卷(juǎn)積层計(jì)算(来(lái)自(zì)[4]作者(zhě):Hadi Kazemi)

彙聚层計(jì)算



池化(huà)层的(de)功能(néng)是(shì)壓縮卷(juǎn)積特(tè)征映射。池化(huà)運算符包(bāo)括最(zuì)大池和(hé)平均池。对(duì)于(yú)我(wǒ)们(men)的(de)項目,我(wǒ)们(men)使用(yòng)了(le)max-pooling。我(wǒ)们(men)使用(yòng)一(yī)个(gè)图(tú)来(lái)说(shuō)明(míng)如(rú)何最(zuì)大化(huà)池工作,它(tā)像一(yī)个(gè)正(zhèng)常的(de)卷(juǎn)積一(yī)樣(yàng)滑動(dòng)一(yī)个(gè)窗(chuāng)口(kǒu),并獲得窗(chuāng)口(kǒu)上(shàng)的(de)最(zuì)大值作为(wèi)輸出(chū)。

通(tòng)用(yòng)占位符图(tú)像 
Max pooling(来(lái)自(zì)[3]作者(zhě):Andrej karpathy)


软(ruǎn)件(jiàn)設計(jì)




通(tòng)用(yòng)占位符图(tú)像

頂級Qsys布(bù)局(jú)


Verilog設計(jì)



FIFO

对(duì)于(yú)FIFO設計(jì),我(wǒ)们(men)使用(yòng)来(lái)自(zì)hackaday的(de)Bruce資源作为(wèi)HPS和(hé)FPGA之間(jiān)的(de)通(tòng)信(xìn)橋(qiáo)梁(liáng)。在(zài)Qsys中(zhōng),定(dìng)義了(le)两(liǎng)个(gè)双(shuāng)端口(kǒu)FIFO,每个(gè)端口(kǒu)都有(yǒu)一(yī)个(gè)端口(kǒu)連(lián)接到(dào)HPS總(zǒng)線(xiàn),另(lìng)一(yī)个(gè)端口(kǒu)輸出(chū)到(dào)FPGA架構。我(wǒ)们(men)使用(yòng)的(de)FIFO深度(dù)为(wèi)256,數據(jù)宽(kuān)度(dù)配置为(wèi)32位。由(yóu)于(yú)我(wǒ)们(men)用(yòng)于(yú)計(jì)算的(de)數據(jù)是(shì)32位,因(yīn)此(cǐ)每次(cì)發(fà)送2个(gè)數據(jù)。对(duì)于(yú)HPS_to_FPGA FIFO,只(zhī)要(yào)有(yǒu)數據(jù),read_buffer_valid将設置为(wèi)1,數據(jù)将保存在(zài)read_buffer中(zhōng)。在(zài)我(wǒ)们(men)处理其他(tā)步驟中(zhōng)的(de)數據(jù)并将read_buffer_valid設置为(wèi)0之前(qián),不(bù)会(huì)读(dú)取(qǔ)新數據(jù)。類(lèi)似于(yú)FPGA_to_HPS,當我(wǒ)们(men)将數據(jù)保存到(dào)write_buffer并将write_valid設置为(wèi)1时(shí),FIFO将读(dú)取(qǔ)該數據(jù),并将其發(fà)送回(huí)HPS并将write_valid設置为(wèi)0以(yǐ)用(yòng)于(yú)下(xià)一(yī)个(gè)輸入(rù)。





通(tòng)用(yòng)占位符图(tú)像
FIFO


通(tòng)用(yòng)占位符图(tú)像

FPGA狀态機(jī)


WAIT_FOR_COMMAND


在(zài)WAIT_FOR_COMMAND狀态下(xià),電(diàn)路(lù)板将等待HPS的(de)輸入(rù)。HPS将生(shēng)成(chéng)一(yī)个(gè)32位命令,前(qián)8位表(biǎo)示FPGA應(yìng)接收(shōu)的(de)數據(jù)包(bāo)編号(hào),以(yǐ)及(jí)下(xià)一(yī)个(gè)狀态的(de)類(lèi)型。在(zài)提(tí)取(qǔ)这(zhè)些信(xìn)息後(hòu),FPGA将從下(xià)一(yī)个(gè)时(shí)鐘(zhōng)切(qiè)換到(dào)新狀态。


LOAD_REG


在(zài)該狀态下(xià),我(wǒ)们(men)有(yǒu)三(sān)个(gè)寄存器(MEM1,MEM2,MEM3)能(néng)够保存226个(gè)16位數據(jù)。我(wǒ)们(men)主(zhǔ)要(yào)使用(yòng)226长度(dù)寄存器用(yòng)于(yú)第(dì)一(yī)級,其具有(yǒu)226x226輸入(rù)大小(用(yòng)于(yú)填充的(de)額外(wài)2位),并且大部(bù)分(fēn)寄存器将不(bù)用(yòng)于(yú)以(yǐ)下(xià)級。这(zhè)里(lǐ)不(bù)使用(yòng)M10K和(hé)MLAB,因(yīn)为(wèi)我(wǒ)们(men)想(xiǎng)要(yào)一(yī)次(cì)訪問(wèn)多(duō)个(gè)數據(jù)。由(yóu)于(yú)寄存器的(de)數量(liàng)非(fēi)常有(yǒu)限,我(wǒ)们(men)将大輸入(rù)文(wén)件(jiàn)分(fēn)成(chéng)幾(jǐ)行。在(zài)該狀态下(xià),每个(gè)时(shí)鐘(zhōng)我(wǒ)们(men)将2个(gè)輸入(rù)數據(jù)加载到(dào)MEM3并向(xiàng)上(shàng)移動(dòng)旧(jiù)數據(jù)。完成(chéng)加载MEM3(旧(jiù)數據(jù)轉(zhuǎn)移到(dào)MEM2和(hé)MEM1)後(hòu),通(tòng)过(guò)将write_buffer_valid更(gèng)改为(wèi)1将ACK(0xffff)信(xìn)号(hào)發(fà)送到(dào)HPS,并将結果(guǒ)保存到(dào)write_buffer。由(yóu)于(yú)濾波(bō)器大小为(wèi)3x3,我(wǒ)们(men)需要(yào)加载三(sān)条(tiáo)線(xiàn)来(lái)啟用(yòng)計(jì)算。每次(cì)我(wǒ)们(men)用(yòng)相應(yìng)的(de)过(guò)濾器完成(chéng)計(jì)算,

LOAD_FIL


在(zài)該狀态下(xià),我(wǒ)们(men)将使用(yòng)從HPS_to_FPGA的(de)read_buffer读(dú)取(qǔ)的(de)權重(zhòng)加载16个(gè)濾波(bō)器,然後(hòu)这(zhè)些16个(gè)濾波(bō)器将用(yòng)于(yú)在(zài)COMPUTE狀态下(xià)從左(zuǒ)到(dào)右(yòu)與(yǔ)加载的(de)寄存器相乘。選擇數字(zì)16有(yǒu)两(liǎng)个(gè)原因(yīn):1。每个(gè)濾波(bō)器将同(tóng)时(shí)執行9次(cì)乘法,因(yīn)此(cǐ)16使得它(tā)在(zài)一(yī)个(gè)时(shí)鐘(zhōng)使用(yòng)144个(gè)乘法器。由(yóu)于(yú)DE1-SOC中(zhōng)有(yǒu)174个(gè)乘數,我(wǒ)们(men)确保數量(liàng)不(bù)会(huì)超过(guò); 2.过(guò)濾器的(de)數量(liàng)是(shì)16的(de)倍數,如(rú)64,128,256,512。如(rú)果(guǒ)我(wǒ)们(men)使它(tā)超过(guò)16或(huò)更(gèng)少(shǎo),我(wǒ)们(men)浪費周期(qī)来(lái)執行如(rú)此(cǐ)繁重(zhòng)的(de)計(jì)算。加载16个(gè)过(guò)濾器後(hòu),ACK信(xìn)号(hào)将被(bèi)發(fà)送回(huí)HPS并切(qiè)換回(huí)WAIT_FOR_COMMAND狀态。


占位符

計(jì)算


我(wǒ)们(men)在(zài)該狀态下(xià)執行加载的(de)寄存器和(hé)过(guò)濾器的(de)乘法運算。模块(kuài)計(jì)算用(yòng)于(yú)執行寄存器的(de)計(jì)算和(hé)过(guò)濾,并總(zǒng)結所(suǒ)有(yǒu)9个(gè)結果(guǒ)。Genvar用(yòng)于(yú)在(zài)always循环(huán)之外(wài)生(shēng)成(chéng)16个(gè)計(jì)算模块(kuài)。每个(gè)模块(kuài)有(yǒu)1个(gè)濾波(bō)器窗(chuāng)口(kǒu)和(hé)1个(gè)寄存器窗(chuāng)口(kǒu)輸入(rù)。在(zài)每个(gè)时(shí)鐘(zhōng)上(shàng),always循环(huán)中(zhōng)的(de)COMPUTE狀态将引發(fà)notein信(xìn)号(hào)以(yǐ)通(tòng)知計(jì)算模块(kuài),填充寄存器窗(chuāng)口(kǒu)(3x3)和(hé)过(guò)濾窗(chuāng)口(kǒu)(3x3)。在(zài)接收(shōu)到(dào)notein信(xìn)号(hào)後(hòu),計(jì)算模块(kuài)将開(kāi)始用(yòng)輸入(rù)模块(kuài)進(jìn)行計(jì)算,并将notein信(xìn)号(hào)傳遞給(gěi)fixedmul模块(kuài),在(zài)此(cǐ)模块(kuài)中(zhōng)執行濾波(bō)器和(hé)寄存器窗(chuāng)口(kǒu)的(de)乘法運算。從fixedmul生(shēng)成(chéng)結果(guǒ)需要(yào)一(yī)个(gè)时(shí)鐘(zhōng),并将notein的(de)值作为(wèi)noteout傳遞回(huí)計(jì)算模块(kuài)。當noteout为(wèi)1时(shí),計(jì)算模块(kuài)總(zǒng)結来(lái)自(zì)fixedmul的(de)結果(guǒ),并将結果(guǒ)和(hé)noteout傳遞給(gěi)外(wài)部(bù)。Notein信(xìn)号(hào)從外(wài)部(bù)傳遞到(dào)計(jì)算,到(dào)fixedmul,計(jì)算到(dào)外(wài)部(bù)。我(wǒ)们(men)这(zhè)樣(yàng)做的(de)原因(yīn)是(shì)同(tóng)步結果(guǒ)并将其正(zhèng)确保存在(zài)結果(guǒ)緩沖區(qū)中(zhōng)。在(zài)时(shí)鐘(zhōng)的(de)每个(gè)上(shàng)升(shēng)沿,寄存器窗(chuāng)口(kǒu)将向(xiàng)右(yòu)移位,結果(guǒ)捕獲将有(yǒu)2个(gè)时(shí)鐘(zhōng)延遲。當我(wǒ)们(men)将所(suǒ)有(yǒu)數據(jù)保存在(zài)結果(guǒ)緩沖區(qū)中(zhōng)时(shí),ACK信(xìn)号(hào)将被(bèi)發(fà)送回(huí)HPS并切(qiè)換回(huí)WAIT_FOR_COMMAND狀态。寄存器窗(chuāng)口(kǒu)将向(xiàng)右(yòu)移動(dòng),結果(guǒ)捕獲将有(yǒu)2个(gè)时(shí)鐘(zhōng)延遲。當我(wǒ)们(men)将所(suǒ)有(yǒu)數據(jù)保存在(zài)結果(guǒ)緩沖區(qū)中(zhōng)时(shí),ACK信(xìn)号(hào)将被(bèi)發(fà)送回(huí)HPS并切(qiè)換回(huí)WAIT_FOR_COMMAND狀态。寄存器窗(chuāng)口(kǒu)将向(xiàng)右(yòu)移動(dòng),結果(guǒ)捕獲将有(yǒu)2个(gè)时(shí)鐘(zhōng)延遲。當我(wǒ)们(men)将所(suǒ)有(yǒu)數據(jù)保存在(zài)結果(guǒ)緩沖區(qū)中(zhōng)时(shí),ACK信(xìn)号(hào)将被(bèi)發(fà)送回(huí)HPS并切(qiè)換回(huí)WAIT_FOR_COMMAND狀态。


RES_WRITE_BACK


在(zài)COMPUTE狀态下(xià),從左(zuǒ)到(dào)右(yòu)的(de)三(sān)行輸入(rù)上(shàng)的(de)16个(gè)濾波(bō)器的(de)乘法結果(guǒ)被(bèi)保存在(zài)res緩沖器中(zhōng)。在(zài)RES_WRITE_BACK狀态,来(lái)自(zì)res緩沖區(qū)的(de)數據(jù)将通(tòng)过(guò)FIFO發(fà)送回(huí)HPS。當write_buffer_valid由(yóu)FIFO設置为(wèi)0时(shí),我(wǒ)们(men)将两(liǎng)个(gè)數據(jù)保存到(dào)write_buffer并将write_buffer_valid設置为(wèi)1,表(biǎo)示數據(jù)已準備就(jiù)緒。發(fà)送完所(suǒ)有(yǒu)結果(guǒ)後(hòu),ACK信(xìn)号(hào)将被(bèi)發(fà)送回(huí)HPS并切(qiè)換回(huí)WAIT_FOR_COMMAND狀态。



HPS設計(jì)

1.Send_command

該函(hán)數将为(wèi)FPGA生(shēng)成(chéng)命令,以(yǐ)設置下(xià)一(yī)个(gè)狀态以(yǐ)及(jí)它(tā)應(yìng)該接收(shōu)的(de)數據(jù)包(bāo)的(de)數量(liàng)。數據(jù)将以(yǐ)如(rú)下(xià)格式發(fà)送:

通(tòng)用(yòng)占位符图(tú)像

2. Load_mem

此(cǐ)函(hán)數将獲取(qǔ)輸入(rù)文(wén)件(jiàn)指針(zhēn),需要(yào)读(dú)取(qǔ)的(de)數字(zì)和(hé)填充選項。此(cǐ)函(hán)數将從輸入(rù)文(wén)件(jiàn)向(xiàng)FPGA發(fà)送一(yī)行,每次(cì)數據(jù)包(bāo)中(zhōng)有(yǒu)2个(gè)數據(jù)。啟用(yòng)填充後(hòu),将在(zài)行的(de)前(qián)端和(hé)末(mò)尾添加0數據(jù),如(rú)果(guǒ)該行是(shì)第(dì)一(yī)行或(huò)最(zuì)後(hòu)一(yī)行,則将發(fà)送整行。在(zài)完成(chéng)發(fà)送所(suǒ)有(yǒu)數據(jù)後(hòu),等待ACK信(xìn)号(hào)并返回(huí)指針(zhēn)以(yǐ)读(dú)取(qǔ)下(xià)一(yī)行。

3. Load_filter

該函(hán)數将采用(yòng)輸入(rù)文(wén)件(jiàn)指針(zhēn),并将16个(gè)濾波(bō)器的(de)內(nèi)容發(fà)送到(dào)FPGA,每个(gè)濾波(bō)器包(bāo)含9个(gè)權重(zhòng)。在(zài)完成(chéng)發(fà)送所(suǒ)有(yǒu)權重(zhòng)後(hòu),等待ACK信(xìn)号(hào)并返回(huí)指針(zhēn)以(yǐ)读(dú)取(qǔ)下(xià)一(yī)个(gè)过(guò)濾器。

4.計(jì)算

向(xiàng)FPGA發(fà)送計(jì)算命令并在(zài)完成(chéng)計(jì)算时(shí)等待ACK信(xìn)号(hào)

5. Getresult

向(xiàng)FPGA發(fà)送命令,詢問(wèn)保存在(zài)結果(guǒ)緩沖區(qū)中(zhōng)的(de)數據(jù)。它(tā)将接收(shōu)所(suǒ)有(yǒu)过(guò)濾器的(de)輸出(chū)文(wén)件(jiàn)的(de)一(yī)行結果(guǒ)。在(zài)load_mem,load_filter和(hé)compute之後(hòu)調用(yòng)它(tā)。

6.輸出(chū)數據(jù)处理

对(duì)于(yú)每个(gè)卷(juǎn)積层,我(wǒ)们(men)将有(yǒu)多(duō)个(gè)輸出(chū)文(wén)本(běn)文(wén)件(jiàn)。对(duì)于(yú)每个(gè)文(wén)件(jiàn),所(suǒ)有(yǒu)數據(jù)都以(yǐ)矩阵(zhèn)格式存儲。每个(gè)數據(jù)是(shì)8.8定(dìng)點(diǎn)格式的(de)16位十(shí)六(liù)進(jìn)制數。我(wǒ)们(men)需要(yào)将每个(gè)十(shí)六(liù)進(jìn)制數轉(zhuǎn)換为(wèi)十(shí)進(jìn)制數。并在(zài)将来(lái)使用(yòng)时(shí)将新數據(jù)輸出(chū)到(dào)文(wén)件(jiàn)中(zhōng)。獲得这(zhè)些輸出(chū)文(wén)件(jiàn)後(hòu),我(wǒ)们(men)可(kě)以(yǐ)将这(zhè)些文(wén)件(jiàn)導入(rù)到(dào)matlab中(zhōng)以(yǐ)生(shēng)成(chéng)功能(néng)图(tú)像。




测試和(hé)結果(guǒ)


我(wǒ)们(men)比較了(le)有(yǒu)和(hé)沒(méi)有(yǒu)FPGA加速器的(de)運行时(shí)間(jiān)和(hé)結果(guǒ)。对(duì)于(yú)未加速的(de)情(qíng)況,我(wǒ)们(men)将代(dài)碼純粹写在(zài)C中(zhōng)。數據(jù)被(bèi)处理为(wèi)浮點(diǎn)用(yòng)于(yú)結果(guǒ)比較和(hé)固定(dìng)點(diǎn)用(yòng)于(yú)速度(dù)比較。

結果(guǒ)比較

由(yóu)于(yú)浮點(diǎn)具有(yǒu)最(zuì)高(gāo)精度(dù),因(yīn)此(cǐ)我(wǒ)们(men)将其視为(wèi)參考,并比較我(wǒ)们(men)的(de)結果(guǒ)與(yǔ)原始結果(guǒ)的(de)距離。正(zhèng)如(rú)我(wǒ)们(men)從輸出(chū)結果(guǒ)中(zhōng)看(kàn)到(dào)的(de),我(wǒ)们(men)從CNN的(de)第(dì)一(yī)层提(tí)取(qǔ)的(de)特(tè)征類(lèi)似于(yú)浮點(diǎn)版本(běn)。當我(wǒ)们(men)研究浮點(diǎn)代(dài)碼生(shēng)成(chéng)的(de)數據(jù)时(shí),我(wǒ)们(men)發(fà)現(xiàn)少(shǎo)量(liàng)數據(jù)的(de)值大于(yú)300,超出(chū)了(le)我(wǒ)们(men)的(de)16位定(dìng)點(diǎn)格式的(de)範圍,它(tā)表(biǎo)明(míng),在(zài)FPGA計(jì)算中(zhōng),溢出(chū)确实發(fà)生(shēng)了(le)但結果(guǒ)并沒(méi)有(yǒu)受到(dào)太大影響。因(yīn)此(cǐ),我(wǒ)们(men)可(kě)以(yǐ)得出(chū)結論,虽然16位定(dìng)點(diǎn)会(huì)偶爾失去(qù)一(yī)定(dìng)程度(dù)的(de)精度(dù)和(hé)溢出(chū),但結果(guǒ)仍然可(kě)靠。


通(tòng)用(yòng)占位符图(tú)像

示例图(tú)片(piàn)



通(tòng)用(yòng)占位符图(tú)像

浮點(diǎn)計(jì)算結果(guǒ)



通(tòng)用(yòng)占位符图(tú)像

FPGA計(jì)算結果(guǒ)


運行时(shí)比較

Speed_FPGA> Speed_HPS_Fixed_point >> Speed_HPS_Floating_point

由(yóu)于(yú)其高(gāo)精度(dù),浮點(diǎn)代(dài)碼需要(yào)最(zuì)长的(de)運行时(shí)間(jiān)。在(zài)HPS定(dìng)點(diǎn)計(jì)算中(zhōng),我(wǒ)们(men)的(de)FPGA加速器速度(dù)提(tí)高(gāo)約12%。階(jiē)段(duàn)1步驟3僅包(bāo)含HPS計(jì)算,因(yīn)此(cǐ)具有(yǒu)非(fēi)常相似的(de)結果(guǒ)。并且FPGA加速器在(zài)解(jiě)決涉及(jí)重(zhòng)度(dù)卷(juǎn)積計(jì)算的(de)階(jiē)段(duàn)(如(rú)階(jiē)段(duàn)1步驟2)方(fāng)面(miàn)表(biǎo)現(xiàn)得更(gèng)好(hǎo)。卷(juǎn)積計(jì)算越多(duō),結果(guǒ)越好(hǎo)。

通(tòng)用(yòng)占位符图(tú)像

最(zuì)後(hòu)結果(guǒ)


摘要(yào)

從流狀态可(kě)以(yǐ)看(kàn)出(chū),我(wǒ)们(men)利用(yòng)了(le)所(suǒ)有(yǒu)DSP模块(kuài)和(hé)88%的(de)ALM。事(shì)实上(shàng),在(zài)該項目期(qī)間(jiān),由(yóu)于(yú)邏輯利用(yòng)失敗,我(wǒ)们(men)失敗了(le)很多(duō)次(cì)。正(zhèng)是(shì)通(tòng)过(guò)优化(huà)結構,我(wǒ)们(men)使其工作,同(tóng)时(shí)不(bù)影響效率。我(wǒ)们(men)克(kè)服(fú)了(le)三(sān)个(gè)最(zuì)難的(de)部(bù)分(fēn):

1.将數據(jù)保存到(dào)寄存器中(zhōng)并将其读(dú)出(chū):

它(tā)看(kàn)起来(lái)很簡單,但在(zài)代(dài)碼開(kāi)發(fà)过(guò)程中(zhōng),我(wǒ)们(men)始終(zhōng)无法從FIFO接收(shōu)數據(jù)并将其保存到(dào)寄存器中(zhōng)。當时(shí)問(wèn)題(tí)在(zài)于(yú)说(shuō)謊并不(bù)簡單,我(wǒ)们(men)所(suǒ)能(néng)做的(de)就(jiù)是(shì)讓LED閃爍以(yǐ)猜测電(diàn)路(lù)板內(nèi)發(fà)生(shēng)了(le)什麼(me)。在(zài)将大件(jiàn)物(wù)品分(fēn)成(chéng)小块(kuài)并在(zài)ModelSim中(zhōng)模拟它(tā)之後(hòu),我(wǒ)们(men)使其成(chéng)功。

2.計(jì)算模块(kuài)執行計(jì)算

一(yī)个(gè)。調試計(jì)算模块(kuài)

一(yī)世。要(yào)找(zhǎo)到(dào)这(zhè)種(zhǒng)同(tóng)步方(fāng)法需要(yào)花費一(yī)定(dìng)的(de)努力。因(yīn)为(wèi)我(wǒ)们(men)不(bù)能(néng)在(zài)always循环(huán)中(zhōng)調用(yòng)類(lèi)似函(hán)數的(de)模块(kuài),所(suǒ)以(yǐ)我(wǒ)们(men)必須找(zhǎo)到(dào)一(yī)種(zhǒng)方(fāng)法来(lái)将輸入(rù)同(tóng)步到(dào)外(wài)部(bù) - 始終(zhōng)模块(kuài),并确切(qiè)地(dì)知道(dào)結果(guǒ)何时(shí)可(kě)以(yǐ)读(dú)取(qǔ)。

II。濫用(yòng)電(diàn)線(xiàn)和(hé)注册。Verilog不(bù)会(huì)为(wèi)連(lián)接生(shēng)成(chéng)錯誤消息,但实際上(shàng),數據(jù)始終(zhōng)无法從fixedmul和(hé)計(jì)算模块(kuài)傳遞出(chū)去(qù)。

湾 在(zài)浮點(diǎn)和(hé)定(dìng)點(diǎn)之間(jiān)進(jìn)行選擇。

我(wǒ)们(men)的(de)初始設計(jì)使用(yòng)了(le)16位浮點(diǎn),但後(hòu)来(lái)我(wǒ)们(men)發(fà)現(xiàn)它(tā)需要(yào)太多(duō)的(de)空間(jiān)和(hé)資源。要(yào)在(zài)FPGA中(zhōng)增加9个(gè)結果(guǒ)需要(yào)4个(gè)时(shí)鐘(zhōng),并且为(wèi)了(le)在(zài)HPS側進(jìn)行計(jì)算,我(wǒ)们(men)需要(yào)設計(jì)处理乘法和(hé)加法的(de)額外(wài)函(hán)數,这(zhè)是(shì)非(fēi)常複雜和(hé)緩慢(màn)的(de)。因(yīn)此(cǐ),我(wǒ)们(men)放(fàng)棄了(le)这(zhè)種(zhǒng)格式,而(ér)是(shì)使用(yòng)定(dìng)點(diǎn)格式。

3.长时(shí)間(jiān)編譯

随着項目變(biàn)得越来(lái)越大,調試时(shí)間(jiān)越来(lái)越长。通(tòng)常的(de)編譯时(shí)間(jiān)是(shì)20分(fēn)鐘(zhōng)来(lái)調試一(yī)个(gè)小東(dōng)西(xī)。



通(tòng)用(yòng)占位符图(tú)像

FPGA結果(guǒ)






結論


我(wǒ)们(men)的(de)系(xì)統專为(wèi)卷(juǎn)積計(jì)算而(ér)設計(jì)。它(tā)不(bù)僅限于(yú)VGG16,還(huán)可(kě)用(yòng)于(yú)執行所(suǒ)有(yǒu)CNN結構的(de)計(jì)算。該項目的(de)主(zhǔ)要(yào)目标(biāo)是(shì)證明(míng)我(wǒ)们(men)的(de)想(xiǎng)法,即FPGA可(kě)用(yòng)于(yú)解(jiě)決卷(juǎn)積計(jì)算,并可(kě)加速整个(gè)过(guò)程。

結果(guǒ)表(biǎo)明(míng)我(wǒ)们(men)的(de)FPGA确实略微加速了(le)这(zhè)个(gè)过(guò)程。虽然加速度(dù)并不(bù)顯着,但仍有(yǒu)很大的(de)空間(jiān)可(kě)以(yǐ)改進(jìn)。在(zài)这(zhè)个(gè)設計(jì)中(zhōng),我(wǒ)们(men)沒(méi)有(yǒu)改變(biàn)FIFO的(de)原始設計(jì),我(wǒ)们(men)保持(chí)字(zì)宽(kuān)为(wèi)32位。最(zuì)大字(zì)宽(kuān)为(wèi)256位,这(zhè)意(yì)味着我(wǒ)们(men)可(kě)以(yǐ)同(tóng)时(shí)發(fà)送16个(gè)數據(jù)而(ér)不(bù)是(shì)2个(gè)。 ,我(wǒ)们(men)使用(yòng)的(de)时(shí)鐘(zhōng)是(shì)最(zuì)慢(màn)的(de),以(yǐ)确保不(bù)会(huì)弄亂系(xì)統的(de)其餘部(bù)分(fēn)。CLOCK_50僅是(shì)最(zuì)快(kuài)时(shí)鐘(zhōng)的(de)1/16,并且比HPS和(hé)FPGA之間(jiān)的(de)通(tòng)信(xìn)以(yǐ)及(jí)其他(tā)計(jì)算慢(màn)。因(yīn)此(cǐ),为(wèi)了(le)更(gèng)好(hǎo)地(dì)提(tí)高(gāo)效率,我(wǒ)们(men)首先(xiān)将两(liǎng)个(gè)FIFO的(de)字(zì)宽(kuān)增加到(dào)256位,这(zhè)比我(wǒ)们(men)當前(qián)的(de)設計(jì)快(kuài)8倍。然後(hòu),我(wǒ)们(men)将使用(yòng)更(gèng)快(kuài)的(de)时(shí)鐘(zhōng)。

FPGA CNN解(jiě)算器的(de)瓶颈在(zài)于(yú)存儲器的(de)限制。由(yóu)于(yú)无法在(zài)電(diàn)路(lù)板上(shàng)保存所(suǒ)有(yǒu)數據(jù),因(yīn)此(cǐ)我(wǒ)们(men)必須在(zài)HPS和(hé)FPGA之間(jiān)移動(dòng)數據(jù),并且大部(bù)分(fēn)时(shí)間(jiān)都丢失了(le)。DE1-SOC板是(shì)執行FPGA計(jì)算的(de)不(bù)錯選擇,我(wǒ)们(men)試图(tú)充分(fēn)利用(yòng)它(tā)。事(shì)实上(shàng),目前(qián)沒(méi)有(yǒu)專門(mén)用(yòng)于(yú)CNN加速的(de)FPGA的(de)良好(hǎo)結構。該項目使我(wǒ)们(men)能(néng)够很好(hǎo)地(dì)了(le)解(jiě)未来(lái)的(de)FPGA CNN加速器是(shì)什麼(me)樣(yàng)的(de),以(yǐ)及(jí)处理數據(jù)的(de)可(kě)能(néng)方(fāng)式。


本(běn)文(wén)摘自(zì):http://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/s2018/yr233_pq32/yr233_pq32/yr233_pq32/index.html#


  •   
  •   
  •   
  •  
  • FPGA教育領域第(dì)一(yī)品牌(pái)
  • 咨詢热(rè)線(xiàn):020-39002701
  • 技術(shù)交流Q群(qún):544453837
⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ 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⁥⁠⁢

⁧⁨⁥⁨