那曲檬骨新材料有限公司

電子發燒友App

硬聲App

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示
電子發燒友網>電子資料下載>電子資料>使用Tensil和PYNQ在PYNQ Z1 FPGA板上運行機器學習

使用Tensil和PYNQ在PYNQ Z1 FPGA板上運行機器學習

2023-06-14 | zip | 0.00 MB | 次下載 | 免費

資料介紹

描述

介紹

教程將使用PYNQ Z1開發板和Tensil 的開源推理加速器來展示如何在 FPGA 上運行機器學習 (ML) 模型。我們將使用在 CIFAR 數據集上訓練的 ResNet-20。這些步驟應該適用于任何受支持的 ML 模型——目前支持所有常見的最先進的卷積神經網絡用你的模型試試吧!

我們將提供易于理解的詳細端到端報道。此外,我們還提供了深入的解釋,以便更好地了解其背后的技術,包括 Tensil 和Xilinx Vivado工具鏈和PYNQ 框架。

如果您遇到問題或發現錯誤,您可以在我們的Discord上提問或發送電子郵件至support@tensil.ai。

pYYBAGNYtROABAshAATdeiNTE-A273.png
?

概述

在開始之前,讓我們看一下 Tensil 工具鏈流程,以鳥瞰我們想要完成的任務。我們將按照以下步驟操作:

  • 獲取張力
  • 選擇架構
  • 生成 TCU 加速器設計(RTL 代碼)
  • 為 PYNQ Z1 合成
  • 為 TCU 編譯 ML 模型
  • 使用 PYNQ 執行
pYYBAGNYtRaAQy8bAAA7S1F49vc285.png
?

1.獲取張力

首先,我們需要獲取 Tensil 工具鏈。最簡單的方法是從 Docker Hub 中拉出 Tensil docker 容器。以下命令將拉取映像,然后運行容器。

docker pull tensilai/tensil
docker run -v $(pwd):/work -w /work -it tensilai/tensil bash

2.選擇架構

Tensil 的優勢在于可定制性,使其適用于非常廣泛的應用。Tensil 架構定義文件 (.tarch) 指定要實現的架構的參數。這些參數使 Tensil 足夠靈活,可以用于小型嵌入式 FPGA 以及大型數據中心 FPGA。我們的示例將選擇在 PYNQ Z1 板核心的 XC7Z020 FPGA 部件上提供最高資源利用率的參數。容器映像方便地包含 PYNQ Z1 開發板的架構文件,位于/demo/arch/pynqz1.tarch. 讓我們來看看里面有什么。

{
    "data_type": "FP16BP8",
    "array_size": 8,
    "dram0_depth": 1048576,
    "dram1_depth": 1048576,
    "local_depth": 8192,
    "accumulator_depth": 2048,
    "simd_registers_depth": 1,
    "stride0_depth": 8,
    "stride1_depth": 8
}

該文件包含一個帶有多個參數的 JSON 對象。第一個data_type定義了整個張量計算單元 (TCU) 中使用的數據類型,包括脈動數組、SIMD ALU、累加器和本地內存。我們將使用 16 位定點和 8 位基點 ( FP16BP8),這在大多數情況下允許對 32 位浮點模型進行簡單舍入,而無需量化。接下來,array_size定義一個 8x8 的脈動陣列大小,這會產生 64 個并行乘法累加 (MAC) 單元。選擇此數字是為了平衡 XC7Z020 上可用的 DSP 單元的利用率,以防您需要將一些 DSP 并行用于另一個應用程序,但您可以增加它以獲得更高的 TCU 性能。

使用dram0_depthdram1_depth,我們定義主機端 DRAM0 和 DRAM1 內存緩沖區的大小。這些緩沖區為 TCU 提供模型的權重和輸入,并存儲中間結果和輸出。請注意,這些內存大小是向量的數量,這意味著數組大小 (8) 乘以數據類型大小(16 位),每個向量總共 128 位。

接下來,我們定義將在 FPGA 架構本身上實現的內存local的大小。accumulator累加器和本地存儲器之間的區別在于,累加器可以執行寫累加操作,其中輸入被添加到已經存儲的數據中,而不是簡單地覆蓋它。再次選擇累加器加上本地內存的總大小來平衡 XC7Z020 上 BRAM 資源的利用率,以防其他地方需要資源。

