十一都过去了还不结项真是没的说了。
一、概述
参见前面几篇试用报告,上一篇写了一个UART接收器模块,最终构思的小处理器叫ledpu。。就是专门让你点亮led的。我预计达到的目标是,对于从串口输入的一串字符,
FPGA会把它识别成一段指令,这段指令内部包括延时、跳转、亮灯、灭灯四种指令,从而可以让闪烁过程持续进行。
二、结构设定
对于这样一个想法,考虑从UART编程,类似于MSP430的BSL,定义当UART接收到四个连续的A时,开始正式读取UART的输出字符,这就是一个模拟的编程过程。程序里定义一个内存区域,用来存储接受值,这相当于RAM或ROM。当然,“编程”总要结束,定义'zzzz'四个字符为结束符号。
现在共规划了两个模块,编程器programmer和存储区mem,还需要一个模块CU——控制单元。由于此
电路不涉及逻辑运算,所以暂不加入ALU。整体描述其功能:UART向pro模块发送字符,当pro模块检测到四个连续的AAAA,开始向mem发送字符,此时CU被暂停运行、暂停从mem读取数据。
当pro模块检测到四个连续的zzzz时,停止发字符。然而此时有3个或4个z已经写到了mem模块里。为此,在CU里面设定,当取出的一个字符为'z'时,已经运行到了mem模块的末尾,重新复位程序计数器。
三、CU模块的考虑
CU就是控制单元,虽然此次定义的CU很low很low,甚至不带ALU。但是还是要考虑它四种指令的实现方式。
对于开关灯指令,只需要做一个if判断,成立则把某个led的管脚设为0/1。跳转指令则直接更改pc的值,从下面的代码中可以看到,pc一直在自加,也可以强行给它赋值来实现跳转:CU单元通过给mem发送pc来取出一个字符执行。从另一个角度来说,这个所谓的CU不过是一个译码器。
led一个重要的效果是延时,在CU内部把外部的50M时钟分频至100Hz,并送到一个计数器里面。这个计数器的功能是:它自己不听计数、自增,当增加到另外一个“基准”num时就停止,并且输出反转为1:其输出作为pc计数器自增的使能信号!
对于非延时的三个指令,会把它的计数结果num1清零,同时把num也清零。这时,计数器不工作,pc按计划自增;如果是延时指令,会给num赋值,且不再清零num1,此时计数器输出为0,pc不再增加,计数值满后输出翻转为1使能pc计数器,CU取到mem中下一个字符。
四、代码及框图
quartus的 一个工具就是生成原理图,省了我画草图的功夫,上图:
顶层模块代码如下,其余见附录:
//顶层module
module ledpu(
input clk,
input dat,
output [3:0]led);
wire [7:0]code;
wire [3:0]pc;
wire en_cu;
wire enpro;
wire [7:0]codeout;
programmer u1(clk,dat,code,en_cu,enpro);
mem u2(en_cu,enpro,pc,code,codeout);
cu u3(en_cu,enpro,clk,codeout,pc,led);
endmodule
五:结果
反复调试之后,基本调通,测试时发出AAAABXCXJzzzz的字符,可以看到led1闪烁。在代码中上述一串字符的意思是编程开始码、打开led、延迟一个单元、关闭led、延迟一个单元、跳转到第一条指令,最后四个z是结束标志,会有部分读取到mem模块,但是由于CU中的判定,读取字符为'z'时会重新执行。在本例中由于加入了跳转(对应于J),
J这个字符会将pc重新定位到0,循环执行。
大家好,这是我写的代码。
all.rar
(1.73 KB)
(下载次数: 7, 2017-10-9 01:24 上传)
六、感慨
长假结束,六天赶项目。同样是给祖国过生日,人家收假通过用“大家好,这是我女朋友GXT”,我通过“大家好,这是我女,,coding出的代码”。