嵌入式学习小组
直播中

黄色的小金橘

12年用户 602经验值
私信 关注

如何实现嵌入式CISI模型机系统的设计?

如何实现嵌入式CISI模型机系统的设计?

回帖(1)

姜春阳

2021-12-24 15:25:44
1、课程设计选题

任意输入5个整数,输出所有正数的平方和。
汇编代码 :
MOV R3,0H ;R0累计和   MOV R1,5H ;R1计数器,从5开始降到0,计数5次L1:TEST R1   ;判断R1为0则跳转   JZ L2     ;跳转L2   INT R2    ;R2输入数据   TEST R2   ;测试R2是否为负数   JB L1     ;如果小于0,跳转L1继续输入   MUL R2,R2 ;R2自乘   ADD R2,R3 ;R3=R3+R2   DEC R1    ;计数减1   JMP L1  L2:OUT R3    ;输出累加和   JMP L2 2、计组理论基础

(1)嵌入式 CISI 模型机系统总体设计


(2)嵌入式 CISC 系统控制器的逻辑结构框图


(3)指令系统设计


对Rs和Rd的规定

(4)微程序流程图设计


(5)地址转移逻辑

地址转移逻辑电路是根据微程序流程图3-2中的棱形框部分及多个分支微地址,利用微地址寄存器的异步置“1”端,实现微地址的多路转移。由于微地址寄存器中的触发器异步置“1”端低电平有效,与µA4~µA0对应的异步置“1”控制信号SE5~SE1的逻辑表达式为:(µA5的异步置“1”端SE6实际未使用)。
SE5<=NOT(CF AND P2 AND T4);SE4<=NOT(ZF AND P2 AND T4); SE3<=NOT(I15 AND P1 AND T4);SE2<=NOT(I14 AND P1 AND T4);SE1<=NOT(I13 AND P1 AND T4);SE0<=NOT(I12 AND P1 AND T4); (6)设计微指令格式和微指令代码

CISC模型机系统使用的微指令采用全水平型微指令,字长为26位,其中微命令字段为18位,P字段为2位,后继微地址为6位,格式如下:

微程序设计

这些微程序代码是写在controm中,代码如下:
LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY CONTROM ISPORT(ADDR: IN STD_LOGIC_VECTOR(5 DOWNTO 0);     UA:OUT STD_LOGIC_VECTOR(5 DOWNTO 0);     O:OUT STD_LOGIC_VECTOR(19 DOWNTO 0)    );END CONTROM;ARCHITECTURE A OF CONTROM ISSIGNAL DATAOUT: STD_LOGIC_VECTOR(25 DOWNTO 0);BEGIN     PROCESS    BEGIN        CASE ADDR IS                WHEN "000000" => DATAOUT<="11010010001111110110000000";--取地址            WHEN "000001" => DATAOUT<="10001010001111111000000000";--MOV                        WHEN "000010" => DATAOUT<="10001010001011111100000000";--INT            WHEN "000011" => DATAOUT<="10000110011111111100000000";--TEST            WHEN "000100" => DATAOUT<="10000010001111111101000000";--JB            WHEN "000101" => DATAOUT<="10001111000111111100000000";--MUL                        WHEN "000110" => DATAOUT<="10001110000111111100000000";--ADD                        WHEN "000111" => DATAOUT<="10001110110111111100000000";--DEC            WHEN "001000" => DATAOUT<="10000010000111111101000000";--JZ                        WHEN "001001" => DATAOUT<="10000000001101111100000000";--OUT            WHEN "001010" => DATAOUT<="01000010001111111000000000";--JMP            WHEN "010000" => DATAOUT<="01000010001111111000000000";--jz            WHEN "100000" => DATAOUT<="01000010001111111000000000";--***            WHEN OTHERS   => DATAOUT<="10000110010011100000000000";        END CASE;        UA(5 DOWNTO 0)<=DATAOUT(5 DOWNTO 0);        O(19 DOWNTO 0)<=DATAOUT(25 DOWNTO 6);    END PROCESS;END A; 自己设计的汇编代码是写在rom里面,代码如下:
LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY ROM IS PORT(        DOUT:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);        ADDR:IN STD_LOGIC_VECTOR(7 DOWNTO 0);        CS_I:IN STD_LOGIC);END ROM;ARCHITECTURE A OF ROM IS--  注记符号     指令格式(OP)    Rs Rd     addr   --    MOV            0001       XX Rd    XXXXXXXX--    INT            0010       XX Rd    XXXXXXXX--    TEST           0011       Rs XX    XXXXXXXX--    JB             0100       XX XX     addr--    MUL            0101       Rs Rd    XXXXXXXX--    ADD            0110       Rs Rd    XXXXXXXX--    DEC            0111       XX Rd    XXXXXXXX--    JZ             1000       XX XX     addr--    OUT            1001       Rs XX    XXXXXXXX--    JMP            1010       XX XX     addrBEGIN        DOUT<="0001001100000000" WHEN ADDR=x"00" AND CS_I='0' ELSE                --MOV R3,0H          "0001000100000101" WHEN ADDR=x"01" AND CS_I='0' ELSE                --MOV R1,5H          "0011010000000000" WHEN ADDR=x"02" AND CS_I='0' ELSE                --L1:TEST R1                  "1000000000001011" WHEN ADDR=x"03" AND CS_I='0' ELSE                --JZ L2          "0010001000000000" WHEN ADDR=x"04" AND CS_I='0' ELSE                --INT R2          "0011100000000000" WHEN ADDR=x"05" AND CS_I='0' ELSE                --TEST R2          "0100000000000010" WHEN ADDR=x"06" AND CS_I='0' ELSE                --JB L1          "0101101000000000" WHEN ADDR=x"07" AND CS_I='0' ELSE                --MUL R2,R2          "0110101100000000" WHEN ADDR=x"08" AND CS_I='0' ELSE                --ADD R2,R3          "0111000100000000" WHEN ADDR=x"09" AND CS_I='0' ELSE                --DEC R1                  "1010000000000010" WHEN ADDR=x"0A" AND CS_I='0' ELSE                --JMP L1                  "1001110000000000" WHEN ADDR=x"0B" AND CS_I='0' ELSE                --L2:OUT R3                  "1010000000001011" WHEN ADDR=x"0C" AND CS_I='0' ELSE                --JMP L2                  "0000000000000000";END A; 3、maxplus2使用:

打开文件,进入maxplus2目录下,筛选"应用程序",运行max2win.exe。修改license。选择"Options"——“License Setup”——“Browse”,选中文件夹license文件里的license.dat,点击ok即可。

在文件夹里新建一个工程文件,你的所有代码和操作产生的文件,将会在这里进行,这是重要的一步。这里随便建立一个"Project"文件夹作为示例,推荐使用英文命名,以免后面产生不必要的麻烦。

(1)切换到maxplus2界面,新建一个文件。点击"Flie"——“New”。

这里以设计PC单元为例,选择"Text Editor file"。

(2)在文件夹里的CISC文件找到pc.vhd,复制代码到Text Editer文本框。

使用快捷键"ctrl+s"保存,按顺序操作。
1.一定要选中project所在的盘。
2.双击maxplus2
3.选中project文件
4.选择.vhd(必须是.vhd)
5.命名为pc
6.点击OK
之后会看到关键字将会被变成深蓝色,说明保存成功了。

(3)将鼠标点击在文本框中,使用快捷键"ctrl+shift+j",使编译条件指向当前文本。

(4)点击编译按钮对代码进行编译。

编译的结果,只要不是error就可以。如果是error,那就找代码哪里出错了。

(5)完成后,点击❌就可以了。以同样的方法,分别创建你想要的器件单元就好了。基本代码都在CISC里面,你可以复制粘贴使用即可,部分代码如果需要做修改,就根据自己的设计进行修改编译,此处不做讲解。
4、创建组合器件单元




  • 微地址寄存器aa
  • 控制寄存器COUNTROM

(1)新建图元层

由于这三个是由各个单元组成的,所以创建的方式与上面会有所差别。同样的新建一个文件,但不是上面的Text Editor file了,选择Graphic Editor file,并且选择.gdf。

(2)导入单元

新建后,右键空白处选择Enter Symbol,第一步和第二步表示首先要确定是maxplus2文件夹,由于前面涉及到很多的单元,我就拿我之前做好的工程演示,自己做的一定要选前面的Project文件。第三步是在图元库里找到你想要的单元,点击ok后就可以在图元层看到生成的器件样子。如果前面编译没错,这里就会有你已经编译好的单元 ,如果没有,就回去找前面哪里错了。

(3)连接器件

这里以aa作为演示,将单元摆放好后进行连线。这些输入输出的引脚原件不是在我们project里有的器件,属于系统内部。同样的按(2)操作:
1.双击prim路径
2.选择input或者output
这样就会显示这些引脚了。

(4)生成COUNTROM图元

同样的按上述步骤,生成后如下图所示。

(5)生成顶层图

步骤和上面一样,只是这里需要极大的耐心,要接对每一根线,接错了后面的仿真就会有错误。

5、编译仿真

编译前最重要的一部就是将编译对象指向当前的窗口,这是很多人容易忘记的,如果没有指向当前的窗口,编译的结果永远是前面某个的代码,新改的代码依然没被编译。切记!!!
(1)选择芯片驱动

“ctrl+shift+j"指向当前窗口后,点击"Assign”——“Device”,选择"EP1K30TC144-1",然后点击ok。

(2)编译顶层图

点击编译按钮,开始进行编译。同样的没有error就没事。

(3)仿真顶层图

1.点MAX+plus II,选择Wareform Editor

2.在Wareform Editor空白处右键选中Insert Node,在Node & Groups from SNF框中,找到你想要观测的引脚,点击ok就可以在Wareform Editor窗口看到引脚了。

3.在Node & Groups from SNF框中,引脚名不一定是我们想要的,我们可以在Wareform Editor窗口里自定义名称。还有就是你想看的一些参数没有,这时你得去顶层图添加引脚接到你想观测的线上,然后编译,在Node & Groups from SNF框中就可以看到你想要的引脚了。

4.设置仿真时序。点击"File"——“End Time”,设置整个周期为100us。
CLK默认200ns,CLR在200ns处为低电平,其余都是高电平。INBUS设置你想要的数据,进制数可以切换,我这里调为10进制,默认是16进制。

具体操作如下:
(1)把INBUS总线初始化为“1”,点击仿真寻找R1计数器对应的时间戳。

(2)在对应的时间戳,INBUS总线输入数据戳。

(3)分析
INBUS中输入数据(对应时间戳),R1为计数器,为了准确应该对应R1的时间戳划入数据。
R2为数据自平方,R3为求和值且累加。

6、结语

仿真过程可能会慢点,耐心等等就好了。看着时序图慢慢的生成,还是感觉不错的,但是时序图分析的结果和预期的结果是否一致,得需要去认真分析。计算机组成原理课设挺麻烦的,哪里错了需要一步一步的回去排查,考验你的细心和耐心。文章不做太多代码的详细解析,只是针对一些实践操作讲述,原理还得回归课本。
补充

在资源文件夹里面有个work文件夹,里面是求5个负数平方和的用例,可以参考学习。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分