// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2025 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 // verilog_format: off `define stop $stop `define checkh(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); `define checks(gotv, expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on module t ( /*AUTOARG*/ // Inputs clk ); typedef bit bit_q_t[$]; // CData (1-bit) typedef byte byte_q_t[$]; // CData (8-bit) typedef logic [7:0] cdata_q_t[$]; // CData (8-bit) typedef shortint sdata_q_t[$]; // SData (16-bit) typedef logic [15:0] sdata_logic_q_t[$]; // SData (16-bit) typedef int idata_q_t[$]; // IData (32-bit) typedef logic [31:0] idata_logic_q_t[$]; // IData (32-bit) typedef longint qdata_q_t[$]; // QData (64-bit) typedef logic [63:0] qdata_logic_q_t[$]; // QData (64-bit) typedef logic [127:0] wide_q_t[$]; // VlWide (128-bit) input clk; integer cyc = 0; logic [7:0] d; string s; initial begin begin bit_q_t bit_q, bit_qq; bit_q.push_back(1'b0); bit_q.push_back(1'b1); bit_q.push_back(1'b1); `checkh(bit_q[0], 1'b0); `checkh(bit_q[1], 1'b1); `checkh(bit_q[2], 1'b1); bit_q = bit_q_t'(4'he); `checkh(bit_q[0], 1'b1); `checkh(bit_q[1], 1'b1); `checkh(bit_q[2], 1'b1); `checkh(bit_q[3], 1'b0); bit_q = bit_q_t'(4'h3); bit_qq = bit_q; `checkh(bit_qq[0], 1'b0); `checkh(bit_qq[1], 1'b0); `checkh(bit_qq[2], 1'b1); `checkh(bit_qq[3], 1'b1); bit_q = bit_q_t'(4'h2); bit_qq = bit_q_t'(bit_q); `checkh(bit_qq[0], 1'b0); `checkh(bit_qq[1], 1'b0); `checkh(bit_qq[2], 1'b1); `checkh(bit_qq[3], 1'b0); bit_q = bit_q_t'({>>{4'hd}}); `checkh(bit_q[0], 1'b1); `checkh(bit_q[1], 1'b1); `checkh(bit_q[2], 1'b0); `checkh(bit_q[3], 1'b1); bit_q = bit_q_t'({<<{4'hc}}); `checkh(bit_q[0], 1'b0); `checkh(bit_q[1], 1'b0); `checkh(bit_q[2], 1'b1); `checkh(bit_q[3], 1'b1); bit_q = {>>{bit_q_t'(4'he)}}; `checkh(bit_q[0], 1'b1); `checkh(bit_q[1], 1'b1); `checkh(bit_q[2], 1'b1); `checkh(bit_q[3], 1'b0); bit_q = {<<{bit_q_t'(4'hd)}}; `checkh(bit_q[0], 1'b1); `checkh(bit_q[1], 1'b0); `checkh(bit_q[2], 1'b1); `checkh(bit_q[3], 1'b1); bit_qq = {>>{bit_q}}; `checkh(bit_qq[0], 1'b1); `checkh(bit_qq[1], 1'b0); `checkh(bit_qq[2], 1'b1); `checkh(bit_qq[3], 1'b1); bit_qq = {<<{bit_q}}; `checkh(bit_qq[0], 1'b1); `checkh(bit_qq[1], 1'b1); `checkh(bit_qq[2], 1'b0); `checkh(bit_qq[3], 1'b1); bit_q = bit_q_t'({>>{4'hd}}); `checkh(bit_q[0], 1'b1); `checkh(bit_q[1], 1'b1); `checkh(bit_q[2], 1'b0); `checkh(bit_q[3], 1'b1); bit_q = bit_q_t'({>>2{4'hd}}); `checkh(bit_q[0], 1'b1); `checkh(bit_q[1], 1'b1); `checkh(bit_q[2], 1'b0); `checkh(bit_q[3], 1'b1); bit_qq = bit_q_t'({>>{bit_q}}); `checkh(bit_qq[0], 1'b1); `checkh(bit_qq[1], 1'b1); `checkh(bit_qq[2], 1'b0); `checkh(bit_qq[3], 1'b1); bit_qq = bit_q_t'({>>2{bit_q}}); `checkh(bit_qq[0], 1'b1); `checkh(bit_qq[1], 1'b1); `checkh(bit_qq[2], 1'b0); `checkh(bit_qq[3], 1'b1); bit_qq = bit_q_t'({<<{bit_q}}); `checkh(bit_qq[0], 1'b1); `checkh(bit_qq[1], 1'b0); `checkh(bit_qq[2], 1'b1); `checkh(bit_qq[3], 1'b1); bit_qq = {<<2{bit_qq}}; `checkh(bit_qq[0], 1'b1); `checkh(bit_qq[1], 1'b1); `checkh(bit_qq[2], 1'b1); `checkh(bit_qq[3], 1'b0); bit_qq = {<<2{bit_q_t'({<<{bit_q}})}}; `checkh(bit_qq[0], 1'b1); `checkh(bit_qq[1], 1'b1); `checkh(bit_qq[2], 1'b1); `checkh(bit_qq[3], 1'b0); end begin cdata_q_t cdata_q, cdata_qq; cdata_q = cdata_q_t'(32'hdeadbeef); `checkh(cdata_q[0], 8'hde); `checkh(cdata_q[1], 8'had); `checkh(cdata_q[2], 8'hbe); `checkh(cdata_q[3], 8'hef); cdata_qq = cdata_q_t'({<<{cdata_q}}); `checkh(cdata_qq[0], 8'hf7); `checkh(cdata_qq[1], 8'h7d); `checkh(cdata_qq[2], 8'hb5); `checkh(cdata_qq[3], 8'h7b); cdata_qq = {<<2{cdata_q}}; `checkh(cdata_qq[0], 8'hfb); `checkh(cdata_qq[1], 8'hbe); `checkh(cdata_qq[2], 8'h7a); `checkh(cdata_qq[3], 8'hb7); end begin sdata_logic_q_t sdata_q, sdata_qq; sdata_q = sdata_logic_q_t'(64'hfeedface_deadbeef); `checkh(sdata_q[0], 16'hfeed); `checkh(sdata_q[1], 16'hface); `checkh(sdata_q[2], 16'hdead); `checkh(sdata_q[3], 16'hbeef); sdata_qq = sdata_logic_q_t'({<<{sdata_q}}); `checkh(sdata_qq[0], 16'hf77d); `checkh(sdata_qq[1], 16'hb57b); `checkh(sdata_qq[2], 16'h735f); `checkh(sdata_qq[3], 16'hb77f); sdata_qq = {<<2{sdata_q}}; `checkh(sdata_qq[0], 16'hfbbe); `checkh(sdata_qq[1], 16'h7ab7); `checkh(sdata_qq[2], 16'hb3af); `checkh(sdata_qq[3], 16'h7bbf); end begin idata_logic_q_t idata_q, idata_qq; idata_q = idata_logic_q_t'(64'h12345678_9abcdef0); `checkh(idata_q[0], 32'h12345678); `checkh(idata_q[1], 32'h9abcdef0); idata_qq = idata_logic_q_t'({<<{idata_q}}); `checkh(idata_qq[0], 32'h0f7b3d59); `checkh(idata_qq[1], 32'h1e6a2c48); idata_q = idata_logic_q_t'(128'hfeedface_deadbeef_cafebabe_12345678); `checkh(idata_q[0], 32'hfeedface); `checkh(idata_q[1], 32'hdeadbeef); `checkh(idata_q[2], 32'hcafebabe); `checkh(idata_q[3], 32'h12345678); idata_qq = {<<2{idata_logic_q_t'({<<{idata_q}})}}; `checkh(idata_qq[0], 32'hfddef5cd); `checkh(idata_qq[1], 32'hed5e7ddf); `checkh(idata_qq[2], 32'hc5fd757d); `checkh(idata_qq[3], 32'h2138a9b4); end begin qdata_logic_q_t qdata_q, qdata_qq; qdata_q.push_back(64'hdeadbeef_cafebabe); qdata_q.push_back(64'hfeedface_12345678); `checkh(qdata_q[0], 64'hdeadbeef_cafebabe); `checkh(qdata_q[1], 64'hfeedface_12345678); qdata_qq = qdata_logic_q_t'({<<{qdata_q}}); `checkh(qdata_qq[0], 64'h1e6a2c48735fb77f); `checkh(qdata_qq[1], 64'h7d5d7f53f77db57b); qdata_q.push_back(64'h1111222233334444); qdata_q.push_back(64'h5555666677778888); qdata_qq = {<<2{qdata_q}}; `checkh(qdata_qq[0], 64'h2222dddd99995555); `checkh(qdata_qq[1], 64'h1111cccc88884444); `checkh(qdata_qq[2], 64'h2d951c84b3af7bbf); `checkh(qdata_qq[3], 64'hbeaebfa3fbbe7ab7); end begin wide_q_t wide_q, wide_qq; wide_q.push_back(128'hdeadbeef_cafebabe_feedface_12345678); wide_q.push_back(128'h11112222_33334444_55556666_77778888); `checkh(wide_q[0], 128'hdeadbeef_cafebabe_feedface_12345678); `checkh(wide_q[1], 128'h11112222_33334444_55556666_77778888); wide_qq = wide_q_t'({<<{wide_q}}); `checkh(wide_qq[0], 128'h1111eeee6666aaaa2222cccc44448888); `checkh(wide_qq[1], 128'h1e6a2c48735fb77f7d5d7f53f77db57b); wide_q.push_back(128'haaaabbbb_ccccdddd_eeeeffff_00001111); wide_q.push_back(128'h22223333_44445555_66667777_88889999); wide_qq = wide_q_t'({<<{wide_q}}); wide_qq = {<<2{wide_q}}; `checkh(wide_qq[0], 128'h66662222dddd999955551111cccc8888); `checkh(wide_qq[1], 128'h44440000ffffbbbb77773333eeeeaaaa); `checkh(wide_qq[2], 128'h2222dddd999955551111cccc88884444); `checkh(wide_qq[3], 128'h2d951c84b3af7bbfbeaebfa3fbbe7ab7); end begin byte_q_t bytq_init; byte_q_t bytq; bit_q_t bitq; bytq_init.push_back(8'h84); bytq_init.push_back(8'haa); `checkh(bytq_init[0], 8'h84); `checkh(bytq_init[1], 8'haa); s = $sformatf("bytq_init=%p", bytq_init); `checks(s, "bytq_init='{'h84, 'haa} "); bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bitq=%p", bitq); `checks(s, "bitq='{'h0, 'h0, 'h1, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1} "); s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa} "); /* Generalized block-reversal semantics for the outer left-stream when blockSize > 1. This seemingly complicated approach is what is required to match commercial simulators, otherwise the straggler bit [1] in the padded byte might end up as 0x01 instead of 0x80. Starting with result of inner {<<{bitq}}: [1,1,0,1,0,1,0,1,0,1,0,0,0,0,1,0,0] (17 bits), apply outer {<<8{...}} using generalized block-reversal like this: - Reverse all bits: [0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,1] - Split into 8-bit blocks from left and pad incomplete blocks on the left: - Block 0: [0,0,1,0,0,0,0,1] (complete) - Block 1: [0,1,0,1,0,1,0,1] (complete) - Block 2: [1] -> pad on left -> [0,0,0,0,0,0,0,1] - Reverse bits within each 8-bit block: - Block 0: [0,0,1,0,0,0,0,1] -> [1,0,0,0,0,1,0,0] = 0x84 - Block 1: [0,1,0,1,0,1,0,1] -> [1,0,1,0,1,0,1,0] = 0xaa - Block 2: [0,0,0,0,0,0,0,1] -> [1,0,0,0,0,0,0,0] = 0x80 */ bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bitq.push_back(1'b1); bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bitq=%p", bitq); `checks(s, "bitq='{'h0, 'h0, 'h1, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h1} "); `checkh(bytq[0], 8'h84); `checkh(bytq[1], 8'haa); `checkh(bytq[2], 8'h80); s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa, 'h80} "); bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bitq.push_back(1'b1); bitq.push_back(1'b1); bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bitq=%p", bitq); `checks(s, "bitq='{'h0, 'h0, 'h1, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h1, 'h1} "); s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa, 'hc0} "); bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b1); bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa, 'he0} "); bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b0); bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa, 'h70} "); bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b0); bitq.push_back(1'b1); bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa, 'hb8} "); bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b0); bitq.push_back(1'b1); bitq.push_back(1'b0); bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa, 'h5c} "); bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b0); bitq.push_back(1'b1); bitq.push_back(1'b0); bitq.push_back(1'b0); bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa, 'h2e} "); bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b0); bitq.push_back(1'b1); bitq.push_back(1'b0); bitq.push_back(1'b0); bitq.push_back(1'b1); bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa, 'h97} "); bytq = bytq_init; bitq = {<<8{bit_q_t'({<<{bytq}})}}; bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b1); bitq.push_back(1'b0); bitq.push_back(1'b1); bitq.push_back(1'b0); bitq.push_back(1'b0); bitq.push_back(1'b1); bitq.push_back(1'b1); bytq = {<<8{bit_q_t'({<<{bitq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h84, 'haa, 'h97, 'h80} "); end // Test StreamR (>>) operations - fairly simple since this should maintain left-to-right order. begin bit_q_t bitq; byte_q_t bytq; bitq = {1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0}; bitq = {>>4{bit_q_t'({<<{bitq}})}}; s = $sformatf("bitq=%p", bitq); `checks(s, "bitq='{'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1} "); bytq = {8'h84, 8'haa}; bitq = {>>{bit_q_t'({<<{bytq}})}}; s = $sformatf("bitq=%p", bitq); `checks(s, "bitq='{'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h0, 'h1, 'h0, 'h0, 'h0, 'h0, 'h1} "); bitq = { 1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0 }; bytq = {>>2{byte_q_t'({<<{bitq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h43, 'h55} "); bytq = {8'h12, 8'h34, 8'h56}; bytq = {>>{byte_q_t'({<<{bytq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h6a, 'h2c, 'h48} "); bitq = {1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0}; bitq = {>>6{bit_q_t'({>>{bitq}})}}; s = $sformatf("bitq=%p", bitq); `checks(s, "bitq='{'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0} "); bytq = {8'h84, 8'haa}; bitq = {>>{bit_q_t'({>>{bytq}})}}; s = $sformatf("bitq=%p", bitq); `checks(s, "bitq='{'h1, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0} "); bitq = { 1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0 }; bytq = {>>8{byte_q_t'({>>{bitq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'haa, 'hc2} "); bytq = {8'h12, 8'h34, 8'h56}; bytq = {>>{byte_q_t'({>>{bytq}})}}; s = $sformatf("bytq=%p", bytq); `checks(s, "bytq='{'h12, 'h34, 'h56} "); end $write("*-* All Finished *-*\n"); $finish; end endmodule