RISC-V MCU中文社区

【分享】 蜂鸟内核ITCM模块以及取值过程

发表于 开源蜂鸟E203 2023-05-09 15:53:32
0
1771
2

队伍编号:CICC1413

摘要

本文主要介绍蜂鸟中的ITCM模块。ITCM在蜂鸟中是用于存储指令的,由于蜂鸟E203内核定位是对于小型的指令系统,因此在蜂鸟定位的系统中,指令基本是全部存储在ITCM中的,因此下面我们介绍ITCM的结构以及从ITCM中取值的过程。

模块介绍

首先,我们先得知道ITCM模块存储位置是在e203_CPU_top下。

图片alt

而我们看ITCM的代码下只有一个子模块

图片alt

该子模块是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中输出为:

图片alt

因此可以发现指令在verilog文件里面存储的方式是小端存储,因此这个在我们自己编写代码中是需要注意的。

此外,在行为级仿真时,我发现仿真结果如下:

图片alt

可以看到PC的变化过程是00001000到00001004再到80000000,由于E203中指令取值是从ITCM中得到,因此我们可以知道0x0000_1000是系统启动,而0x8000_0000则就是ITCM的基地址。

喜欢2
用户评论
studying_drh

studying_drh 实名认证

能拿个好名次将是收获的附带品

积分
问答
粉丝
关注
  • RV-STAR 开发板
  • RISC-V处理器设计系列课程
  • 培养RISC-V大学土壤 共建RISC-V教育生态
RV-STAR 开发板