forked from github/verilator
3069860fdf
Fixes #3872. Testing this is a bit tricky, as the front-end fixes up the operand widths in shifts to match, and we need V3Const to introduce a mismatched one by reducing `4'd2 ** x` (with x being 2 2-bit wide signal) to `4'd1 << x`, but t_dfg_peephole runs with V3Const disabled exactly because it makes it hard to write tests. Rather than fixing this one case in V3Const (which we should do systematically at some point), I fixed DFG to accept these just in case V3Const generates more of them. The assertions were there only because of paranoia (as I thought these were not possible inputs), the code otherwise works.
214 lines
11 KiB
Systemverilog
214 lines
11 KiB
Systemverilog
// DESCRIPTION: Verilator: Verilog Test module
|
|
//
|
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
|
// any use, without warranty, 2022 by Geza Lore.
|
|
// SPDX-License-Identifier: CC0-1.0
|
|
|
|
`define signal(name, expr) wire [$bits(expr)-1:0] ``name = expr
|
|
|
|
module t (
|
|
`include "portlist.vh" // Boilerplate generated by t_dfg_peephole.pl
|
|
rand_a, rand_b, srand_a, srand_b
|
|
);
|
|
|
|
`include "portdecl.vh" // Boilerplate generated by t_dfg_peephole.pl
|
|
|
|
input rand_a;
|
|
input rand_b;
|
|
input srand_a;
|
|
input srand_b;
|
|
wire logic [63:0] rand_a;
|
|
wire logic [63:0] rand_b;
|
|
wire logic signed [63:0] srand_a;
|
|
wire logic signed [63:0] srand_b;
|
|
|
|
wire logic randbit_a = rand_a[0];
|
|
wire logic [127:0] rand_ba = {rand_b, rand_a};
|
|
wire logic [127:0] rand_aa = {2{rand_a}};
|
|
wire logic [63:0] const_a;
|
|
wire logic [63:0] const_b;
|
|
wire logic signed [63:0] sconst_a;
|
|
wire logic signed [63:0] sconst_b;
|
|
wire logic [63:0] array [3:0];
|
|
assign array[0] = (rand_a << 32) | (rand_a >> 32);
|
|
assign array[1] = (rand_a << 16) | (rand_a >> 48);
|
|
|
|
`signal(FOLD_UNARY_CLog2, $clog2(const_a));
|
|
`signal(FOLD_UNARY_CountOnes, $countones(const_a));
|
|
`signal(FOLD_UNARY_IsUnknown, $isunknown(const_a));
|
|
`signal(FOLD_UNARY_LogNot, !const_a[0]);
|
|
`signal(FOLD_UNARY_Negate, -const_a);
|
|
`signal(FOLD_UNARY_Not, ~const_a);
|
|
`signal(FOLD_UNARY_OneHot, $onehot(const_a));
|
|
`signal(FOLD_UNARY_OneHot0, $onehot0(const_a));
|
|
`signal(FOLD_UNARY_RedAnd, &const_a);
|
|
`signal(FOLD_UNARY_RedOr, |const_a);
|
|
`signal(FOLD_UNARY_RedXor, ^const_a);
|
|
// verilator lint_off WIDTH
|
|
wire logic [79:0] tmp_FOLD_UNARY_Extend = const_a;
|
|
wire logic signed [79:0] tmp_FOLD_UNARY_ExtendS = sconst_a;
|
|
//verilator lint_on WIDTH
|
|
`signal(FOLD_UNARY_Extend, tmp_FOLD_UNARY_Extend);
|
|
`signal(FOLD_UNARY_ExtendS, tmp_FOLD_UNARY_ExtendS);
|
|
|
|
`signal(FOLD_BINARY_Add, const_a + const_b);
|
|
`signal(FOLD_BINARY_And, const_a & const_b);
|
|
`signal(FOLD_BINARY_Concat, {const_a, const_b});
|
|
`signal(FOLD_BINARY_Div, const_a / 64'd3);
|
|
`signal(FOLD_BINARY_DivS, sconst_a / 64'sd3);
|
|
`signal(FOLD_BINARY_Eq, const_a == const_b);
|
|
`signal(FOLD_BINARY_Gt, const_a > const_b);
|
|
`signal(FOLD_BINARY_GtS, sconst_a > sconst_b);
|
|
`signal(FOLD_BINARY_Gte, const_a >= const_b);
|
|
`signal(FOLD_BINARY_GteS, sconst_a >= sconst_b);
|
|
`signal(FOLD_BINARY_LogAnd, const_a[0] && const_b[0]);
|
|
`signal(FOLD_BINARY_LogEq, const_a[0] <-> const_b[0]);
|
|
`signal(FOLD_BINARY_LogIf, const_a[0] -> const_b[0]);
|
|
`signal(FOLD_BINARY_LogOr, const_a[0] || const_b[0]);
|
|
`signal(FOLD_BINARY_Lt, const_a < const_b);
|
|
`signal(FOLD_BINARY_LtS, sconst_a < sconst_b);
|
|
`signal(FOLD_BINARY_Lte, const_a <= const_b);
|
|
`signal(FOLD_BINARY_LteS, sconst_a <= sconst_b);
|
|
`signal(FOLD_BINARY_ModDiv, const_a % 64'd3);
|
|
`signal(FOLD_BINARY_ModDivS, sconst_a % 64'sd3);
|
|
`signal(FOLD_BINARY_Mul, const_a * 64'd3);
|
|
`signal(FOLD_BINARY_MulS, sconst_a * 64'sd3);
|
|
`signal(FOLD_BINARY_Neq, const_a != const_b);
|
|
`signal(FOLD_BINARY_Or, const_a | const_b);
|
|
`signal(FOLD_BINARY_Pow, const_a ** 64'd2);
|
|
`signal(FOLD_BINARY_PowSS, sconst_a ** 64'sd2);
|
|
`signal(FOLD_BINARY_PowSU, sconst_a ** 64'd2);
|
|
`signal(FOLD_BINARY_PowUS, const_a ** 64'sd2);
|
|
`signal(FOLD_BINARY_Replicate, {2{const_a}});
|
|
`signal(FOLD_BINARY_ShiftL, const_a << 2);
|
|
`signal(FOLD_BINARY_ShiftR, const_a >> 2);
|
|
`signal(FOLD_BINARY_ShiftRS, sconst_a >>> 2);
|
|
`signal(FOLD_BINARY_Sub, const_a - const_b);
|
|
`signal(FOLD_BINARY_Xor, const_a ^ const_b);
|
|
|
|
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_And, (const_a & (const_b & rand_a)));
|
|
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Or, (const_a | (const_b | rand_a)));
|
|
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Xor, (const_a ^ (const_b ^ rand_a)));
|
|
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Add, (const_a + (const_b + rand_a)));
|
|
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Mul, (const_a * (const_b * rand_a)));
|
|
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_MulS, (sconst_a * (sconst_b * srand_a)));
|
|
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Concat, {const_a, {const_b, rand_a}});
|
|
|
|
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_And, ((rand_a & const_b) & const_a));
|
|
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Or, ((rand_a | const_b) | const_a));
|
|
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Xor, ((rand_a ^ const_b) ^ const_a));
|
|
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Add, ((rand_a + const_b) + const_a));
|
|
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Mul, ((rand_a * const_b) * const_a));
|
|
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_MulS, ((srand_a * sconst_b) * sconst_a));
|
|
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Concat, {{rand_a, const_b}, const_a});
|
|
|
|
`signal(FOLD_SEL, const_a[3:1]);
|
|
|
|
`signal(SWAP_CONST_IN_COMMUTATIVE_BINARY, rand_a + const_a);
|
|
`signal(SWAP_NOT_IN_COMMUTATIVE_BINARY, rand_a + ~rand_a);
|
|
`signal(SWAP_VAR_IN_COMMUTATIVE_BINARY, rand_b + rand_a);
|
|
`signal(PUSH_BITWISE_OP_THROUGH_CONCAT, 32'h12345678 ^ {8'h0, rand_a[23:0]});
|
|
`signal(PUSH_BITWISE_OP_THROUGH_CONCAT_2, 32'h12345678 ^ {rand_b[7:0], rand_a[23:0]});
|
|
`signal(PUSH_COMPARE_OP_THROUGH_CONCAT, 4'b1011 == {2'b10, rand_a[1:0]});
|
|
`signal(PUSH_REDUCTION_THROUGH_COND_WITH_CONST_BRANCH, |(rand_a[32] ? rand_a[3:0] : 4'h0));
|
|
`signal(REPLACE_REDUCTION_OF_CONST_AND, &const_a);
|
|
`signal(REPLACE_REDUCTION_OF_CONST_OR, |const_a);
|
|
`signal(REPLACE_REDUCTION_OF_CONST_XOR, ^const_a);
|
|
`signal(REPLACE_EXTEND, 4'(rand_a[0]));
|
|
`signal(PUSH_NOT_THROUGH_COND, ~(rand_a[0] ? rand_a[4:0] : 5'hb));
|
|
`signal(REMOVE_NOT_NOT, ~~rand_a);
|
|
`signal(REPLACE_NOT_NEQ, ~(rand_a != rand_b));
|
|
`signal(REPLACE_NOT_EQ, ~(rand_a == rand_b));
|
|
`signal(REPLACE_NOT_OF_CONST, ~4'd0);
|
|
`signal(REPLACE_AND_OF_NOT_AND_NOT, ~rand_a[1] & ~rand_b[1]);
|
|
`signal(REPLACE_AND_OF_NOT_AND_NEQ, ~rand_a[2] & (rand_b != 64'd2));
|
|
`signal(REPLACE_AND_OF_CONST_AND_CONST, const_a & const_b);
|
|
`signal(REPLACE_AND_WITH_ZERO, 64'd0 & rand_a);
|
|
`signal(REMOVE_AND_WITH_ONES, -64'd1 & rand_a);
|
|
`signal(REPLACE_CONTRADICTORY_AND, rand_a & ~rand_a);
|
|
`signal(REPLACE_OR_OF_NOT_AND_NOT, ~rand_a[3] | ~rand_b[3]);
|
|
`signal(REPLACE_OR_OF_NOT_AND_NEQ, ~rand_a[4] | (rand_b != 64'd3));
|
|
`signal(REPLACE_OR_OF_CONCAT_ZERO_LHS_AND_CONCAT_RHS_ZERO, {2'd0, rand_a[1:0]} | {rand_b[1:0], 2'd0});
|
|
`signal(REPLACE_OR_OF_CONCAT_LHS_ZERO_AND_CONCAT_ZERO_RHS, {rand_a[1:0], 2'd0} | {2'd0, rand_b[1:0]});
|
|
`signal(REPLACE_OR_OF_CONST_AND_CONST, const_a | const_b);
|
|
`signal(REMOVE_OR_WITH_ZERO, 64'd0 | rand_a);
|
|
`signal(REPLACE_OR_WITH_ONES, -64'd1 | rand_a);
|
|
`signal(REPLACE_TAUTOLOGICAL_OR, rand_a | ~rand_a);
|
|
`signal(REMOVE_SUB_ZERO, rand_a - 64'd0);
|
|
`signal(REPLACE_SUB_WITH_NOT, rand_a[0] - 1'b1);
|
|
`signal(REMOVE_REDUNDANT_ZEXT_ON_RHS_OF_SHIFT, rand_a << {2'b0, rand_a[2:0]});
|
|
`signal(REPLACE_EQ_OF_CONST_AND_CONST, 4'd0 == 4'd1);
|
|
`signal(REMOVE_FULL_WIDTH_SEL, rand_a[63:0]);
|
|
`signal(REMOVE_SEL_FROM_RHS_OF_CONCAT, rand_ba[63:0]);
|
|
`signal(REMOVE_SEL_FROM_LHS_OF_CONCAT, rand_ba[127:64]);
|
|
`signal(PUSH_SEL_THROUGH_CONCAT, rand_ba[120:0]);
|
|
`signal(PUSH_SEL_THROUGH_REPLICATE, rand_aa[0]);
|
|
`signal(REPLACE_SEL_FROM_CONST, const_a[2]);
|
|
`signal(REPLACE_CONCAT_OF_CONSTS, {const_a, const_b});
|
|
`signal(REPLACE_CONCAT_ZERO_AND_SEL_TOP_WITH_SHIFTR, {62'd0, rand_a[63:62]});
|
|
`signal(REPLACE_CONCAT_SEL_BOTTOM_AND_ZERO_WITH_SHIFTL, {rand_a[1:0], 62'd0});
|
|
`signal(PUSH_CONCAT_THROUGH_NOTS, {~(rand_a+64'd101), ~(rand_b+64'd101)} );
|
|
`signal(REMOVE_CONCAT_OF_ADJOINING_SELS, {rand_a[10:3], rand_a[2:1]});
|
|
`signal(REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_LHS_CAT, {rand_a[2:1], rand_b});
|
|
`signal(REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_RHS_CAT, {rand_b, rand_a[10:3]});
|
|
`signal(REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_LHS, {rand_a[10:3], {rand_a[2:1], rand_b}});
|
|
`signal(REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_RHS, {{rand_b, rand_a[10:3]}, rand_a[2:1]});
|
|
`signal(REMOVE_COND_WITH_FALSE_CONDITION, 1'd0 ? rand_a : rand_b);
|
|
`signal(REMOVE_COND_WITH_TRUE_CONDITION, 1'd1 ? rand_a : rand_b);
|
|
`signal(SWAP_COND_WITH_NOT_CONDITION, (~rand_a[0] & 1'd1) ? rand_a : rand_b);
|
|
`signal(SWAP_COND_WITH_NEQ_CONDITION, rand_b != rand_a ? rand_a : rand_b);
|
|
`signal(PULL_NOTS_THROUGH_COND, rand_a[0] ? ~rand_a[4:0] : ~rand_b[4:0]);
|
|
`signal(REPLACE_COND_WITH_THEN_BRANCH_ZERO, rand_a[0] ? 1'd0 : rand_a[1]);
|
|
`signal(REPLACE_COND_WITH_THEN_BRANCH_ONES, rand_a[0] ? 1'd1 : rand_a[1]);
|
|
`signal(REPLACE_COND_WITH_ELSE_BRANCH_ZERO, rand_a[0] ? rand_a[1] : 1'd0);
|
|
`signal(REPLACE_COND_WITH_ELSE_BRANCH_ONES, rand_a[0] ? rand_a[1] : 1'd1);
|
|
`signal(INLINE_ARRAYSEL, array[0]);
|
|
`signal(PUSH_BITWISE_THROUGH_REDUCTION_AND, (&(rand_a + 64'd105)) & (&(rand_b + 64'd108)));
|
|
`signal(PUSH_BITWISE_THROUGH_REDUCTION_OR, (|(rand_a + 64'd106)) | (|(rand_b + 64'd109)));
|
|
`signal(PUSH_BITWISE_THROUGH_REDUCTION_XOR, (^(rand_a + 64'd107)) ^ (^(rand_b + 64'd110)));
|
|
`signal(PUSH_REDUCTION_THROUGH_CONCAT_AND, &{1'd1, rand_b});
|
|
`signal(PUSH_REDUCTION_THROUGH_CONCAT_OR, |{1'd1, rand_b});
|
|
`signal(PUSH_REDUCTION_THROUGH_CONCAT_XOR, ^{1'd1, rand_b});
|
|
`signal(REMOVE_WIDTH_ONE_REDUCTION_AND, &rand_a[0]);
|
|
`signal(REMOVE_WIDTH_ONE_REDUCTION_OR, |rand_a[0]);
|
|
`signal(REMOVE_WIDTH_ONE_REDUCTION_XOR, ^rand_a[0]);
|
|
`signal(REMOVE_XOR_WITH_ZERO, 64'd0 ^ rand_a);
|
|
`signal(REMOVE_XOR_WITH_ONES, -64'd1 ^ rand_a);
|
|
`signal(REPLACE_COND_DEC, randbit_a ? rand_b - 64'b1 : rand_b);
|
|
`signal(REPLACE_COND_INC, randbit_a ? rand_b + 64'b1 : rand_b);
|
|
`signal(NO_REPLACE_COND_DEC, randbit_a ? rand_b - 64'hf000000000000000 : rand_b);
|
|
`signal(NO_REPLACE_COND_INC, randbit_a ? rand_b + 64'hf000000000000000 : rand_b);
|
|
`signal(RIGHT_LEANING_ASSOC, (((rand_a + rand_b) + rand_a) + rand_b));
|
|
`signal(RIGHT_LEANING_CONCET, {{{rand_a, rand_b}, rand_a}, rand_b});
|
|
|
|
// Operators that should work wiht mismatched widths
|
|
`signal(MISMATCHED_ShiftL,const_a << 4'd2);
|
|
`signal(MISMATCHED_ShiftR,const_a >> 4'd2);
|
|
`signal(MISMATCHED_ShiftRS, const_a >> 4'd2);
|
|
`signal(MISMATCHED_PowUU, rand_a ** 4'd5);
|
|
`signal(MISMATCHED_PowSS, srand_a ** 4'sd5);
|
|
`signal(MISMATCHED_PowSU, srand_b ** 4'd5);
|
|
`signal(MISMATCHED_PowUS, rand_b ** 4'sd5);
|
|
|
|
// Some selects need extra temporaries
|
|
wire [63:0] sel_from_cond = rand_a[0] ? rand_a : const_a;
|
|
wire [63:0] sel_from_shiftl = rand_a << 10;
|
|
wire [31:0] sel_from_sel = rand_a[10+:32];
|
|
|
|
`signal(PUSH_SEL_THROUGH_COND, sel_from_cond[2]);
|
|
`signal(PUSH_SEL_THROUGH_SHIFTL, sel_from_shiftl[20:0]);
|
|
`signal(REPLACE_SEL_FROM_SEL, sel_from_sel[4:3]);
|
|
|
|
// Sel from not requires the operand to have a sinle sink, so can't use
|
|
// the chekc due to the raw expression referencing the operand
|
|
wire [63:0] sel_from_not_tmp = ~(rand_a >> rand_b[2:0] << rand_a[3:0]);
|
|
wire sel_from_not = sel_from_not_tmp[2];
|
|
always @(posedge randbit_a) if ($c(0)) $display(sel_from_not); // Do not remove signal
|
|
|
|
// Assigned at the end to avoid inlining by other passes
|
|
assign const_a = 64'h0123456789abcdef;
|
|
assign const_b = 64'h98badefc10325647;
|
|
assign sconst_a = 64'hfedcba9876543210;
|
|
assign sconst_b = 64'hba0123456789cdef;
|
|
endmodule
|