vivado实现译码器(含测试代码)

本篇文章使用Verilog语言编写实现译码器,含有设计代码和测试代码。能够实现以下14条指令的译码操作:

addaddusubsubusltsltuandorxornorsllsrlsralui
reg1_read_o11111111110000
reg2_read_o11111111111110
wreg_o11111111111111
一、接口描述

译码器接口描述表:
译码器接口描述表

二、设计代码

首先需要四个译码器,分别是两个6_64译码器和两个5_32译码器。
(1)6_64译码器decoder_6_64.v

`timescale 1ns / 1ps

module decoder_6_64(
    input[5:0] in,
    output[63:0] out
    );
    genvar i;
    generate
    for(i=0;i<64;i=i+1)
        begin:bit
        assign out[i]=(in==i);
    end
    endgenerate
endmodule

(2)5_32译码器decoder_5_32.v

`timescale 1ns / 1ps

module decoder_5_32(
    input[4:0] in,
    output[31:0] out
    );
    genvar i;
    generate
        for(i=0;i<32;i=i+1)
            begin:bit
            assign out[i]=(in==i);
        end
        endgenerate
endmodule

(3)译码器id_v

`timescale 1ns / 1ps
//`include "define.v"
module id(
    input wire rst,
    input wire[`InstBus] inst_i,
    input wire[`RegDataBus] reg1_data_i,
    input wire[`RegDataBus] reg2_data_i,
    output wire[`Aluop_OnehotBus] aluop_o,
    output wire[`RegDataBus] reg1_o,
    output wire[`RegDataBus] reg2_o,
    output wire[`RegDataBus] wd_o,
    output wire wreg_o,
    output wire[`RegAddrBus] reg1_addr_o,
    output wire[`RegAddrBus] reg2_addr_o,
    output wire reg1_read_o,
    output wire reg2_read_o
    );
    wire[5:0] op;
    wire[4:0] op1;
    wire[4:0] sa;
    wire[5:0] func;
    wire[63:0] op_d;
    wire[31:0] op1_d;
    wire[31:0] sa_d;
    wire[63:0] func_d;
    assign op=inst_i[31:26];
    assign op1=inst_i[25:21];
    assign sa=inst_i[10:6];
    assign func=inst_i[5:0];
    //实例化操作
    decoder_6_64 dec0(.in(op),.out(op_d));
    decoder_5_32 dec1(.in(op1),.out(op1_d));
    decoder_5_32g dec2(.in(sa),.out(sa_d));
    decoder_6_64g dec3(.in(func),.out(func_d));
    //一位二进制信息,由译码器输出决定
    wire inst_add;
    wire inst_addu;
    wire inst_sub;
    wire inst_subu;
    wire inst_slt;
    wire inst_sltu;
    wire inst_and;
    wire inst_or;
    wire inst_xor;
    wire inst_nor;
    wire inst_sll;
    wire inst_srl;
    wire inst_sra;
    wire inst_lui;
    assign inst_add=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncAdd];
    assign inst_addu=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncAddu];
    assign inst_sub=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncSub];
    assign inst_subu=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncSubu];
    assign inst_slt=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncSlt];
    assign inst_sltu=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncSltu];
    assign inst_and=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncAnd];
    assign inst_or=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncOr];
    assign inst_xor=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncXor];
    assign inst_nor=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncNor];
    assign inst_sll=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncSll];
    assign inst_srl=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncSrl];
    assign inst_sra=op_d[`OpZero]&&sa_d[`SaZero]&&func_d[`FuncSra];
    assign inst_lui=op_d[`OpLui];
    wire [13:0] aluop_o;
    assign aluop_o=(rst==`RstEnable)?14'b0:{
        inst_add,
        inst_addu,
        inst_sub,
        inst_subu,
        inst_slt,
        inst_sltu,
        inst_and,
        inst_or,
        inst_xor,
        inst_nor,
        inst_sll,
        inst_srl,
        inst_sra,
        inst_lui
    };
