@@ -30,6 +30,136 @@ Author: Daniel Kroening, kroening@kroening.com
3030
3131/* ******************************************************************\
3232
33+ Function: verilog_synthesist::extract
34+
35+ Inputs:
36+
37+ Outputs:
38+
39+ Purpose:
40+
41+ \*******************************************************************/
42+
43+ exprt verilog_synthesist::extract (
44+ const exprt &src,
45+ const mp_integer &offset,
46+ const typet &dest_type)
47+ {
48+ auto src_width = to_bitvector_type (src.type ()).get_width ();
49+ auto dest_width = get_width (dest_type);
50+
51+ // first add padding, if src is too small
52+ exprt padded_src;
53+ auto padding_width = dest_width + offset - src_width;
54+
55+ if (padding_width > 0 )
56+ {
57+ auto padded_width_int =
58+ numeric_cast_v<std::size_t >(src_width + padding_width);
59+ padded_src = concatenation_exprt{
60+ {unsignedbv_typet{numeric_cast_v<std::size_t >(padding_width)}.zero_expr (),
61+ src},
62+ bv_typet{padded_width_int}};
63+ }
64+ else // large enough
65+ padded_src = src;
66+
67+ // now extract
68+ if (dest_type.id () == ID_bool)
69+ {
70+ return extractbit_exprt{padded_src, from_integer (offset, integer_typet{})};
71+ }
72+ else
73+ {
74+ return extractbits_exprt{
75+ padded_src, from_integer (offset, integer_typet{}), dest_type};
76+ }
77+ }
78+
79+ /* ******************************************************************\
80+
81+ Function: verilog_synthesist::from_bitvector
82+
83+ Inputs:
84+
85+ Outputs:
86+
87+ Purpose:
88+
89+ \*******************************************************************/
90+
91+ exprt verilog_synthesist::from_bitvector (
92+ const exprt &src,
93+ const mp_integer &offset,
94+ const typet &dest)
95+ {
96+ if (dest.id () == ID_struct)
97+ {
98+ const auto &struct_type = to_struct_type (dest);
99+ exprt::operandst field_values;
100+ field_values.reserve (struct_type.components ().size ());
101+
102+ // start from the top; the first field is the most significant
103+ mp_integer component_offset = get_width (dest);
104+
105+ for (auto &component : struct_type.components ())
106+ {
107+ auto width = get_width (component.type ());
108+ component_offset -= width;
109+ // rec. call
110+ field_values.push_back (
111+ from_bitvector (src, offset + component_offset, component.type ()));
112+ }
113+
114+ return struct_exprt{std::move (field_values), struct_type};
115+ }
116+ else
117+ {
118+ return extract (src, offset, dest);
119+ }
120+ }
121+
122+ /* ******************************************************************\
123+
124+ Function: verilog_synthesist::to_bitvector
125+
126+ Inputs:
127+
128+ Outputs:
129+
130+ Purpose:
131+
132+ \*******************************************************************/
133+
134+ exprt verilog_synthesist::to_bitvector (const exprt &src)
135+ {
136+ const auto &src_type = src.type ();
137+
138+ if (src_type.id () == ID_struct)
139+ {
140+ const auto &struct_type = to_struct_type (src_type);
141+ exprt::operandst field_values;
142+ field_values.reserve (struct_type.components ().size ());
143+
144+ // the first struct member is the most significant
145+ for (auto &component : struct_type.components ())
146+ {
147+ auto member = member_exprt{src, component};
148+ auto field_value = to_bitvector (member); // rec. call
149+ field_values.push_back (std::move (field_value));
150+ }
151+
152+ auto width_int = numeric_cast_v<std::size_t >(get_width (src));
153+ return concatenation_exprt{std::move (field_values), bv_typet{width_int}};
154+ }
155+ else
156+ {
157+ return src;
158+ }
159+ }
160+
161+ /* ******************************************************************\
162+
33163Function: verilog_synthesist::synth_expr
34164
35165 Inputs:
@@ -100,23 +230,45 @@ exprt verilog_synthesist::synth_expr(exprt expr, symbol_statet symbol_state)
100230 }
101231 else if (expr.id ()==ID_typecast)
102232 {
103- auto &typecast_expr = to_typecast_expr (expr);
104- typecast_expr.op () = synth_expr (typecast_expr.op (), symbol_state);
233+ {
234+ auto &op = to_typecast_expr (expr).op ();
235+ op = synth_expr (op, symbol_state);
105236
106- // we perform some form of simplification for these
107- if (typecast_expr.op ().is_constant ())
108- simplify (expr, ns);
237+ // we perform some form of simplification for these
238+ if (op.is_constant ())
239+ simplify (expr, ns);
240+ }
109241
110- if (
111- expr.type ().id () == ID_verilog_unsignedbv ||
112- expr.type ().id () == ID_verilog_signedbv)
242+ if (expr.id () == ID_typecast)
113243 {
114- auto aval_bval_type = lower_to_aval_bval (expr.type ());
244+ auto &typecast_expr = to_typecast_expr (expr);
245+ typecast_expr.op () = synth_expr (typecast_expr.op (), symbol_state);
115246
116- if (is_aval_bval (typecast_expr.op ().type ()))
247+ const auto &src_type = typecast_expr.op ().type ();
248+ const auto &dest_type = typecast_expr.type ();
249+
250+ if (
251+ dest_type.id () == ID_verilog_unsignedbv ||
252+ dest_type.id () == ID_verilog_signedbv)
253+ {
254+ auto aval_bval_type = lower_to_aval_bval (dest_type);
255+
256+ if (is_aval_bval (src_type))
257+ {
258+ // separately convert aval and bval
259+ return aval_bval_conversion (typecast_expr.op (), aval_bval_type);
260+ }
261+ }
262+ else if (dest_type.id () == ID_struct)
117263 {
118- // separately convert aval and bval
119- return aval_bval_conversion (typecast_expr.op (), aval_bval_type);
264+ return from_bitvector (typecast_expr.op (), 0 , dest_type);
265+ }
266+ else
267+ {
268+ if (src_type.id () == ID_struct)
269+ {
270+ return extract (to_bitvector (typecast_expr.op ()), 0 , dest_type);
271+ }
120272 }
121273 }
122274
0 commit comments