In reply to sharvil111:
I do not think you got my point about the intermediate streams. Think of each stream as an dynamic array of bits sized to the number of bits in the RHS expression; 64 in this case.
Regardless of the specific streaming operator, we create stream1 the same way; as a concatenation of the RHS.
{stream1[0], stream1[1], ... stream1[62], stream1[63]} = {reg_array[0], reg_array[1]};
For any kind of left-to-right streaming operator (as well as a bit-stream cast), the resulting stream2 is identical to stream1.
for(int i=0;b<$bits(stream1);i++) stream2*= stream1[i];
Let me hold of on what happens on a right-to-left streaming operator and explain what happens after any resulting stream2. That gets concatenated into the variables on the LHS.
{byte_array[0], byte_array[1],... byte_array[7]} = {stream2[0], stream2[1], ... stream2[62], stream2[63]}
So you should understand by now that the first and last steps happen the same way for any kind of streaming operator.
Let us go back to the right-to-left streaming operator, where stream2 = {<<{stream1}}. With no [I]slice_size* specified, bits from stream1 are taken one at a time from right to left into stream2 left-to-right. In another word - reversed.
for(int i=0,j=$bits(stream1)-1;i<$bits(stream1);i++,j--)
stream2*= stream1[j];
With a [I]slice_size* greater than one, bits are still taken from right–to-left, but in left-to-right(or un-reversed) blocks. So the pseudo-code for stream2 = {<<slice_size{stream1}} would look something like
for(int I=0,j=$bits(stream1)-1;i<$bits(stream1);I+=slize_size,j-=slice_sice)
stream2[i+:slice_size] = stream1[j-:slice_size];