单周期CPU设计

这篇具有很好参考价值的文章主要介绍了单周期CPU设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 设计要求

  1. 设计一个基于mips指令集子集的单周期cpu。
  2. 子集指令如下:

addu,subu,add,and,or,slt,addi,addiu,andi,ori,lui ,lw,sw,beq,j,jal,jr。

  1. 所有指令都不考虑溢出。
  2. 最终实现的单周期处理器能够通过Modelsim功能仿真。
  • 设计说明
  1. 单周期处理器由 datapath(数据通路)和 controller(控制器)组成。
    1. 数据通路由如下 module 组成:pc(程序计数器)、gpr (通用寄存器组)、alu(算术逻辑单元)、im(指令存储器)、dm(数据存储器)等。
    1. im:容量为4KB(32bit×1024 字)。
    1. dm:容量为 4KB(32bit×1024 字)。
  2. 如下是供你参考的数据通路示意图。

单周期CPU设计
Figure1 数据通路参考图

  1. clock上升沿有效;reset低电平有效,异步复位;控制信号高电平有效。
  2. reset信号有效时,复位pc寄存器为0x0000_3000
  3. 整个 project 必须采用模块化设计。

单周期CPU设计

  1. 每个 module 由一个独立的 Verilog HDL 文件组成。
  2. 所有mux模块(包括不同位数、不同端口数等)都建模在一个mux.v中。
  3. 为使得代码更加清晰可读,建议多使用宏定义,并将宏定义组织在header.v中。
  4. ctrl.v文件中定义控制模块。
  5. s_cycle_cpu.v定义顶层模块。
  6. code.txt文本文件是需要加载到指令存储器中的机器代码。
  • 模块定义要求
  1. 模块定义必须满足下表中的要求。
  2. 特别注意:im模块的输入pc为32位,但指令存储器只有4kB大小,所以取指令时只取pc的低12位作为地址。

不直接用32位pc值作为指令存储器地址的原因是mars工具设置的代码段的起始地址是0x0000_3000,但是仿真的时候存储器不能定义太大,否则仿真速度会很慢。所以取pc的低12位作为指令地址,这样CPU就是从指令存储器的地址0开始运行。(当然是在你的程序大小不超过4kB的前提下)

文件

模块定义要求

s_cycle_cpu.v

//顶层模块

module s_cycle_cpu(clock,reset);

input clock;  //时钟信号

input reset;  //复位信号

pc.v

//pc模块

module pc(pc,clock,reset,npc);

output [31:0] pc;  //当前指令地址

input clock;

input reset;

input [31:0] npc;  //下条指令地址

im.v

//指令存储器

module im(instruction,pc);

output [31:0] instruction;

input [31:0] pc;

//指令存储器只有4k大小,所以pc12位地址有效(屏蔽掉高位)

reg [31:0] ins_memory[1023:0]; //4kB指令存储器

gpr.v

//通用寄存器

module gpr(a,b,clock,reg_write,num_write,rs,rt,data_write);

output [31:0] a;  //寄存器1的值

output [31:0] b;  //寄存器2的值

input clock;

input reg_write;  //写使能信号

input [4:0] rs; //读寄存器1编号

input [4:0] rt; //读寄存器2编号

input [4:0] num_write; //写寄存器编号

input [31:0] data_write; //写数据

//32个寄存器

reg [31:0] gp_registers[31:0];

dm.v

//数据存储器

module dm(data_out,clock,mem_write,address,data_in);

output [31:0] data_out;

input clock;

input mem_write;

input [31:0] address;

input [31:0] data_in;

//4KB数据存储器

reg [31:0] data_memory[1023:0];

alu.v

//alu模块

module alu(c, a, b);

output [31:0] c;

input [31:0] a, b;

  1. 实验过程
    1. 基本模块
      1. PC模块

1实验思路

       Pc记录当前正在执行的指令的地址,并且能正确在时钟周期上升沿指到下一条指令的地址,所以设计时只需要定义reg,并且在时钟周期上升沿正确赋值即可.

2具体实现

       单周期CPU设计

对模块进行仿真,在时钟周期上升沿,pc正确得到npc结果.

单周期CPU设计

3遇到的问题及解决

注意本模块要求初值位置为00003000h,正确赋初值即可.    

2. IM模块

1实验思路

本模块需要定义一个指令存储器,并且能根据输入的pc地址正确查找到指令.设计时,只需要根据pc的地址,正确输出指令内容即可.

2具体实现

单周期CPU设计

