当前位置:   article > 正文

ZYNQ AXI4总线访问DDR3实现图像数据乒乓存储与显示_axi 访问ps ddr

axi 访问ps ddr

目录

前言

一、添加端口

二、添加局部变量

三、例化读写FIFO

四、内部变量修改,设置一次读写进行多少次突发操作

五、写地址

六、读地址

七、状态机

1.写状态机

2.读状态机

总结



前言

在Altera FPGA进行图像处理时,我们采用的存储芯片为SDRAM,当时参照正点原子的例程是封装SDRAM控制器,然后像操作FIFO一样去控制SDRAM。现在换了ZYNQ的板子后,由于DDR3是挂载在PS端的,Xilinx官方提供了视频接口的IP,但是IP这东西像个小黑盒子一样,在开发过程中遇到了问题,极其不易排查,所以我就在官方的AXI4—FULL接口代码上稍做修改,实现像以前一样像操作FIFO一样去操作PS端的DDR3。


一、添加端口

  1. // Users to add ports here
  2. //图像数据写端口
  3. input wire wr_clk, //输入像素时钟
  4. input wire wr_en, //数据有效信号
  5. input wire [15:0] wr_data, //像素数据
  6. //图像数据读端口
  7. input wire rd_clk, //输入hdmi驱动时钟
  8. input wire rd_en, //读请求
  9. output wire [15:0] rd_data, //像素数据

二、添加局部变量

触发一次读写DDR3的FIFO中的数据量设置为256,当写FIFO中的数据量大于THRESHOLD进行一次写操作的触发,当读FIFO中的数据量小于THRESHOLD时进行一次读操作的触发。一帧图像的最大存储地址为FIRST_FRAME

  1. // I/O Connections assignments
  2. localparam THRESHOLD = 256 ; //触发写FIFO读数据个数
  3. localparam FIRST_FRAME = (640*480)*4 ; //存储最大值

三、例化读写FIFO

