在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 6028|回复: 7

RISC访问Memory时序问题——输出的时钟缓冲

[复制链接]
发表于 2010-8-19 15:42:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
做一个RISC8的ModelSim仿真、在FPGA中的试验、和测试综合,发现了一个RISC访问Memory的时序问题,及一般的ROM、RAM的输出都是需要使用时钟缓冲的。

现象如下:
由于RISC8是3级流水线,即取指令、指令译码、执行并写回。指令流水线的时序图如下:

clk    ___|----|____|----|____|----|____|----|____|---
add    ----<===A1===><===A2===><===A3===><===A4===><==
inst   ------<===I1===><===I2===><===I3===><===I4===><
MicroCode  ----------<===M1===><===M2===><===M3===><==
Reg    ------------------------<===D1===><===D2===><==
Cycle  ---|  Stage1 |  Stage2 |  Stage3 | ------------


这样看起来,好像是实现了三级流水线,而且给出的原TestBench进行仿真也的确如此。
但这样有一个很糟糕的问题:在取指操作中,RISC在第1个clk上升沿后发出指令的Address,但一定要求在下一个clk上升沿之前,指令Memory必须给出数据,才能保证在第2个clk上升沿之后,指令会保存到指令寄存器并进行译码,发出微指令,这样在第3个clk上升沿时,微指令到达各个执行部件并让各执行部件的组合逻辑部分在这第3各上升沿时稳定下来,最终在第3各clk上升沿之后执行完成并且数据寄存器是需要的数值。

问题在于:如果是仿真的话,问题不大,原设计的testbench就是使用语句:
  assign data_in =  mem[address[15:0]] ;
但如果用在FPGA中、或者综合时使用了Foundry的Memory Compiler编译出来的可实现的Memory,问题来了:
很少有能够实现类似assign data_in =  mem[address[15:0]]这样能够异步访问的Memory
大多数FPGA或者Memory Compiler输出的RAM/ROM的输出部分的描述语句是:
always @(posedge clk)
              do = mem[addr];
也就是说,如果使用了这种带输出寄存器的Memory,取指令得两个周期:第一个时钟RISC输出Address,第2个时钟Memory输出Instruction!
这将导致3级流水线无法操作的!

请问诸位前辈,大家在做RISC实现时碰到这样的问题吗?带输出寄存器的Memory是主流memory,难道一定要使用异步输出的Memory?
发表于 2010-8-19 17:17:22 | 显示全部楼层
RISC在第1个clk上升沿后发出指令的Address,其实这个时钟上升沿是把地址送给memory的。所以理想的memory是这样的。
                 ----------------
    clk-----------|  memory     |-----> 指令
     address-----|                   |
                        |_________ |
 楼主| 发表于 2010-8-19 20:11:08 | 显示全部楼层
楼上理解有误:RISC第1个clk上升沿之后T(clk->q),指令的Address才是稳定的,再之后经过路径延迟后地址才送到Memory;Memroy内部开始对地址译码、访问存储单元、灵敏放大后输入到数据储存寄存器的D端,这样memory要到第2个clk上升沿之后T(clk->q)的时候,Memory才能输出稳定的instruction;然后要到第3个clk上升沿之后T(clk->q)的时候,RISC的指令寄存器才能稳定的锁存数据。
有两个办法避开一个时钟:
1.Memory的输出不用寄存器,即输入Address后、经过T(address->dataout)的组合逻辑延迟时直接输出instruction,这就是使用异步存储器,实际应用中很少见了;
2.指令从memory输出后不用寄存器,即Memory的输出寄存器输出的指令直接进行译码;很显然Memory到RISC的路径延迟是很难估计的,这样很难设计RISC。

两种方法都有点别扭:前者不符合常规的Memory构造;后者会导致RISC无指令寄存器而无法译码时间难以忍受。当然,也可以将取指分为两个时钟节拍即输出地址、读取指令,这也是解决办法,不过就增加一级流水线了!
很是感到困惑,想了解高手们如何处理的。
发表于 2010-8-19 20:49:44 | 显示全部楼层
第一个上升沿cpu发出地址读写信号,第二个上升沿memory采样到控制信号,开始输出数据
第三个上升沿cpu可以采样到输出。

如果访问memory的路径够短的话可以考虑memory使用反相时钟,相当于在时钟的下降沿memory能够采样到地址和控制信号,并开始输出数据,cpu在第二个上升沿能够获取数据。

这样的话必须考虑,频率是否满足,时钟的抖动和占空比的变化是否在可接受的范围。。。
发表于 2010-11-7 16:31:35 | 显示全部楼层
都是高手!!!
发表于 2010-11-7 22:08:08 | 显示全部楼层
类似的设计并不少见。ARM内部就有很多。通常片选和地址信号,半个时钟周期就够了。Memory用反沿采样的,然后Memory的DO不要用寄存器打拍,用Latch,这就有1.5拍完成指令处理。并且这1.5拍是DC可自动调整的。
发表于 2014-1-8 02:13:46 | 显示全部楼层
Memory Compiler 生成的Mem一般好像是对输入信号挡了一拍。也许把PC的D端的信号直接给memory的地址输入就可以了。不过应该要确保复位之后PC D端的输入为0。
发表于 2023-8-21 20:38:46 | 显示全部楼层


Pasingen 发表于 2010-8-19 20:11
楼上理解有误:RISC第1个clk上升沿之后T(clk->q),指令的Address才是稳定的,再之后经过路径延迟后地址才送 ...


前辈好,十年后的我也遇到了类似的问题,请问前辈是如何解决的呢?我觉得您说的方法二比较好点。其他人提出的用半个周期的方法有个疑问,如果控制信号列如mem读使能这些是在一个周期下产生的,那么时序差的情况下控制信号会在半个周期之后稳定,岂不是在半个周期的时刻mem看不到读使能置起了?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

×

小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-26 04:26 , Processed in 0.038798 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表