当前位置:   article > 正文

七、基于FPGA的Flash控制器设计_fpga的flash加载有几条命令

fpga的flash加载有几条命令

根据项目需求,设计一个Flash控制器。以便将完成低速数据的存储。Flash选用了S25FL032。使用单线SPI接口,接线如图:

1,Flash S25fl032介绍

1.1 IO描述

1.2 相关命令介绍

1.3主要命令时序介绍

1.3.1 READ命令时序(读数据命令,最大支持40MHZ)

1.3.2 FAST_READ 命令时序(读数据命令,最大支持104MHZ)

1.3.3 READ_ID命令时序(读ID)

1.3.4 WREN,WRDI命令时序(写使能或写不使能)

1.3.5 PP命令(写时序)

1.3.6 SE命令时序(擦除)

2,控制器设计

该Flash支持4线和2线,1线读写;在设计中要求速率不高,因此,使用最简单的单线完成。

2.1 端口设计

  1. spi_flash_control #(
  2. parameter [31:0] SYSCLK = 32'd100_000_000,
  3. parameter [31:0] SPICLK = 32'd10_000_000
  4. )(
  5. input sys_clk,
  6. input sys_rst,
  7. input cmd_start,
  8. input [31:0] cmd_addr,
  9. input [31:0] wr_data, //write 4 byte
  10. output [31:0] rd_data, //read 4 byte
  11. output reg cmd_done,
  12. output flash_cs_n,
  13. output flash_sclk,
  14. input flash_sdi,
  15. output flash_sdo
  16. );

端口介绍:

cmd_start:发起命令,启动控制器;

cmd_addr:命令与地址;高8bit为命令,低24bit为地址;如果命令与地址无关,则低位为0;

wr_data:写数据;一次写4字节;

rd_data:读数据,一次读4自己;

cmd_done:命令完成,控制器完成一次操作。

2.2 命令解析

