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

名称:五级流水线CPU设计Verilog代码VIVADO仿真(文末获取)

软件:VIVADO

语言:Verilog

代码功能:

五级流水线CPU设计

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

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

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

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

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

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

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

工程文件

设计原理及代码实现

总体结构

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
源代码

点击下方的公众号卡片获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值