设计示例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

实验内容寄存器堆(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 华东理工大学

计算机体系结构 实验报告2  华东理工大学

实验名称多通路运算器和寄存器堆实验地点信息楼420实验日期2012-12-7一、实验目的1.了解多通路的运算器与寄存器堆的组成结构。

2.掌握多通路的运算器与寄存器堆的工作原理及设计方法。

二、实验设备PC 机一台, TD-CMX 实验系统一套。

三、实验原理1.ALU&REG 单元的结构ALU&REG单元由运算器和双端口寄存器堆构成,通过不同的控制信号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单周期处理器设计(寄存器堆设计)(三)⼀、寄存器堆介绍对于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四、总结代码我是把每⼀种情况罗列出来的,当然了其实也是可以使⽤循环的。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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。

相关文档
最新文档