E203是两级流水线结构,第一级是IFU进行取指操作,第二级包括译码、执行、交付和写回等功能。架构图如下:

       https://www.cnblogs.com/images/likecs_com/mikewolf2002/1519640/o_pipeline.jpg

     译码模块就是把机器码翻译成对应的输出功能。E203支持RV32IMAC,它的译码器模块是纯的组合电路实现,相对比较简单。只要熟悉了RiscV的指令规范,很容易看懂。


     译码模块的输入信号来自于IFU模块,包括以下信号:

input  [`E203_INSTR_SIZE-1:0] i_instr, //来自IFU的32位指令
input  [`E203_PC_SIZE-1:0] i_pc,       //来自IFU的当前指令PC
input  i_prdt_taken,           //预测需要跳转,来自IFU模块的分支预测单元,对分支跳转指令有用,如果当前指令为分支跳转指令,该信号会被传递到相应的info_bus
 input  i_misalgn,              // 表示当前指令遇到了分支跳转异常
 input  i_buserr,               // 表面当前指令遭遇了取指存储器访问错误
 input  i_muldiv_b2b,           // 前后临接的mul和div指令时置1,如果当前指令为乘法除法指令,该信号传递到相应的info_bus

input  dbg_mode,   //debug模式下,忽视dret指令异常的情况

      译码模块的输出包括以下信号:

output dec_rs1x0, // 该指令源操作数1为x0
 output dec_rs2x0, // 该指令源操作数2为x0
 output dec_rs1en, //该指令需要读取源操作数1
 output dec_rs2en, //该指令需要读取源操作数2
 output dec_rdwen, //该指令需要写结果操作数到目的寄存器
 output [`E203_RFIDX_WIDTH-1:0] dec_rs1idx,  //源操作数1的寄存器索引
 output [`E203_RFIDX_WIDTH-1:0] dec_rs2idx, //源操作数2的寄存器索引
output [`E203_RFIDX_WIDTH-1:0] dec_rdidx,  //目的寄存器索引
 output [`E203_DECINFO_WIDTH-1:0] dec_info, //该指令的其它信息,被打包成一组宽信号,称之为信息总线(info bus).
 output [`E203_XLEN-1:0] dec_imm, //该指令使用的立即数值。
 output [`E203_PC_SIZE-1:0] dec_pc, // 该指令的pc值,等于输入的i_pc
 output dec_misalgn, //指令遇到了分支跳转异常,等于输入的misalgn
 output dec_buserr,  //指令遭遇了取指存储器访问错误,等于输入的i_buserr
 output dec_ilegl, //解码后,发现该指令是非法指令


 output dec_mulhsu, //指令为 mulh或mulhsu或mulhu,这些乘法指令都把结果的高32位放到目的寄存器
 output dec_mul   , //指令为乘法指令
 output dec_div   , //指令为除法指令
 output dec_rem   ,//指数为取余数指令
 output dec_divu  ,//指令为无符号数除法指令
 output dec_remu  ,//指令为无符号数取余数指令

output dec_rv32, //该指令为32位指令,为0的话则是16位的压缩指令
 output dec_bjp, //该指令为跳转指令,jal 或者jalr或者bxx指令
 output dec_jal,  //该指令为jal指令
 output dec_jalr, //该指令为jalr指令
 output dec_bxx, //该指令为bxx

output [`E203_RFIDX_WIDTH-1:0] dec_jalr_rs1idx, //jalr指令中rs1寄存器索引
 output [`E203_XLEN-1:0] dec_bjp_imm  //bjp指令中的立即数

       下面代码判断指令是32位指令还是16位指令的代码。操作码的低2位11,且3到5位不为111,则为rv32指令,否则为16位指令,因为E203不支持rv64,所以用一位信号就可以表示rv32和rvc了。

wire [32-1:0] rv32_instr = i_instr;
wire [16-1:0] rv16_instr = i_instr[15:0];
//指令的低7位为操作码
wire [6:0]  opcode = rv32_instr[6:0];

