FPGA 30 综合数字ADC /DAC 信号发送采集系统设计(综合项目设计)

╰+攻爆jí腚メ 2022-09-09 14:43 218阅读 0赞

在这里插入图片描述

FPGA 30 综合数字ADC /DAC 信号发送采集系统设计(综合项目设计)

\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vb7w3fZO-1630512386043)(img/blog\_img/fpga/image-20210901224056651.png)\]

模块名称 : 综合数字ADC /DAC 信号发送采集系统设计

主要功能 :本实验设计了一个信号发送和采集系统的设计,在整个系统中,基于原先学习的key_filter 按键滤波模块,adc_12s022 模数转换驱动模块,dac_tlv5618 数模转换驱动模块,DAC_rom_siganl 信号rom存储器控制器模块,FIFO模块、FIFO_send_ctrl FIFO发送控制模块和uart_tx 串口发送模块构成了整个综合的实验系统。

输入信号有 : Key_in 、 Clk 、 Rst_n、 ADC_DOUT

输出信号有 :Rs232_Tx 、 ( ADC_CS_N 、ADC_DIN、ADC_SCLK) ( DAC_SCLK、DAC_DIN、DAC_CS_N)。

实现功能(设计思想/流程)是: 通过按键Key_in 按下,按键滤波以后,通过接收按键标志信号(key_flag) 和 按键状态信号(key_state) 输出给 按键控制采样模块,该模块通过判断FIFO数据是否已满、AD转换是否已经完成整这个3个信号来输出Ad_En_Conv 信号,即判断是否启动ADC 驱动模块开始电压(信号),并且内部该模块实现连续的100次采集,采集100次的数据信号,存储在中间的FIFO中,同时,本次使用的FIFO是一个单时钟,输入输出位宽相同的FIFO,在fifo_send_ctrl 模块,通过FIFO模块的FIFO_almost_empty 和 empty 信号输入给fifo_send_ctrl 模块,并且将器转换为标准的8bit发送的串口格式数据发送给uart_byte_tx 模块。此外,我们的信号也是通过fpga的rom资源来存储信号,并设计控制模块,驱动设计的dac_tlv5618 数模转换模块,并在外部的模拟信号连接到adc_128s022 的我们设定的采样通道。配合上半部分的电路连接,进而完成整个系统的设计。

1、首先实现整个系统设计图的下半部分

