赞
踩
本次课程设计的任务是:设计并实现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] ②si12是12位立即数,进行符号位扩展后与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指令相同 |
一台安装了EDA工具软件(Vivado)的计算机。
本次设计的模型机电路如图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.设计原理与内容
通用寄存器堆包含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指定的寄存器中 |
注:
该模块的Verilog HDL代码设计如下:
- module Registers(busA, busB, Ra, Rb, Rw, busW, clk, RegWr);
-
- input [31:0]busW;
-
- input clk;
-
- input RegWr;
-
- input [4:0]Rw;
-
- input [4:0]Ra;
-
- input [4:0]Rb;
-
- output [31:0]busA;
-
- output [31:0]busB;
-
- reg [31:0] regs [0:32];
-
- reg [31:0] busA;
-
- reg [31:0] busB;
-
- integer i;
-
- always@(*)begin
-
- regs[0]=0;
-
- busA = regs[Ra];
-
- busB = regs[Rb];
-
- end
-
- always@(posedge clk)begin
-
- if(RegWr == 1)begin
-
- if(Rw == 0)begin
-
- regs[Rw] = 0;
-
- end
-
- else begin
-
- regs[Rw] = busW;
-
- end
-
- end
-
- end
-
- endmodule
一个立即数扩展模块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代码设计如下:
- module Ext(input[31:0] DataIn, input[1:0]ExtOp,
-
- output[31:0]Dataout);
-
- wire [31:0]imm12;
-
- wire [31:0]imm16;
-
- wire [31:0]imm20;
-
- wire [31:0]imm26;
-
- //对ADDI.W, LD.W, ST.W指令中的12位立即数进行符号位扩展
-
- assign imm12= {{20{DataIn[21]}},DataIn[21:10]};
-
- //对BEQ,BLT指令中的立即数进行符号位扩展及其他部分的拼接
-
- assign imm16={{14{DataIn[25]}} , {DataIn[25:10], 2'b0}};
- // 对LUI12I.W指令中的20位立即数,低12位补0
- assign imm20={DataIn[24:5], 12'b0};
-
- //对B指令中的立即数进行符号位扩展及其他部分的拼接
-
- assign imm26={{4{DataIn[25]}}, DataIn[9:0] , {DataIn[25:10] , 2'b0}};
- reg [31:0]Dataout;
- always @(*)
- begin
- case(ExtOp)
- 2'b00: Dataout <= imm12;
-
- 2'b01: Dataout <= imm16;
- 2'b10: Dataout <= imm20;
-
- 2'b11: Dataout <= imm26;
- default: Dataout <= imm26;
- endcase
- end
-
- endmodule
该模块的参考电路框图如下:
该模块的功能及引脚信号说明如下:
信号名称 | 功能说明 |
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代码设计如下:
- module PC(rst, clk, offset, pc_inc, PCdata);
-
- input rst;
-
- input clk;
-
- input [31:0]offset;
-
- input pc_inc;
-
- output [31:0]PCdata;
-
- reg [31:0]PCdata;
-
- always@(posedge clk)begin
-
- if(rst==1)begin
-
- PCdata = 0;
-
- end
-
- else begin
-
- if(pc_inc == 1)begin
-
- PCdata = PCdata + 4;
-
- end
-
- else begin
-
- PCdata = PCdata + offset;
-
- end
-
- end
-
- end
-
- endmodule
该模块的参考电路框图如下:
该模块的功能及引脚信号说明如下:
信号名称 | 功能说明 |
a, b | 两个32位的数据输入 |
op | 运算类型选择输入 |
AddResult | 运算结果输出 |
Zero | 0标志位输出。运算结果AddResult为0时,Zero=1;否则Zero=0 |
该模块的Verilog HDL代码设计如下:
- module ALU(input[31:0] a, input[31:0] b, input[2:0] op, output[31:0] AddResult, output Zero, output LT);
-
- wire [31:0]m;
-
- wire [31:0]n;
-
- wire [31:0]p;
-
- wire [31:0]q;
-
- assign m = a & 32'h80000000;
- assign n = b & 32'h80000000;
-
- assign p = a & 32'h7fffffff;
- assign q = b & 32'h7fffffff;
-
- reg [31:0]AddResult;
-
- always @(*)
-
- begin
-
- case(op)
-
- 3'b000:AddResult <= a + b;
- 3'b001:AddResult <= a - b;
-
- 3'b010:AddResult <= a & b;
- 3'b011:AddResult <= a | b;
-
- 3'b100:AddResult <= ~(a | b);
- 3'b101:if(m == 32'h00000000 && n== 32'h00000000)begin
-
- if(p>q)begin
-
- AddResult <= 1;
-
- end
-
- else begin
-
- AddResult <= 0;
-
- end
-
- end
-
- else if (m == 32'h00000000 && n== 32'h80000000)begin
-
- AddResult <= 0;
-
- end
-
- else if (m == 32'h80000000 && n== 32'h80000000)begin
-
- if (p>q)begin
-
- AddResult <= 1;
-
- end
-
- else begin
-
- AddResult <= 0;
-
- end
-
- end
-
- else begin
-
- AddResult <= 1;
-
- end
-
- 3'b110: if (a<b)begin
- AddResult <= 1;
- end
- else begin
- AddResult <= 0;
- end
- 3'b111:AddResult <= b;
-
- default:AddResult <= b;
-
- endcase
-
- end
-
- reg Zero;
-
- reg LT;
-
- always @(*)
-
- begin
-
- if (AddResult==0)begin
-
- Zero <= 1;
-
- LT <= 1;
-
- end
-
- else begin
-
- LT <= 0;
-
- end
-
- end
-
- endmodule
该模块的参考电路框图如下:
图中信号说明如下:
信号名称 | 功能说明 |
addr | 32位地址总线,用于传送地址,以便按地址访问存储单元。 |
data_in | 32位数据输入总线 |
data_out | 32位数据输出总线 |
clk | 时钟信号,上升沿有效 |
MemWrEn | 写使能信号。 当MemWrEn为0时,数据从addr地址端口指定的内存单元读出。 当MemWrEn为1时,配合clk时钟信号工作,在clk上升沿,数据存入由addr地址端口指定的内存单元。 |
该模块的Verilog HDL代码设计如下:
- module RAM(clk, MemWrEn, addr, data_in, data_out);
-
- input clk;
-
- input MemWrEn;
-
- input [31:0] addr;
-
- input [31:0] data_in;
-
- output [31:0]data_out;
-
- reg [31:0] regs [0:65535];
-
- reg [31:0] data_out;
-
- always@(*)begin
-
- if(MemWrEn == 0)begin
-
- data_out = regs[addr];
-
- end
-
- end
-
- always@(posedge clk)begin
-
- if(MemWrEn == 1)begin
-
- regs[addr] = data_in;
-
- end
-
- end
-
- endmodule
该模块的参考电路框图如下:
图中信号说明如下:
信号名称 | 功能说明 |
addr | 32位地址总线,用于传送地址,以便按地址访问存储单元。 |
data_out | 32位数据输出总线 |
该模块的Verilog HDL代码设计如下:
- module ROM(address, oe,dataRomOut);
-
- input [31:0]address;//地址
-
- input oe;//oe 为输出允许
-
- output [31:0]dataRomOut;//数据输出
-
- reg [31:0]RomOut;
-
- always @(*) //任何信号(电平)发生改变模块都执行
-
- begin
-
- if (oe)
-
- case(address[6:2])
-
- 5'b00000:RomOut <= 32'b000101_0_0000_0000_0000_0000_0001_00001;
-
- 5'b00001:RomOut <= 32'b000101_0_0000_0000_0000_0000_0010_00010;
-
- 5'b00010:RomOut <= 32'b000101_0_1111_1111_1111_1111_1111_00011;
-
- 5'b00011:RomOut <= 32'b000101_0_1111_1111_1111_1111_1110_00100;
-
- 5'b00100:RomOut <= 32'b000000_0000_01_00000_00010_00001_00101;
-
- 5'b00101:RomOut <= 32'b000000_0000_01_00100_00100_00011_00110;
-
- 5'b00110:RomOut <= 32'b000000_0000_01_00100_00011_00100_00111;
-
- 5'b00111:RomOut <= 32'b000000_0000_01_00101_00101_00001_01000;
-
- 5'b01000:RomOut <= 32'b000000_0000_01_00101_00001_00101_01001;
-
- 5'b01001:RomOut <= 32'b001010_0110_0000_0000_1010_00010_00101;
-
- 5'b01010:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
-
- 5'b01011:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
-
- 5'b01100:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
-
- 5'b01101:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
-
- 5'b01110:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
-
- 5'b01111:RomOut <= 32'b001010_0010_0000_0000_1010_00010_01010;
-
- default: RomOut <= 32'h0;
- endcase
- else RomOut <= 32'hzz;
-
- end
-
- assign dataRomOut=RomOut;
-
- endmodule
该电路的参考结构图如下:
图中输入信号Instr[31:15]为要执行的指令字的部分字段,输出信号RegWr, AluCtrl, ALUBSrc, ExtOp, MemWrEn,MemToReg和srcReg为控制器根据不同指令所产生的控制信号。
该模块的Verilog HDL代码设计如下:
- 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);
-
- reg RegWr;
-
- reg [2:0]AluCtrl;
-
- reg ALUBSrc;
-
- reg [1:0]ExtOp;
-
- reg MemWrEn;
-
- reg MemToReg;
-
- reg srcReg;
-
- reg Br;
-
- reg Br_E_L;
-
- always@(*)begin
-
- if(Instr==17'b00000000000100000)begin
- RegWr = 1;
- AluCtrl = 0;
- ALUBSrc = 0;
- ExtOp = 0;
- MemWrEn = 0;
- MemToReg = 0;
- srcReg = 0;
- Br = 0;
- Br_E_L = 0;
- end
- else if (Instr==17'b00000000000100100)begin
-
- RegWr = 1;
-
- AluCtrl = 3'b101;
- ALUBSrc = 0;
- ExtOp = 0;
- MemWrEn = 0;
- MemToReg = 0;
- srcReg = 0;
- Br = 0;
- Br_E_L = 0;
- end
- else if (Instr==17'b00000000000100101)begin
-
- RegWr = 1;
-
- AluCtrl = 3'b110;
- ALUBSrc = 0;
- ExtOp = 0;
- MemWrEn = 0;
- MemToReg = 0;
- srcReg = 0;
- Br = 0;
- Br_E_L = 0;
- end
- else if (Instr[16:10]==7'b0001010)begin
-
- RegWr = 1;
-
- AluCtrl = 111;
-
- ALUBSrc = 1;
-
- ExtOp = 2'b10;
- MemWrEn = 0;
- MemToReg = 0;
- srcReg = 0;
- Br = 0;
- Br_E_L = 0;
- end
- else if(Instr[16:7]==10'b0010100010)begin
-
- RegWr = 1;
-
- AluCtrl = 0;
-
- ALUBSrc = 1;
-
- ExtOp = 0;
-
- MemWrEn = 0;
-
- MemToReg = 1;
-
- srcReg = 0;
-
- Br = 0;
-
- Br_E_L = 0;
-
- end
-
- else if(Instr[16:7]==10'b0010100110)begin
- RegWr = 0;
- AluCtrl = 0;
- ALUBSrc = 1;
- ExtOp = 0;
- MemWrEn = 1;
- MemToReg = 0;
- srcReg = 1;
- Br = 0;
- Br_E_L = 0;
- end
- else begin
- RegWr = 1;
- AluCtrl = 0;
- ALUBSrc = 0;
- ExtOp = 0;
- MemWrEn = 0;
- MemToReg = 0;
- srcReg = 0;
- Br = 0;
- Br_E_L = 0;
- end
- end
- endmodule
该电路的参考结构图如下:
该模块的Verilog HDL代码设计如下:
- module CPU(input clk, input rst, input oe);
-
- 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;
-
- 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));
-
- endmodule
在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 |
运行结果如下:
在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 |
运行结果如下:
在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 |
运行结果如下:
在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 |
运行结果如下:
在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 |
运行结果如下:
在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 |
运行结果如下:
在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 |
运行如下:
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 |
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版,南通大学信息科学技术学院计算机组成原理课程组
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。