assign reg1_addr_o=(rst==`RstEnable)?`ZeroRegAddr:inst_i[25:21];
assign reg2_addr_o=(rst==`RstEnable)?`ZeroRegAddr:inst_i[20:16];
assign reg1_read_o=(rst==`RstEnable)?`ReadDisable:!(inst_sll||inst_srl||inst_sra||inst_lui);
assign reg2_read_o=(rst==`RstEnable)?`ReadDisable:!(inst_lui);
wire [`RegDataBus] imm;
assign imm=rst?`ZeroWord:(inst_lui?{inst_i[15:0],16'b0}:{27'b0,inst_i[10:6]});
assign reg1_o=rst?`ZeroWord:(reg1_read_o?reg1_data_i:imm);
assign reg2_o=rst?`ZeroWord:(reg2_read_o?reg2_data_i:imm);
assign wd_o=rst?`ZeroRegAddr:(inst_lui?inst_i[20:16]:inst_i[15:11]);
assign wreg_o=rst?`WriteDisable:`WriteEnable;
    
endmodule

(4)宏定义文件define.v

`define InstBus 31:0
`define InstAddrBus 31:0
`define CeDisable 0
`define CeEnable 1
`define ZeroWord 0

`define RegAddrBus 4:0
`define RegDataBus 31:0

`define RegNum 31:0
`define RstEnable 1
`define RstDisable 0
`define ZeroWord 0
`define ReadEnable 1
`define ReadDisable 0
`define WriteEnable 1
`define WriteDisable 0

`define Aluop_OnehotBus 13:0
`define OpZero 6'b000000
`define Op1Zero 5'b00000
`define SaZero 5'b00000
`define FuncZero 6'b000000

`define FuncAdd 6'b100000
`define FuncAddu 6'b100001
`define FuncSub 6'b100010
`define FuncSubu 6'b100011
`define FuncSlt 6'b101010
`define FuncSltu 6'b101011
`define FuncAnd 6'b100100
`define FuncOr 6'b100101
`define FuncXor 6'b100110
`define FuncNor 6'b100111
`define FuncSll 6'b000000
`define FuncSrl 6'b000010
`define FuncSra 6'b000011
`define OpLui 6'b001111

`define AluopAdd 14'b1_0000_0000_0000_0
`define AluopAddu 14'b0_1000_0000_0000_0
`define AluopSub 14'b0_0100_0000_0000_0
`define AluopSubu 14'b0_0010_0000_0000_0
`define AluopSlt 14'b0_0001_0000_0000_0
`define AluopSltu 14'b0_0000_1000_0000_0
`define AluopAnd 14'b0_0000_0100_0000_0
`define AluopOr 14'b0_0000_0010_0000_0
`define AluopXor 14'b0_0000_0001_0000_0
`define AluopNor 14'b0_0000_0000_1000_0
`define AluopSll 14'b0_0000_0000_0100_0
`define AluopSrl 14'b0_0000_0000_0010_0
`define AluopSra 14'b0_0000_0000_0001_0
`define AluopLui 14'b0_0000_0000_0000_1
`define AluopZero 14'b0_0000_0000_0000_0
三、测试代码
`timescale 1ns / 1ps
//`include "define.v"
module id_tb();
reg rst;
reg [`InstBus] inst_i;
reg [`RegDataBus] reg1_data_i;
reg [`RegDataBus] reg2_data_i;
wire [`Aluop_OnehotBus] aluop_o;
wire [`RegDataBus] reg1_o;
wire [`RegDataBus] reg2_o;
wire [`RegAddrBus] wd_o;
wire wreg_o;
wire [`RegAddrBus] reg1_addr_o;
wire [`RegAddrBus] reg2_addr_o;
wire reg1_read_o;
wire reg2_read_o;
id id0(rst,inst_i,reg1_data_i,reg2_data_i,aluop_o,reg1_o,reg2_o,wd_o,wreg_o,reg1_addr_o,reg2_addr_o,reg1_read_o,reg2_read_o);
    reg [`InstBus] inst_mem[0:127];
    initial begin
    $readmemh("E:/exper/14MIPS.data",inst_mem);//此处要修改为自己的指令集
    end
    integer i;
    initial begin
    rst=`RstEnable;
    #50
    rst=`RstDisable;
    reg1_data_i=32'h12345678;
    reg2_data_i=32'h87654321;
    for(i=0;i<=20;i=i+1)begin
    //指令输入
        inst_i=inst_mem[i];
        #20;
    end
    #50 $finish;
    end
endmodule
四、仿真波形图

仿真波形图
波形图描述:
1、330.000ns:此时的操作码为0041,为add操作。Reg1和Reg2中的数据相加。此时inst_add为1.
2、390.000ns:此时的操作码为012a,为subu操作。Reg1和Reg2中的数据相减。此时inst_subu为1.
3、430.000ns:此时的操作码为01f0,为sltu操作。Reg1和Reg2中的数据进行比较运算。此时inst_slt为1.

仅供学习交流,如发现错误,欢迎大家指正。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小橘子xxb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值