2

I want to create 8x1 MUX IP BLOCK through HLS. MUX block should be 8 inputs and single output. Eight input streams :Each input stream data width : 32 bit and output should be single output stream of 32 bit. I tried with below code but in simulation output is not. I am missing some logic behind this implementation. Can anyone guide me.

// MUX CODE 
    void 8x1_MUX(hls::stream<idata> &datain1,hls::stream<idata> &datain2,hls::stream<idata> &datain3,hls::stream<idata> &datain4,hls::stream<idata> &datain5,hls::stream<idata> &datain6,hls::stream<idata> &datain7,hls::stream<idata> &datain8,hls::stream<odata> &dataout,hls::stream<isel> sel)
    {
        isel select;
        select=sel.read();
          idata in1;
          idata in2;
          idata in3;
          idata in4;
          idata in5;
          idata in6;
          idata in7;
          idata in8;      
        
 switch(select)
        {
    
        case 1:
            //idata in1;
    
            if(!datain1.empty())
            {
                    in1=datain1.read();
                    dataout.write(in1);
            }
    
           break;
    
        case 2:
              // idata in2;
               if(!datain2.empty())
               {
                   in2=datain2.read();
                   dataout.write(in2);
               }  
            break;
    
        case 3:
                //idata in3;
                if(!datain3.empty())
                {
                    in3=datain3.read();
                    dataout.write(in3);
                }
                break;
    
        case 4:
                //idata in4;
                if(!datain4.empty())
                {
                    in4=datain4.read();
                    dataout.write(in4);
                }
    
                break;
    
        case 5:
                //idata in5;
                if(!datain5.empty())
                {
                    in5=datain5.read();
                    dataout.write(in5);
    
                }
                break;
    
        case 6:
               // idata in6;
                if(!datain6.empty())
                {
                    in6=datain6.read();
                    dataout.write(in6);
                }
                break;
    
        case 7:
               // idata in7;
                if(!datain7.empty())
                {
                    in7=datain7.read();
                    dataout.write(in7);
                }
                break;
    
        case 8:
               // idata in8;
                if(!datain8.empty())
                {
                    in8=datain8.read();
                    dataout.write(in8);
    
                }
            break;
    
        default:
                 //cout<<"invalid stream"<<endl;
                 break;
        }
  
    }
Sang015
  • 21
  • 2
  • It would be best if you could post a test or a wave diagram showing the problem. However, it seems like your code could read sel and not output anything (if the appropriate datain stream is empty). – haggai_e Aug 28 '20 at 18:19
  • I'm shocked by the fact a 8to1 mux would result in so many lines of code using hls. But I should clarify I use traditional verilog only, and I don't have a general feeling on how rtl vs hls nowadays. – Light Aug 29 '20 at 06:25
  • 8 Data generator block`s whereas each block output (Axi Stream) is 32 Bits and connected to each FIFO (totally 8 FIFO`s). Each FIFO output is connected to 8x1 MUX. MUX should select one of the input of FIFO`s among 8 FIFO`s at that instance. I don`t know how to use select line to select input of FIFO`s. Whether the logic code which i wrote is right ? – Sang015 Aug 29 '20 at 16:13

1 Answers1

0

A possible, short, workaround, resulting in roughtly 2 cycles execution, would look something like this:

void 8x1_MUX(hls::stream<idata> datain[8], hls::stream<odata> &dataout, hls::stream<isel> &sel) {
#pragma HLS PIPELINE
  isel select = sel.read();
  idata packet;
  for (int i = 0; i < 8; ++i) {
    if (i == select - 1) {
      if (datain[i].read_nb(packet)) {
        dataout.write(odata(packet));
      }
    }
  }
}

Bear in mind that the empty() and full() methods are not synthesizeable (that's way I'm using the read non-blocking read_nb() method, as suggested in the HLS guide).

Also, there's no check on your select sel FIFO port, so the IP might get stuck waiting for reading the selection packet.

Alternatevely, you can still use the switch-case structure like so:

void 8x1_MUX(hls::stream<idata> &datain1, hls::stream<idata> &datain2,
    hls::stream<idata> &datain3, hls::stream<idata> &datain4,
    hls::stream<idata> &datain5, hls::stream<idata> &datain6,
    hls::stream<idata> &datain7, hls::stream<idata> &datain8,
    hls::stream<odata> &dataout, hls::stream<isel> &sel) {
#pragma HLS PIPELINE
  isel select = sel.read();
  idata packet;
  switch(select) {
    case 1:
      if (datain1.read_nb(packet)) {
        dataout.write(odata(packet));
      }
      break;
    case 2:
      if (datain2.read_nb(packet)) {
        dataout.write(odata(packet));
      }
      break;
    case 3:
      if (datain3.read_nb(packet)) {
        dataout.write(odata(packet));
      }
      break;
    case 4:
      if (datain4.read_nb(packet)) {
        dataout.write(odata(packet));
      }
      break;
    case 5:
      if (datain5.read_nb(packet)) {
        dataout.write(odata(packet));
      }
      break;
    case 6:
      if (datain6.read_nb(packet)) {
        dataout.write(odata(packet));
      }
      break;
    case 7:
      if (datain7.read_nb(packet)) {
        dataout.write(odata(packet));
      }
      break;
    case 8:
      if (datain8.read_nb(packet)) {
        dataout.write(odata(packet));
      }
      break;
  }
}
Stefano Ribes
  • 326
  • 1
  • 7