概述
寄存器
寄存器是中央处理器内的组成部分
寄存器是有限存贮容量的高速存贮部件
用来暂存指令、数据和地址
寄存器堆
MIPS指令需要32个寄存器,采用寄存器-寄存器结构
需要用数组表示寄存器堆
寄存器堆需要有两个数据输出接口,同时输出;一个输入接口
0号寄存器不保存数据,固定为0【用来完成一些简单指令
读
raddr1读地址
若raddr=00111,则rdata1写入7号寄存器的数据
写四个要求
1 waddr哪个寄存器
2 wdata数据
3 clk等脉冲上升沿
4 WE读写信号高电平
寄存器堆接口
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 [31:0] rdata1;
reg [31:0] rdata2;
reg [31:0] regts[1:31];
//读端口1读端口2用两个独立的always模块来实现
//读端口1
always @(*) //组合逻辑电路,只要有输入马上就有输出
begin
if(oc==1'b1) //禁止输出
begin
radata1<=32'b0;
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
//申请状态
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
case(status)
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
endcase
最后补充-所有模块代码
//top模块:
module top2(
input clk,
input rst,
input [3:0] n,
output [11:0] result
);
wire [31:0] out;
assign result=out[11:0];
fib1 f(clk,rst,n,out);
initial
$monitor($time,,"top:result=%h",result);
endmodule
//
//fib模块:
module fib1(
input clk,
input rst,
input [3:0] n,
output [31:0] result
);
wire [31:0] a,b,f;
reg [31:0] wdata;
wire we = 1'b1;
reg [4:0] ra1,ra2,wa;
reg [3:0] count;
parameter op = 4'b0001; //加法运算
//实例化寄存器
registers myregs(.clk(clk),.oc(~rst),.raddr1(ra1),.raddr2(ra2),.waddr(wa),.wdata(wdata),.we(we),.rdata1(a),.rdata2(b));
//实例化ALU
alu myalu1(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
case(status)
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
endcase
end
initial
$monitor($time,,"fib:rst=%b,wdata=%h,count=%h",rst,wdata,count);
initial
$monitor($time,,"fib:result=%h",result);
endmodule
//
//alu模块:
module alu(
input [31:0] a,
input [31:0] b,
input [3:0] operation,
output [31:0] f,
output z
);
reg[31:0]result;
always@(*)
begin
case(operation)
4'b0000:result=32'b0;
4'b0001:result=a+b;
4'b0010:result=a-b;
4'b0011:result=a&b;
4'b0100:result=a|b;
4'b0101:result=a^b;
default:result=32'b0;
endcase
end
assign f=result;
assign z=~(|result);
initial
$monitor($time,,"alu:a=%h,b=%h,operation=%b",a,b,operation);
initial
$monitor($time,,"alu:f=%h,z=%b",f,z);
endmodule
//
//registers模块:
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 [31:0] rdata1,
output [31:0] rdata2
);
reg [31:0] rdata1;
reg [31:0] rdata2;
reg [31:0] regts[1:31];
//读端口1
always @(*) //只要有输入就立即输出
begin
if(oc == 1'b1) //禁止输出
begin
rdata1 <= 32'b0;
end
else if(raddr1 == 5'b00000) //$0号寄存器只保存0
begin
rdata1 <= 32'b0;
end
begin
rdata1 <= regts[raddr1];
end
end
//读端口2
always @(*)
begin
if(oc == 1'b1)
begin
rdata2 <= 32'b0;
end
else if(raddr2 == 5'b00000)
begin
rdata2 <= 32'b0;
end
begin
rdata2 <= regts[raddr2];
end
end
always @(posedge clk) //脉冲信号作用下才能写
begin
#1 if((we == 1'b1) &&(waddr != 5'b00000)) //判断使能端是否为1,是否为0号地址,0号寄存器不可写
begin
regts[waddr] <= wdata;
end
end
endmodule
//仿真程序
module fib_sim(
output [11:0] result
);
//parameter clk_period=10;
reg clk;
initial
begin
clk=1'b0;
forever
#2 clk=~clk;
end
reg rst=1'b1;
reg[3:0] n=4'b1111;
top2 t(clk,rst,n,result);
initial
begin
#2 rst=1'b0;
#4 rst=1'b1;
end
endmodule
仿真到179’h即停止的原因是输入n的位数为4位。
最后
以上就是轻松超短裙为你收集整理的计算机组成原理实验——实现寄存器堆模块Verilog的全部内容,希望文章能够帮你解决计算机组成原理实验——实现寄存器堆模块Verilog所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复