1 // -*- mode: C++; c-file-style: "cc-mode" -*-
2 //*************************************************************************
3 // DESCRIPTION: Verilator: Netlist (top level) functions
4 //
5 // Code available from: https://verilator.org
6 //
7 //*************************************************************************
8 //
9 // Copyright 2003-2021 by Wilson Snyder. This program is free software; you
10 // can redistribute it and/or modify it under the terms of either the GNU
11 // Lesser General Public License Version 3 or the Perl Artistic License
12 // Version 2.0.
13 // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
14 //
15 //*************************************************************************
16 
17 // CHEAT!
18 #define V3NUMBER_ASCII_BINARY
19 #define V3ERROR_NO_GLOBAL_
20 
21 #include <config_build.h>
22 #include "verilatedos.h"
23 
24 #include "V3Error.cpp"
25 #include "V3FileLine.cpp"
26 #include "V3Number.cpp"
27 #include "V3Number.h"
28 
29 #include <algorithm>
30 #include <cstdarg>
31 
test(const string & lhss,const string & op,const string & rhss,const string & exps)32 void test(const string& lhss, const string& op, const string& rhss, const string& exps) {
33     char* l1 = strdup(lhss.c_str());
34     char* r1 = strdup(rhss.c_str());
35     char* e1 = strdup(exps.c_str());
36 
37     const FileLine fl = new FileLine(FileLine::builtInFinename());
38 
39     V3Number lhnum(fl, l1);
40     V3Number rhnum(fl, r1);
41     V3Number expnum(fl, e1);
42     V3Number gotnum(fl, expnum.width());
43 
44     if (op == "redOr") {
45         gotnum.opRedOr(lhnum);
46     } else if (op == "redAnd") {
47         gotnum.opRedAnd(lhnum);
48     } else if (op == "redXor") {
49         gotnum.opRedXor(lhnum);
50     } else if (op == "concat") {
51         gotnum.opConcat(lhnum, rhnum);
52     } else if (op == "repl") {
53         gotnum.opRepl(lhnum, rhnum);
54     } else if (op == "~") {
55         gotnum.opNot(lhnum);
56     } else if (op == "!") {
57         gotnum.opLogNot(lhnum);
58     } else if (op == "negate") {
59         gotnum.opNegate(lhnum);
60     } else if (op == "+") {
61         gotnum.opAdd(lhnum, rhnum);
62     } else if (op == "-") {
63         gotnum.opSub(lhnum, rhnum);
64     } else if (op == "*") {
65         gotnum.opMul(lhnum, rhnum);
66     } else if (op == "/") {
67         gotnum.opDiv(lhnum, rhnum);
68     } else if (op == "%") {
69         gotnum.opModDiv(lhnum, rhnum);
70     } else if (op == "&") {
71         gotnum.opAnd(lhnum, rhnum);
72     } else if (op == "|") {
73         gotnum.opOr(lhnum, rhnum);
74     } else if (op == "<") {
75         gotnum.opLt(lhnum, rhnum);
76     } else if (op == ">") {
77         gotnum.opGt(lhnum, rhnum);
78     } else if (op == ">>") {
79         gotnum.opShiftR(lhnum, rhnum);
80     } else if (op == "<<") {
81         gotnum.opShiftL(lhnum, rhnum);
82     } else if (op == "==") {
83         gotnum.opEq(lhnum, rhnum);
84     } else if (op == "===") {
85         gotnum.opCaseEq(lhnum, rhnum);
86     } else if (op == "==?") {
87         gotnum.opWildEq(lhnum, rhnum);
88     } else if (op == "!=") {
89         gotnum.opNeq(lhnum, rhnum);
90     } else if (op == "!==") {
91         gotnum.opCaseNeq(lhnum, rhnum);
92     } else if (op == "!=?") {
93         gotnum.opWildNeq(lhnum, rhnum);
94     } else if (op == "<=") {
95         gotnum.opLte(lhnum, rhnum);
96     } else if (op == ">=") {
97         gotnum.opGte(lhnum, rhnum);
98     } else if (op == "&&") {
99         gotnum.opLogAnd(lhnum, rhnum);
100     } else if (op == "||") {
101         gotnum.opLogOr(lhnum, rhnum);
102     } else
103         v3fatalSrc("Bad opcode: " << op);
104 
105     UINFO(0, "------- Test:\n"
106                  << "       " << lhnum << " " << op << endl
107                  << "       " << rhnum << endl
108                  << "     = " << expnum << endl
109                  << "    =? " << gotnum << endl);
110 
111     V3Number ok(fl, 1);
112     ok.opCaseEq(expnum, gotnum);
113     if (ok.toUInt() != 1) v3fatalSrc("%Error:Test FAILED");
114 
115     free(l1);
116     free(r1);
117     free(e1);
118 }
119 
main()120 int main() {
121     UINFO(0, "Test starting\n");
122 
123     test("32'b10", "|", "32'b10", "32'b10");
124     test("2'bx0", "|", "2'b10", "2'b10");
125     test("32'b0x", "|", "32'b10", "32'b1x");
126     test("32'b10", "&", "32'b11", "32'b10");
127     test("32'b10", "+", "32'b10", "32'b100");
128     test("3'b000", "negate", "", "3'b000");
129     test("3'b001", "negate", "", "3'b111");
130     test("32'b11", "-", "32'b001", "32'b10");
131     test("3'b000", "-", "3'b111", "3'b001");
132     test("3'b000", "-", "3'b000", "3'b000");
133     test("57'h000000010F0CCE7", "*", "57'h10", "57'h10F0CCE70");
134     test("57'h000000010F0CCE7", "*", "57'h0DE34E7FFFFFFFF", "57'h02A9D57EF0F3319");
135     test("67'h7FFFFFFFFFFFFFFFF", "*", "67'h4000000003C8A8D6A", "67'h3FFFFFFFFC3757296");
136     test("99'h7FFFFFFFFFFFFFFFFFFFFFFFF", "*", "99'h0000000000000000091338A80",
137          "99'h7FFFFFFFFFFFFFFFF6ECC7580");
138 
139     cout << "Test completed\n";
140 }
141 
142 //###################################################################
143 // Local Variables:
144 // compile-command: "make V3Number_test && ./V3Number_test "
145 // End:
146