3遇到的问题及解决

注意pc的位宽为32位,故地址的后两位永远是零,即四个字节为一个单位.

3. GPR模块

1实验思路

       Gpr模块需要定义一个寄存器堆,该寄存器堆需要两个读出数据的端口,故需要两个数据地址的输入,还要能够实现数据写入,即需要数据 , 地址 , 写使能的输入信号,并且要求该模块能根据这些信号正确的读写. 设计时,需要根据读写信号正确读写即可.

2具体实现

       单周期CPU设计

对GPR进行仿真,观察波形图,在正确的写入下,陈宫根据rs,rt 读出了相应的值.

单周期CPU设计

3遇到的问题及解决

       在设计之初,使用了initial语句实现对零号寄存器的写操作,并且在后面通过判断决定不能再向0号寄存器内部写入数据 .

单周期CPU设计

然而 后来学习得知,这种写法是无法综合的,故应该更换写法,在输出时判断,如果是零号,就直接输出零.

4实验反思及思考

       在写实例模块时,不能使用initial语句,该语句只能在testbench中使用.

4. ALU模块

1实验思路

       该模块需要根据不同的alu_op操作码的值,确定不同的操作,并且正确计算,得出结果.

2具体实现

       单周期CPU设计

经过仿真,可以得出正确的加法结果 c = a + i ;

单周期CPU设计

3遇到的问题及解决

       在该模块的编写过程中,

1.曾把无符号指令和有符号指令分开书写,后来学习得知,这样会综合出两个加法器,会增加电路复杂度,所以应该统一有符号和无符号的器件,只是在特殊标识位有区别.

2.曾不理解slt的作用,而不知道从何下手,后来上网查询了指令功能后,的值需要使用减法器来判断,相减后判断正负即可判断大小.

4实验反思及思考

       要注意具体仿真出的电路的简洁性,写出优的代码.2.要注意对不同的功能进行聚类,统一写出一个模块,减少电路仿真量.

​​​​​​​5. dm模块

1实验思路

       该模块需要定义内存(即数据存储器),并且能正确进行读写操作. 编写时,只需要根据输入的地址和写使能信号正确读写,并输出结果即可.

2具体实现

       单周期CPU设计

3遇到的问题及解决

       注意pc的大小是4字节,需要忽视掉地址后两位即可.

4实验反思及思考

       该模块和寄存器类似,正确赋值即可.

    1. 能够执行addu指令的单周期CPU

1实验思路

       初步只需要实现一个指令,故不需要太多的控制信号,只要建立正确的完整的数据通路即可.书写时,根据老师给出的数据通路,对每一条数据线进行定义,并且正确定义每个模块,并且将线接正确.

2具体实现

       单周期CPU设计

单周期CPU设计

3遇到的问题及解决

1.实验时,reg_write这种定值的线不知道该如何接,最初先定义了一个寄存器,然后将寄存器接入.最后得知可以直接接入定值线,后来接入后可以正确运行. (调试过程仅在J指令时说明)

2.实验时,遇到过接口类型不对应的报错,发生错误的原因是线宽度定义错误或者缺失该线的定义,应该在一开始就注意避免这样的错误,先定义后使用.

4实验反思及思考

       在具体的实例化过程中,如果使用位置对应进行接线,就需要按照一定的规律,以防止自己接线接乱.比如,严格按照前面输出信号,后面定义输入信号,并且对具体的线的定义要有意义,这样在接线时才能知晓自己在接哪里.​​​​​​​

6. 能够执行R型指令的单周期CPU

1实验思路

       要想增加R型指令,只需要增加一条aluop控制信号即可.目前为止,控制信号还很少,控制模块还很好写. 书写控制模块,需要根据instruction的op字段和funct字段确定执行的具体操作.

2具体实现

Ctrl单元:

       单周期CPU设计

顶层模块接线:(仅增加一个ctrl单元)

       单周期CPU设计

3遇到的问题及解决

在该模块的编写过程中,1.曾把无符号指令和有符号指令分开书写,后来学习得知,这样会综合出两个加法器,会增加电路复杂度,所以应该统一有符号和无符号的器件,只是在特殊标识位有区别. (调试过程仅在J指令时说明)

4实验反思及思考

       1.接线时要先定义后使用.

2.使用位置关联进行接线,要明确每根线的意义,防止接错.

3.对ctrl单元的分类要精细.

  1. 添加I型指令

1实验思路

实现I型指令时,就需要用到立即数字段.由于立即数在指令中位宽不够,则需要进行扩展,所以要写一个扩展单元,该单元要根据输入的扩展控制信号确定是符号扩展还是零扩展. 2.由于指令变成了I型指令,则输入地址字段变成了rt字段,故需要一个选择器判断regfile的写寄存器地址是rs还是rt.同样,此时出现了立即数直接相加,因此ALU的另一个端口b也需要加一个选择器判断是经过扩展的立即数还是直接从寄存器里读出的值.

增加了这三个元器件,控制信号又需要三个,因此还要根据指令的op字段确定指令类型,从而细分这些控制信号的值.

2具体实现

1.扩展器

单周期CPU设计

2.顶层模块新加的定义:(图片贴出了最终版本)

单周期CPU设计

3.控制模块新加的判断语句: (图片贴出了最终版本)

单周期CPU设计

3遇到的问题及解决

       1.实验过程中,发现线接错,后来重接. (调试过程仅在J指令时说明)

       2.随着控制信号的增多,如何分类成了一个难题,通过回忆数字逻辑相关知识,经过分析,发现不同指令之间的区别,比如R与I的区分只需要判断op==5’h00即可.仅使用了几个选择器就将指令大体分类完成.

4实验反思及思考

​​​​​​​2. 添加MEM型指令

1实验思路

       增加MEM指令需要增加一个数据存储器,并且在读出数据存储器时加一个选择器判断是alu的输出还是数据存储器的输出.

因此还需要增加一个控制信号来控制数据读出端口.

2具体实现

       1.顶层模块:

单周期CPU设计

       2.ctrl单元:

单周期CPU设计

3遇到的问题及解决

       1.在该模块,遇到读出和写入不正确,后来调试发现控制信号不对,最后改正(调试过程仅在J指令时说明)

4实验反思及思考

       1.随着控制信号的增多,对不同的分类要明确细致.

       2.在分出新的类别时,要把旧的已存在的控制信号定义清楚.否则延续旧的控制信号值可能导致出错.

       3.随着数据线的增多,接线要明确意义,防止混乱.

​​​​​​​3. 添加J型指令

1实验思路

       按照新的指令要求,需要更改alu能输出zero信号.还要增加几个选择器来判断.数据的组合可以直接用线来完成.具体实现如下:

2具体实现

       1.alu的增加:

       单周期CPU设计

       2.过程中使用的{}的定义:

       单周期CPU设计

单周期CPU设计

3.顶层模块的增加:

单周期CPU设计

4.控制模块的增加:

单周期CPU设计

5.控制模块的总体分类方式:

单周期CPU设计

3遇到的问题及解决

       实验中,总是遇到仿真到一半直接跳转到最后的情况,反复排查后发现还是自己的控制信号有问题.

       排查过程:

              1.使用mars单步执行指令,判断寄存器情况;

单周期CPU设计

2.使用Modelsim仿真cpu,一个一个周期看哪个信号线出错,

单周期CPU设计

3.最后发现指令总是在3028h的位置直接跳转到304c(应该是302c),观察mars发现是beq指令,故判断是s_npc选择了错误的端口,是控制信号写错导致.最后更改,正确.

单周期CPU设计

单周期CPU设计

4.经过调试,最后得到正确的仿真结果.

单周期CPU设计

单周期CPU设计

最终版数据流图:

单周期CPU设计

  1. 实验总结

1.实验过程中,经常犯一些低级错误,原因是对verilog 的语法不熟悉,写出错误代码(比如把组合逻辑块写入时序逻辑内,此时还需要额外定义reg , 在非tb的模块中使用initial语句等)通过实验强化了自己的编码能力.

2. 随着控制信号的增多,对不同的分类要明确细致.在分出新的类别时,要把旧的已存在的控制信号定义清楚.否则延续旧的控制信号值可能导致出错.

3. 随着数据线的增多,接线要明确意义,防止混乱.

4.实验伊始,还不知mars的具体功能和modelsim 可以看具体的寄存器值,可以看定义的每根线的值,后来经过老师的讲解和与同学的讨论,学会了这两个辅助工具的绝妙用处.mars单步执行具体观察寄存器值和执行过程,modelsim将时间设置为100ns,单步执行,具体观察线的值和寄存器的值,判断出错位置. 通过学习这些软件的使用,大大加快了我差错的速度和编写的能力.

项目源码

TODO文章来源地址https://www.toymoban.com/news/detail-443697.html

