Skip to content

Instantly share code, notes, and snippets.

@dvtalk
Last active June 10, 2022 07:24
Show Gist options
  • Save dvtalk/da85498c0599fd10cca2117068b3bc55 to your computer and use it in GitHub Desktop.
Save dvtalk/da85498c0599fd10cca2117068b3bc55 to your computer and use it in GitHub Desktop.
SystemVerilog stream operator example
// https://dvtalk.me
// systemverilog stream operator example:
// stream_op_pack():
// queue to var
// var to queue
// bit re-ordering
// stream_op_unpack():
// var to 3 different var
// stream_op_complex():
// converse 8-bit queue to 32-bit queue
// converse 32-bit queue to 8-bit queue
// converse 8-bit queue to 32-bit queue with reverse order
//
// try this in https://www.edaplayground.com/x/YpFJ
// Reading more:
// https://www.amiq.com/consulting/2017/05/29/how-to-pack-data-using-systemverilog-streaming-operators/
// IEEE SV 2017: 11.4.14 Streaming operators (pack/unpack)
//
module top;
initial begin
stream_op_pack();
stream_op_unpack();
stream_op_complex();
stream_op_complex_rev_order();
end
function void stream_op_pack();
automatic byte q[$] = {8'h01, 8'h02, 8'h03};
bit[3:0] p[$];
int m_pack_var;
// queue to var
m_pack_var = {>>byte{8'h06, 8'h07, 8'h08}};
$display ("queue to var %h\n", m_pack_var );
// output:
// 06070800
m_pack_var = {>>byte{q}};
$display ("queue to var %h\n", m_pack_var );
q.delete();
// output
// 01020300
// var to queue
q = {>>byte{24'h060708}};
foreach (q[i]) begin
$display("byte queue, byte-slice 0x%0x", q[i]);
end
// output:
// 0x6
// 0x7
// 0x8
q = {>>4{24'h060708}};
foreach (q[i]) begin
$display("byte queue, 4bit slice 0x%0x", q[i]);
end
// output:
// 0x6
// 0x7
// 0x8
p = {>>4{24'h060708}};
foreach (p[i]) begin
$display("4bit queue, 4bit-slice 0x%0x", p[i]);
end
// output:
// 0x0
// 0x6
// 0x0
// 0x7
// 0x0
// 0x8
// re-order
$display ("byte-slice %h", {>>byte{24'h060708}} );
$display ("byte-slice %h", {<<byte{24'h060708}} );
// output:
// 060708
// 080706
$display ("1bit-slice %h", {>>bit{24'h0a0a0a}} );
$display ("1bit-slice %h", {<<bit{24'h0a0a0a}} );
// output:
// 0a0a0a
// 505050
$display ("4bit-slice %h", {>>4{24'h0a0a0a}} );
$display ("4bit-slice %h", {<<4{24'h0a0a0a}} );
// output:
// 0a0a0a
// 505050
endfunction
function void stream_op_unpack();
byte a, b, c;
{<<byte{a,b,c}} = 24'h060708;
$display("unpack a 0x%0x", a);
$display("unpack b 0x%0x", b);
$display("unpack c 0x%0x\n", c);
{>>byte{a,b,c}} = 24'h060708;
$display("unpack a 0x%0x", a);
$display("unpack b 0x%0x", b);
$display("unpack c 0x%0x", c);
endfunction
function void stream_op_complex();
automatic byte q8[$] = {8'h01, 8'h02, 8'h03, 8'h04, 8'h05, 8'h06, 8'h07};
automatic bit[31:0] q32[$];
q32 = {>>32{q8}};
foreach (q32[i]) begin
$display ("q8 to q32 0x%0x", q32[i] );
end
// output:
// 0x1020304
// 0x5060700
q8.delete();
q8 = {>>8{q32}};
$display ("q32 to q8 %p", q8 );
// output
// '{1, 2, 3, 4, 5, 6, 7, 0}
endfunction
function void stream_op_complex_rev_order();
// input:
// dd 19 df f2 83 e2 5c 4b-f3 a6 cd e0 99 7f 59 33
// expected output
// 0xf2df19dd - 0x4b5ce283 - 0xe0cda6f3 - 0x33597f99
automatic byte q8[$] = { 'hdd , 'h19 , 'hdf , 'hf2 ,
'h83 , 'he2 , 'h5c , 'h4b ,
'hf3 , 'ha6 , 'hcd , 'he0 ,
'h99 , 'h7f , 'h59 , 'h33};
automatic bit[31:0] q32[$];
q32 = {<<32{{<<8{q8}}}};
foreach (q32[i]) begin
$display ("q8 to q32 0x%0x", q32[i] );
end
// q8 to q32 0xf2df19dd
// q8 to q32 0x4b5ce283
// q8 to q32 0xe0cda6f3
// q8 to q32 0x33597f99
q8.delete();
q8 = {<<8{{<<32{q32}}}};
$displayh ("q32 to q8 reverse order %p", q8 );
// q32 to q8 reverse order '{dd, 19, df, f2, 83, e2, 5c, 4b, f3, a6, cd, e0, 99, 7f, 59, 33}
endfunction
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment