精简指令集(RISC)CPU的构造原理和设计方法

Slides:



Advertisements
Similar presentations
第1章第1章 PC/AT 系統 1 Chapter 1 Chapter 1 PC/AT 系統 001.
Advertisements

天水圍的體育設施.
嵌入式系统与单片机 北京科技大学电子信息系.
程序的执行 程序执行和指令执行概述 数据通路基本结构和工作原理 流水线方式下指令的执行
建構 Beta電腦 – Fall /29/0.
计算机组成原理 北京理工大学计算机科学工程系 赵清杰 北京理工大学计算机科学工程系.
第三章 CPU子系统 西南石油大学计算机科学学院 主讲教师 杨 梅 联系电话:
最新計算機概論 第3章 計算機組織.
第五章 中央处理单元.
计算机导论 第4讲 微型计算机硬件系统 1.
Chapter 5 Sequential Logic Circuit
数字系统设计 Digital System Design
大连理工大学软件学院 软件工程系 赖晓晨 计算机组成与结构 大连理工大学软件学院 软件工程系 赖晓晨
第七章 控制器 7.1 控制器的组成及指令的执行 7.2 控制方式和时序的产生 7.3 微程序控制器 7.4 微程序控制器及其微程序设计举例
CH.2 Introduction to Microprocessor-Based Control
汇编语言与接口技术 教师:范新民.
Chapter 5 電腦元件 目標---- 研讀完本章後,你應該可以: 閱讀有關電腦的廣告以及了解它的專業用語(行話)。
得技通电子 问题 1 右何者非為假指令 (1) XRL (2) EQU (3) MACRO (4) ORG.
微处理器设计1 刘鹏 College of ISEE Zhejiang University
臺北市立大學 資訊科學系(含碩士班) 賴阿福 CS TEAM
VHDL數位電路實習與專題設計 文魁資訊-UE301
触发器和时序电路分析 刘鹏 浙江大学信息与电子工程学院 March 30, 2017 ZDMC.
第4章 处理器(CPU) 4.1 引言 4.2 逻辑设计的一般方法 4.3 建立数据通路 4.4 一个简单的实现机制 4.5 多周期实现机制.
VHDL數位電路實習與專題設計 文魁資訊-UE301
Chapter 5 Verilog 硬體描述語言
Chapter 5 Verilog硬體描述語言
指令集架構 計算機也跟人類一樣,需要提供一套完整的語言讓人們跟它充分溝通,以完成正確的計算工作。
1-1 微電腦系統單元 1-2 微電腦系統架構 1-3 微控制器(單晶片微電腦) 1-4 類比與數位訊號介面
1-1 微電腦系統單元 1-2 微電腦系統架構 1-3 微控制器(單晶片微電腦) 1-4 類比與數位訊號介面
Ch01-2 Verilog語法 資料流(DataFlow)設計 行為(Behavior)設計
第17章 Verilog中的高级结构 学习内容: 任务和函数的定义和调用 怎样使用命名块 怎样禁止命名块和任务 有限状态机(FSM)及建模.
EDA技术 廖义奎.
5 Computer Organization (計算機組織).
第四阶段实验 ISP器件的设计与应用 一、实验目的 二、实验内容与要求 三、ISP器件的开发流程 四、EDA Pro2K实验系统介绍
数字系统设计复习 Digital System Design Summary
微处理器设计2 刘鹏 College of ISEE Zhejiang University
一个非常简单的CPU的设计 1、组合逻辑控制器 2、微程序控制器.
Danny Mok Altera HK FAE AHDL培训教材 Danny Mok Altera HK FAE 2018/12/9 P.1.
Verilog硬件描述语言基础.
第15章 串行通信及接口电路.
第14章 其它DSP设计库 14.1 总线控制库 14.2 复数信号库 14.3 Gates库 14.4 状态机函数库
单片机原理 单 片 机 单片机接口技术 单片机应用技术.
计算机原理及系统结构 第十八讲 主讲教师:赵宏伟                 学时:64.
陳慶瀚 機器智慧與自動化技術(MIAT)實驗室 國立中央大學資工系 2013年5月28日
1.3 微型计算机的结构和工作原理.
语法进阶.
时序电路设计 刘鹏 浙江大学信息与电子工程系 Apr. 24, 2011 EE141
数字系统设计 Digital System Design
本 章 重 点 单片机的结构特点 单片机的存储器特点 I/O端口的特点 CPU时序 课时安排:3个课时.
CISC vs. RISC 複雜指令集電腦(Complex Instruction Set Computer: CISC)
认识计算机系统.
第二章 8086微处理器. 第二章 8086微处理器 微处理器的基本结构 8086微处理器的主要特性和内部结构 8086CPU的工作模式和引脚信号 8086的存储器管理 8086的总线操作和时序.
微机原理及接口技术 主讲人 钱晓捷.
4-15 WDT HT66F50.
第一次上机安排 第六周 第七周 周一晚(提高1、2,通信001~012) 周二上(通信014~085) 周四上(通信086~154)
微机原理与接口技术 西安邮电大学计算机学院 王忠民.
第14章 对验证的支持 学习内容 理解Verilog文本输出 理解不同的读取仿真时间的系统函数 理解 Verilog文件I/O功能.
计算机学院 数字逻辑实验的要求.
汽车单片机应用技术 学习情景1: 汽车空调系统的单片机控制 主讲:向楠.
计算机EDA设计 教 程 北航计算机学院 艾明晶.
CPU中的专用寄存器(SFR) 一、累加器Acc 二、通用寄存器B 三、程序计数器PC 四、堆栈指针SP 五、数据指针DPTR
2019/4/29 计算机组成原理 辅导教师:陆明强.
设计示例一 用门级结构描述D触发器:.
中五級電腦科 PASCAL檔案處理.
FPGA组合逻辑 王安然.
Verilog HDL 基本语法 STEP 2016/12/3.
按键处理部分 王安然.
第二章 8086系统结构 /8086的存储器组织 的系统配置及引脚功能 CPU时序
单片机原理及接口技术 前修课程:数模电、微机原理.
第5章 中 央 处 理 器 5.1 CPU的功能和组成 5.2 指令周期 5.3 时序产生器和控制方式 5.4 微程序控制器
Presentation transcript:

