【单周期CPU】LoongArch | 32位寄存器DR | 32位的程序计数器PC | 通用寄存器堆Registers | 32位RAM存储器

news2024/11/15 19:51:28

前言:本章内容主要是演示在vivado下利用Verilog语言进行单周期简易CPU的设计。一步一步自己实现模型机的设计。本章先介绍单周期简易CPU中基本时序逻辑部件设计。

💻环境:一台内存4GB以上,装有64位Windows操作系统和Vivado 2017.4以上版本软件的PC机。

💎本章所采用的指令为LoongArch之LA32R版

目录

Ⅰ前置知识 

0x00 32位寄存器DR

0x01 32位的程序计数器PC

0x02 通用寄存器堆Registers

0x03  32位RAM存储器

Ⅱ Verilog实现

0x00 32位寄存器DR

0x01 32位的程序计数器PC

0x02 通用寄存器堆Registers

0x03 32位RAM存储器


Ⅰ前置知识 

0x00 32位寄存器DR

32位寄存器DR,全称为数据寄存器(Data Register),是计算机中常见的寄存器之一。它用于存储数据,是CPU中的一个重要组成部分。 

本章介绍的32位寄存器DR模块的参考电路框图如下: 

该模块的功能及引脚信号说明如下:

信号名称

功能说明

DataIn

32位数据输入信号

DataOut

32位数据输出信号

clk

时钟信号

WE

数据存入信号。当WE为1且在clk上升沿到来时,数据存入寄存器;当WE为0时,寄存器输出维持不变。

0x01 32位的程序计数器PC

32位程序计数器(Program Counter,PC)是计算机中一种重要的寄存器,它通常存储下一条指令的内存地址,是CPU能够顺利地执行指令的关键。

PC寄存器在CPU中被设计为自加的寄存器,它会在一个时钟周期中自动递增,从而指向下一条指令的地址,使得CPU可以连续地执行一系列指令。在程序执行过程中,PC寄存器会不断地指向下一条要执行的指令,直到程序结束或出现异常情况。

在现代计算机中,PC寄存器的位数一般为32位。当程序执行中遇到条件分支、循环等需要改变执行流程的指令时,CPU会根据条件跳转到不同的地址,PC寄存器也就被设置为相应的地址,从而改变了程序的执行路径。

本章介绍的32位的程序计数器PC模块的参考电路框图如下: 

该模块的功能及引脚信号说明如下:

信号名称

功能说明

rst

PC异步清零信号,高电平有效,即:rst为1时,PCdata =0

clk

时钟信号

offset

32位偏移量

pc_inc

自增控制信号,与clk上升沿配合工作。

在clk上升沿时刻,当pc_inc=1时,PCdata =原PCdata +1;当pc_inc=0时,PCdata =原PCdata +offset。

PCdata

32位数据输出信号

0x02 通用寄存器堆Registers

通用寄存器堆 (Registers) 是计算机体系结构中的一种硬件组件,用于存储和操作数据。它通常由多个独立的寄存器组成,每个寄存器都有固定的位宽。寄存器堆用于执行各种计算机指令和数据传输操作。 

本章介绍的通用寄存器堆Registers的参考电路框图如下:  

该模块的功能及引脚信号说明如下:

信号名称

功能说明

busA和busB

两路32位数据输出信号

Ra(5位)

读寄存器编号输入信号,该编号指定的寄存器的值经过“取数延迟”后,输出到busA

Rb(5位)

读寄存器编号输入信号,该编号指定的寄存器的值经过“取数延迟”后,输出到busB

Rw(5位)

写寄存器编号输入信号,该编号指定的数据要写入哪个寄存器

busW

32位数据输入信号

clk

写操作时钟控制信号,上升沿有效

RegWr

写使能控制信号,clk上升沿时刻,若RegWr为1,则busW上的数据被存入Rw指定的寄存器中

🚩注:

(1)寄存器堆的读操作不受clk控制;

(2)0号寄存器的值恒为0,不受写操作的影响。

0x03 32位RAM存储器

