当前位置:   article > 正文

基于vivado+Verilog FPGA开发 — 基于线性序列机的SPI接口ADC128S102逻辑控制_adc128s102具备sha

adc128s102具备sha

代码规范Verilog 代码规范_verilog代码编写规范-CSDN博客

开发流程FPGA基础知识----第二章 FPGA 开发流程_fpga 一个项目的整个流程-CSDN博客 

源码下载:GitHub - Redamancy785/FPGA-Learning-Record: 项目博客:https://blog.csdn.net/weixin_51460407

         这段 Verilog 代码定义了一个名为 adc128s102_driver 的模块,它是一个用于驱动 ADC128S102(一种模数转换器)的数字驱动程序。模块的功能是通过 SPI 接口与 ADC 通信,启动转换,读取数据,并在转换完成后提供数据输出。

零、ADC128S102芯片介绍

1、数据手册重要参数

2、板载原理图

一、功能定义

二、设计输入 

  1. module adc128s102_driver(
  2. clk_i,
  3. reset_n_i,
  4. addr_i,
  5. conv_go_i,
  6. dout_i,
  7. data_o,
  8. conv_done_o,
  9. cs_n_o,
  10. sclk_o,
  11. din_o
  12. );
  13. input [2:0] addr_i;
  14. input conv_go_i,dout_i,clk_i,reset_n_i;
  15. output conv_done_o,cs_n_o,sclk_o,din_o;
  16. output [11:0] data_o;
  17. // conv_go_i
  18. reg conv_en;
  19. always@(posedge clk_i or negedge reset_n_i)
  20. if(!reset_n_i)
  21. conv_en <= 0;
  22. else if(conv_go_i)
  23. conv_en <= 1;
  24. // sclk_o 翻转间隔计数器
  25. parameter FREQUENCY = 50_000_000; // Hz
  26. parameter SCLK_FREQUENCY = 12_500_000; // Hz
  27. parameter SCLK_TURN_INTERVAL = FREQUENCY/SCLK_FREQUENCY/2;
  28. reg [31:0] sclk_turn_interval_cnt;
  29. always@(posedge clk_i or negedge reset_n_i)
  30. if(!reset_n_i)
  31. sclk_turn_interval_cnt <= 0;
  32. else if(conv_en)begin
  33. if(sclk_turn_interval_cnt == (SCLK_TURN_INTERVAL - 1))
  34. sclk_turn_interval_cnt <= 0;
  35. else
  36. sclk_turn_interval_cnt <= sclk_turn_interval_cnt + 1;
  37. end else
  38. sclk_turn_interval_cnt <= 0;
  39. // sclk_o 翻转次数计数器
  40. reg [5:0] sclk_turn_cnt;
  41. parameter INTERVAL_NUMBER = 35;
  42. always@(posedge clk_i or negedge reset_n_i)
  43. if(!reset_n_i)
  44. sclk_turn_cnt <= 0;
  45. else if(sclk_turn_interval_cnt == (SCLK_TURN_INTERVAL - 1))
  46. if(sclk_turn_cnt == (INTERVAL_NUMBER - 1))
  47. sclk_turn_cnt <= 0;
  48. else
  49. sclk_turn_cnt <= sclk_turn_cnt + 1;
  50. // 序列机
  51. reg cs_n_o,sclk_o,din_o;
  52. reg [11:0] r_data_o;
  53. always@(*)
  54. if(!reset_n_i) begin
  55. r_data_o <= 0;
  56. sclk_o <= 1;
  57. din_o <= 0;
  58. end else begin
  59. case(sclk_turn_cnt)
  60. 0 : begin cs_n_o <= 1; sclk_o <= 1;end
  61. 1 : begin cs_n_o <= 0;end
  62. 2 : begin sclk_o <= 0;end
  63. 3 : begin sclk_o <= 1;end
  64. 4 : begin sclk_o <= 0;end
  65. 5 : begin sclk_o <= 1;end
  66. 6 : begin sclk_o <= 0; din_o <= addr_i[2];end
  67. 7 : begin sclk_o <= 1;end
  68. 8 : begin sclk_o <= 0; din_o <= addr_i[1];end
  69. 9 : begin sclk_o <= 1;end
  70. 10: begin sclk_o <= 0; din_o <= addr_i[0];end
  71. 11: begin sclk_o <= 1; r_data_o[11]<= dout_i;end
  72. 12: begin sclk_o <= 0;din_o <= 0;end
  73. 13: begin sclk_o <= 1;r_data_o[10] <= dout_i;end
  74. 14: begin sclk_o <= 0; end
  75. 15: begin sclk_o <= 1; r_data_o[9] <= dout_i;end
  76. 16: begin sclk_o <= 0; end
  77. 17: begin sclk_o <= 1; r_data_o[8] <= dout_i;end
  78. 18: begin sclk_o <= 0; end
  79. 19: begin sclk_o <= 1; r_data_o[7] <= dout_i;end
  80. 20: begin sclk_o <= 0; end
  81. 21: begin sclk_o <= 1; r_data_o[6] <= dout_i;end
  82. 22: begin sclk_o <= 0; end
  83. 23: begin sclk_o <= 1; r_data_o[5] <= dout_i;end
  84. 24: begin sclk_o <= 0; end
  85. 25: begin sclk_o <= 1; r_data_o[4] <= dout_i;end
  86. 26: begin sclk_o <= 0; end
  87. 27: begin sclk_o <= 1; r_data_o[3] <= dout_i;end
  88. 28: begin sclk_o <= 0; end
  89. 29: begin sclk_o <= 1; r_data_o[2] <= dout_i;end
  90. 30: begin sclk_o <= 0; end
  91. 31: begin sclk_o <= 1; r_data_o[1] <= dout_i;end
  92. 32: begin sclk_o <= 0; end
  93. 33: begin sclk_o <= 1; r_data_o[0] <= dout_i;end
  94. 34: begin cs_n_o <= 1; end
  95. endcase
  96. end
  97. // conv_done_o 与 data_o
  98. reg [11:0] data_o;
  99. reg conv_done_o;
  100. always@(posedge clk_i or negedge reset_n_i)
  101. if(!reset_n_i) begin
  102. data_o <= 0;
  103. conv_done_o <= 0;
  104. end else if((sclk_turn_cnt == INTERVAL_NUMBER - 1) && (sclk_turn_interval_cnt == (SCLK_TURN_INTERVAL - 1)))begin
  105. conv_done_o <= 1;
  106. data_o <= r_data_o;
  107. conv_en <= 0;
  108. end else
  109. conv_done_o <= 0;
  110. endmodule

