Skip to content

Commit 51fa81e

Browse files
authored
Merge pull request #824 from diffblue/verilog-real-literals
Verilog: conversion for real literals
2 parents 522b68e + 56bcfe5 commit 51fa81e

File tree

6 files changed

+137
-13
lines changed

6 files changed

+137
-13
lines changed

regression/verilog/expressions/real-index.sv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ module main;
22

33
// 1800-2017 6.12.1
44
reg [7:0] vector;
5-
wire x = vector[real'(1.5)];
5+
wire x = vector[1.5];
66

77
endmodule

regression/verilog/system-functions/typename1.sv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ module main;
99
assert final ($typename(vector1)=="bit[31:0]");
1010
assert final ($typename(vector2)=="bit[0:31]");
1111
assert final ($typename(vector3)=="bit signed[31:0]");
12+
assert final ($typename(real'(1))=="real");
13+
assert final ($typename(shortreal'(1))=="shortreal");
14+
assert final ($typename(realtime'(1))=="realtime");
1215

1316
// $typename yields an elaboration-time constant
1417
parameter P = $typename(some_bit);

src/verilog/expr2verilog.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include <util/arith_tools.h>
1313
#include <util/bitvector_types.h>
14+
#include <util/ieee_float.h>
1415
#include <util/lispexpr.h>
1516
#include <util/lispirep.h>
1617
#include <util/namespace.h>
@@ -1120,6 +1121,14 @@ expr2verilogt::resultt expr2verilogt::convert_constant(
11201121
const irep_idt &value = src.get_value();
11211122
dest=id2string(value);
11221123
}
1124+
else if(type.id() == ID_verilog_real)
1125+
{
1126+
constant_exprt tmp = src;
1127+
tmp.type() = ieee_float_spect::double_precision().to_type();
1128+
ieee_floatt ieee_float;
1129+
ieee_float.from_expr(tmp);
1130+
return {precedence, ieee_float.to_ansi_c_string()};
1131+
}
11231132
else
11241133
return convert_norep(src, precedence);
11251134

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111
#include <util/bitvector_expr.h>
1212
#include <util/ebmc_util.h>
1313
#include <util/expr_util.h>
14+
#include <util/ieee_float.h>
1415
#include <util/mathematical_expr.h>
1516
#include <util/mathematical_types.h>
1617
#include <util/namespace.h>
@@ -694,6 +695,18 @@ exprt verilog_typecheck_exprt::typename_string(const exprt &expr)
694695
{
695696
s = "bit signed[" + to_string(left) + ":" + to_string(right) + "]";
696697
}
698+
else if(type.id() == ID_verilog_realtime)
699+
{
700+
s = "realtime";
701+
}
702+
else if(type.id() == ID_verilog_real)
703+
{
704+
s = "real";
705+
}
706+
else if(type.id() == ID_verilog_shortreal)
707+
{
708+
s = "shortreal";
709+
}
697710
else
698711
s = "?";
699712

@@ -1276,6 +1289,77 @@ exprt verilog_typecheck_exprt::convert_constant(constant_exprt expr)
12761289
}
12771290

12781291
// check representation
1292+
if(
1293+
rest.find('.') != std::string::npos ||
1294+
(rest.find('h') == std::string::npos &&
1295+
rest.find('e') != std::string::npos)) // real?
1296+
{
1297+
const char *p = rest.c_str();
1298+
1299+
std::string str_whole_number, str_fraction_part, str_exponent;
1300+
1301+
// get whole number part
1302+
while(*p != '.' && *p != 0 && *p != 'e')
1303+
{
1304+
str_whole_number += *p;
1305+
p++;
1306+
}
1307+
1308+
// skip dot
1309+
if(*p == '.')
1310+
p++;
1311+
1312+
// get fraction part
1313+
while(*p != 0 && *p != 'e')
1314+
{
1315+
str_fraction_part += *p;
1316+
p++;
1317+
}
1318+
1319+
// skip e
1320+
if(*p == 'e')
1321+
p++;
1322+
1323+
// skip +
1324+
if(*p == '+')
1325+
p++;
1326+
1327+
// get exponent
1328+
while(*p != 0)
1329+
{
1330+
str_exponent += *p;
1331+
p++;
1332+
}
1333+
1334+
std::string str_number = str_whole_number + str_fraction_part;
1335+
1336+
mp_integer significand;
1337+
1338+
if(str_number.empty())
1339+
significand = 0;
1340+
else
1341+
significand = string2integer(str_number, 10);
1342+
1343+
mp_integer exponent;
1344+
1345+
if(str_exponent.empty())
1346+
exponent = 0;
1347+
else
1348+
exponent = string2integer(str_exponent, 10);
1349+
1350+
// adjust exponent
1351+
exponent -= str_fraction_part.size();
1352+
1353+
ieee_floatt ieee_float{ieee_float_spect::double_precision()};
1354+
1355+
ieee_float.from_base10(significand, exponent);
1356+
1357+
constant_exprt result = ieee_float.to_expr();
1358+
result.type() = verilog_real_typet{};
1359+
result.add_source_location() = expr.source_location();
1360+
1361+
return std::move(result);
1362+
}
12791363

12801364
std::string::size_type pos=rest.find('\'');
12811365
std::size_t bits = 0;
@@ -2104,7 +2188,10 @@ void verilog_typecheck_exprt::implicit_typecast(
21042188
expr = typecast_exprt{expr, dest_type};
21052189
return;
21062190
}
2107-
else if(dest_type.id()==ID_verilog_realtime)
2191+
else if(
2192+
dest_type.id() == ID_verilog_realtime ||
2193+
dest_type.id() == ID_verilog_real ||
2194+
dest_type.id() == ID_verilog_shortreal)
21082195
{
21092196
expr = typecast_exprt{expr, dest_type};
21102197
return;
@@ -2188,6 +2275,14 @@ void verilog_typecheck_exprt::implicit_typecast(
21882275
<< '\'';
21892276
}
21902277
}
2278+
else if(src_type.id() == ID_verilog_real)
2279+
{
2280+
if(dest_type.id() == ID_verilog_realtime)
2281+
{
2282+
expr = typecast_exprt{expr, dest_type};
2283+
return;
2284+
}
2285+
}
21912286

21922287
throw errort().with_location(expr.source_location())
21932288
<< "failed to convert `" << to_string(src_type) << "' to `"
@@ -2453,9 +2548,9 @@ typet verilog_typecheck_exprt::max_type(
24532548
return t0;
24542549

24552550
// If one of the operands is a real, we return the real.
2456-
if(vt0.is_verilog_realtime())
2551+
if(vt0.is_verilog_real())
24572552
return t0;
2458-
else if(vt1.is_verilog_realtime())
2553+
else if(vt1.is_verilog_real())
24592554
return t1;
24602555

24612556
bool is_verilogbv=

src/verilog/vtype.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,15 @@ vtypet::vtypet(const typet &type)
6363
vtype=VERILOG_UNSIGNED;
6464
width=to_verilog_unsignedbv_type(type).get_width();
6565
}
66-
else if(type.id()==ID_verilog_realtime)
66+
else if(type.id() == ID_verilog_realtime || type.id() == ID_verilog_real)
6767
{
68-
vtype=VERILOG_REALTIME;
69-
width=0;
68+
vtype = VERILOG_REAL;
69+
width = 64;
70+
}
71+
else if(type.id() == ID_verilog_shortreal)
72+
{
73+
vtype = VERILOG_REAL;
74+
width = 32;
7075
}
7176
else
7277
{
@@ -109,8 +114,8 @@ std::ostream &operator << (std::ostream &out, const vtypet &vtype)
109114
case vtypet::BOOL:
110115
return out << "bool";
111116

112-
case vtypet::VERILOG_REALTIME:
113-
return out << "bool";
117+
case vtypet::VERILOG_REAL:
118+
return out << "real";
114119

115120
case vtypet::UNKNOWN:
116121
case vtypet::OTHER:

src/verilog/vtype.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,25 @@ class vtypet
2727
inline bool is_integer() const { return vtype==INTEGER; }
2828
inline bool is_verilog_signed() const { return vtype==VERILOG_SIGNED; }
2929
inline bool is_verilog_unsigned() const { return vtype==VERILOG_UNSIGNED; }
30-
inline bool is_verilog_realtime() const { return vtype==VERILOG_REALTIME; }
30+
inline bool is_verilog_real() const
31+
{
32+
return vtype == VERILOG_REAL;
33+
}
3134
inline bool is_other() const { return vtype==OTHER; }
3235

3336
protected:
34-
typedef enum { UNKNOWN, BOOL, SIGNED, UNSIGNED, INTEGER,
35-
VERILOG_SIGNED, VERILOG_UNSIGNED,
36-
VERILOG_REALTIME, OTHER } _vtypet;
37+
typedef enum
38+
{
39+
UNKNOWN,
40+
BOOL,
41+
SIGNED,
42+
UNSIGNED,
43+
INTEGER,
44+
VERILOG_SIGNED,
45+
VERILOG_UNSIGNED,
46+
VERILOG_REAL,
47+
OTHER
48+
} _vtypet;
3749
_vtypet vtype;
3850
unsigned width;
3951

0 commit comments

Comments
 (0)