计算机组成原理实验——寄存器堆


寄存器

寄存器是中央处理器内的组成部分
寄存器是有限存贮容量的高速存贮部件
用来暂存指令、数据和地址

寄存器堆

MIPS指令需要32个寄存器,采用寄存器-寄存器结构
需要用数组表示寄存器堆
寄存器堆需要有两个数据输出接口,同时输出;一个输入接口

0号寄存器不保存数据,固定为0【用来完成一些简单指令


raddr1读地址
若raddr=00111,则rdata1写入7号寄存器的数据

写四个要求
1 waddr哪个寄存器
2 wdata数据
3 clk等脉冲上升沿
4 WE读写信号高电平

寄存器堆接口

1
2
3
4
5
6
7
8
9
10
11
module registers(
    input clk,
    input oc,   //可不要
    input [4:0] raddr1,
    input [4:0] raddr2,
    input [4:0] waddr,
    input [31:0] wdata,
    input we,   //使能端,读写信号
    output reg[31:0] rdata1,
    output reg[31:0] rdata2
    );

reg[32:0]每个寄存器32位
regts[1:31]去掉0号寄存器,0号寄存器只能存放数据0
寄存器堆(32个,32位)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//读端口1读端口2用两个独立的always模块来实现
//读端口1
always @(*) //组合逻辑电路,只要有输入马上就有输出
begin
    if(oc==1'b1)    //禁止输出
    begin
        radata1<=32'bz;
    end
    else if(raddr1==5'b00000)   //$0号寄存器只保存0
    begin
        rdata1<=32'b0;
    end
    else
    begin
        rdata1<=regts[raddr1]
    end
    end

//读端口2

//写端口
always @(posedge clk) //脉冲信号作用下才能写
begin
    if((we==1'b1)&&(waddr!=5'b00000))   //判断使能端是否为1,是否为0号地址,0号不可写
    begin
        regts[waddr]<=wdata;
    end
end

ALU&&寄存器堆

寄存器堆rdata1接ALU a端口,寄存器堆rdata2接ALU b端口
ALU输出f端口接寄存器堆wdata端口
在这里插入图片描述

reg(…out)输出端口与alu(a…)输入端口位数一致
wire[3:0]w, //声明wire电线连接,两两之间
reg r(…w),
alu a(w…),
fib整体框架图
在这里插入图片描述
操作确定:加法
默认:WE=1
初始除了0号寄存器其他寄存器均为空
通过写端口写入数据
rada1 rdata2数据来自寄存器

有限状态机fsm
always@(posedge clk)//时钟脉冲的作用下
if(reset)//复位信号有效,直接跳转到初始状况

else case(state)
STATE1: … //指出每个状态执行完跳转到哪个状态
STATE1: …

default:state <= STATE1;
endcase
在这里插入图片描述
fib&fsm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//申请状态
wire [31:0] a, b ,f;
reg [31:0] wdata;
wire we = 1'b1;
parameter op = 4'b0001; //加法运算
reg [4:0] ra1,ra2,wa;
reg [3:0] count;

//实例化寄存器
registers myregs(.clk(clk),.oc(~rst),.raddr1(ra1),.raddr2(ra2),.waddr(wa),.wda(wdata),.we(we),.rdata1(a),.rdata2(b));
//实例化ALU
alu myalu(a, b, op, f); //a b与rdata1(a),rdata2(b)连接
assign result = wdata;

reg[1:0]status = 2'b00; //状态
always@(posedge clk)
begin
    if(rst == 1'b0) //复位信号
    begin
        status <= 2'b00;    //初始化为0
        count <= 3; //从3开始算
    end else
    2’b00:
        begin
            ra1 <= 5'b1;
            ra2 <= 5'b10;
            wa <= 5'b1; //1号寄存器
            wdata <= 32'b1; //1写入1号寄存器
            status <= 2'b01;    //跳转到下一状态
        end
    2’b01:
        begin
            wa <= 5'b10;
            wdata <= 32'b1;
            status <= 2'b10;
        end
    2'b10:
        begin
            wa <= ra2+1;
            wdata <= f;
            status <= 2'b11;
            count <= count + 1;
        end
    2'b11:
        begin
            if(count < n)
            begin
                ra1 <= ra2;     //ra1=ra1+1
                ra2 <= wa;      //ra2=ra2+1
                status <= 2'b10;
            end
        end