当前位置:网站首页>verilog独热码实现译码MIPS指令集

verilog独热码实现译码MIPS指令集

2022-08-09 08:55:00 面向01编程

译码器端口说明

序号接口名宽度输入/输出作用
1rst1输入复位信号
2inst_i32输入译码阶段的指令
3reg1_data_i32输入从regfile读入数据1
4reg2_data_i32输入从regfile读入数据2
5aluop_o4输出译码阶段运算类型
6reg1_o32输出译码阶段源操作数1
7reg2_o32输出译码阶段源操作数2
8wd_o5输出目的寄存器地址,inst_i[15:11]
9wreg_o1输出是否要写入目的寄存器
10reg2_addr_o5输出第二个寄存器地址,inst_i[20:16]
11reg2_read_o1输出regfile第二个寄存器读使能信号
12reg1_addr_o5输出第一个寄存器地址,inst_i[25:21]
13reg1_read_o1输出regfile第一个寄存器读使能信号

表2.2 译码器内部信号说明

序号接口名宽度作用
1op6对应inst_i[31:26],用于译码
2op25对应inst_i[10:6],用于译码
3op36对应inst_i[5:0],用于译码
4op45对应inst_i[20:16]
5imm32立即数
6instvalid1指令是否有效

表2.3译码阶段需要的信息

序号信号功能
1wreg_o是否要写寄存器
2aluop_o运算类型
3reg1_read_o是否读寄存器1
4reg2_read_o是否读寄存器2
5instvalid指令是否合法
6reg1_addr_o读寄存器地址1
7reg2_addr_o读寄存器地址2

`define FOURBYTE  31:0
`define ONEBYTE   3:0
`define ADD_OP  4'b0000
`define SUB_OP  4'b0001
`define SLT_OP  4'b0010
`define SLTU_OP 4'b0011
`define AND_OP  4'b0100
`define NOR_OP  4'b0101
`define OR_OP   4'b0110
`define XOR_OP  4'b0111
`define SLL_OP  4'b1000
`define SRL_OP  4'b1001
`define SRA_OP  4'b1010
`define LUI_OP  4'b1011
module id(
    input               rst,
    input   [`FOURBYTE] inst_i,
    input   [`FOURBYTE] reg1_data_i,
    input   [`FOURBYTE] reg2_data_i,
    output  [`ONEBYTE]  aluop_o,
    output  [`FOURBYTE] reg1_o,
    output  [`FOURBYTE] reg2_o,
    output  [4:0]       wd_o,        //inst[15:11]
    output              wreg_o,
    output  [4:0]       reg1_addr_o, //inst[25:21]
    output              reg1_read_o,
    output  [4:0]       reg2_addr_o, //inst[20:16]
    output              reg2_read_o
);
    wire [5:0] op   = inst_i[31:26];
    wire [5:0] func = inst_i[5:0];
    wire [4:0] sa   = inst_i[10:6]; //shamt
    wire [4:0] rt   = inst_i[20:16];
    wire instvalid  = wreg_o;
    wire op_tem     = ~(|op);
    

    wire inst_add   = op_tem && (func == 6'b100000);
    wire inst_sub   = op_tem && (func == 6'b100010);
    wire inst_or    = op_tem && (func == 6'b100101);
    wire inst_and   = op_tem && (func == 6'b100100);
    wire inst_xor   = op_tem && (func == 6'b100110);
    wire inst_nor   = op_tem && (func == 6'b100111);
    wire inst_slt   = op_tem && (func == 6'b101010);
    wire inst_sltu  = op_tem && (func == 6'b101011);
    wire inst_sll   = op_tem && (func == 6'b000000);
    wire inst_srl   = op_tem && (func == 6'b000010);
    wire inst_sra   = op_tem && (func == 6'b000011);
    wire inst_lui   = (op == 6'b001111);
    wire [`FOURBYTE] imm = (inst_lui)? {inst_i[15:0],16'b0}:(inst_sll|inst_sra|inst_srl)?{27'b0,sa}:32'b0;
    assign wreg_o        =  inst_add | inst_sub | inst_or  | inst_srl | inst_sra | inst_lui |
                            inst_and | inst_xor | inst_nor | inst_slt | inst_sltu| inst_sll ;
    assign reg1_read_o   =  inst_add | inst_sub | inst_or  | inst_lui |
                            inst_and | inst_xor | inst_nor | inst_slt | inst_sltu ;
    assign reg2_read_o   =  inst_add | inst_sub | inst_or  | inst_srl | inst_sra | 
                            inst_and | inst_xor | inst_nor | inst_slt | inst_sltu| inst_sll ;
    assign wd_o          =  (inst_lui) ? inst_i[20:16] : inst_i[15:11];
    assign reg1_addr_o   = inst_i[25:21];
    assign reg2_addr_o   = inst_i[20:16];
    assign aluop_o[0]    = inst_sub|inst_sltu|inst_nor|inst_xor|inst_srl|inst_lui;
    assign aluop_o[1]    = inst_slt|inst_sltu|inst_or |inst_xor|inst_sra|inst_lui;
    assign aluop_o[2]    = inst_and|inst_nor |inst_or |inst_xor;
    assign aluop_o[3]    = inst_sll|inst_srl |inst_sra|inst_lui;
    assign reg1_o        = (rst)?32'b0:(reg1_read_o)?reg1_data_i:imm;
    assign reg2_o        = (rst)?32'b0:(reg2_read_o)?reg2_data_i:imm;
endmodule
原网站

版权声明
本文为[面向01编程]所创,转载请带上原文链接,感谢
https://blog.csdn.net/cai_ji_cpp/article/details/121341653