// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2004 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0

module t (/*AUTOARG*/
   // Outputs
   ign, ign2, ign3, c_wright_32, c_wleft_32, ign4, ign4s,
   // Inputs
   clk
   );

   input clk;
   output [31:0] ign;
   output [3:0]  ign2;
   output [11:0]  ign3;

   parameter [95:0] P6 = 6;
   localparam P64 = (1 << P6);

   // verilator lint_off WIDTH
   localparam [4:0] PBIG23 = 1'b1 << ~73'b0;
   localparam [3:0] PBIG29 = 4'b1 << 33'h100000000;
   // verilator lint_on WIDTH

   reg [31:0]           iright;
   reg signed [31:0]    irights;
   reg [31:0]           ileft;
   reg [P64-1:0]        qright;
   reg signed [P64-1:0] qrights;
   reg [P64-1:0]        qleft;
   reg [95:0]           wright;
   reg signed [95:0]    wrights;
   reg [95:0]           wleft;

   reg [31:0]           q_iright;
   reg signed [31:0]    q_irights;
   reg [31:0]           q_ileft;
   reg [P64-1:0]        q_qright;
   reg signed [P64-1:0] q_qrights;
   reg [P64-1:0]        q_qleft;
   reg [95:0]           q_wright;
   reg signed [95:0]    q_wrights;
   reg [95:0]           q_wleft;


   reg [31:0]           w_iright;
   reg signed [31:0]    w_irights;
   reg [31:0]           w_ileft;
   reg [P64-1:0]        w_qright;
   reg signed [P64-1:0] w_qrights;
   reg [P64-1:0]        w_qleft;
   reg [95:0]           w_wright;
   reg signed [95:0]    w_wrights;
   reg [95:0]           w_wleft;

   reg [31:0]           iamt;
   reg [63:0]           qamt;
   reg [95:0]           wamt;

   output reg [95:0]    c_wright_32;
   output reg [95:0]    c_wleft_32;

   reg [63:0] crc = 64'h5aef0c8d_d70a4497;
   wire [95:0] rand_96 = {crc[63:32] | crc[31:0], crc};

   assign ign = {31'h0, clk} >>> 4'bx;  // bug760
   assign ign2 = {iamt[1:0] >> {22{iamt[5:2]}}, iamt[1:0] << (0 <<< iamt[5:2])}; // bug1174
   assign ign3 = {iamt[1:0] >> {22{iamt[5:2]}},
                  iamt[1:0] >> {11{iamt[5:2]}},
                  $signed(iamt[1:0]) >>> {22{iamt[5:2]}},
                  $signed(iamt[1:0]) >>> {11{iamt[5:2]}},
                  iamt[1:0] << {22{iamt[5:2]}},
                  iamt[1:0] << {11{iamt[5:2]}}};

   wire [95:0] wamtt = {iamt,iamt,iamt};
   output wire [95:0] ign4;
   assign ign4 = wamtt >> {11{iamt[5:2]}};
   output wire signed [95:0] ign4s;
   assign ign4s = $signed(wamtt) >>> {11{iamt[5:2]}};

   always @* begin
      iright  = 32'h819b018a >> iamt;
      irights = 32'sh819b018a >>> signed'(iamt);
      ileft   = 32'h819b018a << iamt;
      qright  = 64'hf784bf8f_12734089 >> iamt;
      qrights = 64'shf784bf8f_12734089 >>> signed'(iamt);
      qleft   = 64'hf784bf8f_12734089 << iamt;
      wright  = 96'hf784bf8f_12734089_190abe48 >> iamt;
      wrights = 96'shf784bf8f_12734089_190abe48 >>> signed'(iamt);
      wleft   = 96'hf784bf8f_12734089_190abe48 << iamt;

      q_iright  = 32'h819b018a >> qamt;
      q_irights = 32'sh819b018a >>> signed'(qamt);
      q_ileft   = 32'h819b018a << qamt;
      q_qright  = 64'hf784bf8f_12734089 >> qamt;
      q_qrights = 64'shf784bf8f_12734089 >>> signed'(qamt);
      q_qleft   = 64'hf784bf8f_12734089 << qamt;
      q_wright  = 96'hf784bf8f_12734089_190abe48 >> qamt;
      q_wrights = 96'shf784bf8f_12734089_190abe48 >>> signed'(qamt);
      q_wleft   = 96'hf784bf8f_12734089_190abe48 << qamt;

      w_iright  = 32'h819b018a >> wamt;
      w_irights = 32'sh819b018a >>> signed'(wamt);
      w_ileft   = 32'h819b018a << wamt;
      w_qright  = 64'hf784bf8f_12734089 >> wamt;
      w_qrights = 64'shf784bf8f_12734089 >>> signed'(wamt);
      w_qleft   = 64'hf784bf8f_12734089 << wamt;
      w_wright  = 96'hf784bf8f_12734089_190abe48 >> wamt;
      w_wrights = 96'shf784bf8f_12734089_190abe48 >>> signed'(wamt);
      w_wleft   = 96'hf784bf8f_12734089_190abe48 << wamt;

      c_wright_32 = rand_96 >> 32;
      c_wleft_32  = rand_96 << 32;
   end

   integer cyc; initial cyc=1;
   always @ (posedge clk) begin
      if (cyc!=0) begin
         cyc <= cyc + 1;
         crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]};
