当前位置:   article > 正文

计算机组成课设-设计并实现LA32R架构的模型机硬件系统_设计能够产生支持下列6条la32r指令执行的数据通路所需控制信号的控制器

设计能够产生支持下列6条la32r指令执行的数据通路所需控制信号的控制器

一、课程设计题目

1.课程设计任务与要求

本次课程设计的任务是:设计并实现LA32R架构的模型机硬件系统。该模型机的指令系统包括以下6条指令:

序号

类型

指令

功能

说明

1

1RI20

LU12I.W rd,si20

GR[rd] ⟵si20 || 12’b0

GR[rd]的高20位为si20,低12位为0

符号||表示拼接

2

3R

ADD.W rd, rj, rk

GR[rd]⟵GR[rj]+GR[rk]

加法

3

3R

SLT rd, rj, rk

if (GR[rj]<GR[rk]) GR[rd]⟵1 else GR[rd]⟵0

带符号数的大小比较

4

3R

SLTU rd, rj, rk

if (GR[rj]<GR[rk]) GR[rd]⟵1 else GR[rd]⟵0

无符号数的大小比较

5

2RI12

LD.W rd ,rj,si12

Addr⟵GR[rj] + SignExtend (si12) ,GR[rd] ⟵M[Addr]

将内存Addr单元的值取出后存入R[rd]

si1212位立即数,进行符号位扩展后与GR[rj]相加后得到内存单元的地址Addr

6

2RI12

ST.W rd, rj, si12

Addr⟵GR[rj] + SignExtend (si12) , M[Addr]⟵GR[rd]

GR[rd]的值存入内存Addr单元

内存单元的地址Addr的计算方法与LD.W指令相同

2. 课程设计完成条件

一台安装了EDA工具软件(Vivado)的计算机。

3.设计思路与方案

  1. 设计思路
    1. 逐条分析要实现的LA32R指令的格式与功能。
    2. 设计取指令、执行指令所需的执行部件,并逐一进行仿真测试,完成功能验证。
    3. 按指令功能,设计各指令的数据通路,将执行部件进行互连,并进行仿真测试,完成功能验证。
    4. 设计控制部件,并进行仿真测试,实现指令译码功能验证。
    5. 将执行部件与控制部件进行互连,完成模型机的设计,并进行仿真测试,通过分析测试程序的运行结果,完成模型机功能的验证。
  2. 设计方案

本次设计的模型机电路如图1所示。该模型机是总线结构,数据总线32位,地址总线32位。该电路包括运算器、存储器、控制器和通用寄存器等模块。其中,运算器可以完成加法、减法、与、或、或非、带符号比较、无符号比较以及直通功能。存储器可以完成数据存入读出功能,容量是256KB。控制器是采用存储逻辑实现的微程序控制器。有1个通用寄存器,可以存储32位数据。

图1模型机电路框图

图1中各功能器件上标注的控制信号的功能说明见下表。

表1微操作信号说明

信号名称

信号功能说明

RegWr

Register写使能控制信号,clk上升沿时刻,若RegWr为1,则busW上的数据被存入Rw指定的寄存器中

AluCtrl

ALU运算类型选择输入

ALUBSrc

二选一模块控制信号

ExtOp

Ext扩展方式选择信号

MemWrEn

RAM写使能信号。

当MemWrEn为0时,数据从addr地址端口指定的内存单元读出。

当MemWrEn为1时,配合clk时钟信号工作,在clk上升沿,数据存入由addr地址端口指定的内存单元。

MemToReg

二选一模块控制信号

srcReg

二选一模块控制信号

Br

Br_E_L与Br信号共同确定PC自增控制信号,与clk上升沿配合工作。

在clk上升沿时刻,当pc_inc=1时,PCdata =原PCdata +1;当pc_inc=0时,PCdata =原PCdata +offset。

Br_E_L

clk

时钟信号

oe

ROM使能信号

rst

PC异步清零信号,高电平有效,即:rst为1时,PCdata =0

3.设计原理与内容

(1) 通用寄存器堆(register)

通用寄存器堆包含32个寄存器,记为:r0~r31。每个寄存器的位宽都是:32位。其中,r0的值恒为0。其电路原理图如下:

该模块的功能及引脚信号说明如下:

信号名称

功能说明

busA和busB

两路32位数据输出信号

Ra(5位)

读寄存器编号输入信号,该编号指定的寄存器的值经过“取数延迟”后,输出到busA

Rb(5位)

读寄存器编号输入信号,该编号指定的寄存器的值经过“取数延迟”后,输出到busB

Rw(5位)

写寄存器编号输入信号,该编号指定的数据要写入哪个寄存器

busW

32位数据输入信号

clk

