常用的alu算术运算指令(包括ecall和 ebreak)在regular alu单元处理。regular alu单元为alu单元的一个子单元。regular单元的信息总线共21位,格式如下图所示,其中grp为000:

下面的代码产生regular alu单元的信息总线。

  // ALU Instructions
wire rv32_addi = rv32_op_imm & rv32_func3_000;
wire rv32_slti = rv32_op_imm & rv32_func3_010;
wire rv32_sltiu = rv32_op_imm & rv32_func3_011;
wire rv32_xori = rv32_op_imm & rv32_func3_100;
wire rv32_ori = rv32_op_imm & rv32_func3_110;
wire rv32_andi = rv32_op_imm & rv32_func3_111; wire rv32_slli = rv32_op_imm & rv32_func3_001 & (rv32_instr[31:26] == 6'b000000);
wire rv32_srli = rv32_op_imm & rv32_func3_101 & (rv32_instr[31:26] == 6'b000000);
wire rv32_srai = rv32_op_imm & rv32_func3_101 & (rv32_instr[31:26] == 6'b010000); //对一些移位指令,shamt[5] must be zero for RV32I,在RV64I中才可以不为0 wire rv32_sxxi_shamt_legl = (rv32_instr[25] == 1'b0);
wire rv32_sxxi_shamt_ilgl = (rv32_slli | rv32_srli | rv32_srai) & (~rv32_sxxi_shamt_legl); wire rv32_add = rv32_op & rv32_func3_000 & rv32_func7_0000000;
wire rv32_sub = rv32_op & rv32_func3_000 & rv32_func7_0100000;
wire rv32_sll = rv32_op & rv32_func3_001 & rv32_func7_0000000;
wire rv32_slt = rv32_op & rv32_func3_010 & rv32_func7_0000000;
wire rv32_sltu = rv32_op & rv32_func3_011 & rv32_func7_0000000;
wire rv32_xor = rv32_op & rv32_func3_100 & rv32_func7_0000000;
wire rv32_srl = rv32_op & rv32_func3_101 & rv32_func7_0000000;
wire rv32_sra = rv32_op & rv32_func3_101 & rv32_func7_0100000;
wire rv32_or = rv32_op & rv32_func3_110 & rv32_func7_0000000;
wire rv32_and = rv32_op & rv32_func3_111 & rv32_func7_0000000; //对rv32 nop指令,31-20位为0 wire rv32_nop = rv32_addi & rv32_rs1_x0 & rv32_rd_x0 & (~(|rv32_instr[31:20]));
// The ALU group of instructions will be handled by 1cycle ALU-datapath
wire ecall_ebreak = rv32_ecall | rv32_ebreak | rv16_ebreak;
//当前指令是alu_op指令
wire alu_op = (~rv32_sxxi_shamt_ilgl) & (~rv16_sxxi_shamt_ilgl)
& (~rv16_li_lui_ilgl) & (~rv16_addi4spn_ilgl) & (~rv16_addi16sp_ilgl) &
( rv32_op_imm
| rv32_op & (~rv32_func7_0000001) // Exclude the MULDIV
| rv32_auipc
| rv32_lui
| rv16_addi4spn
| rv16_addi
| rv16_lui_addi16sp
| rv16_li | rv16_mv
| rv16_slli
| rv16_miscalu
| rv16_add
| rv16_nop | rv32_nop
| rv32_wfi // We just put WFI into ALU and do nothing in ALU
| ecall_ebreak)
;
wire need_imm;
wire [`E203_DECINFO_ALU_WIDTH-1:0] alu_info_bus;
assign alu_info_bus[`E203_DECINFO_GRP ] = `E203_DECINFO_GRP_ALU;
assign alu_info_bus[`E203_DECINFO_RV32 ] = rv32;
assign alu_info_bus[`E203_DECINFO_ALU_ADD] = rv32_add | rv32_addi | rv32_auipc |
rv16_addi4spn | rv16_addi | rv16_addi16sp | rv16_add |
// We also decode LI and MV as the add instruction, becuase
// they all add x0 with a RS2 or Immeidate, and then write into RD
rv16_li | rv16_mv;
assign alu_info_bus[`E203_DECINFO_ALU_SUB] = rv32_sub | rv16_sub;
assign alu_info_bus[`E203_DECINFO_ALU_SLT] = rv32_slt | rv32_slti;
assign alu_info_bus[`E203_DECINFO_ALU_SLTU] = rv32_sltu | rv32_sltiu;
assign alu_info_bus[`E203_DECINFO_ALU_XOR] = rv32_xor | rv32_xori | rv16_xor;
assign alu_info_bus[`E203_DECINFO_ALU_SLL] = rv32_sll | rv32_slli | rv16_slli;
assign alu_info_bus[`E203_DECINFO_ALU_SRL] = rv32_srl | rv32_srli | rv16_srli;
assign alu_info_bus[`E203_DECINFO_ALU_SRA] = rv32_sra | rv32_srai | rv16_srai;
assign alu_info_bus[`E203_DECINFO_ALU_OR ] = rv32_or | rv32_ori | rv16_or;
assign alu_info_bus[`E203_DECINFO_ALU_AND] = rv32_and | rv32_andi | rv16_andi | rv16_and;
assign alu_info_bus[`E203_DECINFO_ALU_LUI] = rv32_lui | rv16_lui;
assign alu_info_bus[`E203_DECINFO_ALU_OP2IMM] = need_imm;
assign alu_info_bus[`E203_DECINFO_ALU_OP1PC ] = rv32_auipc;
assign alu_info_bus[`E203_DECINFO_ALU_NOP ] = rv16_nop | rv32_nop;
assign alu_info_bus[`E203_DECINFO_ALU_ECAL ] = rv32_ecall;
assign alu_info_bus[`E203_DECINFO_ALU_EBRK ] = rv32_ebreak | rv16_ebreak;
assign alu_info_bus[`E203_DECINFO_ALU_WFI ] = rv32_wfi;

alu中包含一个csr读写控制子单元,所有csr指令都在这个子单元中执行。下面csr读写控制单元的信息总线,其中grp为011

   wire csr_op = rv32_csr;
wire [`E203_DECINFO_CSR_WIDTH-1:0] csr_info_bus;
assign csr_info_bus[`E203_DECINFO_GRP ] = `E203_DECINFO_GRP_CSR;
assign csr_info_bus[`E203_DECINFO_RV32 ] = rv32;
assign csr_info_bus[`E203_DECINFO_CSR_CSRRW ] = rv32_csrrw | rv32_csrrwi;
assign csr_info_bus[`E203_DECINFO_CSR_CSRRS ] = rv32_csrrs | rv32_csrrsi;
assign csr_info_bus[`E203_DECINFO_CSR_CSRRC ] = rv32_csrrc | rv32_csrrci;
assign csr_info_bus[`E203_DECINFO_CSR_RS1IMM] = rv32_csrrwi | rv32_csrrsi | rv32_csrrci;
assign csr_info_bus[`E203_DECINFO_CSR_ZIMMM ] = rv32_rs1;
assign csr_info_bus[`E203_DECINFO_CSR_RS1IS0] = rv32_rs1_x0;
assign csr_info_bus[`E203_DECINFO_CSR_CSRIDX] = rv32_instr[31:20];

alu中乘法除法子单元进行乘法,除法运算,该单元的信息总线格式为:

  // MUL/DIV Instructions
wire rv32_mul = rv32_op & rv32_func3_000 & rv32_func7_0000001;
wire rv32_mulh = rv32_op & rv32_func3_001 & rv32_func7_0000001;
wire rv32_mulhsu = rv32_op & rv32_func3_010 & rv32_func7_0000001;
wire rv32_mulhu = rv32_op & rv32_func3_011 & rv32_func7_0000001;
wire rv32_div = rv32_op & rv32_func3_100 & rv32_func7_0000001;
wire rv32_divu = rv32_op & rv32_func3_101 & rv32_func7_0000001;
wire rv32_rem = rv32_op & rv32_func3_110 & rv32_func7_0000001;
wire rv32_remu = rv32_op & rv32_func3_111 & rv32_func7_0000001; // The MULDIV group of instructions will be handled by MUL-DIV-datapath
`ifdef E203_SUPPORT_MULDIV//{
wire muldiv_op = rv32_op & rv32_func7_0000001;
`endif//}
`ifndef E203_SUPPORT_MULDIV//{
wire muldiv_op = 1'b0;
`endif//} wire [`E203_DECINFO_MULDIV_WIDTH-1:0] muldiv_info_bus;
assign muldiv_info_bus[`E203_DECINFO_GRP ] = `E203_DECINFO_GRP_MULDIV;
assign muldiv_info_bus[`E203_DECINFO_RV32 ] = rv32 ;
assign muldiv_info_bus[`E203_DECINFO_MULDIV_MUL ] = rv32_mul ;
assign muldiv_info_bus[`E203_DECINFO_MULDIV_MULH ] = rv32_mulh ;
assign muldiv_info_bus[`E203_DECINFO_MULDIV_MULHSU] = rv32_mulhsu ;
assign muldiv_info_bus[`E203_DECINFO_MULDIV_MULHU ] = rv32_mulhu ;
assign muldiv_info_bus[`E203_DECINFO_MULDIV_DIV ] = rv32_div ;
assign muldiv_info_bus[`E203_DECINFO_MULDIV_DIVU ] = rv32_divu ;
assign muldiv_info_bus[`E203_DECINFO_MULDIV_REM ] = rv32_rem ;
assign muldiv_info_bus[`E203_DECINFO_MULDIV_REMU ] = rv32_remu ;
assign muldiv_info_bus[`E203_DECINFO_MULDIV_B2B ] = i_muldiv_b2b; assign dec_mulhsu = rv32_mulh | rv32_mulhsu | rv32_mulhu;
assign dec_mul = rv32_mul;
assign dec_div = rv32_div ;
assign dec_divu = rv32_divu;
assign dec_rem = rv32_rem;
assign dec_remu = rv32_remu;

alu中的AGU子单元,主要负责Load,store指令和A扩展指令的地址生成,以及A扩展指令的微操作拆分和执行。

传输到AGU模块的信息总线格式为:

 

   // ===========================================================================
// Load/Store Instructions
wire rv32_lb = rv32_load & rv32_func3_000;
wire rv32_lh = rv32_load & rv32_func3_001;
wire rv32_lw = rv32_load & rv32_func3_010;
wire rv32_lbu = rv32_load & rv32_func3_100;
wire rv32_lhu = rv32_load & rv32_func3_101; wire rv32_sb = rv32_store & rv32_func3_000;
wire rv32_sh = rv32_store & rv32_func3_001;
wire rv32_sw = rv32_store & rv32_func3_010; // ===========================================================================
// Atomic Instructions
`ifdef E203_SUPPORT_AMO//{
wire rv32_lr_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00010);
wire rv32_sc_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00011);
wire rv32_amoswap_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00001);
wire rv32_amoadd_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00000);
wire rv32_amoxor_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00100);
wire rv32_amoand_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b01100);
wire rv32_amoor_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b01000);
wire rv32_amomin_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b10000);
wire rv32_amomax_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b10100);
wire rv32_amominu_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b11000);
wire rv32_amomaxu_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b11100); `endif//E203_SUPPORT_AMO}
`ifndef E203_SUPPORT_AMO//{
wire rv32_lr_w = 1'b0;
wire rv32_sc_w = 1'b0;
wire rv32_amoswap_w = 1'b0;
wire rv32_amoadd_w = 1'b0;
wire rv32_amoxor_w = 1'b0;
wire rv32_amoand_w = 1'b0;
wire rv32_amoor_w = 1'b0;
wire rv32_amomin_w = 1'b0;
wire rv32_amomax_w = 1'b0;
wire rv32_amominu_w = 1'b0;
wire rv32_amomaxu_w = 1'b0; `endif//} wire amoldst_op = rv32_amo | rv32_load | rv32_store | rv16_lw | rv16_sw | (rv16_lwsp & (~rv16_lwsp_ilgl)) | rv16_swsp;
// The RV16 always is word
wire [1:0] lsu_info_size = rv32 ? rv32_func3[1:0] : 2'b10;
// The RV16 always is signed
wire lsu_info_usign = rv32? rv32_func3[2] : 1'b0; wire [`E203_DECINFO_AGU_WIDTH-1:0] agu_info_bus;
assign agu_info_bus[`E203_DECINFO_GRP ] = `E203_DECINFO_GRP_AGU;
assign agu_info_bus[`E203_DECINFO_RV32 ] = rv32;
assign agu_info_bus[`E203_DECINFO_AGU_LOAD ] = rv32_load | rv32_lr_w | rv16_lw | rv16_lwsp;
assign agu_info_bus[`E203_DECINFO_AGU_STORE ] = rv32_store | rv32_sc_w | rv16_sw | rv16_swsp;
assign agu_info_bus[`E203_DECINFO_AGU_SIZE ] = lsu_info_size;
assign agu_info_bus[`E203_DECINFO_AGU_USIGN ] = lsu_info_usign;
assign agu_info_bus[`E203_DECINFO_AGU_EXCL ] = rv32_lr_w | rv32_sc_w;
assign agu_info_bus[`E203_DECINFO_AGU_AMO ] = rv32_amo & (~(rv32_lr_w | rv32_sc_w));// We seperated the EXCL out of AMO in LSU handling
assign agu_info_bus[`E203_DECINFO_AGU_AMOSWAP] = rv32_amoswap_w;
assign agu_info_bus[`E203_DECINFO_AGU_AMOADD ] = rv32_amoadd_w ;
assign agu_info_bus[`E203_DECINFO_AGU_AMOAND ] = rv32_amoand_w ;
assign agu_info_bus[`E203_DECINFO_AGU_AMOOR ] = rv32_amoor_w ;
assign agu_info_bus[`E203_DECINFO_AGU_AMOXOR ] = rv32_amoxor_w ;
assign agu_info_bus[`E203_DECINFO_AGU_AMOMAX ] = rv32_amomax_w ;
assign agu_info_bus[`E203_DECINFO_AGU_AMOMIN ] = rv32_amomin_w ;
assign agu_info_bus[`E203_DECINFO_AGU_AMOMAXU] = rv32_amomaxu_w;
assign agu_info_bus[`E203_DECINFO_AGU_AMOMINU] = rv32_amominu_w;
assign agu_info_bus[`E203_DECINFO_AGU_OP2IMM ] = need_imm;

指令全为0和全为1是非法的指令,下面的代码判定指令是否为全0和全1。

   // Reuse the common signals as much as possible to save gatecounts
wire rv32_all0s_ilgl = rv32_func7_0000000
& rv32_rs2_x0
& rv32_rs1_x0
& rv32_func3_000
& rv32_rd_x0
& opcode_6_5_00
& opcode_4_2_000
& (opcode[1:0] == 2'b00); wire rv32_all1s_ilgl = rv32_func7_1111111
& rv32_rs2_x31
& rv32_rs1_x31
& rv32_func3_111
& rv32_rd_x31
& opcode_6_5_11
& opcode_4_2_111
& (opcode[1:0] == 2'b11); wire rv16_all0s_ilgl = rv16_func3_000 //rv16_func3 = rv32_instr[15:13];
& rv32_func3_000 //rv32_func3 = rv32_instr[14:12];
& rv32_rd_x0 //rv32_rd = rv32_instr[11:7];
& opcode_6_5_00
& opcode_4_2_000
& (opcode[1:0] == 2'b00); wire rv16_all1s_ilgl = rv16_func3_111
& rv32_func3_111
& rv32_rd_x31
& opcode_6_5_11
& opcode_4_2_111
& (opcode[1:0] == 2'b11); wire rv_all0s1s_ilgl = rv32 ? (rv32_all0s_ilgl | rv32_all1s_ilgl)
: (rv16_all0s_ilgl | rv16_all1s_ilgl);

以下的代码判断指令是否需要寄存器操作数1,寄存器操作数2,是否需要写目的寄存器。

   // All the RV32IMA need RD register except the
// * Branch, Store,
// * fence, fence_i
// * ecall, ebreak
wire rv32_need_rd =
(~rv32_rd_x0) & (
(
(~rv32_branch) & (~rv32_store)
& (~rv32_fence_fencei)
& (~rv32_ecall_ebreak_ret_wfi)
)
); // All the RV32IMA need RS1 register except the
// * lui
// * auipc
// * jal
// * fence, fence_i
// * ecall, ebreak
// * csrrwi
// * csrrsi
// * csrrci
wire rv32_need_rs1 =
(~rv32_rs1_x0) & (
(
(~rv32_lui)
& (~rv32_auipc)
& (~rv32_jal)
& (~rv32_fence_fencei)
& (~rv32_ecall_ebreak_ret_wfi)
& (~rv32_csrrwi)
& (~rv32_csrrsi)
& (~rv32_csrrci)
)
); // Following RV32IMA instructions need RS2 register
// * branch
// * store
// * rv32_op
// * rv32_amo except the rv32_lr_w
wire rv32_need_rs2 = (~rv32_rs2_x0) & (
(
(rv32_branch)
| (rv32_store)
| (rv32_op)
| (rv32_amo & (~rv32_lr_w))
)
);

E203 译码模块(2)的更多相关文章

  1. E203 译码模块(1)

    E203是两级流水线结构,第一级是IFU进行取指操作,第二级包括译码.执行.交付和写回等功能.架构图如下: https://www.cnblogs.com/images/cnblogs_com/mik ...

  2. E203译码模块(3)

    下面的代码译码出指令的立即数,不同的指令有不同的立即数编码形式. //I类型指令的imm,[31:20],符号位扩展成32位. wire [31:0] rv32_i_imm = { {20{rv32_ ...

  3. 蜂鸟E203 IFU模块

    E203的IFU(instruction fetch unit)模块主要功能和接口如下: IFU的PC生成单元产生下一条指令的PC. 该PC传输到地址判断和ICB生成单元,就是根据PC值产生相应读指请 ...

  4. what is the purpose of channel coding?(信道编码的作用?)

    信道.信道编码及其作用 1.信道(channel) 信道和通信电路并不等同,用来表示向某一个方向传送信息的媒体.因此一条通信线路往往包含一条发送信道和一条接收信道. 从通信的双方信息交互方式看有三个基 ...

  5. 串行CPU设计

    一.概述 串行CPU工作流程 串行CPU的时序流程如下图所示:取指.译码.执行.回写. 其中,取指.回写是与存储器打交道:而译码与执行则是CPU内部自个儿的操作. 我们究竟想要CPU干什么?     ...

  6. FPGA实现“打字机”(VGA & UART)

    看到标题中的"打字机"三个字,你是不是脑补了下面这幅图像.这是二战电影中常出现的道具,现在恐怕都见不到了. ●电影道具"打字机" 我要实现的当然不是这个样子,只 ...

  7. FPGA学习笔记(五)—— 组合逻辑电路功能的描述

    设计方法:    分析真值表规律        两种描述方式: 方式1:用assign描述,用阻塞赋值= 方式2:用always@(*)描述,用非阻塞赋值<=      选择功能的三种描述方式: ...

  8. 从Learning to Segment Every Thing说起

    原文地址:https://arxiv.org/pdf/1711.10370.pdf 这是何恺明老师发表于CVPR2018的一篇优秀paper. 先简单回顾一下语义分割领域之前的工作 那么什么是语义分割 ...

  9. Verilog HDL语言实现的单周期CPU设计(全部代码及其注释)

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

随机推荐

  1. 用linux编译并运行c文件

    目录 创建一个.c文件 写完代码以后进行编译 @(用linux编译并运行c文件) 创建一个.c文件 vi 文件名.c 对于图形化的linux,需要右键桌面,在终端中打开,输入vi 文件名.c就创建了一 ...

  2. c++ 多态的内幕

    c++ 多态,就是利用了一个二级指针(指针数组),数组里的每个元素都指向了,用virtual修饰的成员函数. 既然提到了指针,那就让我们用内存地址来证明一下吧. 为了证明,我们必须要取到成员函数的首地 ...

  3. [Go] gocron源码阅读-空接口类型interface{}

    gocron源代码中的Action那个地方,就是个空接口类型Action interface{},可以传递任意类型进去,这里是传了个函数进去 command := cli.Command{ Name: ...

  4. prometheus operator的深度好文

    转: https://www.servicemesher.com/blog/prometheus-operator-manual/

  5. C++学习三 模板类出错总结(Missing template arguments before 'L')

    一.模板类的说明 模板类有一个好处是可以放宽你输入的数据类型. 比如有这样的一个函数: int add(int x, int y) { return x+y; } 这个函数对于int类型的x,y才适合 ...

  6. 利用Git生成本机SSH Key并添加到GitHub中

    本地仓库和github之间是通过SSH加密传输的,所以需要先到github中添加你本机的SSH Key 进行认证. 1.在桌面打开git命令窗口 2.输入“ssh-keygen -t rsa -C   ...

  7. 第十三周博客作业 <西北师范大学| 周安伟>

    第十三周助教作业 助教博客链接https://home.cnblogs.com/u/zaw-315/ 本周点评作业数量无 本周点评困难的博客作业无 本周工作情况制作实验七 团队作业3的千帆图和成绩排名 ...

  8. C++ trais技术 模板特化的应用

    // traits 的应用 /////////////////////////////////////////// // traits template <typename T> clas ...

  9. skkyk:题解 洛谷P2420 【让我们异或吧】lca+xor前缀和

    刚学了LCA,写篇题解巩固一下 首先题目有误: (A是否是男生 )xor( B是否是男生)=A和B是否能够成为情侣,这句话显然是错误的qwq 对于这道题,容易看出,对于待处理的两个点,只要我们找到他的 ...

  10. 28道java基础面试题-下

    28道java基础面试题下 15.Java语言如何进行异常处理,关键字:throws.throw.try.catch.finally分别如何使用? 答:Java通过面向对象的方法进行异常处理,把各种不 ...