2-3-16 基于FPGA的SPI LOOP环路实验
软件版本:vitis2021.1(vivado2021.1)操作系统:WIN10 64bit硬件平台:适用XILINX A7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!1 概述在前面完成了SPI发送驱动程序、SPI接收驱动程序设计,本文对前面的SPI收发驱动做一个环路测试,通过仿真,以及在线仿真的方式验证SPI的收发应用。本文将在前面课程的基础上完成,包括采用前面课程编写SPI发送驱动和接收驱动。2 SPI环路程序设计2.1 系统框图以下给出系统框图,关于各个模块的详细描述请看前面的实验。本实验中短接SPI发送模块和接收模块的SCLK和MOSI和MISO,并且在芯片内部通过在线逻辑分析仪在线观察结果2.2 SPI数据发送状态机在本实验中,TX发送状态机中增加spi_ss控制,该信号用于spi接收模块的数据的启动接收和停止接收控制/*********************SPI环路测试*********************1. I_spi_miso接收驱动,用于接收串口数据,当spi_rvalid代表接收驱动接收到了总线的有效数据2. O_spi_mosi发送驱动,用于发送数据,当spi_tx_req为高电平,请求发送数据环路测试中*********************************************************************/`timescale 1ns / 1ps//仿真时钟刻度和精度module spi_master#(parameter CLK_DIV = 10 )(inputI_sysclk, //系统时钟inputI_rstn, //全局复位 output O_spi_sclk, //SPI MASTER输出时钟inputI_spi_sclk, //SPI Slave 输入时钟output O_spi_mosi, //SPI MASTER输出数据inputI_spi_miso //SPI Slave 输入数据);
wire spi_busy;reg spi_tx_req;reg spi_tx_data;reg M_S;
reg spi_ss_i;/*synthesis keep*/wire spi_rvalid;/*synthesis keep*/wire spi_rdata;/*synthesis keep*/
reg delay_cnt;wire delay_done;
assign delay_done = delay_cnt; //复位延时计数always @(posedge I_sysclk or negedge I_rstn) begin //异步复位 if(!I_rstn) delay_cnt <=0; //复位来的是,时钟清零 else if(delay_cnt == 1'b0) //当delay_cnt等于1时,计数清零,不满足就自+1 delay_cnt <= delay_cnt + 1'b1; else delay_cnt <= 0; //达到预期值,计数清零end
always @(posedge I_sysclk or negedge I_rstn) begin //spi发送状态机 if(!I_rstn) begin spi_ss_i <= 1'b1; spi_tx_req<= 1'b0; spi_tx_data <= 8'd0; M_S <= 2'd0; end else begin case(M_S) 0:if(delay_done&&(!spi_busy))begin //延时完成且SPI传输非忙 spi_ss_i <= 1'b1; //拉高spi_ss_i信号,启动spi接收模块的数据的接收 M_S <= 2'd1; //从初始状态转入状态1 end 1:if(delay_done&&(!spi_busy))begin spi_ss_i <= 1'b0; //启动后,将spi_ss_i信号复原 M_S <= 2'd2; end 2:if(delay_done&&(!spi_busy))begin //总线不忙启动传输 spi_tx_req<= 1'b1; //req信号拉高,准备发送 spi_tx_data <= spi_tx_data + 1'b1; //测试数据 M_S <= 2'd3; end 3:if(spi_busy)begin //如果spi总线忙,清除spi_tx_req spi_tx_req<= 1'b0; M_S <= 2'd0; end default:M_S <= 2'd0; endcase endend//spi master tx控制器例化uimspi_tx#(.CLK_DIV(CLK_DIV),.CPOL(1'b0),.CPHA(1'b0))uimspi_tx_inst(.I_clk(I_sysclk),.I_rstn(I_rstn),.O_spi_mosi(O_spi_mosi),.O_spi_sclk(O_spi_sclk),.I_spi_tx_req(spi_tx_req),.I_spi_tx_data(spi_tx_data),.O_spi_busy(spi_busy) );//spi rx控制器例化uispi_rx#(.BITS_LEN(8),.CPOL(1'b0),.CPHA(1'b0))uispi_rx_inst(.I_clk(I_sysclk),.I_rstn(I_rstn),.I_spi_clk(I_spi_sclk),.I_spi_rx(I_spi_miso),.I_spi_ss(spi_ss_i),.O_spi_rvalid(spi_rvalid),.O_spi_rdata(spi_rdata));
ila_0 ila_0(.clk(I_sysclk),.probe0(spi_rvalid),.probe1(spi_rdata));endmodule
3 FPGA工程fpga工程的创建过程不再重复,如有不清楚的请看前面实验
米联客的代码管理规范,在对应的FPGA工程路径下创建uisrc路径,并且创建以下文件夹01_rtl:放用户编写的rtl代码02_sim:仿真文件或者工程03_ip:放使用到的ip文件04_pin:放fpga的pin脚约束文件或者时序约束文件05_boot:放编译好的bit或者bin文件(一般为空)06_doc:放本一些相关文档(一般为空)4 RTL仿真4.1 仿真激励文件仿真测试文件源码如下:
`timescale 1ns / 1ps//定义仿真时间刻度/精度module master_spi_tb;localparam CLK_TIME ='d20;//时钟周期,以ns为单位reg I_sysclk;reg I_rstn;wire O_spi_sclk;wire I_spi_sclk;wire O_spi_mosi;wire I_spi_miso;
assign I_spi_miso = O_spi_mosi;//模拟数据回环assign I_spi_sclk = O_spi_sclk;//模拟时钟回环//例化顶层模块spi_master#(.CLK_DIV(100) )spi_master_inst(.I_sysclk(I_sysclk),.I_rstn(I_rstn),.O_spi_sclk(O_spi_sclk),.O_spi_mosi(O_spi_mosi),.I_spi_sclk(I_spi_sclk),.I_spi_miso(I_spi_miso));initial begin//初始化REG寄存器 I_sysclk= 1'b0;//系统时钟 I_rstn = 1'b0;//复位 #100; I_rstn = 1'b1;endalways #(CLK_TIME/2) I_sysclk = ~I_sysclk; //产生主时钟endmodule
4.2 RTL功能仿真可以放大箭头所指位置,查看接收数据和发送数据是否一致,本实验只测试CHPA=0 CPOL=0的情况。5 上板验证5.1 在线逻辑分析仪设置添加在线逻辑分析仪,设置为Capture Control模式5.2 硬件连接(该教程为通用型教程,教程中仅展示一款示例开发板的连接方式,具体连接方式以所购买的开发板型号以及结合配套代码管脚约束为准。)请确保下载器和开发板已经正确连接,注意跳线帽短接,并且开发板已经上电。(注意JTAG端子不支持热插拔,而USB接口支持,所以在不通电的情况下接通好JTAG后,再插入USB到电脑,之后再上电,以免造成JTAG IO损坏)5.3 在线调试结果在线逻辑分析仪设置成BASIC模式,设置spi_rvalid为高电平的时候触发采集:调整数据格式为十进制,显示为SPI传输的连续的数字,符合我们工程
页:
[1]