My title page contents

五级流水线CPU设计Verilog代码VIVADO仿真

名称:五级流水线CPU设计Verilog代码VIVADO仿真

软件:VIVADO

语言:Verilog

代码功能:

五级流水线CPU设计


- 基于FPGA的简单的五级流水线CPU,支持基本的运算,跳转,数据存储与传送等基本指令,解决流水线cpu中的控制相关和数据相关的问题。

- 根据五级流水的五个阶段(取指,译码,执行,执行,访存,写回),将整个cpu分为五个子模块分别编码实现,然后封装在顶层模块里。

- 在五个子模块中又分别对alu(运算模块),cu(控制模块),bru(跳转处理模块)等更小的子模块进行封装。

- 由于流水执行,跳转指令在译码阶段被识别时,下一条指令已经取指开始执行,如不处理,会导致寄存器值被更改,即控制相关问题。采用在跳转指令后插入空指令的方法处理控制相关。

- 下一条指令读寄存器时,前三条指令还未进行写回,如不处理,所读取的内容将不是最新的,即数据相关问题。采用数据前推的方式解决。

- 由于LW指令改写寄存器的写入数据在访存阶段才能确定,因此单纯的数据回推无法解决相关问题,需要在指令后插入一条空指令。为了简化设计,对于所有LW指令,无论是否出现数据相关,均在其后插入空指令。

- 通过汇编工具将指令翻译成二进制数字,然后输入cpu进行仿真。


FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com



设计文档:

计组课程设计实验报告.docx

工程文件

设计原理及代码实现

总体结构

CPU根据五级流水分成五个模块,分别为取指、译码、执行、访存、写回,每条指令执行时,数据依次流经这些模块。五级流水线各阶段的主要工作如下:

取指阶段:从指令存储器读出指令,同时确定下一条指令地址。

译码阶段:对指令进行译码,从通用寄存器中读出要使用的寄存器的值,如果指令中含有立即数,则将立即数进行符号扩展或无符号扩展。如果是转移指令且满足转移条件,那么给出转移目标,作为新的指令地址。

执行阶段:按照译码阶段给出的操作数、运算类型,进行运算,给出运算结果。如果是Load/Store指令,则另需计算出Load/Store的目标地址。

访存阶段:如果是Load/Store指令,那么在此阶段会访问数据存储器,反之,只是将执行阶段的结果向下传递到回写阶段。同时,此阶段还要判断是否有异常需要处理,如果有,那么会清除流水线,然后转移到异常处理例程入口地址处继续执行。

回写阶段:将运算结果保存到目标寄存器。

1 五级流水线CPU模块示意图



    单周期CPU中,当指令位于某一个特定模块(如MES模块)时,其他模块为空闲状态,会造成浪费。因此引入流水线CPU,对某一个特定模块,当正在执行的某一条特定指令位于其他模块时,该模块转而执行其他指令,而不是闲置。

图2 五级流水线CPU实现简图


以下为顶层模块例化代码,目的是对上述五个阶段进行例化。













3 五级流水线CPU总体结构代码实现

主要功能

跳转指令

所有的跳转操作都封装在跳转控制模块bru,下一条指令的地址根据控制单元cu生成的控制信号生成。

4 下一条指令地址示意图


bru模块具体代码实现如下:

图5 bru模块代码实现

控制相关

由于流水执行,跳转指令在译码阶段被识别时,下一条指令已经取指开始执行,如不处理,会导致寄存器值被更改。这一问题被称为控制相关。

可以采用跳转指令后插入空指令的方法处理控制相关。


数据相关

下一条指令读寄存器时,前三条指令还进行写回,如不处理,所读取的内容将不是最新的,这一问题被称为数据相关。采用数据前推的方式解决。

图8 数据前推示意

特殊地,对于LW指令,由于LW指令改写寄存器的写入数据在mem阶段才能确定,因此单纯的数据回推无法解决相关问题,需要在指令后插入一条空指令。为了简化设计,对于所有LW指令,无论是否出现数据相关,均在其后插入空指令(图10)。由于下一条指令仍需执行,所以此时pc的值要保持不变。

(nextpc = pc if(is_lw))

       图9 LW指令的数据相关解决示意          图10 LW指令后插入空指令


以下为IDS模块结构,目的是用于处理数据相关问题。












图11 IDS模块结构


仿真测试

