实验四、单周期 CPU 设计与实现——单指令 CPU

实验四、单周期 CPU 设计与实现——单指令 CPU

一、实验目的:

通过设计并实现支持一条指令的 CPU,理解和掌握 CPU 设计的基本原理和过程。

二、实验内容:

设计和实现一个支持加法指令的单周期 CPU。要求该加法指令(表示为 add r1,r2,r3)格式约定如下:

     采用寄存器寻址,r1,r2,r3 为寄存器编号,r1 和 r2 存放两个源操作数,r3为目标寄存器,其功能为[r1] + [r2] -> r3;
     指令字长 16 位,操作码和地址码字段分配如下所示:

15 9            8 6       5 3       2 0

OpCode      r1          r2         r3    

三、实验原理

单周期 CPU 是指所有指令均在一个时钟周期内完成的 CPU。CPU 由数据通路及其控 制部件两部分构成,因而要完成一个支持若干条指令 CPU 的设计,需要依次完成以下两件 事:

1) 根据指令功能和格式设计 CPU 的数据通路;

2) 根据指令功能和数据通路设计控制部件。

3.1 根据功能和格式完成 CPU 的数据通路设计

本实验需要设计的 CPU 只需要支持一条加法指令,而该指令的功能是在一个时钟周期 内从寄存器组中 r1 和 r2 中取出两个操作数,然后送到 ALU 进行加法运算,最后把计算结 果保存到 r1 寄存器中。下图给出了改加法指令的数据通路图。

OpCode

r1

 

r2

r3

 

图 3.1. 加法指令 add r1,r2,r3 数据通路

此外,还需要确定各个部件的位数,为了简单起见,我们假设目标 CPU 的机器字长、 存储字长和指令字长相等均为 16 位,存储单元个数假设为 256,按字寻址,并取 PC 位数 为 8。
3.2 根据指令功能、数据通路完成控制单元的设计

控制单元的功能是为当前要执行的指令产生微操作命令从而完成该指令的执行。为了能 够完成加法指令的执行,结合图 1,控制单元需要在取出指令后根据指令操作码(本例中是 加法指令),控制 ALU(参考实验二)做加法(通过给 alu_op 信号线相应赋值),并把结果 写回寄存器组(参考实验三)中(通过给 wr_en 赋值为 true)。图 2 给出了整合控制单元后 目标 CPU 的原理图,系统时钟信号也已标注。

图 3.2. 单指令 CPU 原理图

四、实验步骤

在第三部分通过对该 CPU 实现细节的分析、设计,并得到该 CPU 的原理图后,就可 以依次实现各个模块,并进行仿真验证了。

4.1 CPU 各模块 Verilog 实现

在前面实验中,已经分别设计和实现了 PC、指令存储器、寄存器组和 ALU,这里只给 出各个模块的功能描述及其接口定义,具体实现可以直接使用或者调整前面试验的实现代码。

1) PC 模块

表 4.1 PC 模块功能描述

输入

时钟信号 clk、重置信号 rst

输出

指令地址 pc(8 位)

功能

每个时钟上升沿 PC 的值自动加 1,并输出

Verilog 关键代码:

module pc(
  input wire clk, rst,
  output reg [7:0] pc
);
  
  always@(posedge clk) begin
    if(rst == 1)
      pc = 0;
    else
      pc = pc + 1;
  end

endmodule

2) 指令存储器模块

表 4.2 指令存储器模块功能描述

输入

8 位指令地址 Addr

输出

16 位指令 Ins

功能

存放待执行的指令(初始化),并根据地址输出指令

Verilog 关键代码:

module insmemory(
  input wire [7:0] Addr,
  output reg [15:0] Ins
);
  integer i;
  integer j;
  reg [15:0] unit[8'b11111111:0];
  
  initial begin
    for(i = 0; i < 256; i = i + 1) begin
      j = i % 5;
      unit[i][2:0] = j;
      unit[i][5:3] = j + 1;
      unit[i][8:6] = j + 2;
      unit[i][15:9] = 0;
    end
  end
  
  always@* begin
    Ins = unit[Addr];
  end
  
endmodule

3) 寄存器堆

表 4.3 寄存器堆模块功能描述

输入

时钟信号 clk、读写控制线 wr_en、读寄存器编号 read_reg1 和read_reg2、写寄存器编号 write_reg、写入数据 write_data

输出

对应两个读寄存器编号的寄存器值 reg1 和 reg2

功能

根据读寄存器编号给出对应寄存器的值;在写允许情况下,把写入 端的数据在 clk 下降沿写到写寄存器编号对应的寄存器

Verilog 关键代码:

module registerfile(
  input wire clk, wr_en,
  input wire [2:0] read_reg1, read_reg2, write_reg,
  input wire [15:0] write_data,
  output reg [15:0] reg1, reg2
);
  
  integer i;
  reg [15:0] regfile[7:0];
  
  initial begin
    for(i = 0; i < 8; i = i + 1) begin
      regfile[i] = i;
    end
  end
  
  always@* begin
    reg1 = regfile[read_reg1];
    reg2 = regfile[read_reg2];
  end
  
  always@(negedge clk) begin
      if(wr_en == 1)
        regfile[write_reg] = write_data;
  end
  
endmodule

4) ALU

表 4.4 ALU 模块功能描述

输入

操作数 in1 和 in2、操作选择信号 alu_op

输出

ALU 运算结果 Z

功能

根据操作选择信号计算 in1 和 in2 的运算结果 Z

Verilog 关键代码:

module alu(
  input wire [15:0] in1, in2,
  input wire [2:0] alu_op,
  output reg [15:0] Z
);
  always@* begin
    case(alu_op)
      3'b000: Z = in1+in2;
      3'b001: Z = in1-in2;
      3'b010: Z = in1&&in2;
      3'b011: Z = in1||in2;
      3'b100: Z = in1<<in2;
      3'b101: Z = in1>>in2;
    endcase
  end
  
endmodule

5) 控制单元

表 4.5 控制单元模块功能描述

输入

指令(操作码)

输出

寄存器堆的读写控制线 wr_en、ALU 的操作选择信号 alu_op

功能

根据当前指令功能对 wr_en 和 alu_op 赋值

Verilog 关键代码:

module cu(
  input wire [6:0] Ins_op,
  output reg wr_en,
  output reg [2:0] alu_op
);

  always@* begin
    if(Ins_op == 0)
      wr_en = 1;
      alu_op = 3'b000;
  end

endmodule

4.2 CPU 顶层文件封装实现

通过根据图 2 将以上定义的模块进行连接、封装就得到了目标 CPU,该 CPU 的输入为 系统时钟信号 clk 和重置信号 reset。

Verilog 关键代码:

module cpu(
  input wire clk, rst
);

  wire wr;
  wire [2:0] op;
  wire [7:0] addr;
  wire [15:0] z, ins, r1, r2;
  
  pc pc(
    .clk(clk), .rst(rst), .pc(addr)
  );
  
  insmemory insmemory(
    .Addr(addr), .Ins(ins)
  );
  
  cu cu(
    .Ins_op(ins[15:9]),
    .wr_en(wr), .alu_op(op)
  );
  
  registerfile registerfile(
    .clk(clk), .wr_en(wr), 
    .read_reg1(ins[8:6]), .read_reg2(ins[5:3]), .write_reg(ins[2:0]),
    .write_data(z), .reg1(r1), .reg2(r2)
  );
  
  alu alu(
    .in1(r1), .in2(r2),
    .alu_op(op), .Z(z)
  );
  
endmodule

4.3 CPU 模拟仿真

为了仿真验证所实现的 CPU,需要定义测试文件并在测试文件中对指令存储器和寄存 器堆中的相应寄存器的值进行初始化,并通过仿真波形图查看是否指令得到了正确执行。

1)TestBench 关键代码

module cpu_tb;
  reg clk, rst;
  always #1 clk = ~clk;
  
  initial begin
    clk = 1;
    rst = 1;
    
    #1 rst = 0;
    
    #10 $stop;
  end
  
  cpu uut(
    .clk(clk), .rst(rst)
  );
endmodule

2、ModelSim 仿真及分析

五、总结

通过实验,请思考你认为完成一个 CPU 的设计与实现主要由哪几个步骤完成?主要注 意事项有哪些?

六、进一步实验

1)在本节实现的单指令 CPU 基础上,添加存数指令 st r1,addr,实现一个可以支持加17 / 27

法和存数指令的 CPU,并使用 ModelSim 进行仿真验证。 指令 st r1, addr: [r1] -> mem[addr]的格式如下:

159865 0

实验分析提示

首先根据新增加的访存指令功能设计其数据通路,如图 6.1。为使 CPU 能够支持前面 的加法指令和该访存指令,只需要将两个数据通路进行合并(即图 3.1 和图 6.1),并最终得 到该 CPU 的原理图,如图 6.2 所示。

图 6.1 访存指令数据通路

如果要设计支持更多条指令的 CPU,只需根据每条指令设计其数据通路,并采用合并 的方式构建支持所有指令的 CPU 数据通路,然后在进行控制单元的设计即可。在合并过程 中需要注意的是:当某个部件的输入端口有多个输入来源的时候需在此端口前添加一个多路 选择器从而允许控制部件根据执行的需要选择所需的数据来源。

st

r1

addr

 

18 / 27

 

图 6.2 支持加法和访存指令的 CPU 原理图

2)设计和实现一个支持加法 add、立即数加 addi、存数 st、取数 ld 四条指令的 CPU(机器字长=指令字长=存储字长),要求指令格式如下:

 加法 add: [r1] + [r2] -> r1
15 1211 98 65 0

 立即数加 addi r1,Imm: [r1]+SignExt[Imm] -> r1
