本文参考作者
自己动手写CPU之第六阶段(1)——移动操作指令说明
自己动手写CPU之第六阶段(2)——移动操作指令实现思路
本文会添加笔者自己的思路以及理解在其中。

指令说明


这6条指令都是R类型指令,并且指令码都是6’b000000,即均为SPECIAL类指令,同时,指令第6-10bit都为0,可以依据指令中0-5bit功能码的值判断是哪一种指令。各指令的用法及作用说明如下。

  • 当功能码为6’b001011时,表示是movn指令,不为零移动
    指令用法为:movn rd, rs, rt
    指令作用为:if rt ≠0 then rd <- rs,判断地址为rt的通用寄存器的值,如果不为零,那么将地址为rs的通用寄存器的值赋给地址为rd的通用寄存器,反之,保持地址为rd的通用寄存器不变。movn是Move Conditional on Not Zero的意思。

  • 当功能码为6’b001010时,表示是movz指令,为零移动
    指令用法为:movz rd, rs, rt
    指令作用为:if rt = 0 then rd <- rs,与上面movn指令的作用正好相反,判断地址为rt的通用寄存器的值,如果为零,那么将地址为rs的通用寄存器的值赋给地址为rd的通用寄存器,反之,保持地址为rd的通用寄存器不变。movz是Move Conditional on Zero的意思。

  • 当功能码为6’b010000时,表示是mfhi指令,赋值HI中的值给rd寄存器
    指令用法为:mfhi rd
    指令作用为:rd <- hi,将特殊寄存器HI的值赋给地址为rd的通用寄存器。

  • 当功能码为6’b010010时,表示是mflo
    指令用法为:mflo rd
    指令作用为:rd <- lo,将特殊寄存器LO的值赋给地址为rd的通用寄存器。

  • 当功能码为6’b010001时,表示是mthi指令
    指令用法为:mthi rs
    指令作用为:hi <- rs,将地址为rs的通用寄存器的值赋给特殊寄存器HI。

  • 当功能码为6’b010011时,表示是mtlo指令
    指令用法为:mtlo rs
    指令作用为:lo <- rs,将地址为rs的通用寄存器的值赋给特殊寄存器LO。

指令实现思路说明

本文牵扯到新的特殊寄存器HI,LO。将在原先的基础上添加。

分为三类,movn,movz第一类是不需要特殊寄存器的,直接类似于之前的指令,新加一个判断的功能决定是否写入寄存器。mflo,mfhi 第二类是需要读寄存器的, 设计在执行阶段

  (1)在译码阶段依据指令,给出运算类型alusel_o、运算子类型aluop_o的值,同时因为有要写的目的寄存器,所以wreg_o为WriteEnable,wd_o为指令中rd的值,也就是目的寄存器地址。(2)在执行阶段获取HI或LO寄存器的值,作为要写入目的寄存器的数据,并将这些信息传递到访存阶段。(3)访存阶段将这些信息再传递到回写阶段。(4)回写阶段依据这些信息修改目的寄存器。

mthi、mtlo第三类指令需要写寄存器,他的实现思路如下

  这2条指令需要写HI、LO寄存器,与之前实现的通用寄存器一样,对HI、LO寄存器的写操作放在回写阶段进行。(1)在译码阶段依据指令,给出运算类型alusel_o、运算子类型aluop_o的值,同时读出地址为rs的通用寄存器的值。由于mthi、mtlo不写通用寄存器,所以wreg_o为WriteDisable,wd_o为0。(2)在执行阶段确定要写HI、LO寄存器的情况,以及要写入的值,并将这些信息传递到访存阶段。(3)访存阶段将这些信息再传递到回写阶段。(4)回写阶段依据这些信息修改HI、LO寄存器的值。

这里进行的修改其实只是将数据在译码执行等阶段进行处理,根据指令不同,将原先要写入寄存器堆的数据写入新的寄存器即可。而读特殊寄存器的时候,是将寄存器中的数据读出来在写入通用寄存器,其实和从其他通用寄存器中读数据差别不是很大。下面是雷思磊;老师做的数据流图。

依据上边的分析以及图示,有了如下的修改。
增加了HILO寄存器模块,并且该模块放在回写阶段。
将HI、LO寄存器的值传递到执行阶段,在执行阶段增加了一个选择模块,用于选择要参与运算的数据,如果是mfhi、mflo指令,那么就会选择传递过来的HI、LO寄存器的值。

