寄存器
8位环形移位寄存器
module shift_regist (
input wire clk,
input wire rstn,
input wire [7:0]D,
output reg [7:0]Q
);
always @(posedge clk or negedge rstn) begin
if(!rstn)
Q<=8'b000000;
else
Q<={D[6:0],D[7]} ;
end
endmodule //shift_regist
输入有时钟,复位,D信号,输出为处理后的信号
左移,环形,首尾相连
正常工作的语句,把最高位移到了最低位,其余整体往往前移了一位
右移
寄存器堆
该寄存器堆是CPU中多个寄存器组成的阵列,由32个32位的寄存器构成,两个读数据口(Ra->BusA Rb->BusB),一个写数据口(Rw ->BusW),写数据受使能信号Wen控制,在时钟的下降沿有效
第一种实现方法,代码如下
module D_FF(
input clk,
input [4:0]Ra,
input [4:0]Rb,
input [4:0]Rw,
input Wen,
output [31:0]BusA,
output [31:0]BusB,
input [31:0]BusW
);
reg [31:0]DataReg[31:0];
always@(negedge clk)
begin
if(Wen & Rw!=5'd0)
DataReg[Rw] <= BusW;
end
assign BusA = (Ra==5'd0)?32'd0:DataReg[Ra];
assign BusB = (Ra==5'd0)?32'd0:DataReg[Rb];
endmodule
clk时钟信号,ra,rb是两个端口的读信号,rw是选择写入的寄存器编号,wen决定是读还是写,BUSA,BUSB是两个端口输出的32信号,BUSW是写入的32位信号
由于有32个寄存器,所以需要5位二进制来记录编号
datareg就是系统建的寄存器,用来寄存数据,前面的【31:0】表示有32个,后面的【31:0】表示每个寄存器记录为32位
电路功能是当是写信号时,执行写操作,无论写不写,都会执行读,只不过如果没有指定地址,就不输出读的结果,可以同时输出两个口的数据
仿真文件
`timescale 1ns/1ns
`define clk_period 20
module D_FF_tb;
reg clk;
reg rst_n;
reg [4:0] Ra;
reg [4:0] Rb;
reg [4:0] Rw;
reg Wen;
reg [31:0] BusW;
wire [31:0] BusA;
wire [31:0] BusB;
D_FF D_FF(
.clk(clk),
.rst_n(rst_n),
.Ra(Ra),
.Rb(Rb),
.Rw(Rw),
.Wen(Wen),
.BusW(BusW),
.BusA(BusA),
.BusB(BusB)
);
integer i,j,k;
initial clk = 1'b0;
always #(`clk_period/2)clk = ~clk;
initial begin
rst_n = 1'b0;
Ra = 5'b0;
Rb = 5'b0;
Rw = 5'b0;
Wen = 1'b0;
#5;
rst_n = 1'b1;
Wen = 1'b1;
for (j = 1 ; j < 32; j = j + 1) begin
Rw = j;
BusW = j;
#50;
end
Wen = 1'b0;
#5;
for (i = 1 ; i < 32; i = i + 1) begin
Ra = i;
#5;
end
#5;
for (k = 1 ; k < 32; k = k + 1) begin
Rb = k;
#5;
end
#5;
$stop;
end
endmodule