精简指令集(RISC)CPU的构造原理和设计方法

CPU:中央处理单元,是计算机的核心部件 计算机进行信息处理分两个步骤: 将数据和程序(指令序列)输入到计算机的存储器中 从第一条指令的地址起开始执行程序,得到所需结果,结束运行。 CPU的作用:协调并控制计算机的各部件,使之有条不紊的执行程序

CPU的基本功能: 取指令-地址与控制信号 分析指令-即指令译码,操作和操作控制信号 执行指令-操作控制信号作用于各部件 CPU的基本功能概括: 能对指令进行译码并执行规定的动作 可以进行算术和逻辑运算 能与存储器和外设交换数据 提供系统所需的控制

CPU的内部结构: 算术逻辑运算单元(ALU) 累加器 程序计数器 指令寄存器和译码器 时序和控制部件 RISC即精简指令集计算机: Reduced Instruction Set Computer 时序控制信号由硬件而不是微程序控制

MICRO COMPUTER SYSTEM cpu AB DB 地址 译码器 ROM RAM clock read reset write

指令 指令数目:8条 地址空间:213=8K 指令码 地址码 高8位 低8位 D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 高8位 低8位 指令数目:8条 地址空间:213=8K

指令集 助记符 操作码 功能 HLT 3'b000 暂停 SKZ 3‘b001 累加器为零转移ADD 3’b010 加 助记符 操作码 功能 HLT 3'b000 暂停 SKZ 3‘b001 累加器为零转移ADD 3’b010 加 ANDD 3‘b011 与 XORR 3‘b100 或 LDA 3‘b101 取数 STO 3‘b110 存数 JMP 3‘b111 转移

