// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // Copyright 2024 by Kefa Chen. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 //************************************************************************* #include #include VM_PREFIX_INCLUDE #include "TestCheck.h" /* typedef logic [5:0] udata6_t; typedef union packed { udata6_t a; logic [2:0] b; } sub_t; typedef struct packed { logic [40:0] a; udata6_t [3:0] b; sub_t c; } in_t ; typedef struct packed { udata6_t [3:0] b; sub_t c; logic [40:0] a; } out_t ; // struct in1_t should cover parts of VL_ASSIGNSEL_II functions typedef struct packed { logic [3:0] a; logic [11:0] b; } in1_t; // 4 + 12 = 16 typedef struct packed { logic [11:0] b; logic [3:0] a; } out1_t; // struct in2_t should cover all VL_ASSIGNSEL_II functions typedef struct packed { logic [2:0] a; logic [8:0] b; logic [18:0] c; } in2_t; // 3 + 9 + 19 = 31 typedef struct packed { logic [8:0] b; logic [18:0] c; logic [2:0] a; } out2_t; // struct in3_t should cover all VL_ASSIGNSEL_XQ functions typedef struct packed { logic [1:0] a; logic [8:0] b; logic [16:0] c; logic [32:0] d; } in3_t; // 33 + 17 + 9 + 2 = 61 typedef struct packed { logic [8:0] b; logic [1:0] a; logic [32:0] d; logic [16:0] c; } out3_t; // struct in4_t should cover all VL_ASSIGNSEL_XW functions typedef struct packed { logic [4:0] a; logic [12:0] b; logic [24:0] c; logic [48:0] d; logic [80:0] e; } in4_t; // 5 + 13 + 25 + 49 + 81 = 173 typedef struct packed { logic [24:0] c; logic [48:0] d; logic [80:0] e; logic [4:0] a; logic [12:0] b; } out4_t; */ #define CONCAT_IMPL(a, b) a##b #define CONCAT(a, b) CONCAT_IMPL(a, b) #define CONCAT5(a, b, c, d, e) CONCAT(CONCAT(CONCAT(CONCAT(a, b), c), d), e) #define EXPORTED_STRUCT_NAME(STRUCT_NAME, NUMBER) \ CONCAT5(VM_PREFIX, _, STRUCT_NAME, __struct__, NUMBER) #define EXPORTED_UNION_NAME(UNION_NAME, NUMBER) \ CONCAT5(VM_PREFIX, _, UNION_NAME, __union__, NUMBER) #define SUB_T EXPORTED_UNION_NAME(sub_t, 0) #define IN_T EXPORTED_STRUCT_NAME(in_t, 0) #define OUT_T EXPORTED_STRUCT_NAME(out_t, 0) #define IN1_T EXPORTED_STRUCT_NAME(in1_t, 0) #define IN2_T EXPORTED_STRUCT_NAME(in2_t, 0) #define IN3_T EXPORTED_STRUCT_NAME(in3_t, 0) #define IN4_T EXPORTED_STRUCT_NAME(in4_t, 0) #define OUT1_T EXPORTED_STRUCT_NAME(out1_t, 0) #define OUT2_T EXPORTED_STRUCT_NAME(out2_t, 0) #define OUT3_T EXPORTED_STRUCT_NAME(out3_t, 0) #define OUT4_T EXPORTED_STRUCT_NAME(out4_t, 0) int errors = 0; int main(int argc, char** argv) { const std::unique_ptr contextp{new VerilatedContext}; contextp->debug(0); contextp->randReset(2); contextp->commandArgs(argc, argv); const std::unique_ptr adder{new VM_PREFIX{contextp.get()}}; { IN_T in1, in2; OUT_T out; in1.a = 0x12345678; in1.__SYM__nullptr[0] = 0x1; in1.__SYM__nullptr[1] = 0x2; in1.__SYM__nullptr[2] = 0x3; in1.__SYM__nullptr[3] = 0x4; in1.get__0.a = 0x5; in2.a = 0x11111111; in2.__SYM__nullptr[0] = 0x10; in2.__SYM__nullptr[1] = 0x20; in2.__SYM__nullptr[2] = 0x30; in2.__SYM__nullptr[3] = 0x30; in2.get__0.a = 0x20; adder->op1 = in1.get(); adder->op2 = in2.get(); adder->eval(); out.set(adder->out); TEST_CHECK_EQ(out.__SYM__nullptr[0], 0x11); TEST_CHECK_EQ(out.__SYM__nullptr[1], 0x22); TEST_CHECK_EQ(out.__SYM__nullptr[2], 0x33); TEST_CHECK_EQ(out.__SYM__nullptr[3], 0x34); TEST_CHECK_EQ(out.get__0.a, 0x25); TEST_CHECK_EQ(out.a, 0x23456789); // Additional tests IN1_T op1a, op1b; OUT1_T out1; op1a.a = 0x4; op1b.a = 0x5; op1a.b = 0x1fe; op1b.b = 0x1ef; adder->op1a = op1a.get(); adder->op1b = op1b.get(); adder->eval(); out1.set(adder->out1); TEST_CHECK_EQ(out1.a, op1a.a + op1b.a); TEST_CHECK_EQ(out1.b, op1a.b + op1b.b); IN2_T op2a, op2b; OUT2_T out2; op2a.a = 0x4; op2b.a = 0x3; op2a.b = 0xff; op2b.b = 0x1; op2a.c = 0x11212; op2b.c = 0x12121; adder->op2a = op2a.get(); adder->op2b = op2b.get(); adder->eval(); out2.set(adder->out2); TEST_CHECK_EQ(out2.a, op2a.a + op2b.a); TEST_CHECK_EQ(out2.b, op2a.b + op2b.b); TEST_CHECK_EQ(out2.c, op2a.c + op2b.c); IN3_T op3a, op3b; OUT3_T out3; op3a.a = 0x1; op3b.a = 0x2; op3a.b = 0x155; op3b.b = 0x44; op3a.c = 0xff; op3b.c = 0xff00; op3a.d = 0x123232323ULL; op3b.d = 0x32323232ULL; adder->op3a = op3a.get(); adder->op3b = op3b.get(); adder->eval(); out3.set(adder->out3); TEST_CHECK_EQ(out3.a, op3a.a + op3b.a); TEST_CHECK_EQ(out3.b, op3a.b + op3b.b); TEST_CHECK_EQ(out3.c, op3a.c + op3b.c); TEST_CHECK_EQ(out3.d, op3a.d + op3b.d); IN4_T op4a, op4b; OUT4_T out4; op4a.a = 0xf; op4b.a = 0x2; op4a.b = 0x123; op4b.b = 0x432; op4a.c = 0x123456; op4b.c = 0x654321; op4a.d = 0x123456789ULL; op4b.d = 0x987654321ULL; op4a.e[0] = 0x12345678; op4b.e[0] = 0x87654321; op4a.e[1] = 0xabcde000; op4b.e[1] = 0x000cdeba; op4a.e[2] = 0xe; op4b.e[2] = 0xf; adder->op4a = op4a.get(); adder->op4b = op4b.get(); adder->eval(); out4.set(adder->out4); TEST_CHECK_EQ(out4.a, op4a.a + op4b.a); TEST_CHECK_EQ(out4.b, op4a.b + op4b.b); TEST_CHECK_EQ(out4.c, op4a.c + op4b.c); TEST_CHECK_EQ(out4.d, op4a.d + op4b.d); TEST_CHECK_EQ(out4.e[0], op4a.e[0] + op4b.e[0]); TEST_CHECK_EQ(out4.e[1], op4a.e[1] + op4b.e[1]); TEST_CHECK_EQ(out4.e[2], op4a.e[2] + op4b.e[2]); } printf("*-* All Finished *-*\n"); return errors; }