写操作时钟控制信号,上升沿有效

RegWr

写使能控制信号,clk上升沿时刻,若RegWr为1,则busW上的数据被存入Rw指定的寄存器中

注:

  • 寄存器堆的读操作不受clk控制;
  • 0号寄存器的值恒为0,不受写操作的影响。

该模块的Verilog HDL代码设计如下:

  1. module Registers(busA, busB, Ra, Rb, Rw, busW, clk, RegWr);
  2. input [31:0]busW;
  3. input clk;
  4. input RegWr;
  5. input [4:0]Rw;
  6. input [4:0]Ra;
  7. input [4:0]Rb;
  8. output [31:0]busA;
  9. output [31:0]busB;
  10. reg [31:0] regs [0:32];
  11. reg [31:0] busA;
  12. reg [31:0] busB;
  13. integer i;
  14. always@(*)begin
  15.     regs[0]=0;
  16.     busA = regs[Ra];
  17.     busB = regs[Rb];
  18. end
  19. always@(posedge clk)begin
  20.     if(RegWr == 1)begin
  21.         if(Rw == 0)begin
  22.             regs[Rw] = 0;
  23.         end
  24.         else begin
  25.             regs[Rw] = busW;
  26.         end
  27.     end
  28. end
  29. endmodule

(2)立即数扩展模块(Ext)

一个立即数扩展模块Ext,该模块实现下表所示的4种方式的立即数扩展与拼接操作,以得到一个新的32位数。

Extop

功能

说明

0

Dataout←SignExtend(DataIn[21:10])

把DataIn[21:10]进行符号位扩展

1

Dataout←SignExtend(DataIn[25:10] || 2’b0)

把DataIn[25:10]低位补2bit0后,进行符号位扩展

2

Dataout←DataIn[24:5] || 12’b0

把DataIn[24:5]低位补12bit0

3

Dataout←SignExtend(DataIn[9:0] || DataIn[25:10] || 2’b0)

把DataIn[9:0]和 DataIn[25:10] 进行拼接,然后低位补2个0,再进行符号位扩展

该模块的参考电路框图如下:

该模块的功能及引脚信号说明如下:

信号名称

功能说明

Datain

32位的数据输入信号

Extop

扩展方式选择信号

Dataout

32位的数据输出信号

