Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_psb_ptg.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: dmu_psb_ptg.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_ptg
(
// Control Signals
clk,
rst_l,
// PIC-PTG INTERFACE
// PIC-PTG Interface (Internal Input from PIC to PTG)
tag_deq,
// PTG-PIC Interface (Internal Output to PIC)
no_tag_avail,
tag_issue,
// PCE-PTG INTERFACE
// PCE-PTG Interface (Internal Input from PCE to PTG)
tag_enq,
tag_retire,
// Debug ports
ptg2dbg_dbg_a,
ptg2dbg_dbg_b,
dbg2ptg_dbg_sel_a,
dbg2ptg_dbg_sel_b
);
// synopsys sync_set_reset "rst_l"
///////////////////////////////////////////////////////////////////////
// ************************* Parameters *************************
///////////////////////////////////////////////////////////////////////
parameter TAG_NUM = 32; // 32; number of tags
parameter TAG_WDTH = 5; // 5; number of bits to encode tag: log2(TAG_NUM)
//////////////////////////////////////////////////////////////////////
//************************* Port Declarations *******************
//////////////////////////////////////////////////////////////////////
// Control Signals
input clk;
input rst_l;
// generator external interface inputs
input tag_deq; // request from PRM for pktag
input tag_enq; // request from CRM to retire pktag
input [(TAG_WDTH-1):0] tag_retire; // pktag from CRM
// generator external interface outputs
output no_tag_avail; // all pktags are in use
output [(TAG_WDTH-1):0] tag_issue; // pktag to be issued to PRM per request
// Debug Wires
output [`FIRE_DBG_DATA_BITS] ptg2dbg_dbg_a;
output [`FIRE_DBG_DATA_BITS] ptg2dbg_dbg_b;
input [2:0] dbg2ptg_dbg_sel_a;
input [2:0] dbg2ptg_dbg_sel_b;
//////////////////////////////////////////////////////////////////////
//*********************** Wires and Regs ************************
//////////////////////////////////////////////////////////////////////
wire tag_deq;
reg [TAG_WDTH-1:0] next_tag_issue;
wire n_no_tag_avail;
wire tag_enq;
wire [TAG_WDTH-1:0] tag_retire;
wire [TAG_NUM-1:0] tag_issue_vctr;
wire [TAG_NUM-1:0] next_tag;
wire [TAG_NUM-1:0] higher_priority_tag;
// non flops
wire [TAG_NUM-1:0] nxt_tag_pool;
reg [TAG_NUM-1:0] tag_dec_vctr;
reg [TAG_NUM-1:0] dcd_vec;
// flops
reg [TAG_NUM-1:0] tag_pool;
reg [TAG_WDTH-1:0] tag_issue;
reg no_tag_avail;
reg [5:0] count;
reg ptg_idle;
// 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 ports
wire [`FIRE_DBG_DATA_BITS] ptg2dbg_dbg_a; // PTG debug output a
wire [`FIRE_DBG_DATA_BITS] ptg2dbg_dbg_b; // PTG debug output b
wire [2:0] dbg2ptg_dbg_sel_a; // PTG debug select a
wire [2:0] dbg2ptg_dbg_sel_b; // PTG debug select b
integer i;
//////////////////////////////////////////////////////////////////////
// ******** Zero-in checkers************************************
//////////////////////////////////////////////////////////////////////
// 0in bus_id -req tag_deq -req_id tag_issue -ret tag_enq -ret_id tag_retire -max_ids 32
// 0in encoder -in next_tag -out next_tag_issue -zero off
// 0in decoder -in tag_retire -out dcd_vec
//////////////////////////////////////////////////////////////////////
// ********************* Combinational Logic ***********************
//////////////////////////////////////////////////////////////////////
// debug
always @ (dbg2ptg_dbg_sel_a or dbg2ptg_dbg_sel_b)
begin
dbg_sel[0] = dbg2ptg_dbg_sel_a;
dbg_sel[1] = dbg2ptg_dbg_sel_b;
end
always @ (dbg_sel[0] or dbg_sel[1] or tag_enq or tag_deq or tag_issue or tag_retire
or no_tag_avail or ptg_idle)
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] = {2'b0, tag_enq, tag_retire};
3'b001: nxt_dbg_bus[i] = {1'b0, no_tag_avail, tag_deq, tag_issue};
3'b010: nxt_dbg_bus[i] = 8'b0;
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] = {7'b0,ptg_idle};
endcase
end
end
assign ptg2dbg_dbg_a = dbg_bus[0];
assign ptg2dbg_dbg_b = dbg_bus[1];
// end debug
//************************************
// CLEAR (RETIRE) TAG
//************************************
// if tag pool is empty the retired tag becomes the next tag to issue
always @ (tag_retire or tag_enq or no_tag_avail)
begin
if(no_tag_avail & tag_enq)
begin
dcd_vec = {TAG_NUM{1'b0}};
dcd_vec[tag_retire] = 1'b1;
tag_dec_vctr = dcd_vec & {TAG_NUM{1'b0}};
end
else
begin
dcd_vec = {TAG_NUM{1'b0}};
dcd_vec[tag_retire] = 1'b1;
tag_dec_vctr = dcd_vec & {TAG_NUM{tag_enq}};
end
end // always @ (tag_retire or tag_enq)
//************************************
// ISSUE TAG
//************************************
assign tag_issue_vctr = (next_tag & {TAG_NUM{tag_deq}});
// generate "next tag pool" storage vector
assign nxt_tag_pool = (tag_dec_vctr | tag_pool) & ~tag_issue_vctr;
// generate full signal
assign n_no_tag_avail = ~(|tag_pool);
// Idle counter
always @(posedge clk)
if (~rst_l)
count <= 6'b00_0000;
else if(tag_enq | tag_deq)
begin
if (tag_deq & tag_enq)
count <= count;
else if (tag_deq)
count <= count + 1'b1;
else
count <= count - 1'b1;
end
always @(count)
if (count == 6'b00_0000)
ptg_idle = 1'b1;
else
ptg_idle = 1'b0;
always @(posedge clk)
if (~rst_l)
no_tag_avail <= 1'b0;
else if (tag_deq)
no_tag_avail <= n_no_tag_avail;
else if (tag_enq)
no_tag_avail <= 1'b0;
// "tag pool" storage vector: 1 = avail, 0 = used
always @(posedge clk)
if (~rst_l)
tag_pool <= 32'hffff_fffe; // all tags available on reset
else
tag_pool <= nxt_tag_pool; // retire/issue tags
//***********************************
// priority select
//***********************************
assign higher_priority_tag[TAG_NUM-1:1] = higher_priority_tag[TAG_NUM-2:0] | tag_pool[TAG_NUM-2:0];
assign higher_priority_tag[0] = 1'b0;
assign next_tag[TAG_NUM-1:0] = tag_pool[TAG_NUM-1:0] & ~higher_priority_tag[TAG_NUM-1:0];
//***********************************
// encode tag
//***********************************
always @(next_tag)
begin
next_tag_issue[0] = (next_tag[1] | next_tag[3] | next_tag[5] |
next_tag[7] | next_tag[9] | next_tag[11] |
next_tag[13] | next_tag[15] |
next_tag[17] | next_tag[19] | next_tag[21] |
next_tag[23] | next_tag[25] | next_tag[27] |
next_tag[29] | next_tag[31]);
next_tag_issue[1] = (next_tag[2] | next_tag[3] | next_tag[6] |
next_tag[7] | next_tag[10] | next_tag[11] |
next_tag[14] | next_tag[15] |
next_tag[18] | next_tag[19] | next_tag[22] |
next_tag[23] | next_tag[26] | next_tag[27] |
next_tag[30] | next_tag[31]);
next_tag_issue[2] = (next_tag[4] | next_tag[5] | next_tag[6] |
next_tag[7] | next_tag[12] | next_tag[13] |
next_tag[14] | next_tag[15] |
next_tag[20] | next_tag[21] | next_tag[22] |
next_tag[23] | next_tag[28] | next_tag[29] |
next_tag[30] | next_tag[31]);
next_tag_issue[3] = (next_tag[8] | next_tag[9] | next_tag[10] |
next_tag[11] | next_tag[12] | next_tag[13] |
next_tag[14] | next_tag[15] |
next_tag[24] | next_tag[25] | next_tag[26] |
next_tag[27] | next_tag[28] | next_tag[29] |
next_tag[30] | next_tag[31]);
next_tag_issue[4] = (next_tag[16] | next_tag[17] | next_tag[18] |
next_tag[19] | next_tag[20] | next_tag[21] |
next_tag[22] | next_tag[23] |
next_tag[24] | next_tag[25] | next_tag[26] |
next_tag[27] | next_tag[28] | next_tag[29] |
next_tag[30] | next_tag[31]);
end // always @ (next_tag)
always @(posedge clk)
if (~rst_l)
tag_issue <= {TAG_WDTH{1'b0}};
else if (tag_enq & no_tag_avail)
tag_issue <= tag_retire;
else if (tag_deq)
tag_issue <= next_tag_issue;
// Debug port outputs
always @ (posedge clk)
begin
if(~rst_l)
for (i = 0; i < 2; i = i + 1)
dbg_bus[i] <= 8'h00;
else
for (i = 0; i < 2; i = i + 1)
dbg_bus[i] <= nxt_dbg_bus[i];
end // always @ (posedge clk)
endmodule // dmu_psb_ptg