问答 店铺
热搜: ZYNQ FPGA discuz

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

微信扫一扫 分享朋友圈

已有 101 人浏览分享

开启左侧

[MILIANPAI-F01-EG4D]FPGA程序设计基础实验连载-16 SPI LOOP环路实验

[复制链接]
101 0
安路-FPGA课程
安路课程: 基础入门 » 新手入门实验
安路系列: EG4
本帖最后由 UT发布 于 2025-4-11 09:57 编辑

软件版本:TD_5.6.4_Release_97693
操作系统:WIN11 64bit
硬件平台:适用安路(Anlogic)FPGA
登录米联客”FPGA社区-www.uisrc.com视频课程、答疑解惑!
1概述

在前面完成了SPI发送驱动程序、SPI接收驱动程序设计,本文对前面的SPI收发驱动做一个环路测试,通过仿真,以及在线仿真的方式验证SPI的收发应用。

本文将在前面课程的基础上完成,包括采用前面课程编写SPI发送驱动和接收驱动。

在完成本实验前,请确保已经完成前面的实验,包括已经掌握以下能力:

1:完成了TD软件安装

2:完成了modelsim安装以及TD库的编译

3:掌握了TD仿真环境的设置

4:掌握了modelsim通过do文件启动仿真


实验目的:

1:实现实现SPI回环控制器的设计

2:实用modelsim完成仿真验证

3:编译并且实用chipwatcher观察芯片内部信号

1.1 SPI收发环路简介

主机在通过MOSI数据线发送数据的同时,从机也会通过 MISO 将数据传输给主机(收发同时进行)。数据通常先移出最高位,传输可能会持续任意数量的时钟周期。传输完成后,主设备拉高SS片选信号并停止传输信号。

image.jpg
1.2 硬件电路分析

CEPcamera expand peripheral),CEP2.4间距排针,20pin 差分等长走线具有48个可用IOCEP-GPIO 接口中的IO可以用于完成本实验。进行SPI通信时,短接SPI发送模块和接收模块的SCLK,短接SPI发送模块的MOSI和接收模块的MISO,形成一条通路。

image.jpg
2 SPI环路程序设计
2.1系统框图

本次实验包含三个模块,SPI发送驱动模块、SPI接收驱动模块、顶层模块。以下给出系统框图,关于接收和发送模块的详细描述请看前面的实验,我们主要看顶层模块关于发送状态机的部分。芯片内部接收驱动接收到的有效信号通过在线逻辑分析仪在线观察结果。

image.jpg
发送状态机;

在所有模块开始运行之前先进行复位延时计数结束后再进入到发送状态机部分。延时完成后进入状态0spi总线不忙时拉高ss片选信号,spi_ss_i信号用于控制spi接收模块的数据的启动接收和停止接收,并进入状态1;拉低ss片选信号,启动SPI接收模块,进入状态2;拉高req信号,启动SPI发送模块,发送第一个测试数据spi_tx_data=1,此时SPI接收模块同时接收SPI发送驱动发送的数据O_spi_mosi,并进入状态3;如果spi总线忙,清除spi_tx_req,并重新进入状态0等待spi总线不忙时开启下一次的传输;如果总线不忙,进入状态0开启下一次传输。

image.jpg
2.2 驱动源码

