赞
踩
DDR4读写控制模块
- module ddr4_control#(
- parameter MEM_DATA_BITS = 512 ,
- parameter ADDR_BITS = 26 ,
- parameter BUSRT_BITS = 10 ,//突发的位宽长度
- parameter BURST_LEN = 5
- )
- (
- input i_sys_clk ,
- input i_sys_rst ,
-
- input i_wr_data_rdy ,
- output reg [MEM_DATA_BITS-1:0] o_wr_data ,
- output reg o_wr_ddr4_req ,
-
- input i_rd_data_vaild ,
- input [MEM_DATA_BITS-1:0] i_rd_ddr4_data ,
- output reg o_rd_ddr4_req ,
-
- output [BUSRT_BITS-1:0] o_wr_burst_length ,
- output [BUSRT_BITS-1:0] o_rd_burst_length ,
-
- output reg [ADDR_BITS-1:0] o_wr_base_ddr4_addr ,
- output reg [ADDR_BITS-1:0] o_rd_base_ddr4_addr ,
-
- input i_wr_finished ,
- input i_rd_finished
-
- );
-
- localparam IDLE = 3'b000 ;
- localparam WRITE = 3'b001 ;
- localparam READ = 3'b011 ;
- reg [11:0] wr_data_count ;
- reg [11:0] rd_data_count ;
- reg [2:0] current_state ;
- reg [2:0] next_state ;
-
-
- assign o_wr_burst_length = BURST_LEN;
- assign o_rd_burst_length = BURST_LEN;
- always @(posedge i_sys_clk or posedge i_sys_rst) begin
- if(i_sys_rst) begin
- current_state <= IDLE;
- end
- else begin
- current_state <= next_state;
- end
- end
-
- always @(*) begin
- case(current_state)
- IDLE: begin
- next_state = WRITE;
- end
- WRITE: begin
- if(i_wr_finished) begin
- next_state = READ;
- end
- else begin
- next_state = WRITE;
- end
- end
- READ: begin
- if(i_rd_finished) begin
- next_state = IDLE;
- end
- else begin
- next_state = READ;
- end
- end
- default:begin
- next_state = IDLE;
- end
- endcase
- end
-
- always @(posedge i_sys_clk or posedge i_sys_rst) begin
- if(i_sys_rst) begin
- o_wr_ddr4_req <= 1'd0;
- o_rd_ddr4_req <= 1'd0;
- end
- else if( current_state == IDLE || (current_state == READ && i_rd_finished))begin
- o_wr_ddr4_req <= 1'd1;
- o_rd_ddr4_req <= 1'd0;
- end
- else if( current_state == WRITE && i_wr_finished)begin
- o_wr_ddr4_req <= 1'd0;
- o_rd_ddr4_req <= 1'd1;
- end
- else begin
- o_wr_ddr4_req <= o_wr_ddr4_req;
- o_rd_ddr4_req <= o_rd_ddr4_req;
- end
- end
-
- always @(posedge i_sys_clk or posedge i_sys_rst) begin
- if(i_sys_rst) begin
- wr_data_count <= 12'd0;
- end
- else if(current_state == WRITE && wr_data_count == BURST_LEN - 12'd1 || current_state == IDLE ) begin
- wr_data_count <= 12'd0;
- end
- else if(current_state == WRITE && i_wr_data_rdy ) begin
- wr_data_count <= wr_data_count + 12'd1;
- end
- else begin
- wr_data_count <= wr_data_count;
- end
- end
-
- always @(posedge i_sys_clk or posedge i_sys_rst) begin
- if(i_sys_rst) begin
- o_wr_data <= {MEM_DATA_BITS{1'd0}};
- end
- else if(current_state == WRITE && i_wr_data_rdy ) begin
- o_wr_data <= o_wr_data + 'd10;
- end
- else begin
- wr_data_count <= wr_data_count;
- end
- end
-
- always @(posedge i_sys_clk or posedge i_sys_rst) begin
- if(i_sys_rst) begin
- rd_data_count <= 12'd0;
- end
- else if(current_state == READ && rd_data_count == BURST_LEN - 12'd1 || current_state == IDLE ) begin
- rd_data_count <= 12'd0;
- end
- else if(current_state == READ && i_rd_data_vaild ) begin
- rd_data_count <= rd_data_count + 12'd1;
- end
- else begin
- rd_data_count <= rd_data_count;
- end
- end
-
- always @(posedge i_sys_clk or posedge i_sys_rst) begin
- if(i_sys_rst) begin
- o_rd_base_ddr4_addr <= {ADDR_BITS{1'd0}};
- o_wr_base_ddr4_addr <= {ADDR_BITS{1'd0}};
- end
- else if(i_rd_finished ) begin
- o_rd_base_ddr4_addr <= o_rd_base_ddr4_addr + BURST_LEN;
- o_wr_base_ddr4_addr <= o_wr_base_ddr4_addr + BURST_LEN;
- end
- else begin
- o_rd_base_ddr4_addr <= o_rd_base_ddr4_addr;
- o_wr_base_ddr4_addr <= o_wr_base_ddr4_addr;
- end
- end
-
- endmodule
DDR4 app接口控制
- module ddr4_app
- #(
- parameter ADDR_BITS = 26 ,
- parameter MEM_DATA_BITS = 512 ,
- parameter APP_ADDR_BITS = 29 ,
- parameter BURST_BITS = 10 //突发长度的位宽
- )
- (
- input i_sys_clk ,
- input i_sys_rst ,
-
- output o_wr_data_rdy ,
- input [MEM_DATA_BITS-1:0] i_wr_data ,
- input i_wr_ddr4_req ,
-
- output o_rd_data_vaild ,
- output [MEM_DATA_BITS-1:0] o_rd_ddr4_data ,
- input i_rd_ddr4_req ,
-
- input [BURST_BITS-1:0] i_wr_burst_length ,
- input [BURST_BITS-1:0] i_rd_burst_length ,
-
- input [BURST_BITS-1:0] i_wr_base_ddr4_addr ,
- input [BURST_BITS-1:0] i_rd_base_ddr4_addr ,
-
- output reg o_wr_finished ,
- output reg o_rd_finished ,
-
-
- //DDR phy接口的信号
- output o_c0_init_calib_complete ,
- input i_c0_sys_clk_p ,
- input i_c0_sys_clk_n ,
- output o_c0_ddr4_act_n ,
- output [16:0] o_c0_ddr4_adr ,
- output [1:0] o_c0_ddr4_ba ,
- output [0:0] o_c0_ddr4_bg ,
- output [0:0] o_c0_ddr4_cke ,
- output [0:0] o_c0_ddr4_odt ,
- output [0:0] o_c0_ddr4_cs_n ,
- output [0:0] o_c0_ddr4_ck_t ,
- output [0:0] o_c0_ddr4_ck_c ,
- output o_c0_ddr4_reset_n ,
- inout [7:0] io_c0_ddr4_dm_dbi_n ,
- inout [63:0] io_c0_ddr4_dq ,
- inout [7:0] io_c0_ddr4_dqs_t ,
- inout [7:0] io_c0_ddr4_dqs_c ,
-
- output o_ddr4_clk ,
- output o_ddr4_rst
-
- );
-
- localparam IDLE = 3'b000 ;
- localparam WRITE = 3'b001 ;
- localparam READ = 3'b011 ;
- localparam READ_WAIT = 3'b010 ;
-
-
-
- wire [APP_ADDR_BITS-1:0] app_addr ;
- wire [2:0] app_cmd ;
- wire app_en ;
- wire [MEM_DATA_BITS-1:0] app_wdf_data ;
- wire app_wdf_end ;
- wire [MEM_DATA_BITS/8-1:0] app_wdf_mask ;
- wire app_wdf_wren ;
- wire [MEM_DATA_BITS-1:0] app_rd_data ;
- wire app_rd_data_end ;
- wire app_rd_data_valid ;
- wire app_rdy ;
- wire app_wdf_rdy ;
-
- wire c0_ddr4_ui_clk ;
- wire c0_ddr4_ui_clk_sync_rst ;
-
- wire [BURST_BITS + 12 -1 : 0 ] wr_burst_addr ;// burst_addr = base_addr + offset_addr
- wire [BURST_BITS + 12 -1 : 0 ] rd_burst_addr ;
-
- reg [2:0] app_cmd_r ;
- reg app_en_r ;
- // reg [MEM_DATA_BITS/8-1:0] app_wdf_mask_r ;
- reg app_wdf_wren_r ;
- reg [MEM_DATA_BITS-1:0] app_rd_data_r ;
- reg app_rd_data_end_r ;
- reg [MEM_DATA_BITS-1:0] app_wdf_data_r ;
- // reg app_rd_data_valid_r ;
- // reg app_rdy_r ;
- // reg app_wdf_rdy_r ;
-
-
- reg [2:0] current_state ;
- reg [2:0] next_state ;
-
- reg [11:0] wr_data_count ;
- reg [11:0] wr_addr_count ;
-
- reg [11:0] rd_data_count ;
- reg [11:0] rd_addr_count ;
- //******************************************assign*****************************************************
- // assign o_ddr4_clk = c0_ddr4_ui_clk;
- // assign o_ddr4_rst = c0_ddr4_ui_clk_sync_rst;
- assign wr_burst_addr = (wr_addr_count + i_wr_base_ddr4_addr) << 3;
- assign rd_burst_addr = (rd_addr_count + i_rd_base_ddr4_addr) << 3;
- assign app_cmd = app_cmd_r;
- assign app_en = app_en_r;
- assign o_wr_data_rdy = app_wdf_rdy && (current_state == WRITE)&&app_en;
- assign o_rd_data_vaild = app_rd_data_valid;
- assign o_rd_ddr4_data = app_rd_data;
- // assign app_wdf_wren = app_en & app_wdf_rdy;
- assign app_wdf_wren = app_wdf_wren_r;
- assign app_addr = (current_state == WRITE) ? wr_burst_addr:
- (current_state == READ) ? rd_burst_addr: {APP_ADDR_BITS{1'd0}};
- assign app_wdf_data = i_wr_data;
- assign app_wdf_mask = {MEM_DATA_BITS/8{1'b0}};
- assign app_wdf_end = app_wdf_wren;
- //*****************************************************************************************************
-
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- app_wdf_data_r <= {MEM_DATA_BITS{1'd0}};
- end
- else begin
- app_wdf_data_r <= i_wr_data;
- end
- end
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- current_state <= IDLE;
- end
- else begin
- current_state <= next_state;
- end
- end
-
- always @(*)begin
- if (o_c0_init_calib_complete)
- case(current_state)
- IDLE: begin
- if (i_wr_ddr4_req) begin
- next_state = WRITE;
- end
- else if (i_rd_ddr4_req) begin
- next_state = READ;
- end
- else begin
- next_state = IDLE;
- end
- end
- WRITE: begin
- if(o_wr_finished) begin
- next_state = IDLE;
- end
- else begin
- next_state = WRITE;
- end
- end
- READ: begin
- if(rd_addr_count == i_rd_burst_length - 'd1 ) begin
- next_state = READ_WAIT;
- end
- else if(o_rd_finished) begin
- next_state = IDLE;
- end
- else begin
- next_state = READ;
- end
- end
- READ_WAIT: begin
- if (o_rd_finished) begin
- next_state = IDLE;
- end
- else begin
- next_state = READ_WAIT;
- end
- end
- default:begin
- next_state = IDLE;
- end
- endcase
- else begin
- next_state = IDLE;
- end
- end
-
-
-
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- app_cmd_r <= 3'd0;
- end
- else if (current_state == WRITE )begin
- app_cmd_r <= 3'd0;
- end
- else if (current_state == READ )begin
- app_cmd_r <= 3'd1;
- end
- else begin
- app_cmd_r <= app_cmd_r;
- end
- end
-
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- app_wdf_wren_r <= 1'd0;
- end
- // else if ((current_state == WRITE && o_wr_finished) ||(current_state == READ &&o_rd_finished ) ) begin
- else if ((current_state == WRITE && o_wr_finished)) begin
- app_wdf_wren_r <= 1'd0;
- end
- else if ((current_state == WRITE) && app_rdy && app_wdf_rdy )begin
- app_wdf_wren_r <= 1'd1;
- end
- else begin
- app_wdf_wren_r <= app_wdf_wren_r;
- end
- end
-
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- app_en_r <= 1'd0;
- end
- // else if ((current_state == WRITE && o_wr_finished) ||(current_state == READ &&o_rd_finished ) ) begin
- else if ((current_state == WRITE && o_wr_finished) || rd_addr_count == i_rd_burst_length - 1) begin
- app_en_r <= 1'd0;
- end
- else if ((current_state == WRITE || current_state == READ) && app_rdy )begin
- app_en_r <= 1'd1;
- end
- else begin
- app_en_r <= app_en_r;
- end
- end
-
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- wr_data_count <= 12'd0;
- end
- else if (current_state == WRITE && wr_data_count == i_wr_burst_length - 12'd1 )begin
- wr_data_count <= 12'd0;
- end
- else if (current_state == WRITE && app_rdy && app_wdf_rdy && app_en_r) begin
- wr_data_count <= wr_data_count + 12'd1;
- end
- else begin
- wr_data_count <= wr_data_count;
- end
- end
-
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- wr_addr_count <= 12'd0;
- end
- else if (current_state == WRITE && wr_data_count == i_wr_burst_length - 12'd1 )begin
- wr_addr_count <= 12'd0;
- end
- else if (current_state == WRITE && app_rdy && app_wdf_rdy && app_en_r) begin
- wr_addr_count <= wr_addr_count + 12'd1;
- end
- else begin
- wr_addr_count <= wr_addr_count;
- end
- end
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- o_wr_finished <= 1'd0;
- end
- else if (current_state == WRITE && (wr_data_count == i_wr_burst_length - 12'd2 ))begin
- o_wr_finished <= 1'd1;
- end
- else begin
- o_wr_finished <= 1'd0;
- end
- end
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- rd_addr_count <= 12'd0;
- end
- else if (current_state == READ &&rd_addr_count == i_rd_burst_length - 'd1 )begin
- rd_addr_count <= 12'd0;
- end
- else if (current_state == READ && app_rdy && app_en_r) begin
- rd_addr_count <= rd_addr_count + 12'd1;
- end
- else begin
- rd_addr_count <= rd_addr_count;
- end
- end
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- rd_data_count <= 12'd0;
- end
- else if ((rd_data_count == i_rd_burst_length -1'd1) && app_rd_data_valid) begin
- rd_data_count <= 12'd0;
- end
- else if ((current_state == READ || current_state == READ_WAIT) && app_rd_data_valid )begin
- rd_data_count <= rd_data_count + 12'd1;
- end
- else begin
- rd_data_count <= rd_data_count;
- end
- end
-
-
-
- always@(posedge o_ddr4_clk or posedge o_ddr4_rst) begin
- if(o_ddr4_rst) begin
- o_rd_finished <= 1'd0;
- end
- else if (( current_state == READ || current_state == READ_WAIT) && (rd_data_count == i_rd_burst_length - 12'd1 ) && app_rd_data_valid)begin
- o_rd_finished <= 1'd1;
- end
- else begin
- o_rd_finished <= 1'd0;
- end
- end
- ddr4_0 u_ddr4
- (
- .sys_rst (i_sys_rst ),
- .c0_sys_clk_p (i_c0_sys_clk_p ),
- .c0_sys_clk_n (i_c0_sys_clk_n ),
- .c0_init_calib_complete (o_c0_init_calib_complete ),
- .c0_ddr4_act_n (o_c0_ddr4_act_n ),
- .c0_ddr4_adr (o_c0_ddr4_adr ),
- .c0_ddr4_ba (o_c0_ddr4_ba ),
- .c0_ddr4_bg (o_c0_ddr4_bg ),
- .c0_ddr4_cke (o_c0_ddr4_cke ),
- .c0_ddr4_odt (o_c0_ddr4_odt ),
- .c0_ddr4_cs_n (o_c0_ddr4_cs_n ),
- .c0_ddr4_ck_t (o_c0_ddr4_ck_t ),
- .c0_ddr4_ck_c (o_c0_ddr4_ck_c ),
- .c0_ddr4_reset_n (o_c0_ddr4_reset_n ),
-
- .c0_ddr4_dm_dbi_n (io_c0_ddr4_dm_dbi_n),
- .c0_ddr4_dq (io_c0_ddr4_dq ),
- .c0_ddr4_dqs_c (io_c0_ddr4_dqs_c ),
- .c0_ddr4_dqs_t (io_c0_ddr4_dqs_t ),
- .c0_ddr4_ui_clk (o_ddr4_clk ),
- .c0_ddr4_ui_clk_sync_rst (o_ddr4_rst ),
- .dbg_clk (dbg_clk ),
- .c0_ddr4_app_addr (app_addr ),
- .c0_ddr4_app_cmd (app_cmd ),
- .c0_ddr4_app_en (app_en ),
- .c0_ddr4_app_hi_pri (1'b0 ),
- .c0_ddr4_app_wdf_data (app_wdf_data ),
- .c0_ddr4_app_wdf_end (app_wdf_end ),
- .c0_ddr4_app_wdf_mask (app_wdf_mask ),
- .c0_ddr4_app_wdf_wren (app_wdf_wren ),
- .c0_ddr4_app_rd_data (app_rd_data ),
- .c0_ddr4_app_rd_data_end (app_rd_data_end ),
- .c0_ddr4_app_rd_data_valid (app_rd_data_valid ),
- .c0_ddr4_app_rdy (app_rdy ),
- .c0_ddr4_app_wdf_rdy (app_wdf_rdy ),
-
- // Debug Port
- .dbg_bus (dbg_bus )
-
- );
- endmodule
时序设计图:
DDR4_control
DDR4_APP
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。