使用simd_registers_depth,我們指定每個 SIMD ALU 中包含的寄存器數量,它可以對用于 ML 操作(如 ReLU 激活)的存儲向量執行 SIMD 操作。很少需要增加這個數字,以幫助計算特殊的激活函數。最后,stride0_depth指定stride1_depth用于啟用“跨步”內存讀取和寫入的位數。您不太可能需要更改此參數。

3.生成TCU加速器設計(RTL代碼)

現在我們已經選擇了我們的架構,是時候運行 Tensil RTL 生成器了。RTL 代表“寄存器傳輸級別”——它是一種代碼類型,用于指定數字邏輯內容,如線路、寄存器和低級邏輯。Xilinx Vivado 或yosys等特殊工具可以為 FPGA 甚至 ASIC 合成 RTL。

要使用我們選擇的架構生成設計,請在 Tensil 工具鏈 docker 容器中運行以下命令:

tensil rtl -a /demo/arch/pynqz1.tarch -s true

ARTIFACTS該命令將生成最后打印出來的表格中列出的幾個 Verilog 文件。它還RTL SUMMARY使用生成的 RTL 的一些基本參數打印表格。

----------------------------------------------------------------------
RTL SUMMARY
----------------------------------------------------------------------
Data type:                                      FP16BP8   
Array size:                                     8         
Consts memory size (vectors/scalars/bits):      1,048,576 8,388,608 20
Vars memory size (vectors/scalars/bits):        1,048,576 8,388,608 20
Local memory size (vectors/scalars/bits):       8,192     65,536    13
Accumulator memory size (vectors/scalars/bits): 2,048     16,384    11
Stride #0 size (bits):                          3         
Stride #1 size (bits):                          3         
Operand #0 size (bits):                         16        
Operand #1 size (bits):                         24        
Operand #2 size (bits):                         16        
Instruction size (bytes):                       8         
----------------------------------------------------------------------

4. 為 PYNQ Z1 合成

現在是啟動 Xilinx Vivado 的時候了。我將使用版本 2021.2,您可以在Xilinx 網站上免費下載(用于原型制作) 。

在創建新的 Vivado 項目之前,您需要從此處下載 PYNQ Z1 電路板定義文件。打開包裝并將它們放入/tools/Xilinx/Vivado/2021.2/data/boards/board_files/. (請注意,此路徑包括 Vivado 版本。)解壓后,您需要在工具 -> 設置 -> 電路板存儲庫中添加電路板文件路徑。

poYBAGNYtRiAZDDiAACfZ59Uiqw612.png
?

首先,創建一個名為的新 RTL 項目tensil-pynqz1并添加由 Tensil RTL 工具生成的 Verilog 文件。

pYYBAGNYtR2AZGXEAADus4mPhGE553.png
?

選擇板并搜索 PYNQ。選擇文件版本為 1.0 的 PYNQ-Z1。

poYBAGNYtSCAXB39AADDCGCH0o8658.png
?

在 IP INTEGRATOR 下,單擊創建模塊設計。

pYYBAGNYtSKAOjX8AABTq9Ms-34095.png
?

從 Sources 選項卡拖到模塊設計圖上top_pynqz1您應該會看到 Tensil RTL 塊及其接口。

poYBAGNYtSWAWbcQAAAZrKs0MEc784.png
?

接下來,單擊框圖工具欄(左上角)中的加號按鈕并選擇“ZYNQ7 處理系統”(您可能需要使用搜索框)。+對“處理器系統重置”執行相同操作。Zynq 模塊代表賽靈思平臺的“硬”部分,包括 ARM 處理器、DDR 接口等等。Processor System Reset 是一個實用工具箱,可為設計提供正確同步的復位信號。

單擊“運行塊自動化”和“運行連接自動化”。檢查“所有自動化”。

雙擊 ZYNQ7 處理系統。首先,進入時鐘配置并確保 PL Fabric Clocks 已檢查 FCLK_CLK0 并將其設置為 50MHz。

pYYBAGNYtSeAE9zQAAC8a8Ttufc487.png
?

然后,進入 PS-PL 配置。檢查S AXI HP0 FPDS AXI HP1 FPDS AXI HP2 FPD。這些更改將配置我們設計所需的處理系統 (PS) 和可編程邏輯 (PL) 之間的所有必要接口。

poYBAGNYtSyAfndmAADRipVxoOU857.png
?

