在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
楼主: oldbeginner

开源软核学习笔记04(从10天实现处理器—OpenMIPS开发笔记找思路)——2014_1_19

[复制链接]
 楼主| 发表于 2014-1-24 08:26:23 | 显示全部楼层
用上面的方法,在iu.vhd 的学习中遇到了极大的困难。原因有很多,最困扰的是comb (组合逻辑)process 内部的顺序,

在iu.vhd文件 comb process中,是 回写,访存,执行,译码,取值的顺序。并不是先取值,然后译码。。。顺序。

*********************************
因为process内部是顺序执行的,但是具有并发特性,
http://www.dzsc.com/dzbbs/20061201/200765203625890572.html

要分清楚执行赋值和完成赋值之间的区别
VHDL中PROCESS中的语句是顺序语句,但它们具有并行运行的特征.这是因为,信号量的赋值是在遇到end PROCESS这条语句的时候完成的,也就是说,在PROCESS中,只执行赋值,而真正的完成赋值(更新信号量的值)是在一个系统延时后才完成的,这个和变量不一样,变量是立即完成赋值的.

对信号来说,执行赋值是一个过程,它具有顺序的特征,而完成赋值是一个结果,它的发生才真正具有硬件描述语言最本质的并行的特征.也看下面的例子:

PROCESS(clk)

x <= a;  --信号,执行赋值
y <= b;  --信号,执行赋值
z := c;  --变量,执行并完成赋值

end PROCESS    --系统延时后,此句执行,此时x,y的值才被更新

尽管变量z最后才被赋值,但是他的值更新的时间要比x,y早一个系统延时。
*********************************************************************

上面的帮助很有用,但是不足以解释倒序。

这种倒序在常用用到地方是制造行业的JIT拉动生成模式,
46.JPG

这样更加糊涂了。

又补充看了些计算机组成原理方面的课件,
感觉,这不像是玩《暗黑地狱火》,要一级一级地升,大BOSS在后面才会出现。有点像《刀剑神域》本计划打到100层,结果75层就发现了老大(剧透),或者《迷失》第二季就抓到了敌人老大(结果放走了,事实证明伊拉克人审问能力不足)。
47.jpg
结论,iu.vhd 是需要重点以及仔细学习的,尤其是补充了一下相关资料后更加确认。

*****************************************************************************

难点集中到了流水线,流水线概念好理解(好多课件都使用洗衣机,好像一个模子学出来的)。
流水线.gif
 楼主| 发表于 2014-1-24 09:15:48 | 显示全部楼层
要理解流水线,
先要理解一下数据通路,

48.JPG

上面的六个部件解释如下,

49.JPG

50.JPG

51.JPG

52.JPG

数据通路与OpenMIPS有差别,可以用来借鉴。
下一步理解regfile,即寄存器堆。
 楼主| 发表于 2014-1-24 10:23:13 | 显示全部楼层
********************************
理解 regfile

*********************************
------------------------------------------------------------------------------
-- Entity:  regfile
-- File:    regfile.vhd
-- Author:  Lei Silei
-- Description: register file
------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library std;
use WORK.stdlib.all;
use WORK.all;
-----------------------------------------------------------------------------
************************************************
上面都是说明引用了哪些库和包

继续,
**********************************************
entity regfile is
  port (
    clk   : in  std_logic;
          rst   : in  std_logic;
    waddr  : in  std_logic_vector(4 downto 0);
    wdata  : in  std_logic_vector(31 downto 0);
    we     : in  std_logic;
    raddr1 : in  std_logic_vector(4 downto 0);
    re1    : in  std_logic;
    rdata1 : out std_logic_vector(31 downto 0);
    raddr2 : in  std_logic_vector(4 downto 0);
    re2    : in  std_logic;
    rdata2 : out std_logic_vector(31 downto 0)
  );
end;
**************************************

定义了实体,
不如看图方便,
53.JPG

可以借鉴课件资料,虽然有差别
54.JPG

上图可以帮助理解以下的内容,
***************************************
architecture rtl of regfile is
  type mem is array(0 to 31) of std_logic_vector(31 downto 0);
  signal regarr : mem;
***************************************

