diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 08b8c505dce..d39030c2d0d 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -407,7 +407,7 @@ static const std::string verific_unescape(const char *value) } #endif -void VerificImporter::import_attributes(dict &attributes, DesignObj *obj, Netlist *nl) +void VerificImporter::import_attributes(dict &attributes, DesignObj *obj, Netlist *nl, int wire_width_hint) { if (!obj) return; @@ -433,10 +433,18 @@ void VerificImporter::import_attributes(dict &att auto type_range = nl->GetTypeRange(obj->Name()); if (!type_range) return; - if (type_range->IsTypeScalar()) { + if (nl->IsFromVhdl() && type_range->IsTypeScalar()) { const long long bottom_bound = type_range->GetScalarRangeLeftBound(); const long long top_bound = type_range->GetScalarRangeRightBound(); - const unsigned bit_width = type_range->NumElements(); + int bit_width = type_range->LeftRangeBound()+1; + if (bit_width <= 0) { // VHDL null range + if (wire_width_hint >= 0) + bit_width = wire_width_hint; + else + bit_width = 64; //fallback, currently largest integer width that verific will allow (in vhdl2019 mode) + } else { + if (wire_width_hint >= 0) log_assert(bit_width == wire_width_hint); + } RTLIL::Const bottom_const(bottom_bound, bit_width); RTLIL::Const top_const(top_bound, bit_width); if (bottom_bound < 0 || top_bound < 0) { @@ -1499,7 +1507,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma log(" importing port %s.\n", port->Name()); RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(port->Name())); - import_attributes(wire->attributes, port, nl); + import_attributes(wire->attributes, port, nl, 1); wire->port_id = nl->IndexOf(port) + 1; @@ -1527,11 +1535,11 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(portbus->Name()), portbus->Size()); wire->start_offset = min(portbus->LeftIndex(), portbus->RightIndex()); wire->upto = portbus->IsUp(); - import_attributes(wire->attributes, portbus, nl); + import_attributes(wire->attributes, portbus, nl, portbus->Size()); SetIter si ; Port *port ; FOREACH_PORT_OF_PORTBUS(portbus, si, port) { - import_attributes(wire->attributes, port->GetNet(), nl); + import_attributes(wire->attributes, port->GetNet(), nl, portbus->Size()); break; } 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 log(" importing net %s as %s.\n", net->Name(), log_id(wire_name)); RTLIL::Wire *wire = module->addWire(wire_name); - import_attributes(wire->attributes, net, nl); + import_attributes(wire->attributes, net, nl, 1); net_map[net] = wire; } @@ -1722,10 +1730,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma MapIter mibus; FOREACH_NET_OF_NETBUS(netbus, mibus, net) { if (net) - import_attributes(wire->attributes, net, nl); + import_attributes(wire->attributes, net, nl, netbus->Size()); break; } - import_attributes(wire->attributes, netbus, nl); + import_attributes(wire->attributes, netbus, nl, netbus->Size()); RTLIL::Const initval = Const(State::Sx, GetSize(wire)); bool initval_valid = false; diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h index 0b9616e1944..3c77dd7c3b9 100644 --- a/frontends/verific/verific.h +++ b/frontends/verific/verific.h @@ -81,7 +81,7 @@ struct VerificImporter RTLIL::SigBit net_map_at(Verific::Net *net); RTLIL::IdString new_verific_id(Verific::DesignObj *obj); - void import_attributes(dict &attributes, Verific::DesignObj *obj, Verific::Netlist *nl = nullptr); + void import_attributes(dict &attributes, Verific::DesignObj *obj, Verific::Netlist *nl = nullptr, int wire_width_hint = -1); RTLIL::SigBit netToSigBit(Verific::Net *net); RTLIL::SigSpec operatorInput(Verific::Instance *inst); diff --git a/tests/verific/bounds.sv b/tests/verific/bounds.sv new file mode 100644 index 00000000000..b20d0236904 --- /dev/null +++ b/tests/verific/bounds.sv @@ -0,0 +1,45 @@ +typedef enum {IDLE, RUN, STOP} state_t; + +typedef struct { + logic [7:0] field1; + int field2; +} my_struct_t; + +// Submodule to handle the interface ports +module submodule ( + my_ifc i_ifc, + my_ifc o_ifc +); + // Connect the interface signals + assign o_ifc.data = i_ifc.data; +endmodule + +module test ( + input i_a, + output o_a, + input [0:0] i_b, + output [0:0] o_b, + input [3:0] i_c, + output [3:0] o_c, + input logic i_d, + output logic o_d, + input bit [7:0] i_e, + output bit [7:0] o_e, + input int i_f, + output int o_f, + input state_t i_h, + output state_t o_h, + input my_struct_t i_i, + output my_struct_t o_i +); + + assign o_a = i_a; + assign o_b = i_b; + assign o_c = i_c; + assign o_d = i_d; + assign o_e = i_e; + assign o_f = i_f; + assign o_h = i_h; + assign o_i = i_i; + +endmodule diff --git a/tests/verific/bounds.vhd b/tests/verific/bounds.vhd index 14c6c34a76a..782f3b5adde 100644 --- a/tests/verific/bounds.vhd +++ b/tests/verific/bounds.vhd @@ -2,17 +2,108 @@ library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; -entity work is +entity test is Port ( - a : in INTEGER range -5 to 10; - b : out INTEGER range -6 to 11 + -- BIT type + bit_in : in BIT; + bit_out : out BIT; + + -- BIT_VECTOR type + bit_vector_in : in BIT_VECTOR(3 downto 0); + bit_vector_out : out BIT_VECTOR(3 downto 0); + + -- BIT_VECTOR type with to index + bit_vector_in_to : in BIT_VECTOR(0 to 3); + bit_vector_out_to : out BIT_VECTOR(0 to 3); + + -- STD_ULOGIC type + std_ulogic_in : in STD_ULOGIC; + std_ulogic_out : out STD_ULOGIC; + + -- STD_ULOGIC_VECTOR type + std_ulogic_vector_in : in STD_ULOGIC_VECTOR(3 downto 0); + std_ulogic_vector_out : out STD_ULOGIC_VECTOR(3 downto 0); + + -- STD_ULOGIC_VECTOR type with to index + std_ulogic_vector_in_to : in STD_ULOGIC_VECTOR(0 to 3); + std_ulogic_vector_out_to : out STD_ULOGIC_VECTOR(0 to 3); + + -- STD_LOGIC type + std_logic_in : in STD_LOGIC; + std_logic_out : out STD_LOGIC; + + -- STD_LOGIC_VECTOR type + std_logic_vector_in : in STD_LOGIC_VECTOR(3 downto 0); + std_logic_vector_out : out STD_LOGIC_VECTOR(3 downto 0); + + -- STD_LOGIC_VECTOR type with to index + std_logic_vector_in_to : in STD_LOGIC_VECTOR(0 to 3); + std_logic_vector_out_to : out STD_LOGIC_VECTOR(0 to 3); + + -- SIGNED type + signed_in : in SIGNED(3 downto 0); + signed_out : out SIGNED(3 downto 0); + + -- SIGNED type with to index + signed_in_to : in SIGNED(0 to 3); + signed_out_to : out SIGNED(0 to 3); + + -- UNSIGNED type + unsigned_in : in UNSIGNED(3 downto 0); + unsigned_out : out UNSIGNED(3 downto 0); + + -- UNSIGNED type with to index + unsigned_in_to : in UNSIGNED(0 to 3); + unsigned_out_to : out UNSIGNED(0 to 3); + + -- INTEGER type without range + integer_in : in INTEGER; + integer_out : out INTEGER; + + -- INTEGER type with range + integer_with_range_in : in INTEGER range -5 to 10; + integer_with_range_out : out INTEGER range -6 to 10; + + -- INTEGER type with single value range + integer_single_value_in : in INTEGER range 5 to 5; + integer_single_value_out : out INTEGER range 5 to 5; + + -- INTEGER type with null range + integer_null_range_in : in INTEGER range 7 to -1; + integer_null_range_out : out INTEGER range 0 to -1; + + -- NATURAL type + natural_in : in NATURAL; + natural_out : out NATURAL; + + -- POSITIVE type + positive_in : in POSITIVE; + positive_out : out POSITIVE ); -end entity work; +end entity test; -architecture Behavioral of work is +architecture Behavioral of test is + signal integer_with_range : INTEGER range -1 to 100; begin - process(a) - begin - b <= a; - end process; + bit_out <= bit_in; + bit_vector_out <= bit_vector_in; + bit_vector_out_to <= bit_vector_in_to; + std_ulogic_out <= std_ulogic_in; + std_ulogic_vector_out <= std_ulogic_vector_in; + std_ulogic_vector_out_to <= std_ulogic_vector_in_to; + std_logic_out <= std_logic_in; + std_logic_vector_out <= std_logic_vector_in; + std_logic_vector_out_to <= std_logic_vector_in_to; + signed_out <= signed_in; + signed_out_to <= signed_in_to; + unsigned_out <= unsigned_in; + unsigned_out_to <= unsigned_in_to; + integer_with_range_out <= integer_with_range_in; + integer_out <= integer_in; + integer_single_value_out <= integer_single_value_in; + integer_null_range_out <= integer_null_range_in; + natural_out <= natural_in; + positive_out <= positive_in; + + integer_with_range <= 42; end architecture Behavioral; diff --git a/tests/verific/bounds.ys b/tests/verific/bounds.ys index 425af717cf4..3170862644d 100644 --- a/tests/verific/bounds.ys +++ b/tests/verific/bounds.ys @@ -1,6 +1,168 @@ read -vhdl bounds.vhd -verific -import work -select -assert-count 1 a:bottom_bound=5'bs11011 -select -assert-count 1 a:top_bound=5'bs01010 -select -assert-count 1 a:bottom_bound=5'bs11010 -select -assert-count 1 a:top_bound=5'bs01011 \ No newline at end of file +hierarchy -top test + +# bit: not a scalar type +select -assert-count 0 w:bit_in a:bottom_bound %i +select -assert-count 0 w:bit_in a:top_bound %i +select -assert-count 0 w:bit_out a:bottom_bound %i +select -assert-count 0 w:bit_out a:top_bound %i + +# bit_vector: not a scalar type +select -assert-count 0 w:bit_vector_in a:bottom_bound %i +select -assert-count 0 w:bit_vector_in a:top_bound %i +select -assert-count 0 w:bit_vector_out a:bottom_bound %i +select -assert-count 0 w:bit_vector_out a:top_bound %i + +# bit_vector with to index: not a scalar type +select -assert-count 0 w:bit_vector_in_to a:bottom_bound %i +select -assert-count 0 w:bit_vector_in_to a:top_bound %i +select -assert-count 0 w:bit_vector_out_to a:bottom_bound %i +select -assert-count 0 w:bit_vector_out_to a:top_bound %i + +# std_ulogic: not a scalar type +select -assert-count 0 w:std_ulogic_in a:bottom_bound %i +select -assert-count 0 w:std_ulogic_in a:top_bound %i +select -assert-count 0 w:std_ulogic_out a:bottom_bound %i +select -assert-count 0 w:std_ulogic_out a:top_bound %i + +# std_ulogic_vector: not a scalar type +select -assert-count 0 w:std_ulogic_vector_in a:bottom_bound %i +select -assert-count 0 w:std_ulogic_vector_in a:top_bound %i +select -assert-count 0 w:std_ulogic_vector_out a:bottom_bound %i +select -assert-count 0 w:std_ulogic_vector_out a:top_bound %i + +# std_ulogic_vector with to index: not a scalar type +select -assert-count 0 w:std_ulogic_vector_in_to a:bottom_bound %i +select -assert-count 0 w:std_ulogic_vector_in_to a:top_bound %i +select -assert-count 0 w:std_ulogic_vector_out_to a:bottom_bound %i +select -assert-count 0 w:std_ulogic_vector_out_to a:top_bound %i + +# std_logic: not a scalar type +select -assert-count 0 w:std_logic_in a:bottom_bound %i +select -assert-count 0 w:std_logic_in a:top_bound %i +select -assert-count 0 w:std_logic_out a:bottom_bound %i +select -assert-count 0 w:std_logic_out a:top_bound %i + +# std_logic_vector: not a scalar type +select -assert-count 0 w:std_logic_vector_in a:bottom_bound %i +select -assert-count 0 w:std_logic_vector_in a:top_bound %i +select -assert-count 0 w:std_logic_vector_out a:bottom_bound %i +select -assert-count 0 w:std_logic_vector_out a:top_bound %i + +# std_logic_vector with to index: not a scalar type +select -assert-count 0 w:std_logic_vector_in_to a:bottom_bound %i +select -assert-count 0 w:std_logic_vector_in_to a:top_bound %i +select -assert-count 0 w:std_logic_vector_out_to a:bottom_bound %i +select -assert-count 0 w:std_logic_vector_out_to a:top_bound %i + +# signed: not a scalar type +select -assert-count 0 w:signed_in a:bottom_bound %i +select -assert-count 0 w:signed_in a:top_bound %i +select -assert-count 0 w:signed_out a:bottom_bound %i +select -assert-count 0 w:signed_out a:top_bound %i + +# signed with to index: not a scalar type +select -assert-count 0 w:signed_in_to a:bottom_bound %i +select -assert-count 0 w:signed_in_to a:top_bound %i +select -assert-count 0 w:signed_out_to a:bottom_bound %i +select -assert-count 0 w:signed_out_to a:top_bound %i + +# unsigned: not a scalar type +select -assert-count 0 w:unsigned_in a:bottom_bound %i +select -assert-count 0 w:unsigned_in a:top_bound %i +select -assert-count 0 w:unsigned_out a:bottom_bound %i +select -assert-count 0 w:unsigned_out a:top_bound %i + +# unsigned with to index: not a scalar type +select -assert-count 0 w:unsigned_in_to a:bottom_bound %i +select -assert-count 0 w:unsigned_in_to a:top_bound %i +select -assert-count 0 w:unsigned_out_to a:bottom_bound %i +select -assert-count 0 w:unsigned_out_to a:top_bound %i + +# integer: scalar type +select -assert-count 1 w:integer_in a:bottom_bound=32'b10000000000000000000000000000000 %i +select -assert-count 1 w:integer_in a:top_bound=32'b01111111111111111111111111111111 %i +select -assert-count 1 w:integer_out a:bottom_bound=32'b10000000000000000000000000000000 %i +select -assert-count 1 w:integer_out a:top_bound=32'b01111111111111111111111111111111 %i + +# integer with range: scalar type +select -assert-count 1 w:integer_with_range_in a:bottom_bound=5'bs11011 %i +select -assert-count 1 w:integer_with_range_in a:top_bound=5'bs01010 %i +select -assert-count 1 w:integer_with_range_out a:bottom_bound=5'bs11010 %i +select -assert-count 1 w:integer_with_range_out a:top_bound=5'bs01010 %i + +# integer with single value range: scalar type +select -assert-count 1 w:integer_single_value_in a:bottom_bound=3'bs101 %i +select -assert-count 1 w:integer_single_value_in a:top_bound=3'bs101 %i +select -assert-count 1 w:integer_single_value_out a:bottom_bound=3'bs101 %i +select -assert-count 1 w:integer_single_value_out a:top_bound=3'bs101 %i + +# integer with null range: scalar type +select -assert-count 1 w:integer_null_range_in a:bottom_bound=4'bs0111 %i +select -assert-count 1 w:integer_null_range_in a:top_bound=4'bs1111 %i +select -assert-count 1 w:integer_null_range_out a:bottom_bound=1'bs0 %i +select -assert-count 1 w:integer_null_range_out a:top_bound=1'bs1 %i + +# natural: scalar type +select -assert-count 1 w:natural_in a:bottom_bound=31'b0000000000000000000000000000000 %i +select -assert-count 1 w:natural_in a:top_bound=31'b1111111111111111111111111111111 %i +select -assert-count 1 w:natural_out a:bottom_bound=31'b0000000000000000000000000000000 %i +select -assert-count 1 w:natural_out a:top_bound=31'b1111111111111111111111111111111 %i + +# positive: scalar type +select -assert-count 1 w:positive_in a:bottom_bound=31'b0000000000000000000000000000001 %i +select -assert-count 1 w:positive_in a:top_bound=31'b1111111111111111111111111111111 %i +select -assert-count 1 w:positive_out a:bottom_bound=31'b0000000000000000000000000000001 %i +select -assert-count 1 w:positive_out a:top_bound=31'b1111111111111111111111111111111 %i + + +design -reset +read -vhdl2019 bounds.vhd +hierarchy -top test + +## integer size changed in VHDL 2019 +# integer: scalar type +select -assert-count 1 w:integer_in a:bottom_bound=64'b1000000000000000000000000000000000000000000000000000000000000000 %i +select -assert-count 1 w:integer_in a:top_bound=64'b0111111111111111111111111111111111111111111111111111111111111111 %i +select -assert-count 1 w:integer_out a:bottom_bound=64'b1000000000000000000000000000000000000000000000000000000000000000 %i +select -assert-count 1 w:integer_out a:top_bound=64'b0111111111111111111111111111111111111111111111111111111111111111 %i + +# natural: scalar type +select -assert-count 1 w:natural_in a:bottom_bound=63'b000000000000000000000000000000000000000000000000000000000000000 %i +select -assert-count 1 w:natural_in a:top_bound=63'b111111111111111111111111111111111111111111111111111111111111111 %i +select -assert-count 1 w:natural_out a:bottom_bound=63'b000000000000000000000000000000000000000000000000000000000000000 %i +select -assert-count 1 w:natural_out a:top_bound=63'b111111111111111111111111111111111111111111111111111111111111111 %i + +# positive: scalar type +select -assert-count 1 w:positive_in a:bottom_bound=63'b000000000000000000000000000000000000000000000000000000000000001 %i +select -assert-count 1 w:positive_in a:top_bound=63'b111111111111111111111111111111111111111111111111111111111111111 %i +select -assert-count 1 w:positive_out a:bottom_bound=63'b000000000000000000000000000000000000000000000000000000000000001 %i +select -assert-count 1 w:positive_out a:top_bound=63'b111111111111111111111111111111111111111111111111111111111111111 %i + +## ranged integer sizes should be unaffected +# integer with range: scalar type +select -assert-count 1 w:integer_with_range_in a:bottom_bound=5'bs11011 %i +select -assert-count 1 w:integer_with_range_in a:top_bound=5'bs01010 %i +select -assert-count 1 w:integer_with_range_out a:bottom_bound=5'bs11010 %i +select -assert-count 1 w:integer_with_range_out a:top_bound=5'bs01010 %i + +# integer with single value range: scalar type +select -assert-count 1 w:integer_single_value_in a:bottom_bound=3'bs101 %i +select -assert-count 1 w:integer_single_value_in a:top_bound=3'bs101 %i +select -assert-count 1 w:integer_single_value_out a:bottom_bound=3'bs101 %i +select -assert-count 1 w:integer_single_value_out a:top_bound=3'bs101 %i + +# integer with null range: scalar type +select -assert-count 1 w:integer_null_range_in a:bottom_bound=4'bs0111 %i +select -assert-count 1 w:integer_null_range_in a:top_bound=4'bs1111 %i +select -assert-count 1 w:integer_null_range_out a:bottom_bound=1'bs0 %i +select -assert-count 1 w:integer_null_range_out a:top_bound=1'bs1 %i + + +design -reset +read -sv bounds.sv +hierarchy -top test + +## bounds should not be generated for SV +select -assert-count none a:bottom_bound +select -assert-count none a:top_bound