Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verific frontend: fix top_bound/bottom_bound attributes #4815

Merged
merged 2 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading