Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / niu_rdmc_fetch_desp_sm.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: niu_rdmc_fetch_desp_sm.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 niu_rdmc_fetch_desp_sm (
clk,
reset,
dma_chnl_grp_id,
dma_reset,
dma_fatal_err,
fetch_desp_trig,
fetch_desp_num,
desp_init_valid,
fetch_desp_gnt,
rdmc_resp_rdy_valid,
rdmc_req_err,
rdmc_resp_cmd,
rdmc_resp_cmd_status,
rdmc_resp_data_status,
rdmc_resp_dma_num,
rdmc_resp_data_valid,
rdmc_resp_byteenable,
rdmc_resp_comp,
rdmc_resp_trans_comp,
resp_data_in_process,
fetch_desp_req,
rdmc_resp_accept_sm, //use rdmc_resp_accept if timing
fetch_desp_resp_vld,
fetch_desp_req_sm,
fetch_desp_pre_done,
fetch_desp_done,
resp_bus_err,
resp_bus_err_type,
rbr_idle_cycle
);
input clk;
input reset;
input[4:0] dma_chnl_grp_id;
input dma_reset;
input dma_fatal_err;
input fetch_desp_trig;
input[4:0] fetch_desp_num;
input desp_init_valid;
input fetch_desp_gnt;
input rdmc_resp_rdy_valid;
input rdmc_req_err;
input[4:0] rdmc_resp_cmd;
input[3:0] rdmc_resp_cmd_status;
input[3:0] rdmc_resp_data_status;
input[4:0] rdmc_resp_dma_num;
input rdmc_resp_data_valid;
input[15:0] rdmc_resp_byteenable;
input rdmc_resp_comp;
input rdmc_resp_trans_comp;
input resp_data_in_process;
output fetch_desp_req;
output rdmc_resp_accept_sm;
output fetch_desp_resp_vld;
output fetch_desp_req_sm;
output fetch_desp_pre_done;
output fetch_desp_done;
output resp_bus_err;
output[3:0] resp_bus_err_type;
output rbr_idle_cycle;
reg rbr_idle_cycle;
reg fetch_desp_req_sm;
reg rdmc_resp_accept_sm;
reg fetch_desp_resp_valid_sm;
reg resp_cmd_err;
reg fetch_desp_pre_done;
reg fetch_desp_done;
reg[2:0] next_state;
reg[2:0] state;
reg fetch_desp_req;
//reg rdmc_resp_accept;
reg fetch_desp_resp_vld;
reg[2:0] valid_addr_cnt;
reg[4:0] resp_data_cnt;
reg valid_bit_err;
reg valid_bit_err_r;
reg resp_data_err;
wire vaild_bit0;
wire vaild_bit1;
wire vaild_bit2;
wire vaild_bit3;
wire[3:0] vaild_bit_array;
wire valid_bit_err0;
wire valid_bit_err1;
wire valid_bit_err2;
wire valid_bit_err3;
wire valid_bit_err_tmp;
wire resp_data_cnt_err;
wire resp_bus_err;
wire[3:0] resp_bus_err_type;
wire resp_id_match = (dma_chnl_grp_id == rdmc_resp_dma_num);
wire rdmc_resp_cmd_err = (rdmc_resp_cmd_status == 4'b1111) | !(rdmc_resp_cmd[4:0] == 5'b00101);
parameter
IDLE = 3'b000,
DESP_REQ = 3'b001,
DESP_RESP1 = 3'b010,
DESP_RESP_DATA1 = 3'b011,
DESP_RESP2 = 3'b100,
DESP_RESP_DATA2 = 3'b101,
DESP_RESP_DONE = 3'b110,
RESP_ERR = 3'b111;
always @ (state or
desp_init_valid or fetch_desp_trig or
fetch_desp_gnt or rdmc_resp_rdy_valid or
rdmc_resp_comp or rdmc_resp_trans_comp or
resp_data_in_process or resp_id_match or
dma_fatal_err or rdmc_req_err or rdmc_resp_cmd_err)
begin
rbr_idle_cycle = 1'b0;
fetch_desp_req_sm = 1'b0;
rdmc_resp_accept_sm = 1'b0;
fetch_desp_resp_valid_sm= 1'b0;
resp_cmd_err = 1'b0;
fetch_desp_pre_done = 1'b0;
fetch_desp_done = 1'b0;
next_state = 3'b0;
case (state) //synopsys parallel_case full_case
IDLE:
begin
rbr_idle_cycle = 1'b1;
if (desp_init_valid & !dma_fatal_err)
begin
if (fetch_desp_trig)
begin
fetch_desp_req_sm = 1'b1;
next_state = DESP_REQ;
end
else
next_state = state;
end
else
next_state = state;
end
DESP_REQ:
begin
if (fetch_desp_gnt)
next_state = DESP_RESP1;
else
next_state = state;
end
DESP_RESP1:
begin
if (resp_data_in_process)
begin
rdmc_resp_accept_sm = 1'b0;
fetch_desp_resp_valid_sm = 1'b0;
next_state = state;
end
else if (rdmc_req_err)
begin
rdmc_resp_accept_sm = 1'b0;
fetch_desp_resp_valid_sm = 1'b0;
next_state = RESP_ERR;
end
else if (rdmc_resp_rdy_valid & resp_id_match & rdmc_resp_cmd_err)
begin
rdmc_resp_accept_sm = 1'b1;
fetch_desp_resp_valid_sm = 1'b0;
next_state = RESP_ERR;
end
else if (rdmc_resp_rdy_valid & resp_id_match)
begin
rdmc_resp_accept_sm = 1'b1;
fetch_desp_resp_valid_sm = 1'b1;
next_state = DESP_RESP_DATA1;
end
else
next_state = state;
end
DESP_RESP_DATA1:
begin
if (rdmc_resp_comp & rdmc_resp_trans_comp)
begin
fetch_desp_pre_done = 1'b1;
next_state = DESP_RESP_DONE;
end
else if (rdmc_resp_comp)
next_state = DESP_RESP2;
else
next_state = state;
end
DESP_RESP2:
begin
if (resp_data_in_process)
begin
rdmc_resp_accept_sm = 1'b0;
fetch_desp_resp_valid_sm = 1'b0;
next_state = state;
end
else if (rdmc_resp_rdy_valid & resp_id_match & rdmc_resp_cmd_err)
begin
rdmc_resp_accept_sm = 1'b1;
fetch_desp_resp_valid_sm = 1'b0;
next_state = RESP_ERR;
end
else if (rdmc_resp_rdy_valid & resp_id_match)
begin
rdmc_resp_accept_sm = 1'b1;
fetch_desp_resp_valid_sm = 1'b1;
next_state = DESP_RESP_DATA2;
end
else
next_state = state;
end
DESP_RESP_DATA2:
begin
if (rdmc_resp_comp & rdmc_resp_trans_comp)
begin
fetch_desp_pre_done = 1'b1;
next_state = DESP_RESP_DONE;
end
else if (rdmc_resp_comp)
next_state = RESP_ERR;
else
next_state = state;
end
DESP_RESP_DONE:
begin
fetch_desp_done = 1'b1;
next_state = IDLE;
end
RESP_ERR:
begin
fetch_desp_done = 1'b1;
resp_cmd_err = 1'b1;
next_state = IDLE;
end
default:
next_state = IDLE;
endcase
end
always @ (posedge clk)
if (reset)
state <= 3'b0;
else if (dma_reset)
state <= 3'b0;
else
state <= next_state;
always @ (posedge clk)
if (reset)
fetch_desp_req <= 1'b0;
else if (dma_reset)
fetch_desp_req <= 1'b0;
else if (fetch_desp_req_sm)
fetch_desp_req <= 1'b1;
else if (fetch_desp_gnt)
fetch_desp_req <= 1'b0;
else
fetch_desp_req <= fetch_desp_req;
/*
always @ (posedge clk)
if (reset)
rdmc_resp_accept <= 1'b0;
else
rdmc_resp_accept <= rdmc_resp_accept_sm;
*/
always @ (posedge clk)
if (reset)
fetch_desp_resp_vld <= 1'b0;
else if (dma_reset)
fetch_desp_resp_vld <= 1'b0;
else if (fetch_desp_resp_valid_sm)
fetch_desp_resp_vld <= 1'b1;
else if (rdmc_resp_comp)
fetch_desp_resp_vld <= 1'b0;
else
fetch_desp_resp_vld <= fetch_desp_resp_vld;
assign vaild_bit0 = &rdmc_resp_byteenable[3:0];
assign vaild_bit1 = &rdmc_resp_byteenable[7:4];
assign vaild_bit2 = &rdmc_resp_byteenable[11:8];
assign vaild_bit3 = &rdmc_resp_byteenable[15:12];
assign vaild_bit_array = {vaild_bit3, vaild_bit2, vaild_bit1, vaild_bit0};
assign valid_bit_err0 = |rdmc_resp_byteenable[3:0] & !vaild_bit0;
assign valid_bit_err1 = |rdmc_resp_byteenable[7:4] & !vaild_bit1;
assign valid_bit_err2 = |rdmc_resp_byteenable[11:8] & !vaild_bit2;
assign valid_bit_err3 = |rdmc_resp_byteenable[15:12] & !vaild_bit3;
assign valid_bit_err_tmp = valid_bit_err0 | valid_bit_err1 |
valid_bit_err2 | valid_bit_err3 | valid_bit_err;
assign resp_data_cnt_err = !(resp_data_cnt == fetch_desp_num);
always @ (vaild_bit_array)
begin
case (vaild_bit_array) //synopsys parallel_case full_case
4'b0001, 4'b0010, 4'b0100, 4'b1000:
begin
valid_addr_cnt = 3'b001;
valid_bit_err = 1'b0;
end
4'b0011, 4'b0110, 4'b1100:
begin
valid_addr_cnt = 3'b010;
valid_bit_err = 1'b0;
end
4'b0111, 4'b1110:
begin
valid_addr_cnt = 3'b011;
valid_bit_err = 1'b0;
end
4'b1111:
begin
valid_addr_cnt = 3'b100;
valid_bit_err = 1'b0;
end
default:
begin
valid_addr_cnt = 3'b000;
valid_bit_err = 1'b1;
end
endcase
end
always @ (posedge clk)
if (reset)
resp_data_cnt <= 5'b0;
else if (dma_reset)
resp_data_cnt <= 5'b0;
else if (fetch_desp_gnt)
resp_data_cnt <= 5'b0;
else if (fetch_desp_resp_vld & rdmc_resp_data_valid)
resp_data_cnt <= resp_data_cnt + {2'b0, valid_addr_cnt};
else
resp_data_cnt <= resp_data_cnt;
always @ (posedge clk)
if (reset)
valid_bit_err_r <= 1'b0;
else if (dma_reset)
valid_bit_err_r <= 1'b0;
else if (fetch_desp_gnt)
valid_bit_err_r <= 1'b0;
else if (fetch_desp_resp_vld & rdmc_resp_data_valid)
valid_bit_err_r <= valid_bit_err_tmp | valid_bit_err_r;
else
valid_bit_err_r <= valid_bit_err_r;
always @ (posedge clk)
if (reset)
resp_data_err <= 1'b0;
else if (dma_reset)
resp_data_err <= 1'b0;
else if (fetch_desp_gnt)
resp_data_err <= 1'b0;
else if (fetch_desp_resp_vld & rdmc_resp_data_valid & (rdmc_resp_data_status != 4'b0))
resp_data_err <= 1'b1;
else
resp_data_err <= resp_data_err;
assign resp_bus_err = (resp_cmd_err | resp_data_cnt_err | valid_bit_err_r | resp_data_err) & fetch_desp_done;
assign resp_bus_err_type = {resp_cmd_err, resp_data_cnt_err, valid_bit_err_r, resp_data_err};
endmodule