集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 3462|回复: 2

CPLD与ADC0804接口设计

[复制链接]
weibode01 发表于 2010-11-23 14:25:55 | 显示全部楼层 |阅读模式
本帖最后由 fpgaw 于 2010-11-23 17:35 编辑

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;

       reg[7:0] data_reg;

       reg read_flag;



       always @ (posedge clk or negedge rst_n) begin

              if(!rst_n) begin

                     current_state <= 0;      

                     delay <= 0;

                     data_reg  <= 0;

                     end

              else begin

                     case(current_state)

                            idle: begin

                                          if(delay<10) begin

                                                 delay <= delay+1; end

                                          else begin

                                                 current_state <= next_state;

                                                 delay <= 0; end

                                          end

                            start:  begin

                                                 current_state <= next_state;

                                          end

                            start_wait: begin

                                                 current_state <= next_state;

                                          end

                            convert:  begin

                                          if(delay<2) begin

                                                 delay <= delay+1; end

                                          else begin

                                                 data_reg <= data;

                                                 current_state <= next_state;

                                                 delay <= 0; end

                                          end

                            default: ;

                            endcase

                     end

       end  

      

       always @ (current_state or intr_n or rst_n) begin

              if(!rst_n) begin

                     idle <= 0;

                     start <= 1;

                     start_wait <= 2;

                     convert <= 3;      

                     read_flag <= 0;

                    end

              else begin

                     case (current_state)

                            idle: begin

                                   cs_n <= 1;

                                   wr_n <= 1;

                                   rd_n <= 1;

                                   read_flag <= 0;

                                   next_state <= start; end

                            start: begin

                                   cs_n <= 0;

                                   wr_n <= 0;

                                   rd_n <= 1;

                                   read_flag <= 0;

                                   next_state <= start_wait; end

                            start_wait: begin

                                   wr_n <= 1;

                                   cs_n <= 1;

                                   rd_n <= 1;

                                   read_flag <= 0;

                                   if(!intr_n)       next_state <= convert;

                                   else next_state <= start_wait;

                                   end

                            convert: begin

                                   cs_n <= 0;

                                   rd_n <= 0;

                                   wr_n <= 1;

                                   read_flag <= 1;

                                   next_state <= idle; end

                            default: next_state <= idle;

                            endcase

                     end

       end  

      

endmodule



还有就是那个所谓的查表法,因为百位上只有0、1、2三种可能,所以用if else了:

                     if(data_reg<100) begin

                            led_seg[2] <= led_reg[0];

                            data_dis <= data_reg; end

                     else if(data_reg<200) begin

                            led_seg[2] <= led_reg[1];

                            data_dis <= data_reg-100; end

                     else begin

                            led_seg[2] <= led_reg[2];

                            data_dis <= data_reg-200; end



data_dis是把百位数值减去后的寄存器,剩下的十位和个位就要用到它,如下:

              case (data_dis)

                     0: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[0]; end

                     1: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[1]; end

                     2: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[2]; end

                     3: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[3]; end                 

                     4: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[4]; end

                     5: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[5]; end

                     6: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[6]; end

                     7: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[7]; end

                     8: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[8]; end

                     9: begin led_seg[1] <= led_reg[0];  led_seg[0] <= led_reg[9]; end

                     10: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[1]; end

                     11: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[2]; end

                     12: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[2]; end

                     13: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[3]; end

                     14: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[4]; end

                     15: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[5]; end

                     16: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[6]; end

                     17: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[7]; end

                     18: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[8]; end

                     19: begin led_seg[1] <= led_reg[1];  led_seg[0] <= led_reg[9]; end

                     20: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[0]; end

                     21: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[1]; end

                     22: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[2]; end

                     23: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[3]; end

                     24: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[4]; end

                     25: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[5]; end

                     26: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[6]; end

                     27: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[7]; end

                     28: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[8]; end

                     29: begin led_seg[1] <= led_reg[2];  led_seg[0] <= led_reg[9]; end

                     30: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[0]; end

                     31: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[1]; end

                     32: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[2]; end

                     33: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[3]; end

                     34: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[4]; end

                     35: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[5]; end

                     36: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[6]; end

                     37: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[7]; end

                     38: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[8]; end

                     39: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[9]; end

                     40: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[0]; end

                     41: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[1]; end

                     42: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[2]; end

                     43: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[3]; end

                     44: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[4]; end

                     45: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[5]; end

                     46: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[6]; end

                     47: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[7]; end

                     48: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[8]; end

                     49: begin led_seg[1] <= led_reg[4];  led_seg[0] <= led_reg[9]; end

                     50: begin led_seg[1] <= led_reg[3];  led_seg[0] <= led_reg[0]; end

                     51: begin led_seg[1] <= led_reg[5];  led_seg[0] <= led_reg[1]; end

                     52: begin led_seg[1] <= led_reg[5];  led_seg[0] <= led_reg[2]; end

                     53: begin led_seg[1] <= led_reg[5];  led_seg[0] <= led_reg[3]; end

                     54: begin led_seg[1] <= led_reg[5];  led_seg[0] <= led_reg[4]; end

                     55: begin led_seg[1] <= led_reg[5];  led_seg[0] <= led_reg[5]; end

                     56: begin led_seg[1] <= led_reg[5];  led_seg[0] <= led_reg[6]; end

                     57: begin led_seg[1] <= led_reg[5];  led_seg[0] <= led_reg[7]; end

                     58: begin led_seg[1] <= led_reg[5];  led_seg[0] <= led_reg[8]; end

                     59: begin led_seg[1] <= led_reg[5];  led_seg[0] <= led_reg[9]; end

                     60: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[0]; end

                     61: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[1]; end

                     62: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[2]; end

                     63: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[3]; end

                     64: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[4]; end

                     65: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[5]; end

                     66: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[6]; end

                     67: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[7]; end

                     68: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[8]; end

                     69: begin led_seg[1] <= led_reg[6];  led_seg[0] <= led_reg[9]; end

                     70: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[0]; end

                     71: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[1]; end

                     72: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[2]; end

                     73: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[3]; end

                     74: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[4]; end

                     75: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[5]; end

                     76: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[6]; end

                     77: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[7]; end

                     78: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[8]; end

                     79: begin led_seg[1] <= led_reg[7];  led_seg[0] <= led_reg[9]; end

                     80: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[0]; end

                     81: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[1]; end

                     82: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[2]; end

                     83: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[3]; end

                     84: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[4]; end

                     85: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[5]; end

                     86: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[6]; end

                     87: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[7]; end

                     88: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[8]; end

                     89: begin led_seg[1] <= led_reg[8];  led_seg[0] <= led_reg[9]; end

                     90: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[0]; end

                     91: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[1]; end

                     92: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[2]; end

                     93: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[3]; end

                     94: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[4]; end

                     95: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[5]; end

                     96: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[6]; end

                     97: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[7]; end

                     98: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[8]; end

                     99: begin led_seg[1] <= led_reg[9];  led_seg[0] <= led_reg[9]; end

                     default: ;

                     endcase



       其实不想给自己这么大工作量,但是一时还是想不到更好的算法,所以只有勉为其难了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
wangxia6112 发表于 2010-12-13 11:14:20 | 显示全部楼层
我还不知道如何下手呢
zxopenhl 发表于 2022-7-1 11:49:05 | 显示全部楼层
CPLD与ADC0804接口设计
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-11-23 15:43 , Processed in 0.064020 second(s), 24 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表