新的数据相关问题

进一步考虑mfhi、mflo指令的处理过程,这2条指令会在流水线执行阶段读取HI、LO寄存器的值,如果直接采用HILO模块给出的HI、LO寄存器的值,可能不是正确的HI、LO寄存器的值,因为此时处于访存、回写阶段的指令有可能会修改HI、LO寄存器,以如下程序为例。

1、    lui $1,0x0000          # $1 = 0x00000000
2、    lui $2,0xffff          # $1 = 0xffff0000
3、    mthi $0                # hi = 0x00000000
4、    mthi $1                # hi = 0x00000000
5、    mthi $2                # hi = 0xffff0000
6、    mfhi $4                # $4 = 0xffff0000

指令3、4、5均要修改HI寄存器,当指令6处于执行阶段时,指令5处于访存阶段,指令4处于回写阶段,而此时HI寄存器的值是指令3刚刚写入的0x00000000,HILO模块正是将该值传到执行阶段,如果采用这个值,那么就会出错,偏离程序设想,正确的值应该是当前处于访存阶段的指令5要写的数据,如图所示。

似曾相识,是不是?这就是上一章介绍过的数据相关问题,解决措施还是使用数据前推。将处于访存阶段、回写阶段的指令对HI、LO寄存器的操作信息反馈到执行阶段,执行阶段依据这些信息,确定HI、LO寄存器的正确值。为此,需要修改数据流图如图6-4所示,相比图6-3,主要增加的部分就是将访存阶段、回写阶段的信息反馈到执行阶段,输入到执行阶段的选择模块(图中粗线所示),如果处于执行阶段的是mfhi、mflo指令,那么就会从中选择HI、LO寄存器的正确值。

对系统的修改

修改代码思路与说明

HI,LO寄存器的实现

