Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_psb_pdl.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: dmu_psb_pdl.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_psb_pdl
(
// Control Signals
clk,
rst_l,
// Input from PIC Controller to PDL
pic2pdl_dma_wr_in,
pic2pdl_pktag_in,
pic2pdl_type_in,
pic2pdl_dma_wr_data_in,
pic2pdl_req_in,
// Output from PDL to PIC Controller
pdl2pic_pio_rd_data_out,
// Input from PCE Controller to PDL
pce2pdl_pio_wr_in,
pce2pdl_pktag_in,
pce2pdl_type_in,
pce2pdl_pio_wr_data_in,
pce2pdl_req_in,
// Output from PDL to PCE Controller
pdl2pce_dma_rd_data_out,
// CSR interface
ext_addr,
psb_dma_ext_done,
psb_pio_ext_done,
psb_dma_ext_select,
psb_dma_ext_rd_data,
psb_pio_ext_select,
psb_pio_ext_rd_data,
// Debug Ports
pdl2dbg_dbg_a,
pdl2dbg_dbg_b,
dbg2pdl_dbg_sel_a,
dbg2pdl_dbg_sel_b
);
// synopsys sync_set_reset "rst_l"
//////////////////////////////////////////////////////////////////////
//************************* Parameters *************************
//////////////////////////////////////////////////////////////////////
parameter DMA_DEPTH = 32; // 32
parameter PIO_DEPTH = 16; // 16
//////////////////////////////////////////////////////////////////////
//************************* Port Declarations *******************
//////////////////////////////////////////////////////////////////////
// Control signals
input clk;
input rst_l;
// PIC to PDL Interface
input pic2pdl_dma_wr_in;
input [`FIRE_DLC_PSR_TRN_WDTH-1:0] pic2pdl_pktag_in;
input pic2pdl_type_in;
input [`FIRE_DLC_PSR_DMA_DATA_WDTH-1:0] pic2pdl_dma_wr_data_in;
input pic2pdl_req_in;
// PDL to PIC Interface
output [`FIRE_DLC_PSR_PIO_DATA_WDTH-1:0] pdl2pic_pio_rd_data_out;
// PCE to PDL Interface
input pce2pdl_pio_wr_in;
input [`FIRE_DLC_PSR_TRN_WDTH-1:0] pce2pdl_pktag_in;
input pce2pdl_type_in;
input [`FIRE_DLC_PSR_PIO_DATA_WDTH-1:0] pce2pdl_pio_wr_data_in;
input pce2pdl_req_in;
// PDL to PCE Interface
output [`FIRE_DLC_PSR_DMA_DATA_WDTH-1:0] pdl2pce_dma_rd_data_out;
// CSR Interface
input [`FIRE_DLC_PSR_TRN_WDTH-1:0] ext_addr;
input psb_dma_ext_select;
input psb_pio_ext_select;
output psb_dma_ext_done;
output psb_pio_ext_done;
output [`FIRE_DLC_PSR_DMA_DATA_WDTH-1:0] psb_dma_ext_rd_data; // SAME AS pdl2pce_rd_data_out
output [`FIRE_DLC_PSR_PIO_DATA_WDTH-1:0] psb_pio_ext_rd_data; // SAME AS pdl2pic_rd_data_out
// Debug Ports
output [`FIRE_DBG_DATA_BITS] pdl2dbg_dbg_a;
output [`FIRE_DBG_DATA_BITS] pdl2dbg_dbg_b;
input [2:0] dbg2pdl_dbg_sel_a;
input [2:0] dbg2pdl_dbg_sel_b;
//////////////////////////////////////////////////////////////////////
//*********************** Wires and Regs ************************
//////////////////////////////////////////////////////////////////////
wire pic2pdl_dma_wr_in;
wire [`FIRE_DLC_PSR_DMA_DATA_WDTH-1:0] pic2pdl_dma_wr_data_in;
wire [`FIRE_DLC_PSR_PIO_DATA_WDTH-1:0] pdl2pic_pio_rd_data_out;
wire pce2pdl_pio_wr_in;
wire [`FIRE_DLC_PSR_PIO_DATA_WDTH-1:0] pce2pdl_pio_wr_data_in;
wire [`FIRE_DLC_PSR_DMA_DATA_WDTH-1:0] pdl2pce_dma_rd_data_out;
wire req_in;
reg [DMA_DEPTH-1:0] pktag1_dcd; // decoded pktag1 5 bit to 32 bit
reg [PIO_DEPTH-1:0] pktag2_dcd; // decoded pktag2 4 bit to 16 bit
wire [`FIRE_DLC_PSR_PIO_DATA_WDTH-1:0] psb_pio_ext_rd_data;
wire [`FIRE_DLC_PSR_DMA_DATA_WDTH-1:0] psb_dma_ext_rd_data;
reg psb_dma_ext_done;
reg psb_pio_ext_done;
reg [`FIRE_DLC_PSR_TRN_WDTH-2:0] pio_addr;
reg [`FIRE_DLC_PSR_TRN_WDTH-1:0] dma_addr;
wire [`FIRE_DLC_PSR_DMA_DATA_WDTH-1:0] dma_wr_data_in;
wire [`FIRE_DLC_PSR_PIO_DATA_WDTH-1:0] pio_wr_data_in;
wire [DMA_DEPTH-1:0] pic_dma_wr_data_ld;
wire [PIO_DEPTH-1:0] pce_pio_wr_data_ld;
integer i, j, k, m;
//----------------- FLOPS -----------------------------
// memory array's
// memory with 32 - 46 bit entries
reg [`FIRE_DLC_PSR_DMA_DATA_WDTH-1:0] dma_data[0:DMA_DEPTH-1];
// memory with 16 - 6 bit entries
reg [`FIRE_DLC_PSR_PIO_DATA_WDTH-1:0] pio_data[0:PIO_DEPTH-1];
// 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] pdl2dbg_dbg_a; // PDL debug output a
wire [`FIRE_DBG_DATA_BITS] pdl2dbg_dbg_b; // PDL debug output b
wire [2:0] dbg2pdl_dbg_sel_a; // PDL debug select a
wire [2:0] dbg2pdl_dbg_sel_b; // PDL debug select b
//////////////////////////////////////////////////////////////////////
// ******** Zero-in checkers************************************
//////////////////////////////////////////////////////////////////////
// 0in decoder -in pic2pdl_pktag_in -out pktag1_dcd
// 0in decoder -in pce2pdl_pktag_in[3:0] -out pktag2_dcd
// 0in bits_on -var pic_dma_wr_data_ld -max 1
// 0in bits_on -var pce_pio_wr_data_ld -max 1
//////////////////////////////////////////////////////////////////////
// ******** Combinational Logic ************************************
//////////////////////////////////////////////////////////////////////
// debug
always @ (dbg2pdl_dbg_sel_a or dbg2pdl_dbg_sel_b)
begin
dbg_sel[0] = dbg2pdl_dbg_sel_a;
dbg_sel[1] = dbg2pdl_dbg_sel_b;
end
always @ (dbg_sel[0] or dbg_sel[1] or pic2pdl_req_in or pic2pdl_type_in or pic2pdl_dma_wr_in or pic2pdl_pktag_in
or pce2pdl_req_in or pce2pdl_type_in or pce2pdl_pktag_in or pce2pdl_pio_wr_in
or psb_dma_ext_select or psb_pio_ext_select or ext_addr or psb_dma_ext_done or psb_pio_ext_done)
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] = {pic2pdl_dma_wr_in, pic2pdl_req_in, pic2pdl_type_in, pic2pdl_pktag_in};
3'b001: nxt_dbg_bus[i] = {pce2pdl_pio_wr_in, pce2pdl_req_in, pce2pdl_type_in, pce2pdl_pktag_in};
3'b010: nxt_dbg_bus[i] = {1'b0, psb_dma_ext_select, psb_dma_ext_done, ext_addr};
3'b011: nxt_dbg_bus[i] = {1'b0, psb_pio_ext_select, psb_pio_ext_done, ext_addr};
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 pdl2dbg_dbg_a = dbg_bus[0];
assign pdl2dbg_dbg_b = dbg_bus[1];
// end debug
//--------------------------------------------------------------------
// pktag1 and pktag2 decode
//--------------------------------------------------------------------
// returns a binary 32 bit vector with 1 bit set
// decode pktag from PIC controller (type_in pio = 1 , dma = 0)
always @(pic2pdl_pktag_in)
begin
pktag1_dcd = {DMA_DEPTH{1'b0}};
pktag1_dcd[pic2pdl_pktag_in] = 1'b1;
end
// returns a binary 16 bit vector with 1 bit set
// decode pktag from PCE controller (type_in pio = 1 , dma = 0)
always @(pce2pdl_pktag_in)
begin
pktag2_dcd = {PIO_DEPTH{1'b0}};
pktag2_dcd[pce2pdl_pktag_in[3:0]] = 1'b1;
end
//--------------------------------------------------------------------
// Scoreboard Controller read from pdl
//--------------------------------------------------------------------
assign pdl2pic_pio_rd_data_out = pio_data[pio_addr];
assign pdl2pce_dma_rd_data_out = dma_data[dma_addr];
assign psb_pio_ext_rd_data = pdl2pic_pio_rd_data_out;
assign psb_dma_ext_rd_data = pdl2pce_dma_rd_data_out;
assign req_in = pic2pdl_req_in | pce2pdl_req_in;
// dcm read from pdl
always @ (req_in or psb_pio_ext_select or ext_addr or pic2pdl_pktag_in or psb_dma_ext_select or pce2pdl_pktag_in )
if (!req_in && psb_pio_ext_select)
begin
pio_addr = ext_addr[3:0];
dma_addr = pce2pdl_pktag_in;
psb_pio_ext_done = 1'b1;
psb_dma_ext_done = 1'b0;
end
else if (!req_in && psb_dma_ext_select)
begin
dma_addr = ext_addr;
pio_addr = pic2pdl_pktag_in[3:0];
psb_dma_ext_done = 1'b1;
psb_pio_ext_done = 1'b0;
end
else
begin
dma_addr = pce2pdl_pktag_in;
pio_addr = pic2pdl_pktag_in[3:0];
psb_pio_ext_done = 1'b0;
psb_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 packet 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 pic_dma_wr_data_ld = pktag1_dcd & {DMA_DEPTH{pic2pdl_dma_wr_in}};
assign pce_pio_wr_data_ld = pktag2_dcd & {PIO_DEPTH{pce2pdl_pio_wr_in}};
//--------------------------------------------------------------------
// write from scoreboard controllers
//--------------------------------------------------------------------
assign dma_wr_data_in = pic2pdl_dma_wr_data_in;
assign pio_wr_data_in = pce2pdl_pio_wr_data_in;
//////////////////////////////////////////////////////////////////////
// *********** Sequential Logic ************************************
//////////////////////////////////////////////////////////////////////
always @(posedge clk)
begin
if (~rst_l)
for(j=0; j < DMA_DEPTH; j=j+1)
dma_data[j] <= {`FIRE_DLC_PSR_DMA_DATA_WDTH{1'b0}};
else
for(j=0; j < DMA_DEPTH; j=j+1)
if (pic_dma_wr_data_ld[j])
dma_data[j] <= dma_wr_data_in;
end
always @(posedge clk)
begin
if (~rst_l)
for(k=0; k < PIO_DEPTH; k=k+1)
pio_data[k] <= {`FIRE_DLC_PSR_PIO_DATA_WDTH{1'b0}};
else
for(k=0; k < PIO_DEPTH; k=k+1)
if (pce_pio_wr_data_ld[k])
pio_data[k] <= pio_wr_data_in;
end
// Debug port outputs
always @ (posedge clk)
begin
if(~rst_l)
for (m = 0; m < 2; m = m + 1)
dbg_bus[m] <= 8'h00;
else
for (m = 0; m < 2; m = m + 1)
dbg_bus[m] <= nxt_dbg_bus[m];
end // always @ (posedge clk)
endmodule // dmu_psb_pdl