队伍编号:CICC1413
队伍名称:“芯”之所向
本文主要介绍蜂鸟中的ITCM模块。ITCM在蜂鸟中是用于存储指令的,由于蜂鸟E203内核定位是对于小型的指令系统,因此在蜂鸟定位的系统中,指令基本是全部存储在ITCM中的,因此下面我们介绍ITCM的结构以及从ITCM中取值的过程。
首先,我们先得知道ITCM模块存储位置是在e203_CPU_top下。
而我们看ITCM的代码下只有一个子模块
该子模块是sram的通用模块,也就是说DTCM下也有该子模块。可以看到在ITCM中,数据宽度是`E203_ITCM_RAM_DW,从”e203_defines.v”文件中,我们可以找到其值为64,这里也就引出了一个问题,E203中的指令都是16位和32位的,那我们是怎么访问ITCM得到指令的呢?
IFU中每次取值得到的数据都是32位的,而在ITCM输出的是64位地址区间对齐的数据,我们称为一个通道,所以这会导致IFU可能连续两次甚至多次在同一个通道内访问,如果两次都是在同一通道,那么就可以利用SRAM输出保持不变的特点,直接读取数据,而不需要重复打开ITCM。
当出现这种情况时,会先将SRAM当前输出的最高16位存入缓冲区内,然后重新访问,将新的输出的低16位与缓冲区中的值拼接成32位的完整指令,因此此时只需要在1个时钟周期内得到指令,也不会造成损失。
此时就需要发出两次读操作,将第一次读回的高16位存入缓冲区,将第二次读回的低16位与缓冲区拼接成完整指令,但是这样会导致一个时钟周期的损失。
现在我们可以看一下仿真中的取值过程。
initial begin
$readmemh({testcase, ".verilog"}, itcm_mem);
for (i=0;i<(`E203_ITCM_RAM_DP);i=i+1) begin
`ITCM.mem_r[i][00+7:00] = itcm_mem[i*8+0];
`ITCM.mem_r[i][08+7:08] = itcm_mem[i*8+1];
`ITCM.mem_r[i][16+7:16] = itcm_mem[i*8+2];
`ITCM.mem_r[i][24+7:24] = itcm_mem[i*8+3];
`ITCM.mem_r[i][32+7:32] = itcm_mem[i*8+4];
`ITCM.mem_r[i][40+7:40] = itcm_mem[i*8+5];
`ITCM.mem_r[i][48+7:48] = itcm_mem[i*8+6];
`ITCM.mem_r[i][56+7:56] = itcm_mem[i*8+7];
end
这是tb_top中的一段代码,可以看到仿真中是将testcase中的数据读进ITCM中,而testcase则是一个二进制文件,并且当我将测试文件中内容写为:
93 00 80 00
运行行为级仿真可以看到TCL中输出为:
因此可以发现指令在verilog文件里面存储的方式是小端存储,因此这个在我们自己编写代码中是需要注意的。
此外,在行为级仿真时,我发现仿真结果如下:
可以看到PC的变化过程是00001000到00001004再到80000000,由于E203中指令取值是从ITCM中得到,因此我们可以知道0x0000_1000是系统启动,而0x8000_0000则就是ITCM的基地址。