此处实现根据不同命令,控制实现读写选择,写寄存器装配;写时序bit长度计算。

  1. //flash cmd
  2. always @(posedge sys_clk) begin
  3. if(sys_rst) begin
  4. start_data_reg <= 0;
  5. spi_bit_len <= 0;
  6. wr_start <= 0;
  7. rd_start <= 0;
  8. end
  9. else if(cmd_start && cmd_addr[31:24] == 8'h03) begin
  10. start_data_reg <= {cmd_addr,32'd0};
  11. spi_bit_len <= 8 + 24 + 32;
  12. wr_start <= 0;
  13. rd_start <= 1;
  14. end
  15. else if(cmd_start && cmd_addr[31:24] == 8'h0b) begin
  16. start_data_reg <= {cmd_addr,32'd0};
  17. spi_bit_len <= 8 + 24 + 8 + 32;
  18. wr_start <= 0;
  19. rd_start <= 1;
  20. end
  21. else if(cmd_start && cmd_addr[31:24] == 8'h90) begin
  22. start_data_reg <= {cmd_addr,32'd0};
  23. spi_bit_len <= 8 + 24 + 8 + 8;
  24. wr_start <= 0;
  25. rd_start <= 1;
  26. end
  27. else if(cmd_start && cmd_addr[31:24] == 8'h05) begin
  28. start_data_reg <= {cmd_addr,32'd0};
  29. spi_bit_len <= 8 + 8;
  30. wr_start <= 0;
  31. rd_start <= 1;
  32. end
  33. else if(cmd_start && cmd_addr[31:24] == 8'h06) begin
  34. start_data_reg <= {cmd_addr,32'd0};
  35. spi_bit_len <= 8;
  36. wr_start <= 1;
  37. rd_start <= 0;
  38. end
  39. else if(cmd_start && cmd_addr[31:24] == 8'h02) begin
  40. start_data_reg <= {cmd_addr,wr_data};
  41. spi_bit_len <= 8 + 24 + 32;
  42. wr_start <= 1;
  43. rd_start <= 0;
  44. end
  45. else if(cmd_start && cmd_addr[31:24] == 8'h08) begin
  46. start_data_reg <= {cmd_addr,32'd0};
  47. spi_bit_len <= 8 + 24;
  48. wr_start <= 1;
  49. rd_start <= 0;
  50. end
  51. else begin
  52. start_data_reg <= start_data_reg;
  53. spi_bit_len <= spi_bit_len;
  54. wr_start <= 0;
  55. rd_start <= 0;
  56. end
  57. end

2.3 SPI CLK生成

  1. //spi clk
  2. always @ (posedge sys_clk) begin
  3. if(sys_rst) begin
  4. clk_div <= 0;
  5. clk_cnt <= 0;
  6. end
  7. else if(spi_run_en && clk_cnt >= spirate_val) begin
  8. clk_div <= !clk_div;
  9. clk_cnt <= 0;
  10. end
  11. else if(spi_run_en) begin
  12. clk_div <= clk_div;
  13. clk_cnt <= clk_cnt + 1;
  14. end
  15. else begin
  16. clk_div <= 0;
  17. clk_cnt <= 0;
  18. end
  19. clk_div_reg <= clk_div;
  20. clk_div_pose <= clk_div && !clk_div_reg;
  21. clk_div_nege <= !clk_div && clk_div_reg;
  22. end

2.4 控制器状态机

 控制完成命令,数据读写设计。

  1. //spi state
  2. always @ (posedge sys_clk) begin
  3. if(sys_rst)
  4. spi_state <= idlestate;
  5. else case(spi_state)
  6. idlestate : if(wr_start)
  7. spi_state <= wrstartstate;
  8. else if(rd_start)
  9. spi_state <= rdstartstate;
  10. else
  11. spi_state <= idlestate;
  12. wrstartstate : spi_state <= wrstate;
  13. wrstate : if(spi_bit_cnt == 0)
  14. spi_state <= wrdonestate;
  15. else
  16. spi_state <= wrstate;
  17. wrdonestate : spi_state <= idlestate;
  18. rdstartstate : spi_state <= rdstate;
  19. rdstate : if(spi_bit_cnt == 0)
  20. spi_state <= rddonestate;
  21. else
  22. spi_state <= rdstate;
  23. rddonestate : spi_state <= idlestate;
  24. default : spi_state <= idlestate;
  25. endcase
  26. end
  27. always @ (posedge sys_clk) begin
  28. if(sys_rst) begin
  29. spi_run_en <= 0;
  30. spi_bit_cnt <= 0;
  31. cs_int <= 0;
  32. sclk_int <= 0;
  33. sdo_int <= 0;
  34. cmd_done <= 0;
  35. tx_shift_data <= 0;
  36. rx_shift_data <= 0;
  37. rx_data_reg <= 0;
  38. end
  39. else case(spi_state)
  40. idlestate : begin
  41. spi_run_en <= 0;
  42. spi_bit_cnt <= 0;
  43. cs_int <= 0;
  44. sclk_int <= 0;
  45. sdo_int <= 0;
  46. cmd_done <= 0;
  47. tx_shift_data <= 0;
  48. rx_shift_data <= 0;
  49. rx_data_reg <= rx_data_reg;
  50. end
  51. wrstartstate : begin
  52. spi_run_en <= 1;
  53. spi_bit_cnt <= spi_bit_len;
  54. cs_int <= 1;
  55. sclk_int <= 0;
  56. sdo_int <= 0;
  57. cmd_done <= 0;
  58. tx_shift_data <= start_data_reg;
  59. rx_shift_data <= 0;
  60. rx_data_reg <= rx_data_reg;
  61. end
  62. wrstate : if(clk_div_nege) begin
  63. tx_shift_data <= {tx_shift_data[62:0],1'b0};
  64. spi_bit_cnt <= spi_bit_cnt - 1;
  65. end
  66. else begin
  67. spi_run_en <= 1;
  68. spi_bit_cnt <= spi_bit_cnt;
  69. cs_int <= 1;
  70. cmd_done <= 0;
  71. sclk_int <= clk_div;
  72. sdo_int <= tx_shift_data[63];
  73. tx_shift_data <= tx_shift_data;
  74. rx_shift_data <= 0;
  75. rx_data_reg <= rx_data_reg;
  76. end
  77. wrdonestate : begin
  78. spi_run_en <= 0;
  79. spi_bit_cnt <= 0;
  80. cs_int <= 0;
  81. sclk_int <= 0;
  82. sdo_int <= 0;
  83. cmd_done <= 1;
  84. tx_shift_data <= 0;
  85. rx_shift_data <= 0;
  86. rx_data_reg <= rx_data_reg;
  87. end
  88. rdstartstate : begin
  89. spi_run_en <= 1;
  90. spi_bit_cnt <= spi_bit_len;
  91. cs_int <= 1;
  92. sclk_int <= 0;
  93. sdo_int <= 0;
  94. cmd_done <= 0;
  95. tx_shift_data <= start_data_reg;
  96. rx_shift_data <= 0;
  97. rx_data_reg <= rx_data_reg;
  98. end
  99. rdstate : if(clk_div_nege) begin
  100. tx_shift_data <= {tx_shift_data[62:0],1'b0};
  101. spi_bit_cnt <= spi_bit_cnt - 1;
  102. end
  103. else if(clk_div_pose) begin
  104. rx_shift_data <= {rx_shift_data[31:0],flash_sdi};
  105. end
  106. else begin
  107. spi_run_en <= 1;
  108. spi_bit_cnt <= spi_bit_cnt;
  109. cs_int <= 1;
  110. cmd_done <= 0;
  111. sclk_int <= clk_div;
  112. sdo_int <= tx_shift_data[63];
  113. tx_shift_data <= tx_shift_data;
  114. rx_shift_data <= rx_shift_data;
  115. rx_data_reg <= rx_data_reg;
  116. end
  117. rddonestate : begin
  118. spi_run_en <= 0;
  119. spi_bit_cnt <= 0;
  120. cs_int <= 0;
  121. sclk_int <= 0;
  122. sdo_int <= 0;
  123. cmd_done <= 1;
  124. tx_shift_data <= 0;
  125. rx_shift_data <= 0;
  126. rx_data_reg <= rx_shift_data;
  127. end
  128. endcase
  129. end

 

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

闽ICP备14008679号