// Copyright (c) 2002 - Lattice Semiconductor
//                - August 2002.
//
// This program is controlled by a written license agreement.
// Unauthorized Reproduction or Use is Expressly Prohibited.
// ********************************************************************
//
//
//  Name   : loop.v
//
//  Parent : none
//
//  Children : none
//
//  Overview: Driver which loops receive side outputs back to xmit side inputs
//
//  Log:
//
//  Revision 1.0 08/26/02 Mike Hammer
//
//  Initial revision
//
// *********************************************************************

`timescale 1 ns/100 ps

module loop(

	rfclk,
	sys_resetn,	// system reset (active low)

	renb,
	rsx,
	rsop,
	reop,
	rprty,
	rmod,
        rdat,
        rval,
        rerr,

	tenb,
	tsx,
	tsop,
	teop,
	tprty,
	tadr,
	tmod,
        tdat,
        terr,

	dtpa,
	port_id_int
);

parameter num_fifo  = 8;//1,2,4,8

input		rfclk;
input		sys_resetn;	// system reset (active low)

output		renb;
input		rsx;
input		rsop;
input		reop;
input		rprty;
input [1:0]	rmod;
input [31:0]	rdat;
input 		rval;
input 		rerr;

output		tenb;
output		tsx;
output		tsop;
output		teop;
output		tprty;
output [5:0]	tadr;
output [1:0]	tmod;
output [31:0]	tdat;
output		terr;
input [3:0]     port_id_int;

input [num_fifo-1:0]	dtpa;

reg [3:0]	port_id_lat;

reg		renb;
reg		renb_ff;
reg		tenb_ff;
reg [5:0]       tadr;

wire		tenb;
wire		tsx;
wire		tsop;
wire		teop;
wire		tprty;
wire [1:0]	tmod;
wire [31:0]	tdat;
wire		terr;

reg		tsx_ff;
reg		tsop_ff;
reg		teop_ff;
reg		tprty_ff;
reg [1:0]	tmod_ff;
reg [31:0]	tdat_ff;
reg		terr_ff;

wire [3:0]      port_id_int;

assign	tenb  = tenb_ff;
assign	tsx   = tsx_ff;
assign	tsop  = tsop_ff;
assign	teop  = teop_ff;
assign	tprty = tprty_ff;
assign	tmod  = tmod_ff;
assign	tdat  = tdat_ff;
assign	terr  = terr_ff;

always @(negedge rfclk or negedge sys_resetn) begin

     if (!sys_resetn) begin

	renb  <= 1'd1;

	port_id_lat <= port_id_int;

     end
     else begin

 //     	port_id_lat <= port_id_int[3:0];
      	tadr[5:4] <= 2'd0;
        tadr[3:0] <= port_id_lat[3:0];

	if (rsx) 
	    port_id_lat <= rdat[3:0];

	if ( (rsx && (dtpa[rdat[3:0] - port_id_int]) || (dtpa[port_id_lat - port_id_int])) ) begin

		renb <= 1'b0;
	end
	else begin
		renb <= 1'b1;
	end
     end
end

always @(posedge rfclk or negedge sys_resetn) begin

     if (!sys_resetn) begin

	tsx_ff <= 1'b0; 
	tsop_ff <= 1'b0;
	teop_ff <= 1'b0;
	tprty_ff <= 1'b0;
	tmod_ff <= 2'd0;
	tdat_ff <= 32'd0;
	terr_ff <= 1'b0;
	renb_ff <= 1'b1;
	tenb_ff  <= 1'd1;

     end
     else begin


	tsx_ff <= rsx & !renb_ff;
	tsop_ff <= rsop;
	teop_ff <= reop;
	tprty_ff <= rprty;
	tmod_ff <= rmod;
	tdat_ff <= rdat;
	terr_ff <= rerr;

	tenb_ff <= ~(rval & ~renb_ff);
	renb_ff <= renb;
     end
end

endmodule
