module: ofdm_transmit_serial_to_parallel
description:  parses input data stream into a vector valued output
              that is updated each frame cycle
parameters: int num_channels
inputs: int in, IntVector vec_bit_settings, double clk_data, double clk_frame
outputs:  IntVector vec_out IntVector vec_bit_settings_out
static_variables: 
   int clk_count, int frame_length, int frame_flag
classes: EdgeDetect clk_data_edge(), EdgeDetect clk_frame_edge()
         IntVector data_buf(), IntVector cur_vec_bit_settings() 
set_output_vector_lengths:  
  vec_bit_settings_out=num_channels
  vec_out=num_channels
init: 
  int i;
  if (vec_bit_settings.get_length() != num_channels)
     {
      printf("error in 'ofdm_transmit_serial_to_parallel':  length of vec_bit_settings does not\n");
      printf("   equal num_channels\n");
      printf("   in this case, length of vec_bit_settings = %d\n",
                vec_bit_settings.get_length());
      printf("   num_channels = %d\n",num_channels);
      exit(1);
     }
  copy(vec_bit_settings,vec_bit_settings_out);
  copy(vec_bit_settings,cur_vec_bit_settings);
  clk_count = 0;
  frame_length = 0;
  frame_flag = 0;
  for (i = 0; i < vec_bit_settings.get_length(); i++)
      frame_length += vec_bit_settings.get_elem(i);
  data_buf.set_length(frame_length);
code:
  int i;
  if (clk_frame_edge.inp(clk_frame))
     {
      if (frame_flag == 1)
      {
       frame_flag = 0;
       if (clk_count != frame_length)
         {
          printf("error in 'ofdm_transmit_serial_to_parallel' module\n");
          printf("  clk_count != frame_length\n");
          printf("  -> in this case, clk_count = %d, frame_length = %d\n",
                clk_count, frame_length);
          exit(1);
         }
       clk_count = 0;
       ofdm_write_to_out_buffer(data_buf,cur_vec_bit_settings,vec_out);
       copy(cur_vec_bit_settings,vec_bit_settings_out);
       copy(vec_bit_settings,cur_vec_bit_settings);
       frame_length = 0;
       for (i = 0; i < vec_bit_settings.get_length(); i++)
           frame_length += vec_bit_settings.get_elem(i);
       data_buf.set_length(frame_length);
      }
     } 
  if (clk_data_edge.inp(clk_data))
   {
      frame_flag = 1;
      if (clk_count < frame_length)
         {
          data_buf.set_elem(clk_count,in);
          clk_count++;
         }
   }
functions:
void ofdm_write_to_out_buffer(const IntVector &data_buf_in, 
                              const IntVector &vec_bit_settings_in,
                              const IntVector &vec_out_in)
{
int i, j, data_index, cur_bit_setting, cur_data_val, cur_out_val;
IntVector data_buf(data_buf_in);
IntVector vec_bit_settings(vec_bit_settings_in);
IntVector vec_out(vec_out_in);
if (vec_bit_settings.get_length() != vec_out.get_length())
    {
      printf("error in 'ofdm_write_to_out_buffer' function\n");
      printf("  lengths of 'vec_bit_settings' and 'vec_out' do not match!\n");
      printf("  in this case, vec_bit_settings = '%s' (length = %d)\n",
	     vec_bit_settings.get_name(),vec_bit_settings.get_length());
      printf("            and vec_out = '%s' (length = %d)\n",
	     vec_out.get_name(),vec_out.get_length());
      exit(1);
    }
data_index = 0;
for (i = 0; i < vec_out.get_length(); i++)
   {
    cur_bit_setting = vec_bit_settings.get_elem(i);
    cur_out_val = 0;
    for (j = 0; j < cur_bit_setting; j++)
      {
	cur_data_val = data_buf.get_elem(data_index++);
        cur_out_val += cur_data_val > 0 ? 1 << j : 0;
      }
    vec_out.set_elem(i,cur_out_val);
   }
}
