欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > 单周期CPU(三)译码模块(minisys)(verilog)(vivado)

单周期CPU(三)译码模块(minisys)(verilog)(vivado)

2024/10/25 0:33:11 来源:https://blog.csdn.net/m0_74626628/article/details/140555808  浏览:    关键词:单周期CPU(三)译码模块(minisys)(verilog)(vivado)
`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];    // OPassign read_register_1_address = Instruction[25:21]; // rsassign read_register_2_address = Instruction[20:16]; // rtassign 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 @* beginif (Jal) beginwrite_register_address = 5'b11111; // JAL指令的目标寄存器是31号寄存器end else beginif (RegDst) beginwrite_register_address = write_register_address_1; // r-form指令的目标寄存器地址end else beginwrite_register_address = write_register_address_0; // i-form指令的目标寄存器地址endendendalways @* beginif (MemtoReg) beginwrite_data = read_data; // 数据来自数据RAM的输出end else beginwrite_data = ALU_result; // 运算指令的数据来自ALU_resultendendinteger i;always @(posedge clock) beginif (reset == 1) beginfor (i = 0; i < 32; i = i + 1)register[i] <= 0; // 初始化寄存器组,将所有寄存器清零end else if (RegWrite == 1) beginif (write_register_address != 5'b00000) beginregister[write_register_address] <= write_data; // 写入数据到目标寄存器,除了0号寄存器endendendendmodule

仿真代码如下

`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,$3reg[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中用// outputwire[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,0X8037read_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,0X8097read_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,2read_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 0000read_data = 32'h00000000; ALU_result = 32'h00000004;Jal = 1'b1;RegWrite = 1'b1;MemtoReg = 1'b0;RegDst = 1'b0;opcplus4 = 32'h00000018; endend always #50 clock = ~clock;            
endmodule

仿真波形图如下图

 

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com