数据存储在RAM里,程序存储在ROM里,这是大家经常听到的,那么怎么设计一个存储数据的RAM和一个存储程序的ROM呢?这里我们就来亲手试验一下。
有一点要说明的QuartusII中提供的ROM和Logisim中提供的ROM模块有一点点不同,他们相差一根时钟线,虽然只有这一点不同,但却是很重要的一点,这就涉及到了一个组合逻辑实现的ROM与时序逻辑实现的ROM的区别。
这里给出了QuartusII中的两种实现方式,一种是用库中提供的模块,另一种是组合逻辑的实现方式,关于两者的不同究竟会产生怎样的影响,后面我们再详细讨论。
第六步:实现一个RAM
直接上图吧,基本操作的问题不多叙述了,有问题的话请查看前面的学习或者参考QuartusII的教程。
第七步:ROM的实现
用组合逻辑实现ROM的方法
用组合逻辑实现的ROM其本质是电路,如果感觉难以理解,你可以认为你的程序就是一堆门电路按某种顺序排列表示出来的,而不是存在真正意义的存储器当中,我们写程序的时候其实是搭建了一个电路。
这里给出一种实现方法
这是一个16个字的16位ROM,是用选择器实现的(前面说过了选择器是个有用的好东西),
由于只有16个存储单元,所以4位地址就能表示出来,ROM中的内容就是接到选择器data0x到data15x上的数据,每一次对ROM的编程写入,就是将综合的电路下载到FPGA实验板中。
2,用时序电路实现ROM
实际的ROM应该是可以在系统编程的,也就是说不改变电路结构,能够把程序写入ROM。
在QuartusII软件中库提供的ROM是时序电路实现的,我们时序电路实现的ROM跟RAM的形式是一样的,看图就知道了。
其实在QuartusII中ROM也是通过一个RAM实现的,引入的ROM中有这样的代码
……
COMPONENT altsyncram
GENERIC (
clock_enable_input_a : STRING;
clock_enable_output_a : STRING;
init_file : STRING;
……
widthad_a : NATURAL;
width_a : NATURAL;
width_byteena_a : NATURAL
);
PORT (
clock0 : IN STD_LOGIC ;
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
END COMPONENT;
……
这里altsyncram经过封装,也就是MegaWizard的配置,引出相应的引脚,就成了一个ROM模块交给我们,在我们设计中调用了(上面是一段VHDL语言的代码,关于VHDL语言就不在这里详细介绍了)。
最后需要注意的是这个ROM模块用到我们顶层设计的时候不能用CPU的时钟,而是单独为其提供一个刷新输出数据的高速时钟。在介绍完整个CPU后,我们会把这样做的原因连同说明组合逻辑与时序逻辑实现ROM的不同一起讨论。当然如果你现在有兴趣可以在自己的CPU设计中使用这个ROM模块的时候为其加上CPU的时钟,看看效果。