目录
一、前端设计
1.设计概述
设计了一个单核顺序执行支持16条指令的简易8位CPU,无中断和异常处理、无流水线并行、无乱序执行等高效计算技术。该处理器支持内存读写、寄存器读写、跳转指令及常见的算数、逻辑运算,片上集成了16Byte的寄存器组,可拓展为GPIO用于控制常见的外设。
2.指令集
该处理器所支持的指令集长度类型有两种,分别为短指令和长指令。短指令8位,包含指令编码和寄存器地址;长指令16位,包含指令编码、寄存器地址和存储器地址,由于总线为8位,因此需要两次取指操作才能读取完整的指令。长指令和短指令的格式如下图所示:
指令编码采用四位二进制表示,定义了16种指令,如下表所示:
3.系统组成
(1)概述
根据冯诺依曼架构,计算机由运算器、存储器、控制器、输入和输出组成,整个处理器系统由CPU核和存储器两部分组成,CPU包含了运算器和控制器;由于输入输出种类多样且需要外设控制、中断和异常控制等功能,这在本设计中并未实现,因此本设计不包含输入输出接口。整个CPU系统如下图所示
CPU核由程序计数器PC、指令寄存器IR、累加器ACC、通用寄存器REG、地址选择器ADDR_MUX、算数逻辑单元ALU和控制器CTRL组成;存储器由ROM和RAM组成,ROM中存放程序和数据,RAM中存放数据。CPU核的结构框图如下所示:
(2)存储器
①只读存储器ROM
功能
存放所运行程序的机器码和数据。ROM只读指令接受输入地址,当读信号和使能信号同时为高电平时输出对应地址存储的指令,否则保持高阻态。地址和数据都是8位,可寻址及存储容量大小为256Byte。
框图 端口
Vivado RTL分析后Schematic
②随机读写存储器RAM
功能
存放程序运行的数据、中间数据和运行结果。RAM可读可写,接受8位地址,当读信号和使能信号有效时,输出对应地址存储的数据,否则保持高阻态;当写信号上升沿来临时,将输入输出写入地址对应位置,可寻址和存储容量大小为256Byte。
框图 端口
Vivado RTL分析后Schematic
(3)处理器核
①程序计数器PC
功能
程序计数器(Program Counter,PC),也叫做指令地址寄存器(Instruction Address Register,IAR),对应Intel X86体系CPU中的指令指针寄存器(Instruction Pointer Register,IPR),用来存放要执行的下一条指令在现在代码段中的地址。本设计中PC由CTRL自动修改,同步清零,时钟上升沿触发,高电平使能PC计数。
框图 端口
Vivado RTL分析后Schematic
②指令寄存器IR
功能
指令寄存器(Instruction Register,IR),从数据总线DB上获取指令并解码,根据控制信号和指令类型将特定指令和地址输出到ALU、通用寄存器和地址选择器。
框图 端口
Vivado RTL分析后Schematic
③累加器ACC
功能
用于存储ALU计算的中间结果,同步清零,时钟上升沿触发,高电平使能输出当前的输入信号。
框图 端口
Vivado RTL分析后Schematic
④通用寄存器REG
功能
通用寄存器,存放从ROM/RAM或ACC的数据,输出寄存器中存储的数据到数据总线DB。
框图 端口
Vivado RTL分析后Schematic
⑤地址选择器ADDR_MUX
功能
接受控制使能虚拟号对输入的来自PC和IR的地址进行选择,高电平选通IR的地址,低电平选通PC的地址。
框图 端口
Vivado RTL分析后Schematic
⑥算数逻辑单元ALU
功能
算数逻辑单元(Arithmetic Logic Unit,ALU),根据指令类型来决定进行那种运算,从而将运算结果输出到通用寄存器REG或累加器ACC中。
框图 端口
Vivado RTL分析后Schematic
⑦控制器CTRL
功能
负责控制程序运行流程,根据IR解码的指令类型控制PC、IR、ALU、ADDR_MUX、REG、ACC、ROM和RAM的读写,以实现取指、译码、执行、回写的经典CPU工作流程,是CPU的重点和难点。
框图 端口
Vivado RTL分析后Schematic
状态转移图
状态编码与功能描述
二、仿真验证
1.测试平台
测试程序存放在ROM中,在testbench中仅需要施加时钟激励和使复位信号无效即可通过仿真波形判断程序运行结果和理想结果是否一直,从而判断CPU是否正常工作。测试程序如下:
mem[0] = 8'b0000_0000; //NOP
mem[1] = 8'b0001_0001; //LDO s1
mem[2] = 8'b01000001; //rom(65)
mem[3] = 8'b0001_0010; //LDO s2
mem[4] = 8'b01000010; //rom(66)
mem[5] = 8'b0001_0011; //LDO s3
mem[6] = 8'b01000011; //rom(67)
mem[7] = 8'b0100_0001; //PRE s1
mem[8] = 8'b0110_0010; //ADD s2
mem[9] = 8'b0011_0001; //LDM s1
mem[10] = 8'b0101_0011; //STO s3
mem[11] = 8'b0000_0001; //ram(1)
mem[12] = 8'b0010_0010; //LDA s2
mem[13] = 8'b0000_0001; //ram(1)
mem[14] = 8'b0100_0011; //PRE s3
mem[15] = 8'b0110_0010; //ADD s2
mem[16] = 8'b0011_0011; //LDM s3
mem[17] = 8'b0101_0011; //STO s3
mem[18] = 8'b0000_0010; //ram(2)
mem[19] = 8'b1110_0000; //JMP
mem[20] = 8'b00100001; //跳转地址33
mem[21] = 8'b1111_0000; //HLT
mem[33] = 8'b0100_0001; //PRE s1
mem[34] = 8'b1011_0010; //AND s2
mem[35] = 8'b0011_0100; //LDM s4
mem[36] = 8'b0100_0100; //PRE s4
mem[37] = 8'b1011_0011; //AND s3
mem[38] = 8'b0011_0101; //LDM s5
mem[39] = 8'b0100_0101; //PRE s5
mem[40] = 8'b1100_0010; //OR s2
mem[41] = 8'b0011_0110; //LDM s6
mem[42] = 8'b0100_0110; //PRE s6
mem[43] = 8'b1101_0100; //XOR s4
mem[44] = 8'b0011_0111; //LDM s7
mem[45] = 8'b0100_0111; //PRE s7
mem[46] = 8'b1101_0011; //XOR s3
mem[47] = 8'b0011_1000; //LDM s8
mem[48] = 8'b1010_0001; //INV s1
mem[49] = 8'b0011_1001; //LDM s9
mem[50] = 8'b0111_0001; //SHL s1
mem[51] = 8'b1000_0001; //SHR s1
mem[52] = 8'b1001_1001; //SAR s9
mem[53] = 8'b1110_0000; //JMP
mem[54] = 8'b00010101; //跳转地址21
mem[65] = 8'b00100101; //37
mem[66] = 8'b01011001; //89
mem[67] = 8'b00110101; //53
2.仿真结果
(1)NOP功能正确
(2)LDO功能正确
经过三次访存取数后,寄存器对应地址上存入了相应的数据。
(3)PRE功能正确
(4)STO功能正确
(5)LDA功能正确
(6)JMP功能正确
(7)ADD功能正确
(8)LDM功能正确
(9)AND功能正确
(10)OR功能正确
(11)XOR功能正确
(12)INV功能正确
(13)SHL功能正确
(14)SHR功能正确
(15)SAR功能正确
(16)HLT功能正确
三、逻辑综合
采用Synopsys DC进行综合,编写tcl脚本进行设计读入、时钟创建以及工作环境、输入驱动、输出负载、输入输出延时的设置,进行综合并生成设计报告。
1.综合脚本
由于ROM和RAM等存储器作为外设不属于CPU CORE,且需要专门的工具Memory Complier进行后端设计,因此在综合中不加入ROM和RAM,仅对CORE进行综合,编写综合脚本如下:
#_________________________________________________________
# Design entry
set active_design CORE
#read_verilog $active_design.v
analyze -format verilog ACC.v
analyze -format verilog ADDR_MUX.v
analyze -format verilog ALU.v
analyze -format verilog CTRL.v
analyze -format verilog IR.v
analyze -format verilog PC.v
analyze -format verilog REG.v
analyze -format verilog $active_design.v
elaborate ACC
elaborate ADDR_MUX
elaborate ALU
elaborate CTRL
elaborate IR
elaborate PC
elaborate REG
elaborate $active_design
current_design $active_design
link
uniquify
check_design
#_________________________________________________________
# Setup operating conditions,wire-load,clock,reset
set_operating_conditions ss_1p62v_125c#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
set_wire_load_model -name csm18_wl10#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
set_wire_load_mode top
set_max_area 0
set MY_CLK clk
set CLK_PER 10.0
create_clock -period $CLK_PER \
-waveform [list 0 5] \
-name $MY_CLK [get_ports $MY_CLK]
set_clock_latency 0.1 [get_clocks $MY_CLK]
set_clock_uncertainty 0.2 [get_clocks $MY_CLK]
set_clock_transition 0.1 [get_clocks $MY_CLK]
set_dont_touch_network [list $MY_CLK ]
#_________________________________________________________
# Input drives
set_driving_cell -lib_cell BUFX2 -pin Y [all_inputs]
#set_drive 0 [list $MY_CLK rst]
#_________________________________________________________
# Output loads
set_load 1 [all_outputs]
#_________________________________________________________
# Set input & output delays
set_input_delay 3 -clock $MY_CLK [all_inputs]
set_output_delay 3 -clock $MY_CLK [all_outputs]
#_________________________________________________________
# Compile
compile
#_________________________________________________________
# Report
report_timing
report_area
report_power
report_timing -nworst 5 > ./dc_out/$active_design.rpt
report_area >> ./dc_out/$active_design.rpt
report_power >> ./dc_out/$active_design.rpt
#_________________________________________________________
# Write the database
write -hierarchy -output ./dc_out/$active_design.db $active_design
write -hierarchy -format verilog -output ./dc_out/$active_design.v $active_design
write_sdf ./dc_out/$active_design.sdf
write_sdc ./dc_out/$active_design.sdc
puts ">>>>>>finished<<<<<<"
2.综合结果
①综合后电路图
CORE
CTRL
REG
IR
ACC
ALU
PC
ADDR_MUX
②综合报告
时序报告
面积报告
功耗报告
三、综合后仿真
1、仿真设置
综合后仿真使用Synopsys VCS进行,需要的文件如下
综合后仿真需要的综合后网表文件CORE.v、器件库文件csm18ic.v、引导VCS仿真的Makefile文件和filelist.f文件以及测试平台文件CORE_tb.v和测试中需要使用的模块文件RAM.v和ROM.v。
(1)Makefile
(2)Filelist.f
(3)CORE_tb.v
module CORE_tb;
// Ports
reg clk = 0;
reg rst_n = 0;
wire [7:0]DB,AB;
wire ROM_en,ROM_read,RAM_en,RAM_read,RAM_write;
CORE CORE_0 (
.clk (clk),
.rst_n (rst_n),
.DB (DB),
.AB (AB),
.ROM_en (ROM_en),
.ROM_read (ROM_read),
.RAM_en (RAM_en),
.RAM_read (RAM_read),
.RAM_write (RAM_write)
);
RAM RAM_0 (
.read (RAM_read),
.write (RAM_write),
.en (RAM_en),
.data (DB),
.addr (AB)
);
ROM ROM_0 (
.read (ROM_read),
.en (ROM_en),
.addr (AB),
.data (DB)
);
initial begin
$sdf_annotate("CORE.sdf",CORE_0);//将SDF延时文件反向标注到实例上
$fsdbDumpfile("CORE.fsdb");//生成FSDB文件使用Verdi进行查看
$fsdbDumpvars;
#100 rst_n = 1;
#1500;
$finish;
end
always #5 clk = !clk ;
endmodule
2.仿真结果
使用Verdi查看综合后仿真波形,如下图所示:
综合后仿真中DB、acc_out以及alu_out都有异常的不定态产生,原因有待进一步探究。
【附录】
CPU的RTL代码详见我的github仓库:https://github.com/lionelZhaowy/CPU8bit.git