



QMEM是Quick Memory的简称,顾名思义,就是快速存储器,实际上这是一个片上RAM,可以实现在一个时钟周期内读取其中存储内容(指令、数据),用户可以把一些常用的代码存放在其中,比如:Context切换过程、异常处理句柄、堆栈等。有学者将QMEM类比为OR1200的一级缓存(L1 Cache),这种说法是不对的,缓存是不可寻址的,但是QMEM是可以寻址的,而且QMEM没有缓存中存在的替换问题,所以QMEM的作用不是缓存,就是一个可寻址的片上存储器。它在OR1200结构中的位置如图3.1所示。
取指令的过程:CPU给出指令的有效地址(EA:Effective Address),IMMU将有效地址翻译为物理地址(PA:Physical Address),然后送到QMEM中。QMEM判断该地址是否位于QMEM的地址范围内,如果是,就直接取出指令送到CPU;如果不是位于QMEM的地址范围内,则将该地址发送给ICache。ICache查看该地址是否被缓存,如果是就直接读出指令送往QMEM,后者直接转发给CPU;如果ICache没有命中,则通过指令WB_BIU模块访问外部存储器获取指令。
加载/存储数据的过程:CPU给出读写数据的有效地址,DMMU将有效地址翻译为物理地址,然后送到QMEM中。QMEM判断该地址是否位于QMEM的地址范围内,如果是,就直接读写指定地址;如果不是位于QMEM的地址范围内,则将该地址发送给Dcache。DCache查看该地址是否被缓存,如果是就直接将该数据送往QMEM,后者直接转发给CPU,或者直接写数据;如果DCache没有命中,则会通过SB、数据WB_BIU模块访问外部存储器读写数据。
图3.1 QMEM在OR1200中的位置
所以QMEM的作用如图3.2所示,需要注意的是QMEM中只有一个RAM,指令、数据共用这一个RAM。
图3.2 QMEM的作用示意图
在OR1200的配置文件or1200_defines.v中,关于QMEM的配置选项如下。
其中OR1200_QMEM_IADDR、OR1200_QMEM_IMASK两个参数定义了QMEM中指令的地址范围,OR1200_QMEM_DADDR、OR1200_QMEM_DMASK两个参数定义了QMEM中数据的地址范围,当IMMU、DMMU将指令地址、数据地址送入QMEM后,在QMEM中会进行如下运算。
以IMMU送入的指令地址为例,将输入地址qmemimmu_adr_i与OR1200_QMEM_IMASK相“与”,然后与OR1200_QMEM_IADDR比较,如果采用默认值,即:
此时只要输入地址在0x00800000-0x008fffff(1M大小的空间范围内),都会使得iaddr_qmem_hit为1,表示地址在QMEM范围内,就会从QMEM中读取对应地址指令,反之iaddr_qmem_hit为0。当DMMU将数据地址送入QMEM后,也会进行同样的运算。所以当采用默认配置时QMEM中指令与数据拥有相同的地址空间,地址范围是0x00800000至0x008fffff,大小都是1M。
在第2章建立最小系统时,将上面的代码改为:
代码修改后使得无论输入的指令地址、数据地址的值是多少,iaddr_qmem_hit、daddr_qmem_hit始终为1,表示要访问的指令、数据在QMEM中,这样就会从QMEM内部的RAM中取得指令、数据,所以在最小系统中将代码放在QMEM中,处理器OR1200能够正确执行。