Vivado——寄存器堆设计实验

(实验环境:Vivado 2017.4)

实验要求:

 

 

 

 

实验过程:

1.打开Vivado,创建文件,选择xc7a35tcpg236-1核。

 

 2.添加源文件。

ALU模块:

 

module ALU(OP,A,B,F,CF

    );
    parameter SIZE = 32;//运算位数
        input [3:0] OP;//运算操作
        input [SIZE-1:0] A;//左运算数
        input [SIZE-1:0] B;//右运算数
        output [SIZE-1:0] F;//运算结果
        output       CF; //进位标志位
       reg [SIZE-1:0] F;
        reg C,CF;//C为最高位进位
        always@(*)
        begin
            C=0;
            case(OP)
                4'b0000:begin F=A&B; end    //按位与
                4'b0001:begin F=A|B; end    //按位或
                4'b0010:begin F=A^B; end    //按位异或
                4'b0011:begin F=~(A|B); end //按位或非
                4'b0100:begin {C,F}=A+B; end //加法
                4'b0101:begin {C,F}=A-B; end //减法
                  4'b0110:begin F=A<B; end//A<B则F=1,否则F=0            
                 4'b0111:begin F=B<<A; end   //将B左移A位
            endcase
            CF = C; 
        end

endmodule

 

 

 

Regester_File模块:

 

module Regester_File(
Clk,Write_Reg,R_Addr_A,R_Addr_B,W_Addr,W_Data,R_Data_A,R_Data_B
);
    parameter ADDR = 5;//寄存器编码/地址位宽
    parameter NUMB = 1<<ADDR;//寄存器个数
    parameter SIZE = 32;//寄存器数据位宽
    input Clk;//写入时钟信号
    input Write_Reg;//写控制信号
    input [ADDR-1:0]R_Addr_A;//A端口读寄存器地址
    input [ADDR-1:0]R_Addr_B;//B端口读寄存器地址
    input [ADDR-1:0]W_Addr;//写寄存器地址
    input [SIZE-1:0]W_Data;//写入数据
    output [SIZE-1:0]R_Data_A;//A端口读出数据
    output [SIZE-1:0]R_Data_B;//B端口读出数据
    reg [SIZE-1:0]REG_Files[0:NUMB-1];//寄存器堆本体
    integer i;//用于遍历NUMB个寄存器
    initial//初始化NUMB个寄存器,全为0
        for(i=0;i<NUMB;i=i+1) 
            REG_Files[i]<=i;
    always@(posedge Clk )//时钟信号或清零信号上升沿
    begin
        if(Write_Reg) 
            REG_Files[W_Addr]<=W_Data; 
    end        //读操作没有使能或时钟信号控制, 使用数据流建模(组合逻辑电路,读不需要时钟控制)
    assign R_Data_A=REG_Files[R_Addr_A];
    assign R_Data_B=REG_Files[R_Addr_B]; 
endmodule

 

 

 

顶层模块:

 

module top(
Clk,Write_Reg,Write_Select,//控制信号       
 R_Addr_A,R_Addr_B,W_Addr,//读写地址        
R_Data_A,R_Data_B,        
 OP,CF,ALU_F//ALU运算
  ,W_Data );
        parameter ADDR = 5;
        parameter SIZE = 32;
        input Clk;
        input Write_Reg;//写控制信号
        input [ADDR-1:0]R_Addr_A;//A读端口寄存器地址
        input [ADDR-1:0]R_Addr_B;//B读端口寄存器地址
        input [ADDR-1:0]W_Addr;//写寄存器地址
        
        output [SIZE-1:0]R_Data_A;//A端口读出数据
        output [SIZE-1:0]R_Data_B;//B端口读出数据      
        input [3:0] OP;    
        output CF;
        output [SIZE-1:0] ALU_F;//运算结果F
        input wire Write_Select;//写入数据选择信号
        wire [SIZE-1:0]ALU_F;
        output  reg [SIZE-1:0]W_Data;
        always@(*)
               begin
                  case (Write_Select)
                  1'b0: W_Data=ALU_F;
                  1'b1: W_Data=32'b101;
                  endcase
               end
        Regester_File RF_Test(        //输入        
        .Clk(Clk),//时钟信号        
        .Write_Reg(Write_Reg),//写入控制        
        .R_Addr_A(R_Addr_A),//A端口读地址       
        .R_Addr_B(R_Addr_B),//B端口读地址        
        .W_Addr(W_Addr),//写入地址       
        .W_Data(W_Data),        
        .R_Data_A(R_Data_A),//A端口读出数据        
        .R_Data_B(R_Data_B)//B端口读出数据    
    );              //实例化ALU模块    
     
     ALU ALU_Test(    //输入        
     .OP(OP),//运算符                
     .A(R_Data_A),//从寄存器读A操作数       
     .B(R_Data_B),//从寄存器读B操作数       
     .F(ALU_F),    
     .CF(CF)        
    );
  
 endmodule

 

 

 

测试模块:

 

module test(

    );
    reg  Clk, Write_Reg;
    reg Write_Select;    
    reg [4:0] R_Addr_A ,R_Addr_B, W_Addr;      
    reg [3:0] OP;   
    wire [31:0] R_Data_A, R_Data_B, ALU_F;    
    wire CF;    
    wire [31:0]  W_Data;
initial
    begin
        Write_Reg=1;
        R_Addr_A=5'b01001;
        R_Addr_B=5'b01010;
        OP=4'b0100;
        Write_Select=1;
        W_Addr=5'b01001;Clk=0;#50; Clk=1;#50;
        W_Addr=5'b01010;Clk=0;#50; Clk=1;#50;
        W_Addr=5'b01000;
        Write_Select=0;Clk=0;#50;Clk=1;#50;
    end
        top RF_Test(
            .Clk(Clk),
            .Write_Reg(Write_Reg), 
            .Write_Select(Write_Select),
            .R_Addr_A(R_Addr_A),
            .R_Addr_B(R_Addr_B), 
            .W_Addr(W_Addr), 
            .R_Data_A(R_Data_A),
            .R_Data_B(R_Data_B),
            .OP(OP),
            .CF(CF), 
            .ALU_F(ALU_F),
            .W_Data(W_Data)
         
        );

endmodule

 

2.本实验采取仿真验证,直接进行仿真。(其实是懒得上板了)

 

 3.观察仿真结果。

 

 可以看到,在寄存器$9($t1)和$10($t2)都存储了5,说明写入存储器值成功;而busW(W_Data)为10,说明加法执行成功;此时W_Addr为$8(没验证写入加法结果成功,但肯定是成功的(确信))。

 

posted @ 2020-11-20 09:30  yanying  阅读(3093)  评论(0编辑  收藏  举报