Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / pcie_common / rtl / pcie_dcm_daemon.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: pcie_dcm_daemon.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 pcie_dcm_daemon
(
daemon_csrbus_valid,
daemon_csrbus_mapped,
daemon_csrbus_wr_data,
daemon_csrbus_done,
daemon_csrbus_addr,
daemon_csrbus_wr,
daemon_transaction_in_progress,
// synopsys translate_off
rst_l,
clk,
csrbus_read_data,
// synopsys translate_on
csrbus_valid,
csrbus_mapped,
csrbus_wr_data,
csrbus_done,
csrbus_addr,
csrbus_wr
);
parameter ADDR_WIDTH = 27;
parameter DATA_WIDTH = 64;
// synopsys translate_off
parameter DAEMON_STATE_IDLE = 3'd0;
parameter DAEMON_STATE_RD = 3'd4; // bit 2 is mux select
parameter DAEMON_STATE_WR = 3'd5;
parameter DAEMON_STATE_WAIT_RD = 3'd6;
parameter DAEMON_STATE_WAIT_WR = 3'd7;
// synopsys translate_on
output daemon_csrbus_valid;
output [DATA_WIDTH-1:0] daemon_csrbus_wr_data;
output [ADDR_WIDTH-1:0] daemon_csrbus_addr;
output daemon_csrbus_wr;
output daemon_transaction_in_progress;
output csrbus_mapped;
output csrbus_done;
input daemon_csrbus_mapped;
input daemon_csrbus_done;
// synopsys translate_off
input rst_l;
input clk;
input [DATA_WIDTH-1:0] csrbus_read_data; // needed to return back to daemon task
// synopsys translate_on
input csrbus_valid;
input [DATA_WIDTH-1:0] csrbus_wr_data;
input [ADDR_WIDTH-1:0] csrbus_addr;
input csrbus_wr;
reg daemon_csrbus_valid;
reg [ADDR_WIDTH-1:0] daemon_csrbus_addr;
reg [DATA_WIDTH-1:0] daemon_csrbus_wr_data;
reg daemon_csrbus_wr;
wire daemon_transaction_in_progress;
reg csrbus_done;
reg csrbus_mapped;
// synopsys translate_off
// inputs/outputs from task
reg daemon_wr;
reg daemon_rd;
reg [ADDR_WIDTH-1:0] daemon_addr;
reg [DATA_WIDTH-1:0] daemon_wr_data;
// vlint flag_dangling_net_within_module off
// vlint flag_net_has_no_load off
wire [DATA_WIDTH-1:0] daemon_rd_data;
// vlint flag_net_has_no_load on
// vlint flag_dangling_net_within_module on
// registered versions
reg daemon_wr_reg;
reg daemon_rd_reg;
reg [ADDR_WIDTH-1:0] daemon_addr_reg;
reg [DATA_WIDTH-1:0] daemon_wr_data_reg;
reg daemon_csrbus_done_reg;
// done signals back to verif
// vlint flag_dangling_net_within_module off
// vlint flag_net_has_no_load off
// vlint flag_variable_assign_never_reference off
reg daemon_rd_done;
reg daemon_wr_done;
// vlint flag_variable_assign_never_reference on
// vlint flag_net_has_no_load on
// vlint flag_dangling_net_within_module on
// internal wires
wire daemon_starting_transaction;
wire daemon_ok_to_start_transaction;
wire daemon_rd_done_a1;
wire daemon_wr_done_a1;
reg [2:0] daemon_state;
reg csrbus_valid_d;
// vlint flag_dangling_net_within_module off
// vlint flag_net_has_no_load off
// vlint flag_variable_assign_never_reference off
reg [DATA_WIDTH-1:0] csrbus_read_data_reg;
// vlint flag_variable_assign_never_reference on
// vlint flag_net_has_no_load on
// vlint flag_dangling_net_within_module on
// vlint flag_unsynthesizable_initial off
initial
begin
daemon_state = DAEMON_STATE_IDLE;
// N2- AT: daemon_rd = 1'b0;
// N2- AT: daemon_wr = 1'b0;
daemon_wr_data = {DATA_WIDTH{1'b0}};
daemon_addr = {ADDR_WIDTH{1'b0}};
end // initial begin
// vlint flag_unsynthesizable_initial on
always @(posedge clk)
begin
if (~rst_l) begin
daemon_rd_reg <= 1'b0;
daemon_wr_reg <= 1'b0;
daemon_wr_data_reg <= {DATA_WIDTH{1'b0}};
daemon_addr_reg <= {ADDR_WIDTH{1'b0}};
daemon_rd_done <= 1'b0;
daemon_wr_done <= 1'b0;
daemon_csrbus_done_reg <= 1'b0;
daemon_wr <= 1'b0;
daemon_rd <= 1'b0;
end
else begin
daemon_rd_reg <= daemon_rd;
daemon_wr_reg <= daemon_wr;
daemon_wr_data_reg <= daemon_wr_data;
daemon_addr_reg <= daemon_addr;
daemon_rd_done <= daemon_rd_done_a1;
daemon_wr_done <= daemon_wr_done_a1;
daemon_csrbus_done_reg <= daemon_csrbus_done;
end
end // always @ (posedge clk)
always @(posedge clk)
begin
if (~rst_l ) begin
csrbus_valid_d <= 1'b0;
csrbus_read_data_reg <= {DATA_WIDTH{1'b0}};
end
else begin
csrbus_valid_d <= csrbus_valid;
csrbus_read_data_reg <= csrbus_read_data;
end
end
always @(posedge clk)
begin
if (~rst_l)
daemon_state <= DAEMON_STATE_IDLE;
else begin
case (daemon_state)
DAEMON_STATE_IDLE:
begin
if (daemon_rd_reg & daemon_ok_to_start_transaction) // do daemon read
begin
if (daemon_csrbus_done_reg)
daemon_state <= DAEMON_STATE_WAIT_RD; // zero cycles
else
daemon_state <= DAEMON_STATE_RD; // takes more than zero cycles
end // if (daemon_rd)
else if (daemon_wr_reg & daemon_ok_to_start_transaction)
begin
if (daemon_csrbus_done_reg)
daemon_state <= DAEMON_STATE_WAIT_WR; // less than one cycle
else
daemon_state <= DAEMON_STATE_WR; // slow
end // if (daemon_wr_reg)
else
begin
daemon_state <= DAEMON_STATE_IDLE; // nothing to do
end // else: !if(daemon_wr_reg)
end // case: DAEMON_STATE_IDLE
DAEMON_STATE_WR: // holds a write until finished
begin
if (daemon_csrbus_done_reg) // done or timeout
begin
daemon_state <= DAEMON_STATE_WAIT_WR;
end
else if (~daemon_wr_reg) // timeout
begin
daemon_state <= DAEMON_STATE_WAIT_WR;
end
else
begin
daemon_state <= DAEMON_STATE_WR; // wait
end // else: !if(~daemon_wr_reg)
end
DAEMON_STATE_RD:
begin
if (daemon_csrbus_done_reg) // done
begin
daemon_state <= DAEMON_STATE_WAIT_RD;
end
else if (~daemon_rd_reg)
begin
daemon_state <= DAEMON_STATE_WAIT_RD;
end
else
begin
daemon_state <= DAEMON_STATE_RD; // wait
end
end // case: DAEMON_STATE_RD
DAEMON_STATE_WAIT_RD:
begin
if (daemon_wr_reg & daemon_ok_to_start_transaction)
begin
daemon_state <= DAEMON_STATE_WR; // more than one cycle
end
else if (daemon_rd_reg & daemon_ok_to_start_transaction)
begin
daemon_state <= DAEMON_STATE_RD; // read
end
else
begin
daemon_state <= DAEMON_STATE_IDLE; // nothing to do, go back to idle
end
end // case: DAEMON_STATE_WAIT_RD
DAEMON_STATE_WAIT_WR:
begin
if (daemon_rd_reg & daemon_ok_to_start_transaction) // new rd?
begin
daemon_state <= DAEMON_STATE_RD;
end
else if (daemon_wr_reg & daemon_ok_to_start_transaction) // new write?
begin
daemon_state <= DAEMON_STATE_WR;
end
else
begin
daemon_state <= DAEMON_STATE_IDLE; // nothing to do, go back to idle
end
end // case: DAEMON_STATE_WAIT_WR
default:
begin
daemon_state <= daemon_state;
end
endcase // case(daemon_state)
end
end // always @ (posedge clk)
assign daemon_rd_done_a1 =
(
(daemon_state == DAEMON_STATE_IDLE) &
daemon_csrbus_done &
daemon_rd_reg &
daemon_ok_to_start_transaction
)
|
(
(daemon_state == DAEMON_STATE_RD) &
daemon_csrbus_done
);
assign daemon_wr_done_a1 =
(
(daemon_state == DAEMON_STATE_IDLE) &
daemon_csrbus_done &
daemon_wr_reg &
~daemon_rd_reg &
daemon_ok_to_start_transaction
)
|
(
(daemon_state == DAEMON_STATE_WR) &
daemon_csrbus_done
);
assign daemon_rd_data = csrbus_read_data_reg;
assign daemon_ok_to_start_transaction = ~csrbus_valid_d;
wire good_starting_state = (daemon_state == DAEMON_STATE_IDLE);
assign daemon_starting_transaction = good_starting_state &
(daemon_rd_reg | daemon_wr_reg) &
daemon_ok_to_start_transaction;
// synopsys translate_on
// phaser split_component_by_output
always @(csrbus_valid or csrbus_wr or csrbus_wr_data or csrbus_addr or
daemon_csrbus_done or daemon_csrbus_mapped
// synopsys translate_off
or
daemon_state or
daemon_addr_reg or
daemon_wr_reg or
daemon_wr_data_reg or
daemon_rd_reg or
daemon_transaction_in_progress
// synopsys translate_on
)
begin
// synopsys translate_off
if (daemon_transaction_in_progress)
begin
daemon_csrbus_addr = daemon_addr_reg;
daemon_csrbus_wr = (daemon_state == DAEMON_STATE_WR) |
(
(daemon_state == DAEMON_STATE_IDLE) &
daemon_wr_reg &
~ daemon_rd_reg
);
daemon_csrbus_wr_data = daemon_wr_data_reg;
daemon_csrbus_valid = (
(daemon_state == DAEMON_STATE_IDLE) &
(daemon_rd_reg | daemon_wr_reg)
) |
(daemon_state == DAEMON_STATE_WR) |
(daemon_state == DAEMON_STATE_RD);
csrbus_done = 1'b0;
csrbus_mapped = 1'b0;
end // if (daemon_state != DAEMON_STATE_IDLE)
else // normal operation
// synopsys translate_on
begin
daemon_csrbus_wr = csrbus_wr;
daemon_csrbus_wr_data = csrbus_wr_data;
daemon_csrbus_addr = csrbus_addr;
daemon_csrbus_valid = csrbus_valid;
csrbus_done = daemon_csrbus_done;
csrbus_mapped = daemon_csrbus_mapped;
end // else: !if(daemon_state != DAEMON_STATE_IDLE)
end // always @ (csrbus_wr...
assign daemon_transaction_in_progress =
// synopsys translate_off
((daemon_state != DAEMON_STATE_IDLE) | daemon_starting_transaction ) ? 1'b1 :
// synopsys translate_on
1'b0;
endmodule