Skip to content

Commit b991263

Browse files
authored
Merge pull request #564 from diffblue/aval-bval-concatenation
Verilog: lowering for concatenation of aval/bval encoded vectors
2 parents e2f7b60 + b80d107 commit b991263

File tree

7 files changed

+80
-15
lines changed

7 files changed

+80
-15
lines changed

regression/verilog/case/case3.v

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ module main(input clk, x, y);
1414

1515
always @(posedge clk)
1616
casez (cnt1)
17-
10'b0z00:;
18-
10'b0z01:;
19-
10'b0z1z: out=1;
17+
{10'b0z, 2'b00}:;
18+
{10'b0z, 2'b01}:;
19+
{10'b0z, 2'b1z}: out=1;
2020
endcase
2121

2222
always assert p1: out==0;

regression/verilog/case/case4.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module m(input [7:0] i, output reg [31:0] x);
44
casex(i)
55
8'b1x: x=1;
66
8'bxx: x=2;
7-
8'b11xx: x=3;
7+
{ 'b11, 'bx, 'bx }: x=3;
88
default: x=4;
99
endcase
1010

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE broken-smt-backend
2+
concatenation3.sv
3+
--bound 0
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^\[.*\] always \(\{ 5'bxz01\?, 4'b10zx \}\) === 9'bxz01\?10zx: PROVED up to bound 0$
7+
--
8+
^warning: ignoring
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module main;
2+
assert property ({5'bxz01?, 4'b10zx} === 9'bxz01?10zx);
3+
endmodule

src/verilog/aval_bval_encoding.cpp

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,32 +93,44 @@ constant_exprt lower_to_aval_bval(const constant_exprt &src)
9393

9494
exprt aval(const exprt &src)
9595
{
96-
PRECONDITION(is_aval_bval(src.type()));
97-
auto width = aval_bval_width(src.type());
98-
return extractbits_exprt{
99-
src, from_integer(0, integer_typet()), bv_typet{width}};
96+
if(is_aval_bval(src.type()))
97+
{
98+
auto width = aval_bval_width(src.type());
99+
return extractbits_exprt{src, 0, bv_typet{width}};
100+
}
101+
else
102+
{
103+
auto width = to_bitvector_type(src.type()).get_width();
104+
return typecast_exprt::conditional_cast(src, bv_typet{width});
105+
}
100106
}
101107

102108
exprt bval(const exprt &src)
103109
{
104-
PRECONDITION(is_aval_bval(src.type()));
105-
auto width = aval_bval_width(src.type());
106-
return extractbits_exprt{
107-
src, from_integer(width, integer_typet()), bv_typet{width}};
110+
if(is_aval_bval(src.type()))
111+
{
112+
auto width = aval_bval_width(src.type());
113+
return extractbits_exprt{src, width, bv_typet{width}};
114+
}
115+
else
116+
{
117+
// zeros, signaling 0/1
118+
auto width = to_bitvector_type(src.type()).get_width();
119+
return bv_typet{width}.all_zeros_expr();
120+
}
108121
}
109122

110123
static exprt adjust_size(const exprt &src, std::size_t dest_width)
111124
{
112125
auto src_width = to_bv_type(src.type()).get_width();
113126
if(dest_width > src_width)
114127
{
115-
auto zeros = from_integer(0, bv_typet{dest_width - src_width});
128+
auto zeros = bv_typet{dest_width - src_width}.all_zeros_expr();
116129
return concatenation_exprt{{zeros, src}, bv_typet{dest_width}};
117130
}
118131
else if(dest_width < src_width)
119132
{
120-
return extractbits_exprt{
121-
src, from_integer(0, integer_typet{}), bv_typet{dest_width}};
133+
return extractbits_exprt{src, 0, bv_typet{dest_width}};
122134
}
123135
else
124136
return src;
@@ -152,3 +164,27 @@ exprt aval_bval_conversion(const exprt &src, const typet &dest)
152164
return combine_aval_bval(new_aval, new_bval, dest);
153165
}
154166
}
167+
168+
static exprt concatenate(const exprt::operandst &operands)
169+
{
170+
std::size_t width = 0;
171+
for(auto &op : operands)
172+
width += to_bv_type(op.type()).get_width();
173+
174+
return concatenation_exprt{operands, bv_typet{width}};
175+
}
176+
177+
exprt aval_bval_concatenation(
178+
const exprt::operandst &operands,
179+
const typet &type)
180+
{
181+
exprt::operandst new_aval, new_bval;
182+
183+
for(auto &op : operands)
184+
{
185+
new_aval.push_back(aval(op));
186+
new_bval.push_back(bval(op));
187+
}
188+
189+
return combine_aval_bval(concatenate(new_aval), concatenate(new_bval), type);
190+
}

src/verilog/aval_bval_encoding.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ exprt bval(const exprt &);
3434

3535
exprt aval_bval_conversion(const exprt &, const typet &);
3636

37+
exprt aval_bval_concatenation(const exprt::operandst &, const typet &);
38+
3739
#endif

src/verilog/verilog_synthesis.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,22 @@ exprt verilog_synthesist::synth_expr(exprt expr, symbol_statet symbol_state)
217217

218218
return expr;
219219
}
220+
else if(expr.id() == ID_concatenation)
221+
{
222+
for(auto &op : expr.operands())
223+
op = synth_expr(op, symbol_state);
224+
225+
if(
226+
expr.type().id() == ID_verilog_unsignedbv ||
227+
expr.type().id() == ID_verilog_signedbv)
228+
{
229+
return aval_bval_concatenation(
230+
to_concatenation_expr(expr).operands(),
231+
lower_to_aval_bval(expr.type()));
232+
}
233+
234+
return expr;
235+
}
220236
else if(expr.id()==ID_function_call)
221237
{
222238
return expand_function_call(to_function_call_expr(expr));

0 commit comments

Comments
 (0)