Skip to content

Commit f384eac

Browse files
Merge pull request #4815 from YosysHQ/verific_bounds_fix
Verific frontend: fix `top_bound`/`bottom_bound` attributes
2 parents e32e199 + 378864d commit f384eac

File tree

5 files changed

+330
-24
lines changed

5 files changed

+330
-24
lines changed

frontends/verific/verific.cc

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ static const std::string verific_unescape(const char *value)
407407
}
408408
#endif
409409

410-
void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl)
410+
void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl, int wire_width_hint)
411411
{
412412
if (!obj)
413413
return;
@@ -433,10 +433,18 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att
433433
auto type_range = nl->GetTypeRange(obj->Name());
434434
if (!type_range)
435435
return;
436-
if (type_range->IsTypeScalar()) {
436+
if (nl->IsFromVhdl() && type_range->IsTypeScalar()) {
437437
const long long bottom_bound = type_range->GetScalarRangeLeftBound();
438438
const long long top_bound = type_range->GetScalarRangeRightBound();
439-
const unsigned bit_width = type_range->NumElements();
439+
int bit_width = type_range->LeftRangeBound()+1;
440+
if (bit_width <= 0) { // VHDL null range
441+
if (wire_width_hint >= 0)
442+
bit_width = wire_width_hint;
443+
else
444+
bit_width = 64; //fallback, currently largest integer width that verific will allow (in vhdl2019 mode)
445+
} else {
446+
if (wire_width_hint >= 0) log_assert(bit_width == wire_width_hint);
447+
}
440448
RTLIL::Const bottom_const(bottom_bound, bit_width);
441449
RTLIL::Const top_const(top_bound, bit_width);
442450
if (bottom_bound < 0 || top_bound < 0) {
@@ -1499,7 +1507,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
14991507
log(" importing port %s.\n", port->Name());
15001508

15011509
RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(port->Name()));
1502-
import_attributes(wire->attributes, port, nl);
1510+
import_attributes(wire->attributes, port, nl, 1);
15031511

15041512
wire->port_id = nl->IndexOf(port) + 1;
15051513

@@ -1527,11 +1535,11 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
15271535
RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(portbus->Name()), portbus->Size());
15281536
wire->start_offset = min(portbus->LeftIndex(), portbus->RightIndex());
15291537
wire->upto = portbus->IsUp();
1530-
import_attributes(wire->attributes, portbus, nl);
1538+
import_attributes(wire->attributes, portbus, nl, portbus->Size());
15311539
SetIter si ;
15321540
Port *port ;
15331541
FOREACH_PORT_OF_PORTBUS(portbus, si, port) {
1534-
import_attributes(wire->attributes, port->GetNet(), nl);
1542+
import_attributes(wire->attributes, port->GetNet(), nl, portbus->Size());
15351543
break;
15361544
}
15371545
bool portbus_input = portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN;
@@ -1693,7 +1701,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
16931701
log(" importing net %s as %s.\n", net->Name(), log_id(wire_name));
16941702

16951703
RTLIL::Wire *wire = module->addWire(wire_name);
1696-
import_attributes(wire->attributes, net, nl);
1704+
import_attributes(wire->attributes, net, nl, 1);
16971705

16981706
net_map[net] = wire;
16991707
}
@@ -1722,10 +1730,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
17221730
MapIter mibus;
17231731
FOREACH_NET_OF_NETBUS(netbus, mibus, net) {
17241732
if (net)
1725-
import_attributes(wire->attributes, net, nl);
1733+
import_attributes(wire->attributes, net, nl, netbus->Size());
17261734
break;
17271735
}
1728-
import_attributes(wire->attributes, netbus, nl);
1736+
import_attributes(wire->attributes, netbus, nl, netbus->Size());
17291737

17301738
RTLIL::Const initval = Const(State::Sx, GetSize(wire));
17311739
bool initval_valid = false;

frontends/verific/verific.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ struct VerificImporter
8181
RTLIL::SigBit net_map_at(Verific::Net *net);
8282

8383
RTLIL::IdString new_verific_id(Verific::DesignObj *obj);
84-
void import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, Verific::DesignObj *obj, Verific::Netlist *nl = nullptr);
84+
void import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, Verific::DesignObj *obj, Verific::Netlist *nl = nullptr, int wire_width_hint = -1);
8585

8686
RTLIL::SigBit netToSigBit(Verific::Net *net);
8787
RTLIL::SigSpec operatorInput(Verific::Instance *inst);

tests/verific/bounds.sv

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
typedef enum {IDLE, RUN, STOP} state_t;
2+
3+
typedef struct {
4+
logic [7:0] field1;
5+
int field2;
6+
} my_struct_t;
7+
8+
// Submodule to handle the interface ports
9+
module submodule (
10+
my_ifc i_ifc,
11+
my_ifc o_ifc
12+
);
13+
// Connect the interface signals
14+
assign o_ifc.data = i_ifc.data;
15+
endmodule
16+
17+
module test (
18+
input i_a,
19+
output o_a,
20+
input [0:0] i_b,
21+
output [0:0] o_b,
22+
input [3:0] i_c,
23+
output [3:0] o_c,
24+
input logic i_d,
25+
output logic o_d,
26+
input bit [7:0] i_e,
27+
output bit [7:0] o_e,
28+
input int i_f,
29+
output int o_f,
30+
input state_t i_h,
31+
output state_t o_h,
32+
input my_struct_t i_i,
33+
output my_struct_t o_i
34+
);
35+
36+
assign o_a = i_a;
37+
assign o_b = i_b;
38+
assign o_c = i_c;
39+
assign o_d = i_d;
40+
assign o_e = i_e;
41+
assign o_f = i_f;
42+
assign o_h = i_h;
43+
assign o_i = i_i;
44+
45+
endmodule