wire opcode_1_0_00  = (opcode[1:0] == 2'b00);
wire opcode_1_0_01  = (opcode[1:0] == 2'b01);
 wire opcode_1_0_10  = (opcode[1:0] == 2'b10);
 wire opcode_1_0_11  = (opcode[1:0] == 2'b11);
 //为32位指令或者16位指令
 wire rv32 = (~(i_instr[4:2] == 3'b111)) & opcode_1_0_11;


下面代码为取出32位指令和16位指令的关键编码段。RVC的编码比较复杂,有些指令寄存器为3位表示,有些为5位表示,立即数通常都有旋转,旋转格式还很多。具体参见https://www.cnblogs.com/mikewolf2002/p/9884789.html

wire [4:0]  rv32_rd     = rv32_instr[11:7]; // 目的寄存器索引
 wire [2:0]  rv32_func3  = rv32_instr[14:12];//func3段
 wire [4:0]  rv32_rs1    = rv32_instr[19:15];//源操作数1寄存器索引
 wire [4:0]  rv32_rs2    = rv32_instr[24:20];//源操作数2寄存器索引
 wire [6:0]  rv32_func7  = rv32_instr[31:25];//func7段
 //CR  15-12 func4, 11-7 rd/rs1, 6-2 rs2, 0-1 opcode
 //CI  15-13 func3, 12 imm,11-7 rd/rs1,6-2 imm, 0-1 opcode
 wire [4:0]  rv16_rd     = rv32_rd;
 wire [4:0]  rv16_rs1    = rv16_rd;
 wire [4:0]  rv16_rs2    = rv32_instr[6:2];
 //CIW,CL,CS,CA,CB,CJ
 //rdd=rd', rss1=rs1', rss2=rs2' short register, x8-x15, f8-f15
 wire [4:0]  rv16_rdd    = {2'b01,rv32_instr[4:2]};
 wire [4:0]  rv16_rss1   = {2'b01,rv32_instr[9:7]};
 wire [4:0]  rv16_rss2   = rv16_rdd;

wire [2:0]  rv16_func3  = rv32_instr[15:13]

下面的代码产生指令中的关键信息判断,用于后面的代码复用。

// We generate the signals and reused them as much as possible to save gatecounts
  wire opcode_4_2_000 = (opcode[4:2] == 3'b000);
  wire opcode_4_2_001 = (opcode[4:2] == 3'b001);
   wire opcode_4_2_010 = (opcode[4:2] == 3'b010);
   wire opcode_4_2_011 = (opcode[4:2] == 3'b011);
   wire opcode_4_2_100 = (opcode[4:2] == 3'b100);
   wire opcode_4_2_101 = (opcode[4:2] == 3'b101);
   wire opcode_4_2_110 = (opcode[4:2] == 3'b110);
   wire opcode_4_2_111 = (opcode[4:2] == 3'b111);
   wire opcode_6_5_00  = (opcode[6:5] == 2'b00);
   wire opcode_6_5_01  = (opcode[6:5] == 2'b01);
   wire opcode_6_5_10  = (opcode[6:5] == 2'b10);
   wire opcode_6_5_11  = (opcode[6:5] == 2'b11);

  wire rv32_func3_000 = (rv32_func3 == 3'b000);
   wire rv32_func3_001 = (rv32_func3 == 3'b001);
   wire rv32_func3_010 = (rv32_func3 == 3'b010);
   wire rv32_func3_011 = (rv32_func3 == 3'b011);
   wire rv32_func3_100 = (rv32_func3 == 3'b100);
   wire rv32_func3_101 = (rv32_func3 == 3'b101);
   wire rv32_func3_110 = (rv32_func3 == 3'b110);
   wire rv32_func3_111 = (rv32_func3 == 3'b111);

  wire rv16_func3_000 = (rv16_func3 == 3'b000);
   wire rv16_func3_001 = (rv16_func3 == 3'b001);
   wire rv16_func3_010 = (rv16_func3 == 3'b010);
   wire rv16_func3_011 = (rv16_func3 == 3'b011);
   wire rv16_func3_100 = (rv16_func3 == 3'b100);
   wire rv16_func3_101 = (rv16_func3 == 3'b101);
   wire rv16_func3_110 = (rv16_func3 == 3'b110);
   wire rv16_func3_111 = (rv16_func3 == 3'b111);

  wire rv32_func7_0000000 = (rv32_func7 == 7'b0000000);
   wire rv32_func7_0100000 = (rv32_func7 == 7'b0100000);
   wire rv32_func7_0000001 = (rv32_func7 == 7'b0000001);
   wire rv32_func7_0000101 = (rv32_func7 == 7'b0000101);
   wire rv32_func7_0001001 = (rv32_func7 == 7'b0001001);
   wire rv32_func7_0001101 = (rv32_func7 == 7'b0001101);
   wire rv32_func7_0010101 = (rv32_func7 == 7'b0010101);
   wire rv32_func7_0100001 = (rv32_func7 == 7'b0100001);
   wire rv32_func7_0010001 = (rv32_func7 == 7'b0010001);
   wire rv32_func7_0101101 = (rv32_func7 == 7'b0101101);
   wire rv32_func7_1111111 = (rv32_func7 == 7'b1111111);
   wire rv32_func7_0000100 = (rv32_func7 == 7'b0000100);
   wire rv32_func7_0001000 = (rv32_func7 == 7'b0001000);
   wire rv32_func7_0001100 = (rv32_func7 == 7'b0001100);
   wire rv32_func7_0101100 = (rv32_func7 == 7'b0101100);
   wire rv32_func7_0010000 = (rv32_func7 == 7'b0010000);
   wire rv32_func7_0010100 = (rv32_func7 == 7'b0010100);
   wire rv32_func7_1100000 = (rv32_func7 == 7'b1100000);
   wire rv32_func7_1110000 = (rv32_func7 == 7'b1110000);
   wire rv32_func7_1010000 = (rv32_func7 == 7'b1010000);
   wire rv32_func7_1101000 = (rv32_func7 == 7'b1101000);
   wire rv32_func7_1111000 = (rv32_func7 == 7'b1111000);
   wire rv32_func7_1010001 = (rv32_func7 == 7'b1010001);
   wire rv32_func7_1110001 = (rv32_func7 == 7'b1110001);
   wire rv32_func7_1100001 = (rv32_func7 == 7'b1100001);
   wire rv32_func7_1101001 = (rv32_func7 == 7'b1101001);

  wire rv32_rs1_x0 = (rv32_rs1 == 5'b00000);
   wire rv32_rs2_x0 = (rv32_rs2 == 5'b00000);
   wire rv32_rs2_x1 = (rv32_rs2 == 5'b00001);
   wire rv32_rd_x0  = (rv32_rd  == 5'b00000);
   wire rv32_rd_x2  = (rv32_rd  == 5'b00010);

  wire rv16_rs1_x0 = (rv16_rs1 == 5'b00000);
   wire rv16_rs2_x0 = (rv16_rs2 == 5'b00000);
   wire rv16_rd_x0  = (rv16_rd  == 5'b00000);
   wire rv16_rd_x2  = (rv16_rd  == 5'b00010);

  wire rv32_rs1_x31 = (rv32_rs1 == 5'b11111);
   wire rv32_rs2_x31 = (rv32_rs2 == 5'b11111);
   wire rv32_rd_x31  = (rv32_rd  == 5'b11111);
View Code

相关文章:

  • 2022-01-15
  • 2022-03-08
  • 2021-06-27
  • 2021-10-15
  • 2022-12-23
  • 2021-10-28
  • 2022-12-23
猜你喜欢
  • 2021-07-31
  • 2021-05-15
  • 2021-10-10
  • 2021-12-25
  • 2021-06-17
  • 2021-12-21
  • 2022-12-23
相关资源
相似解决方案