结构体,定义信号 regarr
继续,
****************************************
begin

  process(clk)
  begin
    if rising_edge(clk) then      
      if(rst /= '1') then              
              if (we = '1') and (waddr /= "00000") then
                --如果是写操作,且目的地址不是r0
                      regarr(conv_integer(waddr)) <= wdata;
                    end if;
      end if;
    end if;
  end process;
********************************************


看了 we表示 write enable,waddr 表示 write address,wdata 表示 write data。
就是写数据,
55.JPG

继续,
*********************************************
  --根据raddr1的值,给出读操作的寄存器1的值
  rdata1 <= (others => '0') when raddr1 = "00000" else
            wdata           when raddr1 = waddr and re1 = '1' and we = '1' else
            regarr(conv_integer(raddr1)) when re1 = '1' else
            (others => '0');
            
  --根据raddr2的值,给出读操作的寄存器2的值
  rdata2 <= (others => '0') when raddr2 = "00000" else
            wdata           when raddr2 = waddr and re2 = '1' and we = '1' else
            regarr(conv_integer(raddr2)) when re2 = '1' else
            (others => '0');

end;
**************************************************

实现的功能就是两个注释,
  --根据raddr1的值,给出读操作的寄存器1的值
--根据raddr2的值,给出读操作的寄存器2的值

从VHDL角度,有两个知识点,

others => '0' 用于对数组中的各个元素赋值‘0’;

另外一个就是条件信号代入语句,
56.JPG

******************************************
这样,regfile 就完成了第一遍理解。
 楼主| 发表于 2014-1-25 05:59:57 | 显示全部楼层
****************************
对 iu.vhd 的理解

***************************
首先看《成长日记》里是怎么解释的,

*****************************************
--流水线在整数单元iu 中定义,对应iu.vhd 文件
entity iu is
port ( ...... );
end;

architecture rtl of iu is
--定义两个信号r、rin
signal r, rin : registers;

begin
-----------------------------------------------------------------------
---------------------------- 组合逻辑过程 comb -------------------
-----------------------------------------------------------------------
comb : process( r, rst, ......)

variable v : registers;

begin
v := r;

-----------------------------------------------------------------------
-- WRITE BACK STAGE 回写阶段
-----------------------------------------------------------------------
--依据此时回写阶段寄存器的值,设置Regfile 模块的写信号
--也就是依据r.w 的值,设置Regfile 模块的写信号,Regfile 是32 个整数寄存器

-----------------------------------------------------------------------
-- MEMORY STAGE 访存阶段
-----------------------------------------------------------------------
--依据此时访存阶段寄存器的值,设置对dmem 模块的读写信号
--也就是依据r.m 的值,设置dmem 模块的读写信号,dmem 是数据存储器
--设置下一时钟周期回写阶段寄存器的值,也就是v.w 的值

-----------------------------------------------------------------------
-- EXECUTE STAGE 执行阶段
-----------------------------------------------------------------------
--依据此时执行阶段寄存器的值,进行指定运算
--也就是依据r.e 的值,进行指定运算
--设置下一时钟周期访存阶段寄存器的值,也就是v.m 的值

-----------------------------------------------------------------------
-- DECODE STAGE 译码阶段
-----------------------------------------------------------------------
--依据此时译码阶段寄存器的值,进行指令译码
--也就是依据r.d 的值,进行指令译码
--设置下一时钟周期执行阶段寄存器的值,也就是v.e 的值

-----------------------------------------------------------------------
-- FETCH STAGE 取指阶段
-----------------------------------------------------------------------
--依据此时取指阶段寄存器的值,访问imem 模块,读取指令
--也就是依据r.f 的值,访问imem 模块,读取指令,imem 模块是指令存储器
--设置下一个时钟周期译码阶段寄存器的值,也就是v.d 的值
--设置下一个时钟周期取指阶段寄存器的值,也就是v.f 的值

-----------------------------------------------------------------------
-- OUTPUTS
-----------------------------------------------------------------------
rin <= v;
end process;

-----------------------------------------------------------------------
---------------------------- 时序逻辑过程 reg --------------------
-----------------------------------------------------------------------
reg : process (clk)