再次單擊 Block Diagram 工具欄中的加號+按鈕并選擇“AXI SmartConnect”。我們需要 4 個 SmartConnect 實例。前 3 個實例 ( smartconnect_0to smartconnect_2) 是在 PS 上將 TCU 的 AXI 版本 4 接口和指令 DMA 塊轉換為 AXI 版本 3 所必需的。smartconnect_3DMA 控制寄存器暴露給 Zynq CPU 是必要的,這將使軟件能夠控制 DMA 事務。雙擊每一個并將“從屬和主接口數”設置為 1。

pYYBAGNYtS6AQtGdAAA47LJSBg0376.png
?

現在,將Tensil 塊上的對應地連接m_axi_dram0到on 上。然后將 SmartConnect端口相應地連接到Zynq 模塊Zynq 模塊上。TCU 有兩個 DRAM 組,通過使用具有專用連接到內存的 PS 端口來實現它們的并行操作。m_axi_dram1 portsS00_AXIsmartconnect_0smartconnect_1M00_AXIS_AXI_HP0S_AXI_HP2

接下來,單擊 Block Diagram 工具欄中的加號+按鈕并選擇“AXI Direct Memory Access”(DMA)。DMA 塊用于組織 Tensil 程序到 TCU 的饋送,而不會使 PS ARM 處理器保持忙碌。

雙擊它。禁用“Scatter Gather Engine”和“Write Channel”。將“緩沖區長度寄存器的寬度”更改為 26 位。選擇“Memory Map Data Width”和“Stream Data Width”為64位。將“最大突發大小”更改為 256。

pYYBAGNYtTGAUTx2AACH7GKaTH0473.png
?

instruction將Tensiltop模塊上的端口連接到M_AXIS_MM2SAXI DMA 模塊上的端口。然后,將M_AXI_MM2SAXI DMA 模塊連接到S00_AXIon smartconnect_2,最后,將smartconnect_2M00_AXI端口連接到S_AXI_HP1Zynq。

連接M00_AXIAXI DMA 塊上smartconnect_3。將AXI SmartConnectS_AXI_LITE連接到Zynq 模塊。S00_AXIM_AXI_GP0

最后,單擊“運行連接自動化”并選中“所有自動化”。通過這樣做,我們連接了所有的時鐘和復位。單擊 Block Diagram 工具欄中的“Regenerate Layout”按鈕,使圖表看起來更漂亮。

poYBAGNYtTOAA6KvAAEmP9TL65M016.png
?

接下來,切換到“地址編輯器”選項卡。單擊工具欄中的“全部分配”按鈕。通過這樣做,我們將地址空間分配給各種 AXI 接口。例如,指令 DMA ( axi_dma_0) 和 Tensil ( m_axi_dram0and m_axi_dram1) 可以訪問 PYNQ Z1 板上的整個地址空間。PS 可以訪問指令 DMA 的控制寄存器。

poYBAGNYtTeAbMydAADdG6MbWmg490.png
?

返回“框圖”選項卡,單擊“驗證設計”(或 F6)按鈕。您應該會看到通知您驗證成功的消息!您現在可以通過單擊x右上角的來關閉 Block Design。

最后一步是為我們的設計創建 HDL 包裝器,它將把所有東西聯系在一起并支持綜合和實現。右鍵單擊tensil_pynqz1Sources 選項卡中的項目并選擇“Create HDL Wrapper”。保持選中“讓 Vivado 管理包裝器和自動更新”。等待 Sources 樹完全更新并右鍵單擊tensil_pynqz1_wrapper. 選擇設置為頂部。

現在是時候讓 Vivado 執行綜合和實現并寫入生成的比特流了。在 Flow Navigator 側邊欄中,單擊“Generate Bitstream”并點擊 OK。Vivado 將開始合成我們的 Tensil 設計——這可能需要大約 15 分鐘。完成后,您可以在項目摘要中觀察一些重要的統計數據。首先,查看利用率,它顯示了我們的設計正在使用的每個 FPGA 資源的百分比。請注意我們如何將 BRAM 和 DSP 利用率保持在相當低的水平。

pYYBAGNYtTmAQzmgAAAxYW3SP3M518.png
?

第二個是時序,它告訴我們信號在我們的可編程邏輯 (PL) 中傳播需要多長時間。“Worst Negative Slack”是一個正數是個好消息——我們的設計在指定時鐘速度下滿足所有網絡的傳播約束!

poYBAGNYtTuAFFlQAAAnNuyJ7_U095.png
?

