Decompressor/byte_packer.cpp
//byte_packer:
//Takes in 4 byte wide (little-endian) AXI-Stream and checks accompanying TKEEP signals for presence of null bytes.
//Will remove null bytes from stream and realign bytes into 4 byte wide continuous output stream.
//If TLAST is asserted, will output currently held bytes regardless of having 4 bytes or not.
Takes in 4 byte wide (little-endian) AXI-Stream and checks accompanying TKEEP signals for presence of null bytes.
Will remove null bytes from stream and realign bytes into 4 byte wide continuous output stream.
If TLAST is asserted, will output currently held bytes regardless of having 4 bytes or not.
Takes in 4 byte wide ( little - endian ) AXI - Stream and checks accompanying TKEEP signals for presence of null bytes . Will remove null bytes from stream and realign bytes into 4 byte wide continuous output stream . If TLAST is asserted will output currently held bytes regardless of having 4 bytes or not .
void byte_packer(
		stream<io_strm> &in_strm,
		stream<io_strm> &out_strm
){
#pragma HLS PIPELINE enable_flush
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE axis register both port=in_strm
#pragma HLS INTERFACE axis register both port=out_strm
	static io_strm in_buff = {0};   
	static io_strm data_regA = {0}; 
	static io_strm data_regB = {0}; 
	static unsigned char bytes_neededA = 4; 
	static unsigned char bytes_neededB = 4;
	static bool state = 0; 
	if(state == 0){ 
		in_strm >> in_buff;
		bytes_neededA = align_bytes(in_buff, data_regA); 
		if(bytes_neededA == 0){    
			out_strm << data_regA; 
		}
		else if(bytes_neededA == 4){   
			if(data_regA.last){        
				out_strm << data_regA; 
			} 						   
		}                          
		else if(data_regA.last){   
			out_strm << data_regA; 
		}
		else{ 
			state = 1; 
		}
	}
	else{ 
		in_strm >> in_buff; 
		bytes_neededB = align_bytes(in_buff, data_regB);   
		switch(bytes_neededA){
		case 0 : 
			out_strm << data_regA;				  
			data_regA.data = data_regB.data >> 8; 
			data_regA.keep = data_regB.keep >> 1; 
			bytes_neededA = bytes_neededB;		  
			break;
		case 1 : 
			if(bytes_neededB == 3){ 
				data_regA.data(31,24) = data_regB.data(7,0); 
				data_regA.keep = 0b1111;					 
				data_regA.last = data_regB.last;			 
				out_strm << data_regA;						 
				state = 0;									 
			}
			else if(bytes_neededB <= 2){ 
				data_regA.data(31,24) = data_regB.data(7,0); 
				data_regA.keep = 0b1111;					 
				out_strm << data_regA;						 
				data_regA.data = data_regB.data >> 8;		 
				data_regA.keep = data_regB.keep >> 1;		 
				bytes_neededA = bytes_neededB + 1;			 
			}
			else{ 
				if(data_regB.last){ 
					data_regA.last = 1;
					out_strm << data_regA; 
					state = 0;			   
				} 
			}
			break;
		case 2 : 
			if(bytes_neededB == 2){ 
				data_regA.data(31,16) = data_regB.data(15,0); 
				data_regA.keep = 0b1111;
				data_regA.last = data_regB.last;
				out_strm << data_regA;
				state = 0;	
			}
			else if(bytes_neededB == 3){ 
				data_regA.data(23,16) = data_regB.data(7,0); 
				data_regA.keep = 0b0111; 
				if(data_regB.last){ 
					data_regA.last = 1;
					out_strm << data_regA; 
					state = 0;			   
				}
				else{ 
					bytes_neededA = 1; 
				}
			}
			else if(bytes_neededB <= 1){ 
				data_regA.data(31,16) = data_regB.data(15,0); 
				data_regA.keep = 0b1111;					  
				out_strm << data_regA;						  
				data_regA.data = data_regB.data >> 16;		  
				data_regA.keep = data_regB.keep >> 2;		  
				bytes_neededA = bytes_neededB + 2;			  
			}
			else{ 
				if(data_regB.last){ 
					data_regA.last = 1;
					out_strm << data_regA; 
					state = 0;			   
				} 
			}
			break;
		case 3 : 
			if(bytes_neededB == 1){ 
				data_regA.data(31,8) = data_regB.data(23,0); 
				data_regA.keep = 0b1111;
				data_regA.last = data_regB.last;
				out_strm << data_regA;
				state = 0;	
			}
			else if(bytes_neededB == 2){ 
				data_regA.data(23,8) = data_regB.data(15,0); 
				data_regA.keep = 0b0111; 
				if(data_regB.last){
					data_regA.last = 1;
					out_strm << data_regA; 
					state = 0;			   
				}
				else{
					bytes_neededA = 1;
				}
			}
			else if(bytes_neededB == 3){ 
				data_regA.data(15,8) = data_regB.data(7,0); 
				data_regA.keep = 0b0011; 
				if(data_regB.last){
					data_regA.last = 1;
					out_strm << data_regA; 
					state = 0;			   
				}
				else{
					bytes_neededA = 2;
				}
			}
			else if(bytes_neededB == 0){ 
				data_regA.data(31,8) = data_regB.data(23,0); 
				data_regA.keep = 0b1111;					 
				out_strm << data_regA;						 
				data_regA.data = data_regB.data >> 24;		  
				data_regA.keep = data_regB.keep >> 3;		  
				bytes_neededA = bytes_neededB + 3;			  
			}
			else{ 
				if(data_regB.last){ 
					data_regA.last = 1;
					out_strm << data_regA; 
					state = 0;			   
				} 
			}
			break;
		case 4 : 
			data_regA.data = data_regB.data >> 8; 
			data_regA.keep = data_regB.keep >> 1; 
			bytes_neededA = bytes_neededB;		  
			break;
		}
	}
}
void byte_packer ( stream < io_strm > & in_strm , stream < io_strm > & out_strm ) { #pragma  HLS PIPELINE enable_flush #pragma  HLS INTERFACE ap_ctrl_none port=return #pragma  HLS INTERFACE axis register both port=in_strm #pragma  HLS INTERFACE axis register both port=out_strm static io_strm in_buff = { 0 } ; static io_strm data_regA = { 0 } ; static io_strm data_regB = { 0 } ; static unsigned char bytes_neededA = 4 ; static unsigned char bytes_neededB = 4 ; static bool state = 0 ; if ( state == 0 ) { in_strm >> in_buff ; bytes_neededA = align_bytes ( in_buff , data_regA ) ; if ( bytes_neededA == 0 ) { out_strm << data_regA ; } else if ( bytes_neededA == 4 ) { if ( data_regA . last ) { out_strm << data_regA ; } } else if ( data_regA . last ) { out_strm << data_regA ; } else { state = 1 ; } } else { in_strm >> in_buff ; bytes_neededB = align_bytes ( in_buff , data_regB ) ; switch ( bytes_neededA ) { case 0 : out_strm << data_regA ; data_regA . data = data_regB . data >> 8 ; data_regA . keep = data_regB . keep >> 1 ; bytes_neededA = bytes_neededB ; break ; case 1 : if ( bytes_neededB == 3 ) { data_regA . data ( 31 , 24 ) = data_regB . data ( 7 , 0 ) ; data_regA . keep = 0b1111 ; data_regA . last = data_regB . last ; out_strm << data_regA ; state = 0 ; } else if ( bytes_neededB <= 2 ) { data_regA . data ( 31 , 24 ) = data_regB . data ( 7 , 0 ) ; data_regA . keep = 0b1111 ; out_strm << data_regA ; data_regA . data = data_regB . data >> 8 ; data_regA . keep = data_regB . keep >> 1 ; bytes_neededA = bytes_neededB + 1 ; } else { if ( data_regB . last ) { data_regA . last = 1 ; out_strm << data_regA ; state = 0 ; } } break ; case 2 : if ( bytes_neededB == 2 ) { data_regA . data ( 31 , 16 ) = data_regB . data ( 15 , 0 ) ; data_regA . keep = 0b1111 ; data_regA . last = data_regB . last ; out_strm << data_regA ; state = 0 ; } else if ( bytes_neededB == 3 ) { data_regA . data ( 23 , 16 ) = data_regB . data ( 7 , 0 ) ; data_regA . keep = 0b0111 ; if ( data_regB . last ) { data_regA . last = 1 ; out_strm << data_regA ; state = 0 ; } else { bytes_neededA = 1 ; } } else if ( bytes_neededB <= 1 ) { data_regA . data ( 31 , 16 ) = data_regB . data ( 15 , 0 ) ; data_regA . keep = 0b1111 ; out_strm << data_regA ; data_regA . data = data_regB . data >> 16 ; data_regA . keep = data_regB . keep >> 2 ; bytes_neededA = bytes_neededB + 2 ; } else { if ( data_regB . last ) { data_regA . last = 1 ; out_strm << data_regA ; state = 0 ; } } break ; case 3 : if ( bytes_neededB == 1 ) { data_regA . data ( 31 , 8 ) = data_regB . data ( 23 , 0 ) ; data_regA . keep = 0b1111 ; data_regA . last = data_regB . last ; out_strm << data_regA ; state = 0 ; } else if ( bytes_neededB == 2 ) { data_regA . data ( 23 , 8 ) = data_regB . data ( 15 , 0 ) ; data_regA . keep = 0b0111 ; if ( data_regB . last ) { data_regA . last = 1 ; out_strm << data_regA ; state = 0 ; } else { bytes_neededA = 1 ; } } else if ( bytes_neededB == 3 ) { data_regA . data ( 15 , 8 ) = data_regB . data ( 7 , 0 ) ; data_regA . keep = 0b0011 ; if ( data_regB . last ) { data_regA . last = 1 ; out_strm << data_regA ; state = 0 ; } else { bytes_neededA = 2 ; } } else if ( bytes_neededB == 0 ) { data_regA . data ( 31 , 8 ) = data_regB . data ( 23 , 0 ) ; data_regA . keep = 0b1111 ; out_strm << data_regA ; data_regA . data = data_regB . data >> 24 ; data_regA . keep = data_regB . keep >> 3 ; bytes_neededA = bytes_neededB + 3 ; } else { if ( data_regB . last ) { data_regA . last = 1 ; out_strm << data_regA ; state = 0 ; } } break ; case 4 : data_regA . data = data_regB . data >> 8 ; data_regA . keep = data_regB . keep >> 1 ; bytes_neededA = bytes_neededB ; break ; } } }
byte_packer:
Takes in 4 byte wide (little-endian) AXI-Stream and checks accompanying TKEEP signals for presence of null bytes.
byte_packer : Takes in 4 byte wide ( little - endian ) AXI - Stream and checks accompanying TKEEP signals for presence of null bytes .
//Axi-Stream input buffer //First data register to be filled //Second data register to be filled, used to fill RegA //Number of bytes needed to fill the data pack currently held in data_regA //Current machine state, can be 1 or 0 //Pass-through State: Continue streaming full data packs through until null bytes are encountered //Align data pack and find bytes_needed //If no bytes needed, data already aligned //Stream out full data pack //If data pack is all null bytes //And TLAST is high //Stream out empty data pack with TLAST high //Otherwise, discard empty datapack //If bytes_needed is 1, 2, or 3 //And TLAST is high //Stream out data pack whether it is full or not //Bytes needed to fill this data pack //Change to fill state //Fill State: Replace null bytes with true data bytes from the stream. Remain here as long as stream is discontinuous //Stream in another data pack //Align it and store in Register B //Check if data is needed in RegA //Reg A is already full of good data (Should never happen) //Stream out full data pack //Move RegB data to RegA //Move RegB TKEEP to RegA //Update number of bytes needed by RegA //1 byte needed by RegA //If number of bytes in RegB is exactly 1 //Take 1 byte from it //Update RegA TKEEP signal //Pass TLAST signal //Stream out full data pack //Return to pass-through state //If number of bytes in RegB is 2 or more (more than needed) //Take 1 byte from it //Update RegA TKEEP signal //Stream out full data pack //Shift RegB data and store in RegA //Shift RegB TKEEP signal and store in RegA //Update number of bytes needed by RegA //RegB has no useable bytes. //If RegB is last //Flush out datapack in RegA //Return to pass-through state //Otherwise, read another data pack into RegB next iteration //2 bytes needed by RegA //If number of bytes in RegB is exactly 2 //Take 2 bytes //Return to pass-through state //If only 1 byte in RegB (less than needed) //Take 1 byte //Update TKEEP (in case TLAST is 1) //If TLAST is high //Write out regA //Return to pass-through state //Otherwise //Update number of bytes needed by RegA //If number of bytes in RegB is 3 or more (more than needed) //Take 2 bytes //Update RegA TKEEP signal //Stream out full data pack //Shift RegB data and store in RegA //Shift RegB TKEEP signal and store in RegA //Update number of bytes needed by RegA //RegB has no useable bytes //If RegB is last //Flush out datapack in RegA //Return to pass-through state //Otherwise, read another data pack into RegB next iteration //3 bytes needed by RegA //If number of bytes in RegB is exactly 3 //Take 3 bytes //Return to pass-through state //If only 2 bytes in RegB (less than needed) //Take 2 bytes //Update TKEEP (in case TLAST is 1) //Write out regA //Return to pass-through state //If only 1 byte in RegB (less than needed) //Take 1 byte //Update TKEEP (in case TLAST is 1) //Write out regA //Return to pass-through state //If number of bytes in RegB is 4 (more than needed) //Take 3 bytes //Update RegA TKEEP signal //Stream out full data pack //Shift RegB data and store in RegA //Shift RegB TKEEP signal and store in RegA //Update number of bytes needed by RegA //RegB has no useable bytes //If RegB is last //Flush out datapack in RegA //Return to pass-through state //Otherwise, read another data pack into RegB next iteration //RegA is empty (Should never happen) //Move RegB data to RegA //Move RegB TKEEP to RegA //Update number of bytes needed by RegA