即:DAC信号存储控制模块的设计 DAC_rom_signal.v

  1. module DAC_rom_signal
  2. (
  3. Clk,
  4. Rst_n,
  5. DAC_State,
  6. DAC_DATA,
  7. Data_Start
  8. );
  9. input Clk ;
  10. input Rst_n;
  11. input DAC_State;
  12. output [15:0]DAC_DATA;
  13. output reg Data_Start;
  14. reg [11:0]address;
  15. wire clock ;
  16. wire [11:0]q;
  17. DAC_rom DAC_rom0(
  18. .address(address),
  19. .clock(clock),
  20. .q(q)
  21. );
  22. reg [31:0]timer_cnt ;
  23. reg timer_full_flag ;
  24. parameter Timer_Cnt_Full = 5_000_000 ; // 0.01s 循环定时 // 1S 循环计时 50_000_000 3s 150_000_000 clk div parameter
  25. reg r_Data_Start ; // 信号延时一个时钟
  26. // 定时器脉冲信号
  27. always@(posedge Clk or negedge Rst_n)
  28. if(!Rst_n)
  29. timer_cnt <= 32'd0;
  30. else if(timer_cnt == (Timer_Cnt_Full - 1'b1))
  31. timer_cnt <= 32'd0 ; //定时计数器清零
  32. else
  33. timer_cnt <= timer_cnt + 1'b1 ;
  34. // timer_full_flag
  35. always@(posedge Clk or negedge Rst_n)
  36. if(!Rst_n)
  37. timer_full_flag <= 1'd0;
  38. else if(timer_cnt == (Timer_Cnt_Full - 1'b1))
  39. timer_full_flag <= 1'd1;
  40. else
  41. timer_full_flag <= 1'd0;
  42. assign clock = timer_full_flag ;
  43. // reg [3:0]address ;
  44. always@(posedge Clk or negedge Rst_n)
  45. if(!Rst_n)
  46. address <= 4'd0 ;
  47. else if(timer_full_flag)
  48. address <= address +1'b1; // address 到 4095后会自动清零,相当于循环
  49. else
  50. address <= address ;
  51. // Data_Start DAC_DATA <= 1'b0;
  52. // 启动信号延时一个时钟周期 reg r_Data_Start ;
  53. always@(posedge Clk or negedge Rst_n)
  54. if(!Rst_n)
  55. r_Data_Start <= 1'b0 ;
  56. else if(timer_full_flag && DAC_State)
  57. r_Data_Start <= 1'b1 ;
  58. else
  59. r_Data_Start <= 1'b0 ;
  60. // 延时一个时钟节拍,保证信号可以跟新当前的DA数据
  61. always@(posedge Clk or negedge Rst_n)
  62. if(!Rst_n)
  63. Data_Start <= 1'b0 ;
  64. else
  65. Data_Start <= r_Data_Start ;
  66. assign DAC_DATA = {4'b0100,q} ; // 4'b0100 ,给通道1 发送信号
  67. endmodule

第2步 、dac_tlv5618.v dac芯片驱动设计

  1. module dac_tlv5618
  2. (
  3. Clk,
  4. Rst_n,
  5. DAC_DATA,
  6. Start,
  7. Set_Done,
  8. DAC_CS_N,
  9. DAC_DIN,
  10. DAC_SCLK,
  11. DAC_State
  12. );
  13. input Clk;
  14. input Rst_n;
  15. input [15:0]DAC_DATA;
  16. input Start;
  17. output reg Set_Done;
  18. output reg DAC_CS_N;
  19. output reg DAC_DIN;
  20. output reg DAC_SCLK;
  21. output DAC_State;
  22. assign DAC_State = DAC_CS_N;
  23. reg en;
  24. parameter DIV_PARAM = 2 ; // clk div parameter
  25. reg [3:0]DIV_CNT;
  26. reg SCLK2X;
  27. reg [5:0]SCLK_GEN_CNT ; // 状态机半周期计数个数
  28. wire trans_done ;
  29. // clk_div
  30. //
  31. reg [15:0]r_DAC_DATA ;
  32. always@(posedge Clk or negedge Rst_n)
  33. if(!Rst_n)
  34. r_DAC_DATA <= 16'd0;
  35. else if(Start)
  36. r_DAC_DATA <= DAC_DATA;
  37. else
  38. r_DAC_DATA <= r_DAC_DATA;
  39. // en singal handle
  40. always@(posedge Clk or negedge Rst_n)
  41. if(!Rst_n)
  42. en <= 1'b0;
  43. else if(Start)
  44. en <= 1'b1 ;
  45. else if(trans_done)
  46. en <= 1'b0;
  47. else
  48. en <= en ;
  49. // div_clk --> 12.5Mhz
  50. // reg [3:0]DIV_CNT;
  51. always@(posedge Clk or negedge Rst_n)
  52. if(!Rst_n)
  53. DIV_CNT <= 4'd0;
  54. else if(en)
  55. begin
  56. if(DIV_CNT == DIV_PARAM -1'b1)
  57. DIV_CNT <= 4'd0;
  58. else
  59. DIV_CNT <= DIV_CNT + 1'd1;
  60. end
  61. else
  62. DIV_CNT <= 4'd0;
  63. //生成2倍SCLK使能脉冲,时钟计数器
  64. //reg SCLK2X;
  65. always@(posedge Clk or negedge Rst_n)
  66. if(!Rst_n)
  67. SCLK2X <= 1'b0 ;
  68. else if(en && (DIV_CNT == (DIV_PARAM -1'b1) )) // must add en singal
  69. SCLK2X <= 1'b1;
  70. else
  71. SCLK2X <= 1'b0;
  72. // 状态机半周期计数
  73. // reg [5:0]SCLK_GEN_CNT ;
  74. always@(posedge Clk or negedge Rst_n)
  75. if(!Rst_n)
  76. SCLK_GEN_CNT <= 6'd0;
  77. else if(SCLK2X && en)
  78. begin
  79. if(SCLK_GEN_CNT == 6'd33)
  80. SCLK_GEN_CNT <= 6'd0;
  81. else
  82. SCLK_GEN_CNT <= SCLK_GEN_CNT +1'b1 ;
  83. end
  84. else
  85. SCLK_GEN_CNT <= SCLK_GEN_CNT ;
  86. // state machine handle
  87. // DAC_CS_N; DAC_DIN; DAC_SCLK;
  88. always@(posedge Clk or negedge Rst_n)
  89. if(!Rst_n)
  90. begin
  91. DAC_CS_N <= 1'd1;
  92. DAC_DIN <= 1'd0;
  93. DAC_SCLK <= 1'd1;
  94. end
  95. else if(SCLK2X && (!Set_Done))
  96. begin
  97. case(SCLK_GEN_CNT)
  98. 0 : begin DAC_CS_N <= 1'b0 ; DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[15]; end
  99. 2 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[14]; end
  100. 4 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[13]; end
  101. 6 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[12]; end
  102. 8 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[11]; end
  103. 10 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[10]; end
  104. 12 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[9]; end
  105. 14 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[8]; end
  106. 16 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[7]; end
  107. 18 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[6]; end
  108. 20 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[5]; end
  109. 22 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[4]; end
  110. 24 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[3]; end
  111. 26 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[2]; end
  112. 28 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[1]; end
  113. 30 : begin DAC_SCLK <= 1'b1 ; DAC_DIN <= r_DAC_DATA[0]; end
  114. 32 : begin DAC_SCLK <= 1'b1 ; end
  115. 33 : begin DAC_CS_N <= 1'b1 ; end
  116. 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31: begin DAC_SCLK <= 1'b0 ; end
  117. default: ;
  118. endcase
  119. end
  120. assign trans_done = (SCLK_GEN_CNT == 33) && SCLK2X ;
  121. // Set_Done handle
  122. always@(posedge Clk or negedge Rst_n)
  123. if(!Rst_n)
  124. Set_Done <= 1'b0;
  125. else if(trans_done)
  126. Set_Done <= 1'b1;
  127. else
  128. Set_Done <= 1'b0;
  129. endmodule

通过1、2步骤,可以实现连续信号发生器的设计。

第3部分 按键滤波模块 key_filter.v

  1. //定义按键函数端口
  2. module key_filter(
  3. Clk ,
  4. Rst_n ,
  5. key_in ,
  6. key_flag, //检测按键成功信号
  7. key_state //实时的信号
  8. );
  9. input Clk ;
  10. input Rst_n ;
  11. input key_in ;
  12. output reg key_flag ;
  13. output reg key_state ;
  14. //定义状态机
  15. localparam
  16. IDEL = 4'b0001 ,
  17. FILTER0 = 4'b0010 ,
  18. DOWN = 4'b0100 ,
  19. FILTER1 = 4'b1000 ;
  20. //定义使用到的寄存器
  21. reg [3:0]state ;
  22. reg key_tmp0 , key_tmp1 ; // key_in 的状态寄存器
  23. wire pedge , nedge ;
  24. reg en_cnt_20ms ;
  25. reg [19:0]cnt_20ms ;
  26. reg cnt_20ms_full ;
  27. //对外部输入的异步信号key_in进行同步处理
  28. reg key_in_sa,key_in_sb;
  29. always@(posedge Clk or negedge Rst_n)
  30. if(!Rst_n)begin
  31. key_in_sa <= 1'b0;
  32. key_in_sb <= 1'b0;
  33. end
  34. else begin
  35. key_in_sa <= key_in;
  36. key_in_sb <= key_in_sa;
  37. end
  38. //获取上一个周期的 按键电平 和当前 按键电平
  39. //目的: 获取 按键状态判断是否是下降沿还是上升沿到来
  40. always@(posedge Clk or negedge Rst_n)
  41. if(Rst_n == 1'b0) begin
  42. key_tmp0 <= 1'b0 ;
  43. key_tmp1 <= 1'b0 ;
  44. end
  45. else begin //每次时钟上升沿到来,两个寄存器读取上一次的数据的值
  46. key_tmp0 <= key_in_sb;
  47. key_tmp1 <= key_tmp0;
  48. end
  49. // 下降沿和上升沿到来标志位信号
  50. assign nedge = ((~key_tmp0 ) & ( key_tmp1)) ; //判断下降沿是否到来?
  51. //分析:: 下降沿到来的清况是高电平-->低电平的变换过程,也就是说:
  52. // key_tmp1 存的前1个时刻的电平,
  53. // key_tmp0 存的是当前时刻的电平,
  54. // 要满足该条件,也就是说, key_tmp0 <= 0 且 key_tmp1 <= 1; 此时得到 nedge = 1 ;
  55. assign pedge = key_tmp0 & (!key_tmp1) ; //判断上升沿是否到来?
  56. //状态机判断
  57. always@(posedge Clk or negedge Rst_n)
  58. if(!Rst_n) //复位状态下,状态机处于空闲状态
  59. begin
  60. state <= IDEL ; //复位状态下,状态机处于空闲模式下
  61. en_cnt_20ms <= 1'b0 ; //消抖计数器关闭
  62. key_flag <= 1'b0 ; //按键成功标志位清零
  63. key_state <= 1'b1 ; //默认输入按键状态高电平
  64. end
  65. else
  66. begin
  67. case(state)
  68. IDEL :
  69. begin
  70. key_flag <= 1'b0 ; //空闲状态下,按键成功标志位永远为0
  71. if(nedge == 1'b1) begin //按键检测到下降沿到来
  72. state <= FILTER0 ;//进入下一个案件滤波状态
  73. en_cnt_20ms <= 1 ;//开启使能计数20ms
  74. end
  75. else
  76. state <= IDEL ; //未检测到下降沿到来,信号状态保持不变
  77. end
  78. FILTER0:
  79. if(cnt_20ms_full == 1'b1) begin //看消除抖动20ms后,且20ms内没有检测到上升沿到来 = 20ms
  80. key_flag <= 1'b1; //表示按键 已经成功按下
  81. key_state<= 1'b0; //此时输入按键按下输出状态为低电平
  82. state <= DOWN ; //进入下一状态
  83. en_cnt_20ms <= 0 ; //20ms计数器关闭
  84. end
  85. else if(pedge == 1'b1) begin //没有满20ms 以内,有上升沿的到来,表明此时是抖动信号,非按键按下信号
  86. state <= IDEL ;
  87. en_cnt_20ms <= 0 ;//计数器关闭
  88. end
  89. else //上述两者情况均为出现,则状态机保持不变
  90. state <= FILTER0 ;
  91. DOWN:
  92. begin
  93. key_flag <= 1'b0; //检测到有按键按下,发送一个脉冲信号,由上一个状态的高电平变为低电平
  94. if(pedge == 1'b1) begin //上一个状态时间超过20ms,此时需要一直等待上升沿的到来(做为按键松开的标志)
  95. state <= FILTER1 ; //进入到下一状态
  96. en_cnt_20ms <= 1'b1 ;//开启下一次20ms 延时计数
  97. end
  98. else //没有,则保持该状态
  99. state <= DOWN ;
  100. end
  101. FILTER1:
  102. if(cnt_20ms_full == 1'b1) begin//表示 20ms计数又一次到来,此时按键稳定
  103. key_flag <= 1'b1; //表示上升沿的信号稳定的信号,随后到 IDEL又会设置为低电平,产生一个脉冲信号
  104. key_state<= 1'b1; //此时输入按键按下状态为低电平
  105. en_cnt_20ms <= 1'b0 ; //关闭20ms定时器
  106. state <=IDEL ;
  107. end
  108. else if(nedge)begin // 20ms内又出现了下降沿,表示这是一次抖动
  109. en_cnt_20ms <= 1'b0 ;
  110. state <= DOWN ;
  111. end
  112. else //20ms内状态保持不变
  113. state <=FILTER1 ;
  114. default:
  115. begin
  116. state <= IDEL ;
  117. key_flag <= 1'b0;
  118. key_state<= 1'b1; //默认状态时 1 高电平
  119. en_cnt_20ms <= 1'b0 ; //默认状态时 0 低电平
  120. end
  121. endcase
  122. end
  123. // 定时器启动 always块
  124. always@(posedge Clk or negedge Rst_n)
  125. if(!Rst_n)
  126. cnt_20ms <= 20'd0;
  127. else if(en_cnt_20ms)
  128. cnt_20ms <= cnt_20ms + 1'b1;
  129. else // 关闭时,计时器清零
  130. cnt_20ms <= 20'd0;
  131. //定时器20ms always块 50Mhz 20ms = cnt_20ms : 1_000_000
  132. always@(posedge Clk or negedge Rst_n)
  133. if(Rst_n == 1'b0)
  134. cnt_20ms_full <= 0 ;
  135. else if(cnt_20ms == 20'd999_999)
  136. cnt_20ms_full <= 1'b1 ; //计数值计满标志位
  137. else
  138. cnt_20ms_full <= 1'b0 ; // 未挤满,输出0
  139. endmodule

第4部分: ctrl_sample 通过按键按下滤波后的信号,控制ADC 驱动,完成连续的100次信号采集

  1. // 模块功能,每次按键按下,使用控制AD 100次信号采样
  2. // 采样的信号 存放到fifo中。
  3. module ctrl_sample
  4. (
  5. Clk,
  6. Rst_n,
  7. key_flag ,
  8. key_state ,
  9. Ad_Conv_Done,
  10. Fifo_almost_full,
  11. Ad_En_Conv
  12. );
  13. input Clk;
  14. input Rst_n;
  15. input key_flag ;
  16. input key_state ;
  17. input Ad_Conv_Done;
  18. input Fifo_almost_full;
  19. output reg Ad_En_Conv;
  20. parameter SAMPLE_TIMES = 100 ; //每次采样次数
  21. reg [6:0]sample_cnt ;
  22. // key_state key_flag
  23. // Ad_En_Conv ;
  24. reg en_flag ;
  25. always@(posedge Clk or negedge Rst_n)
  26. if(!Rst_n)
  27. en_flag <= 1'b0 ;
  28. else if(key_flag && (!key_state))
  29. begin
  30. if(Fifo_almost_full)
  31. en_flag <= 1'b0;
  32. else
  33. en_flag <= 1'b1;
  34. end
  35. else if(Fifo_almost_full || (sample_cnt== (SAMPLE_TIMES-1)) )
  36. en_flag <= 1'b0;
  37. else
  38. en_flag <= en_flag ;
  39. // Ad_En_Conv handle
  40. always@(posedge Clk or negedge Rst_n)
  41. if(!Rst_n)
  42. Ad_En_Conv <= 1'b0 ;
  43. else if(key_flag && (!key_state))
  44. begin
  45. if(Fifo_almost_full)
  46. Ad_En_Conv <= 1'b0;
  47. else
  48. Ad_En_Conv <= 1'b1;
  49. end
  50. else if(en_flag && Ad_Conv_Done)
  51. Ad_En_Conv <= 1'b1;
  52. else
  53. Ad_En_Conv <= 1'b0;
  54. // Ad_Conv_Done
  55. // Ad_En_Conv
  56. // sample_cnt
  57. always@(posedge Clk or negedge Rst_n)
  58. if(!Rst_n)
  59. sample_cnt <= 7'b0 ;
  60. else if(Ad_Conv_Done)
  61. begin
  62. if(sample_cnt == (SAMPLE_TIMES-1) )
  63. sample_cnt <=7'd0;
  64. else
  65. sample_cnt <= sample_cnt +1'b1;
  66. end
  67. else
  68. sample_cnt <= sample_cnt ;
  69. endmodule

第5部分: ad128s022.v 芯片驱动模块,可以设置采样通道、采样频率等基本输入参数,即可驱动信号。

  1. module ad128s022
  2. (
  3. Clk,
  4. Rst_n,
  5. Channel,
  6. Data,
  7. En_Conv,
  8. Conv_Done,
  9. ADC_State,
  10. DIV_PARAM,
  11. ADC_SCLK,
  12. ADC_DOUT,
  13. ADC_DIN,
  14. ADC_CS_N
  15. );
  16. input Clk;
  17. input Rst_n;
  18. input [2:0]Channel;
  19. output reg [11:0]Data;
  20. input En_Conv;
  21. output reg Conv_Done;
  22. output ADC_State;
  23. input [7:0]DIV_PARAM;
  24. output reg ADC_SCLK;
  25. input ADC_DOUT;
  26. output reg ADC_DIN;
  27. output reg ADC_CS_N;
  28. reg en ;
  29. reg [2:0]r_Channel;
  30. reg [7:0]DIV_CNT ;
  31. reg SCLK2X ;
  32. reg [5:0]SCLK_GEN_CNT;
  33. reg [11:0]r_Data;
  34. // en handle
  35. always@(posedge Clk or negedge Rst_n)
  36. if(!Rst_n)
  37. en <= 1'b0;
  38. else if(En_Conv)
  39. en <= 1'b1;
  40. else if(Conv_Done)
  41. en <= 1'b0 ;
  42. else
  43. en <= en ;
  44. // r_Channel we set En_Conv is a plus signal
  45. always@(posedge Clk or negedge Rst_n)
  46. if(!Rst_n)
  47. r_Channel <= 3'd0;
  48. else if(En_Conv)
  49. r_Channel <= Channel;
  50. else
  51. r_Channel <= r_Channel;
  52. // 时钟分频脉冲计数
  53. // reg [7:0]DIV_CNT ;
  54. always@(posedge Clk or negedge Rst_n)
  55. if(!Rst_n)
  56. DIV_CNT <= 8'd0 ;
  57. else if(en)
  58. begin
  59. if(DIV_CNT == (DIV_PARAM -1) )
  60. DIV_CNT <= 8'd0 ;
  61. else
  62. DIV_CNT <= DIV_CNT + 1'd1 ;
  63. end
  64. else
  65. DIV_CNT <= 8'd0 ;
  66. // SCLK2X plus
  67. // reg SCLK2X
  68. always@(posedge Clk or negedge Rst_n)
  69. if(!Rst_n)
  70. SCLK2X <= 1'b0;
  71. else if(DIV_CNT == (DIV_PARAM -1) )
  72. SCLK2X <= 1'b1 ;
  73. else
  74. SCLK2X <= 1'b0;
  75. // reg [5:0]SCLK_GEN_CNT
  76. always@(posedge Clk or negedge Rst_n)
  77. if(!Rst_n)
  78. SCLK_GEN_CNT <= 6'd0 ;
  79. else if(en && SCLK2X)
  80. begin
  81. if(SCLK_GEN_CNT == 6'd33)
  82. SCLK_GEN_CNT <=6'd0;
  83. else
  84. SCLK_GEN_CNT <= SCLK_GEN_CNT + 1'b1 ;
  85. end
  86. else
  87. SCLK_GEN_CNT <= SCLK_GEN_CNT ;
  88. //
  89. /*
  90. output ADC_SCLK
  91. input ADC_DOUT;
  92. output ADC_DIN;
  93. output reg ADC_CS_N;
  94. reg [11:0]r_Data;
  95. */
  96. always@(posedge Clk or negedge Rst_n)
  97. if(!Rst_n)
  98. begin
  99. ADC_SCLK <= 1'b1;
  100. ADC_DIN <= 1'b0;
  101. ADC_CS_N <= 1'b1;
  102. end
  103. else if(en && SCLK2X)
  104. begin
  105. case(SCLK_GEN_CNT)
  106. 0: begin ADC_CS_N <= 1'b0; ADC_SCLK <= 1'b1; ADC_DIN <= 1'b0; end
  107. 1,3: begin ADC_SCLK <= 1'b0; end
  108. 2,4,6,8: begin ADC_SCLK <= 1'b1 ; end
  109. 5: begin ADC_SCLK <= 1'b0; ADC_DIN <= r_Channel[2]; end
  110. 7: begin ADC_SCLK <= 1'b0; ADC_DIN <= r_Channel[1]; end
  111. 9: begin ADC_SCLK <= 1'b0; ADC_DIN <= r_Channel[0]; end
  112. 10: begin ADC_SCLK <= 1'b1; r_Data[11] <= ADC_DOUT ; end
  113. 12: begin ADC_SCLK <= 1'b1; r_Data[10] <= ADC_DOUT ; end
  114. 14: begin ADC_SCLK <= 1'b1; r_Data[9] <= ADC_DOUT ; end
  115. 16: begin ADC_SCLK <= 1'b1; r_Data[8] <= ADC_DOUT ; end
  116. 18: begin ADC_SCLK <= 1'b1; r_Data[7] <= ADC_DOUT ; end
  117. 20: begin ADC_SCLK <= 1'b1; r_Data[6] <= ADC_DOUT ; end
  118. 22: begin ADC_SCLK <= 1'b1; r_Data[5] <= ADC_DOUT ; end
  119. 24: begin ADC_SCLK <= 1'b1; r_Data[4] <= ADC_DOUT ; end
  120. 26: begin ADC_SCLK <= 1'b1; r_Data[3] <= ADC_DOUT ; end
  121. 28: begin ADC_SCLK <= 1'b1; r_Data[2] <= ADC_DOUT ; end
  122. 30: begin ADC_SCLK <= 1'b1; r_Data[1] <= ADC_DOUT ; end
  123. 32: begin ADC_SCLK <= 1'b1; r_Data[0] <= ADC_DOUT ; end
  124. 11,13,15,17,19,21,23,25,27,29,31: begin ADC_SCLK <= 1'b0; end
  125. 33: begin ADC_CS_N <= 1'b1; end
  126. default: ;
  127. endcase
  128. end
  129. // output [11:0]Data
  130. always@(posedge Clk or negedge Rst_n)
  131. if(!Rst_n)
  132. Data <= 12'd0 ;
  133. else if(en && SCLK2X && (SCLK_GEN_CNT == 6'd33))
  134. Data <= r_Data ;
  135. else
  136. Data <= Data ;
  137. // conv_Done signal
  138. always@(posedge Clk or negedge Rst_n)
  139. if(!Rst_n)
  140. Conv_Done <= 1'd0 ;
  141. else if(en && SCLK2X && (SCLK_GEN_CNT == 6'd33))
  142. Conv_Done <= 1'd1 ;
  143. else
  144. Conv_Done <= 1'd0 ;
  145. //产生ADC工作状态指示信号,保持和CS片选信号同步即可
  146. assign ADC_State = ADC_CS_N ;
  147. endmodule

第6部分、FIFO模块,注:这个一般来说,是调用内部IP 核来实现的,主要是看FIFO的配置,可以看一下 FPGA22 FIFO 的实现

  1. // megafunction wizard: %FIFO%
  2. // GENERATION: STANDARD
  3. // VERSION: WM1.0
  4. // MODULE: scfifo
  5. // ============================================================
  6. // File Name: AD_fifo.v
  7. // Megafunction Name(s):
  8. // scfifo
  9. //
  10. // Simulation Library Files(s):
  11. //
  12. // ============================================================
  13. // ************************************************************
  14. // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
  15. //
  16. // 13.0.0 Build 156 04/24/2013 SJ Full Version
  17. // ************************************************************
  18. //Copyright (C) 1991-2013 Altera Corporation
  19. //Your use of Altera Corporation's design tools, logic functions
  20. //and other software and tools, and its AMPP partner logic
  21. //functions, and any output files from any of the foregoing
  22. //(including device programming or simulation files), and any
  23. //associated documentation or information are expressly subject
  24. //to the terms and conditions of the Altera Program License
  25. //Subscription Agreement, Altera MegaCore Function License
  26. //Agreement, or other applicable license agreement, including,
  27. //without limitation, that your use is for the sole purpose of
  28. //programming logic devices manufactured by Altera and sold by
  29. //Altera or its authorized distributors. Please refer to the
  30. //applicable agreement for further details.
  31. // synopsys translate_off
  32. `timescale 1 ps / 1 ps
  33. // synopsys translate_on
  34. module AD_fifo (
  35. clock,
  36. data,
  37. rdreq,
  38. sclr,
  39. wrreq,
  40. almost_empty,
  41. almost_full,
  42. empty,
  43. full,
  44. q,
  45. usedw);
  46. input clock;
  47. input [11:0] data;
  48. input rdreq;
  49. input sclr;
  50. input wrreq;
  51. output almost_empty;
  52. output almost_full;
  53. output empty;
  54. output full;
  55. output [11:0] q;
  56. output [9:0] usedw;
  57. wire [9:0] sub_wire0;
  58. wire sub_wire1;
  59. wire sub_wire2;
  60. wire [11:0] sub_wire3;
  61. wire sub_wire4;
  62. wire sub_wire5;
  63. wire [9:0] usedw = sub_wire0[9:0];
  64. wire empty = sub_wire1;
  65. wire full = sub_wire2;
  66. wire [11:0] q = sub_wire3[11:0];
  67. wire almost_empty = sub_wire4;
  68. wire almost_full = sub_wire5;
  69. scfifo scfifo_component (
  70. .clock (clock),
  71. .sclr (sclr),
  72. .wrreq (wrreq),
  73. .data (data),
  74. .rdreq (rdreq),
  75. .usedw (sub_wire0),
  76. .empty (sub_wire1),
  77. .full (sub_wire2),
  78. .q (sub_wire3),
  79. .almost_empty (sub_wire4),
  80. .almost_full (sub_wire5),
  81. .aclr ());
  82. defparam
  83. scfifo_component.add_ram_output_register = "OFF",
  84. scfifo_component.almost_empty_value = 1,
  85. scfifo_component.almost_full_value = 1023,
  86. scfifo_component.intended_device_family = "Cyclone IV E",
  87. scfifo_component.lpm_numwords = 1024,
  88. scfifo_component.lpm_showahead = "OFF",
  89. scfifo_component.lpm_type = "scfifo",
  90. scfifo_component.lpm_width = 12,
  91. scfifo_component.lpm_widthu = 10,
  92. scfifo_component.overflow_checking = "ON",
  93. scfifo_component.underflow_checking = "ON",
  94. scfifo_component.use_eab = "ON";
  95. endmodule

第7 部分 fifo_send_ctrl.v文件,主要实现的是将fifo 的存放数据【12位】设置一个转换【8位】输出,输出串口标准的发送信号.

  1. module fifo_send_ctrl
  2. (
  3. Clk,
  4. Rst_n,
  5. Tx_done ,
  6. Fifo_empty ,
  7. Fifo_q,
  8. Tx_Send_en,
  9. Tx_Data,
  10. Fifo_rdreq
  11. );
  12. input Clk ;
  13. input Rst_n ;
  14. input Tx_done ;
  15. input Fifo_empty ;
  16. input [11:0]Fifo_q ;
  17. output reg Tx_Send_en ;
  18. output reg [7:0]Tx_Data ;
  19. output reg Fifo_rdreq ;
  20. //
  21. localparam
  22. STATE_S0 = 5'b0_0001,
  23. STATE_S1 = 5'b0_0010,
  24. STATE_S2 = 5'b0_0100,
  25. STATE_S3 = 5'b0_1000,
  26. STATE_S4 = 5'b1_0000;
  27. reg[4:0]state;
  28. always@(posedge Clk or negedge Rst_n)
  29. if(!Rst_n)begin
  30. state <= STATE_S0;
  31. end
  32. else begin
  33. case(state)
  34. STATE_S0:
  35. if(Fifo_empty == 1'b0)
  36. begin // fifo 有data
  37. Fifo_rdreq <= 1'b1 ; //发送读信号
  38. state <= STATE_S1;
  39. end
  40. else
  41. state <= STATE_S0;
  42. STATE_S1:
  43. begin
  44. Fifo_rdreq <= 1'b0 ;
  45. state <= STATE_S2;
  46. end
  47. STATE_S2:
  48. begin
  49. Tx_Send_en <= 1'b1;
  50. Tx_Data <= {4'b0000,Fifo_q[11:8]} ; // 先发送高8位
  51. state <= STATE_S3;
  52. end
  53. STATE_S3:
  54. if(Tx_done == 1'b1)
  55. begin
  56. Tx_Send_en <= 1'b1;
  57. Tx_Data <= Fifo_q[7:0] ; //再发送低8位
  58. state <= STATE_S4;
  59. end
  60. else
  61. begin
  62. Tx_Send_en <= 1'b0;
  63. state <= STATE_S3;
  64. end
  65. STATE_S4:
  66. if(Tx_done == 1'b1)
  67. state <= STATE_S0;
  68. else if(Tx_done == 1'b0)
  69. begin
  70. Tx_Send_en <= 1'b0;
  71. state <= STATE_S4;
  72. end
  73. default:state <= STATE_S1;
  74. endcase
  75. end
  76. endmodule

第8部分: uart_byte_tx .v 串口发送模块

  1. module uart_byte_tx(
  2. Clk,
  3. Rst_n,
  4. data_byte,
  5. send_en,
  6. baud_set,
  7. Rs232_Tx,
  8. Tx_Done,
  9. uart_state
  10. );
  11. input Clk;
  12. input Rst_n;
  13. input [7:0]data_byte;
  14. input send_en;
  15. input [2:0]baud_set;
  16. output reg Rs232_Tx;
  17. output reg Tx_Done;
  18. output reg uart_state;
  19. reg bps_clk; //波特率时钟
  20. reg [15:0]div_cnt;//分频计数器
  21. reg [15:0]bps_DR;//分频计数最大值
  22. reg [3:0]bps_cnt;//波特率时钟计数器
  23. reg [7:0]r_data_byte;
  24. localparam START_BIT = 1'b0;
  25. localparam STOP_BIT = 1'b1;
  26. always@(posedge Clk or negedge Rst_n)
  27. if(!Rst_n)
  28. uart_state <= 1'b0;
  29. else if(send_en)
  30. uart_state <= 1'b1;
  31. else if(bps_cnt == 4'd11)
  32. uart_state <= 1'b0;
  33. else
  34. uart_state <= uart_state;
  35. always@(posedge Clk or negedge Rst_n)
  36. if(!Rst_n)
  37. r_data_byte <= 8'd0;
  38. else if(send_en)
  39. r_data_byte <= data_byte;
  40. else
  41. r_data_byte <= r_data_byte;
  42. always@(posedge Clk or negedge Rst_n)
  43. if(!Rst_n)
  44. bps_DR <= 16'd5207;
  45. else begin
  46. case(baud_set)
  47. 0:bps_DR <= 16'd5207;
  48. 1:bps_DR <= 16'd2603;
  49. 2:bps_DR <= 16'd1301;
  50. 3:bps_DR <= 16'd867;
  51. 4:bps_DR <= 16'd433;
  52. default:bps_DR <= 16'd5207;
  53. endcase
  54. end
  55. //counter
  56. always@(posedge Clk or negedge Rst_n)
  57. if(!Rst_n)
  58. div_cnt <= 16'd0;
  59. else if(uart_state)begin
  60. if(div_cnt == bps_DR)
  61. div_cnt <= 16'd0;
  62. else
  63. div_cnt <= div_cnt + 1'b1;
  64. end
  65. else
  66. div_cnt <= 16'd0;
  67. // bps_clk gen
  68. always@(posedge Clk or negedge Rst_n)
  69. if(!Rst_n)
  70. bps_clk <= 1'b0;
  71. else if(div_cnt == 16'd1)
  72. bps_clk <= 1'b1;
  73. else
  74. bps_clk <= 1'b0;
  75. //bps counter
  76. always@(posedge Clk or negedge Rst_n)
  77. if(!Rst_n)
  78. bps_cnt <= 4'd0;
  79. else if(bps_cnt == 4'd11)
  80. bps_cnt <= 4'd0;
  81. else if(bps_clk)
  82. bps_cnt <= bps_cnt + 1'b1;
  83. else
  84. bps_cnt <= bps_cnt;
  85. always@(posedge Clk or negedge Rst_n)
  86. if(!Rst_n)
  87. Tx_Done <= 1'b0;
  88. else if(bps_cnt == 4'd11)
  89. Tx_Done <= 1'b1;
  90. else
  91. Tx_Done <= 1'b0;
  92. always@(posedge Clk or negedge Rst_n)
  93. if(!Rst_n)
  94. Rs232_Tx <= 1'b1;
  95. else begin
  96. case(bps_cnt)
  97. 0:Rs232_Tx <= 1'b1;
  98. 1:Rs232_Tx <= START_BIT;
  99. 2:Rs232_Tx <= r_data_byte[0];
  100. 3:Rs232_Tx <= r_data_byte[1];
  101. 4:Rs232_Tx <= r_data_byte[2];
  102. 5:Rs232_Tx <= r_data_byte[3];
  103. 6:Rs232_Tx <= r_data_byte[4];
  104. 7:Rs232_Tx <= r_data_byte[5];
  105. 8:Rs232_Tx <= r_data_byte[6];
  106. 9:Rs232_Tx <= r_data_byte[7];
  107. 10:Rs232_Tx <= STOP_BIT;
  108. default:Rs232_Tx <= 1'b1;
  109. endcase
  110. end
  111. endmodule

第九部分: 顶层设计文件,就是模块核模块之间的连接

  1. // 实验内容:
  2. // ① 通过按键控制AD采集模块
  3. // ② 按键按下,ad 进行采样100 次,操作
  4. // ③ ad 采样的数据存取到fifo 中
  5. // ④ 读取fifo中的数据,将数据通过串口模块发送,直到fifo 的数据全部读取完毕为止
  6. // ⑤ 读取的数据是12位,串口模块发送需要先变成标准的2个8位数据发送,通过电脑上的串口调试助手显示发送的数据
  7. // 信号发生器模块: 【内部有一个 DA_rom 数据模块】 ,每次间隔0.01S,发送一次模拟数据到,模拟信号发送通道1,发送出去
  8. // 信号采样时间现在本工程暂时无法控制,下一个工程【27_ADC_DAC_system】将会完善改功能
  9. module AD_DA_Top
  10. (
  11. Clk ,
  12. Rst_n ,
  13. key_in ,
  14. ADC_DOUT ,
  15. ADC_SCLK ,
  16. ADC_DIN ,
  17. ADC_CS_N ,
  18. Rs232_Tx ,
  19. DAC_CS_N ,
  20. DAC_DIN ,
  21. DAC_SCLK
  22. );
  23. input Clk ;
  24. input Rst_n ;
  25. input key_in ;
  26. input ADC_DOUT ;
  27. output ADC_SCLK;
  28. output ADC_DIN;
  29. output ADC_CS_N;
  30. output Rs232_Tx;
  31. // 信号源
  32. output DAC_CS_N;
  33. output DAC_DIN;
  34. output DAC_SCLK;
  35. wire key_flag ;
  36. wire key_state ;
  37. wire Ad_En_Conv;
  38. wire Conv_Done;
  39. wire Fifo_empty;
  40. wire Fifo_almost_full;
  41. wire Tx_Done;
  42. wire Tx_Send_en;
  43. wire [7:0]Tx_Data;
  44. wire [11:0]fifo_dtae;
  45. wire [11:0]Fifo_q;
  46. wire Fifo_rdreq;
  47. wire [15:0]DAC_DATA ;
  48. wire Start ;
  49. wire DAC_State;
  50. key_filter key_filter_0(
  51. .Clk(Clk) ,
  52. .Rst_n(Rst_n) ,
  53. .key_in(key_in) ,
  54. .key_flag(key_flag), //检测按键成功信号
  55. .key_state(key_state) //实时的信号
  56. );
  57. ctrl_sample ctrl_sample0
  58. (
  59. .Clk(Clk),
  60. .Rst_n(Rst_n),
  61. .key_flag(key_flag) ,
  62. .key_state(key_state) ,
  63. .Ad_Conv_Done(Conv_Done),
  64. .Fifo_almost_full(Fifo_almost_full),
  65. .Ad_En_Conv(Ad_En_Conv)
  66. );
  67. ad128s022 ad128s022_0
  68. (
  69. .Clk(Clk),
  70. .Rst_n(Rst_n),
  71. .Channel(3'd5),
  72. .Data(fifo_dtae),
  73. .En_Conv(Ad_En_Conv),
  74. .Conv_Done(Conv_Done),
  75. .ADC_State(), // 和 ADC_CS_N 状态保持一致
  76. .DIV_PARAM(8'd13),
  77. .ADC_SCLK(ADC_SCLK),
  78. .ADC_DOUT(ADC_DOUT),
  79. .ADC_DIN(ADC_DIN),
  80. .ADC_CS_N(ADC_CS_N)
  81. );
  82. AD_fifo AD_fifo_0 (
  83. .clock(Clk),
  84. .data(fifo_dtae),
  85. .rdreq(Fifo_rdreq),
  86. .sclr(!Rst_n),
  87. .wrreq(Conv_Done),
  88. .almost_empty(),
  89. .almost_full(Fifo_almost_full),
  90. .empty(Fifo_empty),
  91. .full(),
  92. .q(Fifo_q),
  93. .usedw()
  94. );
  95. fifo_send_ctrl fifo_send_ctrl_0
  96. (
  97. .Clk(Clk),
  98. .Rst_n(Rst_n),
  99. .Tx_done(Tx_Done) ,
  100. .Fifo_empty(Fifo_empty) ,
  101. .Fifo_q(Fifo_q),
  102. .Tx_Send_en(Tx_Send_en),
  103. .Tx_Data(Tx_Data),
  104. .Fifo_rdreq(Fifo_rdreq)
  105. );
  106. uart_byte_tx uart_byte_tx_0(
  107. .Clk(Clk),
  108. .Rst_n(Rst_n),
  109. .data_byte(Tx_Data),
  110. .send_en(Tx_Send_en),
  111. .baud_set(3'd4), // 115200bps
  112. .Rs232_Tx(Rs232_Tx),
  113. .Tx_Done(Tx_Done),
  114. .uart_state()
  115. );
  116. DAC_rom_signal DAC_rom_signal_0
  117. (
  118. .Clk(Clk),
  119. .Rst_n(Rst_n),
  120. .DAC_State(DAC_State),
  121. .DAC_DATA(DAC_DATA),
  122. .Data_Start(Start)
  123. );
  124. dac_tlv5618 dac_tlv5618_0
  125. (
  126. .Clk(Clk),
  127. .Rst_n(Rst_n),
  128. .DAC_DATA(DAC_DATA),
  129. .Start(Start),
  130. .Set_Done(),
  131. .DAC_CS_N(DAC_CS_N),
  132. .DAC_DIN(DAC_DIN),
  133. .DAC_SCLK(DAC_SCLK),
  134. .DAC_State(DAC_State)
  135. );
  136. endmodule

注: 本次作为一个综合实验,主要是对原先学习的知识做一个系统的设计,将现阶段所学的内容整合在一块,同时也需要知道真正在做fpga项目的时候,基本上都是先做系统模块化数字电路设计,后面模块再去写模块代码,做模块验证,最后根据顶层文件直接连接,最后综合和测试即可。

发表评论

表情:
评论列表 (有 0 条评论,218人围观)

还没有评论,来说两句吧...

相关阅读