mirror of
https://github.com/verilator/verilator.git
synced 2025-01-05 22:27:35 +00:00
363 lines
13 KiB
Systemverilog
363 lines
13 KiB
Systemverilog
// DESCRIPTION: Verilator: Verilog Test module
|
|
//
|
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
|
// any use, without warranty, 2023 by Wilson Snyder.
|
|
// SPDX-License-Identifier: CC0-1.0
|
|
|
|
`define STRINGIFY(x) `"x`"
|
|
|
|
`define stop $stop
|
|
`ifdef VERILATOR
|
|
`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)
|
|
`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
|
|
|
|
module t (/*AUTOARG*/
|
|
// Inputs
|
|
clk
|
|
);
|
|
|
|
input clk;
|
|
|
|
reg [66:0] a;
|
|
reg [66:0] b;
|
|
|
|
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
|
|
|
|
integer cyc; initial cyc=1;
|
|
integer last_cyc;
|
|
always @ (posedge clk) begin
|
|
if (cyc!=0) begin
|
|
cyc <= cyc + 1;
|
|
last_cyc <= cyc;
|
|
`ifdef TEST_VERBOSE
|
|
$write("- cyc%0d: %0x**%0x = sh %0x\n", cyc, a, b, shifted);
|
|
`endif
|
|
// Constant versions
|
|
`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);
|
|
`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);
|
|
`ifndef VCS
|
|
`checkh(61'h7ab3811219 ** 21'ha6e30, 61'h01ea58c703687e81);
|
|
`endif
|
|
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
|
|
$write("*-* All Finished *-*\n");
|
|
$finish;
|
|
end
|
|
end
|
|
// 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: ;
|
|
endcase
|
|
case (cyc)
|
|
32'd00: ;
|
|
32'd01: ;
|
|
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: ;
|
|
endcase
|
|
end
|
|
endmodule
|