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

news2024/9/23 6:23:35
`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

仿真波形图如下图

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1942702.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu配置ssh服务器详解

① 确定Ubuntu是否安装SSH服务 systemctl status ssh 一般最开始都没有ssh服务 ② 安装SSH Server sudo apt install openssh-server 执行过程如下 ③ 确定Ubuntu SSH服务状态 systemctl status ssh 现在能看到&#xff1a; 第一行加载状态&#xff0c;已加载ssh.service文件…

大语言模型-GPT-Generative Pre-Training

一、背景信息&#xff1a; GPT是2018 年 6 月由OpenAI 提出的预训练语言模型。 GPT可以应用于复杂的NLP任务中&#xff0c;例如文章生成&#xff0c;代码生成&#xff0c;机器翻译&#xff0c;问答对话等。 GPT也采用两阶段的训练过程&#xff0c;第一阶段是无监督的方式来预训…

使用 Redis 实现验证码、token 的存储,用自定义拦截器完成用户认证、并使用双重拦截器解决 token 刷新的问题

基于session实现登录流程 1.发送验证码 用户在提交手机号后&#xff0c;会校验手机号是否合法&#xff0c;如果不合法&#xff0c;则要求用户重新输入手机号 如果手机号合法&#xff0c;后台此时生成对应的验证码&#xff0c;同时将验证码进行保存&#xff0c;然后再通过短信…

Python爬虫实战案例(爬取图片)

爬取图片的信息 爬取图片与爬取文本内容相似&#xff0c;只是需要加上图片的url&#xff0c;并且在查找图片位置的时候需要带上图片的属性。 这里选取了一个4K高清的壁纸网站&#xff08;彼岸壁纸https://pic.netbian.com&#xff09;进行爬取。 具体步骤如下&#xff1a; …

Android 性能之刷新率设置和管理

目录 1. 刷新率和帧率 2. 多种刷新率 3. 基本原理 3.1 屏幕 & 显示控制器 3.2 Composer Service 4. Framework 策略 4.1基本架构 4.2 刷新率设置项的定义 4.2.1 最低刷新率 4.2.2 默认刷新率 & 默认的用户设置刷新率 4.2.2.1 设置入口 4.2.2.2 设置场景 4…

Matlab画不同指标的对比图

目录 一、指标名字可修改 二、模型名字可修改 三、输入数据可修改 软件用的是Matlab R2024a。 clear,clc,close all figure1figure(1); % set(figure1,Position,[300,100,800,600],Color,[1 1 1]) axes1 axes(Parent,figure1);%% Initialize data points 一、指标名字可修…

zigbee DL-20无线串口模块(电赛备战)

zigbee DL-20无线串口模块(电赛备战) 备战2024电子设计大赛&#xff08;7.29-8.1&#xff09; 概述 DL-20是一款2.4G无线串口模块&#xff0c;支持点对点和广播模式的通信。它具备低数据丢失率、宽电压范围和高传输速率的特点&#xff0c;适用于多种无线通信场景。 在电赛中&…

百日筑基第二十八天-23种设计模式-行为型总汇

百日筑基第二十八天-23种设计模式-行为型总汇 文章目录 百日筑基第二十八天-23种设计模式-行为型总汇前言模板方法模式简介模板方式的特点模板方法模式结构类图模板方式模式案例分析模板方法模式应用源码分析模板方法模式的注意事项和细节 迭代器模式迭代器模式结构类图迭代器模…

googleTest 源码主线框架性分析

本文备忘一个主题的分析过程和结论&#xff0c;即&#xff0c;googleTest框架中是如何调用相关的测试宏的&#xff1f; TEST TEST_F TEST_P 等等 1&#xff0c;googleTest 环境与简单示例 1.1 下载 googletest 并编译 下载&#xff1a; $ git clone https://github.com/goog…

5 C 语言数组与字符串的全面解析

目录 1 数组的概念与特性 1.1 什么是数组 1.2 数组的特点 1.3 数组的用途 2 一维数组的定义与初始化 2.1 一维数组的定义 2.2 声明与定义的区别 2.3 一维数组的多种初始化 3 数组名的命名规则与作用 3.1 数组名的命名规则 3.2 数组名的作用 4 一维数组在内存中的存…

实战篇(十二):如何使用 Processing 创建一个多功能的简易吃豆人游戏

如何使用 Processing 创建一个多功能的简易吃豆人游戏 文章目录 如何使用 Processing 创建一个多功能的==简易==吃豆人游戏引言准备工作第一步:设置基本框架第二步:创建 Pacman 类第三步:创建 Obstacle 类第四步:添加分数系统第五步:运行游戏完整代码结论参考资料引言 吃…

Python基础知识——(005)

文章目录 P21——20. 比较运算符 P22——21. 逻辑运算符 P23——22. 位运算和运算符的优先级 P24——23. 本章总结和章节习题 P21——20. 比较运算符 示例3-17—比较运算符的使用&#xff1a; P22——21. 逻辑运算符 示例3-18—逻辑运算符的使用&#xff1a; print(True and T…

van-dialog 组件调用报错

报错截图 报错原因 这个警告表明 vue 在渲染页面时遇到了一个未知的自定义组件 <van-dialog>&#xff0c;并且提示可能是由于未正确注册该组件导致的。在 vue 中&#xff0c;当我们使用自定义组件时&#xff0c;需要先在 vue 实例中注册这些组件&#xff0c;以便 vue 能…

基于关键字驱动设计Web UI自动化测试框架!

引言 在自动化测试领域&#xff0c;关键字驱动测试&#xff08;Keyword-Driven Testing, KDT&#xff09;是一种高效且灵活的方法&#xff0c;它通过抽象测试用例中的操作为关键字&#xff0c;实现了测试用例与测试代码的分离&#xff0c;从而提高了测试脚本的可维护性和可扩展…

5.Fabric的共识机制

在Fabric中,有以下3中典型共识机制。 Solo共识 solo共识机制只能用于单节点模式,即只能有一个Orderer节点,因此,其共识过程很简单,每接收到一个交易信息,就在共识模块的控制下产生区块并广播给节点存储到账本中。 Solo 模式下的共识只适用于一个Orderer节点,所以可以在…

AI 驱动下的一体化分布式数据库:滴滴、快手、中国恩菲、好未来、翼鸥教育共话创新应用实践|OceanBase Meetup 精彩回顾

7月6日&#xff0c;OceanBase Meetup 北京站——“AI 驱动下的一体化分布式数据库&#xff1a;跨行业多场景的创新应用与实战”举办。来自滴滴、快手、中国恩菲、好未来、翼鸥教育、蚂蚁集团及OceanBase等众多行业技术专家与资深用户&#xff0c;围绕众多用户关注的AI 与数据库…

Performance Metrics in Evaluating Stable Diffusion Models

1.Performance Metrics in Evaluating Stable Diffusion Models 笔记来源&#xff1a; 1.Performance Metrics in Evaluating Stable Diffusion Models 2.Denoising Diffusion Probabilistic Models 3.A simple explanation of the Inception Score 4.What is the inception s…

【LLM】-05-提示工程-部署Langchain-Chat

目录 1、软硬件要求 1.1、软件要求 1.2、硬件要求 1.3、个人配置参考 2、创建cuda环境 3、下载源码及模型 4、配置文件修改 5、初始化知识库 5.1、训练自己的知识库 6、启动 7、API接口调用 7.1、使用openai 参考官方wiki&#xff0c;本文以Ubuntu20.04_x64&#xf…

揭秘!电源炼成记:从基础原理到高端设计的全面解析

文章目录 初始构想&#xff1a;需求驱动设计原理探索&#xff1a;选择适合的拓扑结构精细设计&#xff1a;元器件选型与布局环路稳定&#xff1a;控制策略与补偿网络严格测试&#xff1a;验证与优化持续改进&#xff1a;创新与技术迭代《硬件十万个为什么&#xff08;电源是怎样…

云计算实训11——web服务器的搭建、nfs服务器的搭建、备份静态文件、基于linux和windows实现文件共享

一、搭建web服务器 1.关闭firewall和selinux 关闭防火墙 systemctl stop firewalld systemctl disable firewalld 停用selinux setenforce 0 配置文件中让sellinux不再启动 vim /etc/selinux/config SELINUXpermissive 2.编辑dns配置文件 vim /etc/resolv.conf nameserver 114.…