EDN博客精华文章 作者:ilove314
CPLD与ADC0804接口设计
这个实验做得比较郁闷,因为从上午开始一直摸不着头绪,虽然整体模块设计早早搞定。但是调试阶段可谓费尽周折,原因是没有抓住主要矛盾。一直以为是ADC0804的驱动部分没有做好,直到最后才发现原因出在显示部分。
但是发现问题后,却苦恼于如何用查表法来把8bit的AD转换结果的各个数位分别存入寄存器中以便最后的数码管显示使用。显然的通常在软件的设计中,这样的问题用两个除法或者取余运算就可以解决的,但是在硬件上是不可以的,乘除运算是相当耗费资源的(当然了,如果硬件中不得不设计到这样的模块时,调用它是没问题的)。所以一般的计算在硬件上都是用其它的方法来替代乘除运算的,比如常用的加法或者查表法(关于卷积和的查表算法前面的日志中谈过了,也是一个相当经典的设计思路)。
这里的256个可能取值如何把各个位上的数值分别赋给相应寄存器就比较让人费神,得到的经验就是:我用100级的case语句比10级的if… else
if… …… else…语句要来得节约硬件资源(整个设计240个LE后者就不够用了)。个中原因也是显而易见的,判断if else对于只用一些逻辑门的硬件来说是多么的复杂的任务而,呵呵,大概就是这样了。所以以后在硬件设计的时候应该多比较这些语法,多总结,才能设计出更低成本更高性能的产品。硬件和软件设计不同,有时候往往越简单的语句用法反而越节约资源。
好了,感慨了好一会,看来实验是没白做——学到东西了。这个设计其实很简单,就是通过CPLD来控制ADC0804工作,然后把从ADC0804读出的数值显示在数码管上。(这个实验好像有点老掉牙哈。~_~)


还有就是在控制AD器件的时候,我是把50MHz的主频做了50分频,然后利用到了状态机的设计,延时是用的计数(借助于分频的思想),不知道这样的想法对不对,或者说是有更成熟的延时设计方法(期待高手指点)。
该设计的RTL视图如下:(三个模块)

AD0804与CPLD的接口控制部分的状态机设计视图(ISE在状态机的设计上可以采用原理图的设计,有一个专门的设计界面只要相应的画出下面这个状态图就可以自动生产代码,而QUARTUS似乎只能自己写代码,不知道是我没有发现QUARTUS的这个状态机设计方法还是它确实不够强大):

控制部分的Verilog代码如下:
(没写注释还是因为该死的键盘,写程序的时候可不想像现在这么累人的来回切换,明天赶紧换个去)
module adc_work(clk,rst_n,data,cs_n,rd_n,wr_n,intr_n,key,data_reg);
input clk;
input rst_n;
input[7:0] data;
input intr_n;
input key;
output cs_n,rd_n,wr_n;
output[7:0] data_reg;
reg[1:0] idle,start,start_wait,convert,current_state,next_state;
reg[15:0] delay;
reg cs_n,rd_n,wr_n;
&nb