// $Id: pio_dvalid_gen.v,v 1.0 2005-06-28 13:29:06-07 jhsin Exp jhsin $
// =============================================================================
//                           COPYRIGHT NOTICE
// Copyright 2004 (c) Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// This confidential and proprietary software may be used only as authorised by
// a licensing agreement from Lattice Semiconductor Corporation.
// The entire notice above must be reproduced on all authorized copies and
// copies may only be made to the extent permitted by a licensing agreement from
// Lattice Semiconductor Corporation.
//
// Lattice Semiconductor Corporation        TEL : 1-800-Lattice (USA and Canada)
// 5555 NE Moore Court                            408-826-6000 (other locations)
// Hillsboro, OR 97124                     web  : http://www.latticesemi.com/
// U.S.A                                   email: techsupport@latticesemi.com
// =============================================================================/
//                        FILE DETAILS
// Project          : FCRAM Controller
// File             : pio_dvalid_gen.v
// Title            : Data Valid signal generation using PIO signals
// Dependencies     : 
// Description      : Implements the logic to generate one Datavalid signal.  
//                    Will be instantiated multiple times to ensure the 
//                    flops are placed close together.
// =============================================================================
//                        REVISION HISTORY
// Version          : 1.0
// Author           : Sreenidhi Raatni
// Mod. Date        : April 15, 2004
// Changes Made     : Modified for use in FCRAM controller - mph
//
// =============================================================================

`timescale 1ns/100ps

`include "fcram_params.v"

module pio_dvalid_gen (

    // Clock and reset
    clk,
    rst_n,
    pio_read,

    // Input signals from the PIO
    prmbdet,                       // Preamble detect
    dqsi,                          // DQS at the Pad   
    ddrclkpol,                     // clock polarity selector

    // Output signals to the FPGA Logic
    pio_data_valid                 // data valid signal

) /* synthesis pgroup = "PIO_DVALID_GEN" */;

//////////////////////////////////////////////////////////////////////////////
//clock and reset inputs
input                                 clk;
input                                 rst_n;
input                                 pio_read;

// Input signals from the PIO
input                                 dqsi;
input                                 prmbdet;
input                                 ddrclkpol;

// Output signals to the FPGA Logic
output                                pio_data_valid;

///////////////////////////////////////////////////////////////////////////
// This module implements the logic described in figure 44, page 76 of the
// ECP sysIO Interface Architecture Specification, Rev 03 (12/19/2003).

// Please refer the document for comments and explanation on 
// this circut's use.

// Internal registers and wires

reg                                  prmbdet_d;
reg                                  prmbdet_2d;
reg                                  datavalid_inv;
reg                                  datavalid_non_inv;
reg                                  pio_data_valid;
reg                                  pio_read_d /* synthesis syn_preserve=1 */;
wire                                 pio_read_2d;
wire                                 dv_rst;

// Async reset for the prmbdet_2d and datavalid flops
assign pio_read_2d = ~(prmbdet_d | pio_read_d);
assign dv_rst = (dqsi && !prmbdet_2d);

always @ (posedge clk or negedge rst_n) begin
    if (!rst_n)
	pio_read_d  <= 1'b0;
    else
	pio_read_d  <= pio_read;
end

// ---------------------------------------------------------
always @ (posedge prmbdet or posedge pio_read_d) begin
    if (pio_read_d) begin
        prmbdet_d          <= 1'b0;
    end
    else begin
        prmbdet_d          <= 1'b1;
    end
end

always @ (negedge dqsi or posedge pio_read_2d or negedge rst_n) begin

    if (!rst_n) begin
        prmbdet_2d         <= 1'b0;
    end
    else if (pio_read_2d) begin
        prmbdet_2d         <= 1'b0;
    end
    else begin
        prmbdet_2d         <= prmbdet_d;
    end
end

// ---------------------------------------------------------
//always @ (posedge clk or posedge pio_read_2d) begin
//    if (pio_read_2d) begin
always @ (posedge clk or posedge dv_rst) begin
    if (dv_rst) begin
        datavalid_non_inv      <= 1'b0;
    end
    else begin
        datavalid_non_inv      <= prmbdet_2d;
    end
end

//always @ (negedge clk or posedge pio_read_2d) begin
//    if (pio_read_2d) begin
always @ (negedge clk or posedge dv_rst) begin
    if (dv_rst) begin
        datavalid_inv          <= 1'b0;
    end
    else begin
        datavalid_inv          <= prmbdet_2d;
    end
end

// ---------------------------------------------------------

always @ (negedge clk or negedge rst_n) begin
    if (!rst_n)
	pio_data_valid         <= 1'b0;
    else
	pio_data_valid         <= ddrclkpol ? datavalid_inv : datavalid_non_inv;
end

///////////////////////////////////////////////////////////////////////////
endmodule
