Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_tmu_dim_datafsm.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: dmu_tmu_dim_datafsm.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_tmu_dim_datafsm (
clk,
rst_l,
// DIU interface
tm2di_wr,
tm2di_addr,
// IMU interface
tm2im_data_enq,
// talk to xfrfsm.v
data_start,
data_done,
// talk to bufmgr.v
diu_dma_full,
dma_cl_req,
dma_cl_inc,
pio_cl_inc,
diu_dma_cl_wptr,
diu_pio_cl_wptr,
// talk to rcdbldr.v
rcd_is_cpld,
rcd_is_msi,
align_addr,
payld_len,
first_dwbe,
last_dwbe,
// talk to datapath.v
idb_rptr_inc,
data_mux_select,
first_dwbe_dp,
last_dwbe_dp,
align_addr_dp,
end_addr_dp,
payld_len_is_one_dp,
ld_saved_data_dp,
// talk to relgen.v
rcd_is_cpld_reg,
// debug
y2k_buf_addr_vld_monitor,
rel_type,
k2y_rel_enq,
low_dbg_sel_a,
low_dbg_sel_b,
datafsm_dbg_a,
datafsm_dbg_b,
// idle check
datafsm_is_idle );
//synopsys sync_set_reset "rst_l"
// >>>>>>>>>>>>>>>>>>>>>>>>> Parameter Declarations <<<<<<<<<<<<<<<<<<<<<<<<<
// states
parameter // summit enum data_enum
IDLE = 0,
MSI = 1,
ZF_PRE_WR = 2,
FRST_VD_WR = 3,
MID_VD_WR = 4,
LST_VD_WR = 5,
ZF_PST_WR = 6,
WAIT = 7;
// state number
parameter STATE_NUM = 8;
// data_mux_select
parameter ONLY_VDB = 0,
LAST_VDB = 1,
MID_VDB = 2,
FRST_VDB = 3,
ZERO_FILL = 4;
// data_mux_select number
parameter DATA_MUX_NUM = 5;
// >>>>>>>>>>>>>>>>>>>>>>>>> Port Declarations <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//------------------------------------------------------------------------
// Clock and Reset Signals
//------------------------------------------------------------------------
input clk;
input rst_l;
//------------------------------------------------------------------------
// DIU interface
//------------------------------------------------------------------------
output tm2di_wr;
output [`FIRE_DLC_TRD_ADDR_WDTH-1:0] tm2di_addr; // DIU address
//------------------------------------------------------------------------
// IMU interface
//------------------------------------------------------------------------
output tm2im_data_enq;
//------------------------------------------------------------------------
// talk to xfrfsm.v
//------------------------------------------------------------------------
input data_start;
output data_done; // to bufmgr.v also
//------------------------------------------------------------------------
// talk to bufmgr.v
//------------------------------------------------------------------------
input diu_dma_full;
output dma_cl_req;
output dma_cl_inc;
output pio_cl_inc;
input [`FIRE_DLC_DMA_WPTR_WDTH-2:0] diu_dma_cl_wptr;
input [`FIRE_DLC_PIO_WPTR_WDTH-2:0] diu_pio_cl_wptr;
//------------------------------------------------------------------------
// talk to rcdbldr.v
//------------------------------------------------------------------------
input rcd_is_msi;
input rcd_is_cpld;
input [5:2] align_addr;
input [7:0] payld_len; // only 8-bit due to max. MPS = 512B,
// the possible max. value is 8'b10000000.
input [3:0] first_dwbe;
input [3:0] last_dwbe;
//------------------------------------------------------------------------
// talk to datapath.v
//------------------------------------------------------------------------
output idb_rptr_inc;
output [DATA_MUX_NUM-1:0] data_mux_select;
output [3:0] first_dwbe_dp;
output [3:0] last_dwbe_dp;
output [3:2] align_addr_dp;
output [3:2] end_addr_dp;
output payld_len_is_one_dp;
output ld_saved_data_dp;
//------------------------------------------------------------------------
// talk to relgen.v
//------------------------------------------------------------------------
output rcd_is_cpld_reg;
//------------------------------------------------------------------------
// debug
//------------------------------------------------------------------------
input y2k_buf_addr_vld_monitor;
input rel_type;
input k2y_rel_enq;
input [2:0] low_dbg_sel_a;
input [2:0] low_dbg_sel_b;
output [`FIRE_DBG_DATA_BITS] datafsm_dbg_a;
output [`FIRE_DBG_DATA_BITS] datafsm_dbg_b;
//------------------------------------------------------------------------
// idle check
//------------------------------------------------------------------------
output datafsm_is_idle;
// >>>>>>>>>>>>>>>>>>>>>>>>> Data Type Declarations <<<<<<<<<<<<<<<<<<<<<<<<<
// ~~~~~~~~~~~~~~~~~~~~~~~~~ REGISTER - FLOPS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
reg [3:0] first_dwbe_reg;
reg [3:0] last_dwbe_reg;
reg [5:2] align_addr_reg;
reg [3:2] end_addr_reg;
reg rcd_is_cpld_reg;
reg payld_len_is_one_reg;
reg [1:0] diu_addr_low;
reg [5:0] num_wrs;
reg [5:0] num_rds;
reg [5:0] num_vd_wrs;
reg only_one_vd_wr_reg;
reg diu_wr_ps1;
reg msi_wr_ps1;
reg [`FIRE_DLC_TRD_ADDR_WDTH-1:0] diu_wr_addr_ps1;
reg [DATA_MUX_NUM-1:0] data_mux_sel_ps1;
reg diu_wr_ps2;
reg msi_wr_ps2;
reg [`FIRE_DLC_TRD_ADDR_WDTH-1:0] diu_wr_addr_ps2;
reg [DATA_MUX_NUM-1:0] data_mux_sel_ps2;
reg diu_wr_ps3;
reg [`FIRE_DLC_TRD_ADDR_WDTH-1:0] diu_wr_addr_ps3;
reg [3:0] first_dwbe_ps1;
reg [3:0] last_dwbe_ps1;
reg [3:2] align_addr_ps1;
reg [3:2] end_addr_ps1;
reg payld_len_is_one_ps1;
reg ld_saved_data_ps1;
reg [3:0] first_dwbe_ps2;
reg [3:0] last_dwbe_ps2;
reg [3:2] align_addr_ps2;
reg [3:2] end_addr_ps2;
reg payld_len_is_one_ps2;
reg ld_saved_data_ps2;
reg [STATE_NUM-1:0] data_state; // 0in one_hot
reg [`FIRE_DBG_DATA_BITS] dbg_bus [0:1];
// ~~~~~~~~~~~~~~~~~~~~~~~~~ REGISTER - NON-FLOPS ~~~~~~~~~~~~~~~~~~~~~~~~
reg diu_vd_wr_inc;
reg idb_rptr_inc;
reg diu_wr_ne0;
reg msi_wr_ne0;
reg [DATA_MUX_NUM-1:0] data_mux_sel_ne0 ;
reg data_done;
reg [STATE_NUM-1:0] n_data_state;
reg [`FIRE_DBG_DATA_BITS] nxt_dbg_bus [0:1];
reg [2:0] dbg_sel [0:1];
// ~~~~~~~~~~~~~~~~~~~~~~~~~ NETS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wire dw_carry;
wire init_num_cls_inc;
wire init_num_vd_wrs_inc;
wire init_num_rds_inc;
wire [5:2] end_addr;
wire [7:0] new_len_claligned; // possible max. value is 8'b10001111
wire [7:0] new_len_dwaligned; // possible max. value is 8'b10000011
wire [3:0] init_num_cls; // possible max. value is 4'b1001
wire [5:0] init_num_wrs; // possible max. value is 6'b100100
wire [5:0] init_num_rds; // possible max. value is 6'b100000
wire [5:0] init_num_vd_wrs; // possible max. value is 6'b100001
wire [5:2] align_addr_cur;
wire rcd_is_cpld_cur;
wire [5:0] diu_cl_addr;
wire [`FIRE_DLC_TRD_ADDR_WDTH-1:0] diu_wr_addr_ne0;
wire [3:0] first_dwbe_ne0;
wire [3:0] last_dwbe_ne0;
wire [3:2] align_addr_ne0;
wire [3:2] end_addr_ne0;
wire payld_len_is_one_ne0;
wire ld_saved_data_ne0;
wire only_one_vd_wr;
wire diu_no_space;
wire frst_vd_wr;
wire last_vd_wr;
wire more_vd_wrs;
wire last_wr;
wire more_wrs;
wire more_rds;
wire only_one_rd;
wire last_rd ;
wire end_of_cl;
wire diu_cl_req;
wire diu_cl_inc;
wire payld_len_is_one;
integer i;
integer j;
// >>>>>>>>>>>>>>>>>>>>>>>>> Zero In Checkers <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 0in bits_on -var data_mux_select -max 1
// 0in max -var new_len_claligned -val 8'b10001111 -active data_start
// 0in max -var new_len_dwaligned -val 8'b10000011 -active data_start
// 0in max -var init_num_cls -val 4'b1001 -active data_start
// 0in max -var init_num_wrs -val 6'b100100 -active data_start
// 0in max -var init_num_rds -val 6'b100000 -active data_start
// 0in max -var init_num_vd_wrs -val 6'b100001 -active data_start
/* 0in state -var data_state -val (8'b1 << IDLE) -next
(8'b1 << IDLE)
(8'b1 << MSI)
(8'b1 << ZF_PRE_WR)
(8'b1 << FRST_VD_WR) */
/* 0in state -var data_state -val (8'b1 << MSI) -next
(8'b1 << MSI)
(8'b1 << IDLE) */
/* 0in state -var data_state -val (8'b1 << ZF_PRE_WR) -next
(8'b1 << ZF_PRE_WR)
(8'b1 << FRST_VD_WR) */
/* 0in state -var data_state -val (8'b1 << FRST_VD_WR) -next
(8'b1 << IDLE)
(8'b1 << MSI)
(8'b1 << ZF_PRE_WR)
(8'b1 << FRST_VD_WR)
(8'b1 << WAIT)
(8'b1 << MID_VD_WR)
(8'b1 << LST_VD_WR)
(8'b1 << ZF_PST_WR) */
/* 0in state -var data_state -val (8'b1 << MID_VD_WR) -next
(8'b1 << MID_VD_WR)
(8'b1 << WAIT)
(8'b1 << LST_VD_WR) */
/* 0in state -var data_state -val (8'b1 << LST_VD_WR) -next
(8'b1 << IDLE)
(8'b1 << MSI)
(8'b1 << ZF_PRE_WR)
(8'b1 << FRST_VD_WR)
(8'b1 << ZF_PST_WR) */
/* 0in state -var data_state -val (8'b1 << ZF_PST_WR) -next
(8'b1 << ZF_PST_WR)
(8'b1 << IDLE)
(8'b1 << MSI)
(8'b1 << ZF_PRE_WR)
(8'b1 << FRST_VD_WR) */
/* 0in state -var data_state -val (8'b1 << WAIT) -next
(8'b1 << WAIT)
(8'b1 << MID_VD_WR)
(8'b1 << LST_VD_WR) */
// >>>>>>>>>>>>>>>>>>>>>>>>> Function Declarations <<<<<<<<<<<<<<<<<<<<<<<<<<
function [STATE_NUM + DATA_MUX_NUM + 4 : 0] data_start_handling;
input rcd_is_msi;
input frst_vd_wr;
input only_one_rd;
input only_one_vd_wr;
reg [STATE_NUM-1:0] n_state;
reg [DATA_MUX_NUM-1:0] data_mux_sel;
reg diu_wr_ne0;
reg msi_wr_ne0;
reg idb_rptr_inc;
reg diu_vd_wr_inc;
reg data_done;
begin
n_state = {STATE_NUM{1'b0}};
data_mux_sel = {DATA_MUX_NUM{1'b0}};
diu_wr_ne0 = 1'b0;
msi_wr_ne0 = 1'b0;
idb_rptr_inc = 1'b0;
diu_vd_wr_inc = 1'b0;
data_done = 1'b0;
if (rcd_is_msi) begin
msi_wr_ne0 = 1'b1;
idb_rptr_inc = 1'b1;
if (only_one_rd) begin
n_state[IDLE] = 1'b1;
data_done = 1'b1;
end
else begin
n_state[MSI] = 1'b1;
end
end
else begin
if (frst_vd_wr) begin
n_state[FRST_VD_WR] = 1'b1;
diu_wr_ne0 = 1'b1;
idb_rptr_inc = 1'b1;
diu_vd_wr_inc = 1'b1;
if (only_one_vd_wr) data_mux_sel[ONLY_VDB] = 1'b1;
else data_mux_sel[FRST_VDB] = 1'b1;
end
else begin
n_state[ZF_PRE_WR] = 1'b1;
diu_wr_ne0 = 1'b1;
data_mux_sel[ZERO_FILL] = 1'b1;
end
end
data_start_handling = {n_state, data_mux_sel, diu_wr_ne0,
msi_wr_ne0, idb_rptr_inc, diu_vd_wr_inc, data_done};
end
endfunction // data_start_handling
// >>>>>>>>>>>>>>>>>>>>>>>>> RTL/Behavioral Model <<<<<<<<<<<<<<<<<<<<<<<<<<<
//---------------------------------------------------------------------
// mux out diu_cl_addr
//---------------------------------------------------------------------
assign rcd_is_cpld_cur = data_start ? rcd_is_cpld : rcd_is_cpld_reg;
//BP n2 6-23-04
// assign diu_cl_addr = rcd_is_cpld_cur ? {2'b10, diu_pio_cl_wptr[3:0]}
assign diu_cl_addr = rcd_is_cpld_cur ? {2'b10, 2'b00, diu_pio_cl_wptr[3:2]}
: {1'b0, diu_dma_cl_wptr[4:0]};
//---------------------------------------------------------------------
// computing some initial values
//---------------------------------------------------------------------
assign new_len_claligned = payld_len + {4'b0, align_addr};
assign end_addr = new_len_claligned[3:0];
assign {dw_carry, new_len_dwaligned[1:0]} = {1'b0, payld_len[1:0]} +
{1'b0, align_addr[3:2]};
assign new_len_dwaligned[7:2] = dw_carry ? (payld_len[7:2] + 1'b1) :
payld_len[7:2];
assign init_num_cls_inc = |end_addr;
assign init_num_cls = init_num_cls_inc ? (new_len_claligned[7:4] + 1'b1) :
new_len_claligned[7:4];
assign init_num_wrs = {init_num_cls, 2'b00};
assign init_num_rds_inc = |payld_len[1:0];
assign init_num_rds = init_num_rds_inc ? (payld_len[7:2] + 1'b1) :
payld_len[7:2];
assign init_num_vd_wrs_inc = |new_len_dwaligned[1:0];
assign init_num_vd_wrs = init_num_vd_wrs_inc ? (new_len_dwaligned[7:2] + 1'b1) :
new_len_dwaligned[7:2];
//---------------------------------------------------------------------
// flops to lock data transfer rcd info
//---------------------------------------------------------------------
assign only_one_vd_wr = (~(|init_num_vd_wrs[5:1])) & init_num_vd_wrs[0];
assign payld_len_is_one = payld_len[0] & (~(|payld_len[7:1]));
always @ (posedge clk)
if(~rst_l) begin
rcd_is_cpld_reg <= 1'b0;
align_addr_reg <= 4'b0;
end_addr_reg <= 2'b0;
first_dwbe_reg <= 4'b0;
last_dwbe_reg <= 4'b0;
only_one_vd_wr_reg <= 1'b0;
payld_len_is_one_reg <= 1'b0;
end
else if (data_start)
begin
rcd_is_cpld_reg <= rcd_is_cpld;
align_addr_reg <= align_addr;
end_addr_reg <= end_addr[3:2];
first_dwbe_reg <= first_dwbe;
last_dwbe_reg <= last_dwbe;
only_one_vd_wr_reg <= only_one_vd_wr;
payld_len_is_one_reg <= payld_len_is_one;
end
//---------------------------------------------------------------------
// flops to keep track of data movement
//---------------------------------------------------------------------
// num_wrs
always @ (posedge clk)
if(~rst_l) begin
num_wrs <= 6'b0;
end
else begin
//BP n2 6-24-04
// if (data_start) begin
if (data_start && ~rcd_is_cpld) begin
num_wrs <= init_num_wrs - 1'b1;
end
//BP n2 6-24-04
// else if (diu_wr_ne0) begin
else if (diu_wr_ne0 & ~rcd_is_cpld_cur) begin
num_wrs <= num_wrs - 1'b1;
end
end
// num_rds
always @ (posedge clk)
if(~rst_l) begin
num_rds <= 6'b0;
end
else begin
if (data_start) begin
if (idb_rptr_inc) num_rds <= init_num_rds - 1'b1;
else num_rds <= init_num_rds;
end
else if (idb_rptr_inc) num_rds <= num_rds - 1'b1;
end
// num_vd_wrs
always @ (posedge clk)
if(~rst_l) begin
num_vd_wrs <= 6'b0;
end
else begin
if (data_start) begin
if (diu_vd_wr_inc) num_vd_wrs <= init_num_vd_wrs - 1'b1;
else num_vd_wrs <= init_num_vd_wrs;
end
else if (diu_vd_wr_inc) num_vd_wrs <= num_vd_wrs - 1'b1;
end
// 2-bit LSB diu_addr_low which is appended to diu_cl_addr to form tm2di_addr
always @ (posedge clk)
begin
if (!rst_l) begin
diu_addr_low <= 2'b0;
end
//BP n2 6-24-04
// else if (diu_wr_ne0) diu_addr_low <= diu_addr_low + 1'b1;
else if (diu_wr_ne0 & ~rcd_is_cpld_cur) diu_addr_low <= diu_addr_low + 1'b1;
end
//---------------------------------------------------------------------
// FSM
//---------------------------------------------------------------------
// summit state_vector data_state enum data_enum
// present state
always @ (posedge clk)
if (!rst_l) begin
data_state <= {STATE_NUM{1'b0}};
data_state[IDLE] <= 1'b1;
end
else
data_state <= n_data_state;
// next state logic
//BP n2 6-23-04
wire [1:0] diu_addr_low_2;
assign diu_addr_low_2 = rcd_is_cpld_cur ? diu_pio_cl_wptr[1:0] : diu_addr_low;
assign diu_wr_addr_ne0 = {diu_cl_addr, diu_addr_low_2};
assign diu_no_space = (~rcd_is_cpld_reg) & diu_dma_full;
assign align_addr_cur = data_start ? align_addr : align_addr_reg;
assign frst_vd_wr = (align_addr_cur[5:4] == diu_addr_low);
assign last_vd_wr = (~(|num_vd_wrs[5:1])) & num_vd_wrs[0];
assign more_vd_wrs = |num_vd_wrs;
assign last_wr = (~(|num_wrs[5:1])) & num_wrs[0];
assign more_wrs = |num_wrs;
assign more_rds = |num_rds;
assign only_one_rd = (~(|init_num_rds[5:1])) & init_num_rds[0];
assign last_rd = (~(|num_rds[5:1])) & num_rds[0];
assign end_of_cl = ~(|diu_addr_low);
always @ (data_state or data_start or diu_no_space or
rcd_is_msi or only_one_vd_wr or only_one_vd_wr_reg or
frst_vd_wr or last_vd_wr or more_vd_wrs or
last_wr or more_wrs or more_rds or
only_one_rd or last_rd or end_of_cl or rcd_is_cpld_cur )
begin
n_data_state = {STATE_NUM{1'b0}};
data_mux_sel_ne0 = {DATA_MUX_NUM{1'b0}};
diu_wr_ne0 = 1'b0;
msi_wr_ne0 = 1'b0;
idb_rptr_inc = 1'b0;
diu_vd_wr_inc = 1'b0;
data_done = 1'b0;
case (1'b1) // 0in < case -parallel -full // synopsys parallel_case
data_state[IDLE] :
if (data_start) begin
{n_data_state,
data_mux_sel_ne0,
diu_wr_ne0,
msi_wr_ne0,
idb_rptr_inc,
diu_vd_wr_inc,
data_done} = data_start_handling (rcd_is_msi,
frst_vd_wr,
only_one_rd,
only_one_vd_wr);
end
else n_data_state[IDLE] = 1'b1;
data_state[MSI] :
begin
idb_rptr_inc = 1'b1;
if (last_rd) begin
n_data_state[IDLE] = 1'b1;
data_done = 1'b1;
end
else n_data_state[MSI] = 1'b1;
end
data_state[ZF_PRE_WR] :
begin
diu_wr_ne0 = 1'b1;
data_done = last_wr;
if (frst_vd_wr) begin
n_data_state[FRST_VD_WR] = 1'b1;
idb_rptr_inc = 1'b1;
diu_vd_wr_inc = 1'b1;
if (only_one_vd_wr_reg) data_mux_sel_ne0[ONLY_VDB] = 1'b1;
else data_mux_sel_ne0[FRST_VDB] = 1'b1;
end
else begin
n_data_state[ZF_PRE_WR] = 1'b1;
data_mux_sel_ne0[ZERO_FILL] = 1'b1;
end
end
data_state[FRST_VD_WR] :
begin
if (data_start) begin
{n_data_state,
data_mux_sel_ne0,
diu_wr_ne0,
msi_wr_ne0,
idb_rptr_inc,
diu_vd_wr_inc,
data_done} = data_start_handling (rcd_is_msi,
frst_vd_wr,
only_one_rd,
only_one_vd_wr);
end
else begin
data_done = last_wr;
if (more_wrs & end_of_cl & diu_no_space) begin
n_data_state[WAIT] = 1'b1;
end
else begin
if (more_vd_wrs) begin
diu_wr_ne0 = 1'b1;
diu_vd_wr_inc = 1'b1;
idb_rptr_inc = more_rds;
if (last_vd_wr) begin
n_data_state[LST_VD_WR] = 1'b1;
data_mux_sel_ne0[LAST_VDB] = 1'b1;
end
else begin
n_data_state[MID_VD_WR] = 1'b1;
data_mux_sel_ne0[MID_VDB] = 1'b1;
end
end
//BP n2 6-24-04
// else if (more_wrs) begin
else if (more_wrs && ~rcd_is_cpld_cur) begin
diu_wr_ne0 = 1'b1;
n_data_state[ZF_PST_WR] = 1'b1;
data_mux_sel_ne0[ZERO_FILL] = 1'b1;
end
//BP n2 6-24-04
// else begin
// n_data_state[IDLE] = 1'b1;
else if (rcd_is_cpld_cur) begin
data_done = 1'b1;
n_data_state[IDLE] = 1'b1;
end
else begin
n_data_state[IDLE] = 1'b1;
end
end
end // else: !if(data_start)
end // case: data_state[FRST_VD_WR]
data_state[MID_VD_WR] :
begin
if (end_of_cl & diu_no_space) begin
n_data_state[WAIT] = 1'b1;
end
else begin
diu_wr_ne0 = 1'b1;
diu_vd_wr_inc = 1'b1;
idb_rptr_inc = more_rds;
data_done = last_wr;
if (last_vd_wr) begin
n_data_state[LST_VD_WR] = 1'b1;
data_mux_sel_ne0[LAST_VDB] = 1'b1;
end
else begin
n_data_state[MID_VD_WR] = 1'b1;
data_mux_sel_ne0[MID_VDB] = 1'b1;
end
end
end
data_state[LST_VD_WR] :
begin
if (data_start) begin
{n_data_state,
data_mux_sel_ne0,
diu_wr_ne0,
msi_wr_ne0,
idb_rptr_inc,
diu_vd_wr_inc,
data_done} = data_start_handling (rcd_is_msi,
frst_vd_wr,
only_one_rd,
only_one_vd_wr);
end
else begin
if (more_wrs) begin
data_done = last_wr;
diu_wr_ne0 = 1'b1;
n_data_state[ZF_PST_WR] = 1'b1;
data_mux_sel_ne0[ZERO_FILL] = 1'b1;
end
else begin
n_data_state[IDLE] = 1'b1;
end
end
end
data_state[ZF_PST_WR] :
begin
if (data_start) begin
{n_data_state,
data_mux_sel_ne0,
diu_wr_ne0,
msi_wr_ne0,
idb_rptr_inc,
diu_vd_wr_inc,
data_done} = data_start_handling (rcd_is_msi,
frst_vd_wr,
only_one_rd,
only_one_vd_wr);
end
else if (more_wrs) begin
data_done = last_wr;
diu_wr_ne0 = 1'b1;
n_data_state[ZF_PST_WR] = 1'b1;
data_mux_sel_ne0[ZERO_FILL] = 1'b1;
end
else begin
n_data_state[IDLE] = 1'b1;
end
end
data_state[WAIT] :
begin
if (diu_no_space) begin
n_data_state[WAIT] = 1'b1;
end
else begin
diu_wr_ne0 = 1'b1;
idb_rptr_inc = more_rds;
diu_vd_wr_inc = 1'b1;
if (last_vd_wr) begin
n_data_state[LST_VD_WR] = 1'b1;
data_mux_sel_ne0[LAST_VDB] = 1'b1;
end
else begin
n_data_state[MID_VD_WR] = 1'b1;
data_mux_sel_ne0[MID_VDB] = 1'b1;
end
end
end
endcase // case(1'b1)
end // always @ (data_state or data_start or diu_no_space or...
//---------------------------------------------------------------------
// data control pipeline
//---------------------------------------------------------------------
always @ (posedge clk)
if (!rst_l) begin
diu_wr_ps1 <= 1'b0;
msi_wr_ps1 <=1'b0;
diu_wr_addr_ps1 <= {`FIRE_DLC_TRD_ADDR_WDTH{1'b0}};
data_mux_sel_ps1 <= {DATA_MUX_NUM{1'b0}};
diu_wr_ps2 <= 1'b0;
msi_wr_ps2 <= 1'b0;
diu_wr_addr_ps2 <= {`FIRE_DLC_TRD_ADDR_WDTH{1'b0}};
data_mux_sel_ps2 <= {DATA_MUX_NUM{1'b0}};
diu_wr_ps3 <= 1'b0;
diu_wr_addr_ps3 <= {`FIRE_DLC_TRD_ADDR_WDTH{1'b0}};
end
else begin
//BP n2 6-24-04 only 1 write for PIO's now, n2 limits PIO's to 16 bytes
// diu_wr_ps1 <= diu_wr_ne0;
diu_wr_ps1 <= (diu_wr_ne0 && ~rcd_is_cpld_cur) | (rcd_is_cpld_cur & data_start);
msi_wr_ps1 <= msi_wr_ne0;
diu_wr_addr_ps1 <= diu_wr_addr_ne0;
data_mux_sel_ps1 <= data_mux_sel_ne0;
diu_wr_ps2 <= diu_wr_ps1;
msi_wr_ps2 <= msi_wr_ps1;
diu_wr_addr_ps2 <= diu_wr_addr_ps1;
data_mux_sel_ps2 <= data_mux_sel_ps1;
diu_wr_ps3 <= diu_wr_ps2;
diu_wr_addr_ps3 <= diu_wr_addr_ps2;
end
assign first_dwbe_ne0 = data_start ? first_dwbe : first_dwbe_reg;
assign last_dwbe_ne0 = data_start ? last_dwbe : last_dwbe_reg;
assign align_addr_ne0 = align_addr_cur[3:2];
assign end_addr_ne0 = data_start ? end_addr[3:2] : end_addr_reg;
assign payld_len_is_one_ne0 = data_start ? payld_len_is_one : payld_len_is_one_reg;
assign ld_saved_data_ne0 = ~n_data_state[WAIT];
always @ (posedge clk)
if(~rst_l) begin
first_dwbe_ps1 <= 4'b0;
last_dwbe_ps1 <= 4'b0;
align_addr_ps1 <= 2'b0;
end_addr_ps1 <= 2'b0;
payld_len_is_one_ps1 <= 1'b0;
ld_saved_data_ps1 <= 1'b0;
first_dwbe_ps2 <= 4'b0;
last_dwbe_ps2 <= 4'b0;
align_addr_ps2 <= 2'b0;
end_addr_ps2 <= 2'b0;
payld_len_is_one_ps2 <= 1'b0;
ld_saved_data_ps2 <= 1'b0;
end
else begin
first_dwbe_ps1 <= first_dwbe_ne0;
last_dwbe_ps1 <= last_dwbe_ne0;
align_addr_ps1 <= align_addr_ne0;
end_addr_ps1 <= end_addr_ne0;
payld_len_is_one_ps1 <= payld_len_is_one_ne0;
ld_saved_data_ps1 <= ld_saved_data_ne0;
first_dwbe_ps2 <= first_dwbe_ps1;
last_dwbe_ps2 <= last_dwbe_ps1;
align_addr_ps2 <= align_addr_ps1;
end_addr_ps2 <= end_addr_ps1;
payld_len_is_one_ps2 <= payld_len_is_one_ps1;
ld_saved_data_ps2 <= ld_saved_data_ps1;
end
//---------------------------------------------------------------------
// outputs
//---------------------------------------------------------------------
assign diu_cl_req = (diu_addr_low == 2'b01); // asserted at 2nd wr in a cache line
assign diu_cl_inc = (diu_addr_low == 2'b11); // asserted at 4th wr in a cache line
assign dma_cl_req = (~rcd_is_cpld_reg) & diu_cl_req;
assign dma_cl_inc = (~rcd_is_cpld_reg) & diu_cl_inc;
//BP n2 6-24-04
// assign pio_cl_inc = rcd_is_cpld_reg & diu_cl_inc;
assign pio_cl_inc = rcd_is_cpld & data_start;
assign tm2di_addr = diu_wr_addr_ps3;
assign tm2im_data_enq = msi_wr_ps2;
assign tm2di_wr = diu_wr_ps3;
assign data_mux_select = data_mux_sel_ps2;
assign align_addr_dp = align_addr_ps2;
assign end_addr_dp = end_addr_ps2;
assign first_dwbe_dp = first_dwbe_ps2;
assign last_dwbe_dp = last_dwbe_ps2;
assign payld_len_is_one_dp = payld_len_is_one_ps2;
assign ld_saved_data_dp = ld_saved_data_ps2;
//---------------------------------------------------------------------
// debug
//---------------------------------------------------------------------
always @ (low_dbg_sel_a or low_dbg_sel_b) begin
dbg_sel[0] = low_dbg_sel_a;
dbg_sel[1] = low_dbg_sel_b;
end
always @ (dbg_sel[0] or dbg_sel[1] or data_state or data_start
or data_done or diu_dma_full or idb_rptr_inc or diu_vd_wr_inc
or num_rds or num_wrs or num_vd_wrs or last_rd
or last_wr or more_rds or more_wrs or align_addr_cur
or rcd_is_cpld_cur or rcd_is_msi
or rel_type or k2y_rel_enq or y2k_buf_addr_vld_monitor)
begin
for (i = 0; i < 2; i = i + 1) begin
case (dbg_sel[i]) // synopsys infer_mux
3'b000: nxt_dbg_bus[i] = data_state;
3'b001: nxt_dbg_bus[i] = {num_rds, last_rd, more_rds};
3'b010: nxt_dbg_bus[i] = {num_wrs, last_wr, more_wrs};
3'b011: nxt_dbg_bus[i] = {num_vd_wrs, data_start, data_done};
3'b100: nxt_dbg_bus[i] = {5'b0, idb_rptr_inc, diu_vd_wr_inc, diu_dma_full};
3'b101: nxt_dbg_bus[i] = {2'b0, align_addr_cur, rcd_is_cpld_cur, rcd_is_msi};
3'b110: nxt_dbg_bus[i] = {5'b0, y2k_buf_addr_vld_monitor, rel_type, k2y_rel_enq};
3'b111: nxt_dbg_bus[i] = 8'h00;
endcase
end
end
assign datafsm_dbg_a = dbg_bus[0];
assign datafsm_dbg_b = dbg_bus[1];
always @ (posedge clk)
if(~rst_l) begin : dbg_rst
// integer i;
for (i = 0; i < 2; i = i + 1) begin
dbg_bus[i] <= 8'h00;
end
end
else begin
for (j = 0; j < 2; j = j + 1) begin
dbg_bus[j] <= nxt_dbg_bus[j];
end
end
//---------------------------------------------------------------------
// debug
//---------------------------------------------------------------------
assign datafsm_is_idle = data_state[IDLE];
// >>>>>>>>>>>>>>>>>>>>>>>>> Instantiations <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
endmodule // dmu_tmu_dim_datafsm