`ifdef TEST_VERBOSE
         $write("%d %x %x %x %x %x %x\n", cyc, ileft, iright, qleft, qright, wleft, wright);
`endif
         if (cyc==1) begin
            iamt <= 0;
            qamt <= 0;
            wamt <= 0;
            if (P64 != 64) $stop;
            if (5'b10110>>2  != 5'b00101) $stop;
            if (5'b10110>>>2 != 5'b00101) $stop;  // Note it cares about sign-ness
            if (5'b10110<<2  != 5'b11000) $stop;
            if (5'b10110<<<2 != 5'b11000) $stop;
            if (5'sb10110>>2  != 5'sb00101) $stop;
            if (5'sb10110>>>2 != 5'sb11101) $stop;
            if (5'sb10110<<2  != 5'sb11000) $stop;
            if (5'sb10110<<<2 != 5'sb11000) $stop;
            // Allow >64 bit shifts if the shift amount is a constant
            if ((64'sh458c2de282e30f8b >> 68'sh4) !== 64'sh0458c2de282e30f8) $stop;
         end
         if (cyc==2) begin
            iamt <= 28;
            qamt <= 28;
            wamt <= 28;
            if (ileft   != 32'h819b018a) $stop;
            if (iright  != 32'h819b018a) $stop;
            if (irights != 32'h819b018a) $stop;
            if (qleft   != 64'hf784bf8f_12734089) $stop;
            if (qright  != 64'hf784bf8f_12734089) $stop;
            if (qrights != 64'hf784bf8f_12734089) $stop;
            if (wleft   != 96'hf784bf8f12734089190abe48) $stop;
            if (wright  != 96'hf784bf8f12734089190abe48) $stop;
            if (wrights != 96'hf784bf8f12734089190abe48) $stop;
         end
         if (cyc==3) begin
            iamt <= 31;
            qamt <= 31;
            wamt <= 31;
            if (ileft  != 32'ha0000000) $stop;
            if (iright != 32'h8) $stop;
            if (irights != 32'hfffffff8) $stop;
            if (qleft  != 64'hf127340890000000) $stop;
            if (qright != 64'h0000000f784bf8f1) $stop;
            if (qrights != 64'hffffffff784bf8f1) $stop;
            if (wleft  != 96'hf12734089190abe480000000) $stop;
            if (wright != 96'h0000000f784bf8f127340891) $stop;
            if (wrights != 96'hffffffff784bf8f127340891) $stop;
         end
         if (cyc==4) begin
            iamt <= 32;
            qamt <= 32;
            wamt <= 32;
            if (ileft  != 32'h0) $stop;
            if (iright != 32'h1) $stop;
            if (qleft  != 64'h8939a04480000000) $stop;
            if (qright != 64'h00000001ef097f1e) $stop;
         end
         if (cyc==5) begin
            iamt <= 33;
            qamt <= 33;
            wamt <= 33;
            if (ileft  != 32'h0) $stop;
            if (iright != 32'h0) $stop;
            if (qleft  != 64'h1273408900000000) $stop;
            if (qright != 64'h00000000f784bf8f) $stop;
         end
         if (cyc==6) begin
            iamt <= 64;
            qamt <= 64;
            wamt <= 64;
            if (ileft  != 32'h0) $stop;
            if (iright != 32'h0) $stop;
            if (qleft  != 64'h24e6811200000000) $stop;
            if (qright != 64'h000000007bc25fc7) $stop;
         end
         if (cyc==7) begin
            iamt <= 128;
            qamt <= 128;
            wamt <= 128;
            if (ileft  != 32'h0) $stop;
            if (iright != 32'h0) $stop;
            if (qleft  != 64'h0) $stop;
            if (qright != 64'h0) $stop;
         end
         if (cyc==8) begin
            iamt <= 100;
            qamt <= {32'h10, 32'h0};
            wamt <= {32'h10, 64'h0};
            if (ileft   != '0) $stop;
            if (iright  != '0) $stop;
            if (irights != '1) $stop;
            if (qleft   != '0) $stop;
            if (qright  != '0) $stop;
            if (qrights != '1) $stop;
            if (wleft   != '0) $stop;
            if (wright  != '0) $stop;
            if (wrights != '1) $stop;
         end
         if (cyc==19) begin
            $write("*-* All Finished *-*\n");
            $finish;
         end

         // General rule to test all q's
         if (cyc != 0) begin
            if (ileft != q_ileft) $stop;
            if (iright != q_iright) $stop;
            if (irights != q_irights) $stop;
            if (qleft != q_qleft) $stop;
            if (qright != q_qright) $stop;
            if (qrights != q_qrights) $stop;
            if (wleft != q_wleft) $stop;
            if (wright != q_wright) $stop;
            if (wrights != q_wrights) $stop;

            if (ileft != w_ileft) $stop;
            if (iright != w_iright) $stop;
            if (irights != w_irights) $stop;
            if (qleft != w_qleft) $stop;
            if (qright != w_qright) $stop;
            if (qrights != w_qrights) $stop;
            if (wleft != w_wleft) $stop;
            if (wright != w_wright) $stop;
            if (wrights != w_wrights) $stop;

            if (c_wright_32 << 32 != {rand_96[95:32], 32'd0}) $stop;
            if (c_wleft_32 >> 32 != {32'd0, rand_96[63:0]}) $stop;
         end
      end
   end
endmodule
