From 378864d33beb2550eb897204853d09ebed507924 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Thu, 12 Dec 2024 11:42:39 +0100 Subject: [PATCH] bound attributes: handle vhdl null ranges --- frontends/verific/verific.cc | 24 ++++++++++------ frontends/verific/verific.h | 2 +- tests/verific/bounds.sv | 53 ++++++++++++++++++++++++++++-------- tests/verific/bounds.vhd | 3 ++ tests/verific/bounds.ys | 31 +++++++++++++++++---- 5 files changed, 88 insertions(+), 25 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 30d701aaee9..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; @@ -436,7 +436,15 @@ void VerificImporter::import_attributes(dict &att 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 index d8081f3b764..b20d0236904 100644 --- a/tests/verific/bounds.sv +++ b/tests/verific/bounds.sv @@ -1,14 +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 ia, - output oa, - input [0:0] ib, - output [0:0] ob, - input [3:0] ic, - output [3:0] oc - ); - -assign oa = ia; -assign ob = ib; -assign oc = ic; + 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 084aeb4bb4c..782f3b5adde 100644 --- a/tests/verific/bounds.vhd +++ b/tests/verific/bounds.vhd @@ -83,6 +83,7 @@ entity test is end entity test; architecture Behavioral of test is + signal integer_with_range : INTEGER range -1 to 100; begin bit_out <= bit_in; bit_vector_out <= bit_vector_in; @@ -103,4 +104,6 @@ begin 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 412a6218a3b..3170862644d 100644 --- a/tests/verific/bounds.ys +++ b/tests/verific/bounds.ys @@ -98,10 +98,10 @@ 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=2'bs00 %i -select -assert-count 1 w:integer_null_range_out a:top_bound=2'bs11 %i +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 @@ -116,11 +116,11 @@ select -assert-count 1 w:positive_out a:bottom_bound=31'b00000000000000000000000 select -assert-count 1 w:positive_out a:top_bound=31'b1111111111111111111111111111111 %i -# integer size changed in VHDL 2019 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 @@ -139,9 +139,30 @@ select -assert-count 1 w:positive_in a:top_bound=63'b111111111111111111111111111 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