CPU的基本功能: 取指令-地址与控制信号 分析指令-即指令译码,操作和操作控制信号 执行指令-操作控制信号作用于各部件 CPU的基本功能概括: 能对指令进行译码并执行规定的动作 可以进行算术和逻辑运算 能与存储器和外设交换数据 提供系统所需的控制

CPU的内部结构: 算术逻辑运算单元(ALU) 累加器 程序计数器 指令寄存器和译码器 时序和控制部件

CPU的结构功能图 AB DB clk rst fetch 时钟信号 数据控制 指令寄存器 IR 地址选择 datactl_ena alu_ena load_ir 程序计数器 PC 算逻单元 ALU load_pc inc_pc 累加器 A load_acc 控制状态机 halt rd wr

AB DB clk fetch 时钟信号 数据控制 指令寄存器 IR 地址选择 rst 程序计数器 PC 算逻单元 ALU alu_ena inc_pc 累加器 A datactl_ena load_ir load_pc load_acc 控制状态机 halt rd wr clk 1 2 3 4 5 6 7 fetch alu_ena halt指令 inc_pc rd load_ir halt

累加器 指令寄存器 算逻单元 数据控制 地址选择 程序计数器 控制状态机 时钟信号 AB DB rd load_acc fetch inc_pc load_ir alu_ena clk 1 2 3 4 5 6 7 fetch LDA 1000 alu_ena B0 00 0000 0001 ROM 0002 inc_pc rd load_ir data B0 00 EE load_acc EE 01 1000 1001 RAM address 0000 0001 0002 1000

累加器 指令寄存器 算逻单元 数据控制 地址选择 程序计数器 控制状态机 时钟信号 AB DB rd load_acc fetch inc_pc load_ir alu_ena clk 1 2 3 4 5 6 7 fetch ADD 1001 alu_ena 50 01 0002 0003 ROM 0004 inc_pc rd load_ir data 50 01 11 load_acc EE 11 1000 1001 RAM address 0002 0003 0004 1001

累加器 指令寄存器 算逻单元 数据控制 地址选择 程序计数器 控制状态机 时钟信号 AB DB rd load_acc fetch inc_pc load_ir alu_ena clk 1 2 3 4 5 6 7 fetch STO 1001 alu_ena D0 01 0004 0005 ROM 0006 inc_pc rd load_ir data D0 01 FF wr EE 01 1000 1001 RAM address 0004 0005 0006 1001

17.3.1 时钟发生器 fetch是控制信号,clk的8分频信号 alu_ena用于控制算术逻辑运算单元 clk是时钟信号 reset是复位信号

17.3.1 时钟发生器 状态转移图 Idle idle S1 S2 S3 S4 S5 S6 S7 S8 S1 S2 S3 S4 S5 S6

17.3.1 时钟发生器 //-------clk_gen.v-------- `timescale 1ns/1ns module clk_gen(clk,reset,fetch,alu_ena); input clk, reset; output fetch, alu_ena; wire clk, reset; reg fetch, alu_ena; reg [7:0]state; parameter S1=8'b00000001, S2=8'b00000010, S3=8'b00000100, S4=8'b00001000, S5=8'b00010000, S6=8'b00100000, S7=8'b01000000, S8=8'b10000000, idle=8'b00000000;

always @(posedge clk) if(reset) begin fetch<=0; alu_ena<=0; state<=idle; end else case (state) … default:state<=idle; endcase case (state) S1: begin fetch<=1; state<=S2; end S2: state<=S3; S3: state<=S4; S4: state<=S5; S5: begin state<=S6; fetch=0; end S6: begin state<=S7; alu_ena<=1; end S7: begin alu_ena<=0; state<=S8; end S8: state<=S1; idle: state<=S1; default:state<=idle; endcase

17.3.2 指令寄存器 opcode[2:0] load_ir ir_addr[12:0] clk reset