5. 為 TCU 編譯 ML 模型

Tensil 工具鏈流程的第二個分支是將 ML 模型編譯為由 TCU 指令組成的 Tensil 二進制文件,這些指令由 TCU 硬件直接執行。在本教程中,我們將使用在 CIFAR 數據集上訓練的 ResNet20。該模型包含在 Tensil 泊塢窗圖像中,位于/demo/models/resnet20v2_cifar.onnx. 在 Tensil docker 容器中,運行以下命令。

tensil compile -a /demo/arch/pynqz1.tarch -m /demo/models/resnet20v2_cifar.onnx -o "Identity:0" -s true

我們使用的是模型的 ONNX 版本,但 Tensil 編譯器也支持 TensorFlow,您可以通過在 TensorFlow 凍結圖形式編譯相同的模型來嘗試/demo/models/resnet20v2_cifar.pb。

tensil compile -a /demo/arch/pynqz1.tarch -m /demo/models/resnet20v2_cifar.pb -o "Identity" -s true

生成的編譯文件列在ARTIFACTS表中。清單 ( tmodel) 是已編譯模型的純文本 JSON 描述。Tensil 程序 ( tprog) 和權重數據 ( tdata) 都是 TCU 在執行期間使用的二進制文件。Tensil 編譯器還會打印一個COMPILER SUMMARY表格,其中包含 TCU 架構和模型的有趣統計數據。

------------------------------------------------------------------------------------------
COMPILER SUMMARY
------------------------------------------------------------------------------------------
Model:                                           resnet20v2_cifar_onnx_pynqz1 
Data type:                                       FP16BP8                      
Array size:                                      8                            
Consts memory size (vectors/scalars/bits):       1,048,576                    8,388,608 20
Vars memory size (vectors/scalars/bits):         1,048,576                    8,388,608 20
Local memory size (vectors/scalars/bits):        8,192                        65,536    13
Accumulator memory size (vectors/scalars/bits):  2,048                        16,384    11
Stride #0 size (bits):                           3                            
Stride #1 size (bits):                           3                            
Operand #0 size (bits):                          16                           
Operand #1 size (bits):                          24                           
Operand #2 size (bits):                          16                           
Instruction size (bytes):                        8                            
Consts memory maximum usage (vectors/scalars):   71,341                       570,728   
Vars memory maximum usage (vectors/scalars):     26,624                       212,992   
Consts memory aggregate usage (vectors/scalars): 71,341                       570,728   
Vars memory aggregate usage (vectors/scalars):   91,170                       729,360   
Number of layers:                                23                           
Total number of instructions:                    258,037                      
Compilation time (seconds):                      25.487                       
True consts scalar size:                         568,466                      
Consts utilization (%):                          97.545                       
True MACs (M):                                   61.476                       
MAC efficiency (%):                              0.000                        
------------------------------------------------------------------------------------------

6.使用PYNQ執行

現在是時候將所有東西放在我們的開發板上了。為此,我們首先需要設置 PYNQ 環境。這個過程從為我們的開發板下載 SD 卡映像開始。PYNQ 文檔網站上有設置板連接的詳細說明。您應該能夠打開 Jupyter 筆記本并運行一些示例。

現在 PYNQ 已經啟動并運行了,下一步是scpPYNQ 的 Tensil 驅動程序。首先將Tensil GitHub 存儲庫克隆到您的工作站,然后復制drivers/tcu_pynq/home/xilinx/tcu_pynq您的板上。

git clone git@github.com:tensil-ai/tensil.git
scp -r tensil/drivers/tcu_pynq xilinx@192.168.2.99:

我們還需要scp比特流和編譯器工件。

接下來,我們將復制比特流,其中包含由 Vivado 綜合和實現產生的 FPGA 配置。PYNQ 還需要一個硬件切換文件,該文件描述主機可訪問的 FPGA 組件,例如 DMA。將兩個文件都/home/xilinx放在開發板上。假設您位于 Vivado 項目目錄中,請運行以下命令復制文件。

scp tensil-pynqz1.runs/impl_1/tensil_pynqz1_wrapper.bit xilinx@192.168.2.99:tensil_pynqz1.bit
scp tensil-pynqz1.gen/sources_1/bd/tensil_pynqz1/hw_handoff/tensil_pynqz1.hwh xilinx@192.168.2.99:

請注意,我們重命名了比特流以匹配硬件切換文件名。

