// Eleven basic tests in here: // 1. shortint must be initialised before any initial or always block // 2. assignments to (unsigned) shortint with random numbers // 3. assignments to (unsigned) shortint with random values including X and Z // 4. converting unsigned integers to unsigned shortint // 5. converting signed integers to unsigned shortint // 6. converting integers including X and Z states to unsigned shortint // 7. trying unsigned sums (procedural, function, task and module) // 8. trying unsigned mults (procedural, function and task) // 9. trying relational operators // 10. smaller signed numbers to unsigned shortint (signed extension) // 11. trying some concatenations from bytes to shortints module mu_add (input shortint unsigned a, b, output shortint unsigned sc, ss); assign sc = a + b; always @(a, b) ss = a + b; endmodule module main; parameter N_REPS = 500; // repetition with random numbers parameter XZ_REPS = 500; // repetition with 'x 'z values parameter UMAX = 65536; parameter MAX8 = 256; parameter LEN = 16; // variables used as golden references reg unsigned [LEN-1:0] ar; // holds numbers reg unsigned [LEN-1:0] ar_xz; // holds 'x and/or 'z in random positions reg unsigned [LEN-1:0] ar_expected; integer unsigned ui; integer signed si; reg signed [LEN/2-1:0] slice; // type assumed tested before byte unsigned pt1, pt2; // types to be tested shortint unsigned bu; // holds numbers shortint unsigned bu_xz; // 'x and 'z are attempted on this shortint unsigned bresult; // hold results from sums and mults shortint unsigned mcaresult; // wired to a module instance shortint unsigned mabresult; // also wired to a module instance integer i; // continuous assigments // type LHS type RHS // --------- --------- // shortint 4-value logic assign bu = ar; assign bu_xz = ar_xz; // module instantiation mu_add duv (.a(bu), .b(bu_xz), .sc(mcaresult), .ss(mabresult) ); // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 16'b0 || bu_xz !== 16'b0 || bresult !== 16'b0 || mcaresult !== 16'b0 || mabresult !== 16'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // driving shortint type with unsigned random numbers from a variable for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random} % UMAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to shortint: %b", bu); $finish; end end # 1; // attempting to drive variables having 'x 'z values into type unsigned shortint // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< XZ_REPS; i = i+1) begin #1; ar = {$random} % UMAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to shortint (when 'x 'z): %b", bu); $finish; end end // converting unsigned integers to unsigned shortint // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; ui = {$random} % UMAX; #1; force bu = ui; #1; if (bu !== ui[LEN-1:0]) begin $display ("FAILED - incorrect truncation from unsigned integer to shortint: %b", bu); $finish; end end release bu; // converting signed integers to unsigned shortints // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; si = $random % UMAX/2-1; #1; force bu = si; #1; if (bu !== si[LEN-1:0]) begin $display ("FAILED - incorrect truncation from signed integer to shortint: %b mismatchs %b", bu, si[LEN-1:0]); $finish; end end release bu; // converting integers having 'x 'z values into type unsigned shortint // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) // truncation and coercion to zero expected for (i = 0; i< XZ_REPS; i = i+1) begin #1; si = $random; ar_xz = xz_inject (si[LEN-1:0]); si = {si[31:LEN], ar_xz}; ar_expected = xz_expected (ar_xz); #1; force bu_xz = si; #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect conversion from integer (with 'x 'z) to shortint: %b mismatchs %b", bu_xz, ar_expected); $finish; end end release bu_xz; // trying unsigned sums for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random} % UMAX; ar_xz = {$random} % UMAX; #1; bresult = bu + bu_xz; #1; if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned shortints: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // invoking shortint sum function if ( fu_sum (bu, bu_xz) !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned shortint in function"); $finish; end // invoking byte sum task tu_sum (bu, bu_xz, bresult); if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned shortint in task: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // checking shortint sum from module if ( mcaresult !== u_sum(ar, ar_xz) || mabresult !== u_sum(ar, ar_xz)) begin $display ("FAILED - incorrect addition of unsigned shortint from module"); $finish; end end // trying unsigned mults for (i = 0; i< N_REPS; i = i+1) begin #1; ar = ({$random} % UMAX) << LEN/2; ar_xz = ({$random} % UMAX) << (LEN/2 - 1); #1; bresult = bu * bu_xz; // truncated multiplication #1; if ( bresult !== uh_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect multiplication of unsigned shortints (truncated)"); $finish; end #1; pt1 = {$random}; pt2 = {$random}; #1; bresult = pt1 * pt2; // shortint = byte x byte #1; if ( bresult !== u_mul(pt1, pt2) ) begin $display ("FAILED - incorrect multiplication of unsigned shortints for bytes inputs"); $finish; end // invoking shortint mult function (byte*byte) if ( fu_mul (pt1, pt2) !== u_mul(pt1, pt2) ) begin $display ("FAILED - incorrect product of unsigned bytes for a function returning unsigned shortint"); $finish; end // invoking shortint mult task (byte*byte) tu_mul (pt1, pt2, bresult); if ( bresult !== u_mul(pt1, pt2) ) begin $display ("FAILED - incorrect product of unsigned bytes in task returning unsigned shortint"); $finish; end end // trying relational operators for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random} % UMAX; ar_xz = {$random} % UMAX; #1; if ( (bu < bu_xz ) !== (ar < ar_xz) ) begin $display ("FAILED - incorrect 'less than' on unsigned shortints"); $finish; end if ( (bu <= bu_xz ) !== (ar <= ar_xz) ) begin $display ("FAILED - incorrect 'less than or equal' on unsigned shortints"); $finish; end if ( (bu > bu_xz ) !== (ar > ar_xz) ) begin $display ("FAILED - incorrect 'greater than' on unsigned shortints"); $finish; end if ( (bu >= bu_xz ) !== (ar >= ar_xz) ) begin $display ("FAILED - incorrect 'greater than or equal' than on unsigned shortints"); $finish; end if ( (bu == bu_xz ) !== (ar == ar_xz) ) begin $display ("FAILED - incorrect 'equal to' on unsigned shortints"); $finish; end if ( (bu != bu_xz ) !== (ar != ar_xz) ) begin $display ("FAILED - incorrect 'not equal to' on unsigned shortints"); $finish; end end # 1; // signed small number to unsigned shorint for (i = 0; i < (1<