Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_ilu_eil_bufmgr.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: dmu_ilu_eil_bufmgr.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_ilu_eil_bufmgr (
clk,
rst_l,
d2p_ehb_addr,
d2p_ech_wptr,
d2p_erh_wptr,
p2d_ech_rptr,
p2d_erh_rptr,
p2d_ecd_rptr,
p2d_erd_rptr,
cib2eil_drain,
cib2eil_pec_drain,
rcd_is_cpl,
rcd_is_cpl_reg,
edb_wptr,
n_d2p_ehb_we,
edb_wptr_inc,
ehb_full,
ecd_full,
erd_full,
edb_full_adv,
// debug signals
erh_full,
ech_full,
erd_full_adv,
ecd_full_adv,
il2cl_gr_16 );
// synopsys sync_set_reset "rst_l"
// >>>>>>>>>>>>>>>>>>>>>>>>> Port Declarations <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//------------------------------------------------------------------------
// Clock and Reset Signals
//------------------------------------------------------------------------
input clk; // input clock
input rst_l; // input reset
//------------------------------------------------------------------------
// EHB interface
//------------------------------------------------------------------------
output [5:0] d2p_ehb_addr; // EHB write pointer
//------------------------------------------------------------------------
// EHB interface
//------------------------------------------------------------------------
output il2cl_gr_16; // for stall
//------------------------------------------------------------------------
// EHB management pointers
//------------------------------------------------------------------------
output [5:0] d2p_ech_wptr; // gray-coded cpl-buffer in EHB write pointer
input [5:0] p2d_ech_rptr; // gray-coded cpl-buffer in EHB read pointer
output [5:0] d2p_erh_wptr; // gray-coded req-buffer in EHB write pointer
input [5:0] p2d_erh_rptr; // gray-coded req-buffer in EHB read pointer
//------------------------------------------------------------------------
// EDB management pointers
//------------------------------------------------------------------------
input [`FIRE_P2D_ECD_RPTR_WDTH-1:0] p2d_ecd_rptr; // gray-coded EDB DMA Cpl buf rd pointer
input [`FIRE_P2D_ERD_RPTR_WDTH-1:0] p2d_erd_rptr; // gray-coded EDB PIO Wr buf rd pointer
//------------------------------------------------------------------------
// special handling
//------------------------------------------------------------------------
input cib2eil_drain; // combined drain signal
input cib2eil_pec_drain; // caused by p2d_drain
//------------------------------------------------------------------------
// internal interface
//------------------------------------------------------------------------
input n_d2p_ehb_we; // EHB write stroke, from xfrfsm.v
input edb_wptr_inc; // increase EDB buffer wptr, from datafsm
output [7:0] edb_wptr; // to be injected to datapath, to datafsm
input rcd_is_cpl; // 1- DMA cpl; 0- PIO req, from rcdbldr.v
input rcd_is_cpl_reg; // 1- DMA cpl; 0- PIO req, from rcdbldr.v
output ehb_full; // EHB full based on rcd type, to xfrfsm.v
output ecd_full; // EDB/ECD full to datafsm.v
output erd_full; // EDB/ERD full to datafsm.v
output edb_full_adv;
//---------------------------------------------------------------------
// debug signals
//---------------------------------------------------------------------
output erh_full;
output ech_full;
output erd_full_adv;
output ecd_full_adv;
// >>>>>>>>>>>>>>>>>>>>>>>>> Data Type Declarations <<<<<<<<<<<<<<<<<<<<<<<<<
// ~~~~~~~~~~~~~~~~~~~~~~~~~ REGISTER - FLOPS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//------------------------------------------------------------------------
// EDB management
// -----------------------------------------------------------------------
reg [7:0] ecd_wptr; // EDB cpl buffer wptr, [7] - roll over
reg [7:0] erd_wptr; // EDB req buffer wptr, [7] - roll over
//------------------------------------------------------------------------
// EHB management
// -----------------------------------------------------------------------
reg [5:0] d2p_ehb_addr;
reg [5:0] d2p_erh_wptr; // gray-coded flop
reg [5:0] d2p_ech_wptr; // gray-coded flop
reg [5:0] erh_wptr; // binary pointer
reg [5:0] ech_wptr; // binary pointer
reg [5:0] erh_rptr; // binary pointer
reg [5:0] ech_rptr; // binary pointer
reg [7:0] erd_rptr; // binary pointer
reg [7:0] ecd_rptr; // binary pointer
// for advanced edb fullness check
reg [7:0] erd_wptr_adv;
reg [7:0] ecd_wptr_adv;
// ~~~~~~~~~~~~~~~~~~~~~~~~~ REGISTER - NON-FLOPS ~~~~~~~~~~~~~~~~~~~~~~~~~~
wire ech_full;
wire erh_full;
// ~~~~~~~~~~~~~~~~~~~~~~~~~ NETS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wire [5:0] n_d2p_erh_wptr; // gray-coded
wire [5:0] n_d2p_ech_wptr; // gray-coded
wire [5:0] n_d2p_ehb_addr; // binary write pointer to EHB
wire [5:0] gray_erh_rptr; // output from sync-flop
wire [5:0] gray_ech_rptr; // output from sync-flop
wire [5:0] n_erh_rptr; // binary pointer
wire [5:0] n_ech_rptr; // binary pointer
wire [7:0] gray_erd_rptr; // output from sync-flop
wire [7:0] gray_ecd_rptr; // output from sync-flop
wire [7:0] n_erd_rptr; // binary pointer
wire [7:0] n_ecd_rptr; // binary pointer
wire ld_ech_wptr;
wire ld_erh_wptr;
wire ld_ecd_wptr;
wire ld_erd_wptr;
// for advanced edb fullness check
wire erd_full_adv;
wire ecd_full_adv;
// >>>>>>>>>>>>>>>>>>>>>>>>> Zero In Checkers <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>> Function Declarations <<<<<<<<<<<<<<<<<<<<<<<<<<
// converts gray-coded to binary-coded (6-bit wide)
function [5:0] gray2bin6;
input [5:0] gray;
integer i;
reg temp;
begin
temp = 0;
for (i=5; i>=0; i=i-1)
begin
temp = temp ^ gray[i];
gray2bin6[i] = temp;
end
end
endfunction // gray2bin6
// converts gray-coded to binary-coded (8-bit wide)
function [7:0] gray2bin8;
input [7:0] gray;
integer i;
reg temp;
begin
temp = 0;
for (i=7; i>=0; i=i-1)
begin
temp = temp ^ gray[i];
gray2bin8[i] = temp;
end
end
endfunction // gray2bin8
// >>>>>>>>>>>>>>>>>>>>>>>>> RTL/Behavioral Model <<<<<<<<<<<<<<<<<<<<<<<<<<<
// 0in known_driven -var ld_ech_wptr
// 0in known_driven -var ld_erh_wptr
// 0in known_driven -var ld_ecd_wptr
// 0in known_driven -var ld_erd_wptr
//------------------------------------------------------------------------
// EHB management
//------------------------------------------------------------------------
// convert binary to gray-coded
assign n_d2p_erh_wptr = (erh_wptr >> 1) ^ erh_wptr;
assign n_d2p_ech_wptr = (ech_wptr >> 1) ^ ech_wptr;
// write pointer to EHB
assign n_d2p_ehb_addr = rcd_is_cpl ? {1'b0, ech_wptr[4:0]} :
{1'b1, erh_wptr[4:0]};
// convert gray-coded to binary
assign n_erh_rptr = gray2bin6(gray_erh_rptr);
assign n_ech_rptr = gray2bin6(gray_ech_rptr);
//BPn2 12-16-05 check for 16 or less entries in ehb and stall crm arb
reg gr_16;
// create some constants which are easy to change with eco
reg [4:0] fifteen,sixteen;
always @ (posedge clk)
if(~rst_l) begin
fifteen <= {5'b01111};
sixteen <= {5'b10000};
end
else begin
fifteen <= {5'b01111};
sixteen <= {5'b10000};
end
wire il2cl_gr_16 = gr_16 & ~(cib2eil_drain | cib2eil_pec_drain) ;
always @(erh_wptr or erh_rptr or sixteen or fifteen ) begin
gr_16 = 1'b0;
case({erh_wptr[5],erh_rptr[5]})
2'b00: if ( (erh_wptr[4:0] - erh_rptr[4:0]) <= sixteen ) //
gr_16 = 1'b0;
else
gr_16 = 1'b1;
2'b01: if ( ( (5'b11111 - erh_rptr[4:0]) + erh_wptr[4:0]) <= fifteen )
gr_16 = 1'b0;
else
gr_16 = 1'b1;
2'b10: if ( ( (5'b11111 - erh_rptr[4:0]) + erh_wptr[4:0]) <= fifteen )
gr_16 = 1'b0;
else
gr_16 = 1'b1;
2'b11: if ( (erh_wptr[4:0] - erh_rptr[4:0]) <= sixteen )
gr_16 = 1'b0;
else
gr_16 = 1'b1;
endcase
end
// EHB fullness
assign erh_full = (erh_wptr[4:0] == erh_rptr[4:0]) & (erh_wptr[5] ^ erh_rptr[5]);
assign ech_full = (ech_wptr[4:0] == ech_rptr[4:0]) & (ech_wptr[5] ^ ech_rptr[5]);
assign ehb_full = (rcd_is_cpl ? ech_full : erh_full) & (~cib2eil_drain);
// load signals
assign ld_ech_wptr = n_d2p_ehb_we & rcd_is_cpl;
assign ld_erh_wptr = n_d2p_ehb_we & !rcd_is_cpl;
// EHB pointers
always @ (posedge clk)
if(~rst_l) begin
erh_rptr <= {6{1'b0}};
ech_rptr <= {6{1'b0}};
end
else begin
erh_rptr <= n_erh_rptr;
ech_rptr <= n_ech_rptr;
end
always @ (posedge clk)
if ((!rst_l) | cib2eil_pec_drain) begin
erh_wptr <= 6'b0;
ech_wptr <= 6'b0;
end
else begin
if (ld_ech_wptr) begin
ech_wptr <= ech_wptr + 1'b1;
end
else if (ld_erh_wptr) begin
erh_wptr <= erh_wptr + 1'b1;
end
end
// bug fix P544
always @ (posedge clk)
if(~rst_l) begin
d2p_ech_wptr <= {6{1'b0}};
d2p_erh_wptr <= {6{1'b0}};
d2p_ehb_addr <= {6{1'b0}};
end
else begin
d2p_ech_wptr <= n_d2p_ech_wptr;
d2p_erh_wptr <= n_d2p_erh_wptr;
d2p_ehb_addr <= n_d2p_ehb_addr;
end
//------------------------------------------------------------------------
// EDB management
//------------------------------------------------------------------------
// write pointer to EDB
assign edb_wptr = rcd_is_cpl_reg ? {1'b0, ecd_wptr[6:0]} :
{1'b1, erd_wptr[6:0]};
// convert gray-coded to binary
assign n_erd_rptr = gray2bin8(gray_erd_rptr);
assign n_ecd_rptr = gray2bin8(gray_ecd_rptr);
// EDB fullness
assign erd_full_adv = (erd_wptr_adv[6:0] == erd_rptr[6:0]) &
(erd_wptr_adv[7] ^ erd_rptr[7]);
assign ecd_full_adv = (ecd_wptr_adv[6:0] == ecd_rptr[6:0]) &
(ecd_wptr_adv[7] ^ ecd_rptr[7]);
assign edb_full_adv = rcd_is_cpl ? ecd_full_adv : erd_full_adv;
assign erd_full = (erd_wptr[6:0] == erd_rptr[6:0]) &
(erd_wptr[7] ^ erd_rptr[7]);
assign ecd_full = (ecd_wptr[6:0] == ecd_rptr[6:0]) &
(ecd_wptr[7] ^ ecd_rptr[7]);
// load signals
assign ld_ecd_wptr = edb_wptr_inc & rcd_is_cpl_reg;
assign ld_erd_wptr = edb_wptr_inc & !rcd_is_cpl_reg;
// EDB pointers
always @ (posedge clk)
if(~rst_l) begin
erd_rptr <= {8{1'b0}};
ecd_rptr <= {8{1'b0}};
end
else begin
erd_rptr <= n_erd_rptr;
ecd_rptr <= n_ecd_rptr;
end
always @ (posedge clk)
if ((!rst_l) | cib2eil_pec_drain) begin
erd_wptr <= 8'b0;
ecd_wptr <= 8'b0;
erd_wptr_adv <= 8'b1;
ecd_wptr_adv <= 8'b1;
end
else begin
if (ld_ecd_wptr) begin
ecd_wptr <= ecd_wptr + 1'b1;
ecd_wptr_adv <= ecd_wptr_adv + 1'b1;
end
else if (ld_erd_wptr) begin
erd_wptr <= erd_wptr + 1'b1;
erd_wptr_adv <= erd_wptr_adv + 1'b1;
end
end
// >>>>>>>>>>>>>>>>>>>>>>>>> Instantiations <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// sync-flop instantiations for p2d_erh_rptr
// pcie_common_sync_flop #(6) erh_sync_flop(
// .clk(clk),
// .din(p2d_erh_rptr),
// .dout(gray_erh_rptr));
cl_a1_clksyncff_4x erh_sync_flop_5 ( .d(p2d_erh_rptr[5]), .si(1'b0), .q( gray_erh_rptr[5]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erh_sync_flop_4 ( .d(p2d_erh_rptr[4]), .si(1'b0), .q( gray_erh_rptr[4]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erh_sync_flop_3 ( .d(p2d_erh_rptr[3]), .si(1'b0), .q( gray_erh_rptr[3]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erh_sync_flop_2 ( .d(p2d_erh_rptr[2]), .si(1'b0), .q( gray_erh_rptr[2]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erh_sync_flop_1 ( .d(p2d_erh_rptr[1]), .si(1'b0), .q( gray_erh_rptr[1]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erh_sync_flop_0 ( .d(p2d_erh_rptr[0]), .si(1'b0), .q( gray_erh_rptr[0]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
// sync-flop instantiations for p2d_ech_rptr
// pcie_common_sync_flop #(6) ech_sync_flop(
// .clk(clk),
// .din(p2d_ech_rptr),
// .dout(gray_ech_rptr));
cl_a1_clksyncff_4x ech_sync_flop_5 ( .d(p2d_ech_rptr[5]), .si(1'b0), .q( gray_ech_rptr[5]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ech_sync_flop_4 ( .d(p2d_ech_rptr[4]), .si(1'b0), .q( gray_ech_rptr[4]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ech_sync_flop_3 ( .d(p2d_ech_rptr[3]), .si(1'b0), .q( gray_ech_rptr[3]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ech_sync_flop_2 ( .d(p2d_ech_rptr[2]), .si(1'b0), .q( gray_ech_rptr[2]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ech_sync_flop_1 ( .d(p2d_ech_rptr[1]), .si(1'b0), .q( gray_ech_rptr[1]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ech_sync_flop_0 ( .d(p2d_ech_rptr[0]), .si(1'b0), .q( gray_ech_rptr[0]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
// sync-flop instantiations for p2d_erd_rptr
// pcie_common_sync_flop #(8) erd_sync_flop(
// .clk(clk),
// .din(p2d_erd_rptr),
// .dout(gray_erd_rptr));
cl_a1_clksyncff_4x erd_sync_flop_7 ( .d(p2d_erd_rptr[7]), .si(1'b0), .q( gray_erd_rptr[7]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erd_sync_flop_6 ( .d(p2d_erd_rptr[6]), .si(1'b0), .q( gray_erd_rptr[6]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erd_sync_flop_5 ( .d(p2d_erd_rptr[5]), .si(1'b0), .q( gray_erd_rptr[5]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erd_sync_flop_4 ( .d(p2d_erd_rptr[4]), .si(1'b0), .q( gray_erd_rptr[4]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erd_sync_flop_3 ( .d(p2d_erd_rptr[3]), .si(1'b0), .q( gray_erd_rptr[3]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erd_sync_flop_2 ( .d(p2d_erd_rptr[2]), .si(1'b0), .q( gray_erd_rptr[2]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erd_sync_flop_1 ( .d(p2d_erd_rptr[1]), .si(1'b0), .q( gray_erd_rptr[1]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x erd_sync_flop_0 ( .d(p2d_erd_rptr[0]), .si(1'b0), .q( gray_erd_rptr[0]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
// sync-flop instantiations for p2d_ecd_rptr
// pcie_common_sync_flop #(8) ecd_sync_flop(
// .clk(clk),
// .din(p2d_ecd_rptr),
// .dout(gray_ecd_rptr));
cl_a1_clksyncff_4x ecd_sync_flop_7 ( .d(p2d_ecd_rptr[7]), .si(1'b0), .q( gray_ecd_rptr[7]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ecd_sync_flop_6 ( .d(p2d_ecd_rptr[6]), .si(1'b0), .q( gray_ecd_rptr[6]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ecd_sync_flop_5 ( .d(p2d_ecd_rptr[5]), .si(1'b0), .q( gray_ecd_rptr[5]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ecd_sync_flop_4 ( .d(p2d_ecd_rptr[4]), .si(1'b0), .q( gray_ecd_rptr[4]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ecd_sync_flop_3 ( .d(p2d_ecd_rptr[3]), .si(1'b0), .q( gray_ecd_rptr[3]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ecd_sync_flop_2 ( .d(p2d_ecd_rptr[2]), .si(1'b0), .q( gray_ecd_rptr[2]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ecd_sync_flop_1 ( .d(p2d_ecd_rptr[1]), .si(1'b0), .q( gray_ecd_rptr[1]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
cl_a1_clksyncff_4x ecd_sync_flop_0 ( .d(p2d_ecd_rptr[0]), .si(1'b0), .q( gray_ecd_rptr[0]), .so(),
.l1clk(clk), .siclk(1'b0), .soclk(1'b0) );
endmodule // dmu_ilu_eil_bufmgr