10.30寄存器,寄存器堆

寄存器

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

你可能感兴趣的:(数电,单片机,嵌入式硬件)