在本实验中,TX发送状态机中增加spi_ss控制,该信号用于spi接收模块的数据的启动接收和停止接收控制

  1. module spi_master#
  2. (
  3. parameter CLK_DIV = 10        
  4. )
  5. (
  6. input  I_sysclk,                                                     //系统时钟
  7. input  I_rstn,                                                       //全局复位      
  8. output O_spi_sclk,                                                   //SPI MASTER输出时钟
  9. input  I_spi_sclk,                                                   //SPI Slave 输入时钟
  10. output O_spi_mosi,                                                   //SPI MASTER输出数据
  11. input  I_spi_miso                                                    //SPI Slave 输入数据
  12. );
  13. wire        spi_busy;
  14. reg         spi_tx_req;
  15. reg [7:0]   spi_tx_data;
  16. reg [1:0]   M_S;
  17. reg         spi_ss_i;/*synthesis keep*/
  18. wire        spi_rvalid;/*synthesis keep*/
  19. wire[7:0]   spi_rdata;/*synthesis keep*/
  20. reg [10:0]  delay_cnt;
  21. wire        delay_done;
  22. assign delay_done = delay_cnt[10];                         //复位延时计数
  23. always @(posedge I_sysclk or negedge I_rstn) begin       //异步复位
  24.     if(!I_rstn)
  25.         delay_cnt <=0;                                       //复位来的是,时钟清零
  26.     else if(delay_cnt[10] == 1'b0)                      //当delay_cnt[10]等于1时,计数清零,不满足就自+1
  27.         delay_cnt <= delay_cnt + 1'b1;
  28.     else
  29.         delay_cnt <= 0;                                 //达到预期值,计数清零
  30. end
  31. always @(posedge I_sysclk or negedge I_rstn) begin         //spi发送状态机
  32.     if(!I_rstn) begin
  33.         spi_ss_i    <= 1'b1;
  34.         spi_tx_req  <= 1'b0;
  35.         spi_tx_data <= 8'd0;
  36.         M_S         <= 2'd0;
  37.     end
  38.     else begin
  39.         case(M_S)
  40.         0:if(delay_done&&(!spi_busy))begin          //延时完成且SPI传输非忙
  41.             spi_ss_i <= 1'b1;                        //拉高spi_ss_i信号,启动spi接收模块的数据的接收
  42.             M_S <= 2'd1;                              //从初始状态转入状态1
  43.         end
  44.         1:if(delay_done&&(!spi_busy))begin         
  45.             spi_ss_i <= 1'b0;                        //启动后,将  spi_ss_i信号复原
  46.             M_S <= 2'd2;
  47.         end
  48.         2:if(delay_done&&(!spi_busy))begin          //总线不忙启动传输
  49.            spi_tx_req  <= 1'b1;                       //req信号拉高,准备发送
  50.            spi_tx_data <= spi_tx_data + 1'b1;        //测试数据
  51.            M_S <= 2'd3;
  52.         end
  53.         3:if(spi_busy)begin                           //如果spi总线忙,清除spi_tx_req
  54.            spi_tx_req  <= 1'b0;
  55.            M_S <= 2'd0;
  56.         end
  57.         default:M_S <= 2'd0;
  58.         endcase
  59.     end
  60. end   
  61. //spi master tx控制器例化
  62. uimspi_tx#
  63. (
  64. .CLK_DIV(CLK_DIV),
  65. .CPOL(1'b0),
  66. .CPHA(1'b0)
  67. )
  68. uimspi_tx_inst(
  69. .I_clk(I_sysclk),
  70. .I_rstn(I_rstn),
  71. .O_spi_mosi(O_spi_mosi),
  72. .O_spi_sclk(O_spi_sclk),
  73. .I_spi_tx_req(spi_tx_req),
  74. .I_spi_tx_data(spi_tx_data),
  75. .O_spi_busy(spi_busy)
  76. );
  77. //spi rx控制器例化
  78. uispi_rx#
  79. (
  80. .BITS_LEN(8),
  81. .CPOL(1'b0),
  82. .CPHA(1'b0)
  83. )
  84. uispi_rx_inst(
  85. .I_clk(I_sysclk),
  86. .I_rstn(I_rstn),
  87. .I_spi_clk(I_spi_sclk),
  88. .I_spi_rx(I_spi_miso),
  89. .I_spi_ss(spi_ss_i),
  90. .O_spi_rvalid(spi_rvalid),
  91. .O_spi_rdata(spi_rdata)
  92. );
  93. endmodule
复制代码
3 FPGA工程

fpga工程的创建过程不再重复,如有不清楚的请看前面实验,具体的FPGA型号以对应的开发板上芯片为准

image.jpg

米联客的代码管理规范,在对应的FPGA工程路径下创建uisrc路径,并且创建以下文件夹

01_rtl:放用户编写的rtl代码

02_sim:仿真文件或者工程

03_ip:放使用到的ip文件

04_pin:fpgapin脚约束文件或者时序约束文件

05_boot:放编译好的bit或者bin文件(一般为空)

06_doc:放本一些相关文档(一般为空)

image.jpg
4 Modelsim仿真
4.1 准备工作

Modelsim仿真的创建过程不再重复,如有不清楚的请看前面实验

仿真测试文件源码如下:

  1. `timescale 1ns / 1ps//定义仿真时间刻度/精度
  2. module master_spi_tb();
  3. localparam      CLK_TIME   =  'd20;//时钟周期,以ns为单位
  4. reg I_sysclk;
  5. reg I_rstn;  
  6. wire O_spi_sclk;
  7. wire I_spi_sclk;
  8. wire O_spi_mosi;
  9. wire I_spi_miso;
  10. assign I_spi_miso = O_spi_mosi;//模拟数据回环
  11. assign I_spi_sclk = O_spi_sclk;//模拟时钟回环
  12. //例化顶层模块
  13. spi_master#
  14. (
  15. .CLK_DIV(100)   
  16. )
  17. spi_master_inst(
  18. .I_sysclk(I_sysclk),
  19. .I_rstn(I_rstn),
  20. .O_spi_sclk(O_spi_sclk),
  21. .O_spi_mosi(O_spi_mosi),
  22. .I_spi_sclk(I_spi_sclk),
  23. .I_spi_miso(I_spi_miso)
  24. );
  25. initial begin
  26. //初始化REG寄存器
  27.     I_sysclk= 1'b0;//系统时钟
  28.     I_rstn = 1'b0;//复位
  29.     #100;
  30.     I_rstn = 1'b1;
  31. end
  32. always #(CLK_TIME/2) I_sysclk = ~I_sysclk;     //产生主时钟
  33. endmodule
复制代码
4.2 启动modelsim仿真

启动后,右击需要观察的信号,添加到波形窗口

以下启动modelsim仿真,可以放大箭头所指位置,查看接收数据和发送数据是否一致,本实验只测试CHPA=0 CPOL=0的情况。

image.jpg
5上板验证
5.1 chipwatcher设置

关于chipwatcher的设置,可以参考前面的实验,这里只做关键内容介绍。为了在线逻辑分析仪不去优化一些信号可以实用:

  1. reg         spi_ss_i;/*synthesis keep*/
  2. wire        spi_rvalid;/*synthesis keep*/
  3. wire[7:0]   spi_rdata;/*synthesis keep*/
复制代码
image.jpg

设置好后需要保持,然后重新编译

image.jpg
5.2 硬件连接

(该教程为通用型教程,教程中仅展示一款示例开发板的连接方式,具体连接方式以所购买的开发板型号以及结合配套代码管脚约束为准。)

请确保下载器和开发板已经正确连接,并且开发板已经上电(注意JTAG端子不支持热插拔,而USB接口支持,所以在不通电的情况下接通好JTAG后,再插入USB到电脑,之后再上电,以免造成JTAG IO损坏)

外部环路需要实用跳线帽,CEP-GPIO接口中的IO可以用于完成本实验

image.jpg
image.jpg
5.3 在线调试结果

Chipwatcher的如果调用这里不再重复,如果有不清楚的可以阅读前面文章中的实验。


需要观察的信号如下,设置spi_rvalid为高电平的时候触发采集:

image.jpg

可以看到接收到的数据和发送的数据一致

image.jpg








































您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

0

关注

0

粉丝

293

主题
精彩推荐
热门资讯
网友晒图
图文推荐

  • 微信公众平台

  • 扫描访问手机版