当前位置: 首页 > news >正文

站长工具seo排名查询制作相册的软件

站长工具seo排名查询,制作相册的软件,wordpress超链接,免费行情软件下载入口逻辑#xff0c;移位操作与空指令的添加 综述ID模块的修改EX模块的修改仿真验证I-型指令luioriandixorixornor R-型指令orand 移位类指令sllsrlsrasllvsrlvsravssnop、nop 综述 文章引于自己动手写CPU之第五阶段#xff08;3#xff09;——MIPS指令集中的逻辑、移位与… 逻辑移位操作与空指令的添加 综述ID模块的修改EX模块的修改仿真验证I-型指令luioriandixorixornor R-型指令orand 移位类指令sllsrlsrasllvsrlvsravssnop、nop 综述 文章引于自己动手写CPU之第五阶段3——MIPS指令集中的逻辑、移位与空指令 指令描述参考与博文[BOOK]感谢博主的分享 由于那个指令具有不同的指令格式但一共就只有三种因此这里将其进行区分进行译码以及执行相关代码需要进行修改。这里笔者直接加入的指令具体的指令作用在书中或者博文中都很明确有需要可以自行翻阅查看。 照例笔者会将自己对于代码的理解以及相关的必要知识记录总结在对应的目录下 ID模块的修改 首先是要确定指令的类型这里对对应的指令进行区分使用的方式是首先判断op然后若是op下有对应的指令依次同理进行判断。注意这里有一个例外情况就是使用inst_i[31:21]进行判断这里是单独分开进行判断的。具体见代码。由于具体的指令使用的寄存器数量不同对于每一个数据的处理也是不同的具体可以在书中找到对应的操作然后对应代码中查看。 timescale 1ns / 1ps include defines.v module id(input wire rst ,input wire [InstAddrBus] pc_i ,input wire [InstBus] inst_i ,//读取regfile的值input wire [InstBus] reg1_data_i ,input wire [InstBus] reg2_data_i ,//输出到regfile的信息output reg reg1_read_o ,output reg reg2_read_o ,output reg [RegAddrBus] reg1_addr_o ,output reg [RegAddrBus] reg2_addr_o ,//送到执行阶段的信息output reg [AluOpBus] aluop_o ,output reg [AluSelBus] alusel_o ,output reg [RegBus] reg1_o , //送到执行阶段的源操作数output reg [RegBus] reg2_o , //送到执行阶段的源操作数output reg [RegAddrBus] wd_o ,output reg wreg_o , //处于执行阶段的指令运行的运算结果input wire [RegAddrBus] ex_wd_i , //执行阶段的目的寄存器地址input wire ex_wreg_i , //是否要写入数据标志 input wire [RegBus] ex_wdata_i , //执行阶段送到访存的数据//处于访存阶段的指令运行的运算结果input wire [RegAddrBus] mem_wd_i ,input wire mem_wreg_i ,input wire [RegBus] mem_wdata_i ); //取得指令的指令码功能码 //用于ori指令只需要判断21-31 bit的值即可判断是否是ori指令 wire [5:0] op inst_i[31:26] ; //操作指令码 wire [4:0] op2 inst_i[10:6 ] ; //由位移指令使用定义位移位数 wire [5:0] op3 inst_i[ 5: 0] ; //功能码 wire [4:0] op4 inst_i[20:16] ; //目标寄存器码//保存指令执行需要的立即数 reg [RegBus] imm;//指示指令是否有效 reg instvalid;/********************************************************************************* *************************** 第一阶段对指令进行译码 *************************** *********************************************************************************/always (*) beginif(rst RstEnable)beginaluop_o EXE_NOP_OP ;alusel_o EXE_RES_NOP ;wd_o NOPRegAddr ;wreg_o WriteDisable ;instvalid InstValid ;reg1_read_o 1b0 ;reg2_read_o 1b0 ;reg1_addr_o NOPRegAddr ;reg2_addr_o NOPRegAddr ;imm 32h0 ;endelse beginaluop_o EXE_NOP_OP ;alusel_o EXE_RES_NOP ;wd_o inst_i[15:11] ;wreg_o WriteDisable ;instvalid InstInValid ;reg1_read_o 1b0 ;reg2_read_o 1b0 ; reg1_addr_o inst_i[25:21] ;//默认通过Regfile读取端口1的寄存器地址reg2_addr_o inst_i[20:16] ;//默认通过Regfile读取端口2的寄存器地址 imm ZeroWord ;case(op)EXE_SPECIAL_INST :begincase(op2) 5b0000_0:begincase(op3)EXE_OR:beginwreg_o WriteEnable;aluop_o EXE_OR_OP;alusel_o EXE_RES_LOGIC;reg1_read_o 1b1;reg2_read_o 1b1;instvalid InstValid;endEXE_AND:beginwreg_o WriteEnable;aluop_o EXE_AND_OP;alusel_o EXE_RES_LOGIC;reg1_read_o 1b1;reg2_read_o 1b1;instvalid InstValid;endEXE_XOR:beginwreg_o WriteEnable;aluop_o EXE_XOR_OP;alusel_o EXE_RES_LOGIC;reg1_read_o 1b1;reg2_read_o 1b1;instvalid InstValid;endEXE_NOR:beginwreg_o WriteEnable;aluop_o EXE_NOR_OP;alusel_o EXE_RES_LOGIC;reg1_read_o 1b1;reg2_read_o 1b1;instvalid InstValid;endEXE_SLLV:beginwreg_o WriteEnable;aluop_o EXE_SLL_OP;alusel_o EXE_RES_SHIFT;reg1_read_o 1b1;reg2_read_o 1b1;instvalid InstValid;endEXE_SRLV:beginwreg_o WriteEnable;aluop_o EXE_SRL_OP;alusel_o EXE_RES_SHIFT;reg1_read_o 1b1;reg2_read_o 1b1;instvalid InstValid;endEXE_SRAV:beginwreg_o WriteEnable;aluop_o EXE_SRA_OP;alusel_o EXE_RES_SHIFT;reg1_read_o 1b1;reg2_read_o 1b1;instvalid InstValid;endEXE_SYNC:beginwreg_o WriteEnable;aluop_o EXE_NOP_OP;alusel_o EXE_RES_SHIFT;reg1_read_o 1b0;reg2_read_o 1b1;instvalid InstValid;enddefault:beginendendcaseenddefault:beginendendcaseendEXE_ORI: //判断op的值是进行opi指令begin wreg_o WriteEnable ; //ori 指令需要将结果写入目的寄存器所以wreg_o 为 WriteEnable aluop_o EXE_OR_OP ; //运算的子类型是逻辑“或”运算 alusel_o EXE_RES_LOGIC ; //运算类型是逻辑运算reg1_read_o 1b1 ; //需要通过Regfile的读端口1读取寄存器reg2_read_o 1b0 ; //不需要通过Regfile的读端口2读取寄存器imm {16h0,inst_i[15:0]} ; //指令执行需要的立即数 wd_o inst_i[20:16] ; //执行指令要写入的目的寄存器地址 instvalid InstValid ; //ori指令是有效的endEXE_ANDI:beginwreg_o WriteEnable ;aluop_o EXE_AND_OP ; alusel_o EXE_RES_LOGIC ;reg1_read_o 1b1 ;reg2_read_o 1b0 ;imm {16h0,inst_i[15:0]} ;wd_o inst_i[20:16] ;instvalid InstValid ; endEXE_XORI:beginwreg_o WriteEnable ;aluop_o EXE_XOR_OP ; alusel_o EXE_RES_LOGIC ;reg1_read_o 1b1 ;reg2_read_o 1b0 ;imm {16h0,inst_i[15:0]} ;wd_o inst_i[20:16] ;instvalid InstValid ; endEXE_LUI:beginwreg_o WriteEnable ;aluop_o EXE_OR_OP ; alusel_o EXE_RES_LOGIC ;reg1_read_o 1b1 ;reg2_read_o 1b0 ;imm {inst_i[15:0],16h0 } ;wd_o inst_i[20:16] ;instvalid InstValid ; endEXE_PREF:beginwreg_o WriteDisable ;aluop_o EXE_NOP_OP ; alusel_o EXE_RES_NOP ;reg1_read_o 1b0 ;reg2_read_o 1b0 ;instvalid InstValid ; enddefault: beginendendcaseif(inst_i[31:21] 11b0000_0000_000) begin if(op3 EXE_SLL)beginwreg_o WriteEnable ;aluop_o EXE_SLL_OP ;alusel_o EXE_RES_SHIFT ;reg1_read_o 1b0 ;reg2_read_o 1b1 ;imm[4:0] inst_i[10:6] ;wd_o inst_i[15:11] ;instvalid InstValid ;endelse if(op3 EXE_SRL)beginwreg_o WriteEnable ;aluop_o EXE_SRL_OP ;alusel_o EXE_RES_SHIFT ;reg1_read_o 1b0 ;reg2_read_o 1b1 ;imm[4:0] inst_i[10:6] ;wd_o inst_i[15:11] ;instvalid InstValid ;endelse if(op3 EXE_SRA) beginwreg_o WriteEnable ;aluop_o EXE_SRA_OP ;alusel_o EXE_RES_SHIFT ;reg1_read_o 1b0 ;reg2_read_o 1b1 ;imm[4:0] inst_i[10:6] ;wd_o inst_i[15:11] ;instvalid InstValid ;endendend end/********************************************************************************* *************************** 第二阶段确定进行运算的源操作数1*************************** *********************************************************************************/ //regfile读端口1的输出值 always (*) beginif(rst RstEnable)reg1_o ZeroWord;else // 对于源操作数若是目前端口的读取得寄存器数据地址是 执行阶段的要写入的目的寄存器 那么直接将执行的结果作为reg1_o的值。//这个数相当于是要写入的数据if((reg1_read_o 1b1) (ex_wreg_i 1b1) (ex_wd_i reg1_addr_o) )reg1_o ex_wdata_i; else//对于要是目的寄存器我们要读取的寄存器其实是最终访存要写入的寄存器那么访存的数据就直接作为源操作数进行处理if((reg1_read_o 1b1) (mem_wreg_i 1b1) (mem_wd_i reg1_addr_o) )reg1_o mem_wdata_i ;else if(reg1_read_o 1b1)reg1_o reg1_data_i;else if(reg1_read_o 1b0)reg1_o imm; //立即数else reg1_o ZeroWord; end/********************************************************************************* *************************** 第三阶段确定进行运算的源操作数2*************************** *********************************************************************************/ //regfile读端口2的输出值 always (*) beginif(rst RstEnable)reg2_o ZeroWord;else // 对于源操作数若是目前端口的读取得寄存器数据地址是 执行阶段的要写入的目的寄存器 那么直接将执行的结果作为reg2_o的值。//这个数相当于是要写入的数据if((reg2_read_o 1b1) (ex_wreg_i 1b1) (ex_wd_i reg2_addr_o) )reg2_o ex_wdata_i; else//对于要是目的寄存器我们要读取的寄存器其实是最终访存要写入的寄存器那么访存的数据就直接作为源操作数进行处理if((reg2_read_o 1b1) (mem_wreg_i 1b1) (mem_wd_i reg2_addr_o) )reg2_o mem_wdata_i ;else if(reg2_read_o 1b1)reg2_o reg2_data_i;else if(reg2_read_o 1b0)reg2_o imm; //立即数else reg2_o ZeroWord; end endmoduleEX模块的修改 执行阶段对于不同数以及不同的信息进行处理。新建寄存器用于保存移位寄存器的结果根据指令类型对象对相应的数据进行输出。 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 ); //保存逻辑运算的结果 reg [RegBus] logicout ;//保存位移运算结果 reg [RegBus] shiftres ;// 移动操作的结果 reg [RegBus] moveres ;/********************************************************************************* *************** 依据aluop_i指示的运算子类型进行运算 *********************************************************************************/always (*) beginif( rst RstEnable)logicout ZeroWord;else begincase(aluop_i)EXE_OR_OP:beginlogicout reg1_i | reg2_i;endEXE_AND_OP:beginlogicout reg1_i reg2_i;endEXE_NOR_OP: //逻辑或与非beginlogicout ~(reg1_i | reg2_i);endEXE_XOR_OP:beginlogicout reg1_i ^ reg2_i;enddefault:logicout ZeroWord;endcase;end 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]} } (6d32 - {1b0,reg1_i[4:0] } ) ) | reg2_i reg1_i[4:0];default:beginshiftres ZeroWord;end endcase 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中存放逻辑运算运算结果endEXE_RES_SHIFT:beginwdata_o shiftres; //wdata_o中存放位移运算运算结果endEXE_RES_MOVE:beginwdata_o moveres; //指令为EXE_RES_MOVEenddefault:wdata_o ZeroWord;endcase end endmodule仿真验证 测试逻辑操作 首先分析测试数据。OpenMIPS将指令转换为ori指令来执行。lui指令使用立即数扩展后的立即数做或运算。得到0x01010000 之后进行两次或运算将数据分别写入寄存器1与寄存器2中。 接下来是使用寄存器中的数据进行或运算将结果送入1寄存器。 然后使用立即数与寄存器中的数据进行与运算结果送入寄存器3在使用寄存器1与寄存器3中的数据相与结果送寄存器1然后使用寄寄存器1中的数据与立即数相异或之后分别使用寄存器中的数据进行两次运算即可。 I-型指令 lui lui: 把立即数加载到寄存器高位。ori 逐位逻辑操作指令 andi 逐位逻辑操作指令 xori 逐位逻辑操作指令 异或运算指令使用方法为xori rt, rs, immediate 指令作用为rt - rs XOR zero_extended(immediate)。将地址为rs的通用寄存器的值。与指令中马上数进行零扩展后的值进行逻辑“异或”运算运算结果保存到地址为rt的通用寄存器中。 xornor 逐位逻辑操作指令 R-型指令 or 逐位逻辑操作指令 and 逐位逻辑操作指令 得到的数据与书中预期一致。 测试移位操作与空指令 这里笔者不一一分析这里指出一个问题是在第六行的空指令加上会多一个时钟周期不加会少一个时钟周期。自己看仿真图即可理解。这里依据给出的源文件期间分析应该有五个时钟周期的延时。 简单分析在复位后第五个时钟上升沿寄存器2开始有数据然后更新之后的四个时钟周期对寄存器1,58进行操作因此加上其本身一个维持五个时钟周期。书中是维持了四个时钟周期是不对的。 不加时候的仿真截图 加上之后的 这里书中给出的是四个时钟周期的延时。这里上边已经进行了分析。 移位类指令 sll 当功能码是6’b000000表示是sll指令逻辑左移 指令使用方法为sll rd, rt, sa 指令作用为rd - rt sa (logic)将地址为rt的通用寄存器的值向左移sa位。空出来的位置使用0填充。结果保存到地址为rd的通用寄存器中。srl 当功能码是6’b000010表示是srl指令。逻辑右移 指令使用方法为srl rd, rt, sa 指令作用为rd - rt sa (logic)将地址为rt的通用寄存器的值向右移sa位空出来的位置使用0填充结果保存到地址为rd的通用寄存器中。sra 当功能码是6’b000011。表示是sra指令算术右移 指令使用方法为sra rd, rt, sa 指令作用为rd - rt sa (arithmetic)将地址为rt的通用寄存器的值向右移sa位。空出来的位置使用rt[31]的值填充结果保存到地址为rd的通用寄存器中。sllv 当功能码是6’b000100。表示是sllv指令逻辑左移 指令使用方法为sllv rd, rt, rs 指令作用为rd - rt rs[4:0](logic)。将地址为rt的通用寄存器的值。向左移位空出来的位置使用0填充结果保存到地址为rd的通用寄存器中。移位位数由地址为rs的寄存器值的0-4bit确定。srlv 当功能码是6’b000110表示是srlv指令。逻辑右移 指令使用方法为srlv rd, rt, rs 指令作用为rd - rt rs[4:0](logic)将地址为rt的通用寄存器的值向右移位空出来的位置使用0填充。结果保存到地址为rd的通用寄存器中。移位位数由地址为rs的寄存器值的0-4bit确定。 srav 当功能码是6’b000111表示是srav指令算术右移 指令使用方法为srav rd, rt, rs 指令作用为rd - rt rs[4:0](arithmetic)将地址为rt的通用寄存器的值向右移位。空出来的位置使用rt[31]填充结果保存到地址为rd的通用寄存器中。移位位数由地址为rs的寄存器值的0-4bit确定。 总结来说。这六条移位操作指令能够分为两种情况sllv、srav、srlv这3条指令的助记符最后有“v”。表示移位位数是通过寄存器的值确定的sll、sra、srl这3条指令的助记符最后没有“v”表示移位位数就是指令中6-10bit的sa的值。ssnop、nop 空操作 nop:相当于 sll zero,zero,o ssnop: equals sll zero,zero,1. 这个指令不得与其它指令同时发送这样就保证了其运行要花费至少一个时钟周期。这在简单的流水线的CPU上无关紧要但在复杂些的实现上对于实现强制的延时很有用。 另外MIPS32指令集架构中还定义了sync、pref这2条指令当中sync指令用于保证载入、存储操作的顺序对于OpenMIPS而言是严格依照指令顺序运行的载入、存储操作也是依照顺序进行的所以能够将sync指令当作nop指令处理在这里将其归纳为空指令。pref指令用于缓存预取OpenMIPS没有实现缓存所以也能够将pref指令当作nop指令处理此处也将其归纳为空指令。
http://www.dnsts.com.cn/news/23730.html

相关文章:

  • 搭建网站基本步骤无锡市城市建设规划局网站
  • 公司网站设计与实现wordpress登录页面自定义
  • 建单页网站seo排名优化软件价格
  • 网站建设尺寸像素是多少钱用哪个软件做网站好
  • 湛江市律师网站建设品牌戴尔的网站建设有哪些主要特色
  • 开发平台网站多少钱wordpress缩略图延时加载
  • 电子商务网站主要面向毕业设计做网站怎么答辩
  • 益阳网站制作公司地址常见的网络营销方法
  • 建设众筹类网站网站建设手机源码
  • 文明网站建设情况报告美工设计素材网站
  • 广东专业移动网站服务商青岛做视频的网站设计
  • 绍兴网站的优化动画设计图
  • 郑州做商城网站公司广东省建设安全卡查询网站
  • 做网站到内容填充需要多久免费开源网站系统有哪些
  • wordpress添加主题后怎么添加内容河北优化网站获客qq
  • 家教网站建设的推广有网站开发经验怎么写简历
  • 电商类网站开发合同书临沂画册设计公司
  • 全景图制作平台网站建设搜索引擎推广与优化
  • 淘宝客没网站怎么做做网站一定需要主机吗
  • 漯河做网站公司本地建wordpress
  • 上海市建设交通工会网站wordpress 行业模版
  • 衡水网站建设哪家专业电商网站设计制作
  • 商务网站制作语言基础德阳市建设局官方网站安全月
  • 广西网站开发软件网站收录怎么设置
  • 网站建设横向发展纵向发展seo超级外链
  • 海口网站制作策划关于微网站策划ppt怎么做
  • 做最好的在线看片网站企业信用中国官网
  • 网站网上推广网站开发师是做什么的
  • 钢板防护罩做网站the7做的网站
  • 网站内链的作用拒绝做网站的理由