begin
if rising_edge(clk) then
if(rst = '1') then
......
else
r <= rin; --流水线前进一步
end if;
end if;

end process;
end;

****************************************************************


先把上面思路整理一下,然后一个一个分析。

先说个引子,最近汉堡很火热,除了升级为堡青天之外,还有什么什么之歌;前几天哈佛和斯坦福的职工大会都是吃汉堡。有些有想法的人就开始思考了,认为当代人还需要启蒙教育,我非常认同,

饮食多元化对身体有好处。

上面的引子和流水线有啥关系,这是因为使用流水线技术可以更好地为职工服务,而不是单一地吃汉堡。
比如,职工的后代又可爱又聪明,那么饮食多元化对长身体很必要,利用流水线技术,
57.JPG

上面的图片有两点说明,
1、f d e m w 分别代表 相应的寄存器,中间的食品在他们之中传递,最后喂给可爱的小职工;
2、r 表示当前时刻,因为饭是一口一口吃的,所以一个时刻只能吃一样。

既然有当前时刻,自然有下一时刻,
58.JPG

从上图中可以看出,热狗被吃了,食品都向前移动了一位,菜谱上加了披萨。
从中也可以看出对应关系
v.w = r.m
v.m = r.e
v.d = r.f

*******************************************

其实,从图中也可以看出为什么要倒序,因为 w 如果不把热狗喂给小职工, m给他传递三明治时,w只能把热狗丢了,才能接到三明治,同理对其它人。
下一步就是逐个分析代码验证上面的假设。
 楼主| 发表于 2014-1-25 06:56:13 | 显示全部楼层
****************************************
写回阶段的理解

****************************************
59.JPG

61.JPG

60.JPG
 楼主| 发表于 2014-1-25 07:16:16 | 显示全部楼层
*********************************
访存阶段的理解

*********************************

省略了DMEM,内容比较简单

memory stage.gif

62.JPG
 楼主| 发表于 2014-1-25 08:05:54 | 显示全部楼层
**********************************
执行阶段的理解

************************************

执行阶段.gif

63.JPG


设计到两个函数调用,怎样实现放在后面理解。
    --操作数选择,是立即数还是寄存器的值
    opdata_select(r, v, ex_opdata1, ex_opdata2);

    --因为ORI是逻辑操作指令,所以此处只是调用过程logic_op进行逻辑OR运算
    --结果存储在ex_logic_res中
    logic_op(r, ex_opdata1, ex_opdata2, ex_logic_res);
 楼主| 发表于 2014-1-25 08:52:12 | 显示全部楼层
******************************
译码阶段的理解

******************************
64.JPG

65.JPG

66.JPG

同样,
--调用过程inst_decode
          inst_decode(r.d.inst, v.e.wreg, v.e.rd, v.e.aluop, v.e.alusel,
                      v.e.rfe1, v.e.rfe2, v.e.rfa1, v.e.rfa2, v.e.imm, v.e.cnt, v.e.inst_valid);
的细节留在后面。
 楼主| 发表于 2014-1-25 09:22:38 | 显示全部楼层
************************************
取指阶段的理解

************************************

--依据此时取指阶段寄存器的值,访问imem 模块,读取指令

--也就是依据r.f 的值,访问imem 模块,读取指令,imem 模块是指令存储器

--设置下一个时钟周期译码阶段寄存器的值,也就是v.d 的值

--设置下一个时钟周期取指阶段寄存器的值,也就是v.f 的值

取值阶段.gif

67.JPG
 楼主| 发表于 2014-1-26 06:15:07 | 显示全部楼层
*********************************
复习流水线的理解

*********************************
57.JPG

以流水线为职工服务为例,将抽象形象化;

流水线分段.gif

把数据通路分段;

68.JPG
比较完整的MIPS通路

但是,现在刚开始重点是缩小版的OpenMIPS
69.JPG

下一步尝试利用计算机组成原理的语言再分别理解一下五个阶段。

1、你和他讲流水线,他和你讲吃饭; 2、你和他讲吃饭,他和你讲回写; 3、你和他讲回写,他和你讲热狗。。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-24 09:54 , Processed in 0.054774 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表