当前位置:   article > 正文

vivado DDR4读写存储以及一些坑_fpga ddr4读写异常

fpga ddr4读写异常

DDR4读写控制模块

  1. module ddr4_control#(
  2. parameter MEM_DATA_BITS = 512 ,
  3. parameter ADDR_BITS = 26 ,
  4. parameter BUSRT_BITS = 10 ,//突发的位宽长度
  5. parameter BURST_LEN = 5
  6. )
  7. (
  8. input i_sys_clk ,
  9. input i_sys_rst ,
  10. input i_wr_data_rdy ,
  11. output reg [MEM_DATA_BITS-1:0] o_wr_data ,
  12. output reg o_wr_ddr4_req ,
  13. input i_rd_data_vaild ,
  14. input [MEM_DATA_BITS-1:0] i_rd_ddr4_data ,
  15. output reg o_rd_ddr4_req ,
  16. output [BUSRT_BITS-1:0] o_wr_burst_length ,
  17. output [BUSRT_BITS-1:0] o_rd_burst_length ,
  18. output reg [ADDR_BITS-1:0] o_wr_base_ddr4_addr ,
  19. output reg [ADDR_BITS-1:0] o_rd_base_ddr4_addr ,
  20. input i_wr_finished ,
  21. input i_rd_finished
  22. );
  23. localparam IDLE = 3'b000 ;
  24. localparam WRITE = 3'b001 ;
  25. localparam READ = 3'b011 ;
  26. reg [11:0] wr_data_count ;
  27. reg [11:0] rd_data_count ;
  28. reg [2:0] current_state ;
  29. reg [2:0] next_state ;
  30. assign o_wr_burst_length = BURST_LEN;
  31. assign o_rd_burst_length = BURST_LEN;
  32. always @(posedge i_sys_clk or posedge i_sys_rst) begin
  33. if(i_sys_rst) begin
  34. current_state <= IDLE;
  35. end
  36. else begin
  37. current_state <= next_state;
  38. end
  39. end
  40. always @(*) begin
  41. case(current_state)
  42. IDLE: begin
  43. next_state = WRITE;
  44. end
  45. WRITE: begin
  46. if(i_wr_finished) begin
  47. next_state = READ;
  48. end
  49. else begin
  50. next_state = WRITE;
  51. end
  52. end
  53. READ: begin
  54. if(i_rd_finished) begin
  55. next_state = IDLE;
  56. end
  57. else begin
  58. next_state = READ;
  59. end
  60. end
  61. default:begin
  62. next_state = IDLE;
  63. end
  64. endcase
  65. end
  66. always @(posedge i_sys_clk or posedge i_sys_rst) begin
  67. if(i_sys_rst) begin
  68. o_wr_ddr4_req <= 1'd0;
  69. o_rd_ddr4_req <= 1'd0;
  70. end
  71. else if( current_state == IDLE || (current_state == READ && i_rd_finished))begin
  72. o_wr_ddr4_req <= 1'd1;
  73. o_rd_ddr4_req <= 1'd0;
  74. end
  75. else if( current_state == WRITE && i_wr_finished)begin
  76. o_wr_ddr4_req <= 1'd0;
  77. o_rd_ddr4_req <= 1'd1;
  78. end
  79. else begin
  80. o_wr_ddr4_req <= o_wr_ddr4_req;
  81. o_rd_ddr4_req <= o_rd_ddr4_req;
  82. end
  83. end
  84. always @(posedge i_sys_clk or posedge i_sys_rst) begin
  85. if(i_sys_rst) begin
  86. wr_data_count <= 12'd0;
  87. end
  88. else if(current_state == WRITE && wr_data_count == BURST_LEN - 12'd1 || current_state == IDLE ) begin
  89. wr_data_count <= 12'd0;
  90. end
  91. else if(current_state == WRITE && i_wr_data_rdy ) begin
  92. wr_data_count <= wr_data_count + 12'd1;
  93. end
  94. else begin
  95. wr_data_count <= wr_data_count;
  96. end
  97. end
  98. always @(posedge i_sys_clk or posedge i_sys_rst) begin
  99. if(i_sys_rst) begin
  100. o_wr_data <= {MEM_DATA_BITS{1'd0}};
  101. end
  102. else if(current_state == WRITE && i_wr_data_rdy ) begin
  103. o_wr_data <= o_wr_data + 'd10;
  104. end
  105. else begin
  106. wr_data_count <= wr_data_count;
  107. end
  108. end
  109. always @(posedge i_sys_clk or posedge i_sys_rst) begin
  110. if(i_sys_rst) begin
  111. rd_data_count <= 12'd0;
  112. end
  113. else if(current_state == READ && rd_data_count == BURST_LEN - 12'd1 || current_state == IDLE ) begin
  114. rd_data_count <= 12'd0;
  115. end
  116. else if(current_state == READ && i_rd_data_vaild ) begin
  117. rd_data_count <= rd_data_count + 12'd1;
  118. end
  119. else begin
  120. rd_data_count <= rd_data_count;
  121. end
  122. end
  123. always @(posedge i_sys_clk or posedge i_sys_rst) begin
  124. if(i_sys_rst) begin
  125. o_rd_base_ddr4_addr <= {ADDR_BITS{1'd0}};
  126. o_wr_base_ddr4_addr <= {ADDR_BITS{1'd0}};
  127. end
  128. else if(i_rd_finished ) begin
  129. o_rd_base_ddr4_addr <= o_rd_base_ddr4_addr + BURST_LEN;
  130. o_wr_base_ddr4_addr <= o_wr_base_ddr4_addr + BURST_LEN;
  131. end
  132. else begin
  133. o_rd_base_ddr4_addr <= o_rd_base_ddr4_addr;
  134. o_wr_base_ddr4_addr <= o_wr_base_ddr4_addr;
  135. end
  136. end
  137. endmodule

DDR4 app接口控制

  1. module ddr4_app
  2. #(
  3. parameter ADDR_BITS = 26 ,
  4. parameter MEM_DATA_BITS = 512 ,
  5. parameter APP_ADDR_BITS = 29 ,
  6. parameter BURST_BITS = 10 //突发长度的位宽
  7. )
  8. (
  9. input i_sys_clk ,
  10. input i_sys_rst ,
  11. output o_wr_data_rdy ,
  12. input [MEM_DATA_BITS-1:0] i_wr_data ,
  13. input i_wr_ddr4_req ,
  14. output o_rd_data_vaild ,
  15. output [MEM_DATA_BITS-1:0] o_rd_ddr4_data ,
  16. input i_rd_ddr4_req ,
  17. input [BURST_BITS-1:0] i_wr_burst_length ,
  18. input [BURST_BITS-1:0] i_rd_burst_length ,
  19. input [BURST_BITS-1:0] i_wr_base_ddr4_addr ,
  20. input [BURST_BITS-1:0] i_rd_base_ddr4_addr ,
  21. output reg o_wr_finished ,
  22. output reg o_rd_finished ,
  23. //DDR phy接口的信号
  24. output o_c0_init_calib_complete ,
  25. input i_c0_sys_clk_p ,
  26. input i_c0_sys_clk_n ,
  27. output o_c0_ddr4_act_n ,
  28. output [16:0] o_c0_ddr4_adr ,
  29. output [1:0] o_c0_ddr4_ba ,
  30. output [0:0] o_c0_ddr4_bg ,
  31. output [0:0] o_c0_ddr4_cke ,
  32. output [0:0] o_c0_ddr4_odt ,
  33. output [0:0] o_c0_ddr4_cs_n ,
  34. output [0:0] o_c0_ddr4_ck_t ,
  35. output [0:0] o_c0_ddr4_ck_c ,
  36. output o_c0_ddr4_reset_n ,
  37. inout [7:0] io_c0_ddr4_dm_dbi_n ,
  38. inout [63:0] io_c0_ddr4_dq ,
  39. inout [7:0] io_c0_ddr4_dqs_t ,
  40. inout [7:0] io_c0_ddr4_dqs_c ,
  41. output o_ddr4_clk ,
  42. output o_ddr4_rst
  43. );
  44. localparam IDLE = 3'b000 ;
  45. localparam WRITE = 3'b001 ;
  46. localparam READ = 3'b011 ;
  47. localparam READ_WAIT = 3'b010 ;
  48. wire [APP_ADDR_BITS-1:0] app_addr ;
  49. wire [2:0] app_cmd ;
  50. wire app_en ;
  51. wire [MEM_DATA_BITS-1:0] app_wdf_data ;
  52. wire app_wdf_end ;
  53. wire [MEM_DATA_BITS/8-1:0] app_wdf_mask ;
  54. wire app_wdf_wren ;
  55. wire [MEM_DATA_BITS-1:0] app_rd_data ;
  56. wire app_rd_data_end ;
  57. wire app_rd_data_valid ;
  58. wire app_rdy ;
  59. wire app_wdf_rdy ;
  60. wire c0_ddr4_ui_clk ;
  61. wire c0_ddr4_ui_clk_sync_rst ;
  62. wire [BURST_BITS + 12 -1 : 0 ] wr_burst_addr ;// burst_addr = base_addr + offset_addr
  63. wire [BURST_BITS + 12 -1 : 0 ] rd_burst_addr ;
  64. reg [2:0] app_cmd_r ;
  65. reg app_en_r ;
  66. // reg [MEM_DATA_BITS/8-1:0] app_wdf_mask_r ;
  67. reg app_wdf_wren_r ;
  68. reg [MEM_DATA_BITS-1:0] app_rd_data_r ;
  69. reg app_rd_data_end_r ;
  70. reg [MEM_DATA_BITS-1:0] app_wdf_data_r ;
  71. // reg app_rd_data_valid_r ;
  72. // reg app_rdy_r ;
  73. // reg app_wdf_rdy_r ;
  74. reg [2:0] current_state ;
  75. reg [2:0] next_state ;
  76. reg [11:0] wr_data_count ;
  77. reg [11:0] wr_addr_count ;
  78. reg [11:0] rd_data_count ;
  79. reg [11:0] rd_addr_count ;
  80. //******************************************assign*****************************************************
  81. // assign o_ddr4_clk = c0_ddr4_ui_clk;
  82. // assign o_ddr4_rst = c0_ddr4_ui_clk_sync_rst;
  83. assign wr_burst_addr = (wr_addr_count + i_wr_base_ddr4_addr) << 3;
  84. assign rd_burst_addr = (rd_addr_count + i_rd_base_ddr4_addr) << 3;
  85. assign app_cmd = app_cmd_r;
  86. assign app_en = app_en_r;
  87. assign o_wr_data_rdy = app_wdf_rdy && (current_state == WRITE)&&app_en;
  88. assign o_rd_data_vaild = app_rd_data_valid;
  89. assign o_rd_ddr4_data = app_rd_data;
  90. // assign app_wdf_wren = app_en & app_wdf_rdy;
  91. assign app_wdf_wren = app_wdf_wren_r;
  92. assign app_addr = (current_state == WRITE) ? wr_burst_addr:
  93. (current_state == READ) ? rd_burst_addr: {APP_ADDR_BITS{1'd0}};
  94. assign app_wdf_data = i_wr_data;
  95. assign app_wdf_mask = {MEM_DATA_BITS/8{1'b0}};
  96. assign app_wdf_end = app_wdf_wren;
  97. //*****************************************************************************************************
  98. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  99. if(o_ddr4_rst) begin
  100. app_wdf_data_r <= {MEM_DATA_BITS{1'd0}};
  101. end
  102. else begin
  103. app_wdf_data_r <= i_wr_data;
  104. end
  105. end
  106. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  107. if(o_ddr4_rst) begin
  108. current_state <= IDLE;
  109. end
  110. else begin
  111. current_state <= next_state;
  112. end
  113. end
  114. always @(*)begin
  115. if (o_c0_init_calib_complete)
  116. case(current_state)
  117. IDLE: begin
  118. if (i_wr_ddr4_req) begin
  119. next_state = WRITE;
  120. end
  121. else if (i_rd_ddr4_req) begin
  122. next_state = READ;
  123. end
  124. else begin
  125. next_state = IDLE;
  126. end
  127. end
  128. WRITE: begin
  129. if(o_wr_finished) begin
  130. next_state = IDLE;
  131. end
  132. else begin
  133. next_state = WRITE;
  134. end
  135. end
  136. READ: begin
  137. if(rd_addr_count == i_rd_burst_length - 'd1 ) begin
  138. next_state = READ_WAIT;
  139. end
  140. else if(o_rd_finished) begin
  141. next_state = IDLE;
  142. end
  143. else begin
  144. next_state = READ;
  145. end
  146. end
  147. READ_WAIT: begin
  148. if (o_rd_finished) begin
  149. next_state = IDLE;
  150. end
  151. else begin
  152. next_state = READ_WAIT;
  153. end
  154. end
  155. default:begin
  156. next_state = IDLE;
  157. end
  158. endcase
  159. else begin
  160. next_state = IDLE;
  161. end
  162. end
  163. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  164. if(o_ddr4_rst) begin
  165. app_cmd_r <= 3'd0;
  166. end
  167. else if (current_state == WRITE )begin
  168. app_cmd_r <= 3'd0;
  169. end
  170. else if (current_state == READ )begin
  171. app_cmd_r <= 3'd1;
  172. end
  173. else begin
  174. app_cmd_r <= app_cmd_r;
  175. end
  176. end
  177. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  178. if(o_ddr4_rst) begin
  179. app_wdf_wren_r <= 1'd0;
  180. end
  181. // else if ((current_state == WRITE && o_wr_finished) ||(current_state == READ &&o_rd_finished ) ) begin
  182. else if ((current_state == WRITE && o_wr_finished)) begin
  183. app_wdf_wren_r <= 1'd0;
  184. end
  185. else if ((current_state == WRITE) && app_rdy && app_wdf_rdy )begin
  186. app_wdf_wren_r <= 1'd1;
  187. end
  188. else begin
  189. app_wdf_wren_r <= app_wdf_wren_r;
  190. end
  191. end
  192. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  193. if(o_ddr4_rst) begin
  194. app_en_r <= 1'd0;
  195. end
  196. // else if ((current_state == WRITE && o_wr_finished) ||(current_state == READ &&o_rd_finished ) ) begin
  197. else if ((current_state == WRITE && o_wr_finished) || rd_addr_count == i_rd_burst_length - 1) begin
  198. app_en_r <= 1'd0;
  199. end
  200. else if ((current_state == WRITE || current_state == READ) && app_rdy )begin
  201. app_en_r <= 1'd1;
  202. end
  203. else begin
  204. app_en_r <= app_en_r;
  205. end
  206. end
  207. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  208. if(o_ddr4_rst) begin
  209. wr_data_count <= 12'd0;
  210. end
  211. else if (current_state == WRITE && wr_data_count == i_wr_burst_length - 12'd1 )begin
  212. wr_data_count <= 12'd0;
  213. end
  214. else if (current_state == WRITE && app_rdy && app_wdf_rdy && app_en_r) begin
  215. wr_data_count <= wr_data_count + 12'd1;
  216. end
  217. else begin
  218. wr_data_count <= wr_data_count;
  219. end
  220. end
  221. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  222. if(o_ddr4_rst) begin
  223. wr_addr_count <= 12'd0;
  224. end
  225. else if (current_state == WRITE && wr_data_count == i_wr_burst_length - 12'd1 )begin
  226. wr_addr_count <= 12'd0;
  227. end
  228. else if (current_state == WRITE && app_rdy && app_wdf_rdy && app_en_r) begin
  229. wr_addr_count <= wr_addr_count + 12'd1;
  230. end
  231. else begin
  232. wr_addr_count <= wr_addr_count;
  233. end
  234. end
  235. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  236. if(o_ddr4_rst) begin
  237. o_wr_finished <= 1'd0;
  238. end
  239. else if (current_state == WRITE && (wr_data_count == i_wr_burst_length - 12'd2 ))begin
  240. o_wr_finished <= 1'd1;
  241. end
  242. else begin
  243. o_wr_finished <= 1'd0;
  244. end
  245. end
  246. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  247. if(o_ddr4_rst) begin
  248. rd_addr_count <= 12'd0;
  249. end
  250. else if (current_state == READ &&rd_addr_count == i_rd_burst_length - 'd1 )begin
  251. rd_addr_count <= 12'd0;
  252. end
  253. else if (current_state == READ && app_rdy && app_en_r) begin
  254. rd_addr_count <= rd_addr_count + 12'd1;
  255. end
  256. else begin
  257. rd_addr_count <= rd_addr_count;
  258. end
  259. end
  260. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  261. if(o_ddr4_rst) begin
  262. rd_data_count <= 12'd0;
  263. end
  264. else if ((rd_data_count == i_rd_burst_length -1'd1) && app_rd_data_valid) begin
  265. rd_data_count <= 12'd0;
  266. end
  267. else if ((current_state == READ || current_state == READ_WAIT) && app_rd_data_valid )begin
  268. rd_data_count <= rd_data_count + 12'd1;
  269. end
  270. else begin
  271. rd_data_count <= rd_data_count;
  272. end
  273. end
  274. always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
  275. if(o_ddr4_rst) begin
  276. o_rd_finished <= 1'd0;
  277. end
  278. else if (( current_state == READ || current_state == READ_WAIT) && (rd_data_count == i_rd_burst_length - 12'd1 ) && app_rd_data_valid)begin
  279. o_rd_finished <= 1'd1;
  280. end
  281. else begin
  282. o_rd_finished <= 1'd0;
  283. end
  284. end
  285. ddr4_0 u_ddr4
  286. (
  287. .sys_rst (i_sys_rst ),
  288. .c0_sys_clk_p (i_c0_sys_clk_p ),
  289. .c0_sys_clk_n (i_c0_sys_clk_n ),
  290. .c0_init_calib_complete (o_c0_init_calib_complete ),
  291. .c0_ddr4_act_n (o_c0_ddr4_act_n ),
  292. .c0_ddr4_adr (o_c0_ddr4_adr ),
  293. .c0_ddr4_ba (o_c0_ddr4_ba ),
  294. .c0_ddr4_bg (o_c0_ddr4_bg ),
  295. .c0_ddr4_cke (o_c0_ddr4_cke ),
  296. .c0_ddr4_odt (o_c0_ddr4_odt ),
  297. .c0_ddr4_cs_n (o_c0_ddr4_cs_n ),
  298. .c0_ddr4_ck_t (o_c0_ddr4_ck_t ),
  299. .c0_ddr4_ck_c (o_c0_ddr4_ck_c ),
  300. .c0_ddr4_reset_n (o_c0_ddr4_reset_n ),
  301. .c0_ddr4_dm_dbi_n (io_c0_ddr4_dm_dbi_n),
  302. .c0_ddr4_dq (io_c0_ddr4_dq ),
  303. .c0_ddr4_dqs_c (io_c0_ddr4_dqs_c ),
  304. .c0_ddr4_dqs_t (io_c0_ddr4_dqs_t ),
  305. .c0_ddr4_ui_clk (o_ddr4_clk ),
  306. .c0_ddr4_ui_clk_sync_rst (o_ddr4_rst ),
  307. .dbg_clk (dbg_clk ),
  308. .c0_ddr4_app_addr (app_addr ),
  309. .c0_ddr4_app_cmd (app_cmd ),
  310. .c0_ddr4_app_en (app_en ),
  311. .c0_ddr4_app_hi_pri (1'b0 ),
  312. .c0_ddr4_app_wdf_data (app_wdf_data ),
  313. .c0_ddr4_app_wdf_end (app_wdf_end ),
  314. .c0_ddr4_app_wdf_mask (app_wdf_mask ),
  315. .c0_ddr4_app_wdf_wren (app_wdf_wren ),
  316. .c0_ddr4_app_rd_data (app_rd_data ),
  317. .c0_ddr4_app_rd_data_end (app_rd_data_end ),
  318. .c0_ddr4_app_rd_data_valid (app_rd_data_valid ),
  319. .c0_ddr4_app_rdy (app_rdy ),
  320. .c0_ddr4_app_wdf_rdy (app_wdf_rdy ),
  321. // Debug Port
  322. .dbg_bus (dbg_bus )
  323. );
  324. endmodule

时序设计图:

DDR4_control

 DDR4_APP

 

 

 

 

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

闽ICP备14008679号