特权同学

CPLD与ADC0804接口设计

0
阅读(2649)

这个实验做得比较郁 闷,因为从上午开始一直摸不着头绪,虽然整体模块设计早早搞定。但是调试阶段可谓费尽周折,原因是没有抓住主要矛盾。一直以为是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

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

Baidu
map