一、 實驗要求
設計一個單周期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就輕而易舉。
需要注意的是,在實例化的時候各個對應的接口較為繁雜,應當注意不要出錯,命名簡單易懂。