• 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(没验证写入加法结果成功,但肯定是成功的(确信))。

  • 相关阅读:
    【原创】kafka consumer源代码分析
    【原创】kafka server源代码分析(二)
    【原创】kafka server源代码分析(一)
    【原创】kafka controller源代码分析(二)
    棋盘格检测
    人脸三维建模A Morphable Model For The Synthesis Of 3D Faces(三维人脸合成的变形模型)
    汉字识别关键技术与应用
    城市研究中的常见数据类型及其应用场景
    OpenCV Sift源码分析
    OpenCV feature2d
  • 原文地址:https://www.cnblogs.com/yanying7/p/14009250.html
Copyright © 2020-2023  润新知