用作数据缓存

  1. // Add user logic here
  2. //写数据补位
  3. assign din_wr_fifo = {16'd0,wr_data};
  4. assign wr_en_wr_fifo = wr_en;
  5. assign rd_en_wr = wnext;
  6. //写FIFO
  7. wr_fifo inst_fifo (
  8. .wr_clk(wr_clk), // input wire wr_clk
  9. .rd_clk(M_AXI_ACLK), // input wire rd_clk
  10. .din(din_wr_fifo), // input wire [31 : 0] din
  11. .wr_en(wr_en_wr_fifo), // input wire wr_en
  12. .rd_en(rd_en_wr), // input wire rd_en
  13. .dout(dout_wr_fifo), // output wire [31 : 0] dout
  14. .full(full_wr_fifo), // output wire full
  15. .empty(empty_wr_fifo), // output wire empty
  16. .rd_data_count(rd_data_count_wr_fifo) // output wire [11 : 0] rd_data_count
  17. );
  18. assign rd_data = dout_rd_fifo[15:0];
  19. assign wr_en_rd_fifo = rnext;
  20. //读FIFO
  21. rd_fifo inst_rd_fifo (
  22. .wr_clk(M_AXI_ACLK), // input wire wr_clk
  23. .rd_clk(rd_clk), // input wire rd_clk
  24. .din(M_AXI_RDATA), // input wire [63 : 0] din
  25. .wr_en(wr_en_rd_fifo), // input wire wr_en
  26. .rd_en(rd_en), // input wire rd_en
  27. .dout(dout_rd_fifo), // output wire [31 : 0] dout
  28. .full(full_rd_fifo), // output wire full
  29. .empty(empty_rd_fifo), // output wire empty
  30. .rd_data_count(rd_data_count_rd_fifo), // output wire [11 : 0] rd_data_count
  31. .wr_data_count(wr_data_count_rd_fifo) // output wire [10 : 0] wr_data_count
  32. );

四、内部变量修改,设置一次读写进行多少次突发操作

将原本代码里面C_MASTER_LENGTH 的数值12更改为10,原本的12表示一次读写操作进行64次突发操作,由于一次突发的数据量为16个32位的数据,所以64*16=1024个数据,与AXI4读写DDR3的实验现象一致,更改位10的原因为让其一次读写的数据量保持跟设置的THRESHOLD 一致都为256,避免数据冲突。

五、写地址

由于DDR3可以自由设置数据存储的地址,所以我们在代码内部自己划分读写bank,从而可以实现乒乓操作。

  1. always @(posedge M_AXI_ACLK)begin
  2. if(M_AXI_ARESETN == 0)begin
  3. bank_1 <= 2'b00;
  4. end
  5. else if((axi_awaddr[21:0] == FIRST_FRAME) && writes_done && bank_1 == 2'b00)begin
  6. bank_1 <= 2'b01;
  7. end
  8. else if((axi_awaddr[21:0] == FIRST_FRAME) && writes_done && bank_1 == 2'b01)begin
  9. bank_1 <= 2'b00;
  10. end
  11. else
  12. bank_1 <= bank_1;
  13. end
  14. always @(posedge M_AXI_ACLK)
  15. begin
  16. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
  17. begin
  18. axi_awaddr <= 'b0;
  19. sw_bank_en <= 1'b0;
  20. rw_bank_flag <= 1'b0;
  21. end
  22. else if (M_AXI_AWREADY && axi_awvalid)
  23. begin
  24. //bank0的剩余地址满足一次突发长度
  25. if(axi_awaddr[21:0] < FIRST_FRAME - burst_size_bytes)begin
  26. axi_awaddr <= axi_awaddr + burst_size_bytes;
  27. end
  28. //不满足切换BANK
  29. else begin
  30. axi_awaddr <= {8'b0000_0000,bank_1,22'd0};
  31. end
  32. end
  33. else
  34. axi_awaddr <= axi_awaddr;
  35. end

六、读地址

读地址操作与写地址类似。

七、状态机

1.写状态机

在原本官方状态机上删除读状态与读写错误判断状态。

  1. always @ ( posedge M_AXI_ACLK)
  2. begin
  3. if (M_AXI_ARESETN == 1'b0 )
  4. begin
  5. // reset condition
  6. // All the signals are assigned default values under reset condition
  7. mst_exec_state <= IDLE;
  8. start_single_burst_write <= 1'b0;
  9. compare_done <= 1'b0;
  10. ERROR <= 1'b0;
  11. end
  12. else
  13. begin
  14. // state transition
  15. case (mst_exec_state)
  16. IDLE:
  17. // This state is responsible to wait for user defined C_M_START_COUNT
  18. // number of clock cycles.
  19. if ( init_txn_pulse == 1'b1 || rd_data_count_wr_fifo >= THRESHOLD)
  20. begin
  21. mst_exec_state <= INIT_WRITE;
  22. start_single_burst_write <= 1'b0;
  23. ERROR <= 1'b0;
  24. compare_done <= 1'b0;
  25. end
  26. else
  27. begin
  28. mst_exec_state <= IDLE;
  29. end
  30. INIT_WRITE:
  31. // This state is responsible to issue start_single_write pulse to
  32. // initiate a write transaction. Write transactions will be
  33. // issued until burst_write_active signal is asserted.
  34. // write controller
  35. if (writes_done)
  36. begin
  37. mst_exec_state <= IDLE;//
  38. start_single_burst_write <= 1'b0;
  39. end
  40. else
  41. begin
  42. mst_exec_state <= INIT_WRITE;
  43. if (~axi_awvalid && ~start_single_burst_write && ~burst_write_active)
  44. begin
  45. start_single_burst_write <= 1'b1;
  46. end
  47. else
  48. begin
  49. start_single_burst_write <= 1'b0; //Negate to generate a pulse
  50. end
  51. end
  52. default :
  53. begin
  54. mst_exec_state <= IDLE;
  55. end
  56. endcase
  57. end
  58. end

2.读状态机

与写状态机类似,照着来就行

  1. always @(posedge M_AXI_ACLK)begin
  2. if(M_AXI_ARESETN == 1'b0)begin
  3. curr_state <= IDLE;
  4. start_single_burst_read <= 1'b0;
  5. end
  6. else begin
  7. case(curr_state)
  8. IDLE:
  9. if(wr_data_count_rd_fifo < 2048-THRESHOLD)begin
  10. curr_state <= INIT_READ;
  11. start_single_burst_read <= 1'b0;
  12. end
  13. else begin
  14. curr_state <= IDLE;
  15. end
  16. INIT_READ:
  17. if(reads_done)begin
  18. curr_state <= IDLE;
  19. start_single_burst_read <= 1'b0;
  20. end
  21. else begin
  22. curr_state <= INIT_READ;
  23. if(~axi_arvalid && ~burst_read_active && ~start_single_burst_read)begin
  24. start_single_burst_read <= 1'b1;
  25. end
  26. else begin
  27. start_single_burst_read <= 1'b0;
  28. end
  29. end
  30. default :
  31. begin
  32. curr_state <= IDLE;
  33. end
  34. endcase
  35. end
  36. end

总结

一开始拿到AXI4总线我也是一头雾水,但认真看完总线介绍还是比较简单的

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

闽ICP备14008679号