基于FPGA的跨时钟域信号处理——MCU

说到异步时钟域的信号处理,想必是一个FPGA设计中很关键的技术,也是令很多工程师对FPGA望 而却步的原因。但是异步信号的处理真的有那么神秘吗?那么就让特权同学和你一起慢慢解开这些所谓的难点问题,不过请注意,今后的这些关于异步信号处理的文 章里将会重点从工程实践的角度出发,以一些特权同学遇到过的典型案例的设计为依托,从代码的角度来剖析一些特权同学认为经典的跨时钟域信号处理的方式。这 些文章都是即兴而写,可能不会做太多的分类或者归纳,也有一些特例,希望网友自己把握。

另外,关于异步时钟域的话题,推荐大家不妨去看看这些不错的文章,如《跨越鸿沟:同步世界中的异步信号》,《cpu与fpga跨时钟域数据交换的实现问题》等。

首先说MCU与FPGA之间的异步通信,参加CPLD助学活动的朋友应该都注意到了那块BJ-EPM板子上预留了16PIN的单片机接口,但是那个实验里其实也没有给出什么实验代码。究其原因,大概是特权同学有点自私了吧(呵呵~~~),因为当初刚接触MCU与FPGA通信处理的时候,是为了做一个液晶控制板,用的是很老的EPM7128, 资源很小,摸索了个把月才搞定,不过当时的处理方式上并不稳妥,后来随着不断学习不断积累经验才寻觅到现在的处理方式。不想公开源码自有所谓的“比较关键 的技术”一说,现在想来蛮有些可笑的。网络这么大一个平台,凭什么你只索取不共享呢?所以,特权同学今后会努力把自己的点点滴滴设计经验和大家分享。当然 了,在提出自己的观点和看法的同时,也一定会得到更多高人不同的也许更好的见解,帮助他人的同时自己也在进步,何乐而不为呢。

罗嗦了一大堆,步入正题吧……

首先,这个项目是基于单片机的应用,如果你对单片机的读写时序不是很熟练,不妨看看特权同学的一篇详细讨论51单片机扩展RAM读写时序的文章《单片机的扩展RAM读写时序》。下面简单看下11.0592MHz的51单片机的读写时序图吧。

大体和上面的波形相差无几,地址总线没有画出来,不过地址总线一般是会早于片选CS到来,并且晚于片选信号CS撤销(这个说法不是绝对的,但是至少对于下面的应用是这样)。

我们现在的工作是作为MCU的从机,即模拟MCU的扩展RAM。MCU若发出写时序,FPGA就得在数据稳定于数据总线时将其锁存起来;MCU发出读时序,FPGA就要在MCU锁存数据的建立时间之前把数据放到数据总线上,并且到MCU锁存数据的保持时间结束后才能将数据撤销。基本上,我们要干的就是这些活,下面讨论verilog在设计上如何实现,但是限于篇幅,不对时序分析做讨论,假定这是一个很理想的总线时序。

其实这个MCU的读写时序的时间相对还是很充裕的,因为我们的FPGA用的是50MHz的晶振。所以一个很基本的想法是要求我们把MCU端的信号同步到FPGA的时钟域上,达到异步信号的同步处理。

verilog代码:

//----------------------------------------------------------------------

//----------------------------------------------------------------------

input clk; //50MHz

input rst_n; //复位信号,低有效

input mcu_cs_n; //MCU片选信号,低有效

input mcu_wr_n; //MCU写信号,低有效

input[3:0] mcu_addr; //MCU地址总线

input[7:0] mcu_db; //MCU数据总线

reg[3:0] mcu_addr_r; //mcu_addr锁存寄存器

reg[7:0] mcu_db_r; // mcu_db锁存寄存器

//mcu_cs_n和mcu_wr_n同时拉低时wr_state拉低,表示片选并写选通

wire wr_state = mcu_cs_n || mcu_wr_n; //写状态标志位,写选通时拉底

always @ (posedge clk or negedge rst_n)

if(!rst_n) begin

mcu_addr_r <= 4’h0;

mcu_db_r <= 8’h00;

end

else if(!wr_state) begin

mcu_addr_r <= mcu_addr;// mcu_addr锁存寄存器

mcu_db_r <= mcu_db;// mcu_db锁存寄存器

end

wire pos_wr; // MCU写状态上升沿标志位

reg wr1,wr2; // MCU写状态寄存器

always @ (posedge clk or negedge rst_n)

if(!rst_n) begin

wr1 <= 1'b1;

wr2 <= 1'b1;

end

else begin

wr1 <= wr_state;

wr2 <= wr1;

