URL
https://opencores.org/ocsvn/test_project/test_project/trunk
Subversion Repositories test_project
[/] [test_project/] [trunk/] [rtl/] [verilog/] [components/] [wb_sdram_ctrl/] [wb_sdram_ctrl.v] - Rev 87
Go to most recent revision | Compare with Previous | Blame | View Log
`include "wb_sdram_ctrl_defines.v" module `MODULE_NAME ( // wishbone i/f input [31:0] wb_dat_i, output [31:0] wb_dat_o, input [3:0] wb_sel_i, input [`WB_ADR_HI:2] wb_adr_i, input wb_we_i, input [2:0] wb_cti_i, input wb_stb_i, input wb_cyc_i, output wb_ack_o, // SDRAM IO output sdr_cke_o, output reg sdr_cs_n_o, output reg sdr_ras_n_o, output reg sdr_cas_n_o, output reg sdr_we_n_o, output reg [12:0] sdr_a_o, output reg [1:0] sdr_ba_o, inout [`SDRAM_DATA_WIDTH-1:0] sdr_dq_io, output reg [`SDRAM_DATA_WIDTH/8-1:0] sdr_dqm_o, // system input sdram_clk, input wb_clk, input wb_rst ); reg ref_req; wire ref_ack; /* verilator lint_off UNOPTFLAT */ wire rd_ack, rd_ack_o, wr_ack, wr_ack_o, cmd_ack; /* verilator lint_on UNOPTFLAT */ reg [`BA_SIZE-1:0] ba; reg [`ROW_SIZE-1:0] row; // terminate current cycle if !stb&!cyc, empty fifo // restart if adr_fail (non consecutive adr inc), empty fifo wire terminate, adr_fail, clear; wire end_of_burst; wire burst_counter_set; reg [`COL_SIZE-1:0] burst_counter; `ifdef SDRAM16 wire [`BURST_SIZE:0] burst_counter_next; reg [`BURST_SIZE:0] burst_counter_init; `endif wire fifo_we; wire [1:0] sdr_ba; wire [12:0] sdr_a; reg sdr_dq_oe_reg; wire [`SDRAM_DATA_WIDTH-1:0] sdr_dq_i, sdr_dq_o; wire [`SDRAM_DATA_WIDTH/8-1:0] sdr_dqm; // counter 100us delay and refresh interval reg [12:0] counter; wire counter_zf; // counter zero flag assign counter_zf = (counter==13'd0); always @ (posedge wb_clk or posedge wb_rst) if (wb_rst) counter <= 13'd`DLY_INIT; else if (counter_zf) counter <= 13'd`AREF_INIT; else counter <= counter - 13'd1; always @ (posedge wb_clk or posedge wb_rst) if (wb_rst) ref_req <= 1'b0; else if (counter_zf) ref_req <= 1'b1; else if (ref_ack) ref_req <= 1'b0; `ifdef SDRAM16 assign burst_counter_next = burst_counter[`BURST_SIZE:0] + {{`BURST_SIZE{1'b0}},1'b1}; always @ (posedge sdram_clk or posedge wb_rst) if (wb_rst) begin ba <= `BA_SIZE'd0; row <= `ROW_SIZE'd0; burst_counter_init <= `BURST_SIZE'd0; burst_counter <= `COL_SIZE'd0; end else if (burst_counter_set) begin ba <= `BA; row <= `ROW; // A fix of the fix. // We previously adjusted the burst_counter, which is very important - it determines the address // we generate and use for the SDRAM column addressing. // So instead, when we receive an (arguably incorrect) access request, with the cycle indicator // showing "burst end" (wb_cti_i=3'b111), we change burst_counter_init so it should show that // the transfer will end after a single 32-bit word transaction has taken place (2 16-bit word // transactions) burst_counter_init <= (wb_cti_i == 3'b111) ? {wb_adr_i[`BURST_SIZE-1+2:2],1'b0} + 2 : {wb_adr_i[`BURST_SIZE-1+2:2],1'b0}; burst_counter <= {wb_adr_i[`COL_SIZE+2:2],1'b0}; end else if (rd_ack | wr_ack) begin burst_counter[`BURST_SIZE:0] <= burst_counter_next; end assign end_of_burst = (wb_cti_i==3'b000) ? (burst_counter[0]==1'b1) : (burst_counter_next == burst_counter_init); `endif wb_sdram_ctrl_fsm fsm0 ( .dly_100us(counter_zf), .ref_req(ref_req), .ref_ack(ref_ack), .accept_cmd(burst_counter_set), .rd_ack(rd_ack), .wr_ack(wr_ack), .clear(clear), .wb_stb(wb_stb_i), .wb_cyc(wb_cyc_i), .wb_we(wb_we_i), .wb_ack(wb_ack_o & ((wb_cti_i==3'b000) | (wb_cti_i==3'b111))), .end_of_burst(end_of_burst), .wb_adr_i({`BA,`ROW,burst_counter}), .a({sdr_ba,sdr_a}), .cmd(`CMD), .cs_n(sdr_cs_n), .sdram_clk(sdram_clk), .wb_rst(wb_rst) ); `ifdef SDRAM16 assign sdr_dqm = ((burst_counter[0]==1'b0) & wr_ack) ? ~wb_sel_i[3:2] : ((burst_counter[0]==1'b1) & wr_ack) ? ~wb_sel_i[1:0] : 2'b00; `endif // output registers always @ (posedge sdram_clk or posedge wb_rst) if (wb_rst) begin sdr_cs_n_o <= 1'b1; {sdr_ras_n_o, sdr_cas_n_o, sdr_we_n_o} <= `CMD_NOP; {sdr_ba_o,sdr_a_o} <= 15'd0; sdr_dqm_o <= {`SDRAM_DATA_WIDTH/8{1'b0}}; end else begin sdr_cs_n_o <= #1 sdr_cs_n; {sdr_ras_n_o, sdr_cas_n_o, sdr_we_n_o} <= #1 `CMD; {sdr_ba_o,sdr_a_o} <= #1 {sdr_ba,sdr_a}; sdr_dqm_o <= #1 sdr_dqm; end assign sdr_cke_o = 1'b1; `ifdef SDRAM16 assign sdr_dq_o = (burst_counter[0]==1'b0) ? wb_dat_i[31:16] : wb_dat_i[15:0]; `endif // Tristate driver for data bus // assign sdr_dq_oe = wr_ack; -- sdr_dq_oe was not declared! changed its only reference --jb reg [`SDRAM_DATA_WIDTH-1:0] sdr_dq_o_reg; always @ (posedge sdram_clk or posedge wb_rst) if (wb_rst) {sdr_dq_oe_reg,sdr_dq_o_reg} <= {1'b0,`SDRAM_DATA_WIDTH'd0}; else {sdr_dq_oe_reg,sdr_dq_o_reg} <= {wr_ack,sdr_dq_o};//{sdr_dq_oe_reg,sdr_dq_o_reg} <= {sdr_dq_oe,sdr_dq_o}; --jb assign #1 sdr_dq_io = sdr_dq_oe_reg ? sdr_dq_o_reg : {`SDRAM_DATA_WIDTH{1'bz}}; assign #1 sdr_dq_i = sdr_dq_io; // delay fifo_fill in accordance to cas latency delay # ( .depth(`CL+1), .width(1) ) delay1 ( .d(rd_ack), .q(fifo_we), .clear(clear | terminate), .clk(sdram_clk), .rst(wb_rst) ); `ifdef SDRAM16 assign wr_ack_o = wr_ack & burst_counter[0]; `endif // wishbone buffer wb_sdram_ctrl_fifo fifo ( .d_i(sdr_dq_i), .we_i(fifo_we), .clear(clear | terminate), .clk_i(sdram_clk), .wb_dat_o(wb_dat_o), .wb_cyc_i(wb_cyc_i), .wb_stb_i(wb_stb_i), .wb_ack_o(rd_ack_o), .wb_clk(wb_clk), .rst(wb_rst) ); assign terminate = ~wb_cyc_i & ~wb_stb_i; assign adr_fail = ~(wb_adr_i[`WB_ADR_HI:4]=={ba,row,burst_counter[`COL_SIZE-1:3]}); assign clear = adr_fail & rd_ack_o; /* verilator lint_off UNOPTFLAT */ assign wb_ack_o = (rd_ack_o & !adr_fail) | wr_ack_o; /* verilator lint_on UNOPTFLAT */ endmodule // wb_sdram_ctrl
Go to most recent revision | Compare with Previous | Blame | View Log