2006-08-26 11:35:28 +00:00
// DESCRIPTION: Verilator: Verilog Test module
//
2020-03-21 15:24:24 +00:00
// This file ONLY is placed under the Creative Commons Public Domain, for
2023-12-20 00:22:54 +00:00
// any use, without warranty, 2023 by Wilson Snyder.
2020-03-21 15:24:24 +00:00
// SPDX-License-Identifier: CC0-1.0
2006-08-26 11:35:28 +00:00
2023-11-26 22:11:22 +00:00
`define STRINGIFY(x) `"x`"
`define stop $stop
2014-04-05 19:44:49 +00:00
`ifdef VERILATOR
2023-11-26 22:11:22 +00:00
`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)
2014-04-05 19:44:49 +00:00
`else
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); end while(0)
`endif
2006-08-26 11:35:28 +00:00
module t ( /*AUTOARG*/
// Inputs
clk
) ;
input clk ;
2023-11-26 22:11:22 +00:00
reg [ 66 : 0 ] a ;
reg [ 66 : 0 ] b ;
2006-08-26 11:35:28 +00:00
2023-11-26 22:11:22 +00:00
wire [ 15 : 0 ] aui = a [ 15 : 0 ] ;
wire [ 34 : 0 ] auq = a [ 34 : 0 ] ;
wire [ 66 : 0 ] auw = a [ 66 : 0 ] ;
wire [ 15 : 0 ] bui = b [ 15 : 0 ] ;
wire [ 34 : 0 ] buq = b [ 34 : 0 ] ;
wire [ 66 : 0 ] buw = b [ 66 : 0 ] ;
wire signed [ 15 : 0 ] asi = a [ 15 : 0 ] ;
wire signed [ 34 : 0 ] asq = a [ 34 : 0 ] ;
wire signed [ 66 : 0 ] asw = a [ 66 : 0 ] ;
wire signed [ 15 : 0 ] bsi = b [ 15 : 0 ] ;
wire signed [ 34 : 0 ] bsq = b [ 34 : 0 ] ;
wire signed [ 66 : 0 ] bsw = b [ 66 : 0 ] ;
// verilator lint_off WIDTH
wire [ 66 : 0 ] shifted = 2 * * b [ 20 : 0 ] ;
wire [ 15 : 0 ] uiii = aui * * bui ;
wire [ 15 : 0 ] uiiq = aui * * buq ;
wire [ 15 : 0 ] uiiw = aui * * buw ;
wire [ 15 : 0 ] uiqi = auq * * bui ;
wire [ 15 : 0 ] uiqq = auq * * buq ;
wire [ 15 : 0 ] uiqw = auq * * buw ;
wire [ 15 : 0 ] uiwi = auw * * bui ;
wire [ 15 : 0 ] uiwq = auw * * buq ;
wire [ 15 : 0 ] uiww = auw * * buw ;
wire [ 34 : 0 ] uqii = aui * * bui ;
wire [ 34 : 0 ] uqiq = aui * * buq ;
wire [ 34 : 0 ] uqiw = aui * * buw ;
wire [ 34 : 0 ] uqqi = auq * * bui ;
wire [ 34 : 0 ] uqqq = auq * * buq ;
wire [ 34 : 0 ] uqqw = auq * * buw ;
wire [ 34 : 0 ] uqwi = auw * * bui ;
wire [ 34 : 0 ] uqwq = auw * * buq ;
wire [ 34 : 0 ] uqww = auw * * buw ;
wire [ 66 : 0 ] uwii = aui * * bui ;
wire [ 66 : 0 ] uwiq = aui * * buq ;
wire [ 66 : 0 ] uwiw = aui * * buw ;
wire [ 66 : 0 ] uwqi = auq * * bui ;
wire [ 66 : 0 ] uwqq = auq * * buq ;
wire [ 66 : 0 ] uwqw = auq * * buw ;
wire [ 66 : 0 ] uwwi = auw * * bui ;
wire [ 66 : 0 ] uwwq = auw * * buq ;
wire [ 66 : 0 ] uwww = auw * * buw ;
wire signed [ 15 : 0 ] siii = asi * * bsi ;
wire signed [ 15 : 0 ] siiq = asi * * bsq ;
wire signed [ 15 : 0 ] siiw = asi * * bsw ;
wire signed [ 15 : 0 ] siqi = asq * * bsi ;
wire signed [ 15 : 0 ] siqq = asq * * bsq ;
wire signed [ 15 : 0 ] siqw = asq * * bsw ;
wire signed [ 15 : 0 ] siwi = asw * * bsi ;
wire signed [ 15 : 0 ] siwq = asw * * bsq ;
wire signed [ 15 : 0 ] siww = asw * * bsw ;
wire signed [ 34 : 0 ] sqii = asi * * bsi ;
wire signed [ 34 : 0 ] sqiq = asi * * bsq ;
wire signed [ 34 : 0 ] sqiw = asi * * bsw ;
wire signed [ 34 : 0 ] sqqi = asq * * bsi ;
wire signed [ 34 : 0 ] sqqq = asq * * bsq ;
wire signed [ 34 : 0 ] sqqw = asq * * bsw ;
wire signed [ 34 : 0 ] sqwi = asw * * bsi ;
wire signed [ 34 : 0 ] sqwq = asw * * bsq ;
wire signed [ 34 : 0 ] sqww = asw * * bsw ;
wire signed [ 66 : 0 ] swii = asi * * bsi ;
wire signed [ 66 : 0 ] swiq = asi * * bsq ;
wire signed [ 66 : 0 ] swiw = asi * * bsw ;
wire signed [ 66 : 0 ] swqi = asq * * bsi ;
wire signed [ 66 : 0 ] swqq = asq * * bsq ;
wire signed [ 66 : 0 ] swqw = asq * * bsw ;
wire signed [ 66 : 0 ] swwi = asw * * bsi ;
wire signed [ 66 : 0 ] swwq = asw * * bsq ;
wire signed [ 66 : 0 ] swww = asw * * bsw ;
// verilator lint_on WIDTH
task checkpow ( input [ 66 : 0 ] ures , input signed [ 66 : 0 ] sres ) ;
`ifdef TEST_VERBOSE
$write ( " - lastcyc%0d: %0x**%0x = %0x (exp %0x) \n " , last_cyc , a , b , uwww , ures ) ;
`endif
// verilator lint_off WIDTH
`checkh ( uiii , ures [ 15 : 0 ] ) ;
`checkh ( uiiq , ures [ 15 : 0 ] ) ;
`checkh ( uiiw , ures [ 15 : 0 ] ) ;
`checkh ( uiqi , ures [ 15 : 0 ] ) ;
`checkh ( uiqq , ures [ 15 : 0 ] ) ;
`checkh ( uiqw , ures [ 15 : 0 ] ) ;
`checkh ( uiwi , ures [ 15 : 0 ] ) ;
`checkh ( uiwq , ures [ 15 : 0 ] ) ;
`checkh ( uiww , ures [ 15 : 0 ] ) ;
`checkh ( uqii , ures [ 15 : 0 ] ) ;
`checkh ( uqiq , ures [ 15 : 0 ] ) ;
`checkh ( uqiw , ures [ 15 : 0 ] ) ;
`checkh ( uqqi , ures [ 34 : 0 ] ) ;
`checkh ( uqqq , ures [ 34 : 0 ] ) ;
`checkh ( uqqw , ures [ 34 : 0 ] ) ;
`checkh ( uqwi , ures [ 34 : 0 ] ) ;
`checkh ( uqwq , ures [ 34 : 0 ] ) ;
`checkh ( uqww , ures [ 34 : 0 ] ) ;
`checkh ( uwii , ures [ 15 : 0 ] ) ;
`checkh ( uwiq , ures [ 15 : 0 ] ) ;
`checkh ( uwiw , ures [ 15 : 0 ] ) ;
`checkh ( uwqi , ures [ 34 : 0 ] ) ;
`checkh ( uwqq , ures [ 34 : 0 ] ) ;
`checkh ( uwqw , ures [ 34 : 0 ] ) ;
`checkh ( uwwi , ures [ 66 : 0 ] ) ;
`checkh ( uwwq , ures [ 66 : 0 ] ) ;
`checkh ( uwww , ures [ 66 : 0 ] ) ;
`ifdef TEST_VERBOSE
$write ( " - lastcyc%0d: %0d**%0d = signed %0d (exp %0d) \n " , last_cyc , asw , bsw , swww , sres ) ;
`endif
// verilator lint_off WIDTH
`checkh ( siii , sres [ 15 : 0 ] ) ;
`checkh ( siiq , sres [ 15 : 0 ] ) ;
`checkh ( siiw , sres [ 15 : 0 ] ) ;
`checkh ( siqi , sres [ 15 : 0 ] ) ;
`checkh ( siqq , sres [ 15 : 0 ] ) ;
`checkh ( siqw , sres [ 15 : 0 ] ) ;
`checkh ( siwi , sres [ 15 : 0 ] ) ;
`checkh ( siwq , sres [ 15 : 0 ] ) ;
`checkh ( siww , sres [ 15 : 0 ] ) ;
`checkh ( sqii , sres [ 34 : 0 ] ) ;
`checkh ( sqiq , sres [ 34 : 0 ] ) ;
`checkh ( sqiw , sres [ 34 : 0 ] ) ;
`checkh ( sqqi , sres [ 34 : 0 ] ) ;
`checkh ( sqqq , sres [ 34 : 0 ] ) ;
`checkh ( sqqw , sres [ 34 : 0 ] ) ;
`checkh ( sqwi , sres [ 34 : 0 ] ) ;
`checkh ( sqwq , sres [ 34 : 0 ] ) ;
`checkh ( sqww , sres [ 34 : 0 ] ) ;
`checkh ( swii , sres [ 66 : 0 ] ) ;
`checkh ( swiq , sres [ 66 : 0 ] ) ;
`checkh ( swiw , sres [ 66 : 0 ] ) ;
`checkh ( swqi , sres [ 66 : 0 ] ) ;
`checkh ( swqq , sres [ 66 : 0 ] ) ;
`checkh ( swqw , sres [ 66 : 0 ] ) ;
`checkh ( swwi , sres [ 66 : 0 ] ) ;
`checkh ( swwq , sres [ 66 : 0 ] ) ;
`checkh ( swww , sres [ 66 : 0 ] ) ;
// verilator lint_on WIDTH
endtask
`define goldoneu(vu) \
$write ( " gold: u %0x**%0x: %s = %0x \n " , auw , buw , `STRINGIFY ( vu ) , vu ) ;
`define goldones(vs) \
$write ( " gold: s %0d**%0d: %s = %0d \n " , asw , bsw , `STRINGIFY ( vs ) , vs ) ;
task golddump ( ) ;
// verilator lint_off WIDTH
`goldoneu ( uiii ) ;
`goldoneu ( uiiq ) ;
`goldoneu ( uiiw ) ;
`goldoneu ( uiqi ) ;
`goldoneu ( uiqq ) ;
`goldoneu ( uiqw ) ;
`goldoneu ( uiwi ) ;
`goldoneu ( uiwq ) ;
`goldoneu ( uiww ) ;
`goldoneu ( uqii ) ;
`goldoneu ( uqiq ) ;
`goldoneu ( uqiw ) ;
`goldoneu ( uqqi ) ;
`goldoneu ( uqqq ) ;
`goldoneu ( uqqw ) ;
`goldoneu ( uqwi ) ;
`goldoneu ( uqwq ) ;
`goldoneu ( uqww ) ;
`goldoneu ( uwii ) ;
`goldoneu ( uwiq ) ;
`goldoneu ( uwiw ) ;
`goldoneu ( uwqi ) ;
`goldoneu ( uwqq ) ;
`goldoneu ( uwqw ) ;
`goldoneu ( uwwi ) ;
`goldoneu ( uwwq ) ;
`goldoneu ( uwww ) ;
`goldones ( siii ) ;
`goldones ( siiq ) ;
`goldones ( siiw ) ;
`goldones ( siqi ) ;
`goldones ( siqq ) ;
`goldones ( siqw ) ;
`goldones ( siwi ) ;
`goldones ( siwq ) ;
`goldones ( siww ) ;
`goldones ( sqii ) ;
`goldones ( sqiq ) ;
`goldones ( sqiw ) ;
`goldones ( sqqi ) ;
`goldones ( sqqq ) ;
`goldones ( sqqw ) ;
`goldones ( sqwi ) ;
`goldones ( sqwq ) ;
`goldones ( sqww ) ;
`goldones ( swii ) ;
`goldones ( swiq ) ;
`goldones ( swiw ) ;
`goldones ( swqi ) ;
`goldones ( swqq ) ;
`goldones ( swqw ) ;
`goldones ( swwi ) ;
`goldones ( swwq ) ;
`goldones ( swww ) ;
// verilator lint_on WIDTH
endtask
2008-06-10 01:25:10 +00:00
2006-08-26 11:35:28 +00:00
integer cyc ; initial cyc = 1 ;
2023-11-26 22:11:22 +00:00
integer last_cyc ;
2006-08-26 11:35:28 +00:00
always @ ( posedge clk ) begin
if ( cyc ! = 0 ) begin
2022-05-01 14:10:00 +00:00
cyc < = cyc + 1 ;
2023-11-26 22:11:22 +00:00
last_cyc < = cyc ;
2007-01-18 18:31:49 +00:00
`ifdef TEST_VERBOSE
2023-11-26 22:11:22 +00:00
$write ( " - cyc%0d: %0x**%0x = sh %0x \n " , cyc , a , b , shifted ) ;
2007-01-18 18:31:49 +00:00
`endif
2022-05-01 14:10:00 +00:00
// Constant versions
2023-12-20 00:22:54 +00:00
`checkh ( 67 'h0 * * 21 'h0 , 67 'h1 ) ;
`checkh ( 67 'h1 * * 21 'h0 , 67 'h1 ) ;
`checkh ( 67 'h2 * * 21 'h0 , 67 'h1 ) ;
`checkh ( 67 'h0 * * 21 'h1 , 67 'h0 ) ;
`checkh ( 67 'h0 * * 21 'h4 , 67 'h0 ) ;
2023-11-26 22:11:22 +00:00
`checkh ( 67 'h1 * * 21 'h31 , 67 'h1 ) ;
`checkh ( 67 'h2 * * 21 'h10 , 67 'h10000 ) ;
`checkh ( 67 'd10 * * 21 'h3 , 67 'h3e8 ) ;
`checkh ( 67 'h3 * * 21 'h7 , 67 'h88b ) ;
`checkh ( 67 'h0 * * 21 'h0 , 67 'h1 ) ;
`checkh ( 67 ' sh0 * * 21 ' sh0 , 67 ' sh1 ) ;
`checkh ( 67 'h10 * * 21 'h0 , 67 'h1 ) ;
2014-04-05 19:44:49 +00:00
`ifndef VCS
2022-05-01 14:10:00 +00:00
`checkh ( 61 'h7ab3811219 * * 21 'ha6e30 , 61 'h01ea58c703687e81 ) ;
2014-04-05 19:44:49 +00:00
`endif
2023-11-26 22:11:22 +00:00
if ( cyc = = 0 ) begin end
else if ( cyc = = 1 ) begin a < = 67 'h0 ; b < = 67 'h0 ; end
else if ( cyc = = 2 ) begin a < = 67 'h0 ; b < = 67 'h3 ; end
else if ( cyc = = 3 ) begin a < = 67 'h1 ; b < = 67 'h31 ; end
else if ( cyc = = 4 ) begin a < = 67 'h2 ; b < = 67 'h10 ; end
else if ( cyc = = 5 ) begin a < = 67 'd10 ; b < = 67 'd3 ; end
else if ( cyc = = 6 ) begin a < = 67 'd3 ; b < = 67 'd7 ; end
else if ( cyc = = 7 ) begin a < = 67 'h7ab3811219 ; b < = 67 'ha6e30 ; end
else if ( cyc = = 10 ) begin a < = 67 'h0 ; b < = 67 'h0 ; end
else if ( cyc = = 11 ) begin a < = 67 'h0 ; b < = 67 'h1 ; end
else if ( cyc = = 12 ) begin a < = 67 'h0 ; b < = - 67 'h1 ; end
else if ( cyc = = 13 ) begin a < = 67 'h0 ; b < = 67 'h2 ; end
else if ( cyc = = 14 ) begin a < = 67 'h0 ; b < = 67 'h3 ; end
else if ( cyc = = 20 ) begin a < = 67 'h1 ; b < = 67 'h0 ; end
else if ( cyc = = 21 ) begin a < = 67 'h1 ; b < = 67 'h1 ; end
else if ( cyc = = 22 ) begin a < = 67 'h1 ; b < = - 67 'h1 ; end
else if ( cyc = = 23 ) begin a < = 67 'h1 ; b < = 67 'h2 ; end
else if ( cyc = = 24 ) begin a < = 67 'h1 ; b < = 67 'h3 ; end
else if ( cyc = = 30 ) begin a < = - 67 'h1 ; b < = 67 'h0 ; end
else if ( cyc = = 31 ) begin a < = - 67 'h1 ; b < = 67 'h1 ; end
else if ( cyc = = 32 ) begin a < = - 67 'h1 ; b < = - 67 'h1 ; end
else if ( cyc = = 33 ) begin a < = - 67 'h1 ; b < = 67 'h2 ; end
else if ( cyc = = 34 ) begin a < = - 67 'h1 ; b < = 67 'h3 ; end
else if ( cyc = = 40 ) begin a < = 67 'h2 ; b < = 67 'h0 ; end
else if ( cyc = = 41 ) begin a < = 67 'h2 ; b < = 67 'h1 ; end
else if ( cyc = = 42 ) begin a < = 67 'h2 ; b < = - 67 'h1 ; end
else if ( cyc = = 43 ) begin a < = 67 'h2 ; b < = 67 'h2 ; end
else if ( cyc = = 44 ) begin a < = 67 'h2 ; b < = 67 'h3 ; end
else if ( cyc = = 50 ) begin a < = 67 'h3 ; b < = 67 'h0 ; end
else if ( cyc = = 51 ) begin a < = 67 'h3 ; b < = 67 'h1 ; end
else if ( cyc = = 52 ) begin a < = 67 'h3 ; b < = - 67 'h1 ; end
else if ( cyc = = 53 ) begin a < = 67 'h3 ; b < = 67 'h2 ; end
else if ( cyc = = 54 ) begin a < = 67 'h3 ; b < = 67 'h3 ; end
else if ( cyc = = 60 ) begin a < = - 67 'h2 ; b < = 67 'h0 ; end
else if ( cyc = = 61 ) begin a < = - 67 'h2 ; b < = 67 'h1 ; end
else if ( cyc = = 62 ) begin a < = - 67 'h2 ; b < = - 67 'h1 ; end
else if ( cyc = = 63 ) begin a < = - 67 'h2 ; b < = 67 'h2 ; end
else if ( cyc = = 64 ) begin a < = - 67 'h2 ; b < = 67 'h3 ; end
else if ( cyc = = 99 ) begin
2022-05-01 14:10:00 +00:00
$write ( " *-* All Finished *-* \n " ) ;
$finish ;
end
2006-08-26 11:35:28 +00:00
end
2023-11-26 22:11:22 +00:00
// IEEE:
// op1 < -1 op1 == -1 op1 == 0 op1 == 1 op1 > 1
// op2 is positive op1 ** op2 op2 is odd -> -1, even -> 1 0 1 op1 ** op2
// op2 is zero 1 1 1 1 1
// op2 is negative 0 op2 is odd -> -1, even -> 1 'x 1 0
case ( last_cyc )
32 'd10 : checkpow ( 67 'h1 , 67 'h1 ) ; // 0 ** 0 -> 1
32 'd11 : checkpow ( 67 'h0 , 67 'h0 ) ; // 0 ** 1 -> 1
32 'd12 : ; // 0 ** -1 -> x
32 'd13 : checkpow ( 67 'h0 , 67 'h0 ) ; // 0 ** 2 -> 0
32 'd14 : checkpow ( 67 'h0 , 67 'h0 ) ; // 0 ** 3 -> 0
32 'd20 : checkpow ( 67 'h1 , 67 'h1 ) ; // 1 ** 0 -> 1
32 'd21 : checkpow ( 67 'h1 , 67 'h1 ) ; // 1 ** 1 -> 1
`ifndef IVERILOG
32 'd22 : checkpow ( 67 'h1 , 67 'h1 ) ; // 1 ** -1 -> 1
`endif
32 'd23 : checkpow ( 67 'h1 , 67 'h1 ) ; // 1 ** 2 -> 1
32 'd24 : checkpow ( 67 'h1 , 67 'h1 ) ; // 1 ** 3 -> 1
32 'd30 : checkpow ( 67 'h1 , 67 'h1 ) ; // -1 ** 0 -> 1
32 'd31 : checkpow ( - 67 'h1 , - 67 'h1 ) ; // -1 ** 1 -> -1 if odd else 1
32 'd32 : golddump ( ) ; // -1 ** -1 SEE GOLDEN
32 'd33 : golddump ( ) ; // -1 ** 2 SEE GOLDEN
32 'd34 : golddump ( ) ; // -1 ** 3 SEE GOLDEN
32 'd40 : checkpow ( 67 'h1 , 67 'h1 ) ; // 2 ** 0 -> 1
32 'd41 : checkpow ( 67 'h2 , 67 'h2 ) ; // 2 ** 1
32 'd42 : checkpow ( 67 'h0 , 67 'h0 ) ; // 2 ** -1 -> 0
32 'd43 : checkpow ( 67 'h4 , 67 'h4 ) ; // 2 ** 2
32 'd44 : checkpow ( 67 'h8 , 67 'h8 ) ; // 2 ** 3
32 'd50 : checkpow ( 67 'h1 , 67 'h1 ) ; // 3 ** 0 -> 0
32 'd51 : checkpow ( 67 'h3 , 67 'h3 ) ; // 3 ** 1
32 'd52 : golddump ( ) ; // 3 ** -1 -> 0 (if negative gives 0)
32 'd53 : checkpow ( 67 'h9 , 67 'h9 ) ; // 3 ** 2
32 'd54 : checkpow ( 67 'h1b , 67 'h1b ) ; // 3 ** 3
32 'd60 : checkpow ( 67 'h1 , 67 'h1 ) ; // -2 ** 0 -> 1
32 'd61 : golddump ( ) ; // -2 ** 1 SEE GOLDEN
32 'd62 : golddump ( ) ; // -2 ** -1 SEE GOLDEN
32 'd63 : golddump ( ) ; // -2 ** 2 SEE GOLDEN
32 'd64 : golddump ( ) ; // -2 ** 3 SEE GOLDEN
default : ;
2006-08-26 11:35:28 +00:00
endcase
case ( cyc )
2022-05-01 14:10:00 +00:00
32 'd00 : ;
32 'd01 : ;
2023-11-26 22:11:22 +00:00
32 'd02 : `checkh ( shifted , 67 'h0000000000000001 ) ;
32 'd03 : `checkh ( shifted , 67 'h0000000000000008 ) ;
32 'd04 : `checkh ( shifted , 67 'h0002000000000000 ) ;
32 'd05 : `checkh ( shifted , 67 'h0000000000010000 ) ;
32 'd06 : `checkh ( shifted , 67 'h0000000000000008 ) ;
32 'd07 : `checkh ( shifted , 67 'h0000000000000080 ) ;
32 'd08 : `checkh ( shifted , 67 'h0000000000000000 ) ;
32 'd09 : `checkh ( shifted , 67 'h0000000000000000 ) ;
default : ;
2006-08-26 11:35:28 +00:00
endcase
end
endmodule