32位RAM存储器是一种具有32位数据线的随机存取存储器。RAM (Random Access Memory) 指的是随机存取存储器,它允许随机访问存储器中的任何位置,而无需按照顺序访问。32位RAM存储器的数据线有32条,可以同时传送32位二进制数据,因此它能够以非常快的速度读取和写入数据。

本章介绍的32位RAM存储器参考电路框图如下:   

 该模块的功能及引脚信号说明如下:

信号名称

功能说明

addr

32位地址总线,用于传送地址,以便按地址访问存储单元。

data_in

32位数据输入总线

data_out

32位数据输出总线

clk

时钟信号,上升沿有效

MemWrEn

写使能信号。

当MemWrEn为0时,数据从addr地址端口指定的内存单元读出。

当MemWrEn为1时,配合clk时钟信号工作,在clk上升沿,数据存入由addr地址端口指定的内存单元。

Ⅱ Verilog实现

0x00 32位寄存器DR

设计一个32位的寄存器DR,利用Verilog HDL完成建模设计

设计代码:


module Register32 (
  input [31:0] DataIn,
  output reg [31:0] DataOut,
  input clk,
  input WE
);

  always @(posedge clk) begin
    if (WE) begin
      DataOut <= DataIn;
    end
  end

endmodule

  在Vivado中点击”RTL ANALYSIS->Open Elaborated Design”,可以查看综合得到的 32位寄存器DR的逻辑电路,如图所示: 

 仿真代码:

module Register32_Test;

  reg [31:0] DataIn;
  wire [31:0] DataOut;
  reg clk;
  reg WE;

  Register32 dut (
    .DataIn(DataIn),
    .DataOut(DataOut),
    .clk(clk),
    .WE(WE)
  );

  always begin
    #5 clk = ~clk; // 时钟周期为10个时间单位
  end

  initial begin
    clk = 0;
    WE = 0;
    DataIn = 32'h11111111; // 设置输入数据
    #20 WE = 1; // 在20个时间单位后,使WE为1,触发数据存入
    #20 WE = 0; // 在另外20个时间单位后,使WE为0,保持输出稳定
    #20 DataIn = 32'h11101011; // 修改输入数据
    #20 WE = 1; // 再次触发数据存入
    #50 $finish; // 结束仿真
  end

endmodule

仿真结果:

❓思考:

读者可以思考一个问题,刚开始时为什么DataOut为xxx态?

0x01 32位的程序计数器PC

设计代码:


module ProgramCounter(
  input rst,
  input clk,
  input [31:0] offset,
  input pc_inc,
  output reg [31:0] PCdata
);

  always @(posedge clk or posedge rst) begin
    if (rst) begin
      PCdata <= 32'd0;
    end else begin
      if (pc_inc) begin
        PCdata <= PCdata + 32'd1;
      end else begin
        PCdata <= PCdata + offset;
      end
    end
  end

endmodule

  在Vivado中点击”RTL ANALYSIS->Open Elaborated Design”,可以查看综合得到的32位的程序计数器PC的逻辑电路,如图所示:  

仿真代码:

module ProgramCounter_tb;

  reg rst;
  reg clk;
  reg [31:0] offset;
  reg pc_inc;
  wire [31:0] PCdata;

  ProgramCounter dut (
    .rst(rst),
    .clk(clk),
    .offset(offset),
    .pc_inc(pc_inc),
    .PCdata(PCdata)
  );

  initial begin
    rst = 1;
    clk = 0;
    offset = 32'h00000001;
    pc_inc = 0;
    #10;

    rst = 0;
    #10;

    offset = 32'h00000002;
    pc_inc = 1;
    #10;

    pc_inc = 0;
    #10;

    $display("PCdata = %h", PCdata);

    #10;
    $finish;
  end

  always #5 clk = ~clk;

endmodule

仿真结果:

调整进制后可观察到下列波形

🚩注: 若不知道如何调整进制,可翻看本专栏的第一篇博客:

【单周期CPU】LoongArch | 立即数扩展模块Ext | 32位算术逻辑运算单元(ALU)_流继承的博客-CSDN博客

0x02 通用寄存器堆Registers

 设计代码:

module Registers(
  input [4:0] Ra,
  input [4:0] Rb,
  input [4:0] Rw,
  input [1:0] busW,
  input clk,
  input RegWr,
  output reg [31:0] busA,
  output reg [31:0] busB
);

  reg [31:0] regfile [0:31];

  always @(*) begin
    busA = regfile[Ra];
    busB = regfile[Rb];
  end

  always @(posedge clk) begin
    if (RegWr) begin
      if (Rw != 0)
        regfile[Rw] <= busW;
    end
  end

  initial begin
    for (integer i = 0; i <= 31; i = i + 1)
      regfile[i] = 32'h0;
  end

endmodule

   在Vivado中点击”RTL ANALYSIS->Open Elaborated Design”,可以查看综合得到的通用寄存器堆Registers的逻辑电路,如图所示:  

仿真代码:

module Registers_Test;

  reg [4:0] Ra;
  reg [4:0] Rb;
  reg [4:0] Rw;
  reg [1:0] busW;
  reg clk;
  reg RegWr;
  wire [31:0] busA;
  wire [31:0] busB;

  Registers dut (
    .Ra(Ra),
    .Rb(Rb),
    .Rw(Rw),
    .busW(busW),
    .clk(clk),
    .RegWr(RegWr),
    .busA(busA),
    .busB(busB)
  );

  initial begin
    clk = 0;
    RegWr = 0;
    Ra = 0;
    Rb = 0;
    Rw = 0;
    busW = 2'b01;

    #25;

    
   
    Ra = 2;
    Rb = 4;
    #25;
    $display("busA = %h, busB = %h", busA, busB);
   


    Rw = 6;
    busW = 2'b11;
    RegWr = 1;
    #50;
    $display("busA = %h, busB = %h", busA, busB);

    
    Ra = 6;
    Rb = 0;
    #25;
    $display("busA = %h, busB = %h", busA, busB);

    
    #10;
    $display("busA = %h, busB = %h", busA, busB);
  end

  always begin
    #50;
    clk = ~clk;
  end

endmodule

仿真结果:

调整进制后可观察到下列波形

0x03 32位RAM存储器

设计代码:

module RAM(
input MemWrEn, input clk,
input [31:0] addr,
input [31:0] data_in, output reg [31:0] data_out
);
reg [31:0] ram [0:31];

always@(posedge clk) begin
if (MemWrEn) ram[addr] <= data_in; end
always@(*) begin
if(MemWrEn==0) data_out <= ram[addr]; end
endmodule

    在Vivado中点击”RTL ANALYSIS->Open Elaborated Design”,可以查看综合得到的32位RAM存储器的逻辑电路,如图所示:  

仿真代码:

module RAM_sim; reg MemWrEn; reg clk;
reg [31:0] addr;
reg [31:0] data_in;
wire [31:0] data_out;

RAM
RAM1(.MemWrEn(MemWrEn),.clk(clk),
.addr(addr),.data_in(data_in),.data_out(data_out));

initial begin MemWrEn=1; addr=20; data_in=60; #200;
addr=15; data_in=30; #200;
addr=5; data_in=120; #200;
MemWrEn=0; addr=20; #100;
addr=15; #100;
addr=5; #200;
end

initial clk = 0;
always # 50 clk = ~clk; endmodule

仿真结果:

调整进制后可观察到下列波形

❓思考

在完成上述四个模块之后,读者可以思考一下:

1.“如何将数据存入暂存器”、“如何读取暂存器的值”等问题。

2.“如何控制PC的值自增或加偏移量”、“如何给PC清0”等问题。

3.“如何指定要写入数据的寄存器编号”、“如何保证0号寄存器的值不受写入操作的影响而始终保持为0”,“如何指定从哪个寄存器读出数据”和“是否具有将所有寄存器一次性全部清0的功能”等问题。

4.“如何指定要写入数据的内存单元地址” “如何指定从哪个内存单元读出数据”和“是否具有将所有内存单元一次性全部清0的功能”等问题。

END 


📝因为作者的能力有限,所以文章可能会存在一些错误和不准确之处,恳请大家指出!

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

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

