SPI接口的Verilog语言实现Word格式.docx
- 文档编号:21858761
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:17
- 大小:1.05MB
SPI接口的Verilog语言实现Word格式.docx
《SPI接口的Verilog语言实现Word格式.docx》由会员分享,可在线阅读,更多相关《SPI接口的Verilog语言实现Word格式.docx(17页珍藏版)》请在冰豆网上搜索。
(由于时间原因其步未能完成)
四、设计过程:
模块1:
输入说明:
data7[7..0]:
FPGA写数据到RAM的输入口。
enable:
为输入使能。
reset:
复位。
clk:
输入时钟。
contr_addr[5..0]:
FPGA写数据到RAM的地址的最大值,即写入RAM中数据的个数。
feedback:
SPI系统发送完数据的反馈,提示FPGA又可以重新写数据到RAM,然后发送。
输出说明:
wr_en:
控制RAM写使能。
wr_addr:
写数据到RAM的地址控制,写一数据地址加一。
wr_clock:
RAM写数据时钟,上升沿有效。
fullflag:
RAM写满的标志。
data_out[7..0]:
RAM中写入的数据。
模块说明:
FPGA通过SPI发送数据,数据必须要有个缓存阶段。
此设计中是利用RAM作为缓存。
该模块就是数据写入RAM的控制器,并提示FPGA开始发送数据及发送多少个数据。
SPI发送完数据后提示FPGA重新写数据到RAM继续发送。
仿真时序图:
模块2:
输入说明:
data[7..0]:
输入RAM的数据。
wraddress[5..0]:
RAM写地下输入,写一数据地址加一。
wren:
RAM写使能
rdaddress[5..0]:
RAM读地址输入,读一数据地址加一。
rden:
RAM读使能
wrclock:
RAM写数据时钟,上升沿有效。
rdclock:
RAM读数据时钟,上升沿有效。
输出说明:
q[7..0]:
读RAM数据输出口。
这是双通道的RAM,此设计中需要定制2个容量为64BIT的,能进行数据的读写。
需注意的数据的读写不能同时操作。
模块3:
clk:
系统时钟。
ramindata[7..0]:
输入需要发送的数据。
Cpuwr:
Miso:
主机输入从机输出。
Reset:
复位。
RFirq:
开始发送。
Fullflag:
RAM存满,请求开始发送标志。
Addr_num[5..0]:
需要发送数据的个数。
feedback:
发送完数据后反馈给RAM控制器,请求重新写入RAM数据发送。
outdata[7..0]:
接收到从机发出的数据,用于测试。
mosi:
主机发出的移位数据,从机输入。
Irq:
发送完中断主求。
CSN:
从机选择控制,低电平有效。
SCK:
主机从机发送移位数据时钟。
SendAddr[5..0]:
RAM读地址控制,读取RAM中的数据进行发送。
SendRDen:
RAM读使能。
ReceiveData[7..0]:
接收到的数据,用于写入RAM。
ReceiveAddr[5..0]:
接收到的数据写入RAM的地址控制。
SendramClk:
读取RAM中的数据用于发送的时钟,上升沿有效。
ReceiveClk:
接收到的数据写入RAM中的时钟控制,上升沿有效。
ReceiveWen:
接收到数据写入RAM使能。
CE:
Sendfinishtest:
发送结束标志。
ram_rd:
整个数据接收完后,读取RAM中数据使能。
ram_rd_clk:
整个数据接收完后,读取RAM中数时钟,上升沿有效。
ram_rd_addr[5..0]:
整个数据接收完后,读取RAM中数据的地址控制。
此模块是整个系统的核心部分,控制着SPI的收发。
其整个流程大致如下:
具体的程序写法:
其收发过程都是通过状态机实现的。
状态机容易构成性能良好的同步时序逻辑模块,而且能很大限度的消除毛刺现象。
读取第一个数据(4个状态):
开始发送接收(17个状态,采用顺序编码):
5'
b00000:
CSN=1'
b0;
片选从机,低电平有效
SCK=1'
拉低SPI时钟线,主机发送数据最高位
mosi=senddata[7];
读取数据最高位放到数据线MOSI发送
SendRDen=1'
b1;
读取发送数据使能
SendramCLK=1'
拉低读RAM时钟线
bitcounter=bitcounter+5'
b00001:
拉高SPI时钟线,主机接收从机发出数据最高位
StatusReg0[7]=miso;
存取最高位数据
SendramCLK=1'
拉高读RAM时钟线,产生上升沿读RAM
bitcounter=bitcounter+5'
b00010:
拉低SPI时钟线,主机发送数据次高位数据
mosi=senddata[6];
读取数据次高位放到数据线MOSI发送bitcounter=bitcounter+5'
b00011:
拉高SPI时钟线,主机接收从机发出数据次高位
StatusReg0[6]=miso;
存取次高位数据
ramsendtemp=ramindata;
读取RAM中下一个数据
b00100:
拉低SPI时钟线,主机发送数据的第五位
mosi=senddata[5];
发送数据第五位
关闭读RAM使能
SendAddr=SendAddr+6'
读RAM地址加一
b00101:
StatusReg0[5]=miso;
接收从机发出的数据第五位
b00110:
mosi=senddata[4];
主机发送数据第四位
b00111:
StatusReg0[4]=miso;
接收从机发出的数据第四位
bitcounter=bitcounter+5'
b01000:
mosi=senddata[3];
主机发送数据第三位
b01001:
StatusReg0[3]=miso;
主机接收从机发出的数据第三位
b01010:
mosi=senddata[2];
主机发送数据第二位
b01011:
StatusReg0[2]=miso;
主机接收从机发送的数据的第二位
b01100:
mosi=senddata[1];
主机发送数据的次低位
b01101:
StatusReg0[1]=miso;
主机接收数据的次低位
b01110:
mosi=senddata[0];
主机发送数据的最低位
6'
b01111:
StatusReg0[0]=miso;
主机接收数据的最低位
senddata=ramsendtemp;
b10000:
bitcounter=5'
ramdReceivetemp=StatusReg0;
主机存储接收到的第一个数据,并准备
写入RAM
sendFinishByte=sendFinishByte+6'
发送数据个数加一
receiveByte=receiveByte+6'
接收数据个数加一
发送接收中间数据态(18个状态,采用顺序编码):
主机发送中间数据最高位
主机接收从机发出的数据的最高位
mosi=senddata[6];
主机发送中间数据次高位
ramsendtemp=ramindata;
读取RAM,作为下一个发送数bitcounter=bitcounter+5'
主机接收从机发出数据的次高位
SendAddr=SendAddr+6'
读RAM地址加一
SendramCLK=1'
主机发送中间数据第五位
ReceiveCLK=1'
拉低写数据到RAM时钟
ReceiveWen=1'
RAM写数据使能
主机接收从机发出的数据第五位
主机发送中间数据的第四位
ReceiveData=ramdReceivetemp;
准备好写入的数据(在时钟上升沿到来前,
将数据放到总线上)
主机接收从机发出数据的第四位
ReceiveCLK=1'
将拉收到的上一个数据第一次写入RAM(为
了安全,每个数据写两次)
第二次写入(为了安全,每个数据写两次)
mosi=senddata[2];
ReceiveAddr=ReceiveAddr+6'
ReceiveWen=1'
//取消写ram信号
SCK=1'
StatusReg0[1]=miso;
StatusReg0[0]=miso;
b10001:
bitcounter=5'
ramdReceivetemp=StatusReg0;
主机缓存接收到的数据
主机把读到的下一个数据拉到发生寄
存器,准备发送
receiveByte=receiveByte+6'
发送最后一个数据(21个状态,采用顺序编码):
前面17个状态与接收发送第一个数据,中间数据基本相同。
故不作具体陈述。
b10010:
CSN=1'
取消选择从机使能
bitcounter=bitcounter+5'
ReceiveCLK=1'
b10011:
接收到数据第二次写入RAM(为了安
全,每个数据写两次)
b10100:
ready=1'
发送接收完准备取消
feedback=1'
反馈给RAM控制器,可以重新写数据
senden=1'
取消发送使能
sendfilish=1;
发送完成标志
receiveByte=receiveByte+6'
接收数据加一
ReceiveAddr=6'
接收地址清0
ReceiveWen=1'
取消写ram信号
ReceiveReady=1'
6'
b10101:
feedback=1'
反馈信号清0
顶成框图:
仿真结果说明:
仿真通过设置contr_addr=4来写五个数据(11,12,7,15,16)到RAM,然后发送。
五、设计中遇到的问题及解决办法:
1、控制RAM写数据的时钟时,忽视了Verilog语言的语句执行特
导致RAM中总是写不进去数据。
wr_clock=1'
wr_clock=1'
第一次写入
第二次写入
这样执行后的结果为wr_clock=1'
b1,一直为上高平,并不会有两个上升沿。
最好的解决方法就是使用状态机。
2’b00:
2’b01:
2’b10:
2’b11:
2、处理反馈信号feedback与存满信号fullflag的逻辑关系时,遇到
了些麻烦,最终巧妙的运用异或解决了问题。
a=(~feedback)&
fullflag0;
b=feedback&
(~fullflag0);
fullflag=a|b;
3、在定制FIFO时遇到很大的问题,如数据不能按照严格的时序进出FIFO,而且有些数据还不能写进FIFO,经过多方面调试改写还是没能解决。
最终只能放弃FIFO,改用RAM,外加个控制器就可以了。
六、设计心得与体会:
1、这次设计花了我四天多时间完成,做之前单纯的以为SPI不过就是写几个简单的移位寄存器外加个时钟就可以了,却完全忽视了SPI具有严格的时序要求及数据发送接收存储问题。
SPI不是只发送接收一个八位数据就可以了的,它应该具有强大的信息交换传输功能。
2、仿真时序很不好把握,以后尽量少用QuartusII自带仿真器,要多多学习MODOSIM。
3、VerilogHDL自学了一段时间,第一次用来编写一个完整的系统。
和VHDL比起来还是各有各的好处吧。
它们描述各层的能力各有千秋。
VerilogHDL善于描述更低层设计,比VHDL更灵活,而VHDL善于描述一些高层的设计(主要是一些算法及控制好实现)。
VerilogHDL在仿真方面比VHDL也更方便些,如TESTBEN。
4、FPGA方面需学习的还有很多,为了设计SPI借书查了些资料,才发现自己FPGA基本上还没有入门。
电子设计做信号题需加倍努力啊。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SPI 接口 Verilog 语言 实现