`timescale 1ns/1ns module register(opc_iraddr,data,ena,clk,rst); output [15:0]opc_iraddr; input [7:0]data; input ena,clk,rst; reg [15:0]opc_iraddr; reg state; always @(posedge clk) begin if (rst) opc_iraddr<=16'b0000_0000_0000_0000; state<=1'b0; end else if (ena) casex(state) 1'b0:begin opc_iraddr[15:8]<=data; state<=1; end 1'b1:begin opc_iraddr[7:0]<=data; state<=0; default:begin opc_iraddr[15:0]<=16'bx; state<=1'bx; endcase else state<=1'b0; endmodule

17.3.3 累加器 alu_out[7:0] load_acc clk reset

module accum(accum,data,ena,clk,rst); output [7:0]accum; input [7:0]data; input ena,clk,rst; reg [7:0]accum; always @(posedge clk) begin if(rst) accum<=8'b0000_0000; else if(ena) accum<=data; end endmodule

17.3.4 算术逻辑运算器 助记符 操作码 功能 HLT 3'b000 暂停 SKZ 3‘b001 累加器为零转移ADD 3’b010 加 助记符 操作码 功能 HLT 3'b000 暂停 SKZ 3‘b001 累加器为零转移ADD 3’b010 加 ANDD 3‘b011 与 XORR 3‘b100 或 LDA 3‘b101 取数 STO 3‘b110 存数 JMP 3‘b111 转移

`timescale 1ns/1ns module alu(alu_out,zero,data,accum,alu_ena,opcode,clk); output [7:0]alu_out; output zero; input [7:0]data,accum; input [2:0]opcode; input alu_ena,clk; reg [7:0]alu_out; parameter HLT=3'b000, SKZ=3'b001, ADD=3'b010, ANDD=3'b011, XORR=3'b100, LDA=3'b101, STO=3'b110, JMP=3'b111; assign zero=!accum; always @(posedge clk) if(alu_ena) begin casex(opcode) HLT:alu_out<=accum; SKZ:alu_out<=accum; ADD:alu_out<=data+accum; ANDD:alu_out<=data&accum; XORR:alu_out<=data^accum; LDA:alu_out<=data; STO:alu_out<=accum; JMP:alu_out<=accum; default:alu_out<=8'bxxxx_xxxx; endcase end endmodule

17.3.5 数据控制器 alu_out[7:0] data[7:0] datactl_ena

module datactl(data,in,data_ena); output [7:0]data; input [7:0]in; input data_ena; assign data=(data_ena)?in:8'bz; endmodule

17.3.6 地址多路器

module adr(addr,fetch,pc_addr,ir_addr); input fetch; input [12:0]pc_addr,ir_addr; output [12:0]addr; assign addr=fetch? pc_addr:ir_addr; endmodule

17.3.7 程序计数器

module counter(pc_addr,ir_addr,load,clk,rst); input load,clk,rst; input [12:0]ir_addr; output [12:0]pc_addr; reg [12:0]pc_addr; always @(posedge clk or posedge rst) if(rst) pc_addr<=13'b0_0000_0000_0000; else if(load) pc_addr<=ir_addr; pc_addr<=pc_addr+1; endmodule

17.3.8 状态控制器

