//
// Copyright 2011 Ettus Research LLC
//
// 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, either version 3 of the License, or
// (at your option) any later version.
//
// 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, see .
//
// FIXME ignores the AWIDTH (fifo size) parameter
module fifo_2clock
  #(parameter WIDTH=36, SIZE=6)
   (input wclk, input [WIDTH-1:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space,
    input rclk, output [WIDTH-1:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied,
    input arst);
   
   wire [SIZE:0] level_rclk, level_wclk; // xilinx adds an extra bit if you ask for accurate levels
   wire 	 full, empty, write, read;
   assign dst_rdy_o  = ~full;
   assign src_rdy_o  = ~empty;
   assign write      = src_rdy_i & dst_rdy_o;
   assign read 	     = src_rdy_o & dst_rdy_i;
   wire 	 dummy;
   
   generate
      if(WIDTH==36)
	if(SIZE==9)
	  fifo_xlnx_512x36_2clk fifo_xlnx_512x36_2clk
	       (.rst(arst),
		.wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
		.rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
	else if(SIZE==11)
	  fifo_xlnx_2Kx36_2clk fifo_xlnx_2Kx36_2clk 
		     (.rst(arst),
		      .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
		      .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
	else if(SIZE==6)
	  fifo_xlnx_64x36_2clk fifo_xlnx_64x36_2clk 
		     (.rst(arst),
		      .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
		      .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
	else
	  fifo_xlnx_512x36_2clk fifo_xlnx_512x36_2clk
	       (.rst(arst),
		.wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
		.rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
      else if((WIDTH==19) & (SIZE==4))
	fifo_xlnx_16x19_2clk fifo_xlnx_16x19_2clk
	  (.rst(arst),
	   .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
	   .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
      else if((WIDTH==18) & (SIZE==4))
	fifo_xlnx_16x19_2clk fifo_xlnx_16x19_2clk
	  (.rst(arst),
	   .wr_clk(wclk),.din({1'b0,datain}),.full(full),.wr_en(write),.wr_data_count(level_wclk),
	   .rd_clk(rclk),.dout({dummy,dataout}),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
      else if ((WIDTH==18) & (SIZE==10))
	fifo_xlnx_1Kx18_2clk fifo_xlnx_1Kx18_2clk
	  (.rst(arst),
	   .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
	   .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
   endgenerate
   
   assign occupied  = {{(16-SIZE-1){1'b0}},level_rclk};
   assign space     = ((1<