Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_tsb_tdl.v
// ========== 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
// have any questions.
//
// ========== Copyright Header End ============================================
module dmu_tsb_tdl
(
// Control Signals
clk,
rst_l,
// Input from TIC Controller to TDL (Write Data)
tic2tdl_wr_in,
tic2tdl_trtag_in,
tic2tdl_wr_data_in,
tic2tdl_req_in,
// Input from TEC Controller to TDL (Write Data)
tec2tdl_wr_in,
tec2tdl_trtag_in,
tec2tdl_wr_data_in,
tec2tdl_req_in,
// Output from TDL to TEC Controller (Read Data)
tdl2tec_rd_data_out,
// CSR interface
ext_addr,
tsb_dma_ext_done,
tsb_dma_ext_select,
tsb_dma_ext_rd_data,
// Debug Ports
tdl2dbg_dbg_a,
tdl2dbg_dbg_b,
dbg2tdl_dbg_sel_a,
dbg2tdl_dbg_sel_b
);
// synopsys sync_set_reset "rst_l"
//////////////////////////////////////////////////////////////////////
//************************* Parameters *************************
//////////////////////////////////////////////////////////////////////
parameter DEPTH = 32; //32
parameter DCD_TAG_WIDTH = 32; //32
//////////////////////////////////////////////////////////////////////
//************************* Port Declarations *******************
//////////////////////////////////////////////////////////////////////
// Control signals
input clk;
input rst_l;
// TIC to TDL Interface
input tic2tdl_wr_in;
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 tic2tdl_req_in;
// TEC to TDL Interface
input tec2tdl_wr_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;
input tec2tdl_req_in;
// TDL to TEC Interface
output [`FIRE_DLC_TSR_RD_DATA_WDTH-1:0] tdl2tec_rd_data_out;
// CSR Interface
input [`FIRE_DLC_TSR_TRN_WDTH-1:0] ext_addr;
input tsb_dma_ext_select;
output tsb_dma_ext_done;
output [`FIRE_DLC_TSR_RD_DATA_WDTH-1:0] tsb_dma_ext_rd_data; // SAME AS tdl2tec_rd_data_out
// Debug Ports
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 tic2tdl_wr_in;
wire [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] tic2tdl_wr_data_in;
wire tec2tdl_wr_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;
wire req_in;
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 tsb_dma_ext_done;
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;
integer i, j, k, l;
// memory array
reg [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] dma_data[0:DEPTH-1]; // memory with 32 - 48 bit entries
// debug
reg [2:0] dbg_sel [0:1];
reg [`FIRE_DBG_DATA_BITS] dbg_bus [0:1];
reg [`FIRE_DBG_DATA_BITS] nxt_dbg_bus [0:1];
// debug wires
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 ************************************
//////////////////////////////////////////////////////////////////////
// debug
always @ (dbg2tdl_dbg_sel_a or dbg2tdl_dbg_sel_b)
begin
dbg_sel[0] = dbg2tdl_dbg_sel_a;
dbg_sel[1] = dbg2tdl_dbg_sel_b;
end
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)
begin
for (i = 0; i < 2; i = i + 1)
begin
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;
endcase
end
end
assign tdl2dbg_dbg_a = dbg_bus[0];
assign tdl2dbg_dbg_b = dbg_bus[1];
// end debug
//--------------------------------------------------------------------
// trtag1 and trtag2 decode
//--------------------------------------------------------------------
assign trtag1 = tic2tdl_trtag_in;
always @(trtag1)
begin
trtag1_dcd = {DCD_TAG_WIDTH{1'b0}};
trtag1_dcd[trtag1] = 1'b1;
end
assign trtag2 = tec2tdl_trtag_in;
always @(trtag2)
begin
trtag2_dcd = {DCD_TAG_WIDTH{1'b0}};
trtag2_dcd[trtag2] = 1'b1;
end
//--------------------------------------------------------------------
// 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;
// dcm read from tdl
always @ (req_in or tsb_dma_ext_select or ext_addr or tec2tdl_trtag_in)
if (!req_in && tsb_dma_ext_select)
begin
dma_addr = ext_addr;
tsb_dma_ext_done = 1'b1;
end
else
begin
dma_addr = tec2tdl_trtag_in;
tsb_dma_ext_done = 1'b0;
end
// 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)
begin
for (j=0; j < DEPTH; j=j+1)
begin
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])
end
end
//////////////////////////////////////////////////////////////////////
// *********** Sequential Logic ************************************
//////////////////////////////////////////////////////////////////////
always @(posedge clk)
begin
for (k=0; k < DEPTH; k=k+1)
begin
if (!rst_l)
dma_data[k] <= {`FIRE_DLC_TSR_WR_DATA_WDTH{1'b0}};
else if(wr_data_ld[k])
dma_data[k] <= nxt_wr_data_in[k];
end
end
// Debug port outputs
always @ (posedge clk)
begin
for (l = 0; l < 2; l = l + 1)
begin
if(!rst_l)
dbg_bus[l] <= 8'h00;
else
dbg_bus[l] <= nxt_dbg_bus[l];
end
end // always @ (posedge clk)
endmodule // dmu_tsb_tdl