.tmodel現在,將編譯器生成的、.tprog.tdata工件復制到/home/xilinx板上。

scp resnet20v2_cifar_onnx_pynqz1.t* xilinx@192.168.2.99:

運行我們的 ResNet 模型的最后一件事是 CIFAR 數據集。您可以從Kaggle獲取它或運行以下命令(由于我們只需要測試批次,因此我們刪除了訓練批次以減小文件大小)。把這些文件/home/xilinx/cifar-10-batches-py/放在你的開發板上。

wget http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
tar xfvz cifar-10-python.tar.gz
rm cifar-10-batches-py/data_batch_*
scp -r cifar-10-batches-py xilinx@192.168.2.99:

我們終于準備好啟動 PYNQ Jupyter notebook 并在 TCU 上運行 ResNet 模型。

Jupyter 筆記本

首先,我們導入 Tensil PYNQ 驅動程序和其他必需的實用程序。

import sys
sys.path.append('/home/xilinx')

# Needed to run inference on TCU
import time
import numpy as np
import pynq
from pynq import Overlay
from tcu_pynq.driver import Driver
from tcu_pynq.architecture import pynqz1

# Needed for unpacking and displaying image data
%matplotlib inline
import matplotlib.pyplot as plt
import pickle

現在,從比特流初始化 PYNQ 覆蓋并使用 TCU 架構和覆蓋的 DMA 配置實例化 Tensil 驅動程序。請注意,我們axi_dma_0從疊加層傳遞對象——名稱與 Vivado 設計中的 DMA 模塊匹配。

overlay = Overlay('/home/xilinx/tensil_pynqz1.bit')
tcu = Driver(pynqz1, overlay.axi_dma_0)

Tensil PYNQ 驅動程序包括 PYNQ Z1 架構定義。這里是摘錄自architecture.py:您可以看到它與我們之前使用的架構相匹配。

pynqz1 = Architecture(
    data_type=DataType.FP16BP8,
    array_size=8,
    dram0_depth=1048576,
    dram1_depth=1048576,
    local_depth=8192,
    accumulator_depth=2048,
    simd_registers_depth=1,
    stride0_depth=8,
    stride1_depth=8,
)

接下來,讓我們從test_batch.

def unpickle(file):
    with open(file, 'rb') as fo:
        d = pickle.load(fo, encoding='bytes')
    return d

cifar = unpickle('/home/xilinx/cifar-10-batches-py/test_batch')
data = cifar[b'data']
labels = cifar[b'labels']

data = data[10:20]
labels = labels[10:20]

data_norm = data.astype('float32') / 255
data_mean = np.mean(data_norm, axis=0)
data_norm -= data_mean

cifar_meta = unpickle('/home/xilinx/cifar-10-batches-py/batches.meta')
label_names = [b.decode() for b in cifar_meta[b'label_names']]

def show_img(data, n):
    plt.imshow(np.transpose(data[n].reshape((3, 32, 32)), axes=[1, 2, 0]))

def get_img(data, n):
    img = np.transpose(data_norm[n].reshape((3, 32, 32)), axes=[1, 2, 0])
    img = np.pad(img, [(0, 0), (0, 0), (0, tcu.arch.array_size - 3)], 'constant', constant_values=0)
    return img.reshape((-1, tcu.arch.array_size))

def get_label(labels, label_names, n):
    label_idx = labels[n]
    name = label_names[label_idx]
    return (label_idx, name)

要進行測試,請提取其中一張圖像。

n = 7
img = get_img(data, n)
label_idx, label = get_label(labels, label_names, n)
show_img(data, n)

你應該看到圖像。

poYBAGNYtT2AfjwZAAAm3oVjfnk778.png
?

接下來,tmodel將模型的清單加載到驅動程序中。清單告訴驅動程序在哪里可以找到其他兩個二進制文件(程序和權重數據)。

tcu.load_model('/home/xilinx/resnet20v2_cifar_onnx_pynqz1.tmodel')

最后,運行模型并打印結果!調用tcu.run(inputs)是魔法發生的地方。我們將 ResNet 分類結果向量轉換為 CIFAR 標簽請注意,如果您使用的是 ONNX 模型,則輸入和輸出分別命名為x:0Identity:0。對于 TensorFlow 模型,它們被命名為xIdentity。

inputs = {'x:0': img}