`timescale 1ns / 1ps
`include "defines.v"
module hilo_reg(input       wire                        clk     ,input      wire                        rst     ,   //write portsinput      wire                        we      ,input      wire    [`RegBus]          hi_i    ,input          wire    [`RegBus]          lo_i    ,//read portsoutput         reg     [`RegBus]          hi_o    ,output         reg     [`RegBus]          lo_o    );
always @ (posedge clk )
beginif(rst == `RstEnable)beginhi_o <= `ZeroWord ;lo_o <= `ZeroWord ;endelse if(we == `WriteEnable)beginhi_o <= hi_i ;lo_o <= lo_i ;end
end
endmodule

译码阶段

添加代码即可,这里只需要进行译码即可

case(op)`EXE_SPECIAL_INST :begincase(op2) 5'b0000_0:begincase(op3)......`EXE_MFHI:beginwreg_o         <= `WriteEnable;aluop_o    <= `EXE_MFHI_OP;alusel_o   <= `EXE_RES_MOVE;reg1_read_o <= 1'b0;reg2_read_o <= 1'b0;instvalid   <= `InstValid;end`EXE_MFLO:beginwreg_o        <= `WriteEnable;aluop_o    <= `EXE_MFLO_OP;alusel_o   <= `EXE_RES_MOVE;reg1_read_o <= 1'b0;reg2_read_o <= 1'b0;instvalid   <= `InstValid;end`EXE_MTHI:beginwreg_o        <= `WriteDisable;aluop_o   <= `EXE_MTHI_OP;reg1_read_o <= 1'b1;reg2_read_o <= 1'b0;instvalid    <= `InstValid;end`EXE_MTLO:beginwreg_o        <= `WriteDisable;aluop_o   <= `EXE_MTLO_OP;reg1_read_o <= 1'b1;reg2_read_o <= 1'b0;instvalid    <= `InstValid;end`EXE_MOVN:beginaluop_o   <= `EXE_MOVN_OP;alusel_o   <= `EXE_RES_MOVE;reg1_read_o <= 1'b1;reg2_read_o <= 1'b1;instvalid   <= `InstValid;if(reg2_o != `ZeroWord)wreg_o <= `WriteEnable;else wreg_o <= `WriteDisable;end`EXE_MOVZ:beginaluop_o    <= `EXE_MOVZ_OP;alusel_o   <= `EXE_RES_MOVE;reg1_read_o <= 1'b1;reg2_read_o <= 1'b1;instvalid   <= `InstValid;if(reg2_o == `ZeroWord)wreg_o <= `WriteEnable;else wreg_o <= `WriteDisable;enddefault:beginendendcaseenddefault:beginendendcaseend
endcase

执行阶段

这里修改比较大,后期注释

`timescale 1ns / 1ps
`include "defines.v"
module ex(input         wire                    rst         ,//译码送至执行阶段的数据信息input       wire    [`AluOpBus]        aluop_i     ,input      wire    [`AluSelBus]   alusel_i    ,input      wire    [`RegBus]      reg1_i      ,input      wire    [`RegBus]      reg2_i      ,input      wire    [`RegAddrBus]  wd_i        ,input      wire                    wreg_i      ,//执行结果output       reg     [`RegAddrBus]  wd_o        ,output         reg                     wreg_o      ,output         reg     [`RegBus]      wdata_o     ,//HILO模块给出的HI,LO寄存器的值input      wire    [`RegBus]      hi_i        ,input      wire    [`RegBus]      lo_i        ,//回写阶段的指令是否要写HI,LO,用于检测HI,LO寄存器带来的数据相关问题input         wire    [`RegBus]      wb_hi_i     ,input      wire    [`RegBus]      wb_lo_i     ,input      wire                    wb_whilo_i  ,//访存阶段的指令是否要写HI,LO,用于检测HI,LO寄存器带来的数据相关问题input         wire    [`RegBus]      mem_hi_i    ,input      wire    [`RegBus]      mem_lo_i    ,input      wire                    mem_whilo_i ,//处于执行阶段的指令对HI,LO寄存器的写操作请求output        reg     [`RegBus]      hi_o        ,output         reg     [`RegBus]      lo_o        ,output         reg                     whilo_o );
//保存逻辑运算的结果
reg [`RegBus]  logicout    ;//保存位移运算结果
reg [`RegBus]  shiftres    ;// 移动操作的结果
reg [`RegBus]  moveres     ;// 保存HI寄存器的最新值
reg [`RegBus]  HI          ;// 保存LO寄存器的最新值
reg [`RegBus]  LO          ;
/*********************************************************************************
*************** 依据aluop_i指示的运算子类型进行运算,
*********************************************************************************/always @ (*)
beginif( rst == `RstEnable)logicout <= `ZeroWord;else begincase(aluop_i)`EXE_OR_OP:beginlogicout <= reg1_i | reg2_i;end`EXE_AND_OP:beginlogicout <= reg1_i & reg2_i;end`EXE_NOR_OP:          //逻辑或与非beginlogicout <= ~(reg1_i | reg2_i);end`EXE_XOR_OP:beginlogicout <= reg1_i ^ reg2_i;enddefault:logicout <= `ZeroWord;endcaseend
endalways @ (*)
beginif(rst == `RstEnable)shiftres <= `ZeroWord;else case(aluop_i)`EXE_SLL_OP:     //逻辑左移shiftres <= reg2_i << reg1_i[4:0];`EXE_SRL_OP:shiftres <= reg2_i >> reg1_i[4:0];`EXE_SRA_OP:shiftres <= ( {32{ reg2_i[31]} } << (6'd32 - {1'b0,reg1_i[4:0] } ) ) | reg2_i >> reg1_i[4:0];default:beginshiftres <= `ZeroWord;end endcase
end/*********************************************************************************
*************** 第一阶段,得到最新的HI,LO寄存器的值,此处要解决数据相关问题
*********************************************************************************/
always @ (*)
beginif(rst == `RstEnable){HI,LO} <= {`ZeroWord,`ZeroWord};else if(mem_whilo_i == `WriteEnable){HI,LO} <= {mem_hi_i,mem_lo_i};      //访存阶段的指令要写入HI,LO寄存器中elseif(wb_whilo_i == `WriteEnable)   {HI,LO} <= {wb_hi_i,wb_lo_i};       //回写阶段的指令要写入HI,LO寄存器中else{HI,LO} <= {hi_i,lo_i};
end
/*********************************************************************************
*************** 第二阶段,MFHI,MFLO,MOVE,MOVZ指令
*********************************************************************************/
always @ (*)
beginif(rst == `RstEnable)moveres <= `ZeroWord;                 else                begin               moveres <= `ZeroWord;case(aluop_i)`EXE_MFHI_OP:moveres <= HI;         //如果是MFHI指令,HI的值就会作为移动操作的结果`EXE_MFLO_OP:moveres <= LO;          //如果是MFLO指令,LO的值就会作为移动操作的结果                                  `EXE_MOVZ_OP:moveres <= reg1_i;        //如果是MOVZ指令,reg1_i的值就会作为移动操作的结果      `EXE_MOVN_OP:moveres <= reg1_i;        //如果是MOVN指令,reg1_i的值就会作为移动操作的结果      default:;endcaseend
end
/*********************************************************************************
*************** 第三阶段:依据alusel_i指示的运算类型,确定wdata_o的值
*********************************************************************************/always @ (*)
beginwd_o <= wd_i;              //wd_o等于wd_i,要写入的寄存器地址wreg_o <= wreg_i;          //wreg_o等于wreg_i,表示是否要写入目的寄存器case(alusel_i)`EXE_RES_LOGIC:beginwdata_o <= logicout;        //wdata_o中存放逻辑运算运算结果end`EXE_RES_SHIFT:beginwdata_o <= shiftres;        //wdata_o中存放位移运算运算结果end`EXE_RES_MOVE:beginwdata_o <= moveres;          //指令为EXE_RES_MOVEenddefault:wdata_o <= `ZeroWord;endcase
end
/*********************************************************************************
*********   第四阶段:如果是MTHI,MTLO指令,那么需要给出的whilo_o,hi_o,lo_i的值
*********************************************************************************/
always @ (*)
beginif(rst == `RstEnable)beginwhilo_o <= `WriteDisable;hi_o <= `ZeroWord;lo_o <= `ZeroWord;      end else if(aluop_i == `EXE_MTHI_OP) beginwhilo_o <= `WriteEnable;hi_o <= reg1_i;lo_o <= LO;endelse if(aluop_i == `EXE_MTLO_OP) beginwhilo_o <= `WriteEnable ;hi_o <= HI;lo_o <= reg1_i;endelse     beginwhilo_o <= `WriteDisable ;hi_o <= `ZeroWord;lo_o <= `ZeroWord;end
end
endmodule

之后就是连线以及顶层了。这里给出顶层。

顶层例化代码

其实这里的例化也是有一定的技巧的,首先笔者发现,这里所有的数据传输,因此数据传输模块需要进行端口声明。具体的写法如下,其次就是组合逻辑之间的特殊联系,这里只有译码阶段与通用寄存器之间的连线。

`timescale 1ns / 1ps
`include "defines.v"
module openmips(input           wire                    clk         ,input          wire                    rst         ,   input           wire [`RegBus]         rom_data_i  ,output             wire [`RegBus]         rom_addr_o  ,output             wire                    rom_ce_o    );
//连接IF/ID模块间的连线与译码器ID模块之间的变量
wire    [`InstAddrBus] pc           ;
wire    [`InstAddrBus]  id_pc_i     ;
wire    [`InstBus]     id_inst_i    ;//连接译码阶段ID模块输出与ID/EX模块的输入变量
wire    [`AluOpBus]        id_aluop_o   ;
wire    [`AluSelBus]   id_alusel_o  ;
wire    [`RegBus]      id_reg1_o    ;
wire    [`RegBus]      id_reg2_o    ;
wire    [`RegAddrBus]  id_wd_o      ;
wire                    id_wreg_o    ;//连接EX与EX/MEM之间的连线
wire    [`RegAddrBus]  ex_wd_o      ;
wire                    ex_wreg_o    ;
wire    [`RegBus]      ex_wdata_o   ;
wire    [`RegBus]       ex_hi_o      ;
wire    [`RegBus]       ex_lo_o      ;
wire                    ex_whilo_o   ; //连接EXM与输出之间的连线
wire    [`RegAddrBus]   mem_wd_i     ;
wire                    mem_wreg_i   ;
wire    [`RegBus]       mem_wdata_i  ;
wire    [`RegBus]       mem_hi_i     ;
wire    [`RegBus]       mem_lo_i     ;
wire                    mem_whilo_i  ;//连接MEM_wb与回写阶段(寄存器堆)的输入变量
wire    [`RegAddrBus]  wb_wd_i      ;
wire                    wb_wreg_i    ;
wire    [`RegBus]      wb_wdata_i   ;//连接ID与寄存器regfile之间的连线
wire    [`RegBus]      reg1_data    ;
wire    [`RegBus]      reg2_data    ;
wire                    reg1_read    ;
wire                    reg2_read    ;
wire    [`RegAddrBus]  reg1_addr    ;
wire    [`RegAddrBus]  reg2_addr    ;//ID/EX 与EX之间的联系
wire    [`AluOpBus]     ex_aluop_i   ;
wire    [`AluSelBus]    ex_alusel_i  ;
wire    [`RegBus]       ex_reg1_i    ;
wire    [`RegBus]       ex_reg2_i    ;
wire    [`RegAddrBus]   ex_wd_i      ;
wire                    ex_wreg_i    ;//MEM访存与回写阶段的连线,MEM与MEM_WB
wire    [`RegAddrBus]   mem_wb_o     ;
wire                    mem_wreg_o   ;
wire    [`RegBus]       mem_wdata_o  ;
wire    [`RegBus]       mem_hi_o     ;
wire    [`RegBus]       mem_lo_o     ;
wire                    mem_whilo_o  ;
//lilo模块寄存器的来连线,写寄存器
wire                   hilo_we       ;
wire    [`RegBus]      hilo_hi_i     ;
wire    [`RegBus]      hilo_lo_i     ;
//执行阶段的读寄存器,HILO模块送出去的信息
wire    [`RegBus]      hilo_hi_o     ;
wire    [`RegBus]      hilo_lo_o     ;
pc_reg pc_reg0 (.clk        (clk        ), .rst     (rst        ), .pc          (pc         ), .ce          (rom_ce_o   ));
assign rom_addr_o = pc  ;      //指令寄存器的输入地址就是pc的值if_id if_id0 (.clk        (clk        ), .rst     (rst        ), .if_pc       (pc         ), .if_inst (rom_data_i ), .id_pc       (id_pc_i    ), .id_inst (id_inst_i  ));id id0 (.rst        (rst        ), //与模块if_id之间的连线.pc_i       (id_pc_i    ), .inst_i     (id_inst_i  ), //来自regfile模块的输入.reg1_data_i(reg1_data  ), .reg2_data_i(reg2_data  ), .reg1_read_o(reg1_read  ), .reg2_read_o(reg2_read  ), .reg1_addr_o(reg1_addr  ), .reg2_addr_o(reg2_addr  ),// 与ID/EX模块的连线.aluop_o    (id_aluop_o ), .alusel_o   (id_alusel_o), .reg1_o     (id_reg1_o  ), .reg2_o     (id_reg2_o  ), .wd_o       (id_wd_o    ), .wreg_o     (id_wreg_o  ),//与执行阶段的连线.ex_wd_i    (ex_wd_o    ),.ex_wreg_i  (ex_wreg_o  ),.ex_wdata_i (ex_wdata_o ),//与访存阶段的连线.mem_wd_i   (mem_wb_o   ),.mem_wreg_i (mem_wreg_o ),.mem_wdata_i(mem_wdata_o));regfile regfile0 (.clk      (clk        ), .rst     (rst        ), //与mem_wb之间的连线.we        (wb_wreg_i  ), .waddr       (wb_wd_i    ), .wdata       (wb_wdata_i ), //与ID之间的连线.re1       (reg1_read  ), .re2         (reg2_read  ), .raddr1      (reg1_addr  ), .rdata1      (reg1_data  ), .raddr2      (reg2_addr  ), .rdata2      (reg2_data  ));id_ex id_ex0 (.clk       (clk        ), .rst     (rst        ), //与id之间的连线.id_aluop  (id_aluop_o ), .id_alusel   (id_alusel_o), .id_reg1 (id_reg1_o  ), .id_reg2 (id_reg2_o  ), .id_wd       (id_wd_o    ), .id_wreg (id_wreg_o  ), //与ex之间的连线.ex_aluop  (ex_aluop_i ), .ex_alusel   (ex_alusel_i), .ex_reg1 (ex_reg1_i  ), .ex_reg2 (ex_reg2_i  ), .ex_wd       (ex_wd_i    ), .ex_wreg (ex_wreg_i  ));ex ex0 (.rst     (rst        ), //与id_ex之间的连线.aluop_i    (ex_aluop_i ), .alusel_i    (ex_alusel_i), .reg1_i      (ex_reg1_i  ), .reg2_i      (ex_reg2_i  ), .wd_i        (ex_wd_i    ), .wreg_i      (ex_wreg_i  ), //与HILO寄存器模块的连线.从HILO读出的数据.hi_i       (hilo_hi_o  ),.lo_i       (hilo_lo_o  ),//引入mem_wb的数据.wb_hi_i    (hilo_hi_i  ),.wb_lo_i    (hilo_lo_i  ),.wb_whilo_i (hilo_we    ),//引入的mem数据.mem_hi_i   (mem_hi_i   ),.mem_lo_i   (mem_lo_i   ),.mem_whilo_i(mem_whilo_i),//与ex/mem之间的连线.wd_o       (ex_wd_o    ), .wreg_o     (ex_wreg_o  ), .wdata_o    (ex_wdata_o ),.hi_o       (ex_hi_o    ),.lo_o       (ex_lo_o    ),.whilo_o    (ex_whilo_o ));ex_mem ex_mem0 (.clk       (clk        ), .rst     (rst        ), //与EX之间的连线.ex_wd         (ex_wd_o    ), .ex_wreg (ex_wreg_o  ), .ex_wdata    (ex_wdata_o ),.ex_hi      (ex_hi_o    ),.ex_lo      (ex_lo_o    ),.ex_whilo   (ex_whilo_o ),       //与MEM之间的连线.mem_wd   (mem_wd_i   ), .mem_wreg    (mem_wreg_i ), .mem_wdata   (mem_wdata_i),.mem_hi     (mem_hi_i   ),    .mem_lo     (mem_lo_i   ),    .mem_whilo  (mem_whilo_i));mem mem0 (.rst     (rst        ),//与ex_mem之间的连线.wd_i       (mem_wd_i   ), .wreg_i  (mem_wreg_i ), .wdata_i     (mem_wdata_i), .hi_i        (mem_hi_i   ),.lo_i         (mem_lo_i   ),.whilo_i  (mem_whilo_i),       //与mem_wb之间的连线.wd_o        (mem_wb_o   ),       //要写入的目的寄存器地址 .wreg_o  (mem_wreg_o ),       //是否要写入目的寄存器.wdata_o   (mem_wdata_o),       //要写入的数据.hi_o       (mem_hi_o   ), .lo_o       (mem_lo_o   ), .whilo_o    (mem_whilo_o) );mem_wb mem_wb (.clk      (clk        ), .rst     (rst        ),//与mem之间的连线.mem_wb    (mem_wb_o   ), .mem_wreg    (mem_wreg_o ), .mem_wdata   (mem_wdata_o),.mem_hi_i   (mem_hi_o   ),.mem_lo_i   (mem_lo_o   ),.mem_whilo_i(mem_whilo_o), //送到回写的信息.wb_wd        (wb_wd_i    ), .wb_wreg     (wb_wreg_i  ), .wb_wdata    (wb_wdata_i ),//送到Hilo模块的信息数据.wb_hi_o    (hilo_hi_i  ),.wb_lo_o    (hilo_lo_i  ),.wb_whilo_o (hilo_we    ));hilo_reg hilo_reg0 (.clk        (clk        ), .rst        (rst        ), .we         (hilo_we    ), .hi_i       (hilo_hi_i  ), .lo_i       (hilo_lo_i  ), .hi_o       (hilo_hi_o  ), .lo_o       (hilo_lo_o  ));endmodule

其余阶段的连线在书中自己参阅,这里不一一给出。至此即可实现移动该操作。

测试验证



下面是笔者的测试,符合预期。验证成功。

verilog实现多周期处理器之——(五)移动操作(通用数据传送)指令的实现相关推荐

  1. verilog实现多周期处理器之——(三)数据相关问题及其解决

    本文于自己动手写CPU之第五阶段--流水线数据相关问题 "相关"问题 流水线中常常有一些被称为"相关"的情况发生,它使得指令序列中下一条指令无法依照设计的时钟周 ...

  2. verilog实现多周期处理器之——(二)第一条指令ori的实现

    本博文希望对于OpenMIPS第一条指令ori加以实现并总结.会加入一些基本的理论以及博主的学习记录. 流水与五级流水 什么是流水:拆分,并行.将多条指令的执行相互重叠起来.就构成了流水,这样充分利用 ...

  3. verilog实现多周期处理器之——目录及总述

    本系列博文将使用verilog语言,实现兼容MIPS32指令集架构的处理器--OpenMIPS,MIPS是典型的RSIC处理器.主要依据雷思磊老师的<自己动手写CPU>,袁春风老师主编的& ...

  4. verilog实现多周期处理器之——(一)基本概念以及总体框架

    本系列博文将使用verilog语言,实现兼容MIPS32指令集架构的处理器--OpenMIPS,MIPS是典型的RSIC处理器.本系列博文参考雷思磊老师的<自己动手写CPU>,袁春风老师主 ...

  5. verilog实现多周期处理器之——(四)逻辑,移位操作与空指令的添加

    逻辑,移位操作与空指令的添加 综述 ID模块的修改 EX模块的修改 仿真验证 I-型指令 lui ori andi xori xor&nor R-型指令 or and 移位类指令 sll sr ...

  6. verilog实现多周期处理器之——(六)简单算数操作指令的实现

    实现的指令说明 这里解释有符号扩展与无符号扩展,有符号数扩展符号位.也就是1,无符号数扩展0.也就是在前面补满零或1 R-型指令 加减比较指令 add.addu.sub.sub.slt.sltu 这6 ...

  7. verilog实现多周期处理器之——(零)GUN工具链的安装

    参考雷思磊老师得<自己动手写CPU> 这里不需要下载书中说的虚拟机,这里笔者用的是VMware.不需要破解,直接安装点击选择仅用于非商业即可使用!! 安装Ubuntu这里笔者不给出步骤. ...

  8. Docker系列 五.Docker容器数据卷

    五.Docker容器数据卷 环境&工具: 阿里云轻量级服务器.CentOS 7系统.FinalShell(其他连接客户端也可以) 是什么 docker的理念将运行的环境打包形成容器运行,运行可 ...

  9. 实验五 oracle高级数据查询技术

    实验五 oracle高级数据查询技术 实验目的:  一.掌握日期型数据的操作技术  二.掌握层次查询技术  三.理解情景查询与翻译查询技术  四.了解统计查询技术 实验内容: 一.日期型数据的操作   ...

最新文章

  1. 点分治问题 ----------- P2993 [FJOI2014]最短路径树问题 [最短路径树+点分治+采坑]
  2. 使用jQuery的attr方法来修改onclick值
  3. Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
  4. centos升级之内核kernel
  5. 谈谈C#中的三个关键词new , virtual , override(装载 Winner.Net)
  6. decimalformat精度丢失_php intval 两位小数乘以100后结果少1
  7. 计算机二级学那个科目,考计算机二级选哪个科目好 哪个科目简单
  8. leetcode题解191-位1的个数
  9. vscode中控制台不能输入_vscode调试时如何在控制台输入
  10. c++构造函数分类说明
  11. Win10怎么把登录密码去掉
  12. 联想服务器光驱安装win7系统,联想光盘安装win7系统教程
  13. [ thanos源码分析系列 ]thanos sidecar组件源码简析
  14. 力科(Lecroy)示波器专用波形文件(轨迹文件/trace文件/.trc文件)在MATLAB上的解析与回写
  15. 截止2017年5月19日小虎软考粉丝有798人
  16. 了解软件工程与计算机科学的联系与区别
  17. WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers
  18. Elasticsearch 搜索条件与聚合结果再进行过滤的多重聚合查询-过滤桶的使用(六)
  19. python微信交流群,零基础、入门、大牛都可加入!
  20. 可以把将日文汉字转换成平假名、片假名、罗马音的KaKaSi

热门文章

  1. idea提示不区分大小写,解决方法
  2. golang中包互相引用的解决方法
  3. Jupyter-notebook安装问题及解决
  4. Python是否支持短路?
  5. 如何在VS2013中隐藏引用计数?
  6. 如何查看表或列的所有外键?
  7. 如何从列表中删除第一个项目?
  8. 线索二叉树是一种什么结构_技术面试之常用的数据结构
  9. PTA—考试座位号(C语言)
  10. Node文件服务器(文件上传)