差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
pagename [2019/08/17 18:46]
xuhao [FPGA]
— (当前版本)
行 1: 行 1:
-# KiCad pcb和原理图设计 
-  * KiCad,是一款免费开源的PCB设计工具,提供了一个用于原理图输入和PCB布局布线的集成化开发环境,在这个工具中还有用于产生BOM、Gerber文件、对PCB及其上元器件进行3D查看的功能,支持Python脚本定制。  ​ 
-  * KiCad资源 
-    * [参考资料](https://​www.eetree.cn/​wiki/​kicad) 
-    * [官方库](https://​kicad.github.io/​) 
-    * [Ultra Librarian](https://​www.ultralibrarian.com/​) 
-    * [SamacSys](www.samacsys.com) 
-  * 几点心得 
-    * 少用标签 
-    * 布局布线的时候首先考虑地线,注意区分数字地和模拟地。 
-    * 设计的时候一定要规范,严谨 
- 
-# FPGA、Verilog和小脚丫 
- 
-## FPGA 
-  * Altera/​Intel,​ Xilinx, Lattice Semi 
-  * 硬件设计思想 
-    * 善用IP Core:调用原厂提供的经过验证过的IP内核 
-    * 硬件设计概念:并行工作、时延 
-    * 充分仿真:功能仿真、时序仿真、TestBench 
-  * FPGA设计流程 
- 
- 
-    * 设计准备:方案论证、系统级设计 
-    * 设计输入:将所涉及的系统或电路以开发软件要求的某种形式表示出来,并送入计算机的过程。包括原理图输入、硬件描述语言输入、波形输入、IP核、状态机和网表等。 
-    * 功能仿真:(前仿真?),进行逻辑功能验证。利用波形编辑器和硬件描述语言等建立TestBench,分析仿真报告文件和输出信号波形。没有时延信息,仅验证电路的逻辑功能。 
-    * 设计处理:编译软件对设计输入文件进行逻辑简化、综合优化和适配,产生编程文件。 
-      * 语法检查和设计规则检查 
-      * 逻辑优化和综合:在给定标准元件库和一定设计约束条件下,设计描述从较高层次向较低抽象层次的自动转换和优化过程,有专门的综合器来实现。包括高层次综合(HLS)、门级综合(将高级硬件描述语言转换为门级网表,行为综合、RTL综合)。**可综合的硬件描述语言需要满足一定的语法**,与综合器和器件相关 
-      * 适配和分割 
-      * 布局和布线 
-      * 生成编程文件 
-    * 综合后门级功能仿真:前仿真 
-    * 时序仿真:后仿真,在布局布线后,对系统和各模块进行时序仿真,估计设计的性能,以及检查和消除竞争冒险等。考虑实际器件中的延时问题。 
-    * 器件编程与测试: 
-      * 传统调试:示波器、逻辑分析仪等 
-      * 软件逻辑分析仪:FPGA 片内集成化信号分析工具,利用 FPGA 中未使用的逻辑资源和块存储器,根据用户设定的触发条件,将信号实时的保存到块存储器中,再通过 JTAG 接口传送到计算机,通过计算机的用户界面显示出所采集的时序波形。 
- 
-## Verilog 
-  * 三大特点:并行性,时序性,互连性 
-  * 三种描述方式:数据流描述(assign连续赋值语句),行为级描述(always,​ initial等块语句),结构化模型(实例化功能模块) 
-  * 四种逻辑值:低、高、不定(X)和高阻(H)。**注:在程序设计时,也要考虑到不定状态和高阻状态。** 
-  * 两种变量 
-    * 线网数据类型(wire):​不具备数据存取功能,表示互连关系。只能在alwags语句块之外,被连续赋值(assign)。 
-    * 寄存器数据类型(reg):​可以存取最后一次的赋值,只能在always和initial语句块中被赋值。 
-  * 两种参数类型 
-    * parameter定义的参数:​模块内有效,例化时可以通过参数传递更改参数值; 
-    * localparam定义的参数:不可传递更改。 
-  * 两种赋值: 
-    * 阻塞赋值方式(=):块内语句**逐条**进行赋值,在组合逻辑内使用;​ 
-    * 非阻塞赋值方式(<​=):块内赋值语句**同时**执行,在时序逻辑内使用。 
-  * 几种常用知识点 
-    * 连续赋值语句 assign 
-    * 拼接运算符:{A,​ B} 将A和B连接起来;{B{A}} 将A重复B次 
-    * ·define <​宏名>​ <​宏文本>​ 
-    * ·include "​文本名"​ 
-    * ·timescale 1ns/100ps :指定仿真时间单位和仿真精度  ​ 
- 
- 
-```verilog 
-//​基本语法结构 
-module Decode38(A_in,​ Y_out); ​  //​模块名称(端口列表) 
-//​端口定义申明: 
-input [2:0] A_in; 
-output reg [7:0] Y_out; 
-//​内部变量及参数申明 
- 
-//​模块功能实现 
-always@(A_in) 
-begin 
-    case(A_in) 
-        3'​b000:​ Y_out = 8'​b1111_1110;​ 
-        3'​b001:​ Y_out = 8'​b1111_1101;​ 
-        3'​b010:​ Y_out = 8'​b1111_1011;​ 
-        3'​b011:​ Y_out = 8'​b1111_0111;​ 
-        3'​b100:​ Y_out = 8'​b1110_1111;​ 
-        3'​b101:​ Y_out = 8'​b1101_1111;​ 
-        3'​b110:​ Y_out = 8'​b1011_1111;​ 
-        3'​b111:​ Y_out = 8'​b0111_1111;​ 
-        default: Y_out = 8'​b1111_1111;​ 
-    endcase 
-end 
- 
-endmodule ​  //​模块结束 
-``` 
- 
-## 小脚丫 
-  * 以Lattice LCMX02-4000HC-4MG132芯片为核心,4320个LUT逻辑资源,36个用户IO,板载编程器,开发工具Lattice Diamond。([开源社区](https://​www.stepfpga.com/​doc/​stepfpgaboard)) 
-  * 按键消抖处理:在检测到按键下降沿后,延时20ms,检测到低电平后输出按键按下的脉冲信号。 
-    * 脉冲边沿检测:利用非阻塞赋值特性,保留两个时钟周期内的按键值 
-    * 延时:通过计数器计数时钟脉冲实现 
-    * 巧妙地有效脉冲信号生成方式 
- 
- 
-```verilog 
-assign ​ key_edge = key_rst_pre & (~key_rst);//​脉冲边沿检测。当key检测到下降沿时,key_edge产生一个时钟周期的高电平 
- 
-always @(posedge clk  or  negedge rst) 
-    begin 
-        if (!rst) ​ 
-        key_sec <= {N{1'​b1}}; ​               ​ 
-    else if (cnt==18'​h3ffff) 
-        key_sec <= key;  ​ 
-    end 
-    always @(posedge clk  or  negedge rst) 
-        begin 
-            if (!rst) 
-                key_sec_pre <= {N{1'​b1}};​ 
-            else                    
-                key_sec_pre <= key_sec; ​             
-        end      ​ 
-    assign ​ key_pulse = key_sec_pre & (~key_sec); 
-``` 
- 
-  * 时钟分频 
-    * 偶数n分频:计数器对时钟信号上升沿计数到n,计数到 n/2-1 时将信号翻转; 
-    * 奇数n分频:计数器分别对时钟信号上升沿和下降沿计数到n,计数到 (n-1)/2 时将信号翻转,形成clk_p和clk_n信号,二者相与输出最后结果。 
- 
-```verilog 
-assign clkout = (N==1)?​clk:​(N[0])?​(clk_p&​clk_n):​clk_p;​ //​对clk进行N分频 
-``` 
- 
-  * 状态机 
-  * 数据传输总线 
-    * 串行和并行:串行总线由一根数据线每次传输1bit的数据;并行总线由多根数据线同时传输多位数据。 
-    * 同步和异步:同步通信会在传输数据的同时传递同步的时钟信号,接收端按照时钟信号接收数据;异步通信值传输数据,接收端按照预先规定好的时钟频率接收数据。 
-    * 单工、全双工和半双工:单工通信仅在一个方向上传输数据,全双工通信使两个设备同时收发数据,半双工通信使设备轮流发送或接收数据。 
-    * SPI(Serial Peripheral Interface) **同步串行**外设总线 
-      * 四根信号线(SCLK,​ MOSI, MISO, SS) 
-        - SCLK:串行时钟 
-        - MOSI:数据通道,主设备=>​从设备 
-        - MISO:数据通道,从设备=>​主设备 
-        - SS:设备选通信号 
-      * 通信时序 
-    * I2C(Inter-Integrated Ciruits) **同步串行**总线,集成电路之间的连接 
-      * 两根信号线(SCL、SDA)必须要有上拉电阻 
-      * 通信时序按字节交换信息,每个字节后跟一个ACK或NACK 
-    * UART(Universal Asynchronous Receiver/​Transmitter) **异步串行**总线 
-      * 通信时序:起始位、数据位、校验位、停止位、空闲位 
-    * 几点心得:在verilog设计实现UART功能时,检验起始位下降沿后开启Boud时钟,在Boud时钟中间读取Rx数据,能够保证数据的稳定性;除了UART的基本的并行数据和串行数据相互转化外,可以添加FIFO缓存单元,避免数据丢失;在利用UART通信的时候,可以采用数据帧的格式发送数据,以帧头、数据个数、数据、帧校验和帧尾的格式来传输数据。 
-  * IP核例化:IP核(Intellectual Property core知识产权核)是一段具有特定电路功能的硬件描述语言程序,该程序与集成电路工艺无关,可以移植到不同的半导体工艺中去生产集成电路芯片。在FPGA的设计中调用IP核可以简化设计流程。 
- 
- 
-# Python基本语法和网络爬虫 
-  * 数组操作 numpy 
-  * 数据分析与可视化 pandas, matplotlib.pylot 
-    * 基于matplotlib的图形可视化python包 seaborn 
-  * 网络爬虫 requests, BeautifulSoup 
- 
- 
-# 机器视觉和神经网络 
-  * 图像处理 opencv(c++ & python) 
-  * 神经网络 tensorflow 
-    * 全连接神经网络 
-    * 卷积神经网络 
-      * 池化 
-      * padding 
-    * 激活函数 
-    * 反向传播 
-    * dropout 
-    * Batch Normalization 
-  * http://​www.tensorfly.cn/​tfdoc/​tutorials/​mnist_beginners.html 
- 
-# PYNQ和Vivado 
- 
-# MNIST数据集训练与加速 
- 
-## 方案思路 
-  * 利用tensorflow训练神经网络识别mnist数据集,保存训练参数;利用vivado hls定制卷积和池化ip核;在pynq上复现训练好的神经网络,导入网络参数,利用硬件加速手写数字识别。 
-  * mnist神经网络的搭建和训练([深入MNIST](http://​www.tensorfly.cn/​tfdoc/​tutorials/​mnist_pros.html)) 
-    * 开发工具 PyCharm, python 3.7, tensorflow 1.14.0 
-    * 搭建四层的神经网络: 
-        * (1, 5, 5, 32)卷积,relu激活,2X2池化; 
-        * (32, 5, 5, 64)卷积,relu激活,2X2池化; 
-        * (7X7X64, 1024)全连接层,relu激活,dropout; 
-        * (1024, 10)全连接输出层,softmax分类; 
-  * 如何保存训练数据?训练好的网络参数是以浮点数(float)类型存储,而在硬件电路中,浮点数计算较慢,所以把网络参数转化为定点数类型导入网络。设计的硬件ip中,乘法运算采用int16型乘法,所以网络权重参数采用int16存储,但可以配置小数点位数(fraction_cnt)来存储小数(= int16 / pow(2, fraction_cnt))。将数据以字节的形式存放在bin中。 
- 
- 
-## vivado综合硬件模块:卷积和池化 
- 
-### 开发工具 ​ 
-  * Vivado HLS, Vivado 
- 
-### 池化ip的生成 
-  * 打开Vivado HLS,建立工程pool_stream,新建源文件“pool_stream.cpp”、“pool_stream.h”和测试文件“testbench.cpp”。 
-  * 编写基于c++的池化算法: 
-    * 输入和输出优化:①流的形式 ②输入通道方向按K分块 
-    * pool1D:按行进行池化 
-    * pool2D:按列进行池化 
- 
-```c 
-#define K 8 
-typedef ap_int<​16> ​  ​dtype_dat;​ 
-typedef ap_int<​16*K>​ dtype_bus; 
-typedef struct 
-{ 
-    dtype_bus data; 
-    bool last; 
-}dtype_stream;​ 
-``` 
-```c 
-void pool_1D(hls::​stream<​dtype_bus>​ &​in,​hls::​stream<​dtype_bus>​ &​out,​int ch_div_K,​int height_in,​int width_in,​int Kx) 
-``` 
-  参数说明:  ​ 
-  **in** 特征数据流按照[ch_div_K][height_in][width_in]顺序输入;  ​ 
-  **out** 特征数据流按照[ch_div_K][height_in][width_out]顺序输出;  ​ 
-  **Kx** 特征数据流按行进行Kx池化。 
- 
-```c 
-void pool_2D(hls::​stream<​dtype_bus>​ &​in,​hls::​stream<​dtype_bus>​ &​out,​int ch_div_K,​int height_in,​int width_out,​int Ky) 
-``` 
-  参数说明:  ​ 
-  **in** 特征数据流按照[ch_div_K][height_in][width_out]顺序输入;  ​ 
-  **out** 特征数据流按照[ch_div_K][height_out][width_out]顺序输出;  ​ 
-  **Ky** 特征数据流按列进行Ky池化。 
- 
-  * 优化选项与接口协议设置 
-    * 对语句块的优化:pipeline与 unroll 
-    * 对循环块仿真次数的设置:tripcount 
-    * 对数据存储方式的优化:partition 与 reshape 
-    * 对数据流(stream)的优化:dataflow 
-    * 接口协议设置:ap_hs,​ m_axi, s_axilite, axis等 
- 
-```c 
-void pool(hls::​stream<​dtype_bus>​ &​in,​hls::​stream<​dtype_stream>​ &out, 
-int ch_div_K,​int height_in,​int width_in, 
-int height_out,​int width_out,​int Kx,int Ky) 
-{ 
-    #pragma HLS INTERFACE s_axilite port=return 
-    #pragma HLS INTERFACE s_axilite port=Ky 
-    #pragma HLS INTERFACE s_axilite port=width_in 
-    #pragma HLS INTERFACE s_axilite port=Kx 
-    #pragma HLS INTERFACE s_axilite port=height_in 
-    #pragma HLS INTERFACE s_axilite port=height_out 
-    #pragma HLS INTERFACE s_axilite port=width_out 
-    #pragma HLS INTERFACE s_axilite port=ch_div_K 
- 
-    #pragma HLS DATAFLOW 
-    #pragma HLS INTERFACE axis register both port=out 
-    #pragma HLS INTERFACE axis register both port=in 
- 
-    hls::​stream<​dtype_bus>​ stream_tp; 
-    #pragma HLS STREAM variable=stream_tp depth=8 dim=1 
- 
-    hls::​stream<​dtype_bus>​ stream_tp2; 
- 
-    pool_1D(in,​stream_tp,​ch_div_K,​height_in,​width_in,​Kx);​ 
-    pool_2D(stream_tp,​stream_tp2,​ch_div_K,​height_in,​width_out,​Ky);​ 
-    hs2axis(stream_tp2,​out,​ch_div_K,​height_out,​width_out);​ 
-} 
-``` 
- 
-  * C仿真、C综合和 C&​RTL联合仿真  ​ 
-    * C仿真是用来检验C++程序的功能,通过编写techbench实现; 
-    * C综合是根据上述设定的优化选项和接口协议等将C++程序综合成RTL级HDL语言,并生成综合报告,描述综合后的硬件的时序、消耗的逻辑资源和对外接口类型。 
-    * C&​RTL联合仿真是对综合出来的硬件进行仿真,分析仿真波形来修改C++程序或优化选项等。 
-  * 生成IP核 
-    * 选择 Export RTL生成ip核,包括硬件描述、HDL程序和C驱动程序等。在Vivado中调用生成的ip核时,需要将生成的文件夹添加到Vivado的ip搜索目录下;配置ip时参考driver目录下的xxx_hw.h文件。 
- 
- 
-### 卷积ip的生成(同上,略) 
-  * 卷积算法 
- 
-## jupyter硬件加速识别数字 
-  * Vivado构建pynq的overlay——利用ip配置pynq中的PL部分 
-  *