相关文章

黑马微信小程序登录弹窗问题与解决的说明

1.问题 1.1开发者工具报错 [getFuzzyLocation] is not authorized如何解决&#xff1f; 1.2弹窗问题 2.解决方法 2.1开发工具报错问题 首先登录微信公众平台&#xff0c;找到开发管理。如下图 然后开通wx.getFuzzyLocation 申请模版&#xff0c;通过速度很多&#xff0c;…

24小时不定时价格监测如何做到

在做电商平台的数据监测时&#xff0c;品牌需要对线上监测的数据进行不定时监测&#xff0c;这是因为品牌做价格监测的目的是为了管控渠道&#xff0c;如果对店铺只能在特定的时间进行监测&#xff0c;那对于其他时间段的低价行为将不被发现&#xff0c;这也会使品牌渠道管控的…

【Redis】配置

&#x1f3af;Redis 配置 Redis 的配置文件位于 Redis 安装目录下&#xff0c;文件名为 redis.conf(Windows 名为 redis.windows.conf)。 1、查看配置 语法如下通过 config get 命令查看或设置配置项。 CONFIG GET 配置的名字 使用 * 号获取所有配置项 127.0.0.1:6379>…

Parsing error: Unexpected token :

如果你创建的是Vue3的项目还报这个错误的话&#xff0c;很可能就是.eslintrc.js配置的问题。 我为了省事把vue2项目的.eslintrc.js复制到vue3的项目了。。 .eslintrc.js module.exports {root: true,env: {node: true,},extends: [plugin:vue/vue3-essential,eslint:recomm…

【哈士奇赠书活动 - 29期】- 〖人工智能与ChatGPT〗

文章目录 ⭐️ 赠书 - 《人工智能与ChatGPT》⭐️ 内容简介⭐️ 作者简介⭐️ 编辑推荐⭐️ 赠书活动 → 获奖名单 ⭐️ 赠书 - 《人工智能与ChatGPT》 ⭐️ 内容简介 人们相信人工智能可以为这个时代的技术带来突破&#xff0c;而ChatGPT则使这种希望成为现实。现在&#xff0…

自定义View实战《弹幕》

自定义View实战《弹幕》 前言一、步骤讲解二、缓存优化三、弹幕框架DanmakuFlameMaster介绍DanmakuFlameMasterDanmakuFlameMaster的使用 四、初步实现的完整代码总结 前言 前面已经学习了自定义的View《渐变色的文字》是继承View的。现在我们在继承ViewGroup来实现我们的《弹…

C++【初识哈希】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 16.11.17 文章目录 &#x1f307;前言&#x1f3d9;️正文1、哈希思想2、哈希函数2.1、哈希函数的设计原则2.2、常见的哈希函数 3、哈希…

曹操最有名的4首诗

在中国帝王级的人物中间&#xff0c;真正称得上诗人的&#xff0c;曹操必定是最杰出一个。 曹操简介&#xff1a; 曹操&#xff08;155年&#xff0d;220年正月庚子&#xff09;&#xff0c;字孟德&#xff0c;一名吉利&#xff0c;小字阿瞒&#xff0c;沛国谯&#xff08;今…

Redis实现用户签到

用户签到 现在许多的APP或者网上应用为了提高用户的活跃度&#xff0c;都会设置一个每日签到的活动&#xff0c;签到完成后会给予一定的奖励&#xff0c;从而达到其目的。 而记录用户的签到信息可以使用如下一张数据库表来进行记录。 在用户数量并不多的情况下&#xff0c;数…

排序算法--冒泡排序(Java语言)

冒泡排序&#xff08;Bubble Sort&#xff09;是啥&#xff1f; 冒泡排序是一种简单的排序算法。它重复地走访过要排序的元素列&#xff0c;依次比较两个相邻的元素&#xff0c;如果他们的顺序&#xff08;如从大到小、首字母从A到Z&#xff09;错误就把他们交换过来。走访元素…

Android:Lifecycle