start = time.time()
outputs = tcu.run(inputs)
end = time.time()
print("Ran inference in {:.4}s".format(end - start))
print()

classes = outputs['Identity:0'][:10]
result_idx = np.argmax(classes)
result = label_names[result_idx]
print("Output activations:")
print(classes)
print()
print("Result: {} (idx = {})".format(result, result_idx))
print("Actual: {} (idx = {})".format(label, label_idx))

這是預期的結果:

Ran inference in 0.1513s

Output activations:
[-19.49609375 -12.37890625  -8.01953125  -6.01953125  -6.609375
  -4.921875    -7.71875      2.0859375   -9.640625    -7.85546875]

Result: horse (idx = 7)
Actual: horse (idx = 7)

恭喜!您運行了一個機器學習模型,一個您在自己的工作站上構建的自定義 ML 加速器!想象一下你可以用它做的事情......

包起來

在本教程中,我們使用 Tensil 展示了如何在 FPGA 上運行機器學習 (ML) 模型。我們經歷了許多步驟,包括安裝 Tensil、選擇架構、生成 RTL 設計、綜合設計、編譯 ML 模型,最后使用 PYNQ 執行模型。

如果你一路走來,那么恭喜你!通過嘗試自己的模型和架??構,您已準備好將事情提升到一個新的水平。加入我們的Discord打個招呼并提出問題,或發送電子郵件至support@tensil.ai。


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數據手冊
  2. 1.06 MB  |  532次下載  |  免費
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費
  5. 3TC358743XBG評估板參考手冊
  6. 1.36 MB  |  330次下載  |  免費
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費
  9. 5元宇宙深度解析—未來的未來-風口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費
  11. 6迪文DGUS開發指南
  12. 31.67 MB  |  194次下載  |  免費
  13. 7元宇宙底層硬件系列報告
  14. 13.42 MB  |  182次下載  |  免費
  15. 8FP5207XR-G1中文應用手冊
  16. 1.09 MB  |  178次下載  |  免費

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費
  3. 2555集成電路應用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費
  7. 4開關電源設計實例指南
  8. 未知  |  21549次下載  |  免費
  9. 5電氣工程師手冊免費下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費
  11. 6數字電路基礎pdf(下載)
  12. 未知  |  13750次下載  |  免費
  13. 7電子制作實例集錦 下載
  14. 未知  |  8113次下載  |  免費
  15. 8《LED驅動電路設計》 溫德爾著
  16. 0.00 MB  |  6656次下載  |  免費

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費
  3. 2protel99se軟件下載(可英文版轉中文版)
  4. 78.1 MB  |  537798次下載  |  免費
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費
  11. 6電路仿真軟件multisim 10.0免費下載
  12. 340992  |  191187次下載  |  免費
  13. 7十天學會AVR單片機與C語言視頻教程 下載
  14. 158M  |  183279次下載  |  免費
  15. 8proe5.0野火版下載(中文版免費下載)
  16. 未知  |  138040次下載  |  免費
宜丰县| 属马的和属猴的在一起做生意好吗| 玩百家乐去哪个娱乐城最安全| 网络百家乐免费试玩| 澳门百家乐官网的玩法技巧和规则| 百家乐官网翻天快播粤语| 百家乐网站| 皇冠网小说网址| 博彩优惠| 大发888真钱账户注册| 新濠百家乐娱乐场| 百家乐官网网络赌场| 百家乐官网微笑不倒| 武汉百家乐官网庄闲和| 怎么玩百家乐官网网上赌博| 葡京百家乐官网注码 | 夏津县| 土默特左旗| 栾城县| 在线百家乐官网大家赢| 太阳城百家乐官网试玩优惠| 百家乐官网投注技巧公式| 百家乐官网娱乐城博彩| 百家乐官网投注系统| 金花百家乐官网娱乐城| 送彩金百家乐官网平台| 百家乐官网赌场技巧论坛| 百家乐官网庄闲对冲| CEO百家乐官网的玩法技巧和规则| 全讯网百家乐官网的玩法技巧和规则 | 赌百家乐官网的玩法技巧和规则| 百家乐官网大路图| 皇马百家乐官网的玩法技巧和规则| 免费百家乐官网过滤| 墓地附近做生意风水| 新澳门百家乐娱乐城| 百家乐定位胆技巧| 大发888备用网| 博盈国际| 百家乐官网投注方式| 澳门百家乐官网规律星期娱乐城博彩 |