设计示例2寄存器堆设计
移位寄存器的设计方法
移位寄存器的设计方法下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。
文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!移位寄存器是一种重要的数字电路组件,用于实现数据的移位操作。
实验内容寄存器堆(RegisterFile)ra0,rd0;ra1,rd1
• 检查下载测试是否正确
• 检查代码设计,代码是否独立完成
2019-3-28
2019春_计算机组成原理实验_CS-USTC
3
实验报告
• 内容包括但不限于:逻辑设计(数据通路和状态 图)、核心代码、仿真/下载结果、结果分析、实 验总结、意见/建议等,附设计和仿真代码
• 实验检查后一周内提交实验报告
2019春_计算机组成原理实验_CS-USTC
2
实验要求和检查
• 完成1和3的的逻辑设计、仿真和下载测试
– 逻辑设计采用模块化设计 – 仿真3时忽略display – 下载测试时,时钟采用板载100MHz时钟,其他输入
由拨动开关和按钮开关设置,结果输出至LED指示灯 或7段数码管
• 查看1和2的电路性能和资源使用情况
rst
FIFO
16
display
4
out empty
- out, in:出/入队列数据
clk
full
- full, empty:队列空/满, 空/满时忽略出/入队操作
- display:8个数码管的控 制信号,显示队列状态
.
1. 2 3 2. 3
复位 数据1, 2, 3依次入队 列
数据1出队列
2019-3-28
– ftp://202.38.79.134/ 相应文件夹 – 文件名格式:Labn_学号_姓名.pdf (其中n为第几次
实验,不满足该格式的视为未提交实验报告)
• 严禁抄袭,否则作零分处理
2019-3-28
2019春_计算机组成原理实验_CS-USTC
4
The End
2019-3-28
2019春_计算机组成原理实验_CS-USTC
杭电计组实验-寄存器堆设计实验
杭电计组实验-寄存器堆设计实验————————————————————————————————作者:————————————————————————————————日期:实验报告2018 年 5 月12 日成绩:姓名阳光男学号班级专业计算机科学与技术课程名称《计算机组成原理与系统结构试验》任课老师张翔老师指导老师张翔老师机位号默认实验序号 4 实验名称《实验四寄存器堆设计》实验时间2018/5/12 实验地点1教211 实验设备号个人电脑、Nexys3开发板一、实验程序源代码1.寄存器堆模块代码:module Register_);input [4:0]R_Addr_A;input [4:0]R_Addr_B;input [4:0]W_Addr;input Write_Reg;input [31:0]W_Data;input Clk;input Reset;output [31:0]R_Data_A;output [31:0]R_Data_B;reg [31:0]REG_Files[0:31];reg [5:0]i;initial//仿真过程中的初始化beginfor(i=0;i<=31;i=i+1)REG_Files[i]=0;endassign R_Data_A=REG_Files[R_Addr_A]; assign R_Data_B=REG_Files[R_Addr_B]; always@(posedge Clk or posedge Reset)beginif(Reset)for(i=0;i<=31;i=i+1)REG_Files[i]=0;elseif(Write_Reg&&W_Addr!=0)REG_Files[W_Addr]=W_Data;endendmodule2.顶层电路模块代码:module Top_Register_);input [4:0]Addr;input [1:0]C1;//C1选择32位数据输出哪八位字节input Write_Reg,C2,Clk,Reset;//C2选择读A/B端口的数据output reg [7:0]LED;wire [31:0]R_Data_A,R_Data_B;reg [31:0]W_Data;reg[4:0] A,B;Register_(A,B,Addr,Write_Reg,W_Data,Clk,Reset,R_Data_A,R_Data_B); always@(Addr or Write_Reg or C1 or C2 or R_Data_A or R_Data_B) beginA=0;B=0;LED=0;W_Data=0;if(!Write_Reg)//读操作Write_Reg=0beginif(!C2)beginA=Addr;case(C1)2'b00:LED=R_Data_A[7:0];2'b01:LED=R_Data_A[15:8];2'b10:LED=R_Data_A[23:16];2'b11:LED=R_Data_A[31:24];endcaseendelsebeginB=Addr;case(C1)2'b00:LED=R_Data_B[7:0];2'b01:LED=R_Data_B[15:8];2'b10:LED=R_Data_B[23:16];2'b11:LED=R_Data_B[31:24];endcaseendendelse//写操作begincase(C1)2'b00:W_Data=32'h0000_0003;2'b01:W_Data=32'h0000_0607;2'b10:W_Data=32'hFFFF_FFFF;2'b11:W_Data=32'h1111_1234;endcaseendendendmodule3.测试代码module test;// Inputsreg [4:0] R_Addr_A;reg [4:0] R_Addr_B;reg [4:0] W_Addr;reg Write_Reg;reg [31:0] W_Data;reg Clk;reg Reset;// Outputswire [31:0] R_Data_A;wire [31:0] R_Data_B;// Instantiate the Unit Under Test (UUT) Register_ (.R_Addr_A(R_Addr_A),.R_Addr_B(R_Addr_B),.W_Addr(W_Addr),.Write_Reg(Write_Reg),.W_Data(W_Data),.Clk(Clk),.Reset(Reset),.R_Data_A(R_Data_A),.R_Data_B(R_Data_B));initial begin// Initialize InputsR_Addr_A = 0;R_Addr_B = 0;W_Addr = 0;Write_Reg = 0;W_Data = 0;Clk = 0;Reset = 0;// Wait 100 ns for global reset to finish #100;// Add stimulus here#100;R_Addr_A = 0;R_Addr_B = 0;W_Addr = 5'b00001; Write_Reg = 1;W_Data = 32'h1111_1111; Clk = 1;Reset = 0;#100;R_Addr_A = 0;R_Addr_B = 0;W_Addr = 5'b00001; Write_Reg = 1;W_Data = 32'h1111_1111; Clk = 0;Reset = 0;#100;R_Addr_A = 0;R_Addr_B = 0;W_Addr = 5'b00010; Write_Reg = 1;W_Data = 32'h2222_2222; Clk = 1;Reset = 0;#100;R_Addr_A = 5'b00001;R_Addr_B = 5'b00010;W_Addr = 0;Write_Reg = 0;W_Data = 0;Clk = 0;Reset = 0;#100;R_Addr_A = 5'b00001;R_Addr_B = 5'b00010;W_Addr = 0;Write_Reg = 0;W_Data = 0;Clk = 0;Reset = 1;endendmodule二、仿真波形三、电路图顶层电路模块顶层电路内部结构:四、引脚配置(约束文件)NET "Clk" LOC = C9;NET "Reset" LOC = D9;NET "Write_Reg" LOC = T5;NET "C2" LOC = C4;# PlanAhead Generated physical constraintsNET "LED[7]" LOC = T11;NET "LED[6]" LOC = R11;NET "LED[4]" LOC = M11;NET "LED[3]" LOC = V15;NET "LED[1]" LOC = V16;NET "LED[0]" LOC = U16;NET "LED[2]" LOC = U15;NET "LED[5]" LOC = N11;NET "Addr[0]" LOC = T10;NET "Addr[2]" LOC = V9;NET "Addr[3]" LOC = M8;NET "Addr[4]" LOC = N8;NET "C1[0]" LOC = U8;NET "C1[1]" LOC = V8;NET "Addr[1]" LOC = T9;五、思考与探索(1)实验四实验结果记录表寄存器地址写入数据读出数据$1 32'h0000_0003 32'h0000_0003$2 32'h0000_0607 32'h0000_0607$3 32'hFFFF_FFFF 32'hFFFF_FFFF $4 32'h1111_1234 32'h1111_1234$5 32'h0000_0003 32'h0000_0003$6 32'h0000_0607 32'h0000_0607$7 32'hFFFF_FFFF 32'hFFFF_FFFF $8 32'h1111_1234 32'h1111_1234。
计算机体系结构 实验报告2 华东理工大学
实验名称多通路运算器和寄存器堆实验地点信息楼420实验日期2012-12-7一、实验目的1.了解多通路的运算器与寄存器堆的组成结构。
2.掌握多通路的运算器与寄存器堆的工作原理及设计方法。
二、实验设备PC 机一台, TD-CMX 实验系统一套。
三、实验原理1.ALU® 单元的结构ALU®单元由运算器和双端口寄存器堆构成,通过不同的控制信号SEL1、SEL0 产生不同结构的运算器。
运算器内部含有三个独立运算部件,分别为算术、逻辑和移位运算部件,要处理的数据存于暂存器A 和暂存器B。
SEL0 和SEL1 用于选择运算器和寄存器堆的通路:(1)当SEL1=0、SEL0=0,ALU 的输出D7…D0、REG(右口)的输出OUT7…OUT0 和ALU与REG 的输入IN7…IN0 接到CPU 内总线上时,如图1-2-1 所示,寄存器堆只能从右口进行操作,相当于只有一组控制线的单端口寄存器堆,一般计算机组成原理实验涉及到的运算器和寄存器就是采用这种结构。
(2)当SEL1=1、SEL0=0,REG(右口)的输出OUT7…OUT0 和ALU 与REG(右口)的输入IN7…IN0 接到CPU 内总线上时,运算器和双端口寄存器堆的结构如图1-2-2 所示,寄存器堆由两组控制信号来分别进行控制,每组控制信号都可以相对独立的对寄存器堆进行读写操作,同时增加了执行专用通道A 总线,以利于提高指令执行的效率。
(3)当SEL1=1、SEL0=1,REG(右口)的输出OUT7…OUT0 和ALU 与REG(右口)的输入IN7…IN0 接到CPU 内总线上时,运算器和双端口寄存器堆的结构如图1-2-3 所示,在双通道双端口运算器和寄存器堆的基础上增加了暂存器旁路,把运算结果写回到寄存器堆的同时也可以写到暂存器A、暂存器B 中。
由于在运算型指令中把运算的结果写到通用寄存器中的指令很多,占运算型指令的大多数,发生通用寄存器数据相关的概率相当高,因此,可以用硬件设置专用路径来解决这种通用寄存器数据相关问题。
杭电计算机组成原理寄存器堆设计实验
杭电计算机组成原理寄存器堆设计实验计算机组成原理是计算机科学与技术的基础课程之一,它涉及到计算机的基本组成部分和原理。
在这门课程中,学生通常需要进行一系列的实验来加深对计算机组成原理的理解和应用。
其中之一是关于寄存器堆的设计实验。
寄存器堆是计算机中重要的组成部分之一,它用于存储、读取和写入数据。
在计算机中,数据通常被存储在寄存器中,然后进行各种操作。
因此,设计一个高效可靠的寄存器堆对于计算机的性能至关重要。
根据实验要求,我们需要设计一个8位的寄存器堆,并实现读取、写入和清零等操作。
以下是针对该实验的设计思路和实施步骤。
首先,我们需要确定寄存器堆的结构。
由于该寄存器堆为8位宽度,我们选择使用一个8x8的存储单元阵列。
每个存储单元都可以存储一个8位的数据。
整个寄存器堆由8个存储单元组成,每个存储单元对应一个地址,即0~7接下来,我们需要设计寄存器堆的读写电路。
对于读操作,我们需要通过地址线来选择要读取的存储单元,并将其输出到数据线。
对于写操作,我们同样需要通过地址线来选择要写入的存储单元,并将数据线上的数据写入该存储单元。
为了实现这些操作,我们需要使用多路选择器和数据解码器。
在设计中,我们还需要考虑到时钟信号的输入,以确保读写操作在时钟的上升沿或下降沿进行。
此外,我们还需要添加清零功能,以便将寄存器堆的值重置为零。
为实现清零功能,我们可以将一个额外的输入线与所有存储单元的清零输入连接。
在实施阶段,我们需要使用Verilog或其他硬件描述语言来实现设计。
在代码中,我们首先声明一个8位宽的存储单元阵列作为寄存器堆的基本组成部分。
然后,我们定义读写电路,包括地址线、数据线、多路选择器和数据解码器。
最后,我们添加时钟信号和清零功能。
在完成设计后,我们可以通过仿真工具进行验证。
通过输入不同的数据和地址,观察输出结果是否符合预期。
如果存在问题,我们可以进行调试并进行必要的修改。
一旦仿真结果正确无误,我们就可以开始进行硬件实验了。
一种高速低功耗多端口寄存器堆的设计
2 电路 结构
如 图 1所示 , 电路 主要 分为 地址 锁存 译码 、 存储 阵 列 、 写 时序控 制和 灵敏 放大 几部 分 . 储 阵列为 读 存 3 ×3 2 2个 存储单 元 , 每个 单 元有 1写 8读 9个独 立 端 口, 个读 端 口都 有 各 自的地 址 锁 存 译 码 和灵 敏 每 放 大 电路 . 了加 快读 出速 度 , 为 我们 使用 了双位 线差 分 读 出的办 法 . 线预 充 电至 . 位
关 键 词 :高 速 ;低 功耗 ;多 端 口 ;S RAM ;寄 存 器 堆
EEACC : 25 D ; 1 5D 70 26
中 图 分 类 号 :T 3 N4 2
文献 标 识 码 :A
文 章 编 号 :05 —1 7 2 0 )40 1 .5 2 34 7 (0 7 0 —6 40
1 引 言
们 用 S C 0 1 F 工 艺实 现 了一 个 读 写均 采 用 低 MI . 8 m 摆 幅位线 的 1写 8读 3 2×3 bt 2 i 大小 的寄存 器堆口 . ] 高速 和低 功 耗 是 多端 口寄存 器 堆 的设 计 目标 , 两者 相互制 约 . 寄存器 堆 电路 的 功耗主要 来 自: 址 地 译码 电 路 、 储 阵 列 、 敏 放 大 器 和 外 围 接 口电 存 灵 路_ . 3 延时主 要来 自译码 电路和 灵敏 放大 器 . ] 电路 模 拟表 明 , 译码 电路 延 时约 占总 延 时 的 5 % , 敏 放 0 灵 大器 延时约 占总延 时 的 3 %L . 以采 用多 种 办 法 0 5 可 ] 减小 功耗和 延时 , 比如在 地址 译 码 电 路 中使 用 S L C (o rec u ldlgc 电路 提 高 工 作 速 度 ; 用 su c o pe i) o 使
寄存器堆的设计
寄存器堆设计1、功能概述:MIPS指令格式中的寄存器号是5bits,指令可以访问25=32个32位的寄存器。
这样的一堆寄存器“堆在一起”构成一个寄存器堆(Register File)。
2、接口说明:寄存器堆模块接口信号说明表脉冲regfile_clk,复位端regfiles_rst,写使能端regfiles_Wen,写地址regfile_Waddr,写数据regfiles_Wdata,读地址一regfiles_Raddr_1,读地址二regfiles_Raddr_2,读数据一regfiles_Rdata_1,读数据二regfiles_Rdata_2;设计思路:1、复位处理是利用标志位flag实现的,当复位时,flag=0;利用i来计数,当i<31时,flag都等于0;直到i=32,复位完成,flag=1,这时,才可以进行写操作。
2、当复位时,需要32个脉冲才能将寄存器全部复位。
复位未完成,flag一直等于0。
若复位未完成时,进行写操作,这时,并不能写进去,便出错了。
所以,进行32分频,当寄存器可以写入时,复位已完成。
3、设计电路源代码//----32个32位寄存器堆module regfile(input regfile_clk, //脉冲input regfile_rst, //复位端input regfile_Wen, //写使能端input [4:0] regfile_Raddr_1,//读地址一input [4:0] regfile_Raddr_2,//读地址二input [4:0] regfile_Waddr, //写地址input [31:0] regfile_Wdata, //写数据output [31:0] regfile_Rdata_1,//读数据一output [31:0] regfile_Rdata_2//读数据二);//----------------------------------reg [31:0]regfiles[0:31]; //实现寄存功能reg [4:0] i; //实现flag的变换reg flag; //实现复位的标志reg regfile_clk_1; //实现写数据的脉冲reg [4:0]count;//---32分频处理always@(posedge regfile_c lk or posedge regfile_rst) beginif(regfile_rst)begincount<=5'd0;regfile_clk_1<=1'b0;endelse if(count<5'd16)begincount<=count+1'b1;endelsebegincount<=5'd0;regfile_clk_1<=~regfile_clk_1;endend//---复位处理always@(posedge regfile_c lk or posedge regfile_rst) beginif(regfile_rst)begini<=5'd0;flag<=1'b0;endelse if(i<5'b11111)begini<=i+1'b1;flag<=1'b0;endelseflag<=1'b1;end//---写操作always@(posedge regfile_c lk_1)beginif(~flag)regfiles[i]<=32'd0;elsebeginif(regfile_Wen&&(regfile_Waddr!=5'd0)) //写使能端为一,写地址不为零beginregfiles[regfile_Waddr]<=regfile_Wdata; //写入endendend//---读操作assign regfile_Rdata_1=(regfile_Raddr_1==5'd0)?32'd0:regfiles[regfile_Raddr_1];assign regfile_Rdata_2=(regfile_Raddr_2==5'd0)?32'd0:regfiles[regfile_Raddr_2];////----------------------------------------endmodule4、设计电路仿真所设计的指令存储器模块电路,采用ISE仿真器工具进行了设计仿真验证,验证结果表明存储器功能以及接口时序完全正确,如下是仿真验证的波形图。
RISC-V单周期处理器设计(寄存器堆设计)(三)
RISC-V单周期处理器设计(寄存器堆设计)(三)⼀、寄存器堆介绍对于RISC-V基础指令集中共包含32个通⽤寄存器(x0~x31)。
寄存器堆可以说是整个cpu的核⼼,我们可以回想RISC-V指令集,⼏乎所有类型的指令都要与寄存器打交道的(个⼈理解)。
注意:x0默认为0x00000000,是⼀个只读寄存器。
⼆、寄存器堆功能上图是⼀个寄存器module,我可以如果先不思考寄存器内部如何实现,只是把寄存器堆想成⼀个⿊匣⼦,我们可以思考它到底要⼲什么那?我个⼈理解,寄存器堆实际上就是在系统时钟的控制下,从寄存器堆中对于位置读取数据,或者向对应位置写⼊数据。
如果这样理解的话我们就可以思考出⼀个寄存器堆都需要什么信号了。
1.系统时钟,复位信号(这个相信⼤家都理解)2.读写地址信号。
既然要向寄存器堆中读写数据,⽽⼀个寄存器堆共有32个寄存器,怎么确定要读写那个寄存器呀?事实上每个寄存器在寄存器堆中都有对应的地址,我们只需要给出地址,就可以找到对应地址。
(为啥为5位地址:32个寄存器,如果要表⽰就要⽤5位⼆进制数来表⽰)3.读写数据信号。
如果上⾯这个地址信号理解了,那么寄存器堆已经知道了要读写的地址,那么这个地址到底要写⼊啥,或者读出了什么,则⼀定需要有信号表⽰读出的数据或者写⼊的数据。
4.是否写信号。
如果对RISC-V指令系统了解的清楚的话,我们就知道有些类型数指令需要向寄存器堆中写⼊数据(如:I型 R型),⽽有些类型指令则不需要向寄存器堆中写⼊数据(如:S型)。
因此⼀定需要⼀个信号来⾼速寄存器堆是否读写。
具体如下:可以看到输⼊信号有:时钟,复位,rs1,rs2,rd,wen,busw ⽽输出信号则是:从对应寄存器中读出的数据:BusA,BusB。
三、verilog代码实现module RegFile(input clk,input rstn,input [4:0]Rs1, //第⼀个寄存器地址input [4:0]Rs2, //第⼆个寄存器地址input [4:0]Rd, //写⼊的寄存器地址input Wen, //控制信号output [31:0]BusA, //输出第⼀个寄存器中的值output [31:0]BusB, //输出第⼆个寄存器中的值input [31:0]BusW //写个的寄存器的值);reg [31:0]DataReg[31:0]; //定义出来这个寄存器reg [31:0]BusA1,BusB1; //输出的中间变量reg [31:0]Waddr;always@(Rd)begincase(Rd)5'b00000 : Waddr=32'h0000_0001;5'b00001 : Waddr=32'h0000_0002;5'b00010 : Waddr=32'h0000_0004;5'b00011 : Waddr=32'h0000_0008;5'b00100 : Waddr=32'h0000_0010;5'b00101 : Waddr=32'h0000_0020;5'b00110 : Waddr=32'h0000_0040;5'b00111 : Waddr=32'h0000_0080;5'b01000 : Waddr=32'h0000_0100;5'b01001 : Waddr=32'h0000_0200;5'b01010 : Waddr=32'h0000_0400;5'b01011 : Waddr=32'h0000_0800;5'b01100 : Waddr=32'h0000_1000;5'b01101 : Waddr=32'h0000_2000;5'b01110 : Waddr=32'h0000_4000;5'b01111 : Waddr=32'h0000_8000;5'b10000 : Waddr=32'h0001_0000;5'b10001 :Waddr=32'h0002_0000;5'b10010 : Waddr=32'h0004_0000;5'b10011 : Waddr=32'h0008_0000;5'b10100 : Waddr=32'h0010_0000;5'b10101 : Waddr=32'h0020_0000;5'b10110 : Waddr=32'h0040_0000;5'b10111 : Waddr=32'h0080_0000;5'b11000 : Waddr=32'h0100_0000;5'b11001 : Waddr=32'h0200_0000;5'b11010 : Waddr=32'h0400_0000;5'b11011 : Waddr=32'h0800_0000;5'b11100 : Waddr=32'h1000_0000;5'b11101 : Waddr=32'h2000_0000;5'b11110 : Waddr=32'h4000_0000;5'b11111 : Waddr=32'h8000_0000;endcaseendelse if(W_en[0]==1'b1) DataReg[0]<=32'd0; else DataReg[0]<=32'd0;//向第2个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[1]<=32'd0;else if(W_en[1]==1'b1) DataReg[1]<=BusW; else DataReg[1]<=DataReg[1];//向第3个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[2]<=32'h7fff_fff0;else if(W_en[2]==1'b1) DataReg[2]<=BusW; else DataReg[2]<=DataReg[2];//向第4个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[3]<=32'h1000_0000;else if(W_en[3]==1'b1) DataReg[3]<=BusW; else DataReg[3]<=DataReg[3];//向第5个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[4]<=32'd0;else if(W_en[4]==1'b1) DataReg[4]<=BusW; else DataReg[4]<=DataReg[4];//向第6个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[5]<=32'd0;else if(W_en[5]==1'b1) DataReg[5]<=BusW; else DataReg[5]<=DataReg[5];//向第7个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[6]<=32'd0;else if(W_en[6]==1'b1) DataReg[6]<=BusW; else DataReg[6]<=DataReg[6];//向第8个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[7]<=32'd0;else if(W_en[7]==1'b1) DataReg[7]<=BusW; else DataReg[7]<=DataReg[7];//向第9个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[8]<=32'd0;else if(W_en[8]==1'b1) DataReg[8]<=BusW; else DataReg[8]<=DataReg[8];//向第10个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[9]<=32'd0;else if(W_en[9]==1'b1) DataReg[9]<=BusW; else DataReg[9]<=DataReg[9];//向第11个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[10]<=32'd0;else if(W_en[10]==1'b1) DataReg[10]<=BusW; else DataReg[10]<=DataReg[10];//向第12个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[11]<=32'd0;else if(W_en[11]==1'b1) DataReg[11]<=BusW; else DataReg[11]<=DataReg[11];//向第13个寄存器写⼊else if(W_en[13]==1'b1) DataReg[13]<=BusW; else DataReg[13]<=DataReg[13];//向第15个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[14]<=32'd0;else if(W_en[14]==1'b1) DataReg[14]<=BusW; else DataReg[14]<=DataReg[14];//向第16个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[15]<=32'd0;else if(W_en[15]==1'b1) DataReg[15]<=BusW; else DataReg[15]<=DataReg[15];//向第17个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[16]<=32'd0;else if(W_en[16]==1'b1) DataReg[16]<=BusW; else DataReg[16]<=DataReg[16];//向第18个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[17]<=32'd0;else if(W_en[17]==1'b1) DataReg[17]<=BusW; else DataReg[17]<=DataReg[17];//向第19个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[18]<=32'd0;else if(W_en[18]==1'b1) DataReg[18]<=BusW; else DataReg[18]<=DataReg[18];//向第20个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[19]<=32'd0;else if(W_en[19]==1'b1) DataReg[19]<=BusW; else DataReg[19]<=DataReg[19];//向第21个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[20]<=32'd0;else if(W_en[20]==1'b1) DataReg[20]<=BusW; else DataReg[20]<=DataReg[20];//向第22个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[21]<=32'd0;else if(W_en[21]==1'b1) DataReg[21]<=BusW; else DataReg[21]<=DataReg[21];//向第23个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[22]<=32'd0;else if(W_en[22]==1'b1) DataReg[22]<=BusW; else DataReg[22]<=DataReg[22];//向第24个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[23]<=32'd0;else if(W_en[23]==1'b1) DataReg[23]<=BusW; else DataReg[23]<=DataReg[23];//向第25个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[24]<=32'd0;else if(W_en[24]==1'b1) DataReg[24]<=BusW; else DataReg[24]<=DataReg[24];//向第26个寄存器写⼊else if(W_en[26]==1'b1) DataReg[26]<=BusW; else DataReg[26]<=DataReg[26];//向第28个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[27]<=32'd0;else if(W_en[27]==1'b1) DataReg[27]<=BusW; else DataReg[27]<=DataReg[27];//向第29个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[28]<=32'd0;else if(W_en[28]==1'b1) DataReg[28]<=BusW; else DataReg[28]<=DataReg[28];//向第30个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[29]<=32'd0;else if(W_en[29]==1'b1) DataReg[29]<=BusW; else DataReg[29]<=DataReg[29];//向第31个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[30]<=32'd0;else if(W_en[30]==1'b1) DataReg[30]<=BusW; else DataReg[30]<=DataReg[30];//向第32个寄存器写⼊always@(posedge clk or negedge rstn)if(!rstn) DataReg[31]<=32'd0;else if(W_en[31]==1'b1) DataReg[31]<=BusW; else DataReg[31]<=DataReg[31];//读取寄存器a的值always@(Rs1 or BusW or Rd)begincase(Rs1)5'b00000 : BusA1=DataReg[0];5'b00001 : BusA1=DataReg[1];5'b00010 : BusA1=DataReg[2];5'b00011 : BusA1=DataReg[3];5'b00100 : BusA1=DataReg[4];5'b00101 : BusA1=DataReg[5];5'b00110 : BusA1=DataReg[6];5'b00111 : BusA1=DataReg[7];5'b01000 : BusA1=DataReg[8];5'b01001 : BusA1=DataReg[9];5'b01010 : BusA1=DataReg[10];5'b01011 : BusA1=DataReg[11];5'b01100 : BusA1=DataReg[12];5'b01101 : BusA1=DataReg[13];5'b01110 : BusA1=DataReg[14];5'b01111 : BusA1=DataReg[15];5'b10000 : BusA1=DataReg[16];5'b10001 :BusA1=DataReg[17];5'b10010 : BusA1=DataReg[18];5'b10011 : BusA1=DataReg[19];5'b10100 : BusA1=DataReg[20];5'b10101 : BusA1=DataReg[21];5'b10110 : BusA1=DataReg[22];5'b10111 : BusA1=DataReg[23];5'b11000 : BusA1=DataReg[24];5'b11001 : BusA1=DataReg[25];5'b11101 : BusA1=DataReg[29];5'b11110 : BusA1=DataReg[30];5'b11111 : BusA1=DataReg[31];endcaseendalways@(Rs2 or BusW or Rd)begincase(Rs2)5'b00000 : BusB1=DataReg[0];5'b00001 : BusB1=DataReg[1];5'b00010 : BusB1=DataReg[2];5'b00011 : BusB1=DataReg[3];5'b00100 : BusB1=DataReg[4];5'b00101 : BusB1=DataReg[5];5'b00110 : BusB1=DataReg[6];5'b00111 : BusB1=DataReg[7];5'b01000 : BusB1=DataReg[8];5'b01001 : BusB1=DataReg[9];5'b01010 : BusB1=DataReg[10];5'b01011 : BusB1=DataReg[11];5'b01100 : BusB1=DataReg[12];5'b01101 : BusB1=DataReg[13];5'b01110 : BusB1=DataReg[14];5'b01111 : BusB1=DataReg[15];5'b10000 : BusB1=DataReg[16];5'b10001 :BusB1=DataReg[17];5'b10010 : BusB1=DataReg[18];5'b10011 : BusB1=DataReg[19];5'b10100 : BusB1=DataReg[20];5'b10101 : BusB1=DataReg[21];5'b10110 : BusB1=DataReg[22];5'b10111 : BusB1=DataReg[23];5'b11000 : BusB1=DataReg[24];5'b11001 : BusB1=DataReg[25];5'b11010 : BusB1=DataReg[26];5'b11011 : BusB1=DataReg[27];5'b11100 : BusB1=DataReg[28];5'b11101 : BusB1=DataReg[29];5'b11110 : BusB1=DataReg[30];5'b11111 : BusB1=DataReg[31];endcaseendassign BusA=BusA1;assign BusB=BusB1;endmodule四、总结代码我是把每⼀种情况罗列出来的,当然了其实也是可以使⽤循环的。
设计示例2寄存器堆设计
设计示例2:寄存器堆设计1、 功能概述:MIPS 指令格式中的寄存器号是5bits ,指令可以访问25=32个32位的寄存器。
这样的一堆寄存器“堆在一起”构成一个寄存器堆(Register File )。
模块框图如图1所示:Regfile图1 模块框图2、 结构框图:3、 接口说明:表1: 寄存器堆模块接口信号说明表clk we wdata Valid Validwaddrrst_n图2 寄存器堆写时序框图4、设计电路源代码//功能描述风格寄存器堆的设计module regfile(input clk,input rst_n,//写端口input we, //写使能input[4:0] waddr, //写寄存器下标input[31:0] wdata, //待写入寄存器堆的数据//读端口1input[4:0]raddr1, //读端口1寄存器下标output[31:0] rdata1,//从端口1读出的寄存器堆的数据//读端口2input[4:0]raddr2, //读端口2寄存器下标output[31:0] rdata2 //从端口2读出的寄存器堆的数据);reg[31:0] regs[0:31]; //32个32位寄存器堆//Write operationalways @ (posedge clk or negedge rst_n) beginif(!rst_n) begin:reset_all_registers //将32个寄存器复位为0.integer i;for(i=0;i<32;i=i+1)regs[i] = 32'd0;endelse begin//写寄存器堆有效时,更新寄存器堆中某个寄存器的数据if((we == 1'b1) && (waddr != 5'h0)) beginregs[waddr] <= wdata;endendend//Read port1 operationassign rdata1 = (raddr1 == 5'd0) ? 32'd0 : regs[raddr1];//Read port2 operationassign rdata2 = (raddr2 == 5'd0) ? 32'd0 : regs[raddr2];endmodule//风格2module regfile2(input clk,input rst_n,//写端口input we,input[4:0]waddr,input[31:0] wdata,//读端口1input[4:0]raddr1,output reg[31:0] rdata1,//读端口2input[4:0]raddr2,output reg[31:0] rdata2);reg[31:0] reg0,reg1,reg2,reg3; //Write operationalways @ (posedge clk) beginif(!rst_n) beginreg0 <= 32'd0;reg1 <= 32'd0;reg2 <= 32'd0;reg3 <= 32'd0;endelse beginif(we == 1'b1) begincase(waddr)5'd0: reg0 = wdata;5'd1: reg1 = wdata;5'd2: reg2 = wdata;5'd3: reg3 = wdata;default: ;endcaseendendend//Read port1 operationalways @ (*) begincase(raddr1)5'd0: rdata1 = 32'd0;5'd1: rdata1 = reg1;5'd2: rdata1 = reg2;5'd3: rdata1 = reg3;default: rdata1 = 32'd0;endcaseend//Read port2 operationalways @ (*) begincase(raddr2)5'd0: rdata2 = 32'd0;5'd1: rdata2 = reg1;5'd2: rdata2 = reg2;5'd3: rdata2 = reg3;default: rdata2 = 32'd0;endcaseendendmodule5、设计电路仿真所设计的指令存储器模块电路,采用Modelsim10.1a仿真器工具进行了设计仿真验证,验证结果表明存储器功能以及接口时序完全正确,如下是仿真验证的波形图。
计算机设计与实践——MIPS基本指令
计算机设计与实践——MIPS基本指令MIPS基本指令和寻址⽅式:MIPS是典型的RISC处理器,采⽤32位定长指令字,操作码字段也是固定长度,没有专门的寻址⽅式字段,由指令格式确定各操作数的寻址⽅式。
MIPS指令格式⼀般有三种格式:R-型指令格式I-型指令格式J理指令格式R_Type指指指指31 265bit 6bit OP:操作码rs:第⼀个源操作数寄存器rt: 第⼆个源操作数寄存器(单⽬原数据)rd: 结果寄存器shamt :移位指令的位移量func:指令的具体操作类型特点:R-型指令是RR型指令,其操作码0P字段是特定的000000”,具体操作类型由字段给定。
例如:func= 100000"时,表⽰加法"运算。
R[rd] —R[rs] + R[rt]I_Type 指指指指5bit 5bit 16bit 特点:I-型指令是⽴即数型指令双⽬运算:R[rt] R[rs] (OP) SignExt(imm16)Load指令:funcAddr J R[rs] + SignExt(imm16) M[Addr] J R[rt]J _Type 指令格式3126 256bit特点:J-型指令主要是⽆条件跳转指令,将当前PC 的⾼4位拼上26位⽴即数,后补两个“ 0”, 作为跳转⽬标地址。
R 型指令:定点运算: add / addu , sub / subu , sra , mult/multu , div/divu逻辑运算:and / or / nor , sll / srl⽐较分⽀:beq / bne / slt / sltu跳转指令: jrI 型指令:定点运算: addi / addiu逻辑运算:andi / ori⽐较分⽀:slti / sltiu数据传送: lw / sw/ lhu / sh / lbu / sb / luiJ 型指令:j / jalAddr J R[rs] + SignExt(imm16) R[rt] J M[Addr]Store 指令:计算数据地址(⽴即数要进⾏符号扩展)从存储器中取出数据,装⼊到寄存器中设计模块划分,教学安排1、MIPS格式指令系统设计2、指令存储器设计3、寄存器堆设计4、ALU设计---- 基本算术、逻辑单元的设计32位超前进位加法器的设计32位桶式移位寄存器的设计5、取指令部件的设计6、⽴即数处理单元设计7、单周期处理器设计⼀⼀R型指令的数据通路设计I型指令的数据通路设计Load/Store指令的数据通路设计分⽀指令/转移指令的数据通路设计综合12条指令的完整数据通路设计8、ALU控制单元设计9、主控制单元的设计10、单周期处理器总体验证11、异常和中断处理及其电路实现12、带有异常和中断处理功能的处理器的设计设计⽰例1指令存储器设计1指令存储器模块定义:指令存储器⽤于存放 CPU 运算的程序指令和数据等,采⽤单端⼝存储器设计,设计最⼤为64个存储单元,每个存储单元数据宽度为32bit 。
数字电路与逻辑设计2寄存器移位寄存器
并行读出脉冲必须在经过5个移存脉冲后出 现,而且和移存脉冲出现旳时间错开。
D5
D4
D3
D2
D1
&
&
&
&
&
并行读出指令
串行输 入 1D
11001
CI
1D Q1
CI
1D Q2
CI
1D Q3
CI
1D
Q4
Q5
CI
移存脉冲CP
分析:假设串行输入旳数码为10011(左边先入)
串—并行转换状态表
序号 Q1 Q2 Q3 Q4 Q5
工作过程: ①在开启脉冲和时钟CP作用下,执行并
行置入功能。片ⅡQ3=DI6。 ②开启脉冲消失,在CP作用下,因为标志位0
旳存在,使门G1输出为1,使得SH/LD =1,执行右移移位寄存功能。 ③后来在移存脉冲作用,并行输入数据由片Ⅱ旳 Q3逐位串行输出,同步又不断地将片Ⅰ旳串 行输入端J,K=1旳数据移位寄存到寄存器。
末级输出反相后,接到串行输入端。
Q3Q2Q1Q0
1
0000
0001
0011
0111
∧
Q0Q 1Q2Q 3
CP D SR
74194
S0
1
S1
0
RD D 0 D 1 D2 D 3 D SL
1000
1100
1110
1111
0010
0101
1011
0110
清零
1001 0100
1010
1101
移位寄存器构成旳移位计数器
异步清零 同步置数
高位向低位移动(左移) 低位向高位移动(右移)
保持
3 、用集成移位寄存器实现任意模值 旳计数分频
寄存器的设计与仿真实验
寄存器的设计与仿真实验在计算机科学与工程领域中,寄存器被广泛用于存储和处理数据。
寄存器是一个用于暂时存储和传输数据的硬件组件,在计算机的指令执行过程中起到关键作用。
本文将探讨寄存器的设计原理与实验仿真。
一、寄存器的基本原理寄存器是计算机的一种具体实现方式,用于存储和传输数据。
它由多个存储单元组成,每个存储单元可以存储一个固定长度的二进制数据。
寄存器以位的形式组织数据,每一位都有其特定的含义和作用。
寄存器的设计原理涉及到以下几个方面:1. 数据宽度:寄存器的数据宽度决定了它能够存储的位数。
常见的寄存器宽度有8位、16位、32位和64位等。
数据宽度的选择需要根据实际应用和计算机系统的需求来确定。
2. 位操作:寄存器可以进行各种位操作,如读取、写入、清零、置位等。
这些操作都是通过电路逻辑门的组合实现的,用于对数据进行处理和控制。
3. 时钟信号:寄存器通过时钟信号来同步数据的读取和写入。
时钟信号保证了数据的稳定传输和正确同步。
4. 输入输出端口:寄存器需要与其他组件进行数据的输入和输出交互。
它可以作为数据的来源或目的地,实现数据的传输与共享。
二、寄存器的设计寄存器的设计是计算机硬件设计中的重要环节。
在设计寄存器时,需要考虑下列因素:1. 数据宽度和寄存器数量:根据计算机系统的需求和性能要求,确定寄存器的数据宽度和数量。
数据宽度的选择需要平衡性能与成本之间的关系。
2. 位操作功能:寄存器的位操作功能需要根据实际应用需求来设计。
常见的位操作功能有读取、写入、清零、置位、移位等。
这些功能需要通过逻辑门电路的组合实现。
3. 时钟信号:寄存器的设计需要考虑时钟信号的生成和分配。
时钟信号的频率和稳定性对寄存器的性能和功耗有重要影响。
4. 输入输出接口:寄存器需要与其他组件进行数据的输入和输出,因此需要设计合适的接口电路。
接口电路需要满足性能、带宽、延迟等方面的要求。
在寄存器的设计过程中,可以使用硬件描述语言(HDL)进行仿真和验证。
寄存器组的设计与实现
寄存器组的设计与实现寄存器组是计算机中的重要组成部分,用于存储和操作数据。
设计和实现一个合适的寄存器组对计算机的性能和功能起着至关重要的作用。
下面将详细介绍寄存器组的设计与实现。
首先,寄存器组的设计应满足以下几个关键要求:1.容量大小:寄存器组的容量应根据计算机的需求来确定,通常以位为单位进行衡量。
较大的容量可以提高计算机的运算能力,但也会增加成本和功耗。
2.位宽度:位宽度指寄存器组中每个寄存器可以存储的位数。
根据计算机的需求,可以选择不同的位宽度,常见的有8位、16位、32位和64位。
较大的位宽度可以提高数据处理速度,但也会增加硬件的复杂性。
3.读写速度:寄存器组应具有足够快的读和写速度,以确保数据的实时性和准确性。
这取决于寄存器组的存储器技术和访问方式。
接下来是寄存器组的实现方式。
常见的寄存器组实现方式有以下几种:1.存储在寄存器文件中:寄存器文件是一种硬件电路,用于存储和操作寄存器。
寄存器文件可以使用静态随机存取存储器(SRAM)或动态随机存取存储器(DRAM)来实现。
它包含多个寄存器,并且可以同时读取和写入多个寄存器。
2.分段寄存器组:在一些计算机架构中,寄存器组被划分为多个段,每个段用于存储不同类型的数据,例如程序计数器、指令寄存器、数据寄存器等。
这种分段寄存器组可以提高计算机的性能和功能。
3.流水线寄存器组:流水线是一种计算机指令执行方式,其中指令被分为多个流水线级别,并依次在各级别上执行。
为了实现流水线执行,需要使用流水线寄存器组来存储每个级别的数据和状态。
流水线寄存器组能够提高计算机的指令执行速度和吞吐量。
此外,寄存器组的实现还要考虑以下几个方面:1.传输方式:寄存器组可以使用并行传输方式或串行传输方式进行数据的读写。
并行传输方式可以提高数据传输速度,但需要更多的硬件资源。
串行传输方式可以减少硬件成本,但速度较慢。
2.控制逻辑:寄存器组的读写操作需要通过控制逻辑进行控制。
控制逻辑可以使用组合逻辑电路或时序逻辑电路来实现。
杭电计组实验4-寄存器堆设计实验
杭电计组实验4-寄存器堆设计实验实验报告2018 年 5 月12 日成绩:一、实验程序源代码1.寄存器堆模块代码:moduleRegister_file(R_Addr_A,R_Addr_B,W_Addr,Write_Reg,W_Data,Clk,Reset,R_Data_A,R_Data_B); input [4:0]R_Addr_A;input [4:0]R_Addr_B;input [4:0]W_Addr;input Write_Reg;input [31:0]W_Data;input Clk;input Reset;output [31:0]R_Data_A;output [31:0]R_Data_B;reg [31:0]REG_Files[0:31];reg [5:0]i;initial//仿真过程中的初始化beginfor(i=0;i<=31;i=i+1)REG_Files[i]=0;endassign R_Data_A=REG_Files[R_Addr_A];assign R_Data_B=REG_Files[R_Addr_B];2'b01:LED=R_Data_A[15:8];2'b10:LED=R_Data_A[23:16];2'b11:LED=R_Data_A[31:24];endcaseendelsebeginB=Addr;case(C1)2'b00:LED=R_Data_B[7:0];2'b01:LED=R_Data_B[15:8];2'b10:LED=R_Data_B[23:16];2'b11:LED=R_Data_B[31:24];endcaseendendelse//写操作begincase(C1)2'b00:W_Data=32'h0000_0003;2'b01:W_Data=32'h0000_0607;2'b10:W_Data=32'hFFFF_FFFF;2'b11:W_Data=32'h1111_1234;endcaseendendendmodule3.测试代码module test;// Inputsreg [4:0] R_Addr_A;reg [4:0] R_Addr_B;reg [4:0] W_Addr;reg Write_Reg;reg [31:0] W_Data;reg Clk;reg Reset;// Outputswire [31:0] R_Data_A;wire [31:0] R_Data_B;// Instantiate the Unit Under Test (UUT) Register_file uut (.R_Addr_A(R_Addr_A),.R_Addr_B(R_Addr_B),.W_Addr(W_Addr),.Write_Reg(Write_Reg),.W_Data(W_Data),.Clk(Clk),.Reset(Reset),.R_Data_A(R_Data_A),.R_Data_B(R_Data_B));initial begin// Initialize InputsR_Addr_A = 0;R_Addr_B = 0;W_Addr = 0;Write_Reg = 0;W_Data = 0;Clk = 0;Reset = 0;// Wait 100 ns for global reset to finish #100;// Add stimulus here#100;R_Addr_A = 0;R_Addr_B = 0;W_Addr = 5'b00001;Write_Reg = 1;W_Data = 32'h1111_1111;Clk = 1;Reset = 0;#100;R_Addr_A = 0;R_Addr_B = 0;W_Addr = 5'b00001; Write_Reg = 1;W_Data = 32'h1111_1111; Clk = 0;Reset = 0;#100;R_Addr_A = 0;R_Addr_B = 0;W_Addr = 5'b00010; Write_Reg = 1;W_Data = 32'h2222_2222; Clk = 1;Reset = 0;#100;R_Addr_A = 5'b00001;R_Addr_B = 5'b00010;W_Addr = 0;Write_Reg = 0;W_Data = 0;Clk = 0;Reset = 0;#100;R_Addr_A = 5'b00001;R_Addr_B = 5'b00010;W_Addr = 0;Write_Reg = 0;W_Data = 0;Clk = 0;Reset = 1;endendmodule二、仿真波形三、电路图顶层电路模块顶层电路内部结构:四、引脚配置(约束文件)NET "Clk" LOC = C9;NET "Reset" LOC = D9;NET "Write_Reg" LOC = T5;NET "C2" LOC = C4;# PlanAhead Generated physical constraintsNET "LED[7]" LOC = T11;NET "LED[6]" LOC = R11;NET "LED[4]" LOC = M11;NET "LED[3]" LOC = V15;NET "LED[1]" LOC = V16;NET "LED[0]" LOC = U16;NET "LED[2]" LOC = U15;NET "LED[5]" LOC = N11;NET "Addr[0]" LOC = T10;NET "Addr[2]" LOC = V9;NET "Addr[3]" LOC = M8;NET "Addr[4]" LOC = N8;NET "C1[0]" LOC = U8;NET "C1[1]" LOC = V8;NET "Addr[1]" LOC = T9;五、思考与探索(1)实验四实验结果记录表寄存器地址写入数据读出数据$1 32'h0000_000332'h0000_0003$2 32'h0000_0607 32'h0000_0607$3 32'hFFFF_FFFF32'hFFFF_FFFF$4 32'h1111_123432'h1111_1234$5 32'h0000_000332'h0000_0003$6 32'h0000_060732'h0000_0607$7 32'hFFFF_FFFF 32'hFFFF_FFFF$8 32'h1111_123432'h1111_1234。
寄存器及寄存器堆设计
input wire [3:0] dp_in, // 4 decimal points output reg [3:0] an, // enable 1‐out‐of‐4 asserted low output reg [7:0] sseg // led segments
);
localparam N = 18; //refreshing rate around 800 Hz (50 MHz/2^16)
3、锁存器
• 锁存器由多个一位锁存器/触发器并联构成
– 一般采用电平控制锁存: – 高电平时置入数据 – 低电平时锁存数据,并指示数据稳定 – 带使能端的RS触发器实现的锁存器
module lock(lock, D, clear, Q); //... assign cr = {8{clear}} | (~D); assign Din = D & (~{8{clear}}); assign lock1 = lock | clear; RS_CE R0(lock1, cr[0], Din[0], Q[0], Qbar[0]), R1(lock1, cr[1], Din[1], Q[1], Qbar[1]), R2(lock1, cr[2], Din[2], Q[2], Qbar[2]), R3(lock1, cr[3], Din[3], Q[3], Qbar[3]), R4(lock1, cr[4], Din[4], Q[4], Qbar[4]), R5(lock1, cr[5], Din[5], Q[5], Qbar[5]), R6(lock1, cr[6], Din[6], Q[6], Qbar[6]), R7(lock1, cr[7], Din[7], Q[7], Qbar[7]); endmodule
寄存器堆的设计
寄存器堆的设计————————————————————————————————作者: ————————————————————————————————日期:寄存器堆设计1、功能概述:MIPS指令格式中的寄存器号是5bits,指令可以访问25=32个32位的寄存器。
这样的一堆寄存器“堆在一起”构成一个寄存器堆(Register File)。
2、接口说明:寄存器堆模块接口信号说明表脉冲reg,复位端reg,写使能端reg,写地址reg,写数据reg,读地址一reg,读地址二reg,读数据一reg,读数据二reg;设计思路:1、复位处理是利用标志位flag实现的,当复位时,flag=0;利用i来计数,当i<31时,flag都等于0;直到i=32,复位完成,flag=1,这时,才可以进行写操作。
2、当复位时,需要32个脉冲才能将寄存器全部复位。
复位未完成,flag一直等于0。
若复位未完成时,进行写操作,这时,并不能写进去,便出错了。
所以,进行32分频,当寄存器可以写入时,复位已完成。
3、设计电路源代码//----32个32位寄存器堆moduleregfile(inputreg, //脉冲input reg, //复位端inputreg,//写使能端input[4:0] reg读地址一input[4:0]reg读地址二input[4:0] reg,//写地址input[31:0]reg,//写数据output[31:0] reg读数据一output [31:0] reg读数据二);//----------------------------------reg[31:0]regfiles[0:31]; //实现寄存功能reg [4:0]i;//实现flag的变换reg flag;//实现复位的标志regreg; //实现写数据的脉冲reg [4:0]count;//---32分频处理always@(posedgereg or posedge reg)beginif(reg)begincount<=5'd0;ﻩreg<=1'b0;ﻩendﻩelse if(count<5'd16)ﻩbeginﻩcount<=count+1'b1;endelseﻩbeginﻩcount<=5'd0;ﻩreg<=~reg;endend//---复位处理always@(posedge reg orposedge reg)beginif(reg)ﻩbegini<=5'd0;ﻩflag<=1'b0;ﻩendﻩelseif(i<5'b11111)beginﻩi<=i+1'b1;flag<=1'b0;endﻩelseflag<=1'b1;ﻩend//---写操作always@(posedgereg)beginif(~flag)ﻩregfiles[i]<=32'd0;elsebeginif(reg(reg'd0)) //写使能端为一,写地址不为零ﻩbeginﻩﻩregfiles[reg]<=reg;//写入ﻩﻩﻩendﻩﻩendend//---读操作assign reg(reg'd0)?32'd0:regfiles[reg];assign reg(reg'd0)?32'd0:regfiles[reg];////----------------------------------------endmodule4、设计电路仿真所设计的指令存储器模块电路,采用ISE仿真器工具进行了设计仿真验证,验证结果表明存储器功能以及接口时序完全正确,如下是仿真验证的波形图。
《计算机组成原理》实验报告——寄存器堆
南通大学信息科学技术学院《计算机组成实验》实验报告实验寄存器堆的设计与实现一、实验目的1.熟悉Vivado软件的使用方法。
2.熟悉寄存器堆的功能。
3.掌握自顶而下的硬件模块设计方法。
4.掌握电路仿真测试方法,掌握仿真激励文件的编写,掌握仿真输出的分析方法。
二、实验任务设计一个寄存器堆,满足两路输出一路输入的功能,并完成仿真测试。
三、实验预习(1)实验电路原理及信号说明寄存器堆(REGFILE)是CPU组成的重要存储部件,也是数据通路中的重要部件,其主要功能是对数据进行存储。
在本实验中将为REGFILE构建32×32的寄存器组,即共有32个寄存器,每个寄存器的位宽都是32位。
32×32的REGFILE逻辑结构如图所示:具体设计如下:通过带有32个带使能端的D触发器实现数据的存储,5-32译码器实现地址与存储单元的连接选择,32位32选1选择器来实现输出。
(2)实验电路设计顶层文件:module REGFILE(Ra,Rb,D,Wr,We,Clk,Clrn,Qa,Qb);input [4:0]Ra,Rb,Wr;input [31:0]D;input We,Clk,Clrn;output [31:0]Qa,Qb;wire [31:0]Y;wire[31:0]Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q 10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0;DEC5T32E dec(Wr,We,Y);REG32reg32(D,Y,Clk,Clrn,Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q 13,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0);MUX32X32select1(Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11 ,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0,Ra,Qa);MUX32X32select2(Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11 ,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0,Rb,Qb);Endmodule5-32地址译码器:module DEC5T32E(I,En,Y);input [4:0] I;input En;output [31:0] Y;reg [31:0] Y;always@(En or I)beginif(En)begincase(I)5'b00000:Y=32'b00000000000000000000000000000001;5'b00001:Y=32'b00000000000000000000000000000010;5'b00010:Y=32'b00000000000000000000000000000100;5'b00011:Y=32'b00000000000000000000000000001000;5'b00100:Y=32'b00000000000000000000000000010000;5'b00101:Y=32'b00000000000000000000000000100000;5'b00110:Y=32'b00000000000000000000000001000000;5'b00111:Y=32'b00000000000000000000000010000000;5'b01000:Y=32'b00000000000000000000000100000000;5'b01001:Y=32'b00000000000000000000001000000000;5'b01010:Y=32'b00000000000000000000010000000000;5'b01011:Y=32'b00000000000000000000100000000000;5'b01100:Y=32'b00000000000000000001000000000000;5'b01101:Y=32'b00000000000000000010000000000000;5'b01110:Y=32'b00000000000000000100000000000000;5'b01111:Y=32'b00000000000000001000000000000000;5'b10000:Y=32'b00000000000000010000000000000000;5'b10001:Y=32'b00000000000000100000000000000000;5'b10010:Y=32'b00000000000001000000000000000000;5'b10011:Y=32'b00000000000010000000000000000000;5'b10100:Y=32'b00000000000100000000000000000000;5'b10101:Y=32'b00000000001000000000000000000000;5'b10110:Y=32'b00000000010000000000000000000000;5'b10111:Y=32'b00000000100000000000000000000000;5'b11000:Y=32'b00000001000000000000000000000000;5'b11001:Y=32'b00000010000000000000000000000000;5'b11010:Y=32'b00000100000000000000000000000000;5'b11011:Y=32'b00001000000000000000000000000000;5'b11100:Y=32'b00010000000000000000000000000000;5'b11101:Y=32'b00100000000000000000000000000000;5'b11110:Y=32'b01000000000000000000000000000000;5'b11111:Y=32'b10000000000000000000000000000000;endcaseendelseY=32'b00000000000000000000000000000000;endendmodule32位寄存器moduleREG32(D,En,Clk,Clrn,Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q1 3,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0);input[31:0]D,En;input Clk,Clrn;output[31:0]Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11 ,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0;wire[31:0]Qn31,Qn30,Qn29,Qn28,Qn27,Qn26,Qn25,Qn24,Qn23,Qn22,Qn21,Qn20,Qn19,Qn18,Qn17,Qn16,Qn15,Qn 14,Qn13,Qn12,Qn11,Qn10,Qn9,Qn8,Qn7,Qn6,Qn5,Qn4,Qn3,Qn2,Qn1,Qn0;D_FFEC32 q31(D,Clk,En[31],Clrn,Q31,Qn31);D_FFEC32 q30(D,Clk,En[30],Clrn,Q30,Qn30);D_FFEC32 q29(D,Clk,En[29],Clrn,Q29,Qn29);D_FFEC32 q28(D,Clk,En[28],Clrn,Q28,Qn28);D_FFEC32 q27(D,Clk,En[27],Clrn,Q27,Qn27);D_FFEC32 q26(D,Clk,En[26],Clrn,Q26,Qn26);D_FFEC32 q25(D,Clk,En[25],Clrn,Q25,Qn25);D_FFEC32 q24(D,Clk,En[24],Clrn,Q24,Qn24);D_FFEC32 q23(D,Clk,En[23],Clrn,Q23,Qn23);D_FFEC32 q22(D,Clk,En[22],Clrn,Q22,Qn22);D_FFEC32 q21(D,Clk,En[21],Clrn,Q21,Qn21);D_FFEC32 q20(D,Clk,En[20],Clrn,Q20,Qn20);D_FFEC32 q19(D,Clk,En[19],Clrn,Q19,Qn19);D_FFEC32 q18(D,Clk,En[18],Clrn,Q18,Qn18);D_FFEC32 q17(D,Clk,En[17],Clrn,Q17,Qn17);D_FFEC32 q16(D,Clk,En[16],Clrn,Q16,Qn16);D_FFEC32 q15(D,Clk,En[15],Clrn,Q15,Qn15);D_FFEC32 q14(D,Clk,En[14],Clrn,Q14,Qn14);D_FFEC32 q13(D,Clk,En[13],Clrn,Q13,Qn13);D_FFEC32 q12(D,Clk,En[12],Clrn,Q12,Qn12);D_FFEC32 q11(D,Clk,En[11],Clrn,Q11,Qn11);D_FFEC32 q10(D,Clk,En[10],Clrn,Q10,Qn10);D_FFEC32 q9(D,Clk,En[9],Clrn,Q9,Qn9);D_FFEC32 q8(D,Clk,En[8],Clrn,Q8,Qn8);D_FFEC32 q7(D,Clk,En[7],Clrn,Q7,Qn7);D_FFEC32 q6(D,Clk,En[6],Clrn,Q6,Qn6);D_FFEC32 q5(D,Clk,En[5],Clrn,Q5,Qn5);D_FFEC32 q4(D,Clk,En[4],Clrn,Q4,Qn4);D_FFEC32 q3(D,Clk,En[3],Clrn,Q3,Qn3);D_FFEC32 q2(D,Clk,En[2],Clrn,Q2,Qn2);D_FFEC32 q1(D,Clk,En[1],Clrn,Q1,Qn1);assign Q0=0;assign Qn0=0;endmodule32位32选1选择器moduleMUX32X32(Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q1 1,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0,S,Y);input[31:0]Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10, Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0;input [4:0]S;output [31:0]Y;function [31:0]select;input[31:0]Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10, Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0;input [4:0]S;case(S)5'b00000:select=Q0;5'b00001:select=Q1;5'b00010:select=Q2;5'b00011:select=Q3;5'b00100:select=Q4;5'b00101:select=Q5;5'b00110:select=Q6;5'b00111:select=Q7;5'b01000:select=Q8;5'b01001:select=Q9;5'b01010:select=Q10;5'b01011:select=Q11;5'b01100:select=Q12;5'b01101:select=Q13;5'b01110:select=Q14;5'b01111:select=Q15;5'b10000:select=Q16;5'b10001:select=Q17;5'b10010:select=Q18;5'b10011:select=Q19;5'b10100:select=Q20;5'b10101:select=Q21;5'b10110:select=Q22;5'b10111:select=Q23;5'b11000:select=Q24;5'b11001:select=Q25;5'b11010:select=Q26;5'b11011:select=Q27;5'b11100:select=Q28;5'b11101:select=Q29;5'b11110:select=Q30;5'b11111:select=Q31;endcaseendfunctionassign Y =select(Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10, Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0,S);endmoduleRTL视图如下:四、实验过程、数据记录与结果分析1.仿真测试文件:module REGFILE_Sim( );// REGFILE Inputsreg [4:0] Ra = 0 ;reg [4:0] Rb = 0 ;reg [4:0] Wr = 0 ;reg [31:0] D = 0 ;reg We = 0 ;reg Clk = 0 ;reg Clrn = 0 ;// REGFILE Outputswire [31:0] Qa ;wire [31:0] Qb ;REGFILE u_REGFILE (.Ra ( Ra [4:0] ),.Rb ( Rb [4:0] ),.Wr ( Wr [4:0] ),.D ( D [31:0] ),.We ( We ),.Clk ( Clk ),.Clrn ( Clrn ),.Qa ( Qa [31:0] ),.Qb ( Qb [31:0] ));initialbeginClk=0;We=0; D=0; Ra=0; Rb=0; Wr=1; Clrn=0;#10;endalways #10 Clk=~Clk;always #20 Ra=Ra+1;always #20 Rb=Rb+1;always #20 Wr=Wr+1;always #20 D=D+1;always #20 We=~We;always #100 Clrn=1;endmodule2.仿真测试结果:3.仿真测试结果分析开始时100ns内,Clrn=0,寄存器堆初始化清零,此期间内写入操作均无效,读出数据均为零。
寄存器的设计
R信号为异步清 CASE CONV_INTEGER(S) IS 零,不考虑CP信号。 WHEN 0 => NULL; --保持 WHEN 1 => IQ <=D; --预置 WHEN 2 => IQ <= DSR & IQ(7 DOWNTO 1); --右移 WHEN 3 => IQ <= IQ(6 DOWNTO 0) & DSL; --左移 WHEN 4 => IQ <= IQ(0) & IQ(7 DOWNTO 1); --循环右移 WHEN 5 => IQ <= IQ(6 DOWNTO 0) & IQ(7); --循环左移 WHEN 6 => IQ <= IQ(7) & IQ(7 DOWNTO 1); --算数右移 WHEN 7 => IQ <= IQ(6 DOWNTO 0) & ‘0’; --算数左移 WHEN OTHERS => NULL; END CASE;
2.环形计数器
例1:用74195构成M=4的环形计数器。
态序表
Q0 Q1 Q2 Q3
SRG4
CT=0 M1[SHIFT] M2[LOAD] C3/1→
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
1 LOAD 启动 CP J K 1 0 0 0
注意:
1,3J
1,3K 2,3D 2,3D
(1)电路除了有效计数循环 外,还有五个无效循环。
?
1
1
0
1
解决的办法: 在 4个移位脉冲的作用下 ,依次送入数码。
左移寄存器: 先送高位,后送低位。 右移寄存器: 先送低位,后送高位。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
设计示例2:寄存器堆设计
1、 功能概述:
MIPS 指令格式中的寄存器号是5bits ,指令可以访问25=32个32位的寄存器。
这样的一堆寄存器“堆在一起”构成一个寄存器堆(Register File )。
模块框图如图1所示:
Regfile
图1 模块框图
2、 结构框图:
3、 接口说明:
表1: 寄存器堆模块接口信号说明表
clk we wdata Valid Valid
waddr
rst_n
图2 寄存器堆写时序框图
4、设计电路源代码
//功能描述风格寄存器堆的设计
module regfile(
input clk,
input rst_n,
//写端口
input we, //写使能
input[4:0] waddr, //写寄存器下标
input[31:0] wdata, //待写入寄存器堆的数据
//读端口1
input[4:0]raddr1, //读端口1寄存器下标
output[31:0] rdata1,//从端口1读出的寄存器堆的数据
//读端口2
input[4:0]raddr2, //读端口2寄存器下标
output[31:0] rdata2 //从端口2读出的寄存器堆的数据);
reg[31:0] regs[0:31]; //32个32位寄存器堆
//Write operation
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin:reset_all_registers //将32个寄存器复位为0.
integer i;
for(i=0;i<32;i=i+1)
regs[i] = 32'd0;
end
else begin
//写寄存器堆有效时,更新寄存器堆中某个寄存器的数据
if((we == 1'b1) && (waddr != 5'h0)) begin
regs[waddr] <= wdata;
end
end
end
//Read port1 operation
assign rdata1 = (raddr1 == 5'd0) ? 32'd0 : regs[raddr1];
//Read port2 operation
assign rdata2 = (raddr2 == 5'd0) ? 32'd0 : regs[raddr2];
endmodule
//风格2
module regfile2(
input clk,
input rst_n,
//写端口
input we,
input[4:0]waddr,
input[31:0] wdata,
//读端口1
input[4:0]raddr1,
output reg[31:0] rdata1,
//读端口2
input[4:0]raddr2,
output reg[31:0] rdata2
);
reg[31:0] reg0,reg1,reg2,reg3; //Write operation
always @ (posedge clk) begin
if(!rst_n) begin
reg0 <= 32'd0;
reg1 <= 32'd0;
reg2 <= 32'd0;
reg3 <= 32'd0;
end
else begin
if(we == 1'b1) begin
case(waddr)
5'd0: reg0 = wdata;
5'd1: reg1 = wdata;
5'd2: reg2 = wdata;
5'd3: reg3 = wdata;
default: ;
endcase
end
end
end
//Read port1 operation
always @ (*) begin
case(raddr1)
5'd0: rdata1 = 32'd0;
5'd1: rdata1 = reg1;
5'd2: rdata1 = reg2;
5'd3: rdata1 = reg3;
default: rdata1 = 32'd0;
endcase
end
//Read port2 operation
always @ (*) begin
case(raddr2)
5'd0: rdata2 = 32'd0;
5'd1: rdata2 = reg1;
5'd2: rdata2 = reg2;
5'd3: rdata2 = reg3;
default: rdata2 = 32'd0;
endcase
end
endmodule
5、设计电路仿真
所设计的指令存储器模块电路,采用Modelsim10.1a仿真器工具进行了设计仿真验证,验证结果表明存储器功能以及接口时序完全正确,如下是仿真验证的波形图。
附件1是仿真激励源代码。
图5 寄存器堆电路读写仿真波形图
6、存在问题及解决方式方法,设计讨论等
问题讨论:
//------结构级与行为级描述的区别?
行为级建模包括系统级、算法级和RTL级,行为描述以过程块为基本组成单位,一个模块的行为描述由一个或多个并行运行的过程块组成。
结构级也称为“门级和开关级”,包含模块实例和基本元件实例。
XXXXXXXXX
YYYY
ZZZZZZZZZZZ
附件1:
`timescale 1ns/1ns
module regfile_tb();
reg clk;
reg rst_n;
reg we;
reg[4:0] waddr,raddr1,raddr2;
reg[31:0] wdata;
wire[31:0] rdata1,rdata2;
//寄存器模块实例化调用
regfile regfile_inst(
.clk(clk),
.rst_n(rst_n),
.we(we),
.waddr(waddr),
.wdata(wdata),
.raddr1(raddr1),
.rdata1(rdata1),
.raddr2(raddr2),
.rdata2(rdata2));
//generate the clock
initial begin
clk = 1'b0;
forever #10 clk = ~clk;
end
reg[5:0] j,k;
initial begin
rst_n = 1'b0;
#20 rst_n = 1'b1;
//
#100 we = 1'b1; waddr = 5'd5; wdata = $random; #20 waddr = 5'd30; wdata = $random;
#20 waddr = 5'd0; wdata = 32'hffff;
//#20 raddr1 = 5'd5; raddr2 = 5'd30;
#20 we= 1'b0; raddr1 = 5'd5; raddr2 = 5'd30;
#20 raddr1 = 5'd0;raddr2 = 5'd0;
//write all 32 registers
#100 we = 1'b1;
for(j=0;j<6'd32;j=j+1)
begin
@(posedge clk) #20 waddr = j; wdata = 31-j;
//wdata = $random;
end
//read all 32 registers
#20 we = 1'b0;
for(k=0;k<6'd32;k=k+1) begin
@(posedge clk) #20 raddr1 = k; raddr2 = 31-k;
end
end
endmodule。