1 引 言
现场可编程门阵列fpga 门数众多,人们可以将合适的ip软核或其他形式的核作为嵌入式模块装在自己的设计中。但通常ip软核需要门数较多的fpga 器件支持,作为学习来说的fpga 芯片往往资源有限,需要节约fpga 的成本与面积; 并且没必要实现所有功能, 只要做出关键部分及重要结构,明白其运行机理,又能与真实的cpu 紧密相联即可。实验箱上采用的fpga 芯片为a ltera 公司的epf10k20tc144- 4。这里以inte l的8085a 为例来说明8位计算机的工作原理。
2 8085a cpu 设计及实现
2. 1 fpga 芯片及外围电路简介
a ltera的flex10k 器件是工业界首例嵌入式pld, 基于可重配置cmos sram 元件。epf10k20带有144个lab (逻辑阵列块) 和1152 个逻辑单元, 最大i/o数目为189。另外, 芯片中嵌入式陈列块( eab)有6个, 其ram 总位数为12288。
实验涉及到fpga 芯片的外围部分包括控制开关、2* 8键盘输入、6个数码管输出、8个输入端口、8个输出端口及2个中断开关等。主要用来增添程序设计的灵活性及形象性, 使其可现场调试, 验证结果, 避免单纯用软件仿真的不足。外围电路控制模块及结构可参见文献[ 1] 。
现场调试时可以通过控制开关, 手动从键盘输入相应的地址及数据(通过数码管显示), 输错可以修改; 用写使能开关给ram 写入相应程序。当输入完所有程序后, 按下运行开关即可执行程序, 在数码管上显示地址、数据及最终结果。控制开关用于配合键盘通过手动方式输入程序, 可以形象化的现场编程。在软件下载后不使用计算机, 通过按钮、键盘就能将程序输入到ram 中, 然后运行, 显示出结果。
2. 2 cpu模块
2. 2. 1 内部结构
cpu 模块的内部结构如图1所示。微型计算机由下面几个部分组成: 8位通用寄存器h、l, 16位程序计数器( pc ) , 16位堆栈指示器( sp), 一个加1 /减1 地址锁存器( add /adr ), 8 位nl 寄存器( nl) , 8位中断时间寄存器( t imer ) ; 算术逻辑单元(alu ), 累加器(a ), 标志寄存器( fr ), 数据选择器( sel) ; 指令寄存器( ir) , 控制器( con ) , 4选1多路选择器(mux) , 存储地址寄存器(mar ) , 8 位数据寄存器(mdr) ; 输入数据寄存器( indt ), 输出数据寄存器( outdt )等部分组成。其中标志寄存器有4位, 分别是: 进位位( cy)、零位( z)、符号位( s)、奇偶位( p) , 微机通过检测这些标志位的1位或多位来判断程序是否需要转移。
微型计算机cpu 结构图
图1 微型计算机cpu 结构图
图中字母l为数据载入控制信号, e 为三态输出选通信号, clk为时钟信号, c lr为清零信号, w 为数据载入pc信号, cpc为控制pc 加1信号, s3- s0为控制alu 进行加减、逻辑运算或移位运算的选择信号, iadr、dadr为加1 /减1地址锁存器加1减1控制信号, isp、dsp为堆栈指示器的加1减1 控制信号, e ram、w ram 为读写ram 控制信号。另外, 累加器(a ) , 标志寄存器( fr )增加了专用的清零信号。
所有的控制、时钟及清零信号由控制器( con)模块给出, 而con 模块由外部时钟clkin、清零信号rst及使能信号enable 控制。存储地址寄存器(mar )用来给ram输送地址, 从ram 读指令和数据, 也可以给ram写数据。altera公司的epf10k20tc144 - 4 芯片中有6个嵌入式陈列块, 其ram 总位数为12288。这里ram 可配置为1024 * 8( 1024个地址, 8位数据) ,直接调用参数可设置模块库中lpm _ram _ io 的lpm_file 文件, 用文本编辑器编辑m if文件来初始化数据。如果不用fpga 的内部ram, 可外接64k的8位ram, 即寻址空间为64k。
2. 2. 2 指令系统
内部工作原理和指令系统紧密相联。本微机共有54条指令, 可分为8类, 即数据传送指令、算术与逻辑运算指令、移位指令、增量与减量指令、堆栈操作及中断指令、转移指令、子程序调用及返回指令、其它指令等。指令系统与8080 /8085的指令系统表基本一致, 标志位的变化(无辅助进位位) 与其相同, 可参见文献。
由于资源所限, 没有使用8085a 所有的寄存器及某些功能, 如b、c、d、e 寄存器等, 但是这并不妨碍本微机能够实现其绝大多数功能。从时钟周期数(状态数)来说, 比8085a 更少, 也就是说速度更快。
数据传送指令有14条(一个n表示一个8位二进制数据): 3个状态数的movah (将h 的内容存入a )、movha、mov la(将a 的内容存入l)、mova;l 4状态的mvian(将数据n存入a)、mv ihn、mv iln、mvitn(将数据n 存入t ime寄存器, 此指令为新增) ; 5 状态的movma(将a 的内容装入hl所指的地址)、movam; 4状态数的sphl(将hl寄存器的内容装入sp); 6状态的inn( n所指地址的内容给a )、outn; 4状态的cd _out(a内容给pc+ 1, 停机, 此指令为新增)等。
算术与逻辑运算指令有13 条: 3 状态的cmc( cy符号取反)、stc( cy置1) 、cma(寄存器a 内容取反); 4状态的addh(将a 与h 相加后给a )、adin(将a 与n相加后给a)、subh、su in、cmph(将a 与h相比较(只影响符号) )、adch(将a 与h 及符号cy相加后给a )、sbbh、anah(将a 与h 寄存器的内容相与后给a )、orah、xrah(将a 与h 异或后给a )等。
移位指令有4条, 同8085a。增量与减量指令有4条, 只针对h、l寄存器。堆栈操作及中断指令有8条: 7 状态的pushh( hl 压入堆栈)、pushp( af压入堆栈); 6状态的poph、popp; 8状态的rsta(重新启动); 3状态的etim e( t 寄存器使能, 此指令为新增)、eint(中断使能)、d int等。转移指令有5条: 7状态的jmpn(无条件转移至程序nn, 低位在前); 不跳转时5状态, 跳转时7状态的jnn( z= 1时转移至程序nn)、jcn、jmn、jpen等。子程序调用及返回指令有2条: 11状态的calln (保留当前pc, 转移至程序nn, 低位在前)、7状态的ret(返回)。其它指令有4条: 3状态的nop、c lrf(标志寄存器清零, 此指令为新增)、clra (a 清零, 此指令为新增)、hlt等。
状态数的计算, 若本次指令的前面一指令为3状态数时, 本指令将会减少1 状态。如: movha,adin; 若第1指令movha前没有其它3 状态指令时,它是3个状态, 而adin会减少1状态, 由原来的4状态变为3状态。再如: mov la, movha; 则后一状态由3状态变成2状态。其余类似(但不包括rsta)。
2. 2. 3 工作原理
由图1可知, 不同的子模块一共有20个, 每个模块用vhdl程序来实现, 最后用元件例化语句构成总模块。下面以设计算术逻辑部件模块c_alu及控制模块c_con为例简要介绍一下思路。
( 1)算术逻辑部件c_alu。
算术逻辑部件c_a lu非常占用fpga的逻辑单元log ic cells, 需要尽量优化。s3- s0为控制alu 进行加减、逻辑或移位运算的选择信号, 一共可得到16种运算, 这里用了13种: 6种算术、3种逻辑运算和4种移位指令。如加法、减法、加1、减1、带符号位加法、带符号位减法; a 或b、a 与b、a 异或b; a 左移、a右移、a 带cy 左移、a 带cy右移等。另外, alu 的运算直接影响到符号位的变化, 运算结果存入标志寄存器( fr)。有关alu的运算多为4个状态。
( 2)控制模块c_con。
占用fpga 的逻辑单元log ic ce lls最多的是控制模块c_con。在参考文献[ 3] 中的思路不再适合于稍大型的cpu 设计, 但它是理解如何控制cpu 信号的一个起点。对于一条指令应该细化到每一个步骤及每一位, 而不再是以一个控制字的方式去实现。以指令movah为例, 首先把pc 值送入mar 寄存器, 此为状态s0, 这时起作用的是lmar; 然后在状态s1时, pc值加1, 将存储器单元中的内容读入到ir, 这时cpc、e ram、lir起作用, lmar不再起作用, 需要置0; 接着在状态s2时, 对ir 寄存器中的指令进行译码, 所有的操作指令都是在此状态译码(不包括rsta)。对于3状态指令, 不保存指令, 直接执行, 然后跳转到状态s1。因此对于下一条指令来说, 其状态数减1。
指令中状态数最多的是子程序调用ca lln指令。
c alln指令要保存pc 值到sp- 1及sp- 2中, 然后跳转到子程序。考虑到返回指令ret执行后, pc 要重新在原位置执行, 那么存入sp中的pc 值应该是在得到其指令后加3。对pc 进行单独加3是一种思路, 但需要另外耗费资源, 并且增加状态。这里采用了先把ca lln后的nn存入16位的加1 /减1 地址锁存器, 然后保存pc 到sp, 再将nn 赋值给pc, 跳转到子程序的方法。返回指令ret不仅可以用作子程序调用后的返回, 还可用于中断的返回。
2. 3.. fpga 实现及编程思路
由于使用内部ram, 其地址空间为0000 -03ffh。通常在00h 中放入28 (即jmpn, 跳转指令) , 将程序跳转到从40h 开始。把03- 0eh 作为放常用变量的空间, 用inn及outn指令来调用, 以解决寄存器不足的缺陷。这也是一种编程思路, 可参见文献[ 4] 。0fh、1fh、2fh 分别为外部中断0( int0) , 外部中断1( int1), 定时器中断( time) 的起始位置。int0优先级最高, int1次之, time最低。中断信号高电平有效。中断功能的实现是为了学习其工作原理, 只做了一个定时器中断。计时为减1方式, 当计时为0时, 发出中断信号。t ime中断的使用方法: 首先关中断( dint), 给t赋值(mv itn) , 再开中断( e int), t寄存器使能( et ime)。此后, t 寄存器正常工作。若要再次使用, 首先给t 赋值, 然后t寄存器使能。
初始时的pc 为0000h, sp为03ffh。sp的更改可通过指令sph l来执行。针对实验箱, 将8000-0ffffh 作为输出口地址, 4000 - 7fffh 作为输入口地址。而实际实验箱上只定义了1个8位输入, 1个8位输出。io 口的操作可通过movam 及movma指令去实现。
由于键盘输入时, 要进行去抖动处理, 使用了两种不同的时钟频率。键盘处理采用1kh z的频率,而cpu 的工作时钟可选择实验箱上的不同频率, 从1h z到10mh z皆可, 甚至可以外接其它更高频率。
如果采用1h z的clk in 频率, 可以清楚地看到cpu工作的每一过程。
将本微机下载到实验箱上, 已成功实现了乘法(用减1或右移的方法), 调用子程序, io 口的使用,中断的使用等多项实验, 验证了cpu 设计的正确性。
3 结束语
quartusii对微机进行编译, 其逻辑单元le 用到1151, 占100% 。用fpga 来实现cpu 的功能, 研究其工作原理, 然后用synp lify pro软件对其进行门级研究, 对cpu 的面纱将不再感到神秘, 有利于做成专用集成电路asic, 控制其规模, 节约芯片成本与面积。同时, 也会增加对fpga 的学习兴趣和使用技巧, 开发出更多新的产品。
			
			
       	 	
    	电视机专业英语
         	 	
    	被动元件或提前涨价 国巨系成最大赢家
         	 	
    	采用计算机控制和微型组合探头实现汽车全自动探伤系统的设计
         	 	
    	SiTime携手Bosch加速MEMS时钟器件创新,共创5G和IoT未来
         	 	
    	在设计配平仪时,需要注意的方面有哪些
         	 	
    	基于FPGA的8085A CPU结构分析
         	 	
    	重点人员管控系统平台搭建
         	 	
    	DIPIPM™的PCB设计(2)
         	 	
    	几种通信方式介绍
         	 	
    	目前有哪些经典的目标跟踪算法?
         
       	 	
    	Microchip推出集成低功耗动画显示驱动的PIC24F单片机,适用于电池供电设备
         	 	
    	选购FBT熔融拉锥大芯径光纤耦合器需要注意的技术参数?
         	 	
    	中国电池进入快速洗牌阶段 比亚迪要拆分电池业务
         	 	
    	基于AT89C51的三相异步电动机
         	 	
    	N_tone的频谱为啥那样?
         	 	
    	英特矽尔抗辐射双通道高精度OPA问世
         	 	
    	IP over SDH技术协议有哪些?
         	 	
    	2023年协作机器人五大趋势,中国协作机器人市场势头强劲
         	 	
    	加密货币和区块链的五个突破性的用途列举
         	 	
    	5G是行业数字化转型的关键使能技术