/********************************************************************* SDRAM Controller buswidth converter This file is part of the sdram controller project http://www.opencores.org/cores/sdr_ctrl/ Description: SDRAM Controller Buswidth converter This module does write/read data transalation between application data to SDRAM bus width To Do: nothing Author(s): - Dinesh Annayya, dinesha@opencores.org Version : 0.0 - 8th Jan 2012 - Initial structure 0.2 - 2nd Feb 2012 Improved the command pipe structure to accept up-to 4 command of different bank. 0.3 - 6th Feb 2012 Bug fix on read valid generation Copyright (C) 2000 Authors and OPENCORES.ORG This source file may be used and distributed without restriction provided that this copyright statement is not removed from the file and that any derivative work contains the original copyright notice and the associated disclaimer. This source file is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this source; if not, download it from http://www.opencores.org/lgpl.shtml *******************************************************************/ //`include "sdrc_define.v" module sdrc_bs_convert ( clk , reset_n , sdr_width , /* Control Signal from xfr ctrl */ x2a_rdstart , x2a_wrstart , x2a_rdlast , x2a_wrlast , x2a_rddt , x2a_rdok , a2x_wrdt , a2x_wren_n , x2a_wrnext , /* Control Signal from/to to application i/f */ app_wr_data , app_wr_en_n , app_wr_next , app_last_wr , app_rd_data , app_rd_valid , app_last_rd ); `define SDR_REQ_ID_W 4 `define SDR_RFSH_TIMER_W 12 `define SDR_RFSH_ROW_CNT_W 3 // B2X Command `define OP_PRE 2'b00 `define OP_ACT 2'b01 `define OP_RD 2'b10 `define OP_WR 2'b11 // SDRAM Commands (CS_N, RAS_N, CAS_N, WE_N) `define SDR_DESEL 4'b1111 `define SDR_NOOP 4'b0111 `define SDR_ACTIVATE 4'b0011 `define SDR_READ 4'b0101 `define SDR_WRITE 4'b0100 `define SDR_BT 4'b0110 `define SDR_PRECHARGE 4'b0010 `define SDR_REFRESH 4'b0001 `define SDR_MODE 4'b0000 `define ASIC 1'b1 `define FPGA 1'b0 `define TARGET_DESIGN `ASIC // 12 bit subtractor is not feasibile for FPGA, so changed to 6 bits `define REQ_BW (`TARGET_DESIGN == `FPGA) ? 6 : 12 // Request Width parameter APP_AW = 30; // Application Address Width parameter APP_DW = 64; // Application Data Width parameter APP_BW = 8; // Application Byte Width parameter SDR_DW = 64; // SDR Data Width parameter SDR_BW = 8; // SDR Byte Width input clk ; input reset_n ; input [1:0] sdr_width ; // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit /* Control Signal from xfr ctrl Read Transaction*/ input x2a_rdstart ; // read start indication input x2a_rdlast ; // read last burst access input [SDR_DW-1:0] x2a_rddt ; input x2a_rdok ; /* Control Signal from xfr ctrl Write Transaction*/ input x2a_wrstart ; // writ start indication input x2a_wrlast ; // write last transfer input x2a_wrnext ; output [SDR_DW-1:0] a2x_wrdt ; output [SDR_BW-1:0] a2x_wren_n ; // Application Write Transaction input [APP_DW-1:0] app_wr_data ; input [APP_BW-1:0] app_wr_en_n ; output app_wr_next ; output app_last_wr ; // Indicate last Write Transfer for a given burst size // Application Read Transaction output [APP_DW-1:0] app_rd_data ; output app_rd_valid ; output app_last_rd ; // Indicate last Read Transfer for a given burst size //---------------------------------------------- // Local Decleration // ---------------------------------------- reg [APP_DW-1:0] app_rd_data ; reg app_rd_valid ; reg [SDR_DW-1:0] a2x_wrdt ; reg [SDR_BW-1:0] a2x_wren_n ; reg app_wr_next ; reg [23:0] saved_rd_data ; reg [1:0] rd_xfr_count ; reg [1:0] wr_xfr_count ; assign app_last_wr = x2a_wrlast; assign app_last_rd = x2a_rdlast; always @(*) begin if(sdr_width == 2'b00) // 32 Bit SDR Mode begin a2x_wrdt = app_wr_data; a2x_wren_n = app_wr_en_n; app_wr_next = x2a_wrnext; app_rd_data = x2a_rddt; app_rd_valid = x2a_rdok; end else if(sdr_width == 2'b01) // 16 Bit SDR Mode begin // Changed the address and length to match the 16 bit SDR Mode app_wr_next = (x2a_wrnext & wr_xfr_count[0]); app_rd_valid = (x2a_rdok & rd_xfr_count[0]); if(wr_xfr_count[0] == 1'b1) begin a2x_wren_n = app_wr_en_n[3:2]; a2x_wrdt = app_wr_data[31:16]; end else begin a2x_wren_n = app_wr_en_n[1:0]; a2x_wrdt = app_wr_data[15:0]; end app_rd_data = {x2a_rddt,saved_rd_data[15:0]}; end else // 8 Bit SDR Mode begin // Changed the address and length to match the 16 bit SDR Mode app_wr_next = (x2a_wrnext & (wr_xfr_count[1:0]== 2'b11)); app_rd_valid = (x2a_rdok & (rd_xfr_count[1:0]== 2'b11)); if(wr_xfr_count[1:0] == 2'b11) begin a2x_wren_n = app_wr_en_n[3]; a2x_wrdt = app_wr_data[31:24]; end else if(wr_xfr_count[1:0] == 2'b10) begin a2x_wren_n = app_wr_en_n[2]; a2x_wrdt = app_wr_data[23:16]; end else if(wr_xfr_count[1:0] == 2'b01) begin a2x_wren_n = app_wr_en_n[1]; a2x_wrdt = app_wr_data[15:8]; end else begin a2x_wren_n = app_wr_en_n[0]; a2x_wrdt = app_wr_data[7:0]; end app_rd_data = {x2a_rddt,saved_rd_data[23:0]}; end end always @(posedge clk) begin if(!reset_n) begin rd_xfr_count <= 8'b0; wr_xfr_count <= 8'b0; saved_rd_data <= 24'h0; end else begin // During Write Phase if(x2a_wrlast) begin wr_xfr_count <= 0; end else if(x2a_wrnext) begin wr_xfr_count <= wr_xfr_count + 1'b1; end // During Read Phase if(x2a_rdlast) begin rd_xfr_count <= 0; end else if(x2a_rdok) begin rd_xfr_count <= rd_xfr_count + 1'b1; end // Save Previous Data if(x2a_rdok) begin if(sdr_width == 2'b01) // 16 Bit SDR Mode saved_rd_data[15:0] <= x2a_rddt; else begin// 8 bit SDR Mode - if(rd_xfr_count[1:0] == 2'b00) saved_rd_data[7:0] <= x2a_rddt[7:0]; else if(rd_xfr_count[1:0] == 2'b01) saved_rd_data[15:8] <= x2a_rddt[7:0]; else if(rd_xfr_count[1:0] == 2'b10) saved_rd_data[23:16] <= x2a_rddt[7:0]; end end end end endmodule // sdr_bs_convert