到了这里,关于单周期CPU设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【基于FPGA的芯片设计】RISC-V的20条指令CPU设计

    实验板卡 :xc7a100tlc sg324-2L,共20个开关 实验要求:          

    2024年02月16日
    浏览(51)
  • MIPS指令集单周期CPU兼Verilog学习

            (1)取指,PC+4         (2)译码         (3)取操作数,ALU运算         (4)访存(MEM)         (5)写回(RegWr)         将每一级操作抽象为CPU中的若干个模块:                 (1)指令读取模块(指令存储器)                 (2)指令寄存器(

    2023年04月24日
    浏览(43)
  • 计组高分笔记:【05】中央处理器 「CPU细节 | 取指周期 | 间址周期 | 执行周期 | 中断周期 | 数据通路 | 硬布线控制器 | 微程序控制器 | 指令流水线 | LOAD | STORE」

    CPU由 运算器 和 控制器 组成。 注意:n位CPU,指机器字长为n,表示一次能够处理的二进制位数。自然与数据总线相等 1.1.1 运算器的基本组成 功能:对数据进行加工 通用寄存器组 :如AX、BX、CX、DX、SP等,用于存放操作数(包括源操作数、目的操作数及中间结果)和各种地址

    2024年02月11日
    浏览(43)
  • 单周期CPU设计

    设计一个基于mips指令集子集的单周期cpu。 子集指令如下: addu,subu,add,and,or,slt,addi,addiu,andi,ori,lui ,lw,sw,beq,j,jal,jr。 所有指令都不考虑溢出。 最终实现的单周期处理器能够通过Modelsim功能仿真。 设计说明 单周期处理器由 datapath(数据通路)和 controller(控制

    2024年02月04日
    浏览(45)
  • 计算机组成原理实验——五、单周期CPU设计

    掌握指令执行过程的5个阶段 掌握每条指令的数据通路选择 掌握译码器和控制器的功能和实现 掌握数据输入输出处理的方法 实现risc-v中RV32I指令的单周期CPU 利用实现的risc-v CPU实现平方数 实现risc-v中37条RV32I指令的单周期 cpu; 完成1后在该cpu上实现斐波那契数。 rom dataRAM ins文

    2024年02月11日
    浏览(43)
  • 定长指令周期---时序发生器FSM设计

    定长指令周期—时序发生器FSM设计 实验目的 帮助学生理解传统三级时序系统中时序发生器的基本原理,学生能设计定长指令周期的时序发生器状态机以及输出函数。 实验内容 利用数字逻辑电路相关知识设计定长指令周期的三级时序系统,时序发生器包括状态机和输出函数两

    2024年02月12日
    浏览(43)
  • 【计算机硬件系统设计(华科)——单周期MIPS CPU(Logisim 实现)】

    本章继续讲述计算机硬件系统设计的内容,之前已经大概说明了 ALU 和存储系统的设计,本文讲述CPU的设计。对应的有单周期、多周期 CPU 设计,以及流水线设计,中断处理会在后文中详细说明,本文不进行讲述。 即定长指令周期,机器性能取决于最慢的指令,导致时钟周期

    2024年02月02日
    浏览(53)
  • 什么?要求设计一个循环队列?

    🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯C语言初阶 🍔🍟🌯C语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介::讲解用c语言实现数据结构的循环队列. 先声明一下: 题目来源:力扣(LeetCode) 题目名称: 设计循环队列 :题目链接 难度: 中等 介绍: 设计你的

    2024年02月07日
    浏览(36)
  • 【FPGA】设计一个简单CPU—Verlog实现

    目录 设计成果 CPU的简单介绍 CPU设计思路 Verlog实现 仿真验证 小结 先展示一下成果,目前的CPU设计较为简单,后续会加以优化。连接有指令存储器和数据存储器的CPU综合电路图如图1.1 图1.1(CPU综合电路图)   要设计一款简单的CPU,首先,我们要了解一个CPU的结构组成和工作

    2024年02月04日
    浏览(29)
  • 计算机组成原理3个实验-logisim实现“七段数码管”、“有限状态机控制的8*8位乘法器”、“单周期MIPS CPU设计”。

    目录 标题1.首先是七段数码管   标题二:有限状态机控制的8*8位乘法器 标题三:单周期MIPS CPU设计 1看一下实验要求:    2.接下来就是详细设计: 1. 组合逻辑设计        由于7段数码管由7个发光的数码管构成,因为我们想用二进制将0-9这几个数字表示出来。所以他需要

    2024年01月17日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包