17.3.8 状态控制器 状态控制器两部分: 状态机(machine) 状态控制器machinectl rst有效,ena=0, 状态机停止工作。 `timescale 1ns/1ns module machinectl(ena,fetch,rst,clk); input fetch,rst,clk; output ena; reg ena; always @(posedge clk) begin if(rst) ena<=0; else if(fetch) ena<=1; end endmodule

17.3.8 状态控制器 状态机是CPU的核心部件,用于产生控制信号: 启动、停止某些部件 CPU执行读指令来读写接口、存储器 000 001 010 011 100 101 110 111 状态机是CPU的核心部件,用于产生控制信号: 启动、停止某些部件 CPU执行读指令来读写接口、存储器 状态变量state的值,是指令周期已经过的时钟数

指令周期中8个时钟完成的操作 第0个时钟:rd和load_ir为高电平,ROM中高八位指令代码-->指令寄存器 第1个时钟:rd和load_ir为高电平,inc_pc加1,故PC+1,ROM中低八位指令代码-->指令寄存器 第2个时钟:空操作 第3个时钟:PC+1,指向下一条指令;若HLT指令,halt=1;其它指令控制线输出为0

指令周期中8个时钟完成的操作 第4个时钟:若AND ADD XOR LDA,读相应地址数据; 若JMP, 目的地址-->PC; 若STO, 输出累加器数据。 第5个时钟:若AND ADD XOR , 进行相应运算; 若LDA, 数据-->运算器-->累加器;若JMP,锁存目的地址;若STO,数据到地址处。 第6个时钟:空操作 第7个时钟:若SKZ指令, PC+1跳过一条指令;否则PC无变化

`timescale 1ns/1ns module machine(inc_pc,load_acc,load_pc,rd,wr,load_ir,datactl_ena,halt,clk,zero,ena,opcode); output inc_pc,load_acc,load_pc,rd,wr,load_ir; output datactl_ena,halt; input clk,zero,ena; input [2:0]opcode; reg inc_pc,load_acc,load_pc,rd,wr,load_ir; reg datactl_ena,halt; reg [2:0]state; parameter HLT =3'B000, SKZ =3'b001, ADD =3'b010, ANDD=3'b011, XORR=3'b100, LDA =3'b101, STO =3'b110, JMP =3'b111;

always @(negedge clk) begin if(!ena) state<=3'b000; {inc_pc,load_acc,load_pc,rd}<=4'b0000; {wr,load_ir,datactl_ena,halt}<=4'b0000; end else ctl_cycle;

3'b010: begin //-------begin of task ctl_cycle------- task ctl_cycle; casex(state) 3'b000: begin {inc_pc,load_acc,load_pc,rd}<=4'b0001; {wr,load_ir,datactl_ena,halt}<=4'b0100; state<=3'b001; end 3'b001: begin {inc_pc,load_acc,load_pc,rd}<=4'b1001; state<=3'b010; 3'b010: begin {inc_pc,load_acc,load_pc,rd}<=4'b0000; {wr,load_ir,datactl_ena,halt}<=4'b0000; state<=3'b011;

3'b011: begin if(opcode==HLT) {inc_pc,load_acc,load_pc,rd}<=4'b1000; {wr,load_ir,datactl_ena,halt}<=4'b0001; state<=3'b100; end else {wr,load_ir,datactl_ena,halt}<=4'b0000;

3'b100: begin if(opcode==JMP) begin {inc_pc,load_acc,load_pc,rd}<=4'b0010; {wr,load_ir,datactl_ena,halt}<=4'b0000; end else if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA) {inc_pc,load_acc,load_pc,rd}<=4'b0001; else if(opcode==STO) {inc_pc,load_acc,load_pc,rd}<=4'b0000; {wr,load_ir,datactl_ena,halt}<=4'b0010; end else state<=3'b101; end

3'b101: begin //operation if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA) begin {inc_pc,load_acc,load_pc,rd}<=4'b0101; {wr,load_ir,datactl_ena,halt}<=4'b0000; end else if(opcode==SKZ && zero==1) {inc_pc,load_acc,load_pc,rd}<=4'b1000; {wr,load_ir,datactl_ena,halt}<=4'b0000; end else if(opcode==JMP) {inc_pc,load_acc,load_pc,rd}<=4'b1010; else if(opcode==STO) {inc_pc,load_acc,load_pc,rd}<=4'b0000; {wr,load_ir,datactl_ena,halt}<=4'b1010; end else state<=3'b110; end

3'b110://idle begin if(opcode==STO) {inc_pc,load_acc,load_pc,rd}<=4'b0000; {wr,load_ir,datactl_ena,halt}<=4'b0010; end else if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA) {inc_pc,load_acc,load_pc,rd}<=4'b0001; {wr,load_ir,datactl_ena,halt}<=4'b0000; else state<=3'b111;

3'b111: begin if(opcode==SKZ && zero==1) begin {inc_pc,load_acc,load_pc,rd}<=4'b1000; {wr,load_ir,datactl_ena,halt}<=4'b0000; end else {inc_pc,load_acc,load_pc,rd}<=4'b0000; state<=3'b000; end default: begin {wr,load_ir,datactl_ena,halt}<=4'b0000; state<=3'b000; end endcase endtask //-----------end of task ctl_cycle-------------- endmodule

