【verilog】单周期MIPS CPU设计

xiaoxiao2021-02-28  34

博客地址转至https://xisynotz.xyz

 

 

 

一、    实验要求

设计一个单周期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就轻而易举。

需要注意的是,在实例化的时候各个对应的接口较为繁杂,应当注意不要出错,命名简单易懂。

 

 

转载请注明原文地址: https://www.6miu.com/read-2500230.html

最新回复(0)