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(沒驗證寫入加法結果成功,但肯定是成功的(確信))。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM