Skip to content

Commit

Permalink
Merge pull request #4815 from YosysHQ/verific_bounds_fix
Browse files Browse the repository at this point in the history
Verific frontend: fix `top_bound`/`bottom_bound` attributes
  • Loading branch information
nakengelhardt authored Dec 12, 2024
2 parents e32e199 + 378864d commit f384eac
Show file tree
Hide file tree
Showing 5 changed files with 330 additions and 24 deletions.
26 changes: 17 additions & 9 deletions frontends/verific/verific.cc
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ static const std::string verific_unescape(const char *value)
}
#endif

void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl)
void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl, int wire_width_hint)
{
if (!obj)
return;
Expand All @@ -433,10 +433,18 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &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) {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion frontends/verific/verific.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<RTLIL::IdString, RTLIL::Const> &attributes, Verific::DesignObj *obj, Verific::Netlist *nl = nullptr);
void import_attributes(dict<RTLIL::IdString, RTLIL::Const> &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);
Expand Down
45 changes: 45 additions & 0 deletions tests/verific/bounds.sv
Original file line number Diff line number Diff line change
@@ -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
109 changes: 100 additions & 9 deletions tests/verific/bounds.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Loading

0 comments on commit f384eac

Please sign in to comment.