15 12 11 9 8 0

add

r1

r2

 

addi

r1

imm

 存数 st r1, addr: [r1] -> mem[addr] 15 12 11

9 8 0

 

19 / 27

st

r1

addr

 取数 ld r1, addr: mem[addr] -> r1
15 12 11 9 8 0

ld

r1

addr

  • 29
    点赞
  • 100
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 单周期 CPU 设计实现是一种基于单指令CPU 架构,它的特点是每个指令的执行时间相同,即一个时钟周期。这种设计简单易懂,但效率较低,因为每个指令都需要占用一个时钟周期,无法实现指令流水线和乱序执行等高级优化技术。 ### 回答2: 单周期 CPU 是计算机的一种设计方式,主要是为了实现简单而高效的执行过程。单周期 CPU 的核心思想是每一条指令只需要完成一个时钟周期,可靠性高且可维护性好,每条指令都有一个预分配的时钟周期,这种方法会带来额外的负担和延迟,同时还有占用额外资源的风险。而单指令 CPU 设计是在单周期 CPU 基础上的一种改进,它通过限制计算机的功能,使得每一条指令都具有高度相似的指令格式和执行过程。这种设计方式,有很多的优点,使得它能够更加灵活适应各种不同的需求。 单指令 CPU 设计最重要的优点是它比较容易实现,因为所有指令都具有相似的执行过程,硬件设计也就比较简单,可以节省大量的成本和时间。同时,由于指令格式的统一,程序员将更容易编写出清晰和可读性较高的代码,也有助于减少不同指令间的对齐限制等问题。此外,由于单指令 CPU 可以根据需求动态配置,因此可以适应不同的应用环境,比如平面图形、音效处理等。因此,单指令 CPU 执行效率比较低,但它的灵活性却是非常好的。 对于单指令 CPU实现,主要需要考虑硬件的设计.硬件中要求处理器尽快完成运算,以达到更高的执行速度,同时要保证所耗费的位数不会影响运算结果。为了实现这些目标,有很多种方法可以用于设计实现。计算机工程师可以借助数字逻辑、逆向工程、调试技术等一系列工具,较为轻松地完成实现。但是,由于单指令 CPU 的原理和设计都比较简单,可能无法满足更复杂的计算需求,在这种情况下,工程师会尝试更高级别的计算机设计技术,比如微处理器或高级计算系统,以实现更高性能的计算机系统。 总的来说,单指令 CPU 是一种比较特殊的设计方式,具有一定的优点和缺点,不同场景的计算需求也会影响该方法的实现方式。计算机设计师可以根据实际情况选择不同的设计策略,以满足不同的性能和实现需求。 ### 回答3: 随着计算机科技的不断进步,单周期CPU被认为是计算机结构设计的最基础单元之一。在单周期CPU中,每个指令在一个时钟周期内执行完成,因此称之为单指令CPU。接下来,我们将深入探讨单周期CPU设计实现,并对其优缺点进行比较。 单指令CPU设计针对的是简单指令集架构。在这个架构中,每个指令都是通过单个指令来完成的。对于指令集中所包含的每个指令,单指令CPU均为其分配一个固定的时钟周期。但是这种方案的缺点在于,不同指令所需要的时钟周期数是不同的,因此,在执行某些指令时,CPU会在执行完其本身所需要的时钟周期之后等待更多的时钟周期,直到总时钟周期数等于该指令的时钟周期数,这会浪费很多时间。 此外,在单指令CPU中,所有指令均以相同的速率运行,即使某些指令可能需要更多的时间来完成。尽管如此,在多数情况下,单指令CPU的优点在于其设计简单、易于理解和实现。 当谈到单周期CPU实现时,一般情况下它被分为五个主要的阶段,即指令获取、指令解码、执行操作、访问存储和写回。指令获取阶段的目的是从内存中获取将要执行的指令。在指令解码阶段,CPU会解码指令,理解其意义以及所需要的具体操作。在执行操作阶段,CPU需要根据指令类型执行各种不同的操作,如算术、逻辑和分支操作等。在访问存储阶段,CPU会根据指令类型读取或写入存储器。最后,在写回阶段,结果将会被写入通用寄存器,供后续的指令使用。 在单指令CPU的优缺点方面,由于其简单性,单指令CPU通常比多指令CPU更低成本。此外,由于其设计简单、易于理解和实现单指令CPU在启动时通常需要很少的时间。然而,由于单指令CPU的每个指令都需要相同的时钟周期,因此在执行某些指令时效率可能会较低。 综上所述,单周期CPU设计实现是计算机结构设计中最为基础的部分,但它并不是最优解。单指令CPU的优缺点主要取决于具体情况下所需求解的问题。如果要求计算机系统运行速度更快,关键在于将每个指令的执行时间限制在最短时间内。如果要求计算机系统设计更加简单和稳定,单指令CPU则是更适合的选择。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值