整体架构 LifecycleOwner Lifecycle持有者 在ComponentActivity中new出来&#xff0c;所以Activity和Fragment自带 实现了LifecycleOwner接口的类 可以获得生命周期信息类Lifecycle Fragment和Activity都已经实现了该接口 Lifecycle Registry 生命周期注册器 可以提交生命周…

栈板识别的思考

0.啰嗦几句 最近公司又变动了&#xff0c;所以又做了一个关于视觉的项目。简单说就是栈板定位&#xff0c;主要应用在AGV叉车上&#xff0c;当然这一套流程基本适用于所有的视觉项目。主要是看算法的设计和一些人为的经验。 1.结果图 可以看到在图像上3个托盘都分割出来了&am…

青少年机器人技术一级核心知识点:机械结构及模型(三)

随着科技的不断进步&#xff0c;机器人技术已经成为了一个重要的领域。在这个领域中&#xff0c;机械结构是机器人设计中至关重要的一部分&#xff0c;它决定了机器人的形态、运动方式和工作效率。对于青少年机器人爱好者来说&#xff0c;了解机械结构的基础知识&#xff0c;掌…

2024考研408-计算机组成原理第七章-输入输出系统学习笔记

文章目录 前言一、IO系统基本概念1.1、输入/输出系统基本概念1.1.1、现代计算机的结构1.1.2、常见的I/O设备1.1.3、主机与I/O设备如何进行交互&#xff1f;&#xff08;认识I/O接口&#xff09;1.1.4、I/O系统的基本组成&#xff08;I/O硬件、I/O软件&#xff09;本节回顾 1.2、…

标配8155,智驾延续「高低配」,小鹏G6能否挽回颜面?

对于小鹏汽车来说&#xff0c;G6就是最后的尊严。 高工智能汽车研究院监测数据显示&#xff0c;2023年1-5月&#xff0c;小鹏汽车交付量为3.22万辆&#xff0c;同比上年同期下滑39.81%&#xff0c;是「蔚小理」三家新势力中唯一下滑的一家。 去年上市的G9&#xff08;何小鹏口中…

基于声音信号的工业设备异常检测

异常检测主要目标是将异常事件与正常事件区分开来&#xff0c;因此才有了“异常”一词。本文将介绍基于声音信号的工业机械异常检测&#xff0c;使用的数据集是MIMII声音数据集&#xff0c;该数据集很容易在网上获得。 异常检测的任务可以通过多种方式实现。其中最简单的一种方…

Hadoop基础——HDFS知识点梳理

HDFS基础知识 1. 介绍一下HDFS组成架构&#xff1f; 组成部分&#xff1a; HDFS Client,NameNode,DataNodeSecondary NameNode( HA模式下是 StandBy NameNode) Client: 客户端 文件切分&#xff0c;文件上传HDFS时&#xff0c;client将文件切分成一个一个的block&#xff0…

玩转中文AI模型攻略——ModaHub魔搭社区攻略

目录 1. 注册和登录&#xff1a; 2. 浏览和搜索&#xff1a; 3. ModaHub排行榜&#xff1a; 4. AI应用导航&#xff1a; 5. 向量数据库&#xff1a; 6. 企业Chatbot&#xff1a; ModaHub魔搭社区是一个中文AI模型开源社区&#xff0c;旨在为开发者和研究者提供一个交流、…

抓住出海中东热潮,茄子科技(海外SHAREit Group)有效助力游戏企业出海

近年来&#xff0c;随着国际形势的紧张&#xff0c;不少中国出海企业在海外市场营收受到了不同程度的影响。为摆脱这一困境&#xff0c;大家开始将目光瞄准了海外新兴市场&#xff0c;其中中东以其高速的增长&#xff0c;量利双收的回报赢得了不少中国出海企业的青睐。 与此同…

FastDDS源码剖析:源码结构分析

include: 包含Fast-DDS的头文件。这些头文件定义了库使用的公共API和数据结构。 src: 包含Fast-DDS库的源代码文件。这包括各种组件的实现&#xff0c;例如发布者、订阅者、主题和RTPS协议。 cpp: c实现Fast-DDS的主要源代码。 pcp -fastdds: Fast-DDS公共API的实现。 rtps: …