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