提到FPGA,也许大家想到的都是国外那几个厂商,而事实上,目前国产FPGA也拥有了许多性能强劲、性价比高的产品。不过,光是嘴上说说并不能深入人心,今天,我们就买来三款含有国产FPGA芯片的板子,实际评测国产FPGA到底什么水平。 国产FPGA安路 高集成低功耗SF1系列
作者:常见泽1
第一篇、开箱+软硬件环境搭建
搭建软件环境 Risc-v MCU的开发环境,是免安装的安装FPGA TD软件安装好了后,可能需要license以前license需要找管理员要,现在我发邮件给管理员直接给了我下载地址,下载好了复制过来,安装下载器的驱动 第二篇 熟悉创建工程+点亮LEDLED点灯 第一次用国产的FPGA的IDE感觉很不适应 编译 重新Syn Opt上右键->Rerun 点击RUN就能看到三个LED灯开始闪烁 但是掉电后,在商店,你回发现LED没了这种方法其实没有下载到FLASH中去第三篇、门电路以及选择器电路测试
数据选择器 数据选择器的功能是根据选择信号决定哪路输入信号送到输出信号,输出信号不仅与输入信号有关,还与选择信号有关设置了一个选择信号sel 约束:a-H3-key0b-H2-key1sel –G3 –key2out – J4 – LED_R 开始测试: 按下拉低如果sel为低KEY2按下,输出的LED和KEY0的电平一样如果sel为高KEY2不按,输出的LED和KEY1的电平一样 门电路设计一个与门 一个非门 一个或们第四篇 PLL核初试IP核“IP”是指“知识产权(Intellectual Property)”。“IP核”是指在一些数字电路中使用的比较复杂的功能块,这些功能块可以运用在日常开发中,从而减少设计的工作量,大大缩短开发周期。IP核分类IP核有三种不同的存在形式:HDL语言、网表文件、版图形式。分别对应日常所说的:软核、固核、硬核。 软核软核是指用HDL语言描述的功能块,通常以硬件描述语言的形式出现。主要的优点是设计周期短,设计投入少,且部分功能可以由用户自行修改,灵活度高,但安全度也是最低的。硬核硬核可以提供设计阶段的最后产品—掩膜。以经过完全布局布线的网表文件形式提供。硬核的灵活性不如软核和固核,但由于无法提供RTL文件,安全性非常可靠。固核固核是软核和硬核的折中。指带有平面规划信息的网表,在设计中看作带有布局规划的软核,将RTL 描述结合具体标准单元库进行综合优化设计,形成门级网表,再通过布局布线工具即可使用。和软核相比固核缺少灵活性,但安全性高。目前也是市场上主流的IP核形 PLL 的英文全称是 Phase Locked Loop,即锁相环,是一种时钟反馈电路,具有时钟倍频、分频、相位偏移、 可编程占空比和优化抖动等功能。为了方便我们使用这些功能,各大FPGA厂商都提供了 PLL IP 核,例如xilinx和安陆等 5M的CLK1M是1us 5M应该是200ns测试波形不是很好但是频率是对的 200ns左右 第五篇、简单的计数器和D触发器设计简单D触发器的设计 D触发器功能是在时钟的上升沿(在时序电路设计中经常使用时钟的边沿,即上升沿与下降沿,上升沿为时钟信号由低变高的跳变,下降沿为时钟信号由高到低的跳变),把D触发器的输入送到输出。简单计数器的设计 计数器作为时序电路的基本器件,是一种最简单基本的运算,计数器就是实现这种运算的逻辑电路,计数器在数字系统中主要是对脉冲的个数进行计数。
当按键按下,计算CLK的时钟数CLK配置为KEYUP_DOWN配置为KEYCOUNTER配置为3个LED灯当UP_DOWN按下后,没按一次CLK的KEY,LED灯从001到111开始亮灯第六篇、UART发送一 UART协议UART协议格式信号线上空闲的时候为高电平,当出现下跳到低电平的时候表示数据的起始位,接着是先发送低位(LSB)后发送高位(MSB)的数据流,后面可以加奇偶校验位(也可以不加,无校验),最后加停止位,停止位长度是可以定义的。 在信息传输中,携带数据信息的信号单元叫码元,每秒钟通过信号传输的码元数称为码元的传输速率,简称波特率,单位为“波特每秒(Bps)”。串口常见的波特率有9600、 115200 等。 二 编写本例入门级简单的试验,准备固定bps为9600,每秒可以传输9600个bit的数据,发送 1bit 数据的时间为一个波特,即 1/9600 秒,晶振为25MHz(周期40ns)计数,需要计数的个数为 cnt = (1s * 10^9)ns /9600bit)ns / 40ns ≈ 2604 个系统时钟周期,即每个 bit 数据之间的间隔要在 50MHz 的时钟频率下计数 2604 次。 三 管脚 EEWORLDIMGTK2板载的usb转uart口四测试下载后进行测试EEWORLDIMGTK3第七篇、RISC-V IP及MCU编程 最后发现还得上层再编程不如直接用官方的例程改 打开MCU的软件,简单的IO编程然后编译,生成可执行文件 同时下载老是出问题,经过摸索终于发现,是要先导入Bit和HEX。 然后修改Mode,还得改成Hex。再点RUN。 国产FPGA高云GW1N 系列开发板
作者:littleshrimp
开发板开箱 之前买过2个高云的FPGA小板,对他家的FPGA印象深刻,之前的板子因为集成度比较高应用起来不是很灵活。论坛这次评测活动提供的高云FPGA开发板应用起来就比较灵活,BANK电压使用跳线连接,需要修改时可以直接使用外部供电。仿真器使用跳线连接,可对外仿真也可使用外部仿真器对内仿真。板子上带了一个SPI FLASH的预留焊盘,手册上是有芯片的,实际收到的板子没有焊,在某宝看了一下3块钱左右包邮就能弄一个,需要时可以自己焊上。没带芯片可能还有一个好处,就是如果不需要大FLASH也许可以考虑焊一颗SPI 的PSRAM(没具体分析,是否可行有待验证)。 快递收到时感觉包装有点大,以为盒子里除了板子还有什么“礼品”奖励, 拆开后里里边的包装盒就这么大。难道包装盒里除了开发板还带了其它工具? 打开包装盒后,里边好像真的有,不过这次没有。 不光是盒子大,包装袋也是大尺寸的。 取出板子后,黑黑的板子,很新。看背面的日期是2019年8月生产的,这么好的FPGA以前怎么不知道呢。不过这个板子也有不足,虽然这个板子出厂已经2年了,里边的味道可是不小,拆开包装后就能闻到一股刺鼻的橡胶味,我怀疑是4个脚上的橡胶垫的味道,于是我决定让它在室外感受一下东北的冬天。这些年我也“晒”过很多板子了,去年晒过ST的SensorTile.box今年晒过平头哥的蓝牙MESH场景化套件。晒2天看看,如果还有味就给他的4只脚用用刑挫挫它的"锐气"。开发环境搭建以及新建工程记得第一次接触FPGA还是在大学的时候,那时候对这个没有太多认识,虽然大学学过Verilog HDL编程语言,认为就是把这门课修好就可以,哪知道出了学校才知道它的重要性。本人是做单片机开发的,以后会用到FPGA,所以就申请了此次FPGA开发板测评活动,所以非常感谢电子工程世界论坛以及高云厂商提供的测评机会。在FPGA方向,我是小白一枚。那么学习FPGA就从GW1N系列开发板开始吧。搭建环境前先来简单了解一下GW1N-4FPGA开发板;它有四个数码管、16个LED、一个64M外部Flash、4个滑动开关以及JTAG接口,整体而言外设还是有点少,但是对于我这样一个新手,使用还是可以的。系统框图如下: 再了解一下GW1N-4FPGA芯片系列产品特点:-10,000 次写寿命周期- 超过10 年的数据保存能力(+85°C)- 数据位宽:32- GW1N-1P5/2 行存储容量:96K bits- GW1N-4 行存储容量:256K bits- GW1N-9 行存储容量:608K bits- 页擦除能力:2,048 bytes- 字编程时间:≤16μs- 页擦除时间:≤120ms低功耗;高性能DSP 模块;丰富的基本逻辑单元;灵活的PLL资源等特点。现在来搭建一下开发环境。 1.下载安装包。在官网下载即可。在下载页面根据自己的系统下载相应的安装包。2、安装在下载完安装包,一直NEXT,即可。这里比较简单。3、申请license。在如图所示页面申请license。注意最好在工作日申请,24小时内会有回复。 4、添加license打开高云软件,会弹出添加license页面,直接添加即可,这样开发环境就搭建完成。5、新建工程单机FILE或者在quick start新建工程,新建FPGA工程。如下图所示。完成后选择项目目录。6、选择device,因为是GW1N-LV4LQ144C6/I5,所以选中这个器件即可。完成后会出现一个summary,完成后会有一个关于工程的简单情况展示,如下图。工程就新建完毕。 7、新建工程完毕后,就FILE新建VHDL文件,然后编写代码。如图 8、编写完代码后,即可点击综合,出现红色字体表示有错误或者警告,0错误0警告,则全显示完成。9、综合完成,要进行物理约束,在上图页面中双击USER Constraints,然后出现如下图,选择IO constraints,进行管脚设置。在管脚设置中可以拖拉到管脚或者直接填写管脚号。最后点击完成。10、接下来就是进行布局布线。双击Place & Route。 11、最后就是下载到开发板。以后就是个人的学习所得。不喜勿喷。谢谢。跑马灯实验使用verilog实现循环位置非常方便,几乎就是一条指令led_shift <= {led_shift[14:0],led_shift[15]};加上相应的延时和引脚配置就能实现下边的功能---右边的16个绿色LED转圈显示。使用高云FPGA和相应的环境实现这样的功能也非常方便,首先新建一个FPGA工程选择对应的工程名和路径选择对应的FPGA型号点完成结束工程创建在工程上点右键,选择New File文件类型选择Verilog文件输入文件名点确定创建一个verilog文件编写移位代码 注意cnt的位数一定要大于最大计数位数综合如果之前没人保存会提示保存文件对话框,点确定综合成功后双击FloorPlanner配置对应的引脚在弹出的窗口里点I/O Constraints,然后配置引脚能数原理图,在Location里选择对应的引脚号 配置引脚后会生成一个.cst文件,如果觉得图形化的配置麻烦,也可以在.cst文件里直接配置 引脚配置好后再切换到Process选项卡,双击Place & Route,成功后再双击Rrogram Device在弹出窗口里点Program按钮,默认可能是下到flash里,也可以改成sram再下载。完成上术步骤后就能实现第一张动画里的跑马灯效果。 国产FPGA 正点原子DFPGL22G开发板
作者:Jimmy_Arareb一、 开箱,环境配置及示例工程运行感谢EEWORLD论坛,正点原子以及紫光同创提供了本次测评机会。这也是我本人第一次进行开发板测评,请大家多多指教。1.外观及包装收到开发板时包装完好,配件齐全:开发板本体:开发板正反面均有亚克力板保护,防止磕碰。正点原子出品的开发板一如既往的外设丰富,使用方便。配件FPGA 开发板 PGL22G12V 1A 电源适配器红外遥控器USB Type-C 线收纳盒紫光下载器 Usb Cable功能验证上电测试Flash中烧写的出厂测试程序,观察到LED及数码管正常显示,说明开发板工作正常。2. 环境配置紫光同创提供了一套完善的开发环境,除IP库有待进一步丰富外实际开发体验良好。Pango Design Suite直接双击安装包进行安装即可,注意中途会安装USB Cable驱动及依赖库。安装完毕后需要创建环境变量 PANGO_LICENSE_FILE 并添加License文件所在路径。个人习惯使用VS Code进行文本编辑,在菜单栏中点击 Edit -> Preferences 进入 Preferences 窗口,选择 Integrated Tools 后编辑 Text Editor 栏,填写 Code.exe 所在路径,点击 OK 即可在编辑文本时自动调用VS Code。在VS Code中,Verilog、System Verilog及VHDL均可通过插件可以实现代码高亮,代码跳转,代码自动补全,自动例化,测试模板生成,语法检查,代码格式化,版本管理等功能。ModelSim本次测评所用计算机由于先前的项目开发,已提前安装ModelSim SE-64 10.5。3. 示例工程运行以正点原子提供的流水灯工程为例。创建工程按照PDS提供的新建工程向导进行即可,与其它FPGA开发环境操作基本一致。工程命名及工程路径添加工程文件指定器件型号注意,由于没有Synplify Pro的证书,在器件型号页面中,综合工具需要选择ADS。导入设计文件使用计数器对输入时钟进行分频,得到周期为0.2s的信号,从而控制移位寄存器进行移位,实现流水灯的效果。创建约束使用PDS提供的User Constraint Editor以图形化界面的方式编辑约束文件。时序约束在 Timing Constraints 页面中添加频率为50M的主时钟约束及输入输出接口约束。生成的约束语句如下:create_clock -name {clk} [get_ports {sys_clk}] -period {20.000} -waveform {0.000 10.000}set_input_delay {0.100} [get_ports {sys_rst_n}] -clock [get_clocks {clk}]set_output_delay {0.100} [get_ports {led[0] led[1] led[2] led[3]}] -clock [get_clocks {clk}]物理约束在 Device -> I/O Table 页面中根据原理图选择引脚位置及电平标准。生成的约束语句如下:define_attribute {p:led[3]} {PAP_IO_DIRECTION} {OUTPUT}define_attribute {p:led[3]} {PAP_IO_LOC} {G1}define_attribute {p:led[3]} {PAP_IO_VCCIO} {1.5}define_attribute {p:led[3]} {PAP_IO_STANDARD} {LVCMOS15}define_attribute {p:led[3]} {PAP_IO_DRIVE} {8}define_attribute {p:led[3]} {PAP_IO_NONE} {TRUE}define_attribute {p:led[3]} {PAP_IO_SLEW} {SLOW}define_attribute {p:led[2]} {PAP_IO_DIRECTION} {OUTPUT}define_attribute {p:led[2]} {PAP_IO_LOC} {J7}define_attribute {p:led[2]} {PAP_IO_VCCIO} {1.5}define_attribute {p:led[2]} {PAP_IO_STANDARD} {LVCMOS15}define_attribute {p:led[2]} {PAP_IO_DRIVE} {8}define_attribute {p:led[2]} {PAP_IO_NONE} {TRUE}define_attribute {p:led[2]} {PAP_IO_SLEW} {SLOW}define_attribute {p:led[1]} {PAP_IO_DIRECTION} {OUTPUT}define_attribute {p:led[1]} {PAP_IO_LOC} {J6}define_attribute {p:led[1]} {PAP_IO_VCCIO} {1.5}define_attribute {p:led[1]} {PAP_IO_STANDARD} {LVCMOS15}define_attribute {p:led[1]} {PAP_IO_DRIVE} {8}define_attribute {p:led[1]} {PAP_IO_NONE} {TRUE}define_attribute {p:led[1]} {PAP_IO_SLEW} {SLOW}define_attribute {p:led[0]} {PAP_IO_DIRECTION} {OUTPUT}define_attribute {p:led[0]} {PAP_IO_LOC} {F3}define_attribute {p:led[0]} {PAP_IO_VCCIO} {1.5}define_attribute {p:led[0]} {PAP_IO_STANDARD} {LVCMOS15}define_attribute {p:led[0]} {PAP_IO_DRIVE} {8}define_attribute {p:led[0]} {PAP_IO_NONE} {TRUE}define_attribute {p:led[0]} {PAP_IO_SLEW} {SLOW}define_attribute {p:sys_clk} {PAP_IO_DIRECTION} {INPUT}define_attribute {p:sys_clk} {PAP_IO_LOC} {B5}define_attribute {p:sys_clk} {PAP_IO_VCCIO} {3.3}define_attribute {p:sys_clk} {PAP_IO_STANDARD} {LVCMOS33}define_attribute {p:sys_clk} {PAP_IO_NONE} {TRUE}define_attribute {p:sys_clk} {PAP_IO_HYS_DRIVE_MODE} {NOHYS}define_attribute {p:sys_rst_n} {PAP_IO_DIRECTION} {INPUT}define_attribute {p:sys_rst_n} {PAP_IO_LOC} {G5}define_attribute {p:sys_rst_n} {PAP_IO_VCCIO} {1.5}define_attribute {p:sys_rst_n} {PAP_IO_STANDARD} {LVCMOS15}define_attribute {p:sys_rst_n} {PAP_IO_NONE} {TRUE}分析与综合在编译流程窗口中依次右键 Compile Synthesis Device Map 点击 Run 完成编译。编译后可以查看资源使用报告。布局布线在编译流程窗口中按照同样的操作点击 Place & Route 完成布局布线.完成后可以点击 Report Timing 生成时序报告。下载工程点击 Generate Bitstream 生成比特流,使用Configuration工具扫描JTAG链并连接到目标芯片,选择比特流文件后右键FPGA芯片下载,观察到流水灯正常闪烁。点击 Operations -> Convert File 进入文件转换界面,选择Flash芯片型号及读取模式,选择.sbit文件路径,点击 OK 生成.sfc文件。右键FPAGA芯片点击 Scan Outer Flash ,选择.sfc文件。右键Flash芯片点击 Program ,将配置文件下载至Flash中,断电后重新上电,观察到流水灯正常闪烁。4. ModelSim 仿真测试编译 ModelSim 库在菜单栏中点击 Tools -> Compile Simulation Libraries ,填写仿真库及仿真器的路径后点击 Compile 开始编译。导入仿真文件功能仿真在菜单栏中点击 Process -> Run Simulation -> Run Behavior Simulation ,PDS会调用ModelSim开始联合仿真。设置仿真时间为1sec,观察到流水灯输出正常。5. Debug Core 测试使用片上逻辑分析仪Debug Core可以捕捉FPGA运行过程中的信号,提高调试效率。使用 Fabric Inserter 创建 Debug Core在菜单栏中点击 Tools -> Inserter 打开Fabric Inserter窗口。点击 New DebugCore Unit 创建Debug Core,在 Trigger Parameters 页面进行触发端口、捕获存储和触发条件的参数配置。在 Net Connections 页面点击 Modify Connections 进入Select Net配置界面。连接Debug Core时钟及需要捕获的信号,点击 OK 后返回。最后点击保存生成Debug Core配置文件。使用 Fabric Debugger 下载并捕获数据重新运行 Device Map 至 Generate BitStream 的所有步骤,生成带有Debug Core的比特流。点击菜单栏中的 Tools -> Debugger 打开Fabric Debugger窗口。连接后下载比特流并导入.fic文件。设置触发条件,点击开始采集,观察到Debug Core满足触发条件后正确采集了信号。使用Bus Plot功能可以按照总线的数据进行绘图。测试中遇到了一个问题,布局布线完成后出现Critical Warning:Route-2036: The clock path from u_CORES/u_GTP_SCANCHAIN_PG/scanchain:CAPDR to clkbufg_3/gopclkbufg:CLK is routed by SRB.Route-2036: The clock path from u_CORES/u_GTP_SCANCHAIN_PG/scanchain:TCK_USER to clkbufg_4/gopclkbufg:CLK is routed by SRB.无时序违例且Debug Core工作正常,查看网表发现这两条时钟路径穿过了7个SRB,超过2个的上限触发警告。不知道除手动布线或关闭该警告外是否有其它解决办法。二、 DDS及SPWM实现 DDS及SPWM实现1. DDS模块DDS原理直接数字合成(Direct Digital Synthesizer, DDS)是一种使用单一固定时钟生成任意频率波形的技术。DDS由参考时钟、频率控制字、相位控制字、相位累加器、波形存储器及DAC组成,通过改变频率控制字及相位控制字对波形存储器中的数据进行抽样和偏移,更改输出信号的频率及相位。DDS代码实现驱动旋转变压器需要频率为10KHz的正弦信号,由于没有更改频率的需求,设定参考时钟为50M,相位累加器宽度为20,正弦查找表深度为1024,宽度为16位,计算得到频率控制字为20'd2097。其中正弦查找表使用PDS提供的IP核BRM Based ROM实现。设置地址位宽为10,数据位宽为16。使能输出寄存器及输出寄存器时钟极性反转以放宽时序,选择初始化数据文件格式为HEX。正弦查找表由matlab生成,代码如下:N = 1024;n = 0:N-1;x = fix((2^15 - 1) * sin(2*pi*n/N));fid1 = fopen('sin.dat','wt');for i = 1:Nfprintf(fid1,'%s\n',dec2hex(x(i),4));endfclose(fid1);DDS模块仿真测试激励如下所示,输入50M的参考时钟及复位信号,设置相位控制字为20'd262144。注意使用IP时必须例化GTP_GRS模块进行全局复位。`timescale 1ns / 1psmodule dds_tb ();reg clk_50m = 1'b0;reg rst_n = 1'b0;wire [15:0] sin;initial begin#20 rst_n <= 1'b1;#200000 $stop;endalways begin#10 clk_50m <= ~clk_50m;endGTP_GRS GRS_INST (.GRS_N(rst_n));dds dds_inst_1 (.clk_50m(clk_50m),.rst_n(rst_n),.offset (20'd262144),.sin (sin));endmodule观察仿真波形,输出初始相位为90°,频率为10KHz的正弦信号,模块功能正常。2. SPWM模块SPWM原理正弦脉宽调制(Sinusoidal Power Width Modulation, SPWM)利用一系列脉宽按正弦规律变化的矩形脉冲等效正弦输出。在旋转变压器的应用中,可以利用SPWM配合外部的滤波及功放电路,实现激磁信号的输出,节约DAC的成本。SPWM代码实现使用中心对齐的双向计数器产生三角载波,与DDS输出的正弦值进行比较,使用自然采样法实现SPWM调制。在测试用的顶层模块中例化SPWM模块和PLL IP核以提供200M和50M时钟。PLL IP核设置如下:SPWM模块仿真测试激励如下所示,输入50M的参考时钟及复位信号。注意使用IP时必须例化GTP_GRS模块进行全局复位。观察仿真波形,PLL、DDS、计数器、SPWM输出均功能正常。SPWM硬件测试添加约束及完成全部编译过程后,使用Debug Core观察输出信号,与仿真结果相符。调试时发现Fabric Debugger有个小bug,在Bus Radix选择Signed Decimal时,8'b10000000应当显示-128,但窗口中显示的值为-0,画图界面也有相同的问题,希望紫光同创后续修复。使用示波器测量pwm_p与pwm_n端口的输出,结果正常。三、 AD7606驱动编写1. AD7606驱动程序AD7606是ADI公司出品的一款4/6/8通道同步采样,200kSPS,16位,$\pm$5、$\pm$15V双极性输入的ADC芯片。芯片时序参考数据手册,采用读取后转换,并口模式。芯片时序如下:注意上电后需要先拉高RESET对芯片进行复位,否则芯片会工作异常。开始转换时拉低CONVST A/B引脚,等待BUSY拉低后转换完成。注意从开始转换到BUSY拉高之间的间隔最大为45ns,需要单独设置状态进行处理,否则可能出现误触发。转换完成后先拉低CS再输入时钟RD,完成读取后再拉高CS,一个采样周期完成。注意数据在RD下降沿更新,上升沿读取。程序编写采用状态机控制读取,上电及复位时进入RESET状态,先对AD7606进行复位。复位完成后进入IDLE状态,等待数据采集开始标志输入。开始采集后进入WAIT_1状态,完成计时后进入WAIT_BUSY状态,等待转换完成。BUSY拉低后依次进入READ_CH1至READ_CH4状态,完成读取后进入READ_STOP状态,发出读取完成信号后回到IDLE状态,等待下一次触发。仿真测试按照时序图编写测试激励如下:`timescale 1ns / 1psmodule ad7606_4_tb ();localparam N = 2000;reg clk = 0, rst = 0, ad_busy = 0, capture_flag = 0;reg [15:0] data_sin [N - 1:0];reg [15:0] data_cos [N - 1:0];reg [15:0] data_in = 0;reg [ 1:0] cnt = 0;wire ad_cs, ad_rd, ad_convstab, capture_over, ad_reset;wire [15:0] data_ch1, data_ch2, data_ch3, data_ch4;integer i = 0;initial begin$readmemh("../../matlab/sin.txt", data_sin);$readmemh("../../matlab/cos.txt", data_cos);#50 rst <= 1;#10000000 $stop;endalways begin#10 clk <= ~clk;endalways begin#40 capture_flag = 0;#4960 capture_flag = 1;endalways @(posedge ad_convstab) beginif (~ad_reset) begin#40 ad_busy = 1;#2000 ad_busy = 0;endelse beginad_busy = 0;endendalways @(negedge ad_rd) begincase (cnt)3'd0: data_in <= data_sin;3'd1: data_in <= data_cos;3'd2: data_in <= 0;3'd3: begindata_in <= 0;if (i == N - 1) begini <= 0;end else i <= i + 1;endendcasecnt <= cnt + 1;endad7606_4 u_ad7606_4 (.clk (clk),.rst (rst),.data_in (data_in),.ad_busy (ad_busy),.capture_flag(capture_flag),.ad_cs (ad_cs),.ad_rd (ad_rd),.ad_convstab (ad_convstab),.ad_reset (ad_reset),.data_ch1 (data_ch1),.data_ch2 (data_ch2),.data_ch3 (data_ch3),.data_ch4 (data_ch4),.capture_over(capture_over));endmodule其中1/2通道为模拟的两路sin/cos信号,3/4通道输入为0。生成测试波形的matlab脚本如下:N = 2000;n = 1:N;x = fix((2^15 - 1) * sin(2*pi*n/N));y = fix((2^15 - 1) * cos(2*pi*n/N));fid1 = fopen('sin.txt','wt');fid2 = fopen('cos.txt','wt');for i = 1:Nfprintf(fid1,'%s\n',dec2hex(x(i),4));fprintf(fid2,'%s\n',dec2hex(y(i),4));endfclose(fid1);fclose(fid2);仿真波形正常,正确读取到输入信号。单次读取的时序与数据手册相符。2. AD7606实物模拟目前手头还有一块ZYNQ可以模拟传感器的输入输出,使用ZYNQ7010的PL部分模拟AD7606的时序输出正弦信号进行测试。程序编写时序与上述介绍相同,不再赘述,代码如下:`timescale 1ns / 1psmodule ad7606_sim (input clk,output reg [15:0] data_out,//ad7606通道a输出并行读取数据output reg ad_busy, //ad7606输出busy信号input ad_cs, //读ad7606的使能信号input ad_rd, //读ad7606的时钟信号input ad_convstab,//ad7606开始转换信号,低电平有效input ad_reset, //ad7606复位信号input [15:0] data_ch1,input [15:0] data_ch2,input [15:0] data_ch3,input [15:0] data_ch4);localparam RESET = 9'b000_000_001;localparam IDLE = 9'b000_000_010;localparam AD_CONV = 9'b000_000_100;localparam AD_EN = 9'b000_001_000;localparam WRITE_CH1 = 9'b000_010_000;localparam WRITE_CH2 = 9'b000_100_000;localparam WRITE_CH3 = 9'b001_000_000;localparam WRITE_CH4 = 9'b010_000_000;localparam WRITE_STOP = 9'b100_000_000;localparam CONV_TIME = 200;//AD_CONV状态持续时间reg [ 7:0] cnt;reg [ 8:0] state;reg [15:0] data_buf[3:0];reg [ 1:0] ad_rd_buf;//读取时钟缓存always @(posedge clk) beginif (ad_reset) beginad_rd_buf <= 2'b11;end else beginad_rd_buf <= {ad_rd_buf[0], ad_rd};endend//数据缓存integer i;always @(posedge clk) beginif (ad_reset) beginfor (i = 0; i < 4; i = i + 1) begindata_buf <= 16'b0;endend else beginif (state == IDLE) begindata_buf[0] <= data_ch1;data_buf[1] <= data_ch2;data_buf[2] <= data_ch3;data_buf[3] <= data_ch4;end else beginfor (i = 0; i < 4; i = i + 1) begindata_buf <= data_buf;endendendend//计数器模拟转换过程busy信号always @(posedge clk) beginif (ad_reset) begincnt <= 8'd0;end else begincase (state)AD_CONV: beginif (cnt == CONV_TIME - 1'b1) begincnt <= 8'd0;end else begincnt <= cnt + 1'd1;endenddefault: begincnt <= 8'd0;endendcaseendendalways @(posedge clk) beginif (ad_reset) beginad_busy <= 1'b0;end else beginif (state == AD_CONV) beginad_busy <= 1'b1;end else beginad_busy <= 1'b0;endendend//数据输出always @(posedge clk) beginif (ad_reset) begindata_out <= 16'b0;end else begincase (state)WRITE_CH1: beginif (ad_rd_buf == 2'b10) begindata_out <= data_buf[0];end else begindata_out <= data_out;endendWRITE_CH2: beginif (ad_rd_buf == 2'b10) begindata_out <= data_buf[1];end else begindata_out <= data_out;endendWRITE_CH3: beginif (ad_rd_buf == 2'b10) begindata_out <= data_buf[2];end else begindata_out <= data_out;endendWRITE_CH4: beginif (ad_rd_buf == 2'b10) begindata_out <= data_buf[3];end else begindata_out <= data_out;endenddefault: begindata_out <= 16'b0;endendcaseendend//状态机切换always @(posedge clk) beginif (ad_reset) beginstate <= RESET;end else begincase (state)RESET: beginstate <= IDLE;endIDLE: beginif (~ad_convstab) beginstate <= AD_CONV;end else beginstate <= IDLE;endendAD_CONV: beginif (cnt == CONV_TIME - 1'b1) beginstate <= AD_EN;end else beginstate <= AD_CONV;endendAD_EN: beginif (~ad_cs) beginstate <= WRITE_CH1;end else beginstate <= AD_EN;endendWRITE_CH1: beginif (ad_rd_buf == 2'b01) beginstate <= WRITE_CH2;end else beginstate <= WRITE_CH1;endendWRITE_CH2: beginif (ad_rd_buf == 2'b01) beginstate <= WRITE_CH3;end else beginstate <= WRITE_CH2;endendWRITE_CH3: beginif (ad_rd_buf == 2'b01) beginstate <= WRITE_CH4;end else beginstate <= WRITE_CH3;endendWRITE_CH4: beginif (ad_rd_buf == 2'b01) beginstate <= WRITE_STOP;end else beginstate <= WRITE_CH4;endendWRITE_STOP: beginstate <= IDLE;enddefault: state <= IDLE;endcaseendendendmoduleZYNQ使用Vivado进行开发,支持Block Design,可以轻松地添加各种Xilinx提供及客户自行编写的IP核。使用Block Design添加DDS及Clock Wizard模块,完成顶层模块的编写。完成连线后点击Generate Block Design生成IP核,再点击Create HDL Wrapper生成HDL包装文件,以便后续的仿真与综合使用。仿真测试将驱动及AD7606仿真模块的对应端口连接,编写测试激励如下:`timescale 1ns / 1psmodule top_tb;reg clk_50m = 0, rst = 0, capture_flag = 0;wire ad_busy, ad_cs, ad_rd, ad_convstab, capture_over, ad_reset;wire [15:0] data_ch1, data_ch2, data_ch3, data_ch4, data_out;initial begin#50 rst <= 1;#200000 $stop;endalways begin#10 clk_50m <= ~clk_50m;endalways begin#40 capture_flag = 0;#4960 capture_flag = 1;endad7606_4 u_ad7606_4 (.clk (clk_50m),.rst (rst),.data_in (data_out),.ad_busy (ad_busy),.capture_flag(capture_flag),.ad_cs (ad_cs),.ad_rd (ad_rd),.ad_convstab (ad_convstab),.ad_reset (ad_reset),.data_ch1 (data_ch1),.data_ch2 (data_ch2),.data_ch3 (data_ch3),.data_ch4 (data_ch4),.capture_over(capture_over));top_wrapper u_top_wrapper (.ad_busy_0 (ad_busy),.ad_convstab_0(ad_convstab),.ad_cs_0 (ad_cs),.ad_rd_0 (ad_rd),.ad_reset (ad_reset),.clk_in1 (clk_50m),.data_out_0 (data_out));endmodule仿真波形正常。实物测试将两块开发板按对应引脚连接后,分别烧写程序,使用片上逻辑分析仪观察信号,信号读取正常。四、 检波器代码编写1.旋转变压器原理旋转变压器简介旋转变压器是一种电磁式角度传感器,用来测量旋转轴的角位置和角速度,具有结构简单,可靠性高,耐振动、耐高低温的特点,广泛应用于以航空航天为代表的国防及工业产品中。旋转变压器结构示意图近年来电动汽车快速发展,旋转变压器由于其适用于汽车行驶过程中的恶劣工况的独特优势,开始进入民用领域。旋转变压器的工作原理与普通变压器类似,在初级线圈通入励磁电压,通过旋转改变耦合进入次级绕组的磁链,对次级输出电压进行调制,得到包含角度信息的调幅信号。其中次级绕组有两组,分别称为正、余弦绕组,输出两路正交角度信号。通过对两路输出信号进行检波和鉴相,可以提取出当前转轴的角度和角速度。数学模型在理想条件下,旋转变压器的数学模型为:其中$V_r$是激磁信号,$V_a$是余弦绕组输出,$V_b$是正弦绕组输出,$\omega$为激磁角频率,$\theta$为转轴角位置。旋转变压器信号示意图RDC介绍旋转变压器数字变换器(Resolver to Digital Converter, RDC)可以提供旋转变压器所需的激磁信号,并将旋转变压器输出的正余弦调制信号转化为角位置和角速度的数字信号并输出至数字控制器。对于一般精度要求的应用,通常选用成品RDC芯片,如ADI公司的AD2S1210等。对于特殊应用,可以采用软件方式实现定制的RDC算法,有效补偿各类误差。软件实现RDC一般使用DSP或FPGA,其中DSP开发相对容易,但并行化程度与FPGA相比有一定差距,对于较为复杂的补偿算法不能满足实时性要求。FPGA开发周期较长,但硬件配置更加灵活,可以实时完成复杂算法。RDC一般由三大主要部分组成:激磁信号源提供激磁信号,驱动电流放大器。检波器从正余弦调制信号中提取包络。鉴相器1.SPI接口仿真编写测试激励模拟通信时序,输出结果正确。Modelsim仿真结果
· END ·