tests/verific/bounds.vhd

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,108 @@ library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
33
use IEEE.NUMERIC_STD.ALL;
44

5-
entity work is
5+
entity test is
66
Port (
7-
a : in INTEGER range -5 to 10;
8-
b : out INTEGER range -6 to 11
7+
-- BIT type
8+
bit_in : in BIT;
9+
bit_out : out BIT;
10+
11+
-- BIT_VECTOR type
12+
bit_vector_in : in BIT_VECTOR(3 downto 0);
13+
bit_vector_out : out BIT_VECTOR(3 downto 0);
14+
15+
-- BIT_VECTOR type with to index
16+
bit_vector_in_to : in BIT_VECTOR(0 to 3);
17+
bit_vector_out_to : out BIT_VECTOR(0 to 3);
18+
19+
-- STD_ULOGIC type
20+
std_ulogic_in : in STD_ULOGIC;
21+
std_ulogic_out : out STD_ULOGIC;
22+
23+
-- STD_ULOGIC_VECTOR type
24+
std_ulogic_vector_in : in STD_ULOGIC_VECTOR(3 downto 0);
25+
std_ulogic_vector_out : out STD_ULOGIC_VECTOR(3 downto 0);
26+
27+
-- STD_ULOGIC_VECTOR type with to index
28+
std_ulogic_vector_in_to : in STD_ULOGIC_VECTOR(0 to 3);
29+
std_ulogic_vector_out_to : out STD_ULOGIC_VECTOR(0 to 3);
30+
31+
-- STD_LOGIC type
32+
std_logic_in : in STD_LOGIC;
33+
std_logic_out : out STD_LOGIC;
34+
35+
-- STD_LOGIC_VECTOR type
36+
std_logic_vector_in : in STD_LOGIC_VECTOR(3 downto 0);
37+
std_logic_vector_out : out STD_LOGIC_VECTOR(3 downto 0);
38+
39+
-- STD_LOGIC_VECTOR type with to index
40+
std_logic_vector_in_to : in STD_LOGIC_VECTOR(0 to 3);
41+
std_logic_vector_out_to : out STD_LOGIC_VECTOR(0 to 3);
42+
43+
-- SIGNED type
44+
signed_in : in SIGNED(3 downto 0);
45+
signed_out : out SIGNED(3 downto 0);
46+
47+
-- SIGNED type with to index
48+
signed_in_to : in SIGNED(0 to 3);
49+
signed_out_to : out SIGNED(0 to 3);
50+
51+
-- UNSIGNED type
52+
unsigned_in : in UNSIGNED(3 downto 0);
53+
unsigned_out : out UNSIGNED(3 downto 0);
54+
55+
-- UNSIGNED type with to index
56+
unsigned_in_to : in UNSIGNED(0 to 3);
57+
unsigned_out_to : out UNSIGNED(0 to 3);
58+
59+
-- INTEGER type without range
60+
integer_in : in INTEGER;
61+
integer_out : out INTEGER;
62+
63+
-- INTEGER type with range
64+
integer_with_range_in : in INTEGER range -5 to 10;
65+
integer_with_range_out : out INTEGER range -6 to 10;
66+
67+
-- INTEGER type with single value range
68+
integer_single_value_in : in INTEGER range 5 to 5;
69+
integer_single_value_out : out INTEGER range 5 to 5;
70+
71+
-- INTEGER type with null range
72+
integer_null_range_in : in INTEGER range 7 to -1;
73+
integer_null_range_out : out INTEGER range 0 to -1;
74+
75+
-- NATURAL type
76+
natural_in : in NATURAL;
77+
natural_out : out NATURAL;
78+
79+
-- POSITIVE type
80+
positive_in : in POSITIVE;
81+
positive_out : out POSITIVE
982
);
10-
end entity work;
83+
end entity test;
1184

12-
architecture Behavioral of work is
85+
architecture Behavioral of test is
86+
signal integer_with_range : INTEGER range -1 to 100;
1387
begin
14-
process(a)
15-
begin
16-
b <= a;
17-
end process;
88+
bit_out <= bit_in;
89+
bit_vector_out <= bit_vector_in;
90+
bit_vector_out_to <= bit_vector_in_to;
91+
std_ulogic_out <= std_ulogic_in;
92+
std_ulogic_vector_out <= std_ulogic_vector_in;
93+
std_ulogic_vector_out_to <= std_ulogic_vector_in_to;
94+
std_logic_out <= std_logic_in;
95+
std_logic_vector_out <= std_logic_vector_in;
96+
std_logic_vector_out_to <= std_logic_vector_in_to;
97+
signed_out <= signed_in;
98+
signed_out_to <= signed_in_to;
99+
unsigned_out <= unsigned_in;
100+
unsigned_out_to <= unsigned_in_to;
101+
integer_with_range_out <= integer_with_range_in;
102+
integer_out <= integer_in;
103+
integer_single_value_out <= integer_single_value_in;
104+
integer_null_range_out <= integer_null_range_in;
105+
natural_out <= natural_in;
106+
positive_out <= positive_in;
107+
108+
integer_with_range <= 42;
18109
end architecture Behavioral;

0 commit comments

Comments
 (0)