原创 CPLD与ADC0804接口设计

2008-7-8 11:08 7222 14 14 分类: FPGA/CPLD

CPLDADC0804接口设计<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


 


       这个实验做得比较郁闷,因为从上午开始一直摸不着头绪,虽然整体模块设计早早搞定。但是调试阶段可谓费尽周折,原因是没有抓住主要矛盾。一直以为是ADC0804的驱动部分没有做好,直到最后才发现原因出在显示部分。


但是发现问题后,却苦恼于如何用查表法来把8bitAD转换结果的各个数位分别存入寄存器中以便最后的数码管显示使用。显然的通常在软件的设计中,这样的问题用两个除法或者取余运算就可以解决的,但是在硬件上是不可以的,乘除运算是相当耗费资源的(当然了,如果硬件中不得不设计到这样的模块时,调用它是没问题的)。所以一般的计算在硬件上都是用其它的方法来替代乘除运算的,比如常用的加法或者查表法(关于卷积和的查表算法前面的日志中谈过了,也是一个相当经典的设计思路)。


这里的256个可能取值如何把各个位上的数值分别赋给相应寄存器就比较让人费神,得到的经验就是:我用100级的case语句比10级的if else if …… else…语句要来得节约硬件资源(整个设计240LE后者就不够用了)。个中原因也是显而易见的,判断if else对于只用一些逻辑门的硬件来说是多么的复杂的任务而,呵呵,大概就是这样了。所以以后在硬件设计的时候应该多比较这些语法,多总结,才能设计出更低成本更高性能的产品。硬件和软件设计不同,有时候往往越简单的语句用法反而越节约资源。


 


       好了,感慨了好一会,看来实验是没白做——学到东西了。这个设计其实很简单,就是通过CPLD来控制ADC0804工作,然后把从ADC0804读出的数值显示在数码管上。(这个实验好像有点老掉牙哈。~_~)


 点击看大图


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />


 点击看大图


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


 


       该设计的RTL视图如下:(三个模块)



dffe8a72-7d9d-4f62-a1e1-ccdf5579b9f8.jpg


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



c3920828-0b15-4ad8-88d3-f66674f5ab92.jpg


       控制部分的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


 


还有就是那个所谓的查表法,因为百位上只有012三种可能,所以用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


 


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


      

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
14
关闭 站长推荐上一条 /3 下一条