| ////////////////////////////////////////////////////////////////////////////// |
| // SPDX-FileCopyrightText: 2021 , Dinesh Annayya |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // SPDX-License-Identifier: Apache-2.0 |
| // SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> |
| // |
| /********************************************************************* |
| |
| SDRAM Controller buswidth converter |
| |
| This file is part of the sdram controller project |
| https://github.com/dineshannayya/yifive_r0.git |
| http://www.opencores.org/cores/yifive/ |
| 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 |
| ); |
| |
| |
| parameter APP_AW = 30; // Application Address Width |
| parameter APP_DW = 32; // Application Data Width |
| parameter APP_BW = 4; // Application Byte Width |
| |
| parameter SDR_DW = 16; // SDR Data Width |
| parameter SDR_BW = 2; // 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 |