//Interleaver for UMTS "300 x 2"
//Created by: Warrior Group
//
module first_inter (clk, data, out_data, next_en, reset);

//Input and Output declarations
input clk , data, reset ;
output out_data ;
output next_en ;

//Interleaver Arrays and registers
reg [599:0] tmp ;//Interleaver Array
reg tmp_out_fin ;//Interleaver seria output buffer
reg count ; //Column counter
reg [9:0]next_stage_en_count ; //10 bit counter register
reg busy ; //Pipelining tmp register for next_en output

integer i ; //Used in Parallel to serial Process

//Serial to Parallel Converting and Interleaver Memory writing
always @ ( posedge clk )
begin
  if (!reset)//reset all vectors as follow
    begin
      count = 1'b1 ;
      next_stage_en_count = 10'b0 ;
      busy = 1'b0 ;
      i = -1 ;
    end
//Writing in the Interleaver Memory row by row
  else
    if(!busy)
    begin
      count = count + 1'b1 ;
      next_stage_en_count = next_stage_en_count + 10'b1 ;
//Writing in even Array
      if (!count)
          tmp[299:0] = {data, tmp[299:1]};
//Writing in odd Array
      else if (count)
          tmp[599:300] = {data, tmp[599:301]};
    end
//Check if the 600 locations of Array full or not     
    if (next_stage_en_count == 10'd601)
      busy = 1'b1 ;//if they are busy 
//Check if Interleaver busy about sending data or not     
    if (busy)
      begin
//data parallel to serial process    
        i = i + 1 ;
        if (i < 601)
          tmp_out_fin = tmp[i] ;
        else 
          busy = 1'b0 ; //Interleaver now is not busy
     end
end
//Interleaver reading 
assign out_data = tmp_out_fin ;
//This pin "next_en" tell the previous units that the interleaver is busy
//And it tell the next units that the interleaver is sending its data now
assign next_en = busy ;
endmodule
