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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 8600|回复: 35

开源软核学习笔记05(继续OpenMIPS开发笔记)——2014_1_31

[复制链接]
发表于 2014-1-31 11:15:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
*****************************
day3 的学习,增加一个or函数(其实好几个)

*****************************
首先,从流水线结构上来说,没有变化
day3流水线.gif

有变化的,在上图标成了红色,即三个procedure

因为只是增加了函数,其中
andi , xori , lui 指令结构和day2 相比没有变化,都是有立即数的操作指令
86.JPG

而and ,or ,xor , nor 的指令结构不含立即数
01.JPG

所以在修改inst_decode 时,
andi , xori , lui 的译码和 ori 放在一起;
而 and ,or ,xor , nor放在一起。

**********************
以 or 指令为例,译码时,
when EXE_OR =>
rfe1 := '1';
rfe2 := '1';
wreg :='1';
aluop := EXE_OR_OP;
alusel := EXE_RES_LOGIC;
inst_valid := '1';


其中rfe1 表示是否需要读取寄存器1,rfe2 表示是否需要读取寄存器2,wreg 表示是否
有要写的目的寄存器,aluop 表示ALU 要进行的算术操作
类型,alusel 表示ALU 算术操作的结果选择,inst_valid 表示指令是否有效。

共用
rdo := inst(15 downto 11);
rdo 表示要写的目的寄存器地址,

然后在op_select 中

elsif (r.m.waddr = r.e.rfa1 and r.m.wreg = '1' and r.e.rfe1 = '1') then
opdata1 := r.m.result;
--与上一条指令存在数据相关

elsif (r.w.waddr = r.e.rfa1 and r.w.wreg = '1' and r.e.rfe1 = '1') then
opdata1 := r.w.result;
--与上上一条指令存在数据相关

opdata1 选择数据,而不是立即数。同理opdata2

然后在logic_op 中,
when EXE_OR_OP =>
logicout := aluin1 or aluin2;

比较好理解。

这样就完成了day3的第一次理解。
 楼主| 发表于 2014-2-1 10:20:13 | 显示全部楼层
本帖最后由 oldbeginner 于 2014-2-1 10:41 编辑

*********************************
day4 -1 的理解

增加了移位指令

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

感觉指令的增加,确实增加了记忆负担,因此对指令本身暂时不求甚解,还是把精力放在整体结构上。

day4-1流水线.gif

从上图中,可以看出 执行 阶段变得更加复杂了,增加了两个procedure 来应付 移位指令的运算。

同时只需要更改已有的三个procedure中的一个。
在inst_decode 中,
增加对移位指令的译码。其中EXE_SLLV  EXE_SLRV  EXE_SLAV 放在一起,剩余的放在一起。

增加的shift_op 是完成移位功能运算的。

增加的alu_select 是用来选择 shift_op 还是 logic_op 的运算结果。

*************************
day4 -1 暂时这样理解。
 楼主| 发表于 2014-2-1 11:48:19 | 显示全部楼层
*********************************
day4 -2 的理解

增加了指令

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

增加了 arithmetic 运算功能,执行阶段 更复杂了。
day4-2流水线.gif

首先译码 需要增加 新指令的 译码,修改 inst_decode 。

然后,在执行阶段 新增加 arithmetic_op procedure,暂时不理解具体实现,只了解功能即可。

在 alu_select 加入 arithmetic_op 运算结果  的选择。

******************************
day4 -2 的理解

和day4 -1的理解方式一致,避开了指令的具体实现过程,而是侧重流水线方式。
 楼主| 发表于 2014-2-2 10:32:54 | 显示全部楼层
*********************************
day5-1 的理解

简单乘法指令的实现
*********************************


day 5-1 的内容是从 day 4-2 内容上发展的,这样在画流水线时,就显得臃肿。因为day5-1 与day4内容的独立性,同时为了简洁,流水线直接从day3发展,而不是day4。
day5-1流水线.gif

首先是访存和回写阶段寄存器增加了
whilo : std_logic; --是否要写hi、lo 寄存器
hilo : std_logic_vector(63 downto 0); --要写入hi、lo 寄存器的值


在访存阶段,
          --将HI、LO的写信号传递到回写阶段
          v.w.whilo  := r.m.whilo;
          v.w.hilo   := r.m.hilo;


在执行阶段,(以day3 基准,而不是day4-2)
    --操作数选择,是立即数还是寄存器的值
    opdata_select(r, v, ex_opdata1, ex_opdata2);

    --向访存阶段传递要写的目的寄存器、是否要写入目的寄存器
    v.m.waddr := r.e.rd;
    v.m.wreg := r.e.wreg;   
   
    --调用过程logic_op进行逻辑运算,结果存储在ex_logic_res中
    logic_op(r, ex_opdata1, ex_opdata2, ex_logic_res);

    --调用过程mul_op进行乘法运算,结果存储在ex_mul_res中
    mul_op(r, ex_opdata1, ex_opdata2, ex_mul_res);

   
    --调用过程alu_select,依据操作类型,选择对应的运算结果存储到ex_result中
    alu_select(r, ex_logic_res, ex_shift_res, ex_arithmetic_res, ex_mul_res, ex_result);      
   
    --将最终的运算结果传递到访存阶段
    v.m.result := ex_result;

    --依据乘法结果,给出新的hilo、whilo的值
    set_new_hilo(r, v, ex_mul_res, v.m.hilo, v.m.whilo );


蓝色部分即为增加部分

多了两个procedure , mul_op 和 set_new_hilo。
同时需要在inst_decode增加 对 简单乘法指令的译码。
 楼主| 发表于 2014-2-2 12:39:36 | 显示全部楼层
