对外经济贸易大学 姜咏江
CPU控制逻辑一般都可以用真值表分析,用有限状态机FSM进行描述。就逻辑电路而言,各种逻辑描述最终都得转化成逻辑与门、或门、非门的组合形式。给大家介绍一个本人设计的CISC指令系统的控制逻辑电路自动生成器,可以免去FSM描述的麻烦,又不会出错,大家不妨试试。按照这个思路也可以设计RISC指令系统的控制逻辑电路生成器,因一直较忙,尚未动手。
1 指令分析真值表
无论何种CPU设计都离不开图1所示的指令分析真值表。
图 1 指令分析真值表
指令分析真值表分为左端的自变量部分和右边的因变量部分。自变量一般包括机器指令线、节拍线和标志线。因变量部分包括计算机的所有控制线。本设计中用复位线res作为自变量部分和因变量分界,使用中一定要确定好分界。表格中前四项的位置不能变,特别是“助记符”和“节拍”不能和“基本动作”后面的自变量混序。除了“编号”“助记符”“节拍”“基本动作”和“res”之外,变量的名称可以自己随便更改。节拍必须用向量的方式“p[]”填写。“编号”“基本动作”不进入逻辑表达式,标注随便。
这种指令分析真值表可以先用Excel填写,然后另存为Dbase III 的表,名称是example.dbf。Dbase III 的表名称“example.dbf”不能改成其他名称。这张表要存放在模块描述生成器的安装目录“模块描述”内,覆盖掉原来的同名文件。
2 模块描述生成器的安装
模块描述生成器的原始文件夹内包括安装程序等(见图2),在其中选择setup.exe,双击即可执行安装。
图 2 安装文件夹
安装过程只要根据提示回答就可以安装成功。安装的位置是当前文件夹的“模块描述”子文件夹。
3 模块描述生成器的使用
FoxPro是早期数据库版本,安装之后文件夹如图3所示,文件夹是“模块描述”,其中的可执行程序的名称是“模块描述.EXE”,这个可执行文件是不放在系统菜单中的。
图 3 模块描述生成器文件夹
用FoxPro做成的模块描述生成器操作界面如图4所示,其中菜单中的“查看原始表”就是显示图1的指令分析真值表,允许用户在表上进行适当地修改。单击“生成模块程序”就能够在examcontrol.txt文件中得到最终的Verilog HDL 描述模块。
复制examcontrol.txt文件的全部内容,粘贴到EDA软件Quartus II的Verilog HDL编辑器中,就可以得到CPU控制矩阵的硬件语言描述。
注意,复制之后要将examcontrol.txt文件的全部内容删除,以备下次使用,不然再次使用时,会产生接续;不可删除这个文本文件。
图 4 模块描述生成器操作界面
用写字板显示examcontrol.txt文件的内容比用Word更方便,不能用记事本显示,因为回车符在记事本中不起作用。如果想用总线方式描述输入输出端口,进行一些简单的修改就可以达到目的。
4 设计实例
初始提供给用户自动生成的例子,描述如下:
module luoji (LDA,ADD,SUB,OUT,JMP,JZ,JN,CALL,IN,STR,SDA,PUSH,POP,RET,INC,DEC,ZERO,INP,STRP,JEND,LNOT,LAND,LOR,STPK,JK,MULT,DIVI,DATX,XTDA,STP
,p,EMPTY,ENDF,ZF,NF,RES,PCE,PCL,PCINC,IMARL,DMARL,IRAML,IWRIT,IRAME,DRAML,DWRIT,DRAME,DAE,DAL,ZEO,COML,AL,BL,A_SE,SU,SPE,SPINC,SPDEC,PTRE,PTRL,PTRINC,PTRDEC,OL,INE,IRE,IRL,XL,XE,NOTE,ANDE,ORE,CHENGE,CHUE,GAOWEIE,STOP);
input [9:0] p;
input LDA,ADD,SUB,OUT,JMP,JZ,JN,CALL,IN,STR,SDA,PUSH,POP,RET,INC,DEC,ZERO,INP,STRP,JEND,LNOT,LAND,LOR,STPK,JK,MULT,DIVI,DATX,XTDA,STP;
input EMPTY,ENDF,ZF,NF;
output RES,PCE,PCL,PCINC,IMARL,DMARL,IRAML,IWRIT,IRAME,DRAML,DWRIT,DRAME,DAE,DAL,ZEO,COML,AL,BL,A_SE,SU,SPE,SPINC,SPDEC,PTRE,PTRL,PTRINC,PTRDEC,OL,INE,IRE,IRL,XL,XE,NOTE,ANDE,ORE,CHENGE,CHUE,GAOWEIE,STOP;
assign RES=LDA& p[8]|ADD& p[10|SUB& p[10|OUT& p[8]|JMP& p[6]|JZ& p[6]|JN& p[6]|CALL& p[10|IN& p[8]|STR& p[8]|SDA& p[6]|PUSH& p[6]|POP& p[7]|RET& p[7]|INC& p[4]|DEC& p[4]|ZERO& p[4]|INP& p[7]|STRP& p[4]|JEND& p[6]|LNOT& p[5]|LAND& p[10|LOR& p[10|JK& p[6]|DATX& p[4]|XTDA& p[4];
assign PCE=p[0]|LDA& p[3]|ADD& p[3]|SUB& p[3]|OUT& p[3]|JMP& p[3]|JZ& p[3]|JN& p[3]|CALL& p[3]|CALL& p[7]|IN& p[3]|STR& p[3]|SDA& p[3]|JEND& p[3]|LAND& p[3]|LOR& p[3]|JK& p[3]|MULT& p[3]|DIVI& p[3];
assign PCL=JMP& p[5]|JZ& p[5]& ZF|JN& p[5]& NF|CALL& p[9]|RET& p[6]|JEND& p[5]& ENDF|JK& p[5]& EMPTY;
assign PCINC=p[2]|LDA& p[5]|ADD& p[5]|SUB& p[5]|OUT& p[5]|JZ& p[4]|JN& p[4]|CALL& p[5]|IN& p[5]|STR& p[5]|SDA& p[5]|JEND& p[4]|LAND& p[5]|LOR& p[5]|JK& p[4]|MULT& p[5]|DIVI& p[5];
assign IMARL=p[0]|LDA& p[3]|ADD& p[3]|SUB& p[3]|OUT& p[3]|JMP& p[3]|JZ& p[3]|JN& p[3]|CALL& p[3]|IN& p[3]|STR& p[3]|SDA& p[3]|INP& p[3]|JEND& p[3]|LAND& p[3]|LOR& p[3]|JK& p[3]|MULT& p[3]|DIVI& p[3];
assign DMARL=LDA& p[5]|ADD& p[5]|SUB& p[5]|OUT& p[5]|CALL& p[6]|IN& p[5]|STR& p[5]|PUSH& p[3]|POP& p[4]|RET& p[4]|LAND& p[5]|LOR& p[5]|MULT& p[5]|DIVI& p[5];
assign IRAML=INP& p[5]|MULT& p[11|DIVI& p[11;
assign IWRIT=INP& p[6];
assign IRAME=p[2]|LDA& p[5]|ADD& p[5]|SUB& p[5]|OUT& p[5]|JMP& p[5]|JZ& p[5]& ZF|JN& p[5]& NF|CALL& p[5]|IN& p[5]|STR& p[5]|SDA& p[5]|JEND& p[5]& ENDF|LAND& p[5]|LOR& p[5]|JK& p[5]& EMPTY|MULT& p[5]|DIVI& p[5];
assign DRAML=CALL& p[7]|IN& p[6]|STR& p[6]|PUSH& p[4];
assign DWRIT=CALL& p[8]|IN& p[7]|STR& p[7]|PUSH& p[5];
assign DRAME=LDA& p[7]|ADD& p[7]|SUB& p[7]|OUT& p[7]|POP& p[6]|RET& p[6]|LAND& p[7]|LOR& p[7]|MULT& p[7]|DIVI& p[7];
assign DAE=ADD& p[8]|SUB& p[8]|STR& p[6]|PUSH& p[4]|STRP& p[3]|LNOT& p[3]|LAND& p[8]|LOR& p[8]|MULT& p[8]|DIVI& p[8]|DATX& p[3];
assign DAL=LDA& p[7]|ADD& p[9]|SUB& p[9]|SDA& p[5]|POP& p[6]|LAND& p[9]|LOR& p[9]|MULT& p[9]|DIVI& p[9]|XTDA& p[3];
assign ZEO=ZERO& p[3];
assign COML=p[2];
assign AL=ADD& p[8]|SUB& p[8]|LNOT& p[3]|LAND& p[8]|LOR& p[8]|MULT& p[8]|DIVI& p[8];
assign BL=ADD& p[7]|SUB& p[7]|LAND& p[7]|LOR& p[7]|MULT& p[7]|DIVI& p[7];
assign A_SE=ADD& p[9]|SUB& p[9];
assign SU=SUB& p[9];
assign SPE=CALL& p[6]|PUSH& p[3]|POP& p[4]|RET& p[4];
assign SPINC=POP& p[3]|RET& p[3];
assign SPDEC=CALL& p[7]|PUSH& p[4];
assign PTRE=INP& p[3];
assign PTRL=STRP& p[3];
assign PTRINC=INC& p[3];
assign PTRDEC=DEC& p[3];
assign OL=OUT& p[7];
assign INE=IN& p[6]|INP& p[5];
assign IRE=CALL& p[9];
assign IRL=CALL& p[5];
assign XL=MULT& p[10|DIVI& p[10|DATX& p[3];
assign XE=XTDA& p[3];
assign NOTE=LNOT& p[4];
assign ANDE=LAND& p[9];
assign ORE=LOR& p[9];
assign CHENGE=MULT& p[9];
assign CHUE=DIVI& p[9];
assign GAOWEIE=MULT& p[10|DIVI& p[10;
assign STOP=STPK& p[3]& EMPTY|STP& p[3];
endmodule
这个CPU控制矩阵描述的指令系统,可参考如下指令系统设计:
表 1 参考指令系统
序号 功能设想 助记符 16进制操作码 2进制操作码
1 把ram存储单元R的内容送到累加器da LDA R 01 00000001
2 把ram存储单元R的内容与累加器da的内容相加结果送da ADD R 02 00000010
3 用累加器da的内容减去ram存储单元R的内容结果送da SUB R 03 00000011
4 将R存储单元内容输出到外设 OUT R 04 00000100
5 跳到iram的R单元取指令执行 JMP R 05 00000101
6 如果累加器da的值是0则跳到iram的R单元取指令 JZ R 06 00000110
7 如果累加器da的值为负则跳到iram的R单元取指令 JN R 07 00000111
8 调用iram中R子程序 CALL R 08 00001000
9 输入数据到ram的R存储单元 IN R 09 00001001
10 将累加器da的内容送到ram存储单元R STR R 0A 00001010
11 将数N送到累加器da SDA N 0B 00001011
12 将累加器da的内容入栈 PUSH 0C 00001100
13 将堆栈的内容送到累加器da POP 0D 00001101
14 从子程序返回指令 RET 0E 00001110
15 将PTR的内容加1 INC 0F 00001111
16 将PTR的内容减1 DEC 10 00010000
17 将da复位为0 ZERO 11 00010001
18 将数据输入到ptr指示的iram存储单元 INP 12 00010010
19 将累加器da的内容送到ptr STRP 13 00010011
20 如果输入的数据是h80则跳转到iram的R单元指令 JEND R 14 00010100
21 将累加器da内容取反,结果放入da LNOT 15 00010101
22 将累加器da与R单元内容作逻辑与,结果放入da LAND R 16 00011100
23 将累加器da与R单元内容作逻辑或,结果放入da LOR R 17 00010111
24 缓冲区空暂停 STPK 18 00011000
25 缓冲区空跳转到R执行 JK R 19 00011001
25 程序输入结束 END 80 10000000
26 停机 STP 3F 00111111
参考文献
[1] 姜咏江.PMC计算机设计与应用.北京,清华大学出版社,2008.5.
[2] 姜咏江.计算机原理教程.北京,清华大学出版社,2005.12.
[3] David Money Harrisy.数字设计和计算机体系结构.北京,机械工业出版社,2008.1.
[4] 姜咏江.计算机原理综合课程设计.北京,清华大学出版社,2009.6.
注:本文附录提供安装软件。
2009-12-20
生成器安装软件
https://blog.sciencenet.cn/blog-340399-280170.html
上一篇:
嵌入式不是科学家干的事下一篇:
科学家向商人的演变