自己参考代码分析

验证I型运算指令

源代码

package alu_defs;enum logic [3:0] {ADD = 4'b0001,SUB = 4'b0010,AND = 4'b0011,OR  = 4'b0100,XOR = 4'b0101,SRA = 4'b0110,SLL = 4'b0111,SRL = 4'b1000} aluop;endpackage`default_nettype none
// --------------------------------------------------------------------
// CPU 模块
// --------------------------------------------------------------------
module CPU#(parameter DATAWIDTH = 32,parameter ADDRWIDTH = 32)
(input  wire iCPU_Reset,input  wire iCPU_Clk,// 指令存储器接口output wire [ADDRWIDTH-1:0] oIM_Addr,   //指令存储器地址input  wire [DATAWIDTH-1:0] iIM_Data,   //指令存储器数据// 数据存储器接口input  wire [DATAWIDTH-1:0] iReadData,  //数据存储器读数据output wire [DATAWIDTH-1:0] oWriteData, //数据存储器写数据output wire [ADDRWIDTH-1:0] oAB,        //数据存储器地址output wire oWR,                        //数据存储器写使能// 连接调试器的信号output wire [ADDRWIDTH-1:0] oCurrent_PC,output wire oFetch,input  wire iScanClk,input  wire iScanIn,output wire oScanOut,input  wire [1:0] iScanCtrl
);/** The input port is replaced with an internal signal **/wire   clk   = iCPU_Clk;wire   reset = iCPU_Reset;// Instruction partslogic [31:0] pc, nextPC;logic [31:0] instruction; // instruction codeassign nextPC = pc + 4;   /*-TODO 目前仅支持PC+4,增加分支指令时需修改 -*/// PCDataReg #(32) pcreg(.iD(nextPC), .oQ(pc), .Clk(clk), .Reset(reset), .Load(1'b1));assign oIM_Addr = pc;         // 连接指令存储器的地址端口assign instruction = iIM_Data;// 连接指令存储器的数据端口// Instruction decodelogic [6:0] opcode;logic [2:0] funct3;logic [6:0] funct7;logic [4:0] ra1,ra2,wa;assign funct7 = instruction[31:25];assign ra2    = instruction[24:20];assign ra1    = instruction[19:15];assign funct3 = instruction[14:12];assign wa     = instruction[11:7];assign opcode = instruction[6:0];// Control unitlogic cRegWrite;logic [3:0] aluOp;logic [4:0] cImm_type;  //{J,U,B,S,I}Controller controller(.iOpcode(opcode),.iFunct3(funct3),.iFunct7(funct7),/*-TODO 随着指令的增加,相应添加端口信号 -*/.oRegWrite(cRegWrite),.oImm_type(cImm_type),.oALUop(aluOp));// Immediate data generationlogic [31:0] immData;ImmGen  immGen(.iInstruction(instruction[31:7]),.iImm_type(cImm_type),.oImmediate(immData));// Register filelogic [31:0] regWriteData, regReadData1, regReadData2;RegisterFile #(32) regFile(.Clk(clk),.iWE(cRegWrite), .iWA(wa), .iWD(regWriteData),.iRA1(ra1), .oRD1(regReadData1),.iRA2(ra2), .oRD2(regReadData2));assign regWriteData = aluOut; /*-目前仅支持将ALU运算结果写入寄存器堆,TODO:增加Load类指令时需修改 -*/// ALUlogic [31:0] aluOut;ALU alu(.iX(regReadData1),.iY(immData),.iALUop(aluOp),.oF(aluOut),.moveBit(ra2));/*-TODO 连接数据存储器 -*///---------------------- 送给调试器的变量 ------------------------////送给调试器的观察信号,需要与虚拟面板的信号框相对应struct packed{/*-TODO 在这里添加观察信号的类型 -*/logic [3:0] ALUop;            //对应虚拟元件WS2logic RegWrite;               //对应虚拟元件WS1logic [4:0] ImmType;          //对应虚拟元件WS0}ws;always_comb begin/*-【注意】添加观察信号类型后须关联相应变量!-*/ws.ALUop = aluOp;             //对应虚拟元件WS2ws.RegWrite = cRegWrite;      //对应虚拟元件WS1ws.ImmType = cImm_type;       //对应虚拟元件WS0end//送给调试器的观察变量,需要与虚拟面板的数据框相对应struct packed{/*-TODO 在这里添加观察数据的类型 -*/logic [3:0] ALUop;logic [31:0] aluOut;       //对应虚拟元件WD8logic [31:0] immData;      //对应虚拟元件WD7logic [31:0] regReadData1; //对应虚拟元件WD6logic [4:0]  ra2;          //对应虚拟元件WD5,5位logic [4:0]  ra1;          //对应虚拟元件WD4,5位logic [4:0]  wa;           //对应虚拟元件WD3,5位logic [31:0] instruction;  //对应虚拟元件WD2logic [31:0] pc;           //对应虚拟元件WD1logic [31:0] nextPC;       //对应虚拟元件WD0}wd;always_comb begin/*-【注意】添加观察数据类型后须关联相应变量!-*/wd.ALUop        = aluOp;wd.aluOut       = aluOut;       //对应虚拟元件WD8wd.immData      = immData;      //对应虚拟元件WD7wd.regReadData1 = regReadData1; //对应虚拟元件WD6wd.ra2          = ra2;          //对应虚拟元件WD5,5位wd.ra1          = ra1;          //对应虚拟元件WD4,5位wd.wa           = wa;           //对应虚拟元件WD3,5位wd.instruction  = instruction;  //对应虚拟元件WD2wd.pc           = pc;           //对应虚拟元件WD1wd.nextPC       = nextPC;       //对应虚拟元件WD0end// 调试器部分,请勿修改!WatchChain #(.DATAWIDTH($bits(ws)+$bits(wd))) WatchChain_inst(.DataIn({ws,wd}),.ScanIn(iScanIn),.ScanOut(oScanOut),.ShiftDR(iScanCtrl[1]),.CaptureDR(iScanCtrl[0]),.TCK(iScanClk));assign oCurrent_PC = pc;assign oFetch = 1'b1;endmodule// --------------------------------------------------------------------
// Controller模块
// --------------------------------------------------------------------module Controller(input  logic [6:0] iOpcode,input  logic [2:0] iFunct3,input  logic [6:0] iFunct7,/*- TODO:扩充指令时在这里增加端口 -*/output logic [3:0] oALUop,output logic oRegWrite,output logic [4:0] oImm_type   //对应五种类型:{J,U,B,S,I}
);always @ * begin/*- TODO:扩充指令时需修改 ...... -*///I型指令if (iOpcode==7'b0010011) beginoImm_type = 5'b00001;oRegWrite = 1'b1;if(iFunct3 == 3'b000) oALUop = 4'b0001;else if(iFunct3 == 3'b001) oALUop = 4'b0111;else if(iFunct3 == 3'b100) oALUop = 4'b0101;else if(iFunct3 == 3'b101 && iFunct7[5] == 1'b0) oALUop = 4'b1000;else if(iFunct3 == 3'b101 && iFunct7[5] == 1'b1) oALUop = 4'b0110;else if(iFunct3 == 3'b110) oALUop = 4'b0100;else if(iFunct3 == 3'b111) oALUop = 4'b0011;endelse beginoALUop = 5'b00000;oImm_type = 5'b00000;oRegWrite = 1'b0;end
end
endmodule// --------------------------------------------------------------------
// 立即数生成模块
// --------------------------------------------------------------------
module ImmGen( //立即数生成input  logic [4:0]  iImm_type,   //{J,U,B,S,I}input  logic [31:7] iInstruction,output logic [31:0] oImmediate
);
/*- TODO:增加其他类型的立即数需修改。目前只有I型,所以并未区分Imm_type -*/
always_comb beginif(iImm_type == 5'b00001)oImmediate = {{20{iInstruction[31]}}, iInstruction[31:20]};else if(iImm_type == 5'b00000)oImmediate = {32{1'b0}};elseoImmediate = {32{1'bx}};
end
endmodule// --------------------------------------------------------------------
// ALU模块
// --------------------------------------------------------------------
module ALU
#(parameter N=32)
(input logic [N-1:0] iX, iY,input logic [3:0] iALUop,input logic [4:0] moveBit,output logic [N-1:0] oF
);
wire [N-1:0] X = iX;
wire [N-1:0] Y = iY;
always_comb begincase (iALUop)4'b0001: oF = X + Y;4'b0010: oF = X - Y;4'b0011: oF = X & Y;4'b0100: oF = X | Y;4'b0101: oF = X ^ Y;4'b0110: oF = $signed(X) >>> moveBit;4'b0111: oF = X << moveBit;4'b1000: oF = X >> moveBit;default: oF = {4{1'bx}};endcase
end
endmodule// --------------------------------------------------------------------
// 三端口寄存器堆模块
// --------------------------------------------------------------------
module RegisterFile#(parameter DATAWIDTH = 32,parameter ADDRWIDTH = 5)
(input  logic  Clk,input  logic  iWE,input  logic  [4:0] iWA, iRA1, iRA2,input  logic  [31:0] iWD,output logic  [31:0] oRD1, oRD2
);
/*- TODO:...  -*/
localparam MEMDEPTH = 1<<ADDRWIDTH;
logic [DATAWIDTH-1:0] mem[0:MEMDEPTH-1];always_ff @(posedge Clk)
beginif(iWE)if(iWA!={ADDRWIDTH{1'b0}})mem[iWA] <= iWD;
endassign oRD1 = mem[iRA1];
assign oRD2 = mem[iRA2];
endmodule// --------------------------------------------------------------------
// DataReg模块
// --------------------------------------------------------------------
module DataReg
#(parameter N = 4)
(   output reg [N-1:0] oQ,input wire [N-1:0] iD,input wire Clk,input wire Load,input wire Reset
);
always @(posedge Clk or posedge Reset)
beginif (Reset)oQ <= 0;else if (Load)oQ <= iD;
end
endmodule

RISC-V 实现整数运算指令(Part 1)相关推荐

  1. 计组学习笔记2(RISC v版)

    指令集解释 (规定:R[r]表示通用寄存器r的内容,M[addr]表示存储单元addr的内容,SEXT[imm]表示对imm进行符号扩展,ZEXT[imm]表示对imm进行零扩展) 整数运算类 -U型 ...

  2. RISC V (RV32+RV64) 架构 整体介绍

    文章目录 riscv 市场 芯片介绍 软件介绍 开发板介绍 PC介绍 riscv 架构 编程模型(指令集/寄存器/ABI/SBI) 运行状态 指令集 寄存器 riscv32和riscv64两者的区别 ...

  3. RISC-V 实现整数运算指令(Part 2)

    验证R型运算指令 源代码 package alu_defs;enum logic [3:0] {ADD = 4'b0001,SUB = 4'b0010,AND = 4'b0011,OR = 4'b01 ...

  4. 安装Ubuntu RISC V toolchain失败(网速、git配置原因)

    git获取大容量工程出错:RPC failed: curl GnuTLS recv error : Decryption has failed. error: RPC failed; curl 56 ...

  5. 【《RISC-V “V“ Vector Extension Version 1.0》阅读笔记】

    <RISC-V "V" Vector Extension Version 1.0>阅读笔记 RISC-V "V" Vector Extension ...

  6. Wannafly挑战赛22 D 整数序列 (线段树维护三角函数值)

    链接:https://ac.nowcoder.com/acm/contest/160/D 来源:牛客网 整数序列 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语 ...

  7. 整数序列(牛客,线段树)

    链接:https://ac.nowcoder.com/acm/contest/160/D 来源:牛客网 题目描述 给出一个长度为n的整数序列a1,a2,-,an,进行m次操作,操作分为两类. 操作1: ...

  8. 浮点数到整数的快速转换

    之前在看 lua 源码的时候,看到一处浮点数转整数的方法,当时确实吓我一跳,后来在网上搜索了才知道浮点数原来还有这么神奇的地方,我看到一篇喜欢的文章,翻译一下(英文一般还请见谅),大家要闲着没事可以看 ...

  9. 4-3指令系统-CISC和RISC

    文章目录 一.复杂指令系统计算机CISC 二.精简指令系统计算机RISC 三.CISC和RISC比较 一.复杂指令系统计算机CISC 为增强原有指令的功能,设置更为复杂的新指令实现软件功能的硬化,这类 ...

最新文章

  1. poj3164(最小树形图模版)
  2. Error:java: Compilation failed: internal java compiler
  3. Android ndk 使用第三方so和头文件编译
  4. Angular实现灵活的动态创建组件指令
  5. linux写永久路由命令,用route命令添加永久路由(示例代码)
  6. 使用虚幻引擎4年,我想再谈谈他的网络架构
  7. springmvc或者springboot 中实现跨域的5种方式
  8. harview .har文件解析
  9. matlab 状态空间极点,传递函数、零极点增益与状态空间转换的matlab算法实现
  10. TTL电路和CMOS电路的区别和…
  11. 12月21诛仙服务器维护,12月31日全服停机更新维护公告
  12. 您可能是盗版软件的受害者——解决办法
  13. 如何在word中打印对勾和叉
  14. 【Selenium】控制当前已经打开的 chrome浏览器窗口
  15. 利用Redis实现防止接口重复提交功能
  16. Oracle数据库之同义词(SYNONYM)使用
  17. 更改Linux系统的主机名(hostname)两种实用的方法
  18. 地铁杂记 - 17寸苹果
  19. 我对计算机最感兴趣作文300,电脑让我欢喜让我忧作文300字
  20. 程序员鄙视链最全图解,好有道理

热门文章

  1. python用小海龟画糖葫芦
  2. 读书笔记软件调试之道 :从大局看调试-零容忍策略
  3. ibm电脑服务器郑州维修,郑州IBM ThinkPad笔记本芯片级维修中心
  4. JavaScript实现H5游戏断线自动重连的技术
  5. 成长部落# 编辑推荐 Python 入门学习内容系列
  6. Qt实现屏幕虚拟软键盘
  7. linux中无线管理员密码,无线网管理员密码
  8. csdn博客 代码块的显示设置以及图片的插入技巧
  9. mpv官方文档部分快捷键
  10. 转换word等文件为swf文件