该模块的Verilog HDL代码设计如下:

  1. module Ext(input[31:0] DataIn, input[1:0]ExtOp,
  2.              output[31:0]Dataout);
  3.     wire [31:0]imm12;
  4.     wire [31:0]imm16;
  5.     wire [31:0]imm20;
  6.     wire [31:0]imm26;
  7.     //对ADDI.W, LD.W, ST.W指令中的12位立即数进行符号位扩展
  8.     assign imm12= {{20{DataIn[21]}},DataIn[21:10]};
  9.     //对BEQ,BLT指令中的立即数进行符号位扩展及其他部分的拼接
  10.     assign imm16={{14{DataIn[25]}} , {DataIn[25:10], 2'b0}};
  11.     // 对LUI12I.W指令中的20位立即数,低12位补0
  12.     assign imm20={DataIn[24:5], 12'b0};
  13.     //对B指令中的立即数进行符号位扩展及其他部分的拼接
  14.     assign imm26={{4{DataIn[25]}}, DataIn[9:0] , {DataIn[25:10] , 2'b0}};
  15.     reg [31:0]Dataout;
  16.     always @(*)
  17.     begin
  18.         case(ExtOp)
  19.         2'b00: Dataout <= imm12;
  20.         2'b01: Dataout <= imm16;
  21.         2'b10: Dataout <= imm20;
  22.         2'b11: Dataout <= imm26;
  23.     default: Dataout <= imm26;
  24.         endcase
  25.     end
  26.    
  27. endmodule

(3)程序计数器PC

该模块的参考电路框图如下:

该模块的功能及引脚信号说明如下:

信号名称

功能说明

rst

PC异步清零信号,高电平有效,即:rst为1时,PCdata =0

clk

时钟信号

offset

32位偏移量

pc_inc

自增控制信号,与clk上升沿配合工作。

在clk上升沿时刻,当pc_inc=1时,PCdata =原PCdata +1;当pc_inc=0时,PCdata =原PCdata +offset。

PCdata

32位数据输出信号

该模块的Verilog HDL代码设计如下:

  1. module PC(rst, clk, offset, pc_inc, PCdata);
  2. input rst;
  3. input clk;
  4. input [31:0]offset;
  5. input pc_inc;
  6. output [31:0]PCdata;
  7. reg [31:0]PCdata;
  8. always@(posedge clk)begin
  9.     if(rst==1)begin
  10.         PCdata = 0;
  11.     end
  12.     else begin
  13.          if(pc_inc == 1)begin
  14.             PCdata = PCdata + 4;
  15.          end
  16.          else begin
  17.             PCdata = PCdata + offset;
  18.          end
  19.     end
  20. end
  21. endmodule

(4)算术逻辑运算单元ALU

该模块的参考电路框图如下:

该模块的功能及引脚信号说明如下:

信号名称

功能说明

a, b

两个32位的数据输入

op

运算类型选择输入

AddResult

运算结果输出

Zero

0标志位输出。运算结果AddResult为0时,Zero=1;否则Zero=0

该模块的Verilog HDL代码设计如下:

  1. module ALU(input[31:0] a, input[31:0] b, input[2:0] op, output[31:0] AddResult, output Zero, output LT);
  2.     wire [31:0]m;
  3.     wire [31:0]n;
  4.     wire [31:0]p;
  5.     wire [31:0]q;
  6.     assign m = a & 32'h80000000;
  7.     assign n = b & 32'h80000000;
  8.     assign p = a & 32'h7fffffff;
  9.     assign q = b & 32'h7fffffff;
  10.     reg [31:0]AddResult;
  11.     always @(*)
  12.     begin
  13.         case(op)
  14.         3'b000:AddResult <= a + b;
  15.         3'b001:AddResult <= a - b;
  16.         3'b010:AddResult <= a & b;
  17.         3'b011:AddResult <= a | b;
  18.         3'b100:AddResult <= ~(a | b);
  19.         3'b101:if(m == 32'h00000000 && n== 32'h00000000)begin
  20.                     if(p>q)begin
  21.                         AddResult <= 1;
  22.                     end
  23.                     else begin
  24.                         AddResult <= 0;
  25.                     end
  26.                 end
  27.                 else if (m == 32'h00000000 && n== 32'h80000000)begin
  28.                     AddResult <= 0;
  29.                 end
  30.                 else if (m == 32'h80000000 && n== 32'h80000000)begin
  31.                     if (p>q)begin
  32.                         AddResult <= 1;
  33.                     end
  34.                     else begin
  35.                         AddResult <= 0;
  36.                     end
  37.                 end
  38.                 else begin
  39.                     AddResult <= 1;
  40.                 end
  41.         3'b110: if (a<b)begin
  42.                     AddResult <= 1;
  43.                 end
  44.                 else begin
  45.                     AddResult <= 0;
  46.                 end
  47.         3'b111:AddResult <= b;
  48.         default:AddResult <= b;
  49.             endcase
  50.         end
  51.     reg Zero
  52.     reg LT;
  53.     always @(*)
  54.     begin
  55.         if (AddResult==0)begin
  56.             Zero <= 1;
  57.             LT <= 1;
  58.         end
  59.         else begin
  60.             LT <= 0;
  61.         end
  62.     end
  63. endmodule

(5) 数据存储器(RAM)

该模块的参考电路框图如下:

图中信号说明如下:

信号名称

功能说明

addr

32位地址总线,用于传送地址,以便按地址访问存储单元。

data_in

32位数据输入总线

data_out

32位数据输出总线

clk

时钟信号,上升沿有效

MemWrEn

写使能信号。

当MemWrEn为0时,数据从addr地址端口指定的内存单元读出。

当MemWrEn为1时,配合clk时钟信号工作,在clk上升沿,数据存入由addr地址端口指定的内存单元。

该模块的Verilog HDL代码设计如下:

  1. module RAM(clk, MemWrEn, addr, data_in, data_out);
  2. input clk;
  3. input MemWrEn;
  4. input [31:0] addr;
  5. input [31:0] data_in;
  6. output [31:0]data_out;
  7. reg [31:0] regs [0:65535];
  8. reg [31:0] data_out;
  9. always@(*)begin
  10.     if(MemWrEn == 0)begin
  11.         data_out = regs[addr];
  12.     end
  13. end
  14. always@(posedge clk)begin
  15.     if(MemWrEn == 1)begin
  16.             regs[addr] = data_in;
  17.     end
  18. end
  19. endmodule

(6) 指令存储器(ROM)

该模块的参考电路框图如下:

图中信号说明如下:

                             信号名称

功能说明

addr

32位地址总线,用于传送地址,以便按地址访问存储单元。

data_out

32位数据输出总线

该模块的Verilog HDL代码设计如下:

  1. module ROM(address, oe,dataRomOut);
  2. input [31:0]address;//地址
  3. input oe;//oe 为输出允许
  4. output [31:0]dataRomOut;//数据输出
  5. reg [31:0]RomOut;  
  6. always @(*)     //任何信号(电平)发生改变模块都执行
  7.     begin
  8.         if (oe)
  9.             case(address[6:2])
  10.                 5'b00000:RomOut <= 32'b000101_0_0000_0000_0000_0000_0001_00001;
  11.                 5'b00001:RomOut <= 32'b000101_0_0000_0000_0000_0000_0010_00010;
  12.                 5'b00010:RomOut <= 32'b000101_0_1111_1111_1111_1111_1111_00011;
  13.                 5'b00011:RomOut <= 32'b000101_0_1111_1111_1111_1111_1110_00100;
  14.                 5'b00100:RomOut <= 32'b000000_0000_01_00000_00010_00001_00101;
  15.                 5'b00101:RomOut <= 32'b000000_0000_01_00100_00100_00011_00110;
  16.                 5'b00110:RomOut <= 32'b000000_0000_01_00100_00011_00100_00111;
  17.                 5'b00111:RomOut <= 32'b000000_0000_01_00101_00101_00001_01000;
  18.                 5'b01000:RomOut <= 32'b000000_0000_01_00101_00001_00101_01001;
  19.                 5'b01001:RomOut <= 32'b001010_0110_0000_0000_1010_00010_00101;
  20.                 5'b01010:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
  21.                 5'b01011:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
  22.                 5'b01100:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
  23.                 5'b01101:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
  24.                 5'b01110:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
  25.                 5'b01111:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
  26.                 default: RomOut <= 32'h0;         
  27.             endcase
  28.         else RomOut <= 32'hzz;      
  29.     end
  30.     assign dataRomOut=RomOut;   
  31. endmodule

(7) 控制器(control)

该电路的参考结构图如下:

图中输入信号Instr[31:15]为要执行的指令字的部分字段,输出信号RegWr, AluCtrl, ALUBSrc, ExtOp, MemWrEn,MemToReg和srcReg为控制器根据不同指令所产生的控制信号。

该模块的Verilog HDL代码设计如下:

  1. module Control(input [16:0]Instr, input Zero, input LT, output RegWr, output [2:0]AluCtrl, output ALUBSrc, output [1:0]ExtOp, output MemWrEn, output MemToReg, output srcReg, output Br, output Br_E_L);
  2.     reg RegWr;
  3.     reg [2:0]AluCtrl;
  4.     reg ALUBSrc;
  5.     reg [1:0]ExtOp;
  6.     reg MemWrEn;
  7.     reg MemToReg;
  8.     reg srcReg;
  9.     reg Br;
  10.     reg Br_E_L;
  11.     always@(*)begin
  12.         if(Instr==17'b00000000000100000)begin
  13.             RegWr = 1;
  14.             AluCtrl = 0;
  15.             ALUBSrc = 0;
  16.             ExtOp = 0;
  17.             MemWrEn = 0;
  18.             MemToReg = 0;
  19.             srcReg = 0;
  20.             Br = 0;
  21.             Br_E_L = 0;
  22.         end
  23.         else if (Instr==17'b00000000000100100)begin
  24.             RegWr = 1;
  25.             AluCtrl = 3'b101;
  26.             ALUBSrc = 0;
  27.             ExtOp = 0;
  28.             MemWrEn = 0;
  29.             MemToReg = 0;
  30.             srcReg = 0;
  31.             Br = 0;
  32.             Br_E_L = 0;
  33.         end
  34.         else if (Instr==17'b00000000000100101)begin
  35.             RegWr = 1;
  36.             AluCtrl = 3'b110;
  37.             ALUBSrc = 0;
  38.             ExtOp = 0;
  39.             MemWrEn = 0;
  40.             MemToReg = 0;
  41.             srcReg = 0;
  42.             Br = 0;
  43.             Br_E_L = 0;
  44.         end
  45.         else if (Instr[16:10]==7'b0001010)begin
  46.             RegWr = 1;
  47.             AluCtrl = 111;
  48.             ALUBSrc = 1;
  49.             ExtOp = 2'b10;
  50.             MemWrEn = 0;
  51.             MemToReg = 0;
  52.             srcReg = 0;
  53.             Br = 0;
  54.             Br_E_L = 0;
  55.         end
  56.         else if(Instr[16:7]==10'b0010100010)begin
  57.             RegWr = 1;
  58.             AluCtrl = 0;
  59.             ALUBSrc = 1;
  60.             ExtOp = 0;
  61.             MemWrEn = 0;
  62.             MemToReg = 1;
  63.             srcReg = 0;
  64.             Br = 0;
  65.             Br_E_L = 0;
  66.         end
  67.         else if(Instr[16:7]==10'b0010100110)begin
  68.             RegWr = 0;
  69.             AluCtrl = 0;
  70.             ALUBSrc = 1;
  71.             ExtOp = 0;
  72.             MemWrEn = 1;
  73.             MemToReg = 0;
  74.             srcReg = 1;
  75.             Br = 0;
  76.             Br_E_L = 0;
  77.         end
  78.         else begin
  79.             RegWr = 1;
  80.             AluCtrl = 0;
  81.             ALUBSrc = 0;
  82.             ExtOp = 0;
  83.             MemWrEn = 0;
  84.             MemToReg = 0;
  85.             srcReg = 0;
  86.             Br = 0;
  87.             Br_E_L = 0;
  88.         end
  89.     end
  90. endmodule

(8) 单周期LA32R CPU电路

该电路的参考结构图如下:

该模块的Verilog HDL代码设计如下:

  1. module CPU(input clk, input rst, input oe);
  2.     wire [31:0]L1;
  3.     wire [31:0]L2;
  4.     wire [31:0]L3;
  5.     wire [4:0]L4;
  6.     wire [31:0]L5;
  7.     wire [31:0]L6;
  8.     wire [31:0]L7;
  9.     wire [31:0]L8;
  10.     wire L10;
  11.     wire [31:0]L11;
  12.     wire RegWr;
  13.     wire [2:0]AluCtrl;
  14.     wire ALUBSrc;
  15.     wire [1:0]ExtOp;
  16.     wire MemWrEn;
  17.     wire MemToReg;
  18.     wire srcReg;
  19.     wire Br;
  20.     wire Br_E_L;
  21.     wire Zero;
  22.     wire LT;
  23.     wire [31:0]Instr;
  24.     Ext Ext_Top(.DataIn(Instr), .ExtOp(ExtOp), .Dataout(L1));
  25.     PC PC_Top(.rst(rst), .clk(clk), .offset(L1), .pc_inc(L10), .PCdata(L11));
  26.     PC_inc PC_inc_Top(.Br(Br),.Br_E_L(Br_E_L),.pc_inc(L10));
  27.     Control Control_Top(.Instr(Instr[31:15]), .Zero(Zero), .LT(LT), .RegWr(RegWr), .AluCtrl(AluCtrl), .ALUBSrc(ALUBSrc), .ExtOp(ExtOp), .MemWrEn(MemWrEn), .MemToReg(MemToReg), .srcReg(srcReg), .Br(Br), .Br_E_L(Br_E_L));
  28.     ROM ROM_Top(.address(L11), .oe(oe),.dataRomOut(Instr));
  29.     MUX_a MUXa_Top(.data_a(Instr[4:0]), .data_b(Instr[14:10]), .flag(srcReg), .data_out(L4));
  30.     Registers Register_Top(.busA(L2), .busB(L3), .Ra(Instr[9:5]), .Rb(L4), .Rw(Instr[4:0]), .busW(L5), .clk(clk), .RegWr(RegWr));
  31.     MUX_b MUXb_Top(.data_a(L1), .data_b(L3), .flag(ALUBSrc), .data_out(L6));
  32.     ALU ALU_Top(.a(L2), .b(L6), .op(AluCtrl), .AddResult(L7), .Zero(Zero), .LT(LT));
  33.     RAM RAM_Top(.clk(clk), .MemWrEn(MemWrEn), .addr(L7), .data_in(L3), .data_out(L8));
  34.     MUX_c MUXc_Top(.data_a(L8), .data_b(L7), .flag(MemToReg), .data_out(L5));
  35. endmodule

4.设计调试与结果

(1)通用寄存器堆register

在Vivado环境中,输入Verilog HDL设计代码,保存为.v文件。检查无误后,系统生成的RTL原理图如下:

激励文件如下:

`timescale 1ns / 1ps

module sim4Registers();

reg [31:0]busW;

reg clk;

reg RegWr;

reg [4:0]Rw;

reg [4:0]Ra;

reg [4:0]Rb;

wire [31:0]busA;

wire [31:0]busB;

Registers uut(.busA(busA), .busB(busB), .Ra(Ra), .Rb(Rb), .Rw(Rw), .busW(busW), .clk(clk), .RegWr(RegWr));

initial begin

    clk = 0;

    forever begin

        #100;Rw = 0;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 1;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 2;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 3;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 4;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 5;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 6;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 7;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 8;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 9;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 10;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 11;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 12;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 13;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 14;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 15;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 16;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 17;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 18;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 19;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 20;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 21;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 22;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 23;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 24;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 25;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 26;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 27;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 28;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 29;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 30;RegWr = 1;busW = 32'h00000000;

        #100;Rw = 31;RegWr = 1;busW = 32'h00000000;   

        #100;Ra = 0;Rb = 1;Rw = 1;RegWr = 1;busW = 32'h11111111;

        #100;Ra = 1;Rb = 2;Rw = 2;RegWr = 1;busW = 32'h22222222;

        #100;Ra = 2;Rb = 3;Rw = 3;RegWr = 1;busW = 32'h33333333;

        #100;Ra = 3;Rb = 4;Rw = 4;RegWr = 1;busW = 32'h44444444;

        #100;Ra = 4;Rb = 5;Rw = 5;RegWr = 1;busW = 32'h55555555;

        #100;Ra = 5;Rb = 6;Rw = 6;RegWr = 1;busW = 32'h66666666;

        #100;Ra = 6;Rb = 7;Rw = 7;RegWr = 1;busW = 32'h77777777;

        #100;Ra = 7;Rb = 8;Rw = 8;RegWr = 1;busW = 32'h88888888;

        #100;Ra = 8;Rb = 9;Rw = 9;RegWr = 1;busW = 32'h99999999;

        #100;Ra = 9;Rb = 0;Rw = 0;RegWr = 1;busW = 32'haaaaaaaa;

        #100;Ra = 0;Rb = 0;Rw = 0;RegWr = 0;busW = 32'h33333333;

    end

end

always #40 clk=~clk;

endmodule

运行结果如下:

(2)立即数扩展模块Ext

在Vivado环境中,输入Verilog HDL设计代码,保存为.v文件。检查无误后,系统生成的RTL原理图如下:

激励文件如下:

`timescale 1ns / 1ps

module sim4Ext();

    reg [31:0]DataIn;

    reg [1:0]ExtOp;

    wire [31:0]Dataout;

        Ext uut(.DataIn(DataIn),.ExtOp(ExtOp),.Dataout(Dataout));

            always begin

        DataIn = 32'b00000000000000000001000000000001;ExtOp = 2'b00;#100;

        DataIn = 32'h12345678;ExtOp = 2'b01;#100;

        DataIn = 32'h12345678;ExtOp = 2'b10;#100;    

        DataIn = 32'h12345678;ExtOp = 2'b11;#100;

        end

endmodule

运行结果如下:

(3)程序计数器PC

在Vivado环境中,输入Verilog HDL设计代码,保存为.v文件。检查无误后,系统生成的RTL原理图如下:

测试代码如下:

`timescale 1ns / 1ps

module sim4PC();

reg rst;

reg clk;

reg [31:0]offset;

reg pc_inc;

wire [31:0]PCdata;

PC uut(.rst(rst), .clk(clk), .offset(offset), .pc_inc(pc_inc),.PCdata(PCdata));

initial begin

    clk = 0;

    rst = 1;

    pc_inc = 1;

    forever begin

        #50 rst = 0;pc_inc = 1;

        #50 rst = 0;pc_inc = 0;offset = 32'h12345678;

        #50 rst = 0;pc_inc = 1;

        #50 rst = 0;pc_inc = 1;

        #50 rst = 0;pc_inc = 1;

        #50 rst = 0;pc_inc = 1;

        #50 rst = 1;pc_inc = 1;

    end

end

always #20 clk=~clk;

endmodule

运行结果如下:

(4)算术逻辑运算单元ALU

在Vivado环境中,输入Verilog HDL设计代码,保存为.v文件。检查无误后,系统生成的RTL原理图如下:

代码如下:

`timescale 1ns / 1ps

module sim4Ext();

    reg [31:0]a;

    reg [31:0]b;

    reg [2:0]op;

    wire [31:0]AddResult;

    wire Zero;

        ALU uut(.a(a),.b(b),.op(op),.AddResult(AddResult),.Zero(Zero));

            always begin

        a = 32'h10000078;b = 32'h00000123;op = 3'b000;#100;

        a = 32'h12345678;b = 32'h00000123;op = 3'b001;#100;      

        a = 32'h12345678;b = 32'h00000123;op = 3'b010;#100;

        a = 32'h10000078;b = 32'h00000123;op = 3'b011;#100;

        a = 32'h12345678;b = 32'h00000123;op = 3'b100;#100;      

        a = 32'h12345678;b = 32'h00000123;op = 3'b101;#100;

        a = 32'h12345678;b = 32'h00000123;op = 3'b110;#100;      

        a = 32'h12345678;b = 32'h00000123;op = 3'b111;#100;

        end

endmodule

运行结果如下:

(5)数据存储器RAM

在Vivado环境中,输入Verilog HDL设计代码,保存为.v文件。检查无误后,系统生成的RTL原理图如下:

激励文件如下:

`timescale 1ns / 1ps

module sim4RAM();

reg clk;

reg MemWrEn;

reg [31:0]addr;

reg [31:0]data_in;

wire [31:0]data_out;

reg [0:31] i;

RAM uut(.clk(clk), .MemWrEn(MemWrEn), .addr(addr), .data_in(data_in), .data_out(data_out));

initial begin

    clk = 0;

    i = 0;

    forever begin

        for(i = 0; i < 32; i = i + 1 )begin

            #100;MemWrEn=1;addr=i;data_in = 32'h00000000;

        end

        #100;MemWrEn=0;addr=0;data_in = 32'h00000000;

        #100;MemWrEn=1;addr=0;data_in = 32'h11111111;

        #100;MemWrEn=0;addr=0;data_in = 32'h00000000;

        #100;MemWrEn=0;addr=1;data_in = 32'h00000000;

        #100;MemWrEn=1;addr=1;data_in = 32'h22222222;

        #100;MemWrEn=0;addr=1;data_in = 32'h00000000;

        #100;MemWrEn=0;addr=2;data_in = 32'h00000000;

        #100;MemWrEn=1;addr=2;data_in = 32'h33333333;

        #100;MemWrEn=0;addr=2;data_in = 32'h00000000;

        #100;MemWrEn=0;addr=3;data_in = 32'h44444444;

        #100;MemWrEn=1;addr=3;data_in = 32'h44444444;

        #100;MemWrEn=0;addr=3;data_in = 32'h44444444;      

    end

end

always #40 clk=~clk;

endmodule

运行结果如下:

(6)指令存储器ROM

在Vivado环境中,输入Verilog HDL设计代码,保存为.v文件。检查无误后,系统生成的RTL原理图如下:

激励文件如下:

`timescale 1ns / 1ps

module sim4ROM();

    reg[31:0]address;//地址

    reg oe;//oe 为输出允许

    wire [31:0]dataRomOut;//数据输出

    ROM uut(.address(address), .oe(oe),.dataRomOut(dataRomOut));

    initial begin

    #40; address = 32'h00000000; oe = 1;//0000000

    #40; address = 32'h00000004; oe = 1;//0000100

    #40; address = 32'h00000008; oe = 1;//0001000

    #40; address = 32'h0000000c; oe = 1;//0001100

    #40; address = 32'h00000010; oe = 1;//0010000

    #40; address = 32'h00000014; oe = 1;//0010100

    #40; address = 32'h00000018; oe = 1;//0011000

    #40; address = 32'h0000001c; oe = 1;//0011100

    #40; address = 32'h00000020; oe = 1;//0100000

    #40; address = 32'h00000024; oe = 1;//0100100

    #40; address = 32'h00000028; oe = 1;//0101000

    #40; address = 32'h0000002c; oe = 1;//0101100

    #40; address = 32'h00000030; oe = 1;//0110000

    #40; address = 32'h00000034; oe = 1;//0110100

    #40; address = 32'h00000038; oe = 1;//0111000

    #40; address = 32'h0000003c; oe = 1;//0111100

    $stop;  

    end

endmodule

运行结果如下:

(7)控制器control

Vivado环境中,输入Verilog HDL设计代码,保存为.v文件。检查无误后,系统生成的RTL原理图如下:

激励文件如下:

`timescale 1ns / 1ps

module sim4Control( );

    reg [16:0]Instr;

    wire RegWr;

    wire [2:0]AluCtrl;

    wire ALUBSrc;

    wire [1:0]ExtOp;

    wire MemWrEn;

    wire MemToReg;

    wire srcReg;

    Control uut(.Instr(Instr), .RegWr(RegWr), .AluCtrl(AluCtrl), .ALUBSrc(ALUBSrc), .ExtOp(ExtOp),

                 .MemWrEn(MemWrEn), .MemToReg(MemToReg), .srcReg(srcReg));

        always begin

        #100; Instr=17'b00010101111111111;// LU12I.W

        #100; Instr=17'b00000000000100000;// ADD.W

        #100; Instr=17'b00000000000100100;//SLT

        #100; Instr=17'b00000000000100101;//SLTU

        #100; Instr=17'b00101001100000000;//ST.W

        #100; Instr=17'b00101000100000000;//LD.W

        end

endmodule

运行如下:

(8)单周期LA32R CPU电路

a)控制信号的取指分析

本次设计的指令系统包括6条指令,控制信号的取值分析如下:

输入

输出

指令

oe

rst

srcReg

ExtOp

ALUBSrc

AluCtrl

MemWrEn

MemToReg

RegWr

Br

Br_E_L

add

1

0

0

2’b00

0

3’b000

0

0

1

0

0

slt

1

0

0

2’b00

0

3’b101

0

0

1

0

0

sltu

1

0

0

2’b00

0

3’b110

0

0

1

0

0

lu12i

1

0

0

2’b10

1

3’b111

0

0

1

0

0

st

1

0

1

2’b00

1

3’b000

1

0

0

0

0

ld

1

0

0

2’b00

1

3’b000

0

1

1

0

0

 

应用程序

用所设计的6条指令编写的应用程序如下,该测试程序完成寄存器存储、加法、无符号比较、带符号比较、寄存器与内部存储器数据交换共六个功能。

应用程序助记符代码

应用程序机器代码

Lu12i

32'h14000021;

Lu12i

32'h14000042;

Lu12i

32'h15ffffe3;

Lu12i

32'h15ffffc4;

Add

32’h00100825

Slt

32’h00121066

Slt

32’h00120c87

Sltu

32’h00129428

Sltu

32’h001284a9

St

32’h29802845

ld

32’h2880284a

  1. 应用程序与模型机联调过程及结果

i.本模型机使用ROM存储器存储应用程序,所编写的仿真测试激励文件就是给出几个输入信号的初始值以及clk信号,将由PC程序计数器来控制执行的指令。仿真波形结果的输入信号是rst (PC异步清零信号,高电平有效,即:rst为1时,PCdata =0),oe (ROM使能信号)和clk(时钟信号)。得到的输出是指令执行的结果。运行结果与应用程序预计的结果相一致。

仿真激励文件如下:

`timescale 1ns / 1ps

module sim4CPU();

    wire [31:0]L1;

    wire [31:0]L2;

    wire [31:0]L3;

    wire [4:0]L4;

    wire [31:0]L5;

    wire [31:0]L6;

    wire [31:0]L7;

    wire [31:0]L8;

    wire L10;

    wire [31:0]L11;

    wire RegWr;

    wire [2:0]AluCtrl;

    wire ALUBSrc;

    wire [1:0]ExtOp;

    wire MemWrEn;

    wire MemToReg;

    wire srcReg;

    wire Br;

    wire Br_E_L;

    wire Zero;

    wire LT;

    wire [31:0]Instr;

    reg clk;

    reg rst;

    reg oe;

    Ext Ext_Top(.DataIn(Instr), .ExtOp(ExtOp), .Dataout(L1));

    PC PC_Top(.rst(rst), .clk(clk), .offset(L1), .pc_inc(L10), .PCdata(L11));

    PC_inc PC_inc_Top(.Br(Br),.Br_E_L(Br_E_L),.pc_inc(L10));

    Control Control_Top(.Instr(Instr[31:15]), .Zero(Zero), .LT(LT), .RegWr(RegWr), .AluCtrl(AluCtrl), .ALUBSrc(ALUBSrc), .ExtOp(ExtOp),

                 .MemWrEn(MemWrEn), .MemToReg(MemToReg), .srcReg(srcReg), .Br(Br), .Br_E_L(Br_E_L));

    ROM ROM_Top(.address(L11), .oe(oe),.dataRomOut(Instr));

    MUX_a MUXa_Top(.data_a(Instr[4:0]), .data_b(Instr[14:10]), .flag(srcReg), .data_out(L4));

    Registers Register_Top(.busA(L2), .busB(L3), .Ra(Instr[9:5]), .Rb(L4), .Rw(Instr[4:0]), .busW(L5), .clk(clk), .RegWr(RegWr));

    MUX_b MUXb_Top(.data_a(L1), .data_b(L3), .flag(ALUBSrc), .data_out(L6));

    ALU ALU_Top(.a(L2), .b(L6), .op(AluCtrl), .AddResult(L7), .Zero(Zero), .LT(LT));

    RAM RAM_Top(.clk(clk), .MemWrEn(MemWrEn), .addr(L7), .data_in(L3), .data_out(L8));

    MUX_c MUXc_Top(.data_a(L8), .data_b(L7), .flag(MemToReg), .data_out(L5));

    CPU uut(.clk(clk), .rst(rst), .oe(oe));

    initial begin

        clk = 0;

        rst = 1;

        oe = 1;

        #40;

        rst = 0;

        #40;

    end

    always begin

        #20 clk = ~clk;

    end  

endmodule

在Vivado环境中,输入Verilog HDL设计代码,保存为.v文件。检查无误后,系统生成的RTL原理图如下:

ii.模型机的仿真波形截图如下。如下图,其中的L5为busW的值,可以观测到数据计算结果,通过计算可得运行结果与应用程序预计的结果相一致。

二、参考文献

[1]龙芯架构32位精简版参考手册:V1.02,龙芯中科技术股份有限公司.

[2]白中英, 戴志涛. 计算机组成原理.第六版立体化教材[M]. 科学出版社, 2019.

[3]计算机组成原理课程设计指导书.LoongArch之LA32R版,南通大学信息科学技术学院计算机组成原理课程组

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/794396
推荐阅读
相关标签
  

闽ICP备14008679号