Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_clu_ctm_cmdctlfsm.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: dmu_clu_ctm_cmdctlfsm.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_clu_ctm_cmdctlfsm
(
// clock/reset
clk,
rst_l,
// fsm inputs
mm2cl_tcr_req,
icr_fifo_empty,
nxt_tag_avail,
mrd_vld,
mwr_vld,
eqwr_vld,
mdo_vld,
pio16_vld,
pio64_vld,
uns_vld,
null_vld,
mwr_err,
eqwr_err,
pio_err,
diu_dma_bufmgmt_bsy,
diu_eqw_bufmgmt_bsy,
diu_dma_empty,
diu_pio_empty,
icr_clsts,
dou_space_avail,
uns_req_crdt_avail,
ds2cl_stall,
// fsm outputs
d2j_cmd_vld,
d2j_data_vld,
cl2mm_tcr_ack,
ctm2crm_rcd_enq,
cmd_req_sel,
icr_fifo_rd,
nxt_tag_req,
dma_dptr_req,
proc_uns,
icr_grnt,
proc_pio_err, // BP n2 4-28-05
cl2di_rd_en, // BP n2 5-12-05
// debug port
cmdctlfsm_state,
// idle checker port
cmdctlfsm_idle
);
// synopsys sync_set_reset "rst_l"
// >>>>>>>>>>>>>>>>>>>>>>>>> Parameter Declarations <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------
// State Number
// --------------------------------------------------------
//BP n2 6-09-04
// parameter STATE_NUM = 10;
parameter STATE_NUM = 13;
// --------------------------------------------------------
// State Declarations
// --------------------------------------------------------
parameter // summit enum cur_enum
IDLE = 0,
REQ_4DB_WAIT1 = 1,
REQ_4DB_WAIT2 = 2,
REQ_4DB_ENQ = 3,
CPL_4DB_WAIT1 = 4,
CPL_4DB_WAIT2 = 5,
CPL_4DB_ENQ = 6,
CPL_1DB_WAIT1 = 7,
CPL_1DB_WAIT2 = 8,
CPL_1DB_ENQ = 9,
REQ_1DB_WAIT1 = 10,
REQ_1DB_WAIT2 = 11,
REQ_1DB_ENQ = 12;
//BP n2 6-09-04
// --------------------------------------------------------
// ICR-TCR ARBITER PARAMETERS
// --------------------------------------------------------
parameter N = 2;
// >>>>>>>>>>>>>>>>>>>>>>>>> Port Declarations <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------
// Clock/Reset Signals
// --------------------------------------------------------
input clk;
input rst_l;
// --------------------------------------------------------
// FSM Inputs
// --------------------------------------------------------
input mm2cl_tcr_req;
input icr_fifo_empty;
input nxt_tag_avail;
input mrd_vld;
input mwr_vld;
input eqwr_vld;
input mdo_vld;
input pio16_vld;
input pio64_vld;
input uns_vld;
input null_vld;
input mwr_err;
input eqwr_err;
input pio_err;
input diu_dma_bufmgmt_bsy;
input diu_eqw_bufmgmt_bsy;
input diu_dma_empty;
input diu_pio_empty;
input icr_clsts;
input dou_space_avail;
input uns_req_crdt_avail;
input ds2cl_stall; // for N2 dmu quiescing
// --------------------------------------------------------
// FSM Outputs
// --------------------------------------------------------
// external
output d2j_cmd_vld;
output d2j_data_vld;
output cl2mm_tcr_ack;
output ctm2crm_rcd_enq;
// internal
output cmd_req_sel;
output icr_fifo_rd;
output nxt_tag_req;
output dma_dptr_req;
output proc_uns;
output icr_grnt;
output proc_pio_err; // BP n2 4-28-05, force 0 data on pio err cpl
output cl2di_rd_en; // BP n2 5-12-05, rd enable to diu ram for power savings
// debug port
output [3:0] cmdctlfsm_state;
// idle checker port
output cmdctlfsm_idle;
// >>>>>>>>>>>>>>>>>>>>>>>>> Data Type Declarations <<<<<<<<<<<<<<<<<<<<<<<<<
// ~~~~~~~~~~~~~~~~~~~~~~~~~ REGISTERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ********** Flops **********
reg [(STATE_NUM - 1):0] cur_state;
reg d2j_dvld_s0;
reg d2j_dvld_s1;
reg d2j_dvld_s2;
reg d2j_dvld_s3;
reg d2j_cmd_vld;
reg ctm2crm_rcd_enq;
reg cl2mm_tcr_ack;
// ********** Non-Flops ******
reg [(STATE_NUM - 1):0] nxt_state;
reg [3:0] enc_state;
// ~~~~~~~~~~~~~~~~~~~~~~~~~ NETS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wire [(N-1):0] higher_pri_reqs;
wire [(N-1):0] req;
wire [(N-1):0] grant;
wire icr_req;
wire tcr_req;
wire tcr_grnt;
wire proc_mwr;
wire proc_p16;
wire proc_p64;
wire proc_4db_req;
wire drop_rcd;
wire proc_pio_err;
wire proc_tcr;
wire proc_dma_rd;
wire proc_dma_rd_1stcl;
wire proc_dma_rd_clrmdr;
wire proc_1db_req;
// >>>>>>>>>>>>>>>>>>>>>>>>> 0-in Checkers <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// ----- ARBITER CHECKER ------------------------------------------
/* 0in arb
-req tcr_req icr_req
-gnt tcr_grnt icr_grnt
-priority
-known_grant
*/
// ----- STATE-MACHINE CHECKERS -----------------------------------
// 0in one_hot -var cur_state
/* 0in state
-var cur_state
-val (13'b1 << IDLE)
-next (13'b1 << IDLE)
(13'b1 << REQ_4DB_WAIT1)
(13'b1 << CPL_4DB_WAIT1)
(13'b1 << CPL_1DB_WAIT1)
(13'b1 << REQ_1DB_WAIT1)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << REQ_4DB_WAIT1)
-next (13'b1 << REQ_4DB_WAIT2)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << REQ_4DB_WAIT2)
-next (13'b1 << REQ_4DB_WAIT2)
(13'b1 << REQ_4DB_ENQ)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << REQ_4DB_ENQ)
-next (13'b1 << IDLE)
-match_by_cycle
*/
//BP n2 6-09-04
/* 0in state
-var cur_state
-val (13'b1 << REQ_1DB_WAIT1)
-next (13'b1 << REQ_1DB_WAIT2)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << REQ_1DB_WAIT2)
-next (13'b1 << REQ_1DB_WAIT2)
(13'b1 << REQ_1DB_ENQ)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << REQ_1DB_ENQ)
-next (13'b1 << IDLE)
-match_by_cycle
*/
//end BP n2 6-09-04
/* 0in state
-var cur_state
-val (13'b1 << CPL_4DB_WAIT1)
-next (13'b1 << CPL_4DB_WAIT2)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << CPL_4DB_WAIT2)
-next (13'b1 << CPL_4DB_WAIT2)
(13'b1 << CPL_4DB_ENQ)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << CPL_4DB_ENQ)
-next (13'b1 << IDLE)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << CPL_1DB_WAIT1)
-next (13'b1 << CPL_1DB_WAIT2)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << CPL_1DB_WAIT2)
-next (13'b1 << CPL_1DB_WAIT2)
(13'b1 << CPL_1DB_ENQ)
-match_by_cycle
*/
/* 0in state
-var cur_state
-val (13'b1 << CPL_1DB_ENQ)
-next (13'b1 << IDLE)
-match_by_cycle
*/
// >>>>>>>>>>>>>>>>>>>>>>>>> RTL Model <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------
// IDLE Checker
// --------------------------------------------------------
assign cmdctlfsm_idle = (cur_state[IDLE] & ~d2j_data_vld &
(mm2cl_tcr_req ~^ cl2mm_tcr_ack));
// --------------------------------------------------------
// Debug Port Logic
// --------------------------------------------------------
// encode one-hot current_state vector for debug port
always @(cur_state[(STATE_NUM - 1):1])
begin
enc_state[0] = (cur_state[1] | cur_state[3] | cur_state[5] |
cur_state[7] | cur_state[9]);
enc_state[1] = (cur_state[2] | cur_state[3] | cur_state[6] |
cur_state[7]);
enc_state[2] = (cur_state[4] | cur_state[5] | cur_state[6] |
cur_state[7]);
enc_state[3] = (cur_state[8] | cur_state[9] | cur_state[10] |
cur_state[11] | cur_state[12]);
end
// output cmdctlfsm debug bus
assign cmdctlfsm_state = enc_state;
// --------------------------------------------------------
// ICR-TCR Priority Arbiter
// --------------------------------------------------------
//BP n2 10-06-04
wire cur_state_no_grnt;
reg proc_pio_err_d;
// assign cur_state_no_grnt = ( d2j_dvld_s3 & ~d2j_dvld_s2);
//BP n2 4-27-05 added in pio err because sio expects data for all pio cpl's
assign cur_state_no_grnt = ( d2j_dvld_s3 & ~d2j_dvld_s2) | (proc_pio_err_d);
// arb req generation
// BP 2-14-05 for N2 dbg quiescing, added ds2cl_stall
assign icr_req = (~icr_fifo_empty && ~ds2cl_stall) && ~cur_state_no_grnt;
assign tcr_req = (mm2cl_tcr_req ^ cl2mm_tcr_ack) & nxt_tag_avail & ~ds2cl_stall;
// assign icr_req = ~icr_fifo_empty && ~cur_state_no_grnt;
// assign tcr_req = (mm2cl_tcr_req ^ cl2mm_tcr_ack) & nxt_tag_avail;
// arb req assignment
assign req = {icr_req, tcr_req};
// simple priority arbiter
assign higher_pri_reqs[N-1:1] = higher_pri_reqs[N-2:0] | req[N-2:0];
assign higher_pri_reqs[0] = 1'b0;
assign grant[N-1:0] = req[N-1:0] & ~higher_pri_reqs[N-1:0];
// arb grant assignment
assign {icr_grnt, tcr_grnt} = grant;
// --------------------------------------------------------
// FSM Control Decode
// --------------------------------------------------------
assign proc_mwr = mwr_vld & ~diu_dma_empty;
assign proc_p16 = pio16_vld & ~diu_pio_empty;
assign proc_p64 = pio64_vld & ~diu_pio_empty;
//BP n2 6-08-04
// assign proc_4db_req = proc_mwr | eqwr_vld | mdo_vld;
assign proc_4db_req = proc_mwr | eqwr_vld ;
assign proc_1db_req = mdo_vld ;
// --------------------------------------------------------
// FSM Next State
// --------------------------------------------------------
// next state assignment
always @(cur_state or icr_grnt or icr_fifo_empty or proc_p16 or proc_p64 or
proc_4db_req or nxt_tag_avail or proc_1db_req)
begin
// initialization
nxt_state = {STATE_NUM{1'b0}};
case (1'b1) // synopsys parallel_case
// 0in < case -full
///////////////////////////////////////////////////////////////////////
// IDLE State
cur_state[IDLE] :
casez ({icr_fifo_empty, proc_p16, proc_p64, proc_4db_req,proc_1db_req})
// 0in < case -parallel -full
5'b1_zzzz,
5'b0_0000 : nxt_state[IDLE] = 1'b1;
5'b0_0010 : nxt_state[REQ_4DB_WAIT1] = 1'b1;
5'b0_0100 : nxt_state[CPL_4DB_WAIT1] = 1'b1;
5'b0_1000 : nxt_state[CPL_1DB_WAIT1] = 1'b1;
5'b0_0001 : nxt_state[REQ_1DB_WAIT1] = 1'b1;
endcase
///////////////////////////////////////////////////////////////////////
// ---------- 4 Data-Beat Request ---------------------------
// REQ_4DB Wait-1 State
cur_state[REQ_4DB_WAIT1] :
nxt_state[REQ_4DB_WAIT2] = 1'b1;
// REQ_4DB Wait-2 State
cur_state[REQ_4DB_WAIT2] :
casez ({icr_grnt, nxt_tag_avail})
// 0in < case -parallel -full
2'b0z,
2'b10 : nxt_state[REQ_4DB_WAIT2] = 1'b1;
2'b11 : nxt_state[REQ_4DB_ENQ] = 1'b1;
endcase
// REQ_4DB Enq State
cur_state[REQ_4DB_ENQ] :
nxt_state[IDLE] = 1'b1;
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// ---------- 1 Data-Beat Request ---------------------------
// REQ_1DB Wait-1 State
cur_state[REQ_1DB_WAIT1] :
nxt_state[REQ_1DB_WAIT2] = 1'b1;
// REQ_1DB Wait-2 State
cur_state[REQ_1DB_WAIT2] :
casez ({icr_grnt, nxt_tag_avail})
// 0in < case -parallel -full
2'b0z,
2'b10 : nxt_state[REQ_1DB_WAIT2] = 1'b1;
2'b11 : nxt_state[REQ_1DB_ENQ] = 1'b1;
endcase
// REQ_4DB Enq State
cur_state[REQ_1DB_ENQ] :
nxt_state[IDLE] = 1'b1;
///////////////////////////////////////////////////////////////////////
// ---------- 4 Data-Beat Completion ------------------------
// CPL_4DB Wait-1 State
cur_state[CPL_4DB_WAIT1] :
nxt_state[CPL_4DB_WAIT2] = 1'b1;
// CPL_4DB Wait-2 State
cur_state[CPL_4DB_WAIT2] :
if (icr_grnt)
nxt_state[CPL_4DB_ENQ] = 1'b1;
else
nxt_state[CPL_4DB_WAIT2] = 1'b1;
// CPL_4DB Enq State
cur_state[CPL_4DB_ENQ] :
nxt_state[IDLE] = 1'b1;
///////////////////////////////////////////////////////////////////////
// ---------- 1 Data-Beat Completion ------------------------
// CPL_1DB Wait-1 State
cur_state[CPL_1DB_WAIT1] :
nxt_state[CPL_1DB_WAIT2] = 1'b1;
// CPL_1DB Wait-2 State
cur_state[CPL_1DB_WAIT2] :
if (icr_grnt)
nxt_state[CPL_1DB_ENQ] = 1'b1;
else
nxt_state[CPL_1DB_WAIT2] = 1'b1;
// CPL_1DB Enq State
cur_state[CPL_1DB_ENQ] :
nxt_state[IDLE] = 1'b1;
///////////////////////////////////////////////////////////////////////
endcase
end
// --------------------------------------------------------
// FSM Current State
// --------------------------------------------------------
// summit state_vector cur_state enum cur_enum
// current state assignment
always @(posedge clk)
if (~rst_l)
begin
cur_state <= {STATE_NUM{1'b0}};
cur_state[IDLE] <= 1'b1;
end
else
cur_state <= nxt_state;
// --------------------------------------------------------
// FSM Output Generation
// --------------------------------------------------------
// ----- process tablewalk request -------------------------
// assign proc_tcr = (tcr_grnt & ~d2j_dvld_s2);
//BP n2 10-06-04
assign proc_tcr = (tcr_grnt & ~d2j_dvld_s3);
// ----- process unsupported request -----------------------
assign proc_uns = ~icr_fifo_empty & uns_vld & uns_req_crdt_avail;
// ----- process dma mem read request ----------------------
// process a valid dma read command record
// assign proc_dma_rd = (icr_grnt & mrd_vld & nxt_tag_avail & ~d2j_dvld_s2);
//BP n2 10-06-04
assign proc_dma_rd = (icr_grnt & mrd_vld & nxt_tag_avail & ~d2j_dvld_s3);
// current dma read is for the first CL of a packet
assign proc_dma_rd_1stcl = (icr_clsts & proc_dma_rd & dou_space_avail);
// current dma read is for a remaining CL of a packet
assign proc_dma_rd_clrmdr = (~icr_clsts & proc_dma_rd);
// process the dma read
assign dma_dptr_req = (proc_dma_rd_1stcl | proc_dma_rd_clrmdr);
// ----- process termination records -----------------------
assign drop_rcd = (~icr_fifo_empty &
((~diu_dma_bufmgmt_bsy & mwr_err) |
(~diu_eqw_bufmgmt_bsy & (eqwr_err | null_vld))));
// ----- process pio cpl errors ----------------------------
// assign proc_pio_err = icr_grnt & pio_err & ~d2j_dvld_s2;
//BP n2 10-06-04
assign proc_pio_err = icr_grnt & pio_err & ~d2j_dvld_s3;
//BP 4-27-05 add an extra cycle after pio err cpl's because sii expects this
always @(posedge clk)
if (~rst_l)
proc_pio_err_d <= 1'b0;
else
proc_pio_err_d <= proc_pio_err;
// ----- generate icr fifo dequeue -------------------------
assign icr_fifo_rd = (nxt_state[REQ_4DB_ENQ] | nxt_state[CPL_4DB_ENQ] |
nxt_state[CPL_1DB_ENQ] | proc_uns | dma_dptr_req |
//BP 4-27-05 nxt_state[REQ_1DB_ENQ] | drop_rcd | proc_pio_err);
nxt_state[REQ_1DB_ENQ] | drop_rcd | proc_pio_err_d);
// ----- ctm control ---------------------------------------
// fetch next tag - update request credits
assign nxt_tag_req = nxt_state[REQ_4DB_ENQ] | nxt_state[REQ_1DB_ENQ] | proc_tcr | dma_dptr_req;
// select for cmd/addr/ctag gen; icr = 1'b0, tcr = 1'b1
assign cmd_req_sel = proc_tcr;
// unsupported request enq
always @(posedge clk)
if (~rst_l)
ctm2crm_rcd_enq <= 1'b0;
else
ctm2crm_rcd_enq <= proc_uns;
// ----- dmc-2-jbc interface control -----------------------
// d2j_cmd_vld : 1 cycle
always @(posedge clk)
if (~rst_l)
d2j_cmd_vld <= 1'b0;
else
d2j_cmd_vld <= (nxt_state[REQ_4DB_ENQ] | nxt_state[CPL_4DB_ENQ] |
nxt_state[CPL_1DB_ENQ] | proc_tcr | dma_dptr_req |
nxt_state[REQ_1DB_ENQ] | proc_pio_err);
// shift reg to generate d2j_data_vld : 1 or 4 cycles
always @(posedge clk)
if (~rst_l)
begin
d2j_dvld_s0 <= 1'b0;
d2j_dvld_s1 <= 1'b0;
d2j_dvld_s2 <= 1'b0;
d2j_dvld_s3 <= 1'b0;
end
else if (nxt_state[REQ_4DB_ENQ] | nxt_state[CPL_4DB_ENQ])
begin // dmawr(full/part), eqwr, mdo, pio64_cpl - 4 cycles
d2j_dvld_s0 <= 1'b1;
d2j_dvld_s1 <= 1'b1;
d2j_dvld_s2 <= 1'b1;
d2j_dvld_s3 <= 1'b1;
end
else if (nxt_state[CPL_1DB_ENQ] | nxt_state[REQ_1DB_ENQ])
begin // pio16_cpl - 1 cycle, and new mondo int's
d2j_dvld_s0 <= 1'b0;
d2j_dvld_s1 <= 1'b0;
d2j_dvld_s2 <= 1'b0;
d2j_dvld_s3 <= 1'b1;
end
else
begin
d2j_dvld_s0 <= 1'b0;
d2j_dvld_s1 <= d2j_dvld_s0;
d2j_dvld_s2 <= d2j_dvld_s1;
d2j_dvld_s3 <= d2j_dvld_s2;
end
// BP n2 5-13-05 create a rd enable for the diu ram for power savings
assign cl2di_rd_en = ~cmdctlfsm_idle; // 0in assert_leader -leader cl2di_rd_en -follower d2j_data_vld -min 2 -max 2
// output d2j_vld to jbc
assign d2j_data_vld = d2j_dvld_s3;
// ----- clu-2-mmu interface control -----------------------
// generate tcr acknowledge
always @(posedge clk)
if (~rst_l)
cl2mm_tcr_ack <= 1'b0;
else if (proc_tcr)
cl2mm_tcr_ack <= ~cl2mm_tcr_ack;
endmodule // dmu_clu_ctm_cmdctlfsm