当前位置:网站首页>verilog独热码实现译码MIPS指令集
verilog独热码实现译码MIPS指令集
2022-08-09 08:55:00 【面向01编程】
译码器端口说明
序号 | 接口名 | 宽度 | 输入/输出 | 作用 |
---|---|---|---|---|
1 | rst | 1 | 输入 | 复位信号 |
2 | inst_i | 32 | 输入 | 译码阶段的指令 |
3 | reg1_data_i | 32 | 输入 | 从regfile读入数据1 |
4 | reg2_data_i | 32 | 输入 | 从regfile读入数据2 |
5 | aluop_o | 4 | 输出 | 译码阶段运算类型 |
6 | reg1_o | 32 | 输出 | 译码阶段源操作数1 |
7 | reg2_o | 32 | 输出 | 译码阶段源操作数2 |
8 | wd_o | 5 | 输出 | 目的寄存器地址,inst_i[15:11] |
9 | wreg_o | 1 | 输出 | 是否要写入目的寄存器 |
10 | reg2_addr_o | 5 | 输出 | 第二个寄存器地址,inst_i[20:16] |
11 | reg2_read_o | 1 | 输出 | regfile第二个寄存器读使能信号 |
12 | reg1_addr_o | 5 | 输出 | 第一个寄存器地址,inst_i[25:21] |
13 | reg1_read_o | 1 | 输出 | regfile第一个寄存器读使能信号 |
表2.2 译码器内部信号说明
序号 | 接口名 | 宽度 | 作用 |
---|---|---|---|
1 | op | 6 | 对应inst_i[31:26],用于译码 |
2 | op2 | 5 | 对应inst_i[10:6],用于译码 |
3 | op3 | 6 | 对应inst_i[5:0],用于译码 |
4 | op4 | 5 | 对应inst_i[20:16] |
5 | imm | 32 | 立即数 |
6 | instvalid | 1 | 指令是否有效 |
表2.3译码阶段需要的信息
序号 | 信号 | 功能 |
---|---|---|
1 | wreg_o | 是否要写寄存器 |
2 | aluop_o | 运算类型 |
3 | reg1_read_o | 是否读寄存器1 |
4 | reg2_read_o | 是否读寄存器2 |
5 | instvalid | 指令是否合法 |
6 | reg1_addr_o | 读寄存器地址1 |
7 | reg2_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
边栏推荐
猜你喜欢
随机推荐
RESTful
gin中模型中增删改查+搜索分页
【场景化解决方案】钉钉财务审批同步金蝶云星空
Calendar类和Date类转换时区 && 部分时区城市列表
数据解析之bs4学习
Module模块化编程的优点有哪些
requests之防盗链学习
jdbctemplate连接sql server,代码中查出来的数据跟数据库中不一致,如何解决?
[Vulnerability reproduction] CVE-2018-7490 (path traversal)
Makefile中patsubst、wildcard、notdir的使用
管理方向发展
[漏洞复现]CVE-2018-12613(远程文件包含)
sizeof 结构体问题
Redis缓存设计
内存中的swap机制
Makefile中的%标记和系统通配符*的区别
nyoj306 走迷宫(搜索+二分)
The working principle of switch
Shell programming loop statement and function
基于蓝牙定位功能开发的医院智能导航系统