赞
踩
- `timescale 1ns / 1ps
- //
-
- module Idecode32 (
- input reset,
- input clock,
- output [31:0] read_data_1, // 输出的第一操作数
- output [31:0] read_data_2, // 输出的第二操作数
- input [31:0] Instruction, // 取指单元来的指令
- input [31:0] read_data, // 从DATA RAM or I/O port取出的数据
- input [31:0] ALU_result, // 从执行单元来的运算的结果,需要扩展立即数到32位
- input Jal, // 来自控制单元,说明是JAL指令
- input RegWrite, // 来自控制单元
- input MemtoReg, // 来自控制单元
- input RegDst, // 来自控制单元
- output [31:0] Sign_extend, // 译码单元输出的扩展后的32位立即数
- input [31:0] opcplus4 // 来自取指单元,JAL中用
- );
-
- reg[31:0] register[0:31]; // 寄存器组共32个32位寄存器
- reg[4:0] write_register_address; // 要写的寄存器的号
- reg[31:0] write_data; // 要写寄存器的数据放这里
-
- wire[4:0] read_register_1_address; // 要读的第一个寄存器的号(rs)
- wire[4:0] read_register_2_address; // 要读的第二个寄存器的号(rt)
- wire[4:0] write_register_address_1; // r-form指令要写的寄存器的号(rd)
- wire[4:0] write_register_address_0; // i-form指令要写的寄存器的号(rt)
- wire[15:0] Instruction_immediate_value; // 指令中的立即数
- wire[5:0] opcode; // 指令码
-
- assign opcode = Instruction[31:26]; // OP
- assign read_register_1_address = Instruction[25:21]; // rs
- assign read_register_2_address = Instruction[20:16]; // rt
- assign write_register_address_1 = Instruction[15:11]; // rd (r-form)
- assign write_register_address_0 = Instruction[20:16]; // rt (i-form)
- assign Instruction_immediate_value = Instruction[15:0]; // data, rladr (i-form)
-
- wire sign; // 取符号位的值
-
- assign sign = Instruction[15]; // 取指令的第15位作为符号位
-
- assign Sign_extend[31:16] = (sign) ? {16{1'b1}} : {16{1'b0}}; // 符号扩展,根据符号位填充高位
- assign Sign_extend[15:0] = Instruction[15:0]; // 将原始的16位立即数填充到低位
-
- assign read_data_1 = register[read_register_1_address]; // 从寄存器组中读取第一个源寄存器的数据
- assign read_data_2 = register[read_register_2_address]; // 从寄存器组中读取第二个源寄存器的数据
-
- always @* begin
- if (Jal) begin
- write_register_address = 5'b11111; // JAL指令的目标寄存器是31号寄存器
- end else begin
- if (RegDst) begin
- write_register_address = write_register_address_1; // r-form指令的目标寄存器地址
- end else begin
- write_register_address = write_register_address_0; // i-form指令的目标寄存器地址
- end
- end
- end
- always @* begin
- if (MemtoReg) begin
- write_data = read_data; // 数据来自数据RAM的输出
- end else begin
- write_data = ALU_result; // 运算指令的数据来自ALU_result
- end
- end
- integer i;
- always @(posedge clock) begin
- if (reset == 1) begin
- for (i = 0; i < 32; i = i + 1)
- register[i] <= 0; // 初始化寄存器组,将所有寄存器清零
- end else if (RegWrite == 1) begin
- if (write_register_address != 5'b00000) begin
- register[write_register_address] <= write_data; // 写入数据到目标寄存器,除了0号寄存器
- end
- end
- end
-
- endmodule
仿真代码如下
- `timescale 1ns / 1ps
- //
- // Company:
- // Engineer:
- //
- // Create Date:
- // Design Name:
- // Module Name: idcode32_sim
- // Project Name:
- // Target Devices:
- // Tool Versions:
- // Description:
- //
- // Dependencies:
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //
-
-
- module idcode32_sim ();
-
- // input
- reg[31:0] Instruction = 32'b000000_00010_00011_00111_00000_100000; //add $7,$2,$3
- reg[31:0] read_data = 32'h00000000; // 从DATA RAM or I/O port取出的数据
- reg[31:0] ALU_result = 32'h00000005; // 需要扩展立即数到32位
- reg Jal = 1'b0;
- reg RegWrite = 1'b1;
- reg MemtoReg = 1'b0;
- reg RegDst = 1'b1;
- reg clock = 1'b0 ,reset = 1'b1;
- reg[31:0] opcplus4 = 32'h00000004; // 来自取指单元,JAL中用
- // output
- wire[31:0] read_data_1;
- wire[31:0] read_data_2;
- wire[31:0] Sign_extend;
-
- Idecode32 Uid (
- .reset (reset), // 复位(高电平有效)
- .clock (clock), // CPU时钟
- .read_data_1 (read_data_1), // 输出的第一操作数
- .read_data_2 (read_data_2), // 输出的第二操作数
- .Instruction (Instruction), // 取指单元来的指令
- .read_data (read_data), // 从DATA RAM or I/O port取出的数据
- .ALU_result (ALU_result), // 从执行单元来的运算的结果,需要扩展立即数到32位
- .Jal (Jal), // 来自控制单元,说明是JAL指令
- .RegWrite (RegWrite), // 来自控制单元
- .MemtoReg (MemtoReg), // 来自控制单元
- .RegDst (RegDst), // 来自控制单元
- .Sign_extend (Sign_extend), // 扩展后的32位立即数
- .opcplus4 (opcplus4) // 来自取指单元,JAL中用
- );
-
- initial begin
- #200 reset = 1'b0;
- #200 begin Instruction = 32'b001000_00111_00011_1000000000110111; //addi $3,$7,0X8037
- read_data = 32'h00000000;
- ALU_result = 32'hFFFF803C;
- Jal = 1'b0;
- RegWrite = 1'b1;
- MemtoReg = 1'b0;
- RegDst = 1'b0;
- opcplus4 = 32'h00000008;
- end
- #200 begin Instruction = 32'b001100_00010_00100_1000000010010111; //andi $4,$2,0X8097
- read_data = 32'h00000000;
- ALU_result = 32'h00000002;
- Jal = 1'b0;
- RegWrite = 1'b1;
- MemtoReg = 1'b0;
- RegDst = 1'b0;
- opcplus4 = 32'h0000000c;
- end
- #200 begin Instruction = 32'b000000_00000_00001_00101_00010_000000; //sll $5,$1,2
- read_data = 32'h00000000;
- ALU_result = 32'h00000004;
- Jal = 1'b0;
- RegWrite = 1'b1;
- MemtoReg = 1'b0;
- RegDst = 1'b1;
- opcplus4 = 32'h00000010;
- end
- #200 begin Instruction = 32'b100011_00000_00110_0000000100000000; //LW $6,0(0X100)
- read_data = 32'h0000007B;
- ALU_result = 32'h00000054;
- Jal = 1'b0;
- RegWrite = 1'b1;
- MemtoReg = 1'b1;
- RegDst = 1'b0;
- opcplus4 = 32'h00000014;
- end
- #200 begin Instruction = 32'b000011_00000000000000000000000000; //JAL 0000
- read_data = 32'h00000000;
- ALU_result = 32'h00000004;
- Jal = 1'b1;
- RegWrite = 1'b1;
- MemtoReg = 1'b0;
- RegDst = 1'b0;
- opcplus4 = 32'h00000018;
- end
- end
- always #50 clock = ~clock;
- endmodule
仿真波形图如下图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。