三、功能仿真 

  1. `timescale 1ns / 1ps
  2. module adc128s102_driver_tb();
  3. reg [2:0] u_addr_i;
  4. reg u_conv_go_i,u_dout_i,u_clk_i,u_reset_n_i;
  5. wire u_conv_done_o,u_cs_n_o,u_sclk_o,u_din_o;
  6. wire [11:0] u_data_o;
  7. adc128s102_driver U_adc128s102_driver_0(
  8. .clk_i(u_clk_i),
  9. .reset_n_i(u_reset_n_i),
  10. .addr_i(u_addr_i),
  11. .conv_go_i(u_conv_go_i),
  12. .dout_i(u_dout_i),
  13. .data_o(u_data_o),
  14. .conv_done_o(u_conv_done_o),
  15. .cs_n_o(u_cs_n_o),
  16. .sclk_o(u_sclk_o),
  17. .din_o(u_din_o)
  18. );
  19. initial u_clk_i = 1;
  20. always #10 u_clk_i = ~u_clk_i;
  21. initial begin
  22. u_reset_n_i = 0;
  23. u_addr_i = 3'b101;
  24. u_dout_i = 0;
  25. #201;
  26. u_reset_n_i = 1;
  27. u_conv_go_i = 1;
  28. #40;
  29. u_conv_go_i = 0;
  30. #300;
  31. #80;
  32. u_dout_i = 1;#80;
  33. u_dout_i = 0;#80;
  34. u_dout_i = 1;#80;
  35. u_dout_i = 0;#80;
  36. u_dout_i = 1;#80;
  37. u_dout_i = 0;#80;
  38. u_dout_i = 1;#80;
  39. u_dout_i = 0;#80;
  40. u_dout_i = 1;#80;
  41. u_dout_i = 0;#80;
  42. u_dout_i = 1;#80;
  43. u_dout_i = 0;#80;
  44. u_dout_i = 0;
  45. #1_000;
  46. u_conv_go_i = 0;
  47. #1_000;
  48. $stop;
  49. end
  50. endmodule

 

四、综合优化

五、布局布线

六、时序仿真

七、板级调试 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/441611
推荐阅读
相关标签
  

闽ICP备14008679号