MICRO COMPUTER SYSTEM cpu AB DB 地址 译码器 ROM RAM clock read reset write

17.3.9 外围模块(地址译码器)

module addr_decode(addr,rom_sel,ram_sel); output rom_sel,ram_sel; input [12:0]addr; reg rom_sel,ram_sel; always @(addr) casex(addr) 13'b1_1xxx_xxxx_xxxx:{rom_sel,ram_sel}<=2'b01; 13'b0_xxxx_xxxx_xxxx:{rom_sel,ram_sel}<=2'b10; 13'b1_0xxx_xxxx_xxxx:{rom_sel,ram_sel}<=2'b10; default:{rom_sel,ram_sel}<=2'b00; endcase endmodule

17.3.9 外围模块(RAM) module addr_decode(addr,rom_sel,ram_sel); output rom_sel,ram_sel; input [12:0]addr; reg rom_sel,ram_sel; always @(addr) casex(addr) 13'b1_1xxx_xxxx_xxxx:{rom_sel,ram_sel}<=2'b01; 13'b0_xxxx_xxxx_xxxx:{rom_sel,ram_sel}<=2'b10; 13'b1_0xxx_xxxx_xxxx:{rom_sel,ram_sel}<=2'b10; default:{rom_sel,ram_sel}<=2'b00; endcase endmodule

