OpenRisc-37-OpenRISC的CPU&core的整体架构分析

时间:2020-12-13 08:19:09

引言

前面我们分析了ORPSoC的整体架构,并对其子系统进行了深入的分析和了解。但对于ORPSoC的核心模块or1200_top及其内部的core--or1200_cpu模块却鲜有涉及,算是ORPSoC分析的盲区,也是蒙在我心里的一片乌云。

本小结就对这两个模块的整体架构进行分析,扫除这块所谓的‘盲区’和‘乌云’。

1,a general picture

按照惯例,还是先对这两个模块有一个感性认识。下面就是or1200_top和or1200_cpu的模块连接图。

CPU模块:or1200_top

OpenRisc-37-OpenRISC的CPU&core的整体架构分析

core模块:or1200_cpu

OpenRisc-37-OpenRISC的CPU&core的整体架构分析

2,CPU整体架构

1>模块接口

下面就是CPU的实际模块接口图,从中我们可以清晰的看到一个CPU的外部接口。

OpenRisc-37-OpenRISC的CPU&core的整体架构分析

2>模块整体架构图

上面我们了解了CPU的模块接口,但是其接口比较多,我们需要对这些接口进行分类,画出其接口简图,如下:

从中我们可以看出CPU与外部进行数据交换和控制的接口,以及其模块组成。

经过分析对应的RTL代码,我们可以知道:默认配置下,具有一个一路直接映射的8KB数据cache和一个一路直接映射的8KB指令cache,Cache line长度为16-byte,两个cache都是物理索引(physically tagged)。默认配置下支持MMU,其由一个64-entry hash,1-way direct-mapped的数据TLB和指令TLB组成。此外,用调式单元可实现实时调试,tick timer,PIC,和电源管理。

OpenRisc-37-OpenRISC的CPU&core的整体架构分析

3>深入分析

1》数据流图

上面介绍的只是CPU的概要情况,为了便于理解,我们需要弄清楚CPU的数据流向,掌握了数据在CPU内部的流动情况,我们就会有更清晰的认识,毕竟CPU还是数据驱动的东西。经过阅读or1200_top模块相关RTL的code,我画了or1200_top模块的逻辑上的数据流图,如下:

OpenRisc-37-OpenRISC的CPU&core的整体架构分析

2》分析

仔细分析上图。整个流向就是箭头的方向(自下而上)。下面我就以load/stor指令的执行过程来说明:

假如core要执行load指令,就以bootrom.S中的最后一条指令为例:l.lbz r3,r4,0x2

a,指令含义

我先说一下这条指令的含义。通过查手册,可知,这条指令的format是:

l.lbz rD,I(rA)

其含义是:

EA ← exts(Immediate) + rA[31:0]
rD[7:0] ← (EA)[7:0]
rD[31:8] ← 0

总体含义是将内存的一个字节的数据load到通用寄存器中,其具体操作过程是,将立即数0x02先进行0扩展,再与r4里面的值相加得到有效地址EA(注:这个地址就是虚拟内存地址,注意这个地址是虚拟地址,不是物理地址),然后将内存地址为EA[7:0]处的数据load到寄存器r3的低8位中,高位补0。

b,执行过程

core取得这条指令后,计算出虚拟地址,经dmmu模块,得到物理地址,根据物理地址从qmem(相当于一级cache)读取数据,如果出现miss,就是cache miss异常,异常处理会从内存中读取数据放到stor buff(相当于三级cache)和data cache(相当于二级cache),异常处理完成后,再重新执行这条指令,就能读到数据。

当然,如果dmmu中没有对应的物理地址,就是TLB miss,产生一个TLB miss异常,core jump到异常入口处取指,这个过程我之前介绍过,具体过程,这里就不展开阐述。

c,stor

stor指令与load指令执行过程类似。

3,core整体架构

上面我们分析了CPU的架构,并介绍了其数据流向,下面我说一下core的整体架构。

OpenRISC 1200 是OpenRISC 1000 处理器家族的一个实现版本。

OR1200是 32-bit 标量 RISC架构,Harvard 结构, 5级 integer流水线, 支持MMU,还具有DSP能力。

关于architecture是john von neumann,还是harvard,还是modify harvard,还是princeton ,我觉得争论这个的意义不大,其实在一个现实的core的实现中,没有一个明显的界线,一切以提高性能,降低功耗,减小面积等等这些更实际的指标为基准。所以还是那句话“不管是黑猫,白猫,只要能抓住老鼠,就是好猫”。

1>模块接口

下面是core的接口,从中我们可以了解其具体的接口的名称,从名称中我们可以大概了解其与外部的数据及控制交换通路。

OpenRisc-37-OpenRISC的CPU&core的整体架构分析

2>整体架构

说到core的架构,首先必须要把官方的架构图放到这里,如下:

OpenRisc-37-OpenRISC的CPU&core的整体架构分析

3>分析

1》架构图

上面的图我就不说什么了,可以阅读相关的文档了解其大概情况。上面的图太粗糙了,为了介绍core的工作机制,我们需要更深入的分析,这就需要阅读其对应的RTL代码。

经分析,or1200_cpu这个核心中的核心的结构图,如下:

OpenRisc-37-OpenRISC的CPU&core的整体架构分析

2》分析

上图是一个标准的computer architecture结构图。上面一部分是控制通路,下面一部分是数据通路。

一目了然。

4,小结

终于扫除了最后的盲区!

本小节分析了CPU和core的架构,自此,我们对整个ORPSoC的project有了一个初步的,完整的了解,对整个系统(APP+linux/eCos+FPGA+SoC+IPcore+CPU+core)都一一作了分析,不仅如此,我们还写了属于自己的IPCORE和其driver并作了验证,此外我们还测试验证了vga等ORPSoC之外的开源ipcore。

现在再返回头来看ORPSoC的整体模块连接图,我想,就没有‘乱七八糟’的感觉了吧,代替的应该是是‘一览众山小’吧。

“千里之行始于足下”,路还很远,move on.

5,参考文献

1,arch-manual-1.0

2,ORPSoC RTL code