*********************************
day5-2的理解

双周期乘法指令的实现
*********************************

双周期果然很难,看了好长时间才明白一点,先尝试一下,
day5-2流水线.gif
上图中看不出双周期,原因是,有个选择,比如,

在执行阶段,
    if(r.e.cnt /= "00") then     --在inst_decode过程中依据指令设置r.e.cnt的值
            ex_stall_for_multicycle_inst := '1';     --对于多周期指令,设置该值为"1",表示流水线因为
                                                     --多周期指令而暂停
            v.m.whilo := '0';
            v.m.wreg := '0';
          else
            ex_stall_for_multicycle_inst := '0';
    end if;

图中,是从r.e.cnt 直接连线到 v.m.whilo 和 w.m.wreg 和 pc (省略了ex_stall_for_multicycle_inst,因为效果一样)。

*************************************
变化最大的是,图中并未显示出来
    --如果正处于执行阶段的多周期指令,那么保存该指令的操作数,访存、
    --回写阶段的指令可以继续向前流转,同时保存执行阶段指令计算出的HI、Lo
    --的值,以及cnt的值,对多周期指令而言,每执行一个周期,cnt的值减1,
    --cnt为0表示当前是多周期指令的最后一个周期,

    if(ex_stall_for_multicycle_inst = '1') then
      rin.e.reg1 <= ex_opdata1;
      rin.e.reg2 <= ex_opdata2;   
      rin <= r;
      rin.e.cnt <= cnt_temp;        
      rin.e.hilo <= hilo_temp;
      rin.m <= v.m;                   --访存阶段继续向前流转
      rin.w <= v.w;                   --回写阶段继续向前流转
    else   
      rin <= v;                                                      
    end if;  
 楼主| 发表于 2014-2-5 16:56:29 | 显示全部楼层
**********************************
对并发和顺序的回顾

在单周期和多周期的理解上遇到了困难
********************************


首先复习一下,
********************************
因为process内部是顺序执行的,但是具有并发特性,
(原文链接删除,怕审核耽误)

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

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

PROCESS(clk)

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

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

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

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

看完上面的引用后,坏消息是 以前的动画没有清楚区分 并行和顺序; 好消息是 在单周期不区分,不影响学习效果。

但是 就像本文开头的说明 自己在区别单周期和多周期 时遇到了困难,先试试 区分 并行和顺序。

以day3 为例,
02.JPG

左侧是立即执行,有顺序的;
右侧是并发的,要在下一个周期执行。

更新后的动画
day3并行顺序流水线.gif

下一步 计划 通过 day5-2 的细化, 尝试理解 单周期和 多周期的区别。
 楼主| 发表于 2014-2-5 19:26:10 | 显示全部楼层
本帖最后由 oldbeginner 于 2014-2-5 19:38 编辑

**************************
单周期指令

用其它仿真来理解
***************************


理解出现误差,单周期和多周期是针对指令的。

03.JPG
上图是day3 的modelsim 仿真图,因为是静态的,有效理解对出现者是个挑战。单周期指令。

而如果使用其它仿真工具,则效果较好,
ori    r1, r0, 15
ori    r1, r1, 35
ori    r1, r1, 130
ori    r1, r1, 66  ;complete
MIPS五阶段仿真.gif

***********************
上面的 mips simualtor 代码下载
搜索
MIPS五级整数流水线模拟系统
即可。
发表于 2014-2-5 21:55:03 | 显示全部楼层
回复 7# oldbeginner


    佩服!厉害!过节不忘学习
 楼主| 发表于 2014-2-7 20:20:08 | 显示全部楼层
*****************************
为什么在执行阶段控制 new pc的值

day5- 2 大boss
****************************


OpenMIPS一直适合入门,直到 day 5 -2 ,虽然要讲的指令听起来很简单,把一条指令分成两次来处理,借用cnt 来表示 第一次处理还是 第二次处理。

遇到了困难是:
在执行阶段,有
if(r.e.cnt /= "00") then
ex_stall_for_multicycle_inst := '1';
v.m.whilo := '0';
v.m.wreg := '0';

然后,在取指阶段,
   elsif(ex_stall_for_multicycle_inst = '1') then
      --如果正处于执行阶段的是多周期指令,那么不改变pc的值
      v.f.pc := r.f.pc;      
    else
      --下一条指令是当前读取指令地址加4
      v.f.pc := r.f.pc(31 downto 2) + 1;  
    end if;

问题出在此时译码阶段 还有一条 另外的指令,
感觉应该在 译码阶段 就 设置 ex_stall_for_multicycle_inst

感觉应该调换顺序,

    --调用过程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);

然后,
    if(v.e.cnt /= "00") then     --在inst_decode过程中依据指令设置ve.cnt的值
            ex_stall_for_multicycle_inst := '1';     --对于多周期指令,设置该值为"1",表示流水线因为
                                                     --多周期指令而暂停
            v.m.whilo := '0';
            v.m.wreg := '0';
          else
            ex_stall_for_multicycle_inst := '0';
    end if;
*******************************************************

day 5-2 的modelsim 仿真图没有看懂,
考虑 先继续 后面的,最后再回头理解这里。
 楼主| 发表于 2014-2-7 21:32:07 | 显示全部楼层
*************************************
回到吃饭问题来理解双周期

**************************************
吃双截棍.gif

小职工要吃双截棍,厨师自然要想办法了,一步做不出来,要分两步

04.JPG

05.JPG

06.JPG

双截棍制作第二周期
双周期流水线.gif

是这样吗?好像浪费了一碗面。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

×

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

GMT+8, 2024-11-28 06:46 , Processed in 0.034972 second(s), 9 queries , Gzip On, Redis On.

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