实验五、单周期 CPU 设计与实现
——十条指令 CPU
专业班级:
学
姓
号:
名:
目录
一、实验目的:
二、实验内容:
1 、CPU 各模块 Verilog 实现
......................................................................................................................................3
......................................................................................................................................3
1. 非访存指令............................................................................................................................... 3
2. 访存指令................................................................................................................................... 3
3. 转移类指令 ........................................................................................................................... 3
三、实验原理............................................................................................................................................4
四、实验步骤............................................................................................................................................5
.......................................................................................... 5
1) PC 模块.............................................................................................................................5
2) 指令存储器模块 ...........................................................................................................6
3) 累加器.............................................................................................................................7
4) ALU ...................................................................................................................................8
5) 控制单元 .....................................................................................................................9
6) 数据存储器模块 ...........................................................................................................9
2、 CPU 顶层文件封装实现 ................................................................................................... 11
3、 CPU 模拟仿真 ................................................................................................................... 12
1)TestBench 关键代码 ....................................................................................................12
2)ModelSim 仿真及分析 ..................................................................................................13
五、总结..................................................................................................................................................20
一、实验目的:
通过设计并实现支持 10 条指令的 CPU,进一步理解和掌握
CPU 设计的基本原理和过程。
二、实验内容:
设计和实现一个支持如下十条指令的单周期 CPU。
1.非访存指令
清除累加器指令 CLA
累加器取反指令 COM
算术右移一位指令 SHR:将累加器 ACC 中的数右移一位,
结果放回 ACC
循环左移一位指令 CSL:对累加器中的数据进行操作
停机指令 STP
2.访存指令
加法指令 ADD
存数指令 STA
取数指令 LDA
3.转移类指令
无条件转移指令 JMP imm:signExt(imm) -> PC
有条件转移(负则转)指令 BAN X: ACC 最高位为 1 则
(PC)+ X -> PC,否则 PC 不变
三、实验原理
1、约定机器字长、指令字长和存储字长均为 16 位。
2、约定指令格式如下图所示,高 4 位为指令的操作码字段,低
12 位为指令的地址码或者立即寻址的操作数。
3、指令和相应的操作码对照表
4、CPU 原理图
四、实验步骤
1 、CPU 各模块 Verilog 实现
1) PC 模块
输入
输出
功
能
时钟信号 clk、重置信号 rst 、停机信号 stop、无条件转移
信号 wr、条件转移信号 judge、 pc 修改量 jmp(12 位)
指令地址 addr(12 位)
每个时钟上升沿 addr 的值自动加 1,并输出
如果 wr 为 1,修改 addr 为 jmp - 1
如果 judge 为 1,修改 addr 为 addr + jmp
如果 rst 为 1,修改 addr 为 0
Verilog 关键代码:
module pc(
input wire clk, rst, stop, Wr, judge,
input wire [11:0] jmp,
output reg [11:0] addr
);
reg state;
initial begin
state=1;
addr = 0;
end
always@* begin
if(stop == 1)
state = 0;
if(rst == 1)
addr= 0;
end
always@(posedge clk) begin
if(state == 1)
addr = addr + 1;
end
always@(negedge clk) begin
if(wr== 1)
addr=jmp 一 1;
if(judge == 1)
addr=addr+jmp-1;
end
endmodule
2) 指令存储器模块
输
入
输
出
功
能
12 位指令地址 addr
16 位指令 ins
存放待执行的指令(初始化),并根据地 址输出指令
Verilog 关键代码:
module insmemory(
input wire [11:0] addr,
output reg [15:0] ins
);
reg [15:0] unit [12'b1111111111:0];
initial begin
unit[0] = 16' b011000000000000;//LDA 取数把地址为 0 的内存中的数取到 ACC 中
unit[1] = 16' b0001000000000000;//C0M 累加器取反 ACC 取反
unit[2] = 16' b001000000000000;//SHR 算术右移 ACC 算数右移
unit[3] = 16' b001000000000000;//CSL 循环左移 ACC 循环左移
unit[4] = 16' 0000000000000000;//CLA 清除累加器清除 ACC
unit[5] = 16'b0100000000000001;//ADD 加法把地址为 1 的内存中的数和 ACC 相加,
再保存到 ACC 中
unit[6] = 16' b0101000000000010;//STA 存数把 ACC 的数保存到地址为 2 的内存单
元
unit[7] = 16' b0111000000001001;//JMP 无条件转移无条件转移到第 9 条指令
unit[9] = 16' b100000000000010;//BAN 条件转移符合条件则地址加 2
unit[11] = 16'b111000000000000;//STP 停机
end
a lways@* begin
ins = unit [addr] ;
end
Endmodule
3) 累加器
输
入
输
出
功
能
时钟信号 clk、读写控制线 wr、输入数据 indata
输出数据 outdata
ACC 数据从 outdata 输出,如果 wr 有效,在 clk 下降沿将会把
indata 写入 ACC 中。
Verilog 关键代码:
module acc(
input wire clk, wr,
input wire [15:0] indata,
output wire [15:0] outdata
);
reg [15:0] acc;
assign outdata = acc;
initial begin
acc = 0;
end
always@(negedge clk) begin
if(wr== 1)
acc = indata;
end
endmodule
4) ALU
输
入
输
出
功
能
操作数 in1 和 in2、操作选择信号 alu_op
ALU 运算结果 Z
根据操作选择信号计算 in1 和 in2 的运算结果 Z
Verilog 关键代码:
module alu(
input wire [3:0] op,
input wire [15:0] in1, in2,
output reg judge,
output reg [15:0] z
)
initial begin
judge = 0;
Z=0;
end
always@* begin
case(op)
4'b0000: z = 0;//CLA
4'b0001: z = ~in1;//COM
4'b0010: z = in1[15] == 1 ? {1'b1, in1[15:1]} : {1'b0, in1[15:1]};//SHR