【verilog】單周期MIPS CPU設計


一、    實驗要求

設計一個單周期MIPS CPU,依據給定過的指令集,設計核心的控制信號。依據給定的數據通路和控制單元信號進行設計。

 

二、    實驗內容

1.數據通路設計:mips指令格式只有三種:

1)R類型  從寄存器堆中取出兩個操作數,計算結果寫回寄存器堆

2)I類型  用一個16位的立即數作為一個源操作數

3)J類型  用一個26位的立即數作為跳轉的目標地址

根據以上三種類型可以設計相應的數據通路。基本原理如下

 

下面是實現之后的效果

 

 

2.相應模塊設計

首先明確應該有哪些主要功能模塊

邏輯電路:控制單元,選擇器,ALU,符號位擴展單元,branch加法器等

時序電路:PC寄存器,指令/數據存儲器,寄存器文件

 

 

對應的主要代碼如下:

(1)top模塊對各部分的例化:

 

 

下面是具體的主要模塊的實現

(2)控制單元

module controlunit(

 input [5:0] opcode,

 input [5:0] funct,          //本實驗只考慮add所以暫時用不到這個字段

 

 output reg mem_write,

 output reg mem_toreg,

 output reg branch,

 output reg alu_src,

 output reg reg_dst,

 output reg reg_write,

 output reg [2:0] alu_op,

 output reg jump

 

 );

 

 always@(*)

       case(opcode)

              6'b000000:                        //add

                     begin

                            reg_dst=1;

                            alu_src=0;

                            mem_toreg=0;

                            reg_write=1;

                            mem_write=0;

                            branch=0;

                            alu_op=3'b001;

                            jump=0;

                     end

              6'b001000:                          //addi

                     begin

                            reg_dst=0;

                            alu_src=1;

                            mem_toreg=0;

                            reg_write=1;

                            mem_write=0;

                            branch=0;

                            alu_op=3'b001;

                            jump=0;

                     end

              6'b100011:                        //lw

                     begin

                            reg_dst=0;

                            alu_src=1;

                            mem_toreg=1;

                            reg_write=1;

                            mem_write=0;

                            branch=0;

                            alu_op=3'b001;

                            jump=0;

                     end

              6'b101011:                            //sw

                     begin

                            reg_dst=0;

                            alu_src=1;

                            mem_toreg=0;

                            reg_write=0;

                            mem_write=1;

                            branch=0;

                            alu_op=2'b001;

                            jump=0;

                     end

              6'b000010:                            //jump

                     begin

                            reg_dst=1;

                            alu_src=0;

                            mem_toreg=0;

                            reg_write=0;

                            mem_write=0;

                            branch=1;

                            alu_op=2'b001;

                            jump=1;

                     end

             

              6'b000111:    //bgtz

                     begin

                            reg_dst=1;

                            alu_src=0;

                            mem_toreg=0;

                            reg_write=0;

                            mem_write=0;

                            branch=1;

                            alu_op=2'b001;

                            jump=0;

                     end

                    

                    

              default:

                     begin

                            reg_dst=1;

                            alu_src=0;

                            mem_toreg=0;

                            reg_write=1;

                            mem_write=0;

                            branch=0;

                            alu_op=2'b10;

                     end

       endcase

endmodule

(3)符號位擴展單元

module signextension(num_in,num_out);

 input wire[15:0] num_in;

 output reg[31:0] num_out;

 initial begin

   num_out = 0;

 end

 always @(num_in) begin

      num_out<= {{16{num_in[15]}},num_in[15:0]};

  end

 

endmodule

(4)branch加法器模塊

       這里不進行左移操作,與至指令寄存器的設置相關,本實驗中指令集寄存器每次讀取32位數據,所以不需要像8位那樣進行左移。

 

(5)pc自增模塊

 

(6)選擇器

這里是32位的,還有5位的型號,原理一致較為簡單,此不贅述

 

(7)列一下關於兩個ram的接口

                    

 

(8)ALU,regfile參見前面幾次實驗,這里不作分析

 

 

三、    實驗驗證

1.編寫coe文件

根據實驗的要求以及個人設計的情況,測試代碼如下:

(主要是因為pc寄存器指向的地址是32位而不是8位,所以做了修改,無關算法)

MEMORY_INITIALIZATION_RADIX=16;

MEMORY_INITIALIZATION_VECTOR=

20080000,

200d0014,

8dad0000,

200b0015,

8d6b0000,

200c0015,

8d8c0001,

ad0b0000,

ad0c0001,

21a9fffe,

8d0b0000,

8d0c0001,

016c5020,

ad0a0002,

21080001,

2129ffff,

1d20fff9,

08000011;

 

 

 

測試數據:

MEMORY_INITIALIZATION_RADIX=10;

MEMORY_INITIALIZATION_VECTOR=

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,3,3;

 

 

 

2.仿真測試

這里主要是對pc的跳轉進行分析,發現跳轉無誤,我們進入到ram里觀察執行的情況,下面是dataram:

正好存儲了斐波那契數列的前二十個數,符合要求。

 

四、    分析和總結

本實驗實現了一個單周期mipscpu,實現了addi、add、lw、sw、bgtz、j六條指令。

實驗的關鍵在於弄清楚cpu以及每條指令的數據通路,還有相應的控制信號的具體賦值。

在具體實現的時候,最為重要的的是確保指令的跳轉正確,在此基礎上對各個指令的執行debug就輕而易舉。

需要注意的是,在實例化的時候各個對應的接口較為繁雜,應當注意不要出錯,命名簡單易懂。

 


免責聲明!

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



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