diff --git a/libopenfpga/libbusgroup/src/bus_group.cpp b/libopenfpga/libbusgroup/src/bus_group.cpp index 7aed69215..8bc5688ed 100644 --- a/libopenfpga/libbusgroup/src/bus_group.cpp +++ b/libopenfpga/libbusgroup/src/bus_group.cpp @@ -33,6 +33,11 @@ openfpga::BasicPort BusGroup::bus_port(const BusGroupId& bus_id) const { return bus_ports_[bus_id]; } +bool BusGroup::is_big_endian(const BusGroupId& bus_id) const { + VTR_ASSERT(valid_bus_id(bus_id)); + return bus_big_endians_[bus_id]; +} + std::vector BusGroup::bus_pins(const BusGroupId& bus_id) const { VTR_ASSERT(valid_bus_id(bus_id)); return bus_pin_ids_[bus_id]; @@ -89,6 +94,7 @@ bool BusGroup::empty() const { void BusGroup::reserve_buses(const size_t& num_buses) { bus_ids_.reserve(num_buses); bus_ports_.reserve(num_buses); + bus_big_endians_.reserve(num_buses); bus_pin_ids_.reserve(num_buses); } @@ -105,6 +111,7 @@ BusGroupId BusGroup::create_bus(const openfpga::BasicPort& bus_port) { bus_ids_.push_back(bus_id); bus_ports_.push_back(bus_port); + bus_big_endians_.push_back(true); bus_pin_ids_.emplace_back(); /* Register to fast look-up */ @@ -119,6 +126,11 @@ BusGroupId BusGroup::create_bus(const openfpga::BasicPort& bus_port) { return bus_id; } +void BusGroup::set_bus_big_endian(const BusGroupId& bus_id, const bool& big_endian) { + VTR_ASSERT(valid_bus_id(bus_id)); + bus_big_endians_[bus_id] = big_endian; +} + BusPinId BusGroup::create_pin(const BusGroupId& bus_id, const int& index) { /* Create a new id */ BusPinId pin_id = BusPinId(pin_ids_.size()); diff --git a/libopenfpga/libbusgroup/src/bus_group.h b/libopenfpga/libbusgroup/src/bus_group.h index da63fb210..85d80c579 100644 --- a/libopenfpga/libbusgroup/src/bus_group.h +++ b/libopenfpga/libbusgroup/src/bus_group.h @@ -50,6 +50,9 @@ class BusGroup { /** Get port information of a bus with a given id */ BasicPort bus_port(const BusGroupId& bus_id) const; + /* Check if a bus follows big endian */ + bool is_big_endian(const BusGroupId& bus_id) const; + /* Get the pins under a specific bus */ std::vector bus_pins(const BusGroupId& bus_id) const; @@ -81,6 +84,9 @@ class BusGroup { /* Add a bus to storage */ BusGroupId create_bus(const openfpga::BasicPort& bus_port); + /* Set endianness for a bus; If not set, by default it assumes big-endian */ + void set_bus_big_endian(const BusGroupId& bus_id, const bool& big_endian); + /* Add a pin to a bus, with a given index in the bus, e.g., A[1] in A[0:2] */ BusPinId create_pin(const BusGroupId& bus_id, const int& index); @@ -101,6 +107,9 @@ class BusGroup { /* Port information of each bus */ vtr::vector bus_ports_; + /* Endianness of each bus: big endian by default */ + vtr::vector bus_big_endians_; + /* Indices of each pin under each bus */ vtr::vector> bus_pin_ids_; diff --git a/libopenfpga/libbusgroup/src/bus_group_xml_constants.h b/libopenfpga/libbusgroup/src/bus_group_xml_constants.h index 9f27ae978..62b552f06 100644 --- a/libopenfpga/libbusgroup/src/bus_group_xml_constants.h +++ b/libopenfpga/libbusgroup/src/bus_group_xml_constants.h @@ -6,6 +6,7 @@ constexpr char* XML_BUS_GROUP_NODE_NAME = "bus_group"; constexpr char* XML_BUS_NODE_NAME = "bus"; constexpr char* XML_BUS_PORT_ATTRIBUTE_NAME = "name"; +constexpr char* XML_BUS_BIG_ENDIAN_ATTRIBUTE_NAME = "big_endian"; constexpr char* XML_PIN_NODE_NAME = "pin"; constexpr char* XML_PIN_INDEX_ATTRIBUTE_NAME = "id"; constexpr char* XML_PIN_NAME_ATTRIBUTE_NAME = "name"; diff --git a/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp index 020aa224b..768ff455a 100644 --- a/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp +++ b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp @@ -76,6 +76,9 @@ void read_xml_bus(pugi::xml_node& xml_bus, "Bus port is invalid, check LSB and MSB!\n"); } + /* Find big endian */ + bus_group.set_bus_big_endian(bus_id, get_attribute(xml_bus, XML_BUS_BIG_ENDIAN_ATTRIBUTE_NAME, loc_data, pugiutil::OPTIONAL).as_bool(true)); + for (pugi::xml_node xml_pin : xml_bus.children()) { /* Error out if the XML child has an invalid name! */ if (xml_pin.name() != std::string(XML_PIN_NODE_NAME)) { diff --git a/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp b/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp index 9d9fdb005..be26b44f5 100644 --- a/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp +++ b/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp @@ -46,6 +46,7 @@ int write_xml_bus(std::fstream& fp, } write_xml_attribute(fp, XML_BUS_PORT_ATTRIBUTE_NAME, generate_xml_port_name(bus_group.bus_port(bus_id)).c_str()); + write_xml_attribute(fp, XML_BUS_BIG_ENDIAN_ATTRIBUTE_NAME, bus_group.is_big_endian(bus_id)); fp << ">" << "\n"; /* Output all the pins under this bus */ diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp index 26ce11c2f..fba957963 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp @@ -56,6 +56,7 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp, /* Ports to be added, this is to avoid any bus port */ std::vector port_list; std::vector port_types; + std::vector port_big_endian; /* Print all the I/Os of the circuit implementation to be tested*/ for (const AtomBlockId &atom_blk : atom_ctx.nlist.blocks()) { @@ -96,6 +97,7 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp, if (port_list.end() == std::find(port_list.begin(), port_list.end(), bus_group.bus_port(bus_id))) { port_list.push_back(bus_group.bus_port(bus_id)); port_types.push_back(atom_ctx.nlist.block_type(atom_blk)); + port_big_endian.push_back(bus_group.is_big_endian(bus_id)); } continue; } @@ -104,6 +106,7 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp, BasicPort module_port(std::string(block_name), 1); port_list.push_back(module_port); port_types.push_back(atom_ctx.nlist.block_type(atom_blk)); + port_big_endian.push_back(true); } /* After collecting all the ports, now print the port mapping */ @@ -115,7 +118,7 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp, fp << "," << std::endl; } - fp << generate_verilog_port(port_type2type_map[port_type], module_port); + fp << generate_verilog_port(port_type2type_map[port_type], module_port, true, port_big_endian[iport]); /* Update port counter */ port_counter++; diff --git a/openfpga/src/fpga_verilog/verilog_writer_utils.cpp b/openfpga/src/fpga_verilog/verilog_writer_utils.cpp index ea34f35b7..d537b89f3 100644 --- a/openfpga/src/fpga_verilog/verilog_writer_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_writer_utils.cpp @@ -466,13 +466,19 @@ void print_verilog_module_end(std::fstream& fp, ***********************************************/ std::string generate_verilog_port(const enum e_dump_verilog_port_type& verilog_port_type, const BasicPort& port_info, - const bool& must_print_port_size) { + const bool& must_print_port_size, + const bool& big_endian) { std::string verilog_line; /* Ensure the port type is valid */ VTR_ASSERT(verilog_port_type < NUM_VERILOG_PORT_TYPES); - std::string size_str = "[" + std::to_string(port_info.get_lsb()) + ":" + std::to_string(port_info.get_msb()) + "]"; + std::string size_str; + if (big_endian) { + size_str = "[" + std::to_string(port_info.get_lsb()) + ":" + std::to_string(port_info.get_msb()) + "]"; + } else { + size_str = "[" + std::to_string(port_info.get_msb()) + ":" + std::to_string(port_info.get_lsb()) + "]"; + } /* Only connection require a format of [:] * others require a format of [:] diff --git a/openfpga/src/fpga_verilog/verilog_writer_utils.h b/openfpga/src/fpga_verilog/verilog_writer_utils.h index af344e146..180df8e45 100644 --- a/openfpga/src/fpga_verilog/verilog_writer_utils.h +++ b/openfpga/src/fpga_verilog/verilog_writer_utils.h @@ -87,7 +87,8 @@ void print_verilog_module_end(std::fstream& fp, std::string generate_verilog_port(const enum e_dump_verilog_port_type& dump_port_type, const BasicPort& port_info, - const bool& must_print_port_size = true); + const bool& must_print_port_size = true, + const bool& big_endian = true); bool two_verilog_ports_mergeable(const BasicPort& portA, const BasicPort& portB);