//-------------------------------------------------------------------------------------------------------- // Module : ddr_sdram_ctrl // Type : synthesizable, IP's top // Standard: Verilog 2001 (IEEE1364-2001) // Function: DDR1 SDRAM controller // with AXI4 interface //-------------------------------------------------------------------------------------------------------- module ddr_sdram_ctrl #( parameter READ_BUFFER = 1, parameter BA_BITS = 2, parameter ROW_BITS = 13, parameter COL_BITS = 11, parameter DQ_LEVEL = 1, // DDR DQ_BITS = 4<10) begin assign ddr_a_col = {col_addr[COL_BITS-2:9], burst_last, col_addr[8:0], 1'b0}; end else begin assign ddr_a_col = {burst_last, col_addr[8:0], 1'b0}; end endgenerate wire read_accessible, read_respdone; reg output_enable=1'b0, output_enable_d1=1'b0, output_enable_d2=1'b0; reg o_v_a = 1'b0; reg [(4<=tW2I) stat <= IDLE; end RPRE: begin ddr_ras_n <= 1'b1; cnt <= 8'd0; stat <= READ; end READ: begin ddr_cas_n <= 1'b0; ddr_a <= ddr_a_col; col_addr <= col_addr + {{(COL_BITS-2){1'b0}}, 1'b1}; if(burst_last) begin cnt <= 8'd0; stat <= RRESP; end else begin cnt <= cnt + 8'd1; end end RRESP: begin ddr_cas_n <= 1'b1; cnt <= cnt + 8'd1; if(read_respdone) stat <= RWAIT; end RWAIT: begin cnt <= cnt + 8'd1; if(cnt>=tR2I) stat <= IDLE; end default: stat <= IDLE; endcase end // ------------------------------------------------------------------------------------- // output enable generate // ------------------------------------------------------------------------------------- always @ (posedge clk or negedge rstn) if(~rstn) begin output_enable <= 1'b0; output_enable_d1 <= 1'b0; output_enable_d2 <= 1'b0; end else begin output_enable <= stat==WRITE || output_enable_d1 || output_enable_d2; output_enable_d1 <= stat==WRITE; output_enable_d2 <= output_enable_d1; end // ------------------------------------------------------------------------------------- // output data latches --- stage A // ------------------------------------------------------------------------------------- always @ (posedge clk or negedge rstn) if(~rstn) begin o_v_a <= 1'b0; {o_dh_a, o_dl_a} <= 0; end else begin o_v_a <= (stat==WRITE && wvalid); {o_dh_a, o_dl_a} <= wdata; end // ------------------------------------------------------------------------------------- // output data latches --- stage B // ------------------------------------------------------------------------------------- always @ (posedge clk or negedge rstn) if(~rstn) begin o_v_b <= 1'b0; o_dh_b <= 0; end else begin o_v_b <= o_v_a; o_dh_b <= o_dh_a; end // ------------------------------------------------------------------------------------- // dq and dqs generate for output (write) // ------------------------------------------------------------------------------------- always @ (posedge clk2) if (~clk) begin o_dqs_c <= 1'b0; if (o_v_a) o_d_c <= o_dl_a; else o_d_c <= 0; end else begin o_dqs_c <= o_v_b; if (o_v_b) o_d_c <= o_dh_b; else o_d_c <= 0; end // ------------------------------------------------------------------------------------- // dq delay for output (write) // ------------------------------------------------------------------------------------- always @ (posedge drv_clk) o_d_d <= o_d_c; // ------------------------------------------------------------------------------------- // dq sampling for input (read) // ------------------------------------------------------------------------------------- always @ (posedge clk2) begin i_dqs_c <= ddr_dqs; i_d_c <= ddr_dq; end always @ (posedge clk2) if(i_dqs_c) i_d_d <= {ddr_dq, i_d_c}; always @ (posedge clk or negedge rstn) if(~rstn) begin {i_v_a, i_v_b, i_v_c, i_v_d} <= 0; {i_l_a, i_l_b, i_l_c, i_l_d} <= 0; end else begin i_v_a <= stat==READ ? 1'b1 : 1'b0; i_l_a <= burst_last; i_v_b <= i_v_a; i_l_b <= i_l_a & i_v_a; i_v_c <= i_v_b; i_l_c <= i_l_b; i_v_d <= i_v_c; i_l_d <= i_l_c; end always @ (posedge clk or negedge rstn) if(~rstn) begin i_v_e <= 1'b0; i_l_e <= 1'b0; i_d_e <= 0; end else begin i_v_e <= i_v_d; i_l_e <= i_l_d; i_d_e <= i_d_d; end // ------------------------------------------------------------------------------------- // data buffer for read // ------------------------------------------------------------------------------------- generate if(READ_BUFFER) begin localparam AWIDTH = 10; localparam DWIDTH = 1 + (8<