end

assign pos_wr = ~wr2 && wr1; //写选通信号上升沿pos_wr拉高一个时钟周期

上面的代码就是基于MCU发出的异步时序的一种同步处理。当然了,这种处理是基于特定的应用。MCU写选通撤销时,pos_wr信号(使用了脉冲边沿检测方法处理)会拉高一个时钟周期,就可以利用此信号作为后续处理的状态机中的一个指示信号。然后对已经锁存在FPGA内部相应寄存器里的地址总线和数据总线进行处理。

另外,对于mcu_addr_r和mcu_db_r的锁存为什么要在wr_state为低时进行,这个问题特权同学是这么考虑的:wr_state拉低期间即MCU片选和写选通同时有效期间数据总线/地址总线一定是稳定的,而为了有更充足的数据建立时间,比较常见的做法是用mcu_wr_n的上升沿锁存数据,而如果用诸如posedge mcu_wr_n来做触发锁存数据/地址,那就很容易出现异步冲突的问题(这个问题的危害以后的文章详细讨论),达不到同步的效果,所以这里就用一个电平信号作为使能信号来得更加稳妥。换个角度看,无非是wr_state上升沿的前0-20ns都有可能是最后锁存下来的数据,这对于我们充足的MCU写时序来说是绰绰有余了。理论上来说,wr_stata是一个总线使能信号,应该要做至少一级同步再使用更稳妥一些,但是出于我们充裕的时序,即便是wr_stata没有进行同步处理,退一步说,出现了wr_state的一个亚稳态时在锁存数据,那么此时的数据总线/地址总线的数据也不会受到影响,该什么值还是什么值。不同的应用中往往有允许非常规处理的时候,就像时序分析中的时序例外一样。希望大家能理解这个部分,不理解也没有关系,以后的文章会更深入探讨异步时钟域中亚稳态这个大问题,到时再回头看看也许你就明白了。


转自:

作者:特权同学,

http://forum.edc-cn.com/BLOG_ARTICLE_4275.HTM

如果您有什么疑问请留言或者来信:wiznetbj@wiznettechnology.com ,希望本篇文章可以给您带来帮助,谢谢。


### 如何通过MCU启动FPGA #### MCUFPGA的交互方式 微控制器单元(MCU)可以通过多种接口与现场可编程门阵列(FPGA通信并控制其操作。常见的接口包括SPI、I2C、UART以及GPIO等[^4]。这些接口允许MCUFPGA发送配置数据或触发特定的操作。 #### 使用CORE-V MCU作为示例 以CORE-V MCU为例,它是一个开源项目,能够与其他硬件紧密集成。为了实现MCUFPGA的启动功能,通常需要完成以下几个方面的设计: 1. **硬件连接** 将MCU的通用输入/输出端口(GPIO)或其他串行外设接口(如SPI/I2C)连接至FPGA的相关引脚。这种物理连接是实现MCU控制FPGA的基础。 2. **软件驱动开发** 在MCU上编写专门的固件来管理FPGA的状态机。例如,在某些情况下,可能需要通过SPI协议加载位流文件到FPGA中以便初始化设备。这一步骤涉及到了解码和传输复杂的二进制数据序列给目标器件[^5]。 3. **配置流程定义** 定义清晰的顺序步骤描述如何从休眠状态唤醒FPGA直到完全运行起来的过程。此过程应考虑电源供应情况、时钟信号同步以及其他必要的外围条件满足与否等因素的影响[^3]。 4. **错误处理机制建立** 考虑潜在失败情形下的应对策略非常重要;比如当尝试多次仍未能成功上传新版本bitstream时应该采取什么行动等问题都需要提前规划好解决方案[^2]。 以下是基于上述理论的一个简单伪代码表示方法用于演示目的: ```c void mcu_start_fpga(){ configure_spi_interface(); // 设置 SPI 接口参数 while(!fpga_ready()){ send_bitstream_to_fpga(); delay(10); // 等待一段时间再重试 } initialize_peripherals(); // 初始化其他必要组件 } bool fpga_ready(){ uint8_t status = read_status_register_via_spi(); return (status & READY_FLAG) != 0; } ``` 以上片段展示了基本框架下的一种可能性——即利用循环结构不断监测直至确认接收方已准备好接受进一步指令为止。 #### 总结 综上所述,要让MCU有效地激活关联着它的那个具体型号类型的场效应晶体管阵列,则需精心安排两者间电气特性匹配度较高的线路布局方案的同时也要兼顾程序层面的设计思路合理性考量因素共同作用的结果表现形式才会更加理想化一些[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值