// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: dmu_tsb_tdl.v
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
// This program 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 General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// ========== Copyright Header End ============================================
// Input from TIC Controller to TDL (Write Data)
// Input from TEC Controller to TDL (Write Data)
// Output from TDL to TEC Controller (Read Data)
// synopsys sync_set_reset "rst_l"
//////////////////////////////////////////////////////////////////////
//************************* Parameters *************************
//////////////////////////////////////////////////////////////////////
parameter DEPTH = 32; //32
parameter DCD_TAG_WIDTH = 32; //32
//////////////////////////////////////////////////////////////////////
//************************* Port Declarations *******************
//////////////////////////////////////////////////////////////////////
input [`FIRE_DLC_TSR_TRN_WDTH-1:0] tic2tdl_trtag_in;
input [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] tic2tdl_wr_data_in;
input [`FIRE_DLC_TSR_TRN_WDTH-1:0] tec2tdl_trtag_in;
input [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] tec2tdl_wr_data_in;
output [`FIRE_DLC_TSR_RD_DATA_WDTH-1:0] tdl2tec_rd_data_out;
input [`FIRE_DLC_TSR_TRN_WDTH-1:0] ext_addr;
input tsb_dma_ext_select;
output [`FIRE_DLC_TSR_RD_DATA_WDTH-1:0] tsb_dma_ext_rd_data; // SAME AS tdl2tec_rd_data_out
output [`FIRE_DBG_DATA_BITS] tdl2dbg_dbg_a;
output [`FIRE_DBG_DATA_BITS] tdl2dbg_dbg_b;
input [2:0] dbg2tdl_dbg_sel_a;
input [2:0] dbg2tdl_dbg_sel_b;
//////////////////////////////////////////////////////////////////////
//*********************** Wires and Regs ************************
//////////////////////////////////////////////////////////////////////
wire [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] tic2tdl_wr_data_in;
wire [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] tec2tdl_wr_data_in;
wire [`FIRE_DLC_TSR_RD_DATA_WDTH-1:0] tdl2tec_rd_data_out;
reg [DCD_TAG_WIDTH - 1:0] trtag1_dcd; // decoded trtag1 4 bit to 16 bit
reg [DCD_TAG_WIDTH - 1:0] trtag2_dcd; // decoded trtag2 4 bit to 16 bit
wire [`FIRE_DLC_TSR_TRN_WDTH-1:0] trtag1;
wire [`FIRE_DLC_TSR_TRN_WDTH-1:0] trtag2;
wire [`FIRE_DLC_TSR_RD_DATA_WDTH-1:0] tsb_dma_ext_rd_data;
reg [`FIRE_DLC_TSR_TRN_WDTH-1:0] dma_addr;
reg [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] nxt_wr_data_in [0:DEPTH-1];
wire [DEPTH-1:0] wr_data_ld;
wire [DEPTH-1:0] tic_wr_data_ld;
wire [DEPTH-1:0] tec_wr_data_ld;
reg [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] dma_data[0:DEPTH-1]; // memory with 32 - 48 bit entries
reg [`FIRE_DBG_DATA_BITS] dbg_bus [0:1];
reg [`FIRE_DBG_DATA_BITS] nxt_dbg_bus [0:1];
wire [`FIRE_DBG_DATA_BITS] tdl2dbg_dbg_a; // TDL debug output a
wire [`FIRE_DBG_DATA_BITS] tdl2dbg_dbg_b; // TDL debug output b
wire [2:0] dbg2tdl_dbg_sel_a; // TDL debug select a
wire [2:0] dbg2tdl_dbg_sel_b; // TDL debug select b
//////////////////////////////////////////////////////////////////////
// ******** Zero-in checkers************************************
//////////////////////////////////////////////////////////////////////
// 0in decoder -in trtag1 -out trtag1_dcd
// 0in decoder -in trtag2 -out trtag2_dcd
// 0in bits_on -var tic_wr_data_ld -max 1
// 0in bits_on -var tec_wr_data_ld -max 1
// 0in bits_on -var wr_data_ld -max 2
//////////////////////////////////////////////////////////////////////
// ******** Combinational Logic ************************************
//////////////////////////////////////////////////////////////////////
always @ (dbg2tdl_dbg_sel_a or dbg2tdl_dbg_sel_b)
dbg_sel[0] = dbg2tdl_dbg_sel_a;
dbg_sel[1] = dbg2tdl_dbg_sel_b;
always @ (dbg_sel[0] or dbg_sel[1] or tic2tdl_wr_in or tic2tdl_req_in or tic2tdl_trtag_in
or tec2tdl_wr_in or tec2tdl_req_in or tec2tdl_trtag_in or
tsb_dma_ext_done or tsb_dma_ext_select or ext_addr)
for (i = 0; i < 2; i = i + 1)
case (dbg_sel[i]) // synopsys parallel_case infer_mux
3'b000: nxt_dbg_bus[i] = {1'b0, tic2tdl_wr_in, tic2tdl_req_in, tic2tdl_trtag_in};
3'b001: nxt_dbg_bus[i] = {1'b0, tec2tdl_wr_in, tec2tdl_req_in, tec2tdl_trtag_in};
3'b010: nxt_dbg_bus[i] = {1'b0, tsb_dma_ext_done,tsb_dma_ext_select, ext_addr};
3'b011: nxt_dbg_bus[i] = 8'b0;
3'b100: nxt_dbg_bus[i] = 8'b0;
3'b101: nxt_dbg_bus[i] = 8'b0;
3'b110: nxt_dbg_bus[i] = 8'b0;
3'b111: nxt_dbg_bus[i] = 8'b0;
assign tdl2dbg_dbg_a = dbg_bus[0];
assign tdl2dbg_dbg_b = dbg_bus[1];
//--------------------------------------------------------------------
// trtag1 and trtag2 decode
//--------------------------------------------------------------------
assign trtag1 = tic2tdl_trtag_in;
trtag1_dcd = {DCD_TAG_WIDTH{1'b0}};
trtag1_dcd[trtag1] = 1'b1;
assign trtag2 = tec2tdl_trtag_in;
trtag2_dcd = {DCD_TAG_WIDTH{1'b0}};
trtag2_dcd[trtag2] = 1'b1;
//--------------------------------------------------------------------
// Scoreboard Controller read from tdl
//--------------------------------------------------------------------
assign tdl2tec_rd_data_out = dma_data[dma_addr];
assign tsb_dma_ext_rd_data = tdl2tec_rd_data_out;
assign req_in = tic2tdl_req_in | tec2tdl_req_in;
always @ (req_in or tsb_dma_ext_select or ext_addr or tec2tdl_trtag_in)
if (!req_in && tsb_dma_ext_select)
dma_addr = tec2tdl_trtag_in;
// Register array load is determined by the wr_data_load for the individual
// address row. This value is generated from a decode of the transaction tag
// input and the wr_data input for each agent wanting to perform a write.
// load logic to determine which row will get written to
assign tic_wr_data_ld = trtag1_dcd & {DEPTH{tic2tdl_wr_in}};
assign tec_wr_data_ld = trtag2_dcd & {DEPTH{tec2tdl_wr_in}};
assign wr_data_ld = tic_wr_data_ld | tec_wr_data_ld;
//--------------------------------------------------------------------
// write from scoreboard controllers
//--------------------------------------------------------------------
// mux for each row of the flop array to select data from controller 1 or 2
always @ (tec_wr_data_ld or tic2tdl_wr_data_in or tec2tdl_wr_data_in)
for (j=0; j < DEPTH; j=j+1)
case(tec_wr_data_ld[j]) // synopsys parallel_case
1'b0 : nxt_wr_data_in[j] = tic2tdl_wr_data_in;
1'b1 : nxt_wr_data_in[j] = tec2tdl_wr_data_in;
endcase // case(tec_wr_data_ld [j])
//////////////////////////////////////////////////////////////////////
// *********** Sequential Logic ************************************
//////////////////////////////////////////////////////////////////////
for (k=0; k < DEPTH; k=k+1)
dma_data[k] <= {`FIRE_DLC_TSR_WR_DATA_WDTH{1'b0}};
dma_data[k] <= nxt_wr_data_in[k];
for (l = 0; l < 2; l = l + 1)
dbg_bus[l] <= nxt_dbg_bus[l];
end // always @ (posedge clk)