17.3.9 外围模块(ROM) module rom(data,addr,read,ena); output [7:0]data; input [12:0]addr; input ena,read; reg [7:0]mem[13'h1fff:0]; assign data=(read&&ena)?mem[addr]:8'hzz; endmodule

17.4 RISC_CPU操作和时序 主要操作: 系统的复位和启动操作 总线读操作 总线写操作

17.4.1 系统的复位和启动操作 复位状态reset=1: CPU内部寄存器全为零 数据总线为高阻状态 地址总线为0000H 所有控制信号为无效状态 启动状态reset=0: fetch上升沿启动CPU开始工作 从ROM的000处读指令并执行

17.4.2 总线读操作 复位状态reset=1: CPU内部寄存器全为零 数据总线为高阻状态 地址总线为0000H 所有控制信号为无效状态 fetch上升沿启动CPU开始工作 从ROM的000处读指令并执行

17.5 RISC_CPU 寻址方式和指令系统 指令数目:8条 地址空间:213=8K 指令码 地址码 高8位 低8位 D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 高8位 低8位 指令数目:8条 地址空间:213=8K

17.5 RISC_CPU 寻址方式和指令系统 直接寻址方式 数据放在存储器中,寻址单元的地址由指令直接给出。 指令码 地址码 LDA 010FH 56H 010CH 8EH 010DH 00H 010EH 77H 010FH 56H EDH 指令码 地址码 FFH FFH 00H 1 1 1 1 1 1 1

17.5 RISC_CPU 寻址方式和指令系统 HLT: 停机操作 该操作空一个指令周期,即8个时钟 SKZ: 为零跳过下一条语句 累加器结果为零,跳过下一语句; 累加器结果不为零,顺序执行。 ADD: 相加 累加器的值+地址所知的存储器中的数据,结果送回累加器。

17.5 RISC_CPU 寻址方式和指令系统 ANDD: 相与 累加器的值&地址所知的存储器中的数据,结果送回累加器。 XORR: 相异或 累加器的值^地址所知的存储器中的数据,结果送回累加器。 LDA: 读数据 地址所知的存储器中的数据送累加器。

17.5 RISC_CPU 寻址方式和指令系统 STO: 写数据 累加器中的数据送地址所指的存储器中 JMP: 无条件跳转语句 该操作跳转至指令给出的目的地址,继续执行。

累加器 指令寄存器 算逻单元 数据控制 地址选择 程序计数器 控制状态机 时钟信号 AB DB rd load_acc fetch inc_pc load_ir alu_ena clk 1 2 3 4 5 6 7 fetch LDA 1000 alu_ena B0 00 0000 0001 ROM 0002 inc_pc rd load_ir data B0 00 EE load_acc EE 01 1000 1001 RAM address 0000 0001 0002 1000

累加器 指令寄存器 算逻单元 数据控制 地址选择 程序计数器 控制状态机 时钟信号 AB DB rd load_acc fetch inc_pc load_ir alu_ena clk 1 2 3 4 5 6 7 fetch ADD 1001 alu_ena 50 01 0002 0003 ROM 0004 inc_pc rd load_ir data 50 01 11 load_acc EE 11 1000 1001 RAM address 0002 0003 0004 1001

累加器 指令寄存器 算逻单元 数据控制 地址选择 程序计数器 控制状态机 时钟信号 AB DB rd load_acc fetch inc_pc load_ir alu_ena clk 1 2 3 4 5 6 7 fetch STO 1001 alu_ena D0 01 0004 0005 ROM 0006 inc_pc rd load_ir data D0 01 FF wr EE 01 1000 1001 RAM address 0004 0005 0006 1001

ROM @00 111_00000 //00 BEGIN: JMP TEST_JMP 0011_1100 000_00000 //02 HLT 0000_0000 000_00000 //04 HLT 101_11000 //06 JMP_OK: LDA DATA_1 001_00000 //08 SKZ 000_00000 //0A HLT 101_11000 //0C LDA DATA_2 0000_0001 001_00000 //0E SKZ 111_00000 //10 JMP SKZ_OK 0001_0100 000_00000 //12 HLT 110_11000 //14 SKZ_OK: STO TEMP 0000_0010 101_11000 //16 LDA DTAT_1 110_11000 //18 STO TEMP 101_11000 //1A LDA TEMP 001_00000 //1C SKZ 0000_0000 000_00000 //1E HLT 100_11000 //20 XORR DTAT_2 0000_0001 001_00000 //22 SKZ 000_00000 //24 HLT 111_00000 //26 JMP XORR_OK 0010_0100 100_11000 //28 XORR_OK: XORR DATA_2 001_00000 //2A SKZ 000_00000 //2C HLT 000_00000 //2E EDN: HLT 111_00000 //30 JMP BEGIN @3C 111_00000 //3C TST_JMP: JMP JMP_OK 0000_0110 000_00000 //3E HLT

RAM @00 00000000 //1800 DATA_1 11111111 //1801 DATA_2 10101010 //1802 TEMP

17.6 RISC_CPU 模块的调试 cpu AB DB 地址 译码器 ROM RAM clock read reset write

`include "clk_gen.v" `include "register.v" `include "accum.v" `include "adr.v" `include "alu.v" `include "machine.v" `include "machinectl.v" `include "counter.v" `include "datactl.v" `timescale 1ns/1ns module cpu(clk,reset,halt,rd,wr,addr,data,opcode,fetch,ir_addr,pc_addr); input clk,reset; output rd,wr,halt; output [12:0]addr; output [2:0]opcode; output fetch; output [12:0]ir_addr,pc_addr; inout [7:0]data; wire clk,reset,halt; wire [7:0]data; wire [12:0]addr; wire rd,wr, wire fetch,alu_ena; wire [2:0]opcode; wire [12:0]ir_addr,pc_addr; wire [7:0]alu_out,accum; wire zero,inc_pc,load_acc,load_pc,load_ir,data_ena,contrl_ena; endmodule

module cpu(clk,reset,halt,rd,wr,addr,data,opcode,fetch,ir_addr,pc_addr); clk_gen m_clkgen(.clk(clk),.reset(reset),.fetch(fetch),.alu_ena(alu_ena)); register m_register(.data(data),.ena(load_ir),.rst(reset),.clk(clk),.opc_iraddr({opcode,ir_addr})); accum m_accum(.data(alu_out),.ena(load_acc),.clk(clk),.rst(reset),.accum(accum)); alu m_alu(.data(data),.accum(accum),.clk(clk),.alu_ena(alu_ena),.opcode(opcode),.alu_out(alu_out),.zero(zero)); machinectl m_machinectl(.clk(clk),.rst(reset),.fetch(fetch),.ena(contrl_ena)); machine m_machine(.inc_pc(inc_pc),.load_acc(load_acc),.load_pc(load_pc),.rd(rd),.wr(wr),.load_ir(load_ir), .clk(clk),.datactl_ena(data_ena),.halt(halt),.zero(zero),.ena(contrl_ena),.opcode(opcode)); datactl m_datactl(.in(alu_out),.data_ena(data_ena),.data(data)); adr m_adr(.fetch(fetch),.ir_addr(ir_addr),.pc_addr(pc_addr),.addr(addr)); counter m_counter(.clk(inc_pc),.rst(reset),.ir_addr(ir_addr),.load(load_pc),.pc_addr(pc_addr)); endmodule

`include "cpu.v" `include "ram.v" `include "rom.v" `include "addr_decode.v" `timescale 1ns/1ns `define PERIOD 100 module topcpu; reg reset_req,clock; integer test; reg [(3*8):0]mnemonic; reg [12:0]PC_addr,IR_addr; wire [7:0]data; wire [12:0]addr; wire rd,wr,halt,ram_sel,rom_sel; wire [2:0]opcode; wire fetch; wire [12:0]ir_addr,pc_addr; …….. endmodule

module topcpu; reg reset_req,clock; ……. cpu t_cpu(.clk(clock),.reset(reset_req),.halt(halt),.rd(rd),.wr(wr),.addr(addr),.data(data), .opcode(opcode),.fetch(fetch),.ir_addr(ir_addr),.pc_addr(pc_addr)); ram t_ram(.addr(addr[9:0]),.read(rd),.write(wr),.ena(ram_sel),.data(data)); rom t_rom(.addr(addr),.read(rd),.ena(rom_sel),.data(data)); addr_decode t_addr_decode(.addr(addr),.ram_sel(ram_sel),.rom_sel(rom_sel)); initial begin clock=1; $timeformat(-9,1,"ns",12); display_debug_message; sys_reset; test1; $stop; $finish; end …….. endmodule

module topcpu; …….. task display_debug_message; begin $display("\n********************************************************"); $display("*\"test1;\" to load the 1st diagnostic program. *"); end endtask task test1; test=0; disable MONITOR; $readmemb("test1.pro",t_rom.mem); $display("rom loaded successfully!"); $readmemb("test1.dat",t_ram.mem); $display("ram loaded successfully!"); #1 test=1; #14800; sys_reset; ………. endmodule

module topcpu; task sys_reset; begin reset_req=0; #(`PERIOD*0.7) reset_req=1; #(1.5*`PERIOD) reset_req=0; end endtask always@(test) begin:MONITOR case(test) 1:begin $display("\n***RUNNING CPUtest1-The Basic CPU Diagonostic Program***"); $display("\n TIME PC INSTR ADDR DATA"); $display("------------- ------- -------- ----------- ----------"); while(test==1) @(t_cpu.pc_addr) if((t_cpu.pc_addr%2==1)&&(t_cpu.fetch==1)) #60 PC_addr<=t_cpu.pc_addr-1; IR_addr<=t_cpu.m_adr.ir_addr; #340 $strobe("%t %h %s %h %h",$time,PC_addr,mnemonic,IR_addr,data); endcase endmodule

module topcpu; ……. always@(posedge halt) begin #500 $display("\n*****************************************"); $display("** A HALT INSTRUCTION WAS PROCESSD!!**"); $display("*****************************************"); end always #(`PERIOD/2) clock=~clock; always @(t_cpu.opcode) case(t_cpu.opcode) 3'b000 :mnemonic="HLT"; 3'b001 :mnemonic="SKZ"; 3'b010 :mnemonic="ADD"; 3'b011 :mnemonic="AND"; 3'b100 :mnemonic="XOR"; 3'b101 :mnemonic="LDA"; 3'b110 :mnemonic="STO"; 3'b111 :mnemonic="JMP"; endcase endmodule