本次课程设计的CPU仿真共实现31条指令,其中22条属于计算类型,4条属于数据存取与传送类型,5条跳转类型,为了简化对测试结果的分析,只对pc地址与寄存器数据(及存储器数据)进行验证。

(一)计算、访存、运算指令

每一个指令的执行共花费5个CPU周期,图示第5个周期结束后写回Lui指令的运算结果,置T1值为2^16=65536。其他指令以此类推。运算到LW指令时,插入一个空指令,同时保证PC值不变,以便于其后Beq等一系列指令的顺利执行。执行到Beq指令时,判断T1=T2=65536,跳转到label指令集xor、and、……

图12 计算、访存、运算指令及其仿真结果


(二)跳转指令

执行到Jr 指令时,其后插一条空指令nop,此时对应$t1 = bfc00000,即跳转到目标地址(程序的开始位置),开始循环执行。

图13 跳转指令仿真结果


(三)传送指令

执行到MOVN指令时,判定此时T2=65537!=0,则在5个周期后将T1赋值给T3。


图14 传送指令仿真结果


程序文件

Testbench




部分代码展示:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/09/11 12:10:21
// Design Name: 
// Module Name: one_cycle_cpu
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module pipe_cpu(
    input       clk,
    input       rst
);
wire        c_is_br;
wire        c_is_lw_id_ex;
wire        c_is_lw_ex_id;
wire        pc_temp;
wire [ 1:0] c_alu_src;
wire        reg_we;
wire        c_reg_we_id_ex;
wire        c_reg_we_ex_me;
wire        c_reg_we_me_wb;
wire        c_mem_we_id_ex;
wire        c_mem_we_ex_me;
wire        c_reg_data_id_ex;
wire        c_reg_data_ex_me;
wire        c_reg_data_me_wb;
wire        c_reg_addr_id_ex;
wire        c_reg_addr_ex_me;
wire        c_reg_addr_me_wb;
wire [31:0] mem_data;
wire [31:0] target;
wire [13:0] ca;
wire [ 4:0] reg_addr_ex_b;
wire [31:0] reg_data_ex_b;
wire [ 4:0] reg_addr_me_b;
wire [31:0] reg_data_me_b;
wire [ 4:0] reg_addr_wb_b;
wire [31:0] reg_data_wb_b;
wire [31:0] inst_if_id;
wire [31:0] inst_id_ex;
wire [31:0] inst_ex_me;
wire [31:0] inst_me_wb;
wire [31:0] rs_value;
wire [31:0] rt_value_id_ex;
wire [31:0] rt_value_ex_me;
wire [31:0] alu_result_ex_me;
wire [31:0] alu_result_me_wb;
wire [31:0] reg_waddr;
wire [31:0] reg_wdata;
wire [31:0] nextpc;
reg  [31:0] pc;
reg         reset;
always @(posedge clk) reset <= ~rst;
assign nextpc = target; 
always @(posedge clk) begin
    if (reset)  begin
         pc <= 32'hbfc00000;
    end
    else       pc <= nextpc;
end
ifs _ifs(
    .clk        (clk),
    .rst        (rst),
    .c_is_br    (c_is_br),
    .c_is_lw    (c_is_lw_id_ex),
    .pc         (pc),
    .final_inst (inst_if_id)
);
ids _ids(
    .clk        (clk),
    .rst        (rst),
    .c_is_lw_in (c_is_lw_ex_id),
    .inst_in    (inst_if_id),
    .reg_we     (reg_we),
    .reg_we_ex  (c_reg_we_ex_me),
    .reg_we_me  (c_reg_we_me_wb),
    .reg_waddr  (reg_waddr),
    .reg_wdata  (reg_wdata),
    .reg_addr_ex_b (reg_addr_ex_b),
    .reg_data_ex_b (reg_data_ex_b),
    .reg_addr_me_b (reg_addr_me_b),
    .reg_data_me_b (reg_data_me_b),
    .reg_addr_wb_b (reg_addr_wb_b),
    .reg_data_wb_b (reg_data_wb_b),
    .mem_data_b (mem_data),
    .pc

代码文件(付费下载):



1、代码文件需要付费后才可见。
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » 五级流水线CPU设计Verilog代码VIVADO仿真

发表评论

模板文件不存在: ./template/plugins/comment/pc/index.htm

注册为本站会员,充值100得150,详情咨询客服

目前为止共有 *** 位优秀的会员加入! 立刻加入会员