add peripherals
[shakti-peripherals.git] / src / peripherals / sdram / controller / sdrc_bs_convert.v
1 /*********************************************************************
2
3 SDRAM Controller buswidth converter
4
5 This file is part of the sdram controller project
6 http://www.opencores.org/cores/sdr_ctrl/
7
8 Description: SDRAM Controller Buswidth converter
9
10 This module does write/read data transalation between
11 application data to SDRAM bus width
12
13 To Do:
14 nothing
15
16 Author(s):
17 - Dinesh Annayya, dinesha@opencores.org
18 Version : 0.0 - 8th Jan 2012 - Initial structure
19 0.2 - 2nd Feb 2012
20 Improved the command pipe structure to accept up-to 4 command of different bank.
21 0.3 - 6th Feb 2012
22 Bug fix on read valid generation
23
24
25
26 Copyright (C) 2000 Authors and OPENCORES.ORG
27
28 This source file may be used and distributed without
29 restriction provided that this copyright statement is not
30 removed from the file and that any derivative work contains
31 the original copyright notice and the associated disclaimer.
32
33 This source file is free software; you can redistribute it
34 and/or modify it under the terms of the GNU Lesser General
35 Public License as published by the Free Software Foundation;
36 either version 2.1 of the License, or (at your option) any
37 later version.
38
39 This source is distributed in the hope that it will be
40 useful, but WITHOUT ANY WARRANTY; without even the implied
41 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
42 PURPOSE. See the GNU Lesser General Public License for more
43 details.
44
45 You should have received a copy of the GNU Lesser General
46 Public License along with this source; if not, download it
47 from http://www.opencores.org/lgpl.shtml
48
49 *******************************************************************/
50
51 //`include "sdrc_define.v"
52 module sdrc_bs_convert (
53 clk ,
54 reset_n ,
55 sdr_width ,
56
57 /* Control Signal from xfr ctrl */
58 x2a_rdstart ,
59 x2a_wrstart ,
60 x2a_rdlast ,
61 x2a_wrlast ,
62 x2a_rddt ,
63 x2a_rdok ,
64 a2x_wrdt ,
65 a2x_wren_n ,
66 x2a_wrnext ,
67
68 /* Control Signal from/to to application i/f */
69 app_wr_data ,
70 app_wr_en_n ,
71 app_wr_next ,
72 app_last_wr ,
73 app_rd_data ,
74 app_rd_valid ,
75 app_last_rd
76 );
77
78
79 `define SDR_REQ_ID_W 4
80
81 `define SDR_RFSH_TIMER_W 12
82 `define SDR_RFSH_ROW_CNT_W 3
83
84 // B2X Command
85
86 `define OP_PRE 2'b00
87 `define OP_ACT 2'b01
88 `define OP_RD 2'b10
89 `define OP_WR 2'b11
90
91 // SDRAM Commands (CS_N, RAS_N, CAS_N, WE_N)
92
93 `define SDR_DESEL 4'b1111
94 `define SDR_NOOP 4'b0111
95 `define SDR_ACTIVATE 4'b0011
96 `define SDR_READ 4'b0101
97 `define SDR_WRITE 4'b0100
98 `define SDR_BT 4'b0110
99 `define SDR_PRECHARGE 4'b0010
100 `define SDR_REFRESH 4'b0001
101 `define SDR_MODE 4'b0000
102
103 `define ASIC 1'b1
104 `define FPGA 1'b0
105 `define TARGET_DESIGN `ASIC
106 // 12 bit subtractor is not feasibile for FPGA, so changed to 6 bits
107 `define REQ_BW (`TARGET_DESIGN == `FPGA) ? 6 : 12 // Request Width
108
109 parameter APP_AW = 30; // Application Address Width
110 parameter APP_DW = 64; // Application Data Width
111 parameter APP_BW = 8; // Application Byte Width
112
113 parameter SDR_DW = 64; // SDR Data Width
114 parameter SDR_BW = 8; // SDR Byte Width
115
116 input clk ;
117 input reset_n ;
118 input [1:0] sdr_width ; // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
119
120 /* Control Signal from xfr ctrl Read Transaction*/
121 input x2a_rdstart ; // read start indication
122 input x2a_rdlast ; // read last burst access
123 input [SDR_DW-1:0] x2a_rddt ;
124 input x2a_rdok ;
125
126 /* Control Signal from xfr ctrl Write Transaction*/
127 input x2a_wrstart ; // writ start indication
128 input x2a_wrlast ; // write last transfer
129 input x2a_wrnext ;
130 output [SDR_DW-1:0] a2x_wrdt ;
131 output [SDR_BW-1:0] a2x_wren_n ;
132
133 // Application Write Transaction
134 input [APP_DW-1:0] app_wr_data ;
135 input [APP_BW-1:0] app_wr_en_n ;
136 output app_wr_next ;
137 output app_last_wr ; // Indicate last Write Transfer for a given burst size
138
139 // Application Read Transaction
140 output [APP_DW-1:0] app_rd_data ;
141 output app_rd_valid ;
142 output app_last_rd ; // Indicate last Read Transfer for a given burst size
143
144 //----------------------------------------------
145 // Local Decleration
146 // ----------------------------------------
147
148 reg [APP_DW-1:0] app_rd_data ;
149 reg app_rd_valid ;
150 reg [SDR_DW-1:0] a2x_wrdt ;
151 reg [SDR_BW-1:0] a2x_wren_n ;
152 reg app_wr_next ;
153
154 reg [23:0] saved_rd_data ;
155 reg [1:0] rd_xfr_count ;
156 reg [1:0] wr_xfr_count ;
157
158
159 assign app_last_wr = x2a_wrlast;
160 assign app_last_rd = x2a_rdlast;
161
162 always @(*) begin
163 if(sdr_width == 2'b00) // 32 Bit SDR Mode
164 begin
165 a2x_wrdt = app_wr_data;
166 a2x_wren_n = app_wr_en_n;
167 app_wr_next = x2a_wrnext;
168 app_rd_data = x2a_rddt;
169 app_rd_valid = x2a_rdok;
170 end
171 else if(sdr_width == 2'b01) // 16 Bit SDR Mode
172 begin
173 // Changed the address and length to match the 16 bit SDR Mode
174 app_wr_next = (x2a_wrnext & wr_xfr_count[0]);
175 app_rd_valid = (x2a_rdok & rd_xfr_count[0]);
176 if(wr_xfr_count[0] == 1'b1)
177 begin
178 a2x_wren_n = app_wr_en_n[3:2];
179 a2x_wrdt = app_wr_data[31:16];
180 end
181 else
182 begin
183 a2x_wren_n = app_wr_en_n[1:0];
184 a2x_wrdt = app_wr_data[15:0];
185 end
186
187 app_rd_data = {x2a_rddt,saved_rd_data[15:0]};
188 end else // 8 Bit SDR Mode
189 begin
190 // Changed the address and length to match the 16 bit SDR Mode
191 app_wr_next = (x2a_wrnext & (wr_xfr_count[1:0]== 2'b11));
192 app_rd_valid = (x2a_rdok & (rd_xfr_count[1:0]== 2'b11));
193 if(wr_xfr_count[1:0] == 2'b11)
194 begin
195 a2x_wren_n = app_wr_en_n[3];
196 a2x_wrdt = app_wr_data[31:24];
197 end
198 else if(wr_xfr_count[1:0] == 2'b10)
199 begin
200 a2x_wren_n = app_wr_en_n[2];
201 a2x_wrdt = app_wr_data[23:16];
202 end
203 else if(wr_xfr_count[1:0] == 2'b01)
204 begin
205 a2x_wren_n = app_wr_en_n[1];
206 a2x_wrdt = app_wr_data[15:8];
207 end
208 else begin
209 a2x_wren_n = app_wr_en_n[0];
210 a2x_wrdt = app_wr_data[7:0];
211 end
212
213 app_rd_data = {x2a_rddt,saved_rd_data[23:0]};
214 end
215 end
216
217
218
219 always @(posedge clk)
220 begin
221 if(!reset_n)
222 begin
223 rd_xfr_count <= 8'b0;
224 wr_xfr_count <= 8'b0;
225 saved_rd_data <= 24'h0;
226 end
227 else begin
228
229 // During Write Phase
230 if(x2a_wrlast) begin
231 wr_xfr_count <= 0;
232 end
233 else if(x2a_wrnext) begin
234 wr_xfr_count <= wr_xfr_count + 1'b1;
235 end
236
237 // During Read Phase
238 if(x2a_rdlast) begin
239 rd_xfr_count <= 0;
240 end
241 else if(x2a_rdok) begin
242 rd_xfr_count <= rd_xfr_count + 1'b1;
243 end
244
245 // Save Previous Data
246 if(x2a_rdok) begin
247 if(sdr_width == 2'b01) // 16 Bit SDR Mode
248 saved_rd_data[15:0] <= x2a_rddt;
249 else begin// 8 bit SDR Mode -
250 if(rd_xfr_count[1:0] == 2'b00) saved_rd_data[7:0] <= x2a_rddt[7:0];
251 else if(rd_xfr_count[1:0] == 2'b01) saved_rd_data[15:8] <= x2a_rddt[7:0];
252 else if(rd_xfr_count[1:0] == 2'b10) saved_rd_data[23:16] <= x2a_rddt[7:0];
253 end
254 end
255 end
256 end
257
258 endmodule // sdr_bs_convert