FPGA与单片机SPI通信问题
小弟,用单片机做主机给FPGA发一个字节数据,然后FPGA发送回来。但是发现在FPGA里MISO延迟一个周期导致单片机接受的数据少了一位。想请教大神们怎么解决啊?下图为仿真图FPGA,上升沿接受数据,下降沿发送数据,程序也如下LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY spi_fpga is
PORT (SCK: IN std_logic;
MOSI: IN std_logic;
CS: INstd_logic;
MISO: OUT std_logic);
END spi_fpga;
ARCHITECTURE one of spi_fpga is
SIGNAL MOSI_IN: std_logic;
BEGIN
PROCESS (CS,SCK)
BEGIN
IF (CS='1') THEN
NULL;
ELSIF rising_edge(SCK) THEN
MOSI_IN <= MOSI;
END IF;
END PROCESS;
PROCESS (SCK)
BEGIN
IF falling_edge (SCK) THEN
MISO <= MOSI_IN;
END IF;
END PROCESS;
END one; 没人知道吗?高手求出现啊 不用SCK作为SPI接口时钟
而用相对于SCK更高速的一个系统时钟来做这个模块的时钟 y595906642 发表于 2012-9-2 20:08 static/image/common/back.gif
不用SCK作为SPI接口时钟
而用相对于SCK更高速的一个系统时钟来做这个模块的时钟 ...
这个SCK是单片机自带SPI发数据的时候产生的 LZ你省省吧。FPGA时序电路是有延时的,至少1cyc,所以你回收的肯定是少一个bit的。除非你用高频去采样,比如我现在用100M去处理。 楼上的都已经说了办法就是用高速时钟处理内部逻辑SPI的时钟用高速时钟采样同步 处理
我用的是68M的时钟SPI接口部分 OK kebaojun305 发表于 2012-9-3 08:47 static/image/common/back.gif
楼上的都已经说了办法就是用高速时钟处理内部逻辑SPI的时钟用高速时钟采样同步 处理
我用的是6 ...
新手啊,请大神谅解啊,再问下 怎么用高速时钟去同步SPI时钟啊 你用高速时钟采到SCK的上升,下降沿就行了,不需要同步。 y595906642 发表于 2012-9-3 09:50 static/image/common/back.gif
你用高速时钟采到SCK的上升,下降沿就行了,不需要同步。
大神,能不能具体点啊? wye11083 发表于 2012-9-3 08:00 static/image/common/back.gif
LZ你省省吧。FPGA时序电路是有延时的,至少1cyc,所以你回收的肯定是少一个bit的。除非你用高频去采样,比 ...
用与门吗? 可以了,多谢你们的回复。就是这个问题十分感谢 {:funk:}就好了一会又不行了 我晕 比如用50MHZ时钟检测sck的上升沿下降沿 cmdrainsy 发表于 2012-9-3 10:43 static/image/common/back.gif
比如用50MHZ时钟检测sck的上升沿下降沿
是的 现在用50M去检测,我用了一个与门,刚开始对了,不知怎么的又不行了 郁闷?
signal buff : std_logic;
if rising_edge(clk50m) then
buff <= sck;
if buff = '0' and sck = '1' then --上升沿检测 本帖最后由 kebaojun305 于 2012-9-3 11:31 编辑
大神 不敢当还早呢,这种基本的电路 网上有很多讲的。原帖地址 http://aax1985.spaces.eepw.com.cn/articles/article/item/22609#
这是昨晚的课程,主要讲时钟同步,课上做了一个实验仿真的对比。(08.4.24)
概述
数字电路中,时钟是整个电路最重要、最特殊的信号。
第一, 系统内大部分器件的动作都是在时钟的跳变沿上进行, 这就要求时钟信号时延差要非常小, 否则就可能造成时序逻辑状态出错.
第二, 时钟信号通常是系统中频率最高的信号.
第三, 时钟信号通常是负载最重的信号, 所以要合理分配负载。出于这样的考虑在FPGA这类可编程器件内部一般都设有数量不等的专门用于系统时钟驱动的全局时钟网络。这类网络的特点是:一、负载能力特别强, 任何一个全局时钟驱动线都可以驱动芯片内部的触发器; 二是时延差特别小; 三是时钟信号波形畸变小, 工作可靠性好。
因此, 在FPGA设计中最好的时钟方案是: 由专用的全局时钟输入引脚驱动单个主时钟去控制设计项目中的每一个触发器。同步设计时, 全局时钟输入一般都接在器件的时钟端, 否则会使其性能受到影响。
对于需要多时钟的时序电路, 最好选用一个频率是它们的时钟频率公倍数的高频主时钟。
各个功能模块要使用统一的复位电路。在使用带时钟的触发器、计数器等有复位端的库器件时, 一般应尽量使用有同步复位的器件。注意复位时保证各个器件都能复位, 以避免某些寄存器的初始状态不确定而引起系统工作不可靠。
若想掌握时钟设计方法首先需要了解建立时间和保持时间的概念。
建立时间(setup time):是指在触发器的时钟信号上升沿到来以前,数据稳定不变的时间,如果建立时间不够,数据将不能在这个时钟上升沿被打入触发器;保持时间(hold time):是指在触发器的时钟信号上升沿到来以后,数据稳定不变的时间,如果保持时间不够,数据同样不能被打入触发器。
对于一个设计项目来说,全局时钟(或同步时钟)是最简单和最可预测的时钟。在CPLD/FPGA设计中最好的时钟方案是:由专用的全局时钟输入引脚驱动的单个主时钟去钟控设计项目中的每一个触发器。只要可能就应尽量在设计项目中采用全局时钟。CPLD/FPGA都具有专门的全局时钟引脚,它直接连到器件中的每一个寄存器。这种全局时钟提供器件中最短的时钟到输出的延时。
在许多应用中只将异步信号同步化还是不够的,当系统中有两个或两个以上非同源时钟的时候,数据的建立和保持时间很难得到保证,我们将面临复杂的时间问题,那么这个时候怎么办呢?
最好的方法是将所有非同源时钟同步化,那么又怎么样将非同源时钟同步化呢?
我们可以使用带使能端的D触发器,并引入一个高频时钟(频率高于系统中的所有源时钟),便可以达到使系统中所有源时钟同步的效果。
系统时钟设计:
系统有两个不同源时钟,一个为3MHz,一个为5MHz,不同的触发器使用不同的时钟。为了系统稳定,假设我们引入一个20MHz时钟,那么这个20MHz的时钟怎么才能将3M和5M时钟同步化呢?
20M的高频时钟将作为系统时钟,输入到所有触发器的的时钟端。3M_EN 和5M_EN将控制所有触发器的使能端。即原来接3M时钟的触发器,接20M时钟,同时3M_EN 将控制该触发器使能,原接5M时钟的触发器,也接20M时钟,同时5M_EN 将控制该触发器使能。这样我们就可以将任何非同源时钟同步化。
异步信号输入总是无法满足数据的建立保持时间,所以建议大家把所有异步输入都先经过双触发器进行同步化。
下面是用20MHz的时钟作为同步时钟得出的功能仿真波形:(下面一个小波形是将上面一个图的EN_3信号的局部放大,可以明显看出黄线前后两个时钟大小相差了一个主时钟周期,这是因为20/3不为整数导致一个EN_3的脉冲周期有可能6个也有可能7个主时钟周期)
15MHz的同步时钟功能仿真波形,可以得到一致的EN_3和EN_5的脉冲,其高电平保持都为1/20M的时间。
综合后的原理图:
在通常的FPGA设计中对时钟偏差的控制主要有以下几种方法:
1、控制时钟信号尽量走可编程器件的的全局时钟网络。在可编程器件中一般都有专门的时钟驱动器及全局时钟网络,不同种类、型号的可编程器件,它们中的全局时钟网络数量不同,因此要根据不同的设计需要选择含有合适数量全局时钟网络的可编程器件。一般来说,走全局时钟网络的时钟信号到各使能端的延时小,时钟偏差很小,基本可以忽略不计。
2、若设计中时钟信号数量很多,无法让所有的信号都走全局时钟网络,那么可以通过在设计中加约束的方法,控制不能走全局时钟网络的时钟信号的时钟偏差。
3、异步接口时序裕度要足够大局部同步电路之间接口都可以看成是异步接口,比较典型的是设计中的高低频电路接口、I/O接口,那么接口电路中后一级触发器的建立-保持时间要满足要求,时序裕度要足够大。
4、在系统时钟大于30MHz时,设计难度有所加大,建议采用流水线等设计方法。
5、要保证电路设计的理论最高工作频率大于电路的实际工作频率。
复位和置位信号处理:
在设计时应尽量保证有一全局复位信号,或保证触发器、计数器在使用前已经正确清零状态。在设计寄存器的清除和置位信号时,应尽量直接从器件的专用引脚驱动。另外,要考虑到有些器件上电时,触发器处于一种不确定的状态,系统设计时应加入全局复位/Reset。
这样主复位引脚就可以给设计中的每一个触发器馈送清除或置位信号,保证系统处于一个确定的初始状态。需要注意的一点是:不要对寄存器的置位和清除端同时施加不同信号产生的控制,因为如果出现两个信号同时有效的意外情况,会使寄存器进入不定状态。
原帖
http://lib.dicder.com/others/2010/0616/278.html
经典跨时钟域同步电路
2010-06-16 11:09:21 来源: 评论:0 点击:
1. Level Synchronzier
2. Edge-Detect Synchronzier
3. Pulse Synchronizer
4. Handshaking
4.1 Full Handshaking
4.2 Partial Handshake
kebaojun305 发表于 2012-9-3 08:47 static/image/common/back.gif
楼上的都已经说了办法就是用高速时钟处理内部逻辑SPI的时钟用高速时钟采样同步 处理
我用的是6 ...
改了还是不行啊,能不能在程序中指点下啊 很简单,把这一堆换成
PROCESS (SCK)
BEGIN
IF falling_edge (SCK) THEN
MISO <= MOSI_IN;
END IF;
END PROCESS;
换成 MISO = MOSI_IN就行了。不用输出寄存器,直接连到输入寄存器上。 wye11083 发表于 2012-9-3 14:27 static/image/common/back.gif
很简单,把这一堆换成
PROCESS (SCK)
BEGIN
额,这样报错的啊 chenweigang 发表于 2012-9-3 12:51 static/image/common/back.gif
改了还是不行啊,能不能在程序中指点下啊
VHDL不会 好了,多谢各位 楼主的问题搞定了?有个帖子你可以看看
给大家发个自己写的fpga和单片机spi通信程序(大鸟飞过)
http://www.amobbs.com/thread-5121723-1-1.html
页:
[1]