/******************************************************************************/
/* */
/* Copyright (c) 1999 Sun Microsystems, Inc. All rights reserved. */
/* */
/* The contents of this file are subject to the current version of the Sun */
/* Community Source License, microSPARCII ("the License"). You may not use */
/* this file except in compliance with the License. You may obtain a copy */
/* of the License by searching for "Sun Community Source License" on the */
/* World Wide Web at http://www.sun.com. See the License for the rights, */
/* obligations, and limitations governing use of the contents of this file. */
/* */
/* Sun Microsystems, Inc. has intellectual property rights relating to the */
/* technology embodied in these files. In particular, and without limitation, */
/* these intellectual property rights may include one or more U.S. patents, */
/* foreign patents, or pending applications. */
/* */
/* Sun, Sun Microsystems, the Sun logo, all Sun-based trademarks and logos, */
/* Solaris, Java and all Java-based trademarks and logos are trademarks or */
/* registered trademarks of Sun Microsystems, Inc. in the United States and */
/* other countries. microSPARC is a trademark or registered trademark of */
/* SPARC International, Inc. All SPARC trademarks are used under license and */
/* are trademarks or registered trademarks of SPARC International, Inc. in */
/* the United States and other countries. Products bearing SPARC trademarks */
/* are based upon an architecture developed by Sun Microsystems, Inc. */
/* */
/******************************************************************************/
/****************************************************************************
* @(#)afxm_sm.v 1.20 3/1/96
* afxm_sm.v
*
* Description:
* This is the afxmaster state machine for the Falcon pci bridge.
*
* This module is instantiated by the falcon_stub.v module.
*
*
****************************************************************************/
`define IDLE 3'b000
`define REQ 3'b001
`define RADR 3'b011
`define CADR 3'b010
`define DATACYC 3'b110
`define HOLD 3'b100
`define ERROR 3'b101
`timescale 1ns/1ns
module afxm_sm
( am_cstb_l, dma_burst, cross_page, idle_cyc, req_cyc, radr_cyc, radr_cyc1,
cadr_cyc, cadr_cyc1, data_cyc, data_cyc1,
hold_cyc, hold_cyc1, preempted, error, rmw_write,
dma_read, clk, valid_l, cas_cyc, am_gnt_l,
activity, rcv_fifo_read, rcv_fifo_empty, xfer_count,
abort_write, pend_abort_write, no_rcv_read,
delayed_abort_write, am_read, rmw, rmw_next, trcv_val,
cmd_start_g, txmt_stop_fifo_wr_g, reset_l );
output am_cstb_l
; // afx req from falcon
input dma_burst
; // dma r/w burst indicator
input cross_page
; // page cross flag during burst
output idle_cyc
; // afxm_sm idle state
output req_cyc
; // afxm_sm cstb_l request state
output radr_cyc
; // afxm_sm row_address state
output radr_cyc1
; // afxm_sm delayed row_address state
input rcv_fifo_read
; // tar_rcv1_fifo_read | tar_rcv2_fifo_read
output cadr_cyc
; // afxm_sm column_address state
output cadr_cyc1
; // afxm_sm delayed column_address state
output data_cyc
; // afxm_sm data valid state
output data_cyc1
; // afxm_sm delayed data valid state
output hold_cyc
; // afxm_sm hold_address state
output hold_cyc1
; // afxm_sm delayed hold_address state
output preempted
; // data xfer preempted flag
output error
; // afxm_sm error state
output rmw_write
; // write/~read cycle of rmw
output dma_read
; // dma r/w indicator for Falcon
input clk
; // gclk
input valid_l
; // read/write select
input cas_cyc
; // low address select
input am_gnt_l
; // afx grant to falcon
input activity
; // start signal to afxm_sm
input rcv_fifo_empty
; // write buffers empty indicator
input [2:0] xfer_count
; // data transfer count
input abort_write
; // abort burst write
input pend_abort_write
; // pending abort burst write
input no_rcv_read
; // rcv_fifo data not valid
input delayed_abort_write
; // abort due to last_single
input am_read
; // dma r/w indicator for IIe
input rmw
; // current write is sub-word (rd-mod-wrt)
input rmw_next
; // next write is sub-word (rd-mod-wrt)
input trcv_val
; // tar_rcv_fifo dataout valid
input cmd_start_g
; // pci target core busy
input txmt_stop_fifo_wr_g
; // stop xmit_fifo writes (from pci_slave)
input reset_l
; // system or PCI reset_l
wire [2:0] state
; // curr state of afx master machine
wire dma_read; // read/write xfer?
reg radr_cyc1;
reg cadr_cyc1;
reg data_cyc1;
reg hold_cyc1;
wire rmw_write; // rmw write/~read indicator
wire preempted; // data xfer preempted flag
parameter MAX_XFER = 4'h7; //max afx burst xfer memif allows
function [5:0] master_sm;
input [2:0] state;
input activity;
input rcv_fifo_empty;
input rmw_next;
input rmw;
input rmw_write;
input am_read;
input dma_read;
input dma_burst;
input am_gnt_l;
input cas_cyc;
input valid_l;
input abort_write;
input pend_abort_write;
input trcv_val;
input cmd_start_g;
input [2:0] xfer_count;
input reset_l;
reg [2:0] ns; // next_state
reg dma_rd; // r/w indicator for Falcon
reg rmw_wrt; // rmw write/~read cycle
reg preempt; // data xfer preempted flag
begin
if (~reset_l) begin
ns = `IDLE;
dma_rd = 1'b1;
rmw_wrt = 1'b0;
end
else begin
ns = state;
dma_rd = dma_read;
rmw_wrt = rmw_write;
case (state)
`IDLE: begin
preempt = 1'b0;
rmw_wrt = 1'b0;
dma_rd = ~pend_abort_write; // keep dma_rd low if
// abort_write possible
if (activity)
ns = `REQ;
end
`REQ: begin
dma_rd = am_read;
//if (pack_done | ~cmd_start_g | dma_read) begin
// if (~dma_burst | am_gnt_l)
ns = `RADR;
// else
// ns = `CADR;
//end
//else
// ns = `REQ;
end
`RADR: begin
//2.0: add dma_rd statement because of
// earlier start (REQ too early to
// catch am_read transition).
dma_rd = am_read;
if (~am_gnt_l) begin
ns = `CADR;
end
else begin
ns = `RADR;
end
end
`CADR: begin
if (~am_gnt_l & cas_cyc)
ns = `DATACYC;
else if (am_gnt_l) begin //preempted burst: rearbitrate!
if (~abort_write)
preempt = 1'b1;
ns = `REQ;
end
end
`DATACYC: begin
if (~am_gnt_l & ~valid_l & ~rmw) begin
ns = `HOLD;
if (preempt)
preempt = 1'b0;
end
else if (~valid_l & rmw) begin //rmw turnaround
ns = `HOLD;
if (preempt)
preempt = 1'b0;
end
else if (am_gnt_l & ~rmw & (dma_burst|trcv_val)) begin //preempted burst: rearbitrate!
if (~rmw_next & trcv_val &
(~abort_write | (xfer_count==(MAX_XFER+1))))
preempt = 1'b1;
ns = `REQ;
end
else if (am_gnt_l & ~rmw & ~dma_burst & ~trcv_val) begin //burst done
dma_rd = 1'b1;
ns = `IDLE;
end
else if (am_gnt_l & rmw) //preempted rmw: error!
ns = `ERROR;
else begin
ns = `DATACYC;
rmw_wrt = rmw_wrt;
end
end
`HOLD: begin
if (~am_gnt_l & ~rmw & dma_burst) begin
if (~rmw_next)
dma_rd = am_read;
else
dma_rd = dma_rd;
ns = `DATACYC;
end
else if (~rmw & ~dma_burst) begin
if (~rcv_fifo_empty) begin
ns = `REQ;
dma_rd = am_read;
end
else begin
ns = `IDLE;
dma_rd = ~pend_abort_write;
end
end
else if (am_gnt_l & ~rmw & dma_burst) begin //preempted burst: rearbitrate!
dma_rd = am_read;
if (~abort_write)
preempt = 1'b1;
ns = `REQ;
end
else if (~am_gnt_l & rmw & ~rmw_wrt) begin //rmw turnaround
dma_rd = am_read;
rmw_wrt = 1'b1;
ns = `DATACYC;
end
else if (rmw_wrt) begin //rmw done
rmw_wrt = 1'b0;
if (rcv_fifo_empty) begin
ns = `IDLE;
dma_rd = 1'b1;
end
else begin
dma_rd = am_read;
ns = `REQ;
end
end
else if (am_gnt_l & rmw & ~rmw_wrt) begin //preempted rmw: error!
dma_rd = am_read;
ns = `ERROR;
end
else begin
dma_rd = dma_rd;
rmw_wrt = rmw_wrt;
ns = `HOLD;
end
end
`ERROR: begin
ns = `ERROR;
//synopsys translate_off
$display("afxm: ERROR IN AFX MASTER! rmw=%h, rmw_next=%h, preempt=%h ",rmw,rmw_next,preempt);
$stop;
//synopsys translate_on
end
default: begin
ns = `IDLE;
//synopsys translate_off
if (reset_l) $display("%t: ERROR: illegal state=%h",$time, state);
//synopsys translate_on
end
endcase
end
master_sm[5:0] = {ns, dma_rd, rmw_wrt, preempt };
end
endfunction
reg [5:0] sm_output
;
always @(posedge clk) begin
if (reset_l == 1'b0)
//2.0: changed sm_output init (dma_read = 1)
//sm_output <= #1 11'h080;
sm_output <= #1 6'h04;
else
sm_output <= #1 master_sm(state, activity, rcv_fifo_empty, rmw_next, rmw,
rmw_write, am_read, dma_read, dma_burst,
am_gnt_l, cas_cyc, valid_l, abort_write,
pend_abort_write,
trcv_val, cmd_start_g,
xfer_count, reset_l);
end
assign state = sm_output[5:3];
assign dma_read = sm_output[2];
assign rmw_write = sm_output[1];
assign preempted = sm_output[0];
wire idle_cyc = (state==`IDLE);
wire req_cyc = (state==`REQ);
wire radr_cyc = (state==`RADR);
wire cadr_cyc = (state==`CADR);
wire data_cyc = (state==`DATACYC);
wire hold_cyc = (state==`HOLD);
wire error = (state==`ERROR);
always @(posedge clk) begin
radr_cyc1 <= #1 radr_cyc;
cadr_cyc1 <= #1 cadr_cyc;
data_cyc1 <= #1 data_cyc;
hold_cyc1 <= #1 hold_cyc;
end
//qualify req_cyc to make sure cstb isn't asserted on writes
//before packing is complete
//wire qreq_cyc = req_cyc & (dma_read | pack_done);
//wire initial_req = (qreq_cyc|radr_cyc) & am_gnt_l;
wire initial_req
= (req_cyc|radr_cyc) & am_gnt_l;
wire write_req
= ~dma_read & ~cross_page & ~rmw_next & ~rmw_write & (xfer_count < MAX_XFER);
wire read_req
= dma_read & ~rmw & ~cross_page;
wire rmw_wr_req
= dma_read & rmw & ~rmw_write & ~hold_cyc;
wire burst_ok1
= ~am_gnt_l & (activity | rmw) & (~abort_write | rmw);
wire burst_ok2
= ~am_gnt_l & activity & ~abort_write & ~am_cstb_l &
~txmt_stop_fifo_wr_g;
wire am_cstb_l_in1
=
~((initial_req) ||
(burst_ok1 & (write_req || read_req || rmw_wr_req))
);
wire am_cstb_l_in2
=
~(burst_ok2 & (write_req || read_req || rmw_wr_req));
reg am_cstb_l;
always @(posedge clk) begin
if (cadr_cyc | am_gnt_l)
am_cstb_l <= #1 am_cstb_l_in1;
//2.0: fix to abort mem read earlier upon stop_fifo_wr detection
//else if (hold_cyc)
//2.0: add no_rcv_read term for quick_abort condition
else if (hold_cyc | txmt_stop_fifo_wr_g | (~delayed_abort_write & no_rcv_read))
am_cstb_l <= #1 am_cstb_l_in2;
end
endmodule
| This page: |
Created: | Thu Aug 19 12:02:44 1999 |
| From: |
../../../sparc_v8/ssparc/pcic/afxmaster/rtl/afxm_sm.v
|