From b7d49654bb1190ee8302b144457e15f6c5f60563 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 30 Dec 2020 11:37:14 -0700 Subject: [PATCH 01/32] [VPR] Add node sides truth table to rr_graph node storage --- vpr/src/route/rr_graph_storage.h | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 7b230a7c187..1ec1e2c8219 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -2,6 +2,7 @@ #define _RR_GRAPH_STORAGE_ #include +#include #include "rr_graph_fwd.h" #include "rr_node_fwd.h" @@ -57,11 +58,23 @@ struct alignas(16) t_rr_node_data { int16_t yhigh_ = -1; t_rr_type type_ = NUM_RR_TYPES; + + /* The character is a hex number which is a 4-bit truth table for node sides + * The 4-bits in serial represent 4 sides on which a node could appear + * It follows a fixed sequence, which is (LEFT, BOTTOM, RIGHT, TOP) whose indices are (3, 2, 1, 0) + * - When a node appears on a given side, it is set to "1" + * - When a node does not appear on a given side, it is set to "0" + * For example, + * - '1' means '0001' in hex number, which means the node appears on TOP + * - 'A' means '1100' in hex number, which means the node appears on LEFT and BOTTOM sides, + */ union { e_direction direction; //Valid only for CHANX/CHANY e_side side; //Valid only for IPINs/OPINs + char sides; } dir_side_; + uint16_t capacity_ = 0; }; @@ -588,6 +601,26 @@ class t_rr_graph_storage { return node_storage[id].dir_side_.side; } + static inline std::vector get_node_sides( + vtr::array_view_id node_storage, + const RRNodeId& id) { + auto& node_data = node_storage[id]; + if (node_data.type_ != IPIN && node_data.type_ != OPIN) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, + "Attempted to access RR node 'side' for non-IPIN/OPIN type '%s'", + rr_node_typename[node_data.type_]); + } + // Return a vector showing only the sides that the node appears + std::vector exist_sides; + std::bitset<4> side_tt = node_storage[id].dir_side_.sides; + for (const e_side& side : SIDES) { + if (side_tt[size_t(side)]) { + exist_sides.push_back(side); + } + } + return exist_sides; + } + private: friend struct edge_swapper; friend class edge_sort_iterator; @@ -736,6 +769,20 @@ class t_rr_graph_view { return t_rr_graph_storage::get_node_side(node_storage_, id); } + std::vector node_sides(const RRNodeId& id) const { + return t_rr_graph_storage::get_node_sides(node_storage_, id); + } + + /** + * A function to find if the given node appears on a specific side + * This function is placed only here in the purpose of minimizing + * the footprint of node_storage data structure + */ + bool node_on_specific_side(const RRNodeId& id, const e_side& side) const { + std::vector node_sides = t_rr_graph_storage::get_node_sides(node_storage_, id); + return (node_sides.end() != std::find(node_sides.begin(), node_sides.end(), side)); + } + /* PTC get methods */ short node_ptc_num(RRNodeId id) const; short node_pin_num(RRNodeId id) const; //Same as ptc_num() but checks that type() is consistent From d846f1b3e4acc5613da17ec7ff097f65367da602 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 30 Dec 2020 14:09:23 -0700 Subject: [PATCH 02/32] [VPR] Now remove the old side storage and updated methods to use the encoded side truth table --- vpr/src/route/rr_graph_storage.cpp | 8 +++++++- vpr/src/route/rr_graph_storage.h | 24 +++++++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/vpr/src/route/rr_graph_storage.cpp b/vpr/src/route/rr_graph_storage.cpp index 5f0e1dd93df..3fecfb282ae 100644 --- a/vpr/src/route/rr_graph_storage.cpp +++ b/vpr/src/route/rr_graph_storage.cpp @@ -711,7 +711,13 @@ void t_rr_graph_storage::set_node_side(RRNodeId id, e_side new_side) { if (node_type(id) != IPIN && node_type(id) != OPIN) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id)); } - node_storage_[id].dir_side_.side = new_side; + std::bitset side_bits = node_storage_[id].dir_side_.sides; + /* Enable the side bit */ + side_bits[size_t(new_side)] = true; + if (side_bits.to_ulong() > CHAR_MAX) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Invalid side '%s' to be added to rr node %u", SIDE_STRING[new_side], size_t(id)); + } + node_storage_[id].dir_side_.sides = static_cast(side_bits.to_ulong()); } short t_rr_graph_view::node_ptc_num(RRNodeId id) const { diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 1ec1e2c8219..d62e56b7c63 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -70,11 +70,9 @@ struct alignas(16) t_rr_node_data { */ union { e_direction direction; //Valid only for CHANX/CHANY - e_side side; //Valid only for IPINs/OPINs - char sides; + unsigned char sides; //Valid only for IPINs/OPINs } dir_side_; - uint16_t capacity_ = 0; }; @@ -469,6 +467,10 @@ class t_rr_graph_storage { void set_node_rc_index(RRNodeId, short new_rc_index); void set_node_capacity(RRNodeId, short new_capacity); void set_node_direction(RRNodeId, e_direction new_direction); + + /* Add a side to the node abbributes; + * Note that a node may have multiple valid sides + */ void set_node_side(RRNodeId, e_side new_side); /**************** @@ -589,6 +591,9 @@ class t_rr_graph_storage { return node_storage[id].dir_side_.direction; } + /** THIS FUNCTION IS GOING TO BE DEPRECATED + * Return the first valid side for the node + */ static inline e_side get_node_side( vtr::array_view_id node_storage, RRNodeId id) { @@ -598,7 +603,16 @@ class t_rr_graph_storage { "Attempted to access RR node 'side' for non-IPIN/OPIN type '%s'", rr_node_typename[node_data.type_]); } - return node_storage[id].dir_side_.side; + std::vector exist_sides; + std::bitset side_tt = node_storage[id].dir_side_.sides; + for (const e_side& side : SIDES) { + if (side_tt[size_t(side)]) { + return side; + } + } + /* No valid sides, return an invalid value */ + return NUM_SIDES; + } static inline std::vector get_node_sides( @@ -612,7 +626,7 @@ class t_rr_graph_storage { } // Return a vector showing only the sides that the node appears std::vector exist_sides; - std::bitset<4> side_tt = node_storage[id].dir_side_.sides; + std::bitset side_tt = node_storage[id].dir_side_.sides; for (const e_side& side : SIDES) { if (side_tt[size_t(side)]) { exist_sides.push_back(side); From 5d080424e09c4688753d14e775253f9498cb3c47 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 30 Dec 2020 15:20:07 -0700 Subject: [PATCH 03/32] [VPR] Bug fix on the side decoding function --- vpr/src/route/rr_graph_storage.cpp | 2 +- vpr/src/route/rr_graph_storage.h | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/vpr/src/route/rr_graph_storage.cpp b/vpr/src/route/rr_graph_storage.cpp index 3fecfb282ae..e64d32428ab 100644 --- a/vpr/src/route/rr_graph_storage.cpp +++ b/vpr/src/route/rr_graph_storage.cpp @@ -711,7 +711,7 @@ void t_rr_graph_storage::set_node_side(RRNodeId id, e_side new_side) { if (node_type(id) != IPIN && node_type(id) != OPIN) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id)); } - std::bitset side_bits = node_storage_[id].dir_side_.sides; + std::bitset side_bits = node_storage_[id].dir_side_.sides; /* Enable the side bit */ side_bits[size_t(new_side)] = true; if (side_bits.to_ulong() > CHAR_MAX) { diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index d62e56b7c63..56d5d7eaac0 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -593,7 +593,7 @@ class t_rr_graph_storage { /** THIS FUNCTION IS GOING TO BE DEPRECATED * Return the first valid side for the node - */ + */ static inline e_side get_node_side( vtr::array_view_id node_storage, RRNodeId id) { @@ -604,7 +604,7 @@ class t_rr_graph_storage { rr_node_typename[node_data.type_]); } std::vector exist_sides; - std::bitset side_tt = node_storage[id].dir_side_.sides; + std::bitset side_tt = node_storage[id].dir_side_.sides; for (const e_side& side : SIDES) { if (side_tt[size_t(side)]) { return side; @@ -612,7 +612,6 @@ class t_rr_graph_storage { } /* No valid sides, return an invalid value */ return NUM_SIDES; - } static inline std::vector get_node_sides( @@ -626,7 +625,7 @@ class t_rr_graph_storage { } // Return a vector showing only the sides that the node appears std::vector exist_sides; - std::bitset side_tt = node_storage[id].dir_side_.sides; + std::bitset side_tt = node_storage[id].dir_side_.sides; for (const e_side& side : SIDES) { if (side_tt[size_t(side)]) { exist_sides.push_back(side); From 123df92bfa69b9ed548d558bfb24c4ad153cb101 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 30 Dec 2020 17:48:34 -0700 Subject: [PATCH 04/32] [VPR] Initialize the node sides and add methods as well as sanity checks for the node_side() --- vpr/src/route/rr_graph.cpp | 9 ++++++- vpr/src/route/rr_graph_storage.h | 41 ++++++++++++++++++++++---------- vpr/src/route/rr_node.h | 2 ++ vpr/src/route/rr_node_impl.h | 8 +++++++ 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 60a36f0994c..e0f59a1220b 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -1498,7 +1498,14 @@ static void build_rr_sinks_sources(const int i, L_rr_node[inode].set_coordinates(i + width_offset, j + height_offset, i + width_offset, j + height_offset); L_rr_node[inode].set_side(side); - VTR_ASSERT(type->pinloc[width_offset][height_offset][L_rr_node[inode].side()][L_rr_node[inode].pin_num()]); + // Sanity check + VTR_ASSERT(1 <= L_rr_node[inode].sides().size()); + if (1 == L_rr_node[inode].sides().size()) { + VTR_ASSERT(type->pinloc[width_offset][height_offset][L_rr_node[inode].side()][L_rr_node[inode].pin_num()]); + } else { + VTR_ASSERT(L_rr_node[inode].is_node_on_specific_side(side)); + VTR_ASSERT(type->pinloc[width_offset][height_offset][side][L_rr_node[inode].pin_num()]); + } } } } diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 56d5d7eaac0..2d0c0b4015e 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -70,7 +70,7 @@ struct alignas(16) t_rr_node_data { */ union { e_direction direction; //Valid only for CHANX/CHANY - unsigned char sides; //Valid only for IPINs/OPINs + unsigned char sides = 0x0; //Valid only for IPINs/OPINs } dir_side_; uint16_t capacity_ = 0; @@ -203,6 +203,19 @@ class t_rr_graph_storage { node_storage_.data(), node_storage_.size()), id); } + std::vector node_sides(RRNodeId id) const { + return get_node_sides( + vtr::array_view_id( + node_storage_.data(), node_storage_.size()), + id); + } + bool is_node_on_specific_side(RRNodeId id, e_side side) const { + return is_node_on_specific_side( + vtr::array_view_id( + node_storage_.data(), node_storage_.size()), + id, side); + } + const char* node_side_string(RRNodeId id) const; /* PTC get methods */ @@ -603,7 +616,6 @@ class t_rr_graph_storage { "Attempted to access RR node 'side' for non-IPIN/OPIN type '%s'", rr_node_typename[node_data.type_]); } - std::vector exist_sides; std::bitset side_tt = node_storage[id].dir_side_.sides; for (const e_side& side : SIDES) { if (side_tt[size_t(side)]) { @@ -634,6 +646,21 @@ class t_rr_graph_storage { return exist_sides; } + /* Find if the given node appears on a specific side */ + static inline bool is_node_on_specific_side( + vtr::array_view_id node_storage, + const RRNodeId& id, const e_side& side) { + auto& node_data = node_storage[id]; + if (node_data.type_ != IPIN && node_data.type_ != OPIN) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, + "Attempted to access RR node 'side' for non-IPIN/OPIN type '%s'", + rr_node_typename[node_data.type_]); + } + // Return a vector showing only the sides that the node appears + std::bitset side_tt = node_storage[id].dir_side_.sides; + return side_tt[size_t(side)]; + } + private: friend struct edge_swapper; friend class edge_sort_iterator; @@ -786,16 +813,6 @@ class t_rr_graph_view { return t_rr_graph_storage::get_node_sides(node_storage_, id); } - /** - * A function to find if the given node appears on a specific side - * This function is placed only here in the purpose of minimizing - * the footprint of node_storage data structure - */ - bool node_on_specific_side(const RRNodeId& id, const e_side& side) const { - std::vector node_sides = t_rr_graph_storage::get_node_sides(node_storage_, id); - return (node_sides.end() != std::find(node_sides.begin(), node_sides.end(), side)); - } - /* PTC get methods */ short node_ptc_num(RRNodeId id) const; short node_pin_num(RRNodeId id) const; //Same as ptc_num() but checks that type() is consistent diff --git a/vpr/src/route/rr_node.h b/vpr/src/route/rr_node.h index 99923c1acd0..4d1fc2f6e06 100644 --- a/vpr/src/route/rr_node.h +++ b/vpr/src/route/rr_node.h @@ -112,6 +112,8 @@ class t_rr_node { const char* direction_string() const; e_side side() const; + std::vector sides() const; + bool is_node_on_specific_side(e_side side) const; const char* side_string() const; float R() const; diff --git a/vpr/src/route/rr_node_impl.h b/vpr/src/route/rr_node_impl.h index 53bb885eb48..70a228d3668 100644 --- a/vpr/src/route/rr_node_impl.h +++ b/vpr/src/route/rr_node_impl.h @@ -159,4 +159,12 @@ inline e_side t_rr_node::side() const { return storage_->node_side(id_); } +inline std::vector t_rr_node::sides() const { + return storage_->node_sides(id_); +} + +inline bool t_rr_node::is_node_on_specific_side(e_side side) const { + return storage_->is_node_on_specific_side(id_, side); +} + #endif /* _RR_NODE_IMPL_H_ */ From 9f93338ea05dadfca28840f5c855f5f608858933 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 30 Dec 2020 18:51:16 -0700 Subject: [PATCH 05/32] [VPR] code format fix --- vpr/src/route/rr_graph_storage.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 2d0c0b4015e..66c2afdfe0f 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -69,8 +69,8 @@ struct alignas(16) t_rr_node_data { * - 'A' means '1100' in hex number, which means the node appears on LEFT and BOTTOM sides, */ union { - e_direction direction; //Valid only for CHANX/CHANY - unsigned char sides = 0x0; //Valid only for IPINs/OPINs + e_direction direction; //Valid only for CHANX/CHANY + unsigned char sides = 0x0; //Valid only for IPINs/OPINs } dir_side_; uint16_t capacity_ = 0; @@ -649,7 +649,8 @@ class t_rr_graph_storage { /* Find if the given node appears on a specific side */ static inline bool is_node_on_specific_side( vtr::array_view_id node_storage, - const RRNodeId& id, const e_side& side) { + const RRNodeId& id, + const e_side& side) { auto& node_data = node_storage[id]; if (node_data.type_ != IPIN && node_data.type_ != OPIN) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, From 8721190e38aa8e8b8f0f80bc2203dcf567dff03f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 6 Jan 2021 14:02:54 -0700 Subject: [PATCH 06/32] [VPR] Throw fatal error when node side is invalid --- vpr/src/route/rr_graph_storage.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 66c2afdfe0f..a76025ed45c 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -623,6 +623,14 @@ class t_rr_graph_storage { } } /* No valid sides, return an invalid value */ + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, + "Invalid side for RR node '%d':\n\ttype='%s'\txlow,ylow=(%d,%d)\n\txhigh,yhigh=(%d,%d)", + size_t(id), + rr_node_typename[node_data.type_], + node_data.xlow_, + node_data.ylow_, + node_data.xhigh_, + node_data.yhigh_); return NUM_SIDES; } From 64f87b87928ca15c2c54310af3f6b81909d0a235 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 6 Jan 2021 15:05:00 -0700 Subject: [PATCH 07/32] [VPR] Add enumerations to rr_graph I/O file formats --- vpr/src/route/rr_graph.xsd | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/vpr/src/route/rr_graph.xsd b/vpr/src/route/rr_graph.xsd index 728ea747e3c..30aefe9b8cb 100644 --- a/vpr/src/route/rr_graph.xsd +++ b/vpr/src/route/rr_graph.xsd @@ -236,10 +236,21 @@ - - + + + + + + + + + + + + + From 83643479d654546e4ea2dfc4710473b976545a40 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 6 Jan 2021 16:41:11 -0700 Subject: [PATCH 08/32] [VPR] Update rr_graph reader and writer for node_sides() method. Code format error to be fixed --- .../gen/rr_graph_uxsdcxx.capnp | 23 +- vpr/src/route/gen/rr_graph_uxsdcxx.h | 233 +++++++++- vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h | 66 ++- .../route/gen/rr_graph_uxsdcxx_interface.h | 431 +++++++++--------- vpr/src/route/rr_graph.xsd | 58 ++- vpr/src/route/rr_graph_storage.h | 13 +- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 94 +++- vpr/src/route/rr_node.h | 3 +- vpr/src/route/rr_node_impl.h | 2 +- 9 files changed, 648 insertions(+), 275 deletions(-) diff --git a/libs/libvtrcapnproto/gen/rr_graph_uxsdcxx.capnp b/libs/libvtrcapnproto/gen/rr_graph_uxsdcxx.capnp index 145245b3d49..c90c4b358db 100644 --- a/libs/libvtrcapnproto/gen/rr_graph_uxsdcxx.capnp +++ b/libs/libvtrcapnproto/gen/rr_graph_uxsdcxx.capnp @@ -2,11 +2,11 @@ # https://github.com/duck2/uxsdcxx # Modify only if your build process doesn't involve regenerating this file. # -# Cmdline: uxsdcxx/uxsdcap.py /home/kmurray/trees/vtr/vpr/src/route/rr_graph.xsd -# Input file: /home/kmurray/trees/vtr/vpr/src/route/rr_graph.xsd -# md5sum of input file: 40e83d2ea6556761d4e29f21324b1871 +# Cmdline: uxsdcxx/uxsdcap.py /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd +# Input file: /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd +# md5sum of input file: f7808029c0bfdf2e30e6e1f5f05fcc4a -@0xb803100e76d3342d; +@0xa6084fe8f0768aad; using Cxx = import "/capnp/c++.capnp"; $Cxx.namespace("ucap"); @@ -45,10 +45,21 @@ enum NodeDirection { enum LocSide { uxsdInvalid @0; - left @1; + top @1; right @2; - top @3; + topRight @3; bottom @4; + topBottom @5; + rightBottom @6; + topRightBottom @7; + left @8; + topLeft @9; + rightLeft @10; + topRightLeft @11; + bottomLeft @12; + topBottomLeft @13; + rightBottomLeft @14; + topRightBottomLeft @15; } struct Channel { diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx.h b/vpr/src/route/gen/rr_graph_uxsdcxx.h index 78aade3b638..205a770be3a 100644 --- a/vpr/src/route/gen/rr_graph_uxsdcxx.h +++ b/vpr/src/route/gen/rr_graph_uxsdcxx.h @@ -4,9 +4,9 @@ * https://github.com/duck2/uxsdcxx * Modify only if your build process doesn't involve regenerating this file. * - * Cmdline: uxsdcxx/uxsdcxx.py /home/kmurray/trees/vtr/vpr/src/route/rr_graph.xsd - * Input file: /home/kmurray/trees/vtr/vpr/src/route/rr_graph.xsd - * md5sum of input file: 40e83d2ea6556761d4e29f21324b1871 + * Cmdline: uxsdcxx/uxsdcxx.py /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd + * Input file: /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd + * md5sum of input file: f7808029c0bfdf2e30e6e1f5f05fcc4a */ #include @@ -1762,7 +1762,7 @@ constexpr const char* lookup_switch_type[] = {"UXSD_INVALID", "mux", "tristate", constexpr const char* lookup_pin_type[] = {"UXSD_INVALID", "OPEN", "OUTPUT", "INPUT"}; constexpr const char* lookup_node_type[] = {"UXSD_INVALID", "CHANX", "CHANY", "SOURCE", "SINK", "OPIN", "IPIN"}; constexpr const char* lookup_node_direction[] = {"UXSD_INVALID", "INC_DIR", "DEC_DIR", "BI_DIR"}; -constexpr const char* lookup_loc_side[] = {"UXSD_INVALID", "LEFT", "RIGHT", "TOP", "BOTTOM"}; +constexpr const char* lookup_loc_side[] = {"UXSD_INVALID", "TOP", "RIGHT", "TOP_RIGHT", "BOTTOM", "TOP_BOTTOM", "RIGHT_BOTTOM", "TOP_RIGHT_BOTTOM", "LEFT", "TOP_LEFT", "RIGHT_LEFT", "TOP_RIGHT_LEFT", "BOTTOM_LEFT", "TOP_BOTTOM_LEFT", "RIGHT_BOTTOM_LEFT", "TOP_RIGHT_BOTTOM_LEFT"}; /* Lexers(string->token functions) for enums. */ inline enum_switch_type lex_enum_switch_type(const char* in, bool throw_on_invalid, const std::function* report_error) { @@ -2127,6 +2127,231 @@ inline enum_loc_side lex_enum_loc_side(const char* in, bool throw_on_invalid, co break; } break; + case 8: + switch (*((triehash_uu64*)&in[0])) { + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('L', 32, 64) | onechar('E', 40, 64) | onechar('F', 48, 64) | onechar('T', 56, 64): + return enum_loc_side::TOP_LEFT; + break; + default: + break; + } + break; + case 9: + switch (*((triehash_uu64*)&in[0])) { + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): + switch (in[8]) { + case onechar('T', 0, 8): + return enum_loc_side::TOP_RIGHT; + break; + default: + break; + } + break; + default: + break; + } + break; + case 10: + switch (*((triehash_uu64*)&in[0])) { + case onechar('R', 0, 64) | onechar('I', 8, 64) | onechar('G', 16, 64) | onechar('H', 24, 64) | onechar('T', 32, 64) | onechar('_', 40, 64) | onechar('L', 48, 64) | onechar('E', 56, 64): + switch (in[8]) { + case onechar('F', 0, 8): + switch (in[9]) { + case onechar('T', 0, 8): + return enum_loc_side::RIGHT_LEFT; + break; + default: + break; + } + break; + default: + break; + } + break; + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('B', 32, 64) | onechar('O', 40, 64) | onechar('T', 48, 64) | onechar('T', 56, 64): + switch (in[8]) { + case onechar('O', 0, 8): + switch (in[9]) { + case onechar('M', 0, 8): + return enum_loc_side::TOP_BOTTOM; + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + case 11: + switch (*((triehash_uu64*)&in[0])) { + case onechar('B', 0, 64) | onechar('O', 8, 64) | onechar('T', 16, 64) | onechar('T', 24, 64) | onechar('O', 32, 64) | onechar('M', 40, 64) | onechar('_', 48, 64) | onechar('L', 56, 64): + switch (in[8]) { + case onechar('E', 0, 8): + switch (in[9]) { + case onechar('F', 0, 8): + switch (in[10]) { + case onechar('T', 0, 8): + return enum_loc_side::BOTTOM_LEFT; + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + case 12: + switch (*((triehash_uu64*)&in[0])) { + case onechar('R', 0, 64) | onechar('I', 8, 64) | onechar('G', 16, 64) | onechar('H', 24, 64) | onechar('T', 32, 64) | onechar('_', 40, 64) | onechar('B', 48, 64) | onechar('O', 56, 64): + switch (*((triehash_uu32*)&in[8])) { + case onechar('T', 0, 32) | onechar('T', 8, 32) | onechar('O', 16, 32) | onechar('M', 24, 32): + return enum_loc_side::RIGHT_BOTTOM; + break; + default: + break; + } + break; + default: + break; + } + break; + case 14: + switch (*((triehash_uu64*)&in[0])) { + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): + switch (*((triehash_uu32*)&in[8])) { + case onechar('T', 0, 32) | onechar('_', 8, 32) | onechar('L', 16, 32) | onechar('E', 24, 32): + switch (in[12]) { + case onechar('F', 0, 8): + switch (in[13]) { + case onechar('T', 0, 8): + return enum_loc_side::TOP_RIGHT_LEFT; + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + case 15: + switch (*((triehash_uu64*)&in[0])) { + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('B', 32, 64) | onechar('O', 40, 64) | onechar('T', 48, 64) | onechar('T', 56, 64): + switch (*((triehash_uu32*)&in[8])) { + case onechar('O', 0, 32) | onechar('M', 8, 32) | onechar('_', 16, 32) | onechar('L', 24, 32): + switch (in[12]) { + case onechar('E', 0, 8): + switch (in[13]) { + case onechar('F', 0, 8): + switch (in[14]) { + case onechar('T', 0, 8): + return enum_loc_side::TOP_BOTTOM_LEFT; + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + case 16: + switch (*((triehash_uu64*)&in[0])) { + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): + switch (*((triehash_uu64*)&in[8])) { + case onechar('T', 0, 64) | onechar('_', 8, 64) | onechar('B', 16, 64) | onechar('O', 24, 64) | onechar('T', 32, 64) | onechar('T', 40, 64) | onechar('O', 48, 64) | onechar('M', 56, 64): + return enum_loc_side::TOP_RIGHT_BOTTOM; + break; + default: + break; + } + break; + default: + break; + } + break; + case 17: + switch (*((triehash_uu64*)&in[0])) { + case onechar('R', 0, 64) | onechar('I', 8, 64) | onechar('G', 16, 64) | onechar('H', 24, 64) | onechar('T', 32, 64) | onechar('_', 40, 64) | onechar('B', 48, 64) | onechar('O', 56, 64): + switch (*((triehash_uu64*)&in[8])) { + case onechar('T', 0, 64) | onechar('T', 8, 64) | onechar('O', 16, 64) | onechar('M', 24, 64) | onechar('_', 32, 64) | onechar('L', 40, 64) | onechar('E', 48, 64) | onechar('F', 56, 64): + switch (in[16]) { + case onechar('T', 0, 8): + return enum_loc_side::RIGHT_BOTTOM_LEFT; + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + case 21: + switch (*((triehash_uu64*)&in[0])) { + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): + switch (*((triehash_uu64*)&in[8])) { + case onechar('T', 0, 64) | onechar('_', 8, 64) | onechar('B', 16, 64) | onechar('O', 24, 64) | onechar('T', 32, 64) | onechar('T', 40, 64) | onechar('O', 48, 64) | onechar('M', 56, 64): + switch (*((triehash_uu32*)&in[16])) { + case onechar('_', 0, 32) | onechar('L', 8, 32) | onechar('E', 16, 32) | onechar('F', 24, 32): + switch (in[20]) { + case onechar('T', 0, 8): + return enum_loc_side::TOP_RIGHT_BOTTOM_LEFT; + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; + default: + break; + } + break; default: break; } diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h b/vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h index 4d78a7cf016..7cd609689df 100644 --- a/vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h +++ b/vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h @@ -4,9 +4,9 @@ * https://github.com/duck2/uxsdcxx * Modify only if your build process doesn't involve regenerating this file. * - * Cmdline: uxsdcxx/uxsdcap.py /home/kmurray/trees/vtr/vpr/src/route/rr_graph.xsd - * Input file: /home/kmurray/trees/vtr/vpr/src/route/rr_graph.xsd - * md5sum of input file: 40e83d2ea6556761d4e29f21324b1871 + * Cmdline: uxsdcxx/uxsdcap.py /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd + * Input file: /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd + * md5sum of input file: f7808029c0bfdf2e30e6e1f5f05fcc4a */ #include @@ -263,14 +263,36 @@ inline enum_loc_side conv_enum_loc_side(ucap::LocSide e, const std::function @@ -46,10 +46,21 @@ enum class enum_node_direction { UXSD_INVALID = 0, BI_DIR }; enum class enum_loc_side { UXSD_INVALID = 0, - LEFT, - RIGHT, TOP, - BOTTOM }; + RIGHT, + TOP_RIGHT, + BOTTOM, + TOP_BOTTOM, + RIGHT_BOTTOM, + TOP_RIGHT_BOTTOM, + LEFT, + TOP_LEFT, + RIGHT_LEFT, + TOP_RIGHT_LEFT, + BOTTOM_LEFT, + TOP_BOTTOM_LEFT, + RIGHT_BOTTOM_LEFT, + TOP_RIGHT_BOTTOM_LEFT }; /* Base class for the schema. */ struct DefaultRrGraphContextTypes { @@ -119,14 +130,14 @@ class RrGraphBase { virtual void finish_write() = 0; virtual void error_encountered(const char* file, int line, const char* message) = 0; /** Generated for complex type "channel": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline int get_channel_chan_width_max(typename ContextTypes::ChannelReadContext& ctx) = 0; virtual inline int get_channel_x_max(typename ContextTypes::ChannelReadContext& ctx) = 0; virtual inline int get_channel_x_min(typename ContextTypes::ChannelReadContext& ctx) = 0; @@ -134,33 +145,33 @@ class RrGraphBase { virtual inline int get_channel_y_min(typename ContextTypes::ChannelReadContext& ctx) = 0; /** Generated for complex type "x_list": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline unsigned int get_x_list_index(typename ContextTypes::XListReadContext& ctx) = 0; virtual inline int get_x_list_info(typename ContextTypes::XListReadContext& ctx) = 0; /** Generated for complex type "y_list": - * - * - * - * - */ + * + * + * + * + */ virtual inline unsigned int get_y_list_index(typename ContextTypes::YListReadContext& ctx) = 0; virtual inline int get_y_list_info(typename ContextTypes::YListReadContext& ctx) = 0; /** Generated for complex type "channels": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline typename ContextTypes::ChannelWriteContext init_channels_channel(typename ContextTypes::ChannelsWriteContext& ctx, int chan_width_max, int x_max, int x_min, int y_max, int y_min) = 0; virtual inline void finish_channels_channel(typename ContextTypes::ChannelWriteContext& ctx) = 0; virtual inline typename ContextTypes::ChannelReadContext get_channels_channel(typename ContextTypes::ChannelsReadContext& ctx) = 0; @@ -176,15 +187,15 @@ class RrGraphBase { virtual inline typename ContextTypes::YListReadContext get_channels_y_list(int n, typename ContextTypes::ChannelsReadContext& ctx) = 0; /** Generated for complex type "timing": - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + */ virtual inline float get_timing_Cin(typename ContextTypes::TimingReadContext& ctx) = 0; virtual inline void set_timing_Cin(float Cin, typename ContextTypes::TimingWriteContext& ctx) = 0; virtual inline float get_timing_Cinternal(typename ContextTypes::TimingReadContext& ctx) = 0; @@ -197,27 +208,27 @@ class RrGraphBase { virtual inline void set_timing_Tdel(float Tdel, typename ContextTypes::TimingWriteContext& ctx) = 0; /** Generated for complex type "sizing": - * - * - * - * - */ + * + * + * + * + */ virtual inline float get_sizing_buf_size(typename ContextTypes::SizingReadContext& ctx) = 0; virtual inline float get_sizing_mux_trans_size(typename ContextTypes::SizingReadContext& ctx) = 0; /** Generated for complex type "switch": - * - * - * - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + * + * + * + */ virtual inline int get_switch_id(typename ContextTypes::SwitchReadContext& ctx) = 0; virtual inline const char* get_switch_name(typename ContextTypes::SwitchReadContext& ctx) = 0; virtual inline void set_switch_name(const char* name, typename ContextTypes::SwitchWriteContext& ctx) = 0; @@ -232,12 +243,12 @@ class RrGraphBase { virtual inline typename ContextTypes::SizingReadContext get_switch_sizing(typename ContextTypes::SwitchReadContext& ctx) = 0; /** Generated for complex type "switches": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_switches_switch(typename ContextTypes::SwitchesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::SwitchWriteContext add_switches_switch(typename ContextTypes::SwitchesWriteContext& ctx, int id) = 0; virtual inline void finish_switches_switch(typename ContextTypes::SwitchWriteContext& ctx) = 0; @@ -245,25 +256,25 @@ class RrGraphBase { virtual inline typename ContextTypes::SwitchReadContext get_switches_switch(int n, typename ContextTypes::SwitchesReadContext& ctx) = 0; /** Generated for complex type "segment_timing": - * - * - * - * - */ + * + * + * + * + */ virtual inline float get_segment_timing_C_per_meter(typename ContextTypes::SegmentTimingReadContext& ctx) = 0; virtual inline void set_segment_timing_C_per_meter(float C_per_meter, typename ContextTypes::SegmentTimingWriteContext& ctx) = 0; virtual inline float get_segment_timing_R_per_meter(typename ContextTypes::SegmentTimingReadContext& ctx) = 0; virtual inline void set_segment_timing_R_per_meter(float R_per_meter, typename ContextTypes::SegmentTimingWriteContext& ctx) = 0; /** Generated for complex type "segment": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline int get_segment_id(typename ContextTypes::SegmentReadContext& ctx) = 0; virtual inline const char* get_segment_name(typename ContextTypes::SegmentReadContext& ctx) = 0; virtual inline void set_segment_name(const char* name, typename ContextTypes::SegmentWriteContext& ctx) = 0; @@ -273,12 +284,12 @@ class RrGraphBase { virtual inline bool has_segment_timing(typename ContextTypes::SegmentReadContext& ctx) = 0; /** Generated for complex type "segments": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_segments_segment(typename ContextTypes::SegmentsWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::SegmentWriteContext add_segments_segment(typename ContextTypes::SegmentsWriteContext& ctx, int id) = 0; virtual inline void finish_segments_segment(typename ContextTypes::SegmentWriteContext& ctx) = 0; @@ -286,26 +297,26 @@ class RrGraphBase { virtual inline typename ContextTypes::SegmentReadContext get_segments_segment(int n, typename ContextTypes::SegmentsReadContext& ctx) = 0; /** Generated for complex type "pin": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline int get_pin_ptc(typename ContextTypes::PinReadContext& ctx) = 0; virtual inline void set_pin_value(const char* value, typename ContextTypes::PinWriteContext& ctx) = 0; virtual inline const char* get_pin_value(typename ContextTypes::PinReadContext& ctx) = 0; /** Generated for complex type "pin_class": - * - * - * - * - * - * - */ + * + * + * + * + * + * + */ virtual inline enum_pin_type get_pin_class_type(typename ContextTypes::PinClassReadContext& ctx) = 0; virtual inline void preallocate_pin_class_pin(typename ContextTypes::PinClassWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::PinWriteContext add_pin_class_pin(typename ContextTypes::PinClassWriteContext& ctx, int ptc) = 0; @@ -314,16 +325,16 @@ class RrGraphBase { virtual inline typename ContextTypes::PinReadContext get_pin_class_pin(int n, typename ContextTypes::PinClassReadContext& ctx) = 0; /** Generated for complex type "block_type": - * - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + * + */ virtual inline int get_block_type_height(typename ContextTypes::BlockTypeReadContext& ctx) = 0; virtual inline int get_block_type_id(typename ContextTypes::BlockTypeReadContext& ctx) = 0; virtual inline const char* get_block_type_name(typename ContextTypes::BlockTypeReadContext& ctx) = 0; @@ -336,12 +347,12 @@ class RrGraphBase { virtual inline typename ContextTypes::PinClassReadContext get_block_type_pin_class(int n, typename ContextTypes::BlockTypeReadContext& ctx) = 0; /** Generated for complex type "block_types": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_block_types_block_type(typename ContextTypes::BlockTypesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::BlockTypeWriteContext add_block_types_block_type(typename ContextTypes::BlockTypesWriteContext& ctx, int height, int id, int width) = 0; virtual inline void finish_block_types_block_type(typename ContextTypes::BlockTypeWriteContext& ctx) = 0; @@ -349,14 +360,14 @@ class RrGraphBase { virtual inline typename ContextTypes::BlockTypeReadContext get_block_types_block_type(int n, typename ContextTypes::BlockTypesReadContext& ctx) = 0; /** Generated for complex type "grid_loc": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline int get_grid_loc_block_type_id(typename ContextTypes::GridLocReadContext& ctx) = 0; virtual inline int get_grid_loc_height_offset(typename ContextTypes::GridLocReadContext& ctx) = 0; virtual inline int get_grid_loc_width_offset(typename ContextTypes::GridLocReadContext& ctx) = 0; @@ -364,12 +375,12 @@ class RrGraphBase { virtual inline int get_grid_loc_y(typename ContextTypes::GridLocReadContext& ctx) = 0; /** Generated for complex type "grid_locs": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::GridLocWriteContext add_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext& ctx, int block_type_id, int height_offset, int width_offset, int x, int y) = 0; virtual inline void finish_grid_locs_grid_loc(typename ContextTypes::GridLocWriteContext& ctx) = 0; @@ -377,15 +388,15 @@ class RrGraphBase { virtual inline typename ContextTypes::GridLocReadContext get_grid_locs_grid_loc(int n, typename ContextTypes::GridLocsReadContext& ctx) = 0; /** Generated for complex type "node_loc": - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + */ virtual inline int get_node_loc_ptc(typename ContextTypes::NodeLocReadContext& ctx) = 0; virtual inline enum_loc_side get_node_loc_side(typename ContextTypes::NodeLocReadContext& ctx) = 0; virtual inline void set_node_loc_side(enum_loc_side side, typename ContextTypes::NodeLocWriteContext& ctx) = 0; @@ -395,42 +406,42 @@ class RrGraphBase { virtual inline int get_node_loc_ylow(typename ContextTypes::NodeLocReadContext& ctx) = 0; /** Generated for complex type "node_timing": - * - * - * - * - */ + * + * + * + * + */ virtual inline float get_node_timing_C(typename ContextTypes::NodeTimingReadContext& ctx) = 0; virtual inline float get_node_timing_R(typename ContextTypes::NodeTimingReadContext& ctx) = 0; /** Generated for complex type "node_segment": - * - * - * - */ + * + * + * + */ virtual inline int get_node_segment_segment_id(typename ContextTypes::NodeSegmentReadContext& ctx) = 0; /** Generated for complex type "meta": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline const char* get_meta_name(typename ContextTypes::MetaReadContext& ctx) = 0; virtual inline void set_meta_name(const char* name, typename ContextTypes::MetaWriteContext& ctx) = 0; virtual inline void set_meta_value(const char* value, typename ContextTypes::MetaWriteContext& ctx) = 0; virtual inline const char* get_meta_value(typename ContextTypes::MetaReadContext& ctx) = 0; /** Generated for complex type "metadata": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_metadata_meta(typename ContextTypes::MetadataWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::MetaWriteContext add_metadata_meta(typename ContextTypes::MetadataWriteContext& ctx) = 0; virtual inline void finish_metadata_meta(typename ContextTypes::MetaWriteContext& ctx) = 0; @@ -438,19 +449,19 @@ class RrGraphBase { virtual inline typename ContextTypes::MetaReadContext get_metadata_meta(int n, typename ContextTypes::MetadataReadContext& ctx) = 0; /** Generated for complex type "node": - * - * - * - * - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + * + * + * + * + */ virtual inline unsigned int get_node_capacity(typename ContextTypes::NodeReadContext& ctx) = 0; virtual inline enum_node_direction get_node_direction(typename ContextTypes::NodeReadContext& ctx) = 0; virtual inline void set_node_direction(enum_node_direction direction, typename ContextTypes::NodeWriteContext& ctx) = 0; @@ -473,12 +484,12 @@ class RrGraphBase { virtual inline bool has_node_metadata(typename ContextTypes::NodeReadContext& ctx) = 0; /** Generated for complex type "rr_nodes": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_rr_nodes_node(typename ContextTypes::RrNodesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::NodeWriteContext add_rr_nodes_node(typename ContextTypes::RrNodesWriteContext& ctx, unsigned int capacity, unsigned int id, enum_node_type type) = 0; virtual inline void finish_rr_nodes_node(typename ContextTypes::NodeWriteContext& ctx) = 0; @@ -486,15 +497,15 @@ class RrGraphBase { virtual inline typename ContextTypes::NodeReadContext get_rr_nodes_node(int n, typename ContextTypes::RrNodesReadContext& ctx) = 0; /** Generated for complex type "edge": - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + */ virtual inline unsigned int get_edge_sink_node(typename ContextTypes::EdgeReadContext& ctx) = 0; virtual inline unsigned int get_edge_src_node(typename ContextTypes::EdgeReadContext& ctx) = 0; virtual inline unsigned int get_edge_switch_id(typename ContextTypes::EdgeReadContext& ctx) = 0; @@ -504,12 +515,12 @@ class RrGraphBase { virtual inline bool has_edge_metadata(typename ContextTypes::EdgeReadContext& ctx) = 0; /** Generated for complex type "rr_edges": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::EdgeWriteContext add_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext& ctx, unsigned int sink_node, unsigned int src_node, unsigned int switch_id) = 0; virtual inline void finish_rr_edges_edge(typename ContextTypes::EdgeWriteContext& ctx) = 0; @@ -517,21 +528,21 @@ class RrGraphBase { virtual inline typename ContextTypes::EdgeReadContext get_rr_edges_edge(int n, typename ContextTypes::RrEdgesReadContext& ctx) = 0; /** Generated for complex type "rr_graph": - * - * - * - * - * - * - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ virtual inline const char* get_rr_graph_tool_comment(typename ContextTypes::RrGraphReadContext& ctx) = 0; virtual inline void set_rr_graph_tool_comment(const char* tool_comment, typename ContextTypes::RrGraphWriteContext& ctx) = 0; virtual inline const char* get_rr_graph_tool_name(typename ContextTypes::RrGraphReadContext& ctx) = 0; diff --git a/vpr/src/route/rr_graph.xsd b/vpr/src/route/rr_graph.xsd index 30aefe9b8cb..64fd87fa78d 100644 --- a/vpr/src/route/rr_graph.xsd +++ b/vpr/src/route/rr_graph.xsd @@ -234,23 +234,59 @@ + - - - - - - - - - + - + + + - + + + + + + + diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index a76025ed45c..d8ea7674b68 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -203,7 +203,7 @@ class t_rr_graph_storage { node_storage_.data(), node_storage_.size()), id); } - std::vector node_sides(RRNodeId id) const { + std::bitset node_sides(RRNodeId id) const { return get_node_sides( vtr::array_view_id( node_storage_.data(), node_storage_.size()), @@ -634,7 +634,7 @@ class t_rr_graph_storage { return NUM_SIDES; } - static inline std::vector get_node_sides( + static inline std::bitset get_node_sides( vtr::array_view_id node_storage, const RRNodeId& id) { auto& node_data = node_storage[id]; @@ -646,12 +646,7 @@ class t_rr_graph_storage { // Return a vector showing only the sides that the node appears std::vector exist_sides; std::bitset side_tt = node_storage[id].dir_side_.sides; - for (const e_side& side : SIDES) { - if (side_tt[size_t(side)]) { - exist_sides.push_back(side); - } - } - return exist_sides; + return side_tt; } /* Find if the given node appears on a specific side */ @@ -818,7 +813,7 @@ class t_rr_graph_view { return t_rr_graph_storage::get_node_side(node_storage_, id); } - std::vector node_sides(const RRNodeId& id) const { + std::bitset node_sides(const RRNodeId& id) const { return t_rr_graph_storage::get_node_sides(node_storage_, id); } diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index a358034622d..9fdde67571c 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -578,12 +578,17 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { inode, node.type()); } } else { - node.set_side(from_uxsd_loc_side(side)); + std::bitset side_mask = from_uxsd_loc_side(side); + for (const e_side& candidate_side : SIDES) { + if (side_mask[size_t(candidate_side)]) { + node.set_side(candidate_side); + } + } } } inline uxsd::enum_loc_side get_node_loc_side(const t_rr_node& node) final { if (node.type() == IPIN || node.type() == OPIN) { - return to_uxsd_loc_side(node.side()); + return to_uxsd_loc_side(node.sides()); } else { return uxsd::enum_loc_side::UXSD_INVALID; } @@ -1626,39 +1631,84 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { // Enum converters from/to uxsd types - e_side from_uxsd_loc_side(uxsd::enum_loc_side side) { + std::bitset from_uxsd_loc_side(uxsd::enum_loc_side side) { + std::bitset side_mask(0x0); switch (side) { - case uxsd::enum_loc_side::LEFT: - return LEFT; + case uxsd::enum_loc_side::TOP: + side_mask.set(TOP); + break; + case uxsd::enum_loc_side::TOP_LEFT: + side_mask.set(TOP); + side_mask.set(LEFT); + break; + case uxsd::enum_loc_side::TOP_RIGHT: + side_mask.set(TOP); + side_mask.set(RIGHT); + break; + case uxsd::enum_loc_side::TOP_BOTTOM: + side_mask.set(TOP); + side_mask.set(BOTTOM); + break; + case uxsd::enum_loc_side::TOP_RIGHT_LEFT: + side_mask.set(TOP); + side_mask.set(RIGHT); + side_mask.set(LEFT); + break; + case uxsd::enum_loc_side::TOP_RIGHT_BOTTOM: + side_mask.set(TOP); + side_mask.set(RIGHT); + side_mask.set(BOTTOM); + break; + case uxsd::enum_loc_side::TOP_BOTTOM_LEFT: + side_mask.set(TOP); + side_mask.set(BOTTOM); + side_mask.set(LEFT); break; case uxsd::enum_loc_side::RIGHT: - return RIGHT; + side_mask.set(RIGHT); + break; + case uxsd::enum_loc_side::RIGHT_BOTTOM: + side_mask.set(RIGHT); + side_mask.set(BOTTOM); + break; + case uxsd::enum_loc_side::RIGHT_LEFT: + side_mask.set(RIGHT); + side_mask.set(LEFT); + break; + case uxsd::enum_loc_side::RIGHT_BOTTOM_LEFT: + side_mask.set(RIGHT); + side_mask.set(BOTTOM); + side_mask.set(LEFT); break; - case uxsd::enum_loc_side::TOP: - return TOP; case uxsd::enum_loc_side::BOTTOM: - return BOTTOM; + side_mask.set(BOTTOM); + break; + case uxsd::enum_loc_side::BOTTOM_LEFT: + side_mask.set(BOTTOM); + side_mask.set(LEFT); + break; + case uxsd::enum_loc_side::LEFT: + side_mask.set(LEFT); + break; + case uxsd::enum_loc_side::TOP_RIGHT_BOTTOM_LEFT: + side_mask.set(TOP); + side_mask.set(RIGHT); + side_mask.set(BOTTOM); + side_mask.set(LEFT); break; default: report_error( "Invalid side %d", side); } + return side_mask; } - uxsd::enum_loc_side to_uxsd_loc_side(e_side side) { - switch (side) { - case LEFT: - return uxsd::enum_loc_side::LEFT; - case RIGHT: - return uxsd::enum_loc_side::RIGHT; - case TOP: - return uxsd::enum_loc_side::TOP; - case BOTTOM: - return uxsd::enum_loc_side::BOTTOM; - default: - report_error( - "Invalid side %d", side); + uxsd::enum_loc_side to_uxsd_loc_side(std::bitset sides) { + if (0 == sides.to_ulong()) { + report_error( + "Invalid side %ld", sides.to_ulong()); } + return static_cast(sides.to_ulong()); } e_direction from_uxsd_node_direction(uxsd::enum_node_direction direction) { diff --git a/vpr/src/route/rr_node.h b/vpr/src/route/rr_node.h index 4d1fc2f6e06..7230962a752 100644 --- a/vpr/src/route/rr_node.h +++ b/vpr/src/route/rr_node.h @@ -8,6 +8,7 @@ #include #include +#include // t_rr_node is a proxy object for accessing data in t_rr_graph_storage. // @@ -112,7 +113,7 @@ class t_rr_node { const char* direction_string() const; e_side side() const; - std::vector sides() const; + std::bitset sides() const; bool is_node_on_specific_side(e_side side) const; const char* side_string() const; diff --git a/vpr/src/route/rr_node_impl.h b/vpr/src/route/rr_node_impl.h index 70a228d3668..4e1888c4aa6 100644 --- a/vpr/src/route/rr_node_impl.h +++ b/vpr/src/route/rr_node_impl.h @@ -159,7 +159,7 @@ inline e_side t_rr_node::side() const { return storage_->node_side(id_); } -inline std::vector t_rr_node::sides() const { +inline std::bitset t_rr_node::sides() const { return storage_->node_sides(id_); } From ab4b14dea19bfd3363132e2c68c7c3cce4335e78 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 09:25:34 -0700 Subject: [PATCH 09/32] [VPR] Revert the conventional side sequence and introduce explicit mapping from VPR sides to uxsd sides --- .../gen/rr_graph_uxsdcxx.capnp | 26 ++++---- vpr/src/route/gen/rr_graph_uxsdcxx.h | 4 +- vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h | 66 +++++++++---------- .../route/gen/rr_graph_uxsdcxx_interface.h | 20 +++--- vpr/src/route/rr_graph.xsd | 52 +++------------ vpr/src/route/rr_graph_uxsdcxx_serializer.h | 61 ++++++++++++++++- 6 files changed, 124 insertions(+), 105 deletions(-) diff --git a/libs/libvtrcapnproto/gen/rr_graph_uxsdcxx.capnp b/libs/libvtrcapnproto/gen/rr_graph_uxsdcxx.capnp index c90c4b358db..7013bcf8ad2 100644 --- a/libs/libvtrcapnproto/gen/rr_graph_uxsdcxx.capnp +++ b/libs/libvtrcapnproto/gen/rr_graph_uxsdcxx.capnp @@ -4,9 +4,9 @@ # # Cmdline: uxsdcxx/uxsdcap.py /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd # Input file: /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd -# md5sum of input file: f7808029c0bfdf2e30e6e1f5f05fcc4a +# md5sum of input file: cd57d47fc9dfa62c7030397ca759217e -@0xa6084fe8f0768aad; +@0xe4650d345d47589d; using Cxx = import "/capnp/c++.capnp"; $Cxx.namespace("ucap"); @@ -45,21 +45,21 @@ enum NodeDirection { enum LocSide { uxsdInvalid @0; - top @1; + left @1; right @2; - topRight @3; + top @3; bottom @4; - topBottom @5; + rightLeft @5; rightBottom @6; - topRightBottom @7; - left @8; - topLeft @9; - rightLeft @10; - topRightLeft @11; - bottomLeft @12; + rightBottomLeft @7; + topRight @8; + topBottom @9; + topLeft @10; + topRightBottom @11; + topRightLeft @12; topBottomLeft @13; - rightBottomLeft @14; - topRightBottomLeft @15; + topRightBottomLeft @14; + bottomLeft @15; } struct Channel { diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx.h b/vpr/src/route/gen/rr_graph_uxsdcxx.h index 205a770be3a..b9ce441ae76 100644 --- a/vpr/src/route/gen/rr_graph_uxsdcxx.h +++ b/vpr/src/route/gen/rr_graph_uxsdcxx.h @@ -6,7 +6,7 @@ * * Cmdline: uxsdcxx/uxsdcxx.py /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd * Input file: /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd - * md5sum of input file: f7808029c0bfdf2e30e6e1f5f05fcc4a + * md5sum of input file: cd57d47fc9dfa62c7030397ca759217e */ #include @@ -1762,7 +1762,7 @@ constexpr const char* lookup_switch_type[] = {"UXSD_INVALID", "mux", "tristate", constexpr const char* lookup_pin_type[] = {"UXSD_INVALID", "OPEN", "OUTPUT", "INPUT"}; constexpr const char* lookup_node_type[] = {"UXSD_INVALID", "CHANX", "CHANY", "SOURCE", "SINK", "OPIN", "IPIN"}; constexpr const char* lookup_node_direction[] = {"UXSD_INVALID", "INC_DIR", "DEC_DIR", "BI_DIR"}; -constexpr const char* lookup_loc_side[] = {"UXSD_INVALID", "TOP", "RIGHT", "TOP_RIGHT", "BOTTOM", "TOP_BOTTOM", "RIGHT_BOTTOM", "TOP_RIGHT_BOTTOM", "LEFT", "TOP_LEFT", "RIGHT_LEFT", "TOP_RIGHT_LEFT", "BOTTOM_LEFT", "TOP_BOTTOM_LEFT", "RIGHT_BOTTOM_LEFT", "TOP_RIGHT_BOTTOM_LEFT"}; +constexpr const char* lookup_loc_side[] = {"UXSD_INVALID", "LEFT", "RIGHT", "TOP", "BOTTOM", "RIGHT_LEFT", "RIGHT_BOTTOM", "RIGHT_BOTTOM_LEFT", "TOP_RIGHT", "TOP_BOTTOM", "TOP_LEFT", "TOP_RIGHT_BOTTOM", "TOP_RIGHT_LEFT", "TOP_BOTTOM_LEFT", "TOP_RIGHT_BOTTOM_LEFT", "BOTTOM_LEFT"}; /* Lexers(string->token functions) for enums. */ inline enum_switch_type lex_enum_switch_type(const char* in, bool throw_on_invalid, const std::function* report_error) { diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h b/vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h index 7cd609689df..8474e458e00 100644 --- a/vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h +++ b/vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h @@ -6,7 +6,7 @@ * * Cmdline: uxsdcxx/uxsdcap.py /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd * Input file: /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd - * md5sum of input file: f7808029c0bfdf2e30e6e1f5f05fcc4a + * md5sum of input file: cd57d47fc9dfa62c7030397ca759217e */ #include @@ -263,36 +263,36 @@ inline enum_loc_side conv_enum_loc_side(ucap::LocSide e, const std::function @@ -46,21 +46,21 @@ enum class enum_node_direction { UXSD_INVALID = 0, BI_DIR }; enum class enum_loc_side { UXSD_INVALID = 0, - TOP, + LEFT, RIGHT, - TOP_RIGHT, + TOP, BOTTOM, - TOP_BOTTOM, + RIGHT_LEFT, RIGHT_BOTTOM, - TOP_RIGHT_BOTTOM, - LEFT, + RIGHT_BOTTOM_LEFT, + TOP_RIGHT, + TOP_BOTTOM, TOP_LEFT, - RIGHT_LEFT, + TOP_RIGHT_BOTTOM, TOP_RIGHT_LEFT, - BOTTOM_LEFT, TOP_BOTTOM_LEFT, - RIGHT_BOTTOM_LEFT, - TOP_RIGHT_BOTTOM_LEFT }; + TOP_RIGHT_BOTTOM_LEFT, + BOTTOM_LEFT }; /* Base class for the schema. */ struct DefaultRrGraphContextTypes { diff --git a/vpr/src/route/rr_graph.xsd b/vpr/src/route/rr_graph.xsd index 64fd87fa78d..decca0f9205 100644 --- a/vpr/src/route/rr_graph.xsd +++ b/vpr/src/route/rr_graph.xsd @@ -234,59 +234,23 @@ - - + - + - + - - + + + - + - - + diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 9fdde67571c..5210a071f0e 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -579,7 +579,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { } } else { std::bitset side_mask = from_uxsd_loc_side(side); - for (const e_side& candidate_side : SIDES) { + for (const e_side& candidate_side : SIDES) { if (side_mask[size_t(candidate_side)]) { node.set_side(candidate_side); } @@ -1703,12 +1703,67 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { return side_mask; } + /* The enumeration MUST follow the order of side maskcode + * so that it is easy for RRGraph writer to convert the mask code to enumerations + * + * index | LEFT BOTTOM RIGHT TOP | mask + * ======+======================+====== + * 1 | X | 0001 + * ======+======================+====== + * 2 | X | 0010 + * ======+======================+====== + * 3 | X X | 0011 + * ======+======================+====== + * 4 | X | 0100 + * ======+======================+====== + * 5 | X X | 0101 + * ======+======================+====== + * 6 | X X | 0110 + * ======+======================+====== + * 7 | X X X | 0111 + * ======+======================+====== + * 8 | X | 1000 + * ======+======================+====== + * 9 | X X | 1001 + * ======+======================+====== + * 10 | X X | 1010 + * ======+======================+====== + * 11 | X X X | 1011 + * ======+======================+====== + * 12 | X X | 1100 + * ======+======================+====== + * 13 | X X X | 1101 + * ======+======================+====== + * 14 | X X X | 1110 + * ======+======================+====== + * 15 | X X X X | 1111 + */ uxsd::enum_loc_side to_uxsd_loc_side(std::bitset sides) { - if (0 == sides.to_ulong()) { + std::array side_map = {uxsd::enum_loc_side::UXSD_INVALID, + uxsd::enum_loc_side::TOP, + uxsd::enum_loc_side::RIGHT, + uxsd::enum_loc_side::TOP_RIGHT, + uxsd::enum_loc_side::BOTTOM, + uxsd::enum_loc_side::TOP_BOTTOM, + uxsd::enum_loc_side::RIGHT_BOTTOM, + uxsd::enum_loc_side::TOP_RIGHT_BOTTOM, + uxsd::enum_loc_side::LEFT, + uxsd::enum_loc_side::TOP_LEFT, + uxsd::enum_loc_side::RIGHT_LEFT, + uxsd::enum_loc_side::TOP_RIGHT_LEFT, + uxsd::enum_loc_side::BOTTOM_LEFT, + uxsd::enum_loc_side::TOP_BOTTOM_LEFT, + uxsd::enum_loc_side::RIGHT_BOTTOM_LEFT, + uxsd::enum_loc_side::TOP_RIGHT_BOTTOM_LEFT}; + // Error out when + // - the side has no valid bits + // - the side is beyond the mapping range: this is to warn any changes on side truth table which may cause the mapping failed + if ((0 == sides.count()) + || (sides.to_ulong() > side_map.size() - 1)) { report_error( "Invalid side %ld", sides.to_ulong()); } - return static_cast(sides.to_ulong()); + return side_map[sides.to_ulong()]; } e_direction from_uxsd_node_direction(uxsd::enum_node_direction direction) { From a26afe6f61365296d8f0de2515fcf0b84cda0a82 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 09:44:47 -0700 Subject: [PATCH 10/32] [VPR] Add two methods: add_side() and set_sides(); Reworked set_side() --- vpr/src/route/rr_graph.cpp | 2 +- vpr/src/route/rr_graph_storage.cpp | 31 +++++++++++++++++++++++++++++- vpr/src/route/rr_graph_storage.h | 11 +++++++++-- vpr/src/route/rr_node.cpp | 8 ++++++++ vpr/src/route/rr_node.h | 2 ++ 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index e0f59a1220b..5cac9c13c1b 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -1496,7 +1496,7 @@ static void build_rr_sinks_sources(const int i, //for the pin on all sides at which it exists //As such, multipler driver problem can be avoided. L_rr_node[inode].set_coordinates(i + width_offset, j + height_offset, i + width_offset, j + height_offset); - L_rr_node[inode].set_side(side); + L_rr_node[inode].add_side(side); // Sanity check VTR_ASSERT(1 <= L_rr_node[inode].sides().size()); diff --git a/vpr/src/route/rr_graph_storage.cpp b/vpr/src/route/rr_graph_storage.cpp index e64d32428ab..64787164423 100644 --- a/vpr/src/route/rr_graph_storage.cpp +++ b/vpr/src/route/rr_graph_storage.cpp @@ -708,11 +708,40 @@ void t_rr_graph_storage::set_node_direction(RRNodeId id, e_direction new_directi } void t_rr_graph_storage::set_node_side(RRNodeId id, e_side new_side) { + if (node_type(id) != IPIN && node_type(id) != OPIN) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id)); + } + std::bitset side_bits; + /* The new side will overwrite existing side storage */ + side_bits[size_t(new_side)] = true; + if (side_bits.to_ulong() > CHAR_MAX) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Invalid side '%s' to be added to rr node %u", SIDE_STRING[new_side], size_t(id)); + } + node_storage_[id].dir_side_.sides = static_cast(side_bits.to_ulong()); +} + +void t_rr_graph_storage::set_node_sides(RRNodeId id, std::vector new_sides) { + if (node_type(id) != IPIN && node_type(id) != OPIN) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id)); + } + /* The new sides will overwrite existing side storage */ + std::bitset side_bits; + for (const e_side& new_side : new_sides) { + side_bits[size_t(new_side)] = true; + } + if (side_bits.to_ulong() > CHAR_MAX) { + for (const e_side& new_side : new_sides) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Invalid side '%s' to be added to rr node %u", SIDE_STRING[new_side], size_t(id)); + } + } + node_storage_[id].dir_side_.sides = static_cast(side_bits.to_ulong()); +} + +void t_rr_graph_storage::add_node_side(RRNodeId id, e_side new_side) { if (node_type(id) != IPIN && node_type(id) != OPIN) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id)); } std::bitset side_bits = node_storage_[id].dir_side_.sides; - /* Enable the side bit */ side_bits[size_t(new_side)] = true; if (side_bits.to_ulong() > CHAR_MAX) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Invalid side '%s' to be added to rr node %u", SIDE_STRING[new_side], size_t(id)); diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index d8ea7674b68..413b522d77d 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -481,10 +481,17 @@ class t_rr_graph_storage { void set_node_capacity(RRNodeId, short new_capacity); void set_node_direction(RRNodeId, e_direction new_direction); - /* Add a side to the node abbributes; - * Note that a node may have multiple valid sides + /* Set a side to the node abbributes + * Note that this function will overwrite any existing side attributes + * If the node has multiple sides, you should use the method set_node_sides() */ void set_node_side(RRNodeId, e_side new_side); + /* Set multiple sides to the node abbributes */ + void set_node_sides(RRNodeId, std::vector new_side); + /* Add a side to the node abbributes + * This is the function to use when you just add a new side WITHOUT reseting side attributes + */ + void add_node_side(RRNodeId, e_side new_side); /**************** * Edge methods * diff --git a/vpr/src/route/rr_node.cpp b/vpr/src/route/rr_node.cpp index 0319ba76a21..39b91b74daf 100644 --- a/vpr/src/route/rr_node.cpp +++ b/vpr/src/route/rr_node.cpp @@ -124,3 +124,11 @@ void t_rr_node::set_direction(e_direction new_direction) { void t_rr_node::set_side(e_side new_side) { storage_->set_node_side(id_, new_side); } + +void t_rr_node::set_sides(std::vector new_sides) { + storage_->set_node_sides(id_, new_sides); +} + +void t_rr_node::add_side(e_side new_side) { + storage_->add_node_side(id_, new_side); +} diff --git a/vpr/src/route/rr_node.h b/vpr/src/route/rr_node.h index 7230962a752..32734fb93ca 100644 --- a/vpr/src/route/rr_node.h +++ b/vpr/src/route/rr_node.h @@ -139,6 +139,8 @@ class t_rr_node { void set_direction(e_direction); void set_side(e_side); + void set_sides(std::vector); + void add_side(e_side); void next_node() { id_ = RRNodeId((size_t)(id_) + 1); From 714265d3f880c6e0b9e0dbcd0f374756f955c0af Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 09:59:30 -0700 Subject: [PATCH 11/32] [VPR] Code format fix --- .../route/gen/rr_graph_uxsdcxx_interface.h | 62 +++++++++---------- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 8 +-- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h b/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h index d2a7999dd0b..c846db4f5da 100644 --- a/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h +++ b/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h @@ -137,7 +137,7 @@ class RrGraphBase { * * * - */ + */ virtual inline int get_channel_chan_width_max(typename ContextTypes::ChannelReadContext& ctx) = 0; virtual inline int get_channel_x_max(typename ContextTypes::ChannelReadContext& ctx) = 0; virtual inline int get_channel_x_min(typename ContextTypes::ChannelReadContext& ctx) = 0; @@ -146,11 +146,11 @@ class RrGraphBase { /** Generated for complex type "x_list": * - * + * * * * - */ + */ virtual inline unsigned int get_x_list_index(typename ContextTypes::XListReadContext& ctx) = 0; virtual inline int get_x_list_info(typename ContextTypes::XListReadContext& ctx) = 0; @@ -159,7 +159,7 @@ class RrGraphBase { * * * - */ + */ virtual inline unsigned int get_y_list_index(typename ContextTypes::YListReadContext& ctx) = 0; virtual inline int get_y_list_info(typename ContextTypes::YListReadContext& ctx) = 0; @@ -171,7 +171,7 @@ class RrGraphBase { * * * - */ + */ virtual inline typename ContextTypes::ChannelWriteContext init_channels_channel(typename ContextTypes::ChannelsWriteContext& ctx, int chan_width_max, int x_max, int x_min, int y_max, int y_min) = 0; virtual inline void finish_channels_channel(typename ContextTypes::ChannelWriteContext& ctx) = 0; virtual inline typename ContextTypes::ChannelReadContext get_channels_channel(typename ContextTypes::ChannelsReadContext& ctx) = 0; @@ -188,14 +188,14 @@ class RrGraphBase { /** Generated for complex type "timing": * - * + * * * * * * * - */ + */ virtual inline float get_timing_Cin(typename ContextTypes::TimingReadContext& ctx) = 0; virtual inline void set_timing_Cin(float Cin, typename ContextTypes::TimingWriteContext& ctx) = 0; virtual inline float get_timing_Cinternal(typename ContextTypes::TimingReadContext& ctx) = 0; @@ -212,7 +212,7 @@ class RrGraphBase { * * * - */ + */ virtual inline float get_sizing_buf_size(typename ContextTypes::SizingReadContext& ctx) = 0; virtual inline float get_sizing_mux_trans_size(typename ContextTypes::SizingReadContext& ctx) = 0; @@ -223,12 +223,12 @@ class RrGraphBase { * * * - * + * * - * + * * * - */ + */ virtual inline int get_switch_id(typename ContextTypes::SwitchReadContext& ctx) = 0; virtual inline const char* get_switch_name(typename ContextTypes::SwitchReadContext& ctx) = 0; virtual inline void set_switch_name(const char* name, typename ContextTypes::SwitchWriteContext& ctx) = 0; @@ -248,7 +248,7 @@ class RrGraphBase { * * * - */ + */ virtual inline void preallocate_switches_switch(typename ContextTypes::SwitchesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::SwitchWriteContext add_switches_switch(typename ContextTypes::SwitchesWriteContext& ctx, int id) = 0; virtual inline void finish_switches_switch(typename ContextTypes::SwitchWriteContext& ctx) = 0; @@ -260,7 +260,7 @@ class RrGraphBase { * * * - */ + */ virtual inline float get_segment_timing_C_per_meter(typename ContextTypes::SegmentTimingReadContext& ctx) = 0; virtual inline void set_segment_timing_C_per_meter(float C_per_meter, typename ContextTypes::SegmentTimingWriteContext& ctx) = 0; virtual inline float get_segment_timing_R_per_meter(typename ContextTypes::SegmentTimingReadContext& ctx) = 0; @@ -274,7 +274,7 @@ class RrGraphBase { * * * - */ + */ virtual inline int get_segment_id(typename ContextTypes::SegmentReadContext& ctx) = 0; virtual inline const char* get_segment_name(typename ContextTypes::SegmentReadContext& ctx) = 0; virtual inline void set_segment_name(const char* name, typename ContextTypes::SegmentWriteContext& ctx) = 0; @@ -289,7 +289,7 @@ class RrGraphBase { * * * - */ + */ virtual inline void preallocate_segments_segment(typename ContextTypes::SegmentsWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::SegmentWriteContext add_segments_segment(typename ContextTypes::SegmentsWriteContext& ctx, int id) = 0; virtual inline void finish_segments_segment(typename ContextTypes::SegmentWriteContext& ctx) = 0; @@ -304,7 +304,7 @@ class RrGraphBase { * * * - */ + */ virtual inline int get_pin_ptc(typename ContextTypes::PinReadContext& ctx) = 0; virtual inline void set_pin_value(const char* value, typename ContextTypes::PinWriteContext& ctx) = 0; virtual inline const char* get_pin_value(typename ContextTypes::PinReadContext& ctx) = 0; @@ -316,7 +316,7 @@ class RrGraphBase { * * * - */ + */ virtual inline enum_pin_type get_pin_class_type(typename ContextTypes::PinClassReadContext& ctx) = 0; virtual inline void preallocate_pin_class_pin(typename ContextTypes::PinClassWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::PinWriteContext add_pin_class_pin(typename ContextTypes::PinClassWriteContext& ctx, int ptc) = 0; @@ -334,7 +334,7 @@ class RrGraphBase { * * * - */ + */ virtual inline int get_block_type_height(typename ContextTypes::BlockTypeReadContext& ctx) = 0; virtual inline int get_block_type_id(typename ContextTypes::BlockTypeReadContext& ctx) = 0; virtual inline const char* get_block_type_name(typename ContextTypes::BlockTypeReadContext& ctx) = 0; @@ -352,7 +352,7 @@ class RrGraphBase { * * * - */ + */ virtual inline void preallocate_block_types_block_type(typename ContextTypes::BlockTypesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::BlockTypeWriteContext add_block_types_block_type(typename ContextTypes::BlockTypesWriteContext& ctx, int height, int id, int width) = 0; virtual inline void finish_block_types_block_type(typename ContextTypes::BlockTypeWriteContext& ctx) = 0; @@ -367,7 +367,7 @@ class RrGraphBase { * * * - */ + */ virtual inline int get_grid_loc_block_type_id(typename ContextTypes::GridLocReadContext& ctx) = 0; virtual inline int get_grid_loc_height_offset(typename ContextTypes::GridLocReadContext& ctx) = 0; virtual inline int get_grid_loc_width_offset(typename ContextTypes::GridLocReadContext& ctx) = 0; @@ -380,7 +380,7 @@ class RrGraphBase { * * * - */ + */ virtual inline void preallocate_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::GridLocWriteContext add_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext& ctx, int block_type_id, int height_offset, int width_offset, int x, int y) = 0; virtual inline void finish_grid_locs_grid_loc(typename ContextTypes::GridLocWriteContext& ctx) = 0; @@ -396,7 +396,7 @@ class RrGraphBase { * * * - */ + */ virtual inline int get_node_loc_ptc(typename ContextTypes::NodeLocReadContext& ctx) = 0; virtual inline enum_loc_side get_node_loc_side(typename ContextTypes::NodeLocReadContext& ctx) = 0; virtual inline void set_node_loc_side(enum_loc_side side, typename ContextTypes::NodeLocWriteContext& ctx) = 0; @@ -410,7 +410,7 @@ class RrGraphBase { * * * - */ + */ virtual inline float get_node_timing_C(typename ContextTypes::NodeTimingReadContext& ctx) = 0; virtual inline float get_node_timing_R(typename ContextTypes::NodeTimingReadContext& ctx) = 0; @@ -418,7 +418,7 @@ class RrGraphBase { * * * - */ + */ virtual inline int get_node_segment_segment_id(typename ContextTypes::NodeSegmentReadContext& ctx) = 0; /** Generated for complex type "meta": @@ -429,7 +429,7 @@ class RrGraphBase { * * * - */ + */ virtual inline const char* get_meta_name(typename ContextTypes::MetaReadContext& ctx) = 0; virtual inline void set_meta_name(const char* name, typename ContextTypes::MetaWriteContext& ctx) = 0; virtual inline void set_meta_value(const char* value, typename ContextTypes::MetaWriteContext& ctx) = 0; @@ -441,7 +441,7 @@ class RrGraphBase { * * * - */ + */ virtual inline void preallocate_metadata_meta(typename ContextTypes::MetadataWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::MetaWriteContext add_metadata_meta(typename ContextTypes::MetadataWriteContext& ctx) = 0; virtual inline void finish_metadata_meta(typename ContextTypes::MetaWriteContext& ctx) = 0; @@ -461,7 +461,7 @@ class RrGraphBase { * * * - */ + */ virtual inline unsigned int get_node_capacity(typename ContextTypes::NodeReadContext& ctx) = 0; virtual inline enum_node_direction get_node_direction(typename ContextTypes::NodeReadContext& ctx) = 0; virtual inline void set_node_direction(enum_node_direction direction, typename ContextTypes::NodeWriteContext& ctx) = 0; @@ -489,7 +489,7 @@ class RrGraphBase { * * * - */ + */ virtual inline void preallocate_rr_nodes_node(typename ContextTypes::RrNodesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::NodeWriteContext add_rr_nodes_node(typename ContextTypes::RrNodesWriteContext& ctx, unsigned int capacity, unsigned int id, enum_node_type type) = 0; virtual inline void finish_rr_nodes_node(typename ContextTypes::NodeWriteContext& ctx) = 0; @@ -505,7 +505,7 @@ class RrGraphBase { * * * - */ + */ virtual inline unsigned int get_edge_sink_node(typename ContextTypes::EdgeReadContext& ctx) = 0; virtual inline unsigned int get_edge_src_node(typename ContextTypes::EdgeReadContext& ctx) = 0; virtual inline unsigned int get_edge_switch_id(typename ContextTypes::EdgeReadContext& ctx) = 0; @@ -520,7 +520,7 @@ class RrGraphBase { * * * - */ + */ virtual inline void preallocate_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::EdgeWriteContext add_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext& ctx, unsigned int sink_node, unsigned int src_node, unsigned int switch_id) = 0; virtual inline void finish_rr_edges_edge(typename ContextTypes::EdgeWriteContext& ctx) = 0; @@ -542,7 +542,7 @@ class RrGraphBase { * * * - */ + */ virtual inline const char* get_rr_graph_tool_comment(typename ContextTypes::RrGraphReadContext& ctx) = 0; virtual inline void set_rr_graph_tool_comment(const char* tool_comment, typename ContextTypes::RrGraphWriteContext& ctx) = 0; virtual inline const char* get_rr_graph_tool_name(typename ContextTypes::RrGraphReadContext& ctx) = 0; diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 5210a071f0e..3c8939b1d3c 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -1755,15 +1755,15 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { uxsd::enum_loc_side::TOP_BOTTOM_LEFT, uxsd::enum_loc_side::RIGHT_BOTTOM_LEFT, uxsd::enum_loc_side::TOP_RIGHT_BOTTOM_LEFT}; - // Error out when - // - the side has no valid bits + // Error out when + // - the side has no valid bits // - the side is beyond the mapping range: this is to warn any changes on side truth table which may cause the mapping failed if ((0 == sides.count()) - || (sides.to_ulong() > side_map.size() - 1)) { + || (sides.to_ulong() > side_map.size() - 1)) { report_error( "Invalid side %ld", sides.to_ulong()); } - return side_map[sides.to_ulong()]; + return side_map[sides.to_ulong()]; } e_direction from_uxsd_node_direction(uxsd::enum_node_direction direction) { From 87ca6aeb3670bf646a1512029dd8a98887ce4549 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 11:20:26 -0700 Subject: [PATCH 12/32] [VPR] Use more straight forward way to build side mapping; use bitset to set node sides --- vpr/src/route/rr_graph_storage.cpp | 21 ++++++----- vpr/src/route/rr_graph_storage.h | 13 ++++++- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 42 +++++++++------------ vpr/src/route/rr_node.cpp | 2 +- vpr/src/route/rr_node.h | 2 +- 5 files changed, 43 insertions(+), 37 deletions(-) diff --git a/vpr/src/route/rr_graph_storage.cpp b/vpr/src/route/rr_graph_storage.cpp index 64787164423..bc0ccc8b866 100644 --- a/vpr/src/route/rr_graph_storage.cpp +++ b/vpr/src/route/rr_graph_storage.cpp @@ -720,21 +720,24 @@ void t_rr_graph_storage::set_node_side(RRNodeId id, e_side new_side) { node_storage_[id].dir_side_.sides = static_cast(side_bits.to_ulong()); } -void t_rr_graph_storage::set_node_sides(RRNodeId id, std::vector new_sides) { +void t_rr_graph_storage::set_node_sides(RRNodeId id, std::bitset new_sides) { if (node_type(id) != IPIN && node_type(id) != OPIN) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id)); } /* The new sides will overwrite existing side storage */ - std::bitset side_bits; - for (const e_side& new_side : new_sides) { - side_bits[size_t(new_side)] = true; - } - if (side_bits.to_ulong() > CHAR_MAX) { - for (const e_side& new_side : new_sides) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Invalid side '%s' to be added to rr node %u", SIDE_STRING[new_side], size_t(id)); + if (new_sides.to_ulong() > CHAR_MAX) { + std::string new_sides_str; + for (const e_side& side : SIDES) { + if (new_sides[side]) { + if (!new_sides_str.empty()) { + new_sides_str.append(", "); + } + new_sides_str.append(SIDE_STRING[side]); + } } + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Invalid sides '%s' to be added to rr node %u", new_sides_str.c_str(), size_t(id)); } - node_storage_[id].dir_side_.sides = static_cast(side_bits.to_ulong()); + node_storage_[id].dir_side_.sides = static_cast(new_sides.to_ulong()); } void t_rr_graph_storage::add_node_side(RRNodeId id, e_side new_side) { diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 413b522d77d..66160d0ba2c 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -487,7 +487,7 @@ class t_rr_graph_storage { */ void set_node_side(RRNodeId, e_side new_side); /* Set multiple sides to the node abbributes */ - void set_node_sides(RRNodeId, std::vector new_side); + void set_node_sides(RRNodeId, std::bitset new_side); /* Add a side to the node abbributes * This is the function to use when you just add a new side WITHOUT reseting side attributes */ @@ -624,6 +624,16 @@ class t_rr_graph_storage { rr_node_typename[node_data.type_]); } std::bitset side_tt = node_storage[id].dir_side_.sides; + if (1 < side_tt.count()) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, + "Try to get one side for RR node '%d':\n\ttype='%s'\txlow,ylow=(%d,%d)\n\txhigh,yhigh=(%d,%d), which has multiple sides!", + size_t(id), + rr_node_typename[node_data.type_], + node_data.xlow_, + node_data.ylow_, + node_data.xhigh_, + node_data.yhigh_); + } for (const e_side& side : SIDES) { if (side_tt[size_t(side)]) { return side; @@ -651,7 +661,6 @@ class t_rr_graph_storage { rr_node_typename[node_data.type_]); } // Return a vector showing only the sides that the node appears - std::vector exist_sides; std::bitset side_tt = node_storage[id].dir_side_.sides; return side_tt; } diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 3c8939b1d3c..f08ec73230f 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -578,12 +578,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { inode, node.type()); } } else { - std::bitset side_mask = from_uxsd_loc_side(side); - for (const e_side& candidate_side : SIDES) { - if (side_mask[size_t(candidate_side)]) { - node.set_side(candidate_side); - } - } + node.set_sides(from_uxsd_loc_side(side)); } } inline uxsd::enum_loc_side get_node_loc_side(const t_rr_node& node) final { @@ -1703,8 +1698,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { return side_mask; } - /* The enumeration MUST follow the order of side maskcode - * so that it is easy for RRGraph writer to convert the mask code to enumerations + /* A truth table to help understand the conversion from VPR side mask to uxsd side code * * index | LEFT BOTTOM RIGHT TOP | mask * ======+======================+====== @@ -1739,22 +1733,22 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { * 15 | X X X X | 1111 */ uxsd::enum_loc_side to_uxsd_loc_side(std::bitset sides) { - std::array side_map = {uxsd::enum_loc_side::UXSD_INVALID, - uxsd::enum_loc_side::TOP, - uxsd::enum_loc_side::RIGHT, - uxsd::enum_loc_side::TOP_RIGHT, - uxsd::enum_loc_side::BOTTOM, - uxsd::enum_loc_side::TOP_BOTTOM, - uxsd::enum_loc_side::RIGHT_BOTTOM, - uxsd::enum_loc_side::TOP_RIGHT_BOTTOM, - uxsd::enum_loc_side::LEFT, - uxsd::enum_loc_side::TOP_LEFT, - uxsd::enum_loc_side::RIGHT_LEFT, - uxsd::enum_loc_side::TOP_RIGHT_LEFT, - uxsd::enum_loc_side::BOTTOM_LEFT, - uxsd::enum_loc_side::TOP_BOTTOM_LEFT, - uxsd::enum_loc_side::RIGHT_BOTTOM_LEFT, - uxsd::enum_loc_side::TOP_RIGHT_BOTTOM_LEFT}; + std::array side_map; + side_map[0] = uxsd::enum_loc_side::UXSD_INVALID; + side_map[(1 << TOP)] = uxsd::enum_loc_side::TOP; + side_map[(1 << RIGHT)] = uxsd::enum_loc_side::RIGHT; + side_map[(1 << BOTTOM)] = uxsd::enum_loc_side::BOTTOM; + side_map[(1 << TOP) | (1 << RIGHT)] = uxsd::enum_loc_side::TOP_RIGHT; + side_map[(1 << TOP) | (1 << BOTTOM)] = uxsd::enum_loc_side::TOP_BOTTOM; + side_map[(1 << RIGHT) | (1 << BOTTOM)] = uxsd::enum_loc_side::RIGHT_BOTTOM; + side_map[(1 << TOP) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_LEFT; + side_map[(1 << RIGHT) | (1 << LEFT)] = uxsd::enum_loc_side::RIGHT_LEFT; + side_map[(1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::BOTTOM_LEFT; + side_map[(1 << TOP) | (1 << RIGHT) | (1 << BOTTOM)] = uxsd::enum_loc_side::TOP_RIGHT_BOTTOM; + side_map[(1 << TOP) | (1 << RIGHT) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_RIGHT_LEFT; + side_map[(1 << TOP) | (1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_BOTTOM_LEFT; + side_map[(1 << RIGHT) | (1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::RIGHT_BOTTOM_LEFT; + side_map[(1 << TOP) | (1 << RIGHT) | (1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_RIGHT_BOTTOM_LEFT; // Error out when // - the side has no valid bits // - the side is beyond the mapping range: this is to warn any changes on side truth table which may cause the mapping failed diff --git a/vpr/src/route/rr_node.cpp b/vpr/src/route/rr_node.cpp index 39b91b74daf..dbd4450e9ca 100644 --- a/vpr/src/route/rr_node.cpp +++ b/vpr/src/route/rr_node.cpp @@ -125,7 +125,7 @@ void t_rr_node::set_side(e_side new_side) { storage_->set_node_side(id_, new_side); } -void t_rr_node::set_sides(std::vector new_sides) { +void t_rr_node::set_sides(std::bitset new_sides) { storage_->set_node_sides(id_, new_sides); } diff --git a/vpr/src/route/rr_node.h b/vpr/src/route/rr_node.h index 32734fb93ca..b43a6cde678 100644 --- a/vpr/src/route/rr_node.h +++ b/vpr/src/route/rr_node.h @@ -139,7 +139,7 @@ class t_rr_node { void set_direction(e_direction); void set_side(e_side); - void set_sides(std::vector); + void set_sides(std::bitset); void add_side(e_side); void next_node() { From 126acb2c799ac9c5a157ac5403186cb95f2738cf Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 11:57:51 -0700 Subject: [PATCH 13/32] [VPR] Reduce fatal error in node_side() to suppressable error, so that titan tests can pass --- vpr/src/route/rr_graph_storage.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 66160d0ba2c..7c219590276 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -625,14 +625,15 @@ class t_rr_graph_storage { } std::bitset side_tt = node_storage[id].dir_side_.sides; if (1 < side_tt.count()) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, - "Try to get one side for RR node '%d':\n\ttype='%s'\txlow,ylow=(%d,%d)\n\txhigh,yhigh=(%d,%d), which has multiple sides!", - size_t(id), - rr_node_typename[node_data.type_], - node_data.xlow_, - node_data.ylow_, - node_data.xhigh_, - node_data.yhigh_); + /* Throw a non-fatal error which is suppressable */ + VPR_ERROR(VPR_ERROR_ROUTE, + "Try to get one side for RR node '%d':\n\ttype='%s'\txlow,ylow=(%d,%d)\n\txhigh,yhigh=(%d,%d), which has multiple sides!", + size_t(id), + rr_node_typename[node_data.type_], + node_data.xlow_, + node_data.ylow_, + node_data.xhigh_, + node_data.yhigh_); } for (const e_side& side : SIDES) { if (side_tt[size_t(side)]) { From 69c619cb1353d5192630046fc7ffb48df3a57b0e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 12:48:54 -0700 Subject: [PATCH 14/32] [VPR] reduce error to warning --- vpr/src/route/rr_graph_storage.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 7c219590276..c9c79e32fae 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -626,14 +626,13 @@ class t_rr_graph_storage { std::bitset side_tt = node_storage[id].dir_side_.sides; if (1 < side_tt.count()) { /* Throw a non-fatal error which is suppressable */ - VPR_ERROR(VPR_ERROR_ROUTE, - "Try to get one side for RR node '%d':\n\ttype='%s'\txlow,ylow=(%d,%d)\n\txhigh,yhigh=(%d,%d), which has multiple sides!", - size_t(id), - rr_node_typename[node_data.type_], - node_data.xlow_, - node_data.ylow_, - node_data.xhigh_, - node_data.yhigh_); + VTR_LOG_WARN("Try to get one side for RR node '%d':\n\ttype='%s'\txlow,ylow=(%d,%d)\n\txhigh,yhigh=(%d,%d), which has multiple sides!", + size_t(id), + rr_node_typename[node_data.type_], + node_data.xlow_, + node_data.ylow_, + node_data.xhigh_, + node_data.yhigh_); } for (const e_side& side : SIDES) { if (side_tt[size_t(side)]) { From 3e266a1fa65ba873da8ba2b135b179629a0a7739 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 14:21:08 -0700 Subject: [PATCH 15/32] [VPR] Bug fix in the type conversion --- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index f08ec73230f..75de8e51e9e 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -1738,10 +1738,11 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { side_map[(1 << TOP)] = uxsd::enum_loc_side::TOP; side_map[(1 << RIGHT)] = uxsd::enum_loc_side::RIGHT; side_map[(1 << BOTTOM)] = uxsd::enum_loc_side::BOTTOM; + side_map[(1 << LEFT)] = uxsd::enum_loc_side::LEFT; + side_map[(1 << TOP) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_LEFT; side_map[(1 << TOP) | (1 << RIGHT)] = uxsd::enum_loc_side::TOP_RIGHT; side_map[(1 << TOP) | (1 << BOTTOM)] = uxsd::enum_loc_side::TOP_BOTTOM; side_map[(1 << RIGHT) | (1 << BOTTOM)] = uxsd::enum_loc_side::RIGHT_BOTTOM; - side_map[(1 << TOP) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_LEFT; side_map[(1 << RIGHT) | (1 << LEFT)] = uxsd::enum_loc_side::RIGHT_LEFT; side_map[(1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::BOTTOM_LEFT; side_map[(1 << TOP) | (1 << RIGHT) | (1 << BOTTOM)] = uxsd::enum_loc_side::TOP_RIGHT_BOTTOM; From c890a2fe625446bfac0cec4e43111d086d1dc3e4 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 14:56:54 -0700 Subject: [PATCH 16/32] [Arch] Add a small RRGraph (11x8 array) for titan architecture to test node_sides --- .../stratixv_arch.timing_11x8_rr_graph.xml | 57386 ++++++++++++++++ 1 file changed, 57386 insertions(+) create mode 100644 vtr_flow/arch/titan/rr_graph/stratixv_arch.timing_11x8_rr_graph.xml diff --git a/vtr_flow/arch/titan/rr_graph/stratixv_arch.timing_11x8_rr_graph.xml b/vtr_flow/arch/titan/rr_graph/stratixv_arch.timing_11x8_rr_graph.xml new file mode 100644 index 00000000000..3cd23f50314 --- /dev/null +++ b/vtr_flow/arch/titan/rr_graph/stratixv_arch.timing_11x8_rr_graph.xml @@ -0,0 +1,57386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +io[0].core_in[0] + +io[0].core_in[1] + +io[0].core_in[2] + +io[0].core_in[3] + +io[0].core_in[4] + +io[0].core_in[5] + +io[0].core_in[6] + +io[0].core_in[7] + +io[0].core_in[8] + +io[0].core_in[9] + +io[0].core_in[10] + +io[0].core_in[11] + +io[0].core_in[12] + +io[0].core_in[13] + +io[0].core_in[14] + +io[0].core_in[15] + +io[0].core_in[16] + +io[0].core_in[17] + +io[0].core_in[18] + +io[0].core_in[19] + +io[0].core_in[20] + +io[0].core_in[21] + +io[0].core_in[22] + +io[0].core_in[23] + +io[0].core_in[24] + +io[0].core_in[25] + +io[0].core_in[26] + +io[0].core_in[27] + +io[0].core_in[28] + +io[0].core_in[29] + +io[0].core_in[30] + +io[0].core_in[31] + +io[0].core_in[32] + +io[0].core_in[33] + +io[0].core_in[34] + +io[0].core_in[35] + +io[0].core_in[36] + +io[0].core_in[37] + +io[0].core_in[38] + +io[0].core_in[39] + +io[0].core_in[40] + +io[0].core_in[41] + +io[0].core_in[42] + +io[0].core_in[43] + +io[0].core_in[44] + +io[0].core_in[45] + +io[0].core_in[46] + +io[0].core_in[47] + +io[0].core_in[48] + +io[0].core_in[49] + +io[0].core_out[0] + +io[0].core_out[1] + +io[0].core_out[2] + +io[0].core_out[3] + +io[0].core_out[4] + +io[0].core_out[5] + +io[0].core_out[6] + +io[0].core_out[7] + +io[0].core_out[8] + +io[0].core_out[9] + +io[0].core_out[10] + +io[0].core_out[11] + +io[0].core_out[12] + +io[0].core_out[13] + +io[0].core_out[14] + +io[0].core_out[15] + +io[0].core_out[16] + +io[0].core_out[17] + +io[0].core_out[18] + +io[0].core_out[19] + +io[0].core_out[20] + +io[0].core_out[21] + +io[0].core_out[22] + +io[0].core_out[23] + +io[0].core_out[24] + +io[0].core_out[25] + +io[0].core_out[26] + +io[0].core_out[27] + +io[0].core_out[28] + +io[0].core_out[29] + +io[0].core_out[30] + +io[0].core_out[31] + +io[0].core_out[32] + +io[0].core_out[33] + +io[0].core_out[34] + +io[0].core_out[35] + +io[0].core_out[36] + +io[0].core_out[37] + +io[0].core_out[38] + +io[0].core_out[39] + +io[0].clk[0] + +io[0].clk[1] + +io[0].clk[2] + +io[0].clk[3] + +io[0].clk[4] + +io[1].core_in[0] + +io[1].core_in[1] + +io[1].core_in[2] + +io[1].core_in[3] + +io[1].core_in[4] + +io[1].core_in[5] + +io[1].core_in[6] + +io[1].core_in[7] + +io[1].core_in[8] + +io[1].core_in[9] + +io[1].core_in[10] + +io[1].core_in[11] + +io[1].core_in[12] + +io[1].core_in[13] + +io[1].core_in[14] + +io[1].core_in[15] + +io[1].core_in[16] + +io[1].core_in[17] + +io[1].core_in[18] + +io[1].core_in[19] + +io[1].core_in[20] + +io[1].core_in[21] + +io[1].core_in[22] + +io[1].core_in[23] + +io[1].core_in[24] + +io[1].core_in[25] + +io[1].core_in[26] + +io[1].core_in[27] + +io[1].core_in[28] + +io[1].core_in[29] + +io[1].core_in[30] + +io[1].core_in[31] + +io[1].core_in[32] + +io[1].core_in[33] + +io[1].core_in[34] + +io[1].core_in[35] + +io[1].core_in[36] + +io[1].core_in[37] + +io[1].core_in[38] + +io[1].core_in[39] + +io[1].core_in[40] + +io[1].core_in[41] + +io[1].core_in[42] + +io[1].core_in[43] + +io[1].core_in[44] + +io[1].core_in[45] + +io[1].core_in[46] + +io[1].core_in[47] + +io[1].core_in[48] + +io[1].core_in[49] + +io[1].core_out[0] + +io[1].core_out[1] + +io[1].core_out[2] + +io[1].core_out[3] + +io[1].core_out[4] + +io[1].core_out[5] + +io[1].core_out[6] + +io[1].core_out[7] + +io[1].core_out[8] + +io[1].core_out[9] + +io[1].core_out[10] + +io[1].core_out[11] + +io[1].core_out[12] + +io[1].core_out[13] + +io[1].core_out[14] + +io[1].core_out[15] + +io[1].core_out[16] + +io[1].core_out[17] + +io[1].core_out[18] + +io[1].core_out[19] + +io[1].core_out[20] + +io[1].core_out[21] + +io[1].core_out[22] + +io[1].core_out[23] + +io[1].core_out[24] + +io[1].core_out[25] + +io[1].core_out[26] + +io[1].core_out[27] + +io[1].core_out[28] + +io[1].core_out[29] + +io[1].core_out[30] + +io[1].core_out[31] + +io[1].core_out[32] + +io[1].core_out[33] + +io[1].core_out[34] + +io[1].core_out[35] + +io[1].core_out[36] + +io[1].core_out[37] + +io[1].core_out[38] + +io[1].core_out[39] + +io[1].clk[0] + +io[1].clk[1] + +io[1].clk[2] + +io[1].clk[3] + +io[1].clk[4] + + +PLL.in_signal[0] + +PLL.in_signal[1] + +PLL.in_signal[2] + +PLL.in_signal[3] + +PLL.in_signal[4] + +PLL.in_signal[5] + +PLL.in_signal[6] + +PLL.in_signal[7] + +PLL.in_signal[8] + +PLL.in_signal[9] + +PLL.in_signal[10] + +PLL.in_signal[11] + +PLL.in_signal[12] + +PLL.in_signal[13] + +PLL.out_clock[0] + +PLL.out_clock[1] + +PLL.out_clock[2] + +PLL.out_clock[3] + +PLL.out_clock[4] + +PLL.out_clock[5] + +PLL.out_clock[6] + +PLL.out_clock[7] + +PLL.out_clock[8] + +PLL.out_clock[9] + +PLL.out_signal[0] + +PLL.out_signal[1] + +PLL.out_signal[2] + +PLL.out_signal[3] + +PLL.out_signal[4] + +PLL.out_signal[5] + +PLL.out_signal[6] + +PLL.out_signal[7] + +PLL.out_signal[8] + +PLL.out_signal[9] + +PLL.in_clock[0] + +PLL.in_clock[1] + + +LAB.data_in[0] +LAB.data_in[1] +LAB.data_in[2] +LAB.data_in[3] +LAB.data_in[4] +LAB.data_in[5] +LAB.data_in[6] +LAB.data_in[7] +LAB.data_in[8] +LAB.data_in[9] +LAB.data_in[10] +LAB.data_in[11] +LAB.data_in[12] +LAB.data_in[13] +LAB.data_in[14] +LAB.data_in[15] +LAB.data_in[16] +LAB.data_in[17] +LAB.data_in[18] +LAB.data_in[19] +LAB.data_in[20] +LAB.data_in[21] +LAB.data_in[22] +LAB.data_in[23] +LAB.data_in[24] +LAB.data_in[25] +LAB.data_in[26] +LAB.data_in[27] +LAB.data_in[28] +LAB.data_in[29] +LAB.data_in[30] +LAB.data_in[31] +LAB.data_in[32] +LAB.data_in[33] +LAB.data_in[34] +LAB.data_in[35] +LAB.data_in[36] +LAB.data_in[37] +LAB.data_in[38] +LAB.data_in[39] +LAB.data_in[40] +LAB.data_in[41] +LAB.data_in[42] +LAB.data_in[43] +LAB.data_in[44] +LAB.data_in[45] +LAB.data_in[46] +LAB.data_in[47] +LAB.data_in[48] +LAB.data_in[49] +LAB.data_in[50] +LAB.data_in[51] +LAB.data_in[52] +LAB.data_in[53] +LAB.data_in[54] +LAB.data_in[55] +LAB.data_in[56] +LAB.data_in[57] +LAB.data_in[58] +LAB.data_in[59] +LAB.data_in[60] +LAB.data_in[61] +LAB.data_in[62] +LAB.data_in[63] +LAB.data_in[64] +LAB.data_in[65] +LAB.data_in[66] +LAB.data_in[67] +LAB.data_in[68] +LAB.data_in[69] +LAB.data_in[70] +LAB.data_in[71] +LAB.data_in[72] +LAB.data_in[73] +LAB.data_in[74] +LAB.data_in[75] +LAB.data_in[76] +LAB.data_in[77] +LAB.data_in[78] +LAB.data_in[79] + +LAB.control_in[0] +LAB.control_in[1] +LAB.control_in[2] +LAB.control_in[3] +LAB.control_in[4] +LAB.control_in[5] +LAB.control_in[6] + +LAB.cin[0] + +LAB.sharein[0] + +LAB.data_out[0] +LAB.data_out[1] +LAB.data_out[2] +LAB.data_out[3] +LAB.data_out[4] +LAB.data_out[5] +LAB.data_out[6] +LAB.data_out[7] +LAB.data_out[8] +LAB.data_out[9] +LAB.data_out[10] +LAB.data_out[11] +LAB.data_out[12] +LAB.data_out[13] +LAB.data_out[14] +LAB.data_out[15] +LAB.data_out[16] +LAB.data_out[17] +LAB.data_out[18] +LAB.data_out[19] +LAB.data_out[20] +LAB.data_out[21] +LAB.data_out[22] +LAB.data_out[23] +LAB.data_out[24] +LAB.data_out[25] +LAB.data_out[26] +LAB.data_out[27] +LAB.data_out[28] +LAB.data_out[29] +LAB.data_out[30] +LAB.data_out[31] +LAB.data_out[32] +LAB.data_out[33] +LAB.data_out[34] +LAB.data_out[35] +LAB.data_out[36] +LAB.data_out[37] +LAB.data_out[38] +LAB.data_out[39] + +LAB.cout[0] + +LAB.shareout[0] + +LAB.clk[0] + +LAB.clk[1] + + +DSP.data_in[0] + +DSP.data_in[1] + +DSP.data_in[2] + +DSP.data_in[3] + +DSP.data_in[4] + +DSP.data_in[5] + +DSP.data_in[6] + +DSP.data_in[7] + +DSP.data_in[8] + +DSP.data_in[9] + +DSP.data_in[10] + +DSP.data_in[11] + +DSP.data_in[12] + +DSP.data_in[13] + +DSP.data_in[14] + +DSP.data_in[15] + +DSP.data_in[16] + +DSP.data_in[17] + +DSP.data_in[18] + +DSP.data_in[19] + +DSP.data_in[20] + +DSP.data_in[21] + +DSP.data_in[22] + +DSP.data_in[23] + +DSP.data_in[24] + +DSP.data_in[25] + +DSP.data_in[26] + +DSP.data_in[27] + +DSP.data_in[28] + +DSP.data_in[29] + +DSP.data_in[30] + +DSP.data_in[31] + +DSP.data_in[32] + +DSP.data_in[33] + +DSP.data_in[34] + +DSP.data_in[35] + +DSP.data_in[36] + +DSP.data_in[37] + +DSP.data_in[38] + +DSP.data_in[39] + +DSP.data_in[40] + +DSP.data_in[41] + +DSP.data_in[42] + +DSP.data_in[43] + +DSP.data_in[44] + +DSP.data_in[45] + +DSP.data_in[46] + +DSP.data_in[47] + +DSP.data_in[48] + +DSP.data_in[49] + +DSP.data_in[50] + +DSP.data_in[51] + +DSP.data_in[52] + +DSP.data_in[53] + +DSP.data_in[54] + +DSP.data_in[55] + +DSP.data_in[56] + +DSP.data_in[57] + +DSP.data_in[58] + +DSP.data_in[59] + +DSP.data_in[60] + +DSP.data_in[61] + +DSP.data_in[62] + +DSP.data_in[63] + +DSP.data_in[64] + +DSP.data_in[65] + +DSP.data_in[66] + +DSP.data_in[67] + +DSP.data_in[68] + +DSP.data_in[69] + +DSP.data_in[70] + +DSP.data_in[71] + +DSP.data_in[72] + +DSP.data_in[73] + +DSP.data_in[74] + +DSP.data_in[75] + +DSP.data_in[76] + +DSP.data_in[77] + +DSP.data_in[78] + +DSP.data_in[79] + +DSP.data_in[80] + +DSP.data_in[81] + +DSP.data_in[82] + +DSP.data_in[83] + +DSP.data_in[84] + +DSP.data_in[85] + +DSP.data_in[86] + +DSP.data_in[87] + +DSP.data_in[88] + +DSP.data_in[89] + +DSP.data_in[90] + +DSP.data_in[91] + +DSP.data_in[92] + +DSP.data_in[93] + +DSP.data_in[94] + +DSP.data_in[95] + +DSP.data_in[96] + +DSP.data_in[97] + +DSP.data_in[98] + +DSP.data_in[99] + +DSP.data_in[100] + +DSP.data_in[101] + +DSP.data_in[102] + +DSP.data_in[103] + +DSP.data_in[104] + +DSP.data_in[105] + +DSP.data_in[106] + +DSP.data_in[107] + +DSP.data_in[108] + +DSP.data_in[109] + +DSP.data_in[110] + +DSP.data_in[111] + +DSP.data_in[112] + +DSP.data_in[113] + +DSP.data_in[114] + +DSP.data_in[115] + +DSP.data_in[116] + +DSP.data_in[117] + +DSP.data_in[118] + +DSP.data_in[119] + +DSP.data_in[120] + +DSP.data_in[121] + +DSP.data_in[122] + +DSP.data_in[123] + +DSP.data_in[124] + +DSP.data_in[125] + +DSP.data_in[126] + +DSP.data_in[127] + +DSP.data_in[128] + +DSP.data_in[129] + +DSP.data_in[130] + +DSP.data_in[131] + +DSP.data_in[132] + +DSP.data_in[133] + +DSP.data_in[134] + +DSP.data_in[135] + +DSP.data_in[136] + +DSP.data_in[137] + +DSP.data_in[138] + +DSP.data_in[139] + +DSP.data_in[140] + +DSP.data_in[141] + +DSP.data_in[142] + +DSP.data_in[143] + +DSP.data_in[144] + +DSP.data_in[145] + +DSP.data_in[146] + +DSP.data_in[147] + +DSP.data_in[148] + +DSP.data_in[149] + +DSP.data_in[150] + +DSP.data_in[151] + +DSP.data_in[152] + +DSP.data_in[153] + +DSP.data_in[154] + +DSP.data_in[155] + +DSP.data_in[156] + +DSP.data_in[157] + +DSP.data_in[158] + +DSP.data_in[159] + +DSP.data_in[160] + +DSP.data_in[161] + +DSP.data_in[162] + +DSP.data_in[163] + +DSP.data_in[164] + +DSP.data_in[165] + +DSP.data_in[166] + +DSP.data_in[167] + +DSP.data_in[168] + +DSP.data_in[169] + +DSP.data_in[170] + +DSP.data_in[171] + +DSP.data_in[172] + +DSP.data_in[173] + +DSP.data_in[174] + +DSP.data_in[175] + +DSP.data_in[176] + +DSP.data_in[177] + +DSP.data_in[178] + +DSP.data_in[179] + +DSP.data_in[180] + +DSP.data_in[181] + +DSP.data_in[182] + +DSP.data_in[183] + +DSP.data_in[184] + +DSP.data_in[185] + +DSP.data_in[186] + +DSP.data_in[187] + +DSP.data_in[188] + +DSP.data_in[189] + +DSP.data_in[190] + +DSP.data_in[191] + +DSP.data_in[192] + +DSP.data_in[193] + +DSP.data_in[194] + +DSP.data_in[195] + +DSP.data_in[196] + +DSP.data_in[197] + +DSP.data_in[198] + +DSP.data_in[199] + +DSP.data_in[200] + +DSP.data_in[201] + +DSP.data_in[202] + +DSP.data_in[203] + +DSP.data_in[204] + +DSP.data_in[205] + +DSP.data_in[206] + +DSP.data_in[207] + +DSP.data_in[208] + +DSP.data_in[209] + +DSP.data_in[210] + +DSP.data_in[211] + +DSP.data_in[212] + +DSP.data_in[213] + +DSP.data_in[214] + +DSP.data_in[215] + +DSP.data_in[216] + +DSP.data_in[217] + +DSP.data_in[218] + +DSP.data_in[219] + +DSP.data_in[220] + +DSP.data_in[221] + +DSP.data_in[222] + +DSP.data_in[223] + +DSP.data_in[224] + +DSP.data_in[225] + +DSP.data_in[226] + +DSP.data_in[227] + +DSP.data_in[228] + +DSP.data_in[229] + +DSP.data_in[230] + +DSP.data_in[231] + +DSP.data_in[232] + +DSP.data_in[233] + +DSP.data_in[234] + +DSP.data_in[235] + +DSP.data_in[236] + +DSP.data_in[237] + +DSP.data_in[238] + +DSP.data_in[239] + +DSP.data_in[240] + +DSP.data_in[241] + +DSP.data_in[242] + +DSP.data_in[243] + +DSP.data_in[244] + +DSP.data_in[245] + +DSP.data_in[246] + +DSP.data_in[247] + +DSP.data_in[248] + +DSP.data_in[249] + +DSP.data_in[250] + +DSP.data_in[251] + +DSP.data_in[252] + +DSP.data_in[253] + +DSP.data_in[254] + +DSP.data_in[255] + +DSP.data_in[256] + +DSP.data_in[257] + +DSP.data_in[258] + +DSP.data_in[259] + +DSP.data_in[260] + +DSP.data_in[261] + +DSP.data_in[262] + +DSP.data_in[263] + +DSP.data_in[264] + +DSP.data_in[265] + +DSP.data_in[266] + +DSP.data_in[267] + +DSP.data_in[268] + +DSP.data_in[269] + +DSP.data_in[270] + +DSP.data_in[271] + +DSP.data_in[272] + +DSP.data_in[273] + +DSP.data_in[274] + +DSP.data_in[275] + +DSP.data_in[276] + +DSP.data_in[277] + +DSP.data_in[278] + +DSP.data_in[279] + +DSP.data_in[280] + +DSP.data_in[281] + +DSP.data_in[282] + +DSP.data_in[283] + +DSP.data_in[284] + +DSP.data_in[285] + +DSP.data_in[286] + +DSP.data_in[287] + +DSP.chain_in[0] + +DSP.chain_in[1] + +DSP.chain_in[2] + +DSP.chain_in[3] + +DSP.chain_in[4] + +DSP.chain_in[5] + +DSP.chain_in[6] + +DSP.chain_in[7] + +DSP.chain_in[8] + +DSP.chain_in[9] + +DSP.chain_in[10] + +DSP.chain_in[11] + +DSP.chain_in[12] + +DSP.chain_in[13] + +DSP.chain_in[14] + +DSP.chain_in[15] + +DSP.chain_in[16] + +DSP.chain_in[17] + +DSP.chain_in[18] + +DSP.chain_in[19] + +DSP.chain_in[20] + +DSP.chain_in[21] + +DSP.chain_in[22] + +DSP.chain_in[23] + +DSP.chain_in[24] + +DSP.chain_in[25] + +DSP.chain_in[26] + +DSP.chain_in[27] + +DSP.chain_in[28] + +DSP.chain_in[29] + +DSP.chain_in[30] + +DSP.chain_in[31] + +DSP.chain_in[32] + +DSP.chain_in[33] + +DSP.chain_in[34] + +DSP.chain_in[35] + +DSP.chain_in[36] + +DSP.chain_in[37] + +DSP.chain_in[38] + +DSP.chain_in[39] + +DSP.chain_in[40] + +DSP.chain_in[41] + +DSP.chain_in[42] + +DSP.chain_in[43] + +DSP.control_in[0] + +DSP.control_in[1] + +DSP.control_in[2] + +DSP.control_in[3] + +DSP.control_in[4] + +DSP.control_in[5] + +DSP.control_in[6] + +DSP.control_in[7] + +DSP.control_in[8] + +DSP.control_in[9] + +DSP.control_in[10] + +DSP.control_in[11] + +DSP.control_in[12] + +DSP.control_in[13] + +DSP.control_in[14] + +DSP.control_in[15] + +DSP.control_in[16] + +DSP.control_in[17] + +DSP.control_in[18] + +DSP.control_in[19] + +DSP.control_in[20] + +DSP.scan_a_in[0] + +DSP.scan_a_in[1] + +DSP.scan_a_in[2] + +DSP.scan_a_in[3] + +DSP.scan_a_in[4] + +DSP.scan_a_in[5] + +DSP.scan_a_in[6] + +DSP.scan_a_in[7] + +DSP.scan_a_in[8] + +DSP.scan_a_in[9] + +DSP.scan_a_in[10] + +DSP.scan_a_in[11] + +DSP.scan_a_in[12] + +DSP.scan_a_in[13] + +DSP.scan_a_in[14] + +DSP.scan_a_in[15] + +DSP.scan_a_in[16] + +DSP.scan_a_in[17] + +DSP.data_out_top[0] + +DSP.data_out_top[1] + +DSP.data_out_top[2] + +DSP.data_out_top[3] + +DSP.data_out_top[4] + +DSP.data_out_top[5] + +DSP.data_out_top[6] + +DSP.data_out_top[7] + +DSP.data_out_top[8] + +DSP.data_out_top[9] + +DSP.data_out_top[10] + +DSP.data_out_top[11] + +DSP.data_out_top[12] + +DSP.data_out_top[13] + +DSP.data_out_top[14] + +DSP.data_out_top[15] + +DSP.data_out_top[16] + +DSP.data_out_top[17] + +DSP.data_out_top[18] + +DSP.data_out_top[19] + +DSP.data_out_top[20] + +DSP.data_out_top[21] + +DSP.data_out_top[22] + +DSP.data_out_top[23] + +DSP.data_out_top[24] + +DSP.data_out_top[25] + +DSP.data_out_top[26] + +DSP.data_out_top[27] + +DSP.data_out_top[28] + +DSP.data_out_top[29] + +DSP.data_out_top[30] + +DSP.data_out_top[31] + +DSP.data_out_top[32] + +DSP.data_out_top[33] + +DSP.data_out_top[34] + +DSP.data_out_top[35] + +DSP.data_out_top[36] + +DSP.data_out_top[37] + +DSP.data_out_top[38] + +DSP.data_out_top[39] + +DSP.data_out_top[40] + +DSP.data_out_top[41] + +DSP.data_out_top[42] + +DSP.data_out_top[43] + +DSP.data_out_top[44] + +DSP.data_out_top[45] + +DSP.data_out_top[46] + +DSP.data_out_top[47] + +DSP.data_out_top[48] + +DSP.data_out_top[49] + +DSP.data_out_top[50] + +DSP.data_out_top[51] + +DSP.data_out_top[52] + +DSP.data_out_top[53] + +DSP.data_out_top[54] + +DSP.data_out_top[55] + +DSP.data_out_top[56] + +DSP.data_out_top[57] + +DSP.data_out_top[58] + +DSP.data_out_top[59] + +DSP.data_out_top[60] + +DSP.data_out_top[61] + +DSP.data_out_top[62] + +DSP.data_out_top[63] + +DSP.data_out_top[64] + +DSP.data_out_top[65] + +DSP.data_out_top[66] + +DSP.data_out_top[67] + +DSP.data_out_top[68] + +DSP.data_out_top[69] + +DSP.data_out_top[70] + +DSP.data_out_top[71] + +DSP.data_out_bot[0] + +DSP.data_out_bot[1] + +DSP.data_out_bot[2] + +DSP.data_out_bot[3] + +DSP.data_out_bot[4] + +DSP.data_out_bot[5] + +DSP.data_out_bot[6] + +DSP.data_out_bot[7] + +DSP.data_out_bot[8] + +DSP.data_out_bot[9] + +DSP.data_out_bot[10] + +DSP.data_out_bot[11] + +DSP.data_out_bot[12] + +DSP.data_out_bot[13] + +DSP.data_out_bot[14] + +DSP.data_out_bot[15] + +DSP.data_out_bot[16] + +DSP.data_out_bot[17] + +DSP.data_out_bot[18] + +DSP.data_out_bot[19] + +DSP.data_out_bot[20] + +DSP.data_out_bot[21] + +DSP.data_out_bot[22] + +DSP.data_out_bot[23] + +DSP.data_out_bot[24] + +DSP.data_out_bot[25] + +DSP.data_out_bot[26] + +DSP.data_out_bot[27] + +DSP.data_out_bot[28] + +DSP.data_out_bot[29] + +DSP.data_out_bot[30] + +DSP.data_out_bot[31] + +DSP.data_out_bot[32] + +DSP.data_out_bot[33] + +DSP.data_out_bot[34] + +DSP.data_out_bot[35] + +DSP.data_out_bot[36] + +DSP.data_out_bot[37] + +DSP.data_out_bot[38] + +DSP.data_out_bot[39] + +DSP.data_out_bot[40] + +DSP.data_out_bot[41] + +DSP.data_out_bot[42] + +DSP.data_out_bot[43] + +DSP.data_out_bot[44] + +DSP.data_out_bot[45] + +DSP.data_out_bot[46] + +DSP.data_out_bot[47] + +DSP.data_out_bot[48] + +DSP.data_out_bot[49] + +DSP.data_out_bot[50] + +DSP.data_out_bot[51] + +DSP.data_out_bot[52] + +DSP.data_out_bot[53] + +DSP.data_out_bot[54] + +DSP.data_out_bot[55] + +DSP.data_out_bot[56] + +DSP.data_out_bot[57] + +DSP.data_out_bot[58] + +DSP.data_out_bot[59] + +DSP.data_out_bot[60] + +DSP.data_out_bot[61] + +DSP.data_out_bot[62] + +DSP.data_out_bot[63] + +DSP.data_out_bot[64] + +DSP.data_out_bot[65] + +DSP.data_out_bot[66] + +DSP.data_out_bot[67] + +DSP.data_out_bot[68] + +DSP.data_out_bot[69] + +DSP.data_out_bot[70] + +DSP.data_out_bot[71] + +DSP.chain_out[0] + +DSP.chain_out[1] + +DSP.chain_out[2] + +DSP.chain_out[3] + +DSP.chain_out[4] + +DSP.chain_out[5] + +DSP.chain_out[6] + +DSP.chain_out[7] + +DSP.chain_out[8] + +DSP.chain_out[9] + +DSP.chain_out[10] + +DSP.chain_out[11] + +DSP.chain_out[12] + +DSP.chain_out[13] + +DSP.chain_out[14] + +DSP.chain_out[15] + +DSP.chain_out[16] + +DSP.chain_out[17] + +DSP.chain_out[18] + +DSP.chain_out[19] + +DSP.chain_out[20] + +DSP.chain_out[21] + +DSP.chain_out[22] + +DSP.chain_out[23] + +DSP.chain_out[24] + +DSP.chain_out[25] + +DSP.chain_out[26] + +DSP.chain_out[27] + +DSP.chain_out[28] + +DSP.chain_out[29] + +DSP.chain_out[30] + +DSP.chain_out[31] + +DSP.chain_out[32] + +DSP.chain_out[33] + +DSP.chain_out[34] + +DSP.chain_out[35] + +DSP.chain_out[36] + +DSP.chain_out[37] + +DSP.chain_out[38] + +DSP.chain_out[39] + +DSP.chain_out[40] + +DSP.chain_out[41] + +DSP.chain_out[42] + +DSP.chain_out[43] + +DSP.scan_a_out[0] + +DSP.scan_a_out[1] + +DSP.scan_a_out[2] + +DSP.scan_a_out[3] + +DSP.scan_a_out[4] + +DSP.scan_a_out[5] + +DSP.scan_a_out[6] + +DSP.scan_a_out[7] + +DSP.scan_a_out[8] + +DSP.scan_a_out[9] + +DSP.scan_a_out[10] + +DSP.scan_a_out[11] + +DSP.scan_a_out[12] + +DSP.scan_a_out[13] + +DSP.scan_a_out[14] + +DSP.scan_a_out[15] + +DSP.scan_a_out[16] + +DSP.scan_a_out[17] + +DSP.signal_out[0] + +DSP.signal_out[1] + +DSP.signal_out[2] + +DSP.signal_out[3] + +DSP.signal_out[4] + +DSP.signal_out[5] + +DSP.clk[0] + +DSP.clk[1] + +DSP.clk[2] + +DSP.clk[3] + + +M9K.data_addr_control_in[0] + +M9K.data_addr_control_in[1] + +M9K.data_addr_control_in[2] + +M9K.data_addr_control_in[3] + +M9K.data_addr_control_in[4] + +M9K.data_addr_control_in[5] + +M9K.data_addr_control_in[6] + +M9K.data_addr_control_in[7] + +M9K.data_addr_control_in[8] + +M9K.data_addr_control_in[9] + +M9K.data_addr_control_in[10] + +M9K.data_addr_control_in[11] + +M9K.data_addr_control_in[12] + +M9K.data_addr_control_in[13] + +M9K.data_addr_control_in[14] + +M9K.data_addr_control_in[15] + +M9K.data_addr_control_in[16] + +M9K.data_addr_control_in[17] + +M9K.data_addr_control_in[18] + +M9K.data_addr_control_in[19] + +M9K.data_addr_control_in[20] + +M9K.data_addr_control_in[21] + +M9K.data_addr_control_in[22] + +M9K.data_addr_control_in[23] + +M9K.data_addr_control_in[24] + +M9K.data_addr_control_in[25] + +M9K.data_addr_control_in[26] + +M9K.data_addr_control_in[27] + +M9K.data_addr_control_in[28] + +M9K.data_addr_control_in[29] + +M9K.data_addr_control_in[30] + +M9K.data_addr_control_in[31] + +M9K.data_addr_control_in[32] + +M9K.data_addr_control_in[33] + +M9K.data_addr_control_in[34] + +M9K.data_addr_control_in[35] + +M9K.data_addr_control_in[36] + +M9K.data_addr_control_in[37] + +M9K.data_addr_control_in[38] + +M9K.data_addr_control_in[39] + +M9K.data_addr_control_in[40] + +M9K.data_addr_control_in[41] + +M9K.data_addr_control_in[42] + +M9K.data_addr_control_in[43] + +M9K.data_addr_control_in[44] + +M9K.data_addr_control_in[45] + +M9K.data_addr_control_in[46] + +M9K.data_addr_control_in[47] + +M9K.data_addr_control_in[48] + +M9K.data_addr_control_in[49] + +M9K.data_addr_control_in[50] + +M9K.data_addr_control_in[51] + +M9K.data_addr_control_in[52] + +M9K.data_addr_control_in[53] + +M9K.data_addr_control_in[54] + +M9K.data_addr_control_in[55] + +M9K.data_addr_control_in[56] + +M9K.data_addr_control_in[57] + +M9K.data_addr_control_in[58] + +M9K.data_addr_control_in[59] + +M9K.data_addr_control_in[60] + +M9K.data_addr_control_in[61] + +M9K.data_addr_control_in[62] + +M9K.data_addr_control_in[63] + +M9K.data_addr_control_in[64] + +M9K.data_addr_control_in[65] + +M9K.data_addr_control_in[66] + +M9K.data_addr_control_in[67] + +M9K.data_addr_control_in[68] + +M9K.data_addr_control_in[69] + +M9K.data_addr_control_in[70] + +M9K.data_addr_control_in[71] + +M9K.data_addr_control_in[72] + +M9K.data_addr_control_in[73] + +M9K.data_addr_control_in[74] + +M9K.data_addr_control_in[75] + +M9K.data_addr_control_in[76] + +M9K.data_addr_control_in[77] + +M9K.data_addr_control_in[78] + +M9K.data_addr_control_in[79] + +M9K.data_addr_control_in[80] + +M9K.data_addr_control_in[81] + +M9K.data_addr_control_in[82] + +M9K.data_addr_control_in[83] + +M9K.data_addr_control_in[84] + +M9K.data_addr_control_in[85] + +M9K.data_addr_control_in[86] + +M9K.data_addr_control_in[87] + +M9K.data_addr_control_in[88] + +M9K.data_addr_control_in[89] + +M9K.data_addr_control_in[90] + +M9K.data_addr_control_in[91] + +M9K.data_addr_control_in[92] + +M9K.data_addr_control_in[93] + +M9K.data_addr_control_in[94] + +M9K.data_addr_control_in[95] + +M9K.data_addr_control_in[96] + +M9K.data_addr_control_in[97] + +M9K.data_addr_control_in[98] + +M9K.data_addr_control_in[99] + +M9K.data_addr_control_in[100] + +M9K.data_addr_control_in[101] + +M9K.data_addr_control_in[102] + +M9K.data_addr_control_in[103] + +M9K.data_out[0] + +M9K.data_out[1] + +M9K.data_out[2] + +M9K.data_out[3] + +M9K.data_out[4] + +M9K.data_out[5] + +M9K.data_out[6] + +M9K.data_out[7] + +M9K.data_out[8] + +M9K.data_out[9] + +M9K.data_out[10] + +M9K.data_out[11] + +M9K.data_out[12] + +M9K.data_out[13] + +M9K.data_out[14] + +M9K.data_out[15] + +M9K.data_out[16] + +M9K.data_out[17] + +M9K.data_out[18] + +M9K.data_out[19] + +M9K.data_out[20] + +M9K.data_out[21] + +M9K.data_out[22] + +M9K.data_out[23] + +M9K.data_out[24] + +M9K.data_out[25] + +M9K.data_out[26] + +M9K.data_out[27] + +M9K.data_out[28] + +M9K.data_out[29] + +M9K.data_out[30] + +M9K.data_out[31] + +M9K.data_out[32] + +M9K.data_out[33] + +M9K.data_out[34] + +M9K.data_out[35] + +M9K.control_out[0] + +M9K.control_out[1] + +M9K.control_out[2] + +M9K.clk_in[0] + +M9K.clk_in[1] + + +M144K.data_addr_control_in[0] + +M144K.data_addr_control_in[1] + +M144K.data_addr_control_in[2] + +M144K.data_addr_control_in[3] + +M144K.data_addr_control_in[4] + +M144K.data_addr_control_in[5] + +M144K.data_addr_control_in[6] + +M144K.data_addr_control_in[7] + +M144K.data_addr_control_in[8] + +M144K.data_addr_control_in[9] + +M144K.data_addr_control_in[10] + +M144K.data_addr_control_in[11] + +M144K.data_addr_control_in[12] + +M144K.data_addr_control_in[13] + +M144K.data_addr_control_in[14] + +M144K.data_addr_control_in[15] + +M144K.data_addr_control_in[16] + +M144K.data_addr_control_in[17] + +M144K.data_addr_control_in[18] + +M144K.data_addr_control_in[19] + +M144K.data_addr_control_in[20] + +M144K.data_addr_control_in[21] + +M144K.data_addr_control_in[22] + +M144K.data_addr_control_in[23] + +M144K.data_addr_control_in[24] + +M144K.data_addr_control_in[25] + +M144K.data_addr_control_in[26] + +M144K.data_addr_control_in[27] + +M144K.data_addr_control_in[28] + +M144K.data_addr_control_in[29] + +M144K.data_addr_control_in[30] + +M144K.data_addr_control_in[31] + +M144K.data_addr_control_in[32] + +M144K.data_addr_control_in[33] + +M144K.data_addr_control_in[34] + +M144K.data_addr_control_in[35] + +M144K.data_addr_control_in[36] + +M144K.data_addr_control_in[37] + +M144K.data_addr_control_in[38] + +M144K.data_addr_control_in[39] + +M144K.data_addr_control_in[40] + +M144K.data_addr_control_in[41] + +M144K.data_addr_control_in[42] + +M144K.data_addr_control_in[43] + +M144K.data_addr_control_in[44] + +M144K.data_addr_control_in[45] + +M144K.data_addr_control_in[46] + +M144K.data_addr_control_in[47] + +M144K.data_addr_control_in[48] + +M144K.data_addr_control_in[49] + +M144K.data_addr_control_in[50] + +M144K.data_addr_control_in[51] + +M144K.data_addr_control_in[52] + +M144K.data_addr_control_in[53] + +M144K.data_addr_control_in[54] + +M144K.data_addr_control_in[55] + +M144K.data_addr_control_in[56] + +M144K.data_addr_control_in[57] + +M144K.data_addr_control_in[58] + +M144K.data_addr_control_in[59] + +M144K.data_addr_control_in[60] + +M144K.data_addr_control_in[61] + +M144K.data_addr_control_in[62] + +M144K.data_addr_control_in[63] + +M144K.data_addr_control_in[64] + +M144K.data_addr_control_in[65] + +M144K.data_addr_control_in[66] + +M144K.data_addr_control_in[67] + +M144K.data_addr_control_in[68] + +M144K.data_addr_control_in[69] + +M144K.data_addr_control_in[70] + +M144K.data_addr_control_in[71] + +M144K.data_addr_control_in[72] + +M144K.data_addr_control_in[73] + +M144K.data_addr_control_in[74] + +M144K.data_addr_control_in[75] + +M144K.data_addr_control_in[76] + +M144K.data_addr_control_in[77] + +M144K.data_addr_control_in[78] + +M144K.data_addr_control_in[79] + +M144K.data_addr_control_in[80] + +M144K.data_addr_control_in[81] + +M144K.data_addr_control_in[82] + +M144K.data_addr_control_in[83] + +M144K.data_addr_control_in[84] + +M144K.data_addr_control_in[85] + +M144K.data_addr_control_in[86] + +M144K.data_addr_control_in[87] + +M144K.data_addr_control_in[88] + +M144K.data_addr_control_in[89] + +M144K.data_addr_control_in[90] + +M144K.data_addr_control_in[91] + +M144K.data_addr_control_in[92] + +M144K.data_addr_control_in[93] + +M144K.data_addr_control_in[94] + +M144K.data_addr_control_in[95] + +M144K.data_addr_control_in[96] + +M144K.data_addr_control_in[97] + +M144K.data_addr_control_in[98] + +M144K.data_addr_control_in[99] + +M144K.data_addr_control_in[100] + +M144K.data_addr_control_in[101] + +M144K.data_addr_control_in[102] + +M144K.data_addr_control_in[103] + +M144K.data_addr_control_in[104] + +M144K.data_addr_control_in[105] + +M144K.data_addr_control_in[106] + +M144K.data_addr_control_in[107] + +M144K.data_addr_control_in[108] + +M144K.data_addr_control_in[109] + +M144K.data_addr_control_in[110] + +M144K.data_addr_control_in[111] + +M144K.data_addr_control_in[112] + +M144K.data_addr_control_in[113] + +M144K.data_addr_control_in[114] + +M144K.data_addr_control_in[115] + +M144K.data_addr_control_in[116] + +M144K.data_addr_control_in[117] + +M144K.data_addr_control_in[118] + +M144K.data_addr_control_in[119] + +M144K.data_addr_control_in[120] + +M144K.data_addr_control_in[121] + +M144K.data_addr_control_in[122] + +M144K.data_addr_control_in[123] + +M144K.data_addr_control_in[124] + +M144K.data_addr_control_in[125] + +M144K.data_addr_control_in[126] + +M144K.data_addr_control_in[127] + +M144K.data_addr_control_in[128] + +M144K.data_addr_control_in[129] + +M144K.data_addr_control_in[130] + +M144K.data_addr_control_in[131] + +M144K.data_addr_control_in[132] + +M144K.data_addr_control_in[133] + +M144K.data_addr_control_in[134] + +M144K.data_addr_control_in[135] + +M144K.data_addr_control_in[136] + +M144K.data_addr_control_in[137] + +M144K.data_addr_control_in[138] + +M144K.data_addr_control_in[139] + +M144K.data_addr_control_in[140] + +M144K.data_addr_control_in[141] + +M144K.data_addr_control_in[142] + +M144K.data_addr_control_in[143] + +M144K.data_addr_control_in[144] + +M144K.data_addr_control_in[145] + +M144K.data_addr_control_in[146] + +M144K.data_addr_control_in[147] + +M144K.data_addr_control_in[148] + +M144K.data_addr_control_in[149] + +M144K.data_addr_control_in[150] + +M144K.data_addr_control_in[151] + +M144K.data_addr_control_in[152] + +M144K.data_addr_control_in[153] + +M144K.data_addr_control_in[154] + +M144K.data_addr_control_in[155] + +M144K.data_addr_control_in[156] + +M144K.data_addr_control_in[157] + +M144K.data_addr_control_in[158] + +M144K.data_addr_control_in[159] + +M144K.data_addr_control_in[160] + +M144K.data_addr_control_in[161] + +M144K.data_addr_control_in[162] + +M144K.data_addr_control_in[163] + +M144K.data_addr_control_in[164] + +M144K.data_addr_control_in[165] + +M144K.data_addr_control_in[166] + +M144K.data_addr_control_in[167] + +M144K.data_addr_control_in[168] + +M144K.data_addr_control_in[169] + +M144K.data_addr_control_in[170] + +M144K.data_addr_control_in[171] + +M144K.data_addr_control_in[172] + +M144K.data_addr_control_in[173] + +M144K.data_addr_control_in[174] + +M144K.data_addr_control_in[175] + +M144K.data_addr_control_in[176] + +M144K.data_addr_control_in[177] + +M144K.data_addr_control_in[178] + +M144K.data_addr_control_in[179] + +M144K.data_addr_control_in[180] + +M144K.data_addr_control_in[181] + +M144K.data_addr_control_in[182] + +M144K.data_addr_control_in[183] + +M144K.data_addr_control_in[184] + +M144K.data_addr_control_in[185] + +M144K.data_addr_control_in[186] + +M144K.data_addr_control_in[187] + +M144K.data_addr_control_in[188] + +M144K.data_addr_control_in[189] + +M144K.data_addr_control_in[190] + +M144K.data_addr_control_in[191] + +M144K.data_addr_control_in[192] + +M144K.data_addr_control_in[193] + +M144K.data_addr_control_in[194] + +M144K.data_addr_control_in[195] + +M144K.data_addr_control_in[196] + +M144K.data_addr_control_in[197] + +M144K.data_addr_control_in[198] + +M144K.data_addr_control_in[199] + +M144K.data_addr_control_in[200] + +M144K.data_addr_control_in[201] + +M144K.data_addr_control_in[202] + +M144K.data_addr_control_in[203] + +M144K.data_addr_control_in[204] + +M144K.data_addr_control_in[205] + +M144K.data_addr_control_in[206] + +M144K.data_addr_control_in[207] + +M144K.data_addr_control_in[208] + +M144K.data_addr_control_in[209] + +M144K.data_addr_control_in[210] + +M144K.data_addr_control_in[211] + +M144K.data_addr_control_in[212] + +M144K.data_addr_control_in[213] + +M144K.data_addr_control_in[214] + +M144K.data_addr_control_in[215] + +M144K.data_addr_control_in[216] + +M144K.data_addr_control_in[217] + +M144K.data_addr_control_in[218] + +M144K.data_addr_control_in[219] + +M144K.data_addr_control_in[220] + +M144K.data_addr_control_in[221] + +M144K.data_addr_control_in[222] + +M144K.data_addr_control_in[223] + +M144K.data_addr_control_in[224] + +M144K.data_addr_control_in[225] + +M144K.data_addr_control_in[226] + +M144K.data_addr_control_in[227] + +M144K.data_addr_control_in[228] + +M144K.data_addr_control_in[229] + +M144K.data_addr_control_in[230] + +M144K.data_addr_control_in[231] + +M144K.data_addr_control_in[232] + +M144K.data_addr_control_in[233] + +M144K.data_addr_control_in[234] + +M144K.data_addr_control_in[235] + +M144K.data_addr_control_in[236] + +M144K.data_addr_control_in[237] + +M144K.data_addr_control_in[238] + +M144K.data_addr_control_in[239] + +M144K.data_addr_control_in[240] + +M144K.data_addr_control_in[241] + +M144K.data_addr_control_in[242] + +M144K.data_addr_control_in[243] + +M144K.data_addr_control_in[244] + +M144K.data_addr_control_in[245] + +M144K.data_addr_control_in[246] + +M144K.data_addr_control_in[247] + +M144K.data_addr_control_in[248] + +M144K.data_addr_control_in[249] + +M144K.data_addr_control_in[250] + +M144K.data_addr_control_in[251] + +M144K.data_addr_control_in[252] + +M144K.data_addr_control_in[253] + +M144K.data_addr_control_in[254] + +M144K.data_addr_control_in[255] + +M144K.data_addr_control_in[256] + +M144K.data_addr_control_in[257] + +M144K.data_addr_control_in[258] + +M144K.data_addr_control_in[259] + +M144K.data_addr_control_in[260] + +M144K.data_addr_control_in[261] + +M144K.data_addr_control_in[262] + +M144K.data_addr_control_in[263] + +M144K.data_addr_control_in[264] + +M144K.data_addr_control_in[265] + +M144K.data_addr_control_in[266] + +M144K.data_addr_control_in[267] + +M144K.data_addr_control_in[268] + +M144K.data_addr_control_in[269] + +M144K.data_addr_control_in[270] + +M144K.data_addr_control_in[271] + +M144K.data_addr_control_in[272] + +M144K.data_addr_control_in[273] + +M144K.data_addr_control_in[274] + +M144K.data_addr_control_in[275] + +M144K.data_addr_control_in[276] + +M144K.data_addr_control_in[277] + +M144K.data_addr_control_in[278] + +M144K.data_addr_control_in[279] + +M144K.data_addr_control_in[280] + +M144K.data_addr_control_in[281] + +M144K.data_addr_control_in[282] + +M144K.data_addr_control_in[283] + +M144K.data_addr_control_in[284] + +M144K.data_addr_control_in[285] + +M144K.data_addr_control_in[286] + +M144K.data_addr_control_in[287] + +M144K.data_addr_control_in[288] + +M144K.data_addr_control_in[289] + +M144K.data_addr_control_in[290] + +M144K.data_addr_control_in[291] + +M144K.data_addr_control_in[292] + +M144K.data_addr_control_in[293] + +M144K.data_addr_control_in[294] + +M144K.data_addr_control_in[295] + +M144K.data_addr_control_in[296] + +M144K.data_addr_control_in[297] + +M144K.data_addr_control_in[298] + +M144K.data_addr_control_in[299] + +M144K.data_addr_control_in[300] + +M144K.data_addr_control_in[301] + +M144K.data_addr_control_in[302] + +M144K.data_addr_control_in[303] + +M144K.data_addr_control_in[304] + +M144K.data_addr_control_in[305] + +M144K.data_addr_control_in[306] + +M144K.data_addr_control_in[307] + +M144K.data_addr_control_in[308] + +M144K.data_addr_control_in[309] + +M144K.data_addr_control_in[310] + +M144K.data_addr_control_in[311] + +M144K.data_addr_control_in[312] + +M144K.data_addr_control_in[313] + +M144K.data_addr_control_in[314] + +M144K.data_addr_control_in[315] + +M144K.data_addr_control_in[316] + +M144K.data_addr_control_in[317] + +M144K.data_addr_control_in[318] + +M144K.data_addr_control_in[319] + +M144K.data_addr_control_in[320] + +M144K.data_addr_control_in[321] + +M144K.data_addr_control_in[322] + +M144K.data_addr_control_in[323] + +M144K.data_addr_control_in[324] + +M144K.data_addr_control_in[325] + +M144K.data_addr_control_in[326] + +M144K.data_addr_control_in[327] + +M144K.data_addr_control_in[328] + +M144K.data_addr_control_in[329] + +M144K.data_addr_control_in[330] + +M144K.data_addr_control_in[331] + +M144K.data_addr_control_in[332] + +M144K.data_addr_control_in[333] + +M144K.data_addr_control_in[334] + +M144K.data_addr_control_in[335] + +M144K.data_addr_control_in[336] + +M144K.data_addr_control_in[337] + +M144K.data_addr_control_in[338] + +M144K.data_addr_control_in[339] + +M144K.data_addr_control_in[340] + +M144K.data_addr_control_in[341] + +M144K.data_addr_control_in[342] + +M144K.data_addr_control_in[343] + +M144K.data_addr_control_in[344] + +M144K.data_addr_control_in[345] + +M144K.data_addr_control_in[346] + +M144K.data_addr_control_in[347] + +M144K.data_addr_control_in[348] + +M144K.data_addr_control_in[349] + +M144K.data_addr_control_in[350] + +M144K.data_addr_control_in[351] + +M144K.data_addr_control_in[352] + +M144K.data_addr_control_in[353] + +M144K.data_addr_control_in[354] + +M144K.data_addr_control_in[355] + +M144K.data_addr_control_in[356] + +M144K.data_addr_control_in[357] + +M144K.data_addr_control_in[358] + +M144K.data_addr_control_in[359] + +M144K.data_addr_control_in[360] + +M144K.data_addr_control_in[361] + +M144K.data_addr_control_in[362] + +M144K.data_addr_control_in[363] + +M144K.data_addr_control_in[364] + +M144K.data_addr_control_in[365] + +M144K.data_addr_control_in[366] + +M144K.data_addr_control_in[367] + +M144K.data_addr_control_in[368] + +M144K.data_addr_control_in[369] + +M144K.data_addr_control_in[370] + +M144K.data_addr_control_in[371] + +M144K.data_addr_control_in[372] + +M144K.data_addr_control_in[373] + +M144K.data_addr_control_in[374] + +M144K.data_addr_control_in[375] + +M144K.data_addr_control_in[376] + +M144K.data_addr_control_in[377] + +M144K.data_addr_control_in[378] + +M144K.data_addr_control_in[379] + +M144K.data_addr_control_in[380] + +M144K.data_addr_control_in[381] + +M144K.data_addr_control_in[382] + +M144K.data_addr_control_in[383] + +M144K.data_addr_control_in[384] + +M144K.data_addr_control_in[385] + +M144K.data_addr_control_in[386] + +M144K.data_addr_control_in[387] + +M144K.data_addr_control_in[388] + +M144K.data_addr_control_in[389] + +M144K.data_addr_control_in[390] + +M144K.data_addr_control_in[391] + +M144K.data_addr_control_in[392] + +M144K.data_addr_control_in[393] + +M144K.data_addr_control_in[394] + +M144K.data_addr_control_in[395] + +M144K.data_addr_control_in[396] + +M144K.data_addr_control_in[397] + +M144K.data_addr_control_in[398] + +M144K.data_addr_control_in[399] + +M144K.data_addr_control_in[400] + +M144K.data_addr_control_in[401] + +M144K.data_addr_control_in[402] + +M144K.data_addr_control_in[403] + +M144K.data_addr_control_in[404] + +M144K.data_addr_control_in[405] + +M144K.data_addr_control_in[406] + +M144K.data_addr_control_in[407] + +M144K.data_addr_control_in[408] + +M144K.data_addr_control_in[409] + +M144K.data_addr_control_in[410] + +M144K.data_addr_control_in[411] + +M144K.data_addr_control_in[412] + +M144K.data_addr_control_in[413] + +M144K.data_addr_control_in[414] + +M144K.data_addr_control_in[415] + +M144K.data_out[0] + +M144K.data_out[1] + +M144K.data_out[2] + +M144K.data_out[3] + +M144K.data_out[4] + +M144K.data_out[5] + +M144K.data_out[6] + +M144K.data_out[7] + +M144K.data_out[8] + +M144K.data_out[9] + +M144K.data_out[10] + +M144K.data_out[11] + +M144K.data_out[12] + +M144K.data_out[13] + +M144K.data_out[14] + +M144K.data_out[15] + +M144K.data_out[16] + +M144K.data_out[17] + +M144K.data_out[18] + +M144K.data_out[19] + +M144K.data_out[20] + +M144K.data_out[21] + +M144K.data_out[22] + +M144K.data_out[23] + +M144K.data_out[24] + +M144K.data_out[25] + +M144K.data_out[26] + +M144K.data_out[27] + +M144K.data_out[28] + +M144K.data_out[29] + +M144K.data_out[30] + +M144K.data_out[31] + +M144K.data_out[32] + +M144K.data_out[33] + +M144K.data_out[34] + +M144K.data_out[35] + +M144K.data_out[36] + +M144K.data_out[37] + +M144K.data_out[38] + +M144K.data_out[39] + +M144K.data_out[40] + +M144K.data_out[41] + +M144K.data_out[42] + +M144K.data_out[43] + +M144K.data_out[44] + +M144K.data_out[45] + +M144K.data_out[46] + +M144K.data_out[47] + +M144K.data_out[48] + +M144K.data_out[49] + +M144K.data_out[50] + +M144K.data_out[51] + +M144K.data_out[52] + +M144K.data_out[53] + +M144K.data_out[54] + +M144K.data_out[55] + +M144K.data_out[56] + +M144K.data_out[57] + +M144K.data_out[58] + +M144K.data_out[59] + +M144K.data_out[60] + +M144K.data_out[61] + +M144K.data_out[62] + +M144K.data_out[63] + +M144K.data_out[64] + +M144K.data_out[65] + +M144K.data_out[66] + +M144K.data_out[67] + +M144K.data_out[68] + +M144K.data_out[69] + +M144K.data_out[70] + +M144K.data_out[71] + +M144K.data_out[72] + +M144K.data_out[73] + +M144K.data_out[74] + +M144K.data_out[75] + +M144K.data_out[76] + +M144K.data_out[77] + +M144K.data_out[78] + +M144K.data_out[79] + +M144K.data_out[80] + +M144K.data_out[81] + +M144K.data_out[82] + +M144K.data_out[83] + +M144K.data_out[84] + +M144K.data_out[85] + +M144K.data_out[86] + +M144K.data_out[87] + +M144K.data_out[88] + +M144K.data_out[89] + +M144K.data_out[90] + +M144K.data_out[91] + +M144K.data_out[92] + +M144K.data_out[93] + +M144K.data_out[94] + +M144K.data_out[95] + +M144K.data_out[96] + +M144K.data_out[97] + +M144K.data_out[98] + +M144K.data_out[99] + +M144K.data_out[100] + +M144K.data_out[101] + +M144K.data_out[102] + +M144K.data_out[103] + +M144K.data_out[104] + +M144K.data_out[105] + +M144K.data_out[106] + +M144K.data_out[107] + +M144K.data_out[108] + +M144K.data_out[109] + +M144K.data_out[110] + +M144K.data_out[111] + +M144K.data_out[112] + +M144K.data_out[113] + +M144K.data_out[114] + +M144K.data_out[115] + +M144K.data_out[116] + +M144K.data_out[117] + +M144K.data_out[118] + +M144K.data_out[119] + +M144K.control_out[0] + +M144K.control_out[1] + +M144K.control_out[2] + +M144K.clk_in[0] + +M144K.clk_in[1] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5e3eed5af5304f6a549a7b8d64be81be8628b244 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 15:02:56 -0700 Subject: [PATCH 17/32] [Test] Add a new test case for read rr_graph --- .../strong_read_rr_graph/config/config.txt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt new file mode 100644 index 00000000000..7fc257b8504 --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt @@ -0,0 +1,27 @@ +# +############################################ +# Configuration file for running experiments +############################################## + +# Path to directory of circuits to use +circuits_dir=benchmarks/blif/6 + +# Path to directory of architectures to use +archs_dir=arch/titan + +# Add circuits to list to sweep +circuit_list_add=styr.blif + +# Add architectures to list to sweep +arch_list_add=stratixiv_arch.timing.xml + +# Parse info and how to parse +parse_file=vpr_standard.txt + +# How to parse QoR info +qor_parse_file=qor_standard.txt + +# Pass requirements +pass_requirements_file=pass_requirements.txt + +script_params= -read_rr_graph /tasks/arch/titan/rr_graph/stratixv_arch.timing_11x8_rr_graph.xml -route_chan_width 20 From a7f45893ab9fa1fed3ca0431f85b85306a7933c9 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 15:05:30 -0700 Subject: [PATCH 18/32] [Test] Add a test to validate rr_graph writer --- .../strong_write_rr_graph/config/config.txt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt new file mode 100644 index 00000000000..1bc07158d84 --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt @@ -0,0 +1,27 @@ +# +############################################ +# Configuration file for running experiments +############################################## + +# Path to directory of circuits to use +circuits_dir=benchmarks/blif/6 + +# Path to directory of architectures to use +archs_dir=arch/titan + +# Add circuits to list to sweep +circuit_list_add=styr.blif + +# Add architectures to list to sweep +arch_list_add=stratixiv_arch.timing.xml + +# Parse info and how to parse +parse_file=vpr_standard.txt + +# How to parse QoR info +qor_parse_file=qor_standard.txt + +# Pass requirements +pass_requirements_file=pass_requirements.txt + +script_params= -write_rr_graph stratixv_arch.timing_11x8_rr_graph.xml From 35e2350bd3c86a885ac7d4d2c5494b0a5a6dbe74 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 15:06:01 -0700 Subject: [PATCH 19/32] [Test] Add tests to regression task list --- vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt index 76c3cd41d86..ab5495ddcf1 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt @@ -73,3 +73,5 @@ regression_tests/vtr_reg_strong/strong_fix_clusters regression_tests/vtr_reg_strong/strong_analytic_placer regression_tests/vtr_reg_strong/strong_place_quench_slack regression_tests/vtr_reg_strong/strong_post_routing_sync +regression_tests/vtr_reg_strong/strong_read_rr_graph +regression_tests/vtr_reg_strong/strong_write_rr_graph From cbeabea8815755cfe5021b102492408892931e3f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 15:25:55 -0700 Subject: [PATCH 20/32] [Test] Move rr_graph to local test directory and correct bugs --- .../vtr_reg_strong/strong_read_rr_graph/config/config.txt | 2 +- .../config/stratixiv_arch.timing_11x8_rr_graph.xml} | 0 .../vtr_reg_strong/strong_write_rr_graph/config/config.txt | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename vtr_flow/{arch/titan/rr_graph/stratixv_arch.timing_11x8_rr_graph.xml => tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml} (100%) diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt index 7fc257b8504..e9b6460cd19 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt @@ -24,4 +24,4 @@ qor_parse_file=qor_standard.txt # Pass requirements pass_requirements_file=pass_requirements.txt -script_params= -read_rr_graph /tasks/arch/titan/rr_graph/stratixv_arch.timing_11x8_rr_graph.xml -route_chan_width 20 +script_params=-starting_stage vpri -read_rr_graph /tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml -route_chan_width 20 diff --git a/vtr_flow/arch/titan/rr_graph/stratixv_arch.timing_11x8_rr_graph.xml b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml similarity index 100% rename from vtr_flow/arch/titan/rr_graph/stratixv_arch.timing_11x8_rr_graph.xml rename to vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt index 1bc07158d84..eb651bbaf33 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt @@ -24,4 +24,4 @@ qor_parse_file=qor_standard.txt # Pass requirements pass_requirements_file=pass_requirements.txt -script_params= -write_rr_graph stratixv_arch.timing_11x8_rr_graph.xml +script_params=-starting_stage vpr -write_rr_graph stratixv_arch.timing_11x8_rr_graph.xml From bfc0fd66e396cbcaa74744dabc081547c843e8d1 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 15:27:57 -0700 Subject: [PATCH 21/32] [Test] Bug fix in typo --- .../vtr_reg_strong/strong_read_rr_graph/config/config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt index e9b6460cd19..e51c4dbe7be 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt @@ -24,4 +24,4 @@ qor_parse_file=qor_standard.txt # Pass requirements pass_requirements_file=pass_requirements.txt -script_params=-starting_stage vpri -read_rr_graph /tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml -route_chan_width 20 +script_params=-starting_stage vpr -read_rr_graph /tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml -route_chan_width 20 From dda6514323f5f5c1d6693ffaad3e8dffd2c75996 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 15:45:36 -0700 Subject: [PATCH 22/32] [Test] Now use relative path to read a rr_graph file; vtr_flow.py should be enhanced to support rr_graph file access! --- .../vtr_reg_strong/strong_read_rr_graph/config/config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt index e51c4dbe7be..a6818d68483 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt @@ -24,4 +24,4 @@ qor_parse_file=qor_standard.txt # Pass requirements pass_requirements_file=pass_requirements.txt -script_params=-starting_stage vpr -read_rr_graph /tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml -route_chan_width 20 +script_params=-starting_stage vpr -read_rr_graph ../../../../config/stratixiv_arch.timing_11x8_rr_graph.xml -route_chan_width 20 From c6cf3bc7033dd704f7b6344154aa06a3e321cbf3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 15:50:32 -0700 Subject: [PATCH 23/32] [VPR] code format fix --- .../route/gen/rr_graph_uxsdcxx_interface.h | 408 +++++++++--------- 1 file changed, 204 insertions(+), 204 deletions(-) diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h b/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h index c846db4f5da..df629786d9b 100644 --- a/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h +++ b/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h @@ -130,14 +130,14 @@ class RrGraphBase { virtual void finish_write() = 0; virtual void error_encountered(const char* file, int line, const char* message) = 0; /** Generated for complex type "channel": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline int get_channel_chan_width_max(typename ContextTypes::ChannelReadContext& ctx) = 0; virtual inline int get_channel_x_max(typename ContextTypes::ChannelReadContext& ctx) = 0; virtual inline int get_channel_x_min(typename ContextTypes::ChannelReadContext& ctx) = 0; @@ -145,33 +145,33 @@ class RrGraphBase { virtual inline int get_channel_y_min(typename ContextTypes::ChannelReadContext& ctx) = 0; /** Generated for complex type "x_list": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline unsigned int get_x_list_index(typename ContextTypes::XListReadContext& ctx) = 0; virtual inline int get_x_list_info(typename ContextTypes::XListReadContext& ctx) = 0; /** Generated for complex type "y_list": - * - * - * - * - */ + * + * + * + * + */ virtual inline unsigned int get_y_list_index(typename ContextTypes::YListReadContext& ctx) = 0; virtual inline int get_y_list_info(typename ContextTypes::YListReadContext& ctx) = 0; /** Generated for complex type "channels": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline typename ContextTypes::ChannelWriteContext init_channels_channel(typename ContextTypes::ChannelsWriteContext& ctx, int chan_width_max, int x_max, int x_min, int y_max, int y_min) = 0; virtual inline void finish_channels_channel(typename ContextTypes::ChannelWriteContext& ctx) = 0; virtual inline typename ContextTypes::ChannelReadContext get_channels_channel(typename ContextTypes::ChannelsReadContext& ctx) = 0; @@ -187,15 +187,15 @@ class RrGraphBase { virtual inline typename ContextTypes::YListReadContext get_channels_y_list(int n, typename ContextTypes::ChannelsReadContext& ctx) = 0; /** Generated for complex type "timing": - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + */ virtual inline float get_timing_Cin(typename ContextTypes::TimingReadContext& ctx) = 0; virtual inline void set_timing_Cin(float Cin, typename ContextTypes::TimingWriteContext& ctx) = 0; virtual inline float get_timing_Cinternal(typename ContextTypes::TimingReadContext& ctx) = 0; @@ -208,27 +208,27 @@ class RrGraphBase { virtual inline void set_timing_Tdel(float Tdel, typename ContextTypes::TimingWriteContext& ctx) = 0; /** Generated for complex type "sizing": - * - * - * - * - */ + * + * + * + * + */ virtual inline float get_sizing_buf_size(typename ContextTypes::SizingReadContext& ctx) = 0; virtual inline float get_sizing_mux_trans_size(typename ContextTypes::SizingReadContext& ctx) = 0; /** Generated for complex type "switch": - * - * - * - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + * + * + * + */ virtual inline int get_switch_id(typename ContextTypes::SwitchReadContext& ctx) = 0; virtual inline const char* get_switch_name(typename ContextTypes::SwitchReadContext& ctx) = 0; virtual inline void set_switch_name(const char* name, typename ContextTypes::SwitchWriteContext& ctx) = 0; @@ -243,12 +243,12 @@ class RrGraphBase { virtual inline typename ContextTypes::SizingReadContext get_switch_sizing(typename ContextTypes::SwitchReadContext& ctx) = 0; /** Generated for complex type "switches": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_switches_switch(typename ContextTypes::SwitchesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::SwitchWriteContext add_switches_switch(typename ContextTypes::SwitchesWriteContext& ctx, int id) = 0; virtual inline void finish_switches_switch(typename ContextTypes::SwitchWriteContext& ctx) = 0; @@ -256,25 +256,25 @@ class RrGraphBase { virtual inline typename ContextTypes::SwitchReadContext get_switches_switch(int n, typename ContextTypes::SwitchesReadContext& ctx) = 0; /** Generated for complex type "segment_timing": - * - * - * - * - */ + * + * + * + * + */ virtual inline float get_segment_timing_C_per_meter(typename ContextTypes::SegmentTimingReadContext& ctx) = 0; virtual inline void set_segment_timing_C_per_meter(float C_per_meter, typename ContextTypes::SegmentTimingWriteContext& ctx) = 0; virtual inline float get_segment_timing_R_per_meter(typename ContextTypes::SegmentTimingReadContext& ctx) = 0; virtual inline void set_segment_timing_R_per_meter(float R_per_meter, typename ContextTypes::SegmentTimingWriteContext& ctx) = 0; /** Generated for complex type "segment": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline int get_segment_id(typename ContextTypes::SegmentReadContext& ctx) = 0; virtual inline const char* get_segment_name(typename ContextTypes::SegmentReadContext& ctx) = 0; virtual inline void set_segment_name(const char* name, typename ContextTypes::SegmentWriteContext& ctx) = 0; @@ -284,12 +284,12 @@ class RrGraphBase { virtual inline bool has_segment_timing(typename ContextTypes::SegmentReadContext& ctx) = 0; /** Generated for complex type "segments": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_segments_segment(typename ContextTypes::SegmentsWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::SegmentWriteContext add_segments_segment(typename ContextTypes::SegmentsWriteContext& ctx, int id) = 0; virtual inline void finish_segments_segment(typename ContextTypes::SegmentWriteContext& ctx) = 0; @@ -297,26 +297,26 @@ class RrGraphBase { virtual inline typename ContextTypes::SegmentReadContext get_segments_segment(int n, typename ContextTypes::SegmentsReadContext& ctx) = 0; /** Generated for complex type "pin": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline int get_pin_ptc(typename ContextTypes::PinReadContext& ctx) = 0; virtual inline void set_pin_value(const char* value, typename ContextTypes::PinWriteContext& ctx) = 0; virtual inline const char* get_pin_value(typename ContextTypes::PinReadContext& ctx) = 0; /** Generated for complex type "pin_class": - * - * - * - * - * - * - */ + * + * + * + * + * + * + */ virtual inline enum_pin_type get_pin_class_type(typename ContextTypes::PinClassReadContext& ctx) = 0; virtual inline void preallocate_pin_class_pin(typename ContextTypes::PinClassWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::PinWriteContext add_pin_class_pin(typename ContextTypes::PinClassWriteContext& ctx, int ptc) = 0; @@ -325,16 +325,16 @@ class RrGraphBase { virtual inline typename ContextTypes::PinReadContext get_pin_class_pin(int n, typename ContextTypes::PinClassReadContext& ctx) = 0; /** Generated for complex type "block_type": - * - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + * + */ virtual inline int get_block_type_height(typename ContextTypes::BlockTypeReadContext& ctx) = 0; virtual inline int get_block_type_id(typename ContextTypes::BlockTypeReadContext& ctx) = 0; virtual inline const char* get_block_type_name(typename ContextTypes::BlockTypeReadContext& ctx) = 0; @@ -347,12 +347,12 @@ class RrGraphBase { virtual inline typename ContextTypes::PinClassReadContext get_block_type_pin_class(int n, typename ContextTypes::BlockTypeReadContext& ctx) = 0; /** Generated for complex type "block_types": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_block_types_block_type(typename ContextTypes::BlockTypesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::BlockTypeWriteContext add_block_types_block_type(typename ContextTypes::BlockTypesWriteContext& ctx, int height, int id, int width) = 0; virtual inline void finish_block_types_block_type(typename ContextTypes::BlockTypeWriteContext& ctx) = 0; @@ -360,14 +360,14 @@ class RrGraphBase { virtual inline typename ContextTypes::BlockTypeReadContext get_block_types_block_type(int n, typename ContextTypes::BlockTypesReadContext& ctx) = 0; /** Generated for complex type "grid_loc": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline int get_grid_loc_block_type_id(typename ContextTypes::GridLocReadContext& ctx) = 0; virtual inline int get_grid_loc_height_offset(typename ContextTypes::GridLocReadContext& ctx) = 0; virtual inline int get_grid_loc_width_offset(typename ContextTypes::GridLocReadContext& ctx) = 0; @@ -375,12 +375,12 @@ class RrGraphBase { virtual inline int get_grid_loc_y(typename ContextTypes::GridLocReadContext& ctx) = 0; /** Generated for complex type "grid_locs": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::GridLocWriteContext add_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext& ctx, int block_type_id, int height_offset, int width_offset, int x, int y) = 0; virtual inline void finish_grid_locs_grid_loc(typename ContextTypes::GridLocWriteContext& ctx) = 0; @@ -388,15 +388,15 @@ class RrGraphBase { virtual inline typename ContextTypes::GridLocReadContext get_grid_locs_grid_loc(int n, typename ContextTypes::GridLocsReadContext& ctx) = 0; /** Generated for complex type "node_loc": - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + */ virtual inline int get_node_loc_ptc(typename ContextTypes::NodeLocReadContext& ctx) = 0; virtual inline enum_loc_side get_node_loc_side(typename ContextTypes::NodeLocReadContext& ctx) = 0; virtual inline void set_node_loc_side(enum_loc_side side, typename ContextTypes::NodeLocWriteContext& ctx) = 0; @@ -406,42 +406,42 @@ class RrGraphBase { virtual inline int get_node_loc_ylow(typename ContextTypes::NodeLocReadContext& ctx) = 0; /** Generated for complex type "node_timing": - * - * - * - * - */ + * + * + * + * + */ virtual inline float get_node_timing_C(typename ContextTypes::NodeTimingReadContext& ctx) = 0; virtual inline float get_node_timing_R(typename ContextTypes::NodeTimingReadContext& ctx) = 0; /** Generated for complex type "node_segment": - * - * - * - */ + * + * + * + */ virtual inline int get_node_segment_segment_id(typename ContextTypes::NodeSegmentReadContext& ctx) = 0; /** Generated for complex type "meta": - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + */ virtual inline const char* get_meta_name(typename ContextTypes::MetaReadContext& ctx) = 0; virtual inline void set_meta_name(const char* name, typename ContextTypes::MetaWriteContext& ctx) = 0; virtual inline void set_meta_value(const char* value, typename ContextTypes::MetaWriteContext& ctx) = 0; virtual inline const char* get_meta_value(typename ContextTypes::MetaReadContext& ctx) = 0; /** Generated for complex type "metadata": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_metadata_meta(typename ContextTypes::MetadataWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::MetaWriteContext add_metadata_meta(typename ContextTypes::MetadataWriteContext& ctx) = 0; virtual inline void finish_metadata_meta(typename ContextTypes::MetaWriteContext& ctx) = 0; @@ -449,19 +449,19 @@ class RrGraphBase { virtual inline typename ContextTypes::MetaReadContext get_metadata_meta(int n, typename ContextTypes::MetadataReadContext& ctx) = 0; /** Generated for complex type "node": - * - * - * - * - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + * + * + * + * + */ virtual inline unsigned int get_node_capacity(typename ContextTypes::NodeReadContext& ctx) = 0; virtual inline enum_node_direction get_node_direction(typename ContextTypes::NodeReadContext& ctx) = 0; virtual inline void set_node_direction(enum_node_direction direction, typename ContextTypes::NodeWriteContext& ctx) = 0; @@ -484,12 +484,12 @@ class RrGraphBase { virtual inline bool has_node_metadata(typename ContextTypes::NodeReadContext& ctx) = 0; /** Generated for complex type "rr_nodes": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_rr_nodes_node(typename ContextTypes::RrNodesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::NodeWriteContext add_rr_nodes_node(typename ContextTypes::RrNodesWriteContext& ctx, unsigned int capacity, unsigned int id, enum_node_type type) = 0; virtual inline void finish_rr_nodes_node(typename ContextTypes::NodeWriteContext& ctx) = 0; @@ -497,15 +497,15 @@ class RrGraphBase { virtual inline typename ContextTypes::NodeReadContext get_rr_nodes_node(int n, typename ContextTypes::RrNodesReadContext& ctx) = 0; /** Generated for complex type "edge": - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + */ virtual inline unsigned int get_edge_sink_node(typename ContextTypes::EdgeReadContext& ctx) = 0; virtual inline unsigned int get_edge_src_node(typename ContextTypes::EdgeReadContext& ctx) = 0; virtual inline unsigned int get_edge_switch_id(typename ContextTypes::EdgeReadContext& ctx) = 0; @@ -515,12 +515,12 @@ class RrGraphBase { virtual inline bool has_edge_metadata(typename ContextTypes::EdgeReadContext& ctx) = 0; /** Generated for complex type "rr_edges": - * - * - * - * - * - */ + * + * + * + * + * + */ virtual inline void preallocate_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext& ctx, size_t size) = 0; virtual inline typename ContextTypes::EdgeWriteContext add_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext& ctx, unsigned int sink_node, unsigned int src_node, unsigned int switch_id) = 0; virtual inline void finish_rr_edges_edge(typename ContextTypes::EdgeWriteContext& ctx) = 0; @@ -528,21 +528,21 @@ class RrGraphBase { virtual inline typename ContextTypes::EdgeReadContext get_rr_edges_edge(int n, typename ContextTypes::RrEdgesReadContext& ctx) = 0; /** Generated for complex type "rr_graph": - * - * - * - * - * - * - * - * - * - * - * - * - * - * - */ + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ virtual inline const char* get_rr_graph_tool_comment(typename ContextTypes::RrGraphReadContext& ctx) = 0; virtual inline void set_rr_graph_tool_comment(const char* tool_comment, typename ContextTypes::RrGraphWriteContext& ctx) = 0; virtual inline const char* get_rr_graph_tool_name(typename ContextTypes::RrGraphReadContext& ctx) = 0; From 0afcd0c4d37a06770a264c90fd78ca6b3fbf70cf Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 16:44:20 -0700 Subject: [PATCH 24/32] [Test] Add golden results for test cases and update the task configuration to relax qor check --- .../vtr_reg_strong/strong_read_rr_graph/config/config.txt | 6 +++--- .../strong_read_rr_graph/config/golden_results.txt | 2 ++ .../vtr_reg_strong/strong_write_rr_graph/config/config.txt | 6 +++--- .../strong_write_rr_graph/config/golden_results.txt | 2 ++ 4 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/golden_results.txt create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/golden_results.txt diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt index a6818d68483..8423ebd1e44 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt @@ -16,12 +16,12 @@ circuit_list_add=styr.blif arch_list_add=stratixiv_arch.timing.xml # Parse info and how to parse -parse_file=vpr_standard.txt +parse_file=vpr_no_timing.txt # How to parse QoR info -qor_parse_file=qor_standard.txt +qor_parse_file=qor_no_timing.txt # Pass requirements -pass_requirements_file=pass_requirements.txt +pass_requirements_file=pass_requirements_no_timing.txt script_params=-starting_stage vpr -read_rr_graph ../../../../config/stratixiv_arch.timing_11x8_rr_graph.xml -route_chan_width 20 diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/golden_results.txt new file mode 100644 index 00000000000..5500cb17200 --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/golden_results.txt @@ -0,0 +1,2 @@ +arch circuit script_params vtr_flow_elapsed_time error odin_synth_time max_odin_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_time placed_wirelength_est place_time place_quench_time min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time +stratixiv_arch.timing.xml styr.blif common 10.41 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 10 -1 -1 success v8.0.0-3029-g69c619cb1-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 8.4.0 on Linux-3.10.0-1127.18.2.el7.x86_64 x86_64 2021-01-07T14:18:26 lnissrv4.eng.utah.edu /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing 753028 10 10 168 178 1 62 30 11 8 88 io auto 0.38 339 0.05 0.00 -1 743 13 0 0 100248. 1139.18 0.13 diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt index eb651bbaf33..64966d2d89e 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt @@ -16,12 +16,12 @@ circuit_list_add=styr.blif arch_list_add=stratixiv_arch.timing.xml # Parse info and how to parse -parse_file=vpr_standard.txt +parse_file=vpr_no_timing.txt # How to parse QoR info -qor_parse_file=qor_standard.txt +qor_parse_file=qor_no_timing.txt # Pass requirements -pass_requirements_file=pass_requirements.txt +pass_requirements_file=pass_requirements_no_timing.txt script_params=-starting_stage vpr -write_rr_graph stratixv_arch.timing_11x8_rr_graph.xml diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/golden_results.txt new file mode 100644 index 00000000000..5865b921c93 --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/golden_results.txt @@ -0,0 +1,2 @@ +arch circuit script_params vtr_flow_elapsed_time error odin_synth_time max_odin_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_time placed_wirelength_est place_time place_quench_time min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time +stratixiv_arch.timing.xml styr.blif common 27.62 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 10 -1 -1 success v8.0.0-3029-g69c619cb1-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 8.4.0 on Linux-3.10.0-1127.18.2.el7.x86_64 x86_64 2021-01-07T14:18:26 lnissrv4.eng.utah.edu /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing 762884 10 10 168 178 1 62 30 11 8 88 io auto 0.55 338 0.07 0.00 20 737 16 0 0 100248. 1139.18 2.94 From 2b084358af8643be89acea9af7d26b50896da5bd Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 7 Jan 2021 16:49:17 -0700 Subject: [PATCH 25/32] [VPR] code format fix --- vpr/src/route/gen/rr_graph_uxsdcxx_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h b/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h index df629786d9b..56f8aa8f56d 100644 --- a/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h +++ b/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h @@ -171,7 +171,7 @@ class RrGraphBase { * * * - */ + */ virtual inline typename ContextTypes::ChannelWriteContext init_channels_channel(typename ContextTypes::ChannelsWriteContext& ctx, int chan_width_max, int x_max, int x_min, int y_max, int y_min) = 0; virtual inline void finish_channels_channel(typename ContextTypes::ChannelWriteContext& ctx) = 0; virtual inline typename ContextTypes::ChannelReadContext get_channels_channel(typename ContextTypes::ChannelsReadContext& ctx) = 0; From e5d4979e3f4e3bcb4257dd807b8ecc92066c550a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 8 Jan 2021 15:25:48 -0700 Subject: [PATCH 26/32] [Test] Now use -verify_rr_graph to avoid storing a large RRGraph XML file --- .../stratixiv_arch.timing_11x8_rr_graph.xml | 57386 ---------------- .../config/config.txt | 9 +- .../config/golden_results.txt | 0 .../strong_write_rr_graph/config/config.txt | 27 - .../config/golden_results.txt | 2 - .../vtr_reg_strong/task_list.txt | 3 +- 6 files changed, 6 insertions(+), 57421 deletions(-) delete mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml rename vtr_flow/tasks/regression_tests/vtr_reg_strong/{strong_read_rr_graph => strong_verify_rr_graph_titan}/config/config.txt (65%) rename vtr_flow/tasks/regression_tests/vtr_reg_strong/{strong_read_rr_graph => strong_verify_rr_graph_titan}/config/golden_results.txt (100%) delete mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt delete mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/golden_results.txt diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml deleted file mode 100644 index 3cd23f50314..00000000000 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/stratixiv_arch.timing_11x8_rr_graph.xml +++ /dev/null @@ -1,57386 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -io[0].core_in[0] - -io[0].core_in[1] - -io[0].core_in[2] - -io[0].core_in[3] - -io[0].core_in[4] - -io[0].core_in[5] - -io[0].core_in[6] - -io[0].core_in[7] - -io[0].core_in[8] - -io[0].core_in[9] - -io[0].core_in[10] - -io[0].core_in[11] - -io[0].core_in[12] - -io[0].core_in[13] - -io[0].core_in[14] - -io[0].core_in[15] - -io[0].core_in[16] - -io[0].core_in[17] - -io[0].core_in[18] - -io[0].core_in[19] - -io[0].core_in[20] - -io[0].core_in[21] - -io[0].core_in[22] - -io[0].core_in[23] - -io[0].core_in[24] - -io[0].core_in[25] - -io[0].core_in[26] - -io[0].core_in[27] - -io[0].core_in[28] - -io[0].core_in[29] - -io[0].core_in[30] - -io[0].core_in[31] - -io[0].core_in[32] - -io[0].core_in[33] - -io[0].core_in[34] - -io[0].core_in[35] - -io[0].core_in[36] - -io[0].core_in[37] - -io[0].core_in[38] - -io[0].core_in[39] - -io[0].core_in[40] - -io[0].core_in[41] - -io[0].core_in[42] - -io[0].core_in[43] - -io[0].core_in[44] - -io[0].core_in[45] - -io[0].core_in[46] - -io[0].core_in[47] - -io[0].core_in[48] - -io[0].core_in[49] - -io[0].core_out[0] - -io[0].core_out[1] - -io[0].core_out[2] - -io[0].core_out[3] - -io[0].core_out[4] - -io[0].core_out[5] - -io[0].core_out[6] - -io[0].core_out[7] - -io[0].core_out[8] - -io[0].core_out[9] - -io[0].core_out[10] - -io[0].core_out[11] - -io[0].core_out[12] - -io[0].core_out[13] - -io[0].core_out[14] - -io[0].core_out[15] - -io[0].core_out[16] - -io[0].core_out[17] - -io[0].core_out[18] - -io[0].core_out[19] - -io[0].core_out[20] - -io[0].core_out[21] - -io[0].core_out[22] - -io[0].core_out[23] - -io[0].core_out[24] - -io[0].core_out[25] - -io[0].core_out[26] - -io[0].core_out[27] - -io[0].core_out[28] - -io[0].core_out[29] - -io[0].core_out[30] - -io[0].core_out[31] - -io[0].core_out[32] - -io[0].core_out[33] - -io[0].core_out[34] - -io[0].core_out[35] - -io[0].core_out[36] - -io[0].core_out[37] - -io[0].core_out[38] - -io[0].core_out[39] - -io[0].clk[0] - -io[0].clk[1] - -io[0].clk[2] - -io[0].clk[3] - -io[0].clk[4] - -io[1].core_in[0] - -io[1].core_in[1] - -io[1].core_in[2] - -io[1].core_in[3] - -io[1].core_in[4] - -io[1].core_in[5] - -io[1].core_in[6] - -io[1].core_in[7] - -io[1].core_in[8] - -io[1].core_in[9] - -io[1].core_in[10] - -io[1].core_in[11] - -io[1].core_in[12] - -io[1].core_in[13] - -io[1].core_in[14] - -io[1].core_in[15] - -io[1].core_in[16] - -io[1].core_in[17] - -io[1].core_in[18] - -io[1].core_in[19] - -io[1].core_in[20] - -io[1].core_in[21] - -io[1].core_in[22] - -io[1].core_in[23] - -io[1].core_in[24] - -io[1].core_in[25] - -io[1].core_in[26] - -io[1].core_in[27] - -io[1].core_in[28] - -io[1].core_in[29] - -io[1].core_in[30] - -io[1].core_in[31] - -io[1].core_in[32] - -io[1].core_in[33] - -io[1].core_in[34] - -io[1].core_in[35] - -io[1].core_in[36] - -io[1].core_in[37] - -io[1].core_in[38] - -io[1].core_in[39] - -io[1].core_in[40] - -io[1].core_in[41] - -io[1].core_in[42] - -io[1].core_in[43] - -io[1].core_in[44] - -io[1].core_in[45] - -io[1].core_in[46] - -io[1].core_in[47] - -io[1].core_in[48] - -io[1].core_in[49] - -io[1].core_out[0] - -io[1].core_out[1] - -io[1].core_out[2] - -io[1].core_out[3] - -io[1].core_out[4] - -io[1].core_out[5] - -io[1].core_out[6] - -io[1].core_out[7] - -io[1].core_out[8] - -io[1].core_out[9] - -io[1].core_out[10] - -io[1].core_out[11] - -io[1].core_out[12] - -io[1].core_out[13] - -io[1].core_out[14] - -io[1].core_out[15] - -io[1].core_out[16] - -io[1].core_out[17] - -io[1].core_out[18] - -io[1].core_out[19] - -io[1].core_out[20] - -io[1].core_out[21] - -io[1].core_out[22] - -io[1].core_out[23] - -io[1].core_out[24] - -io[1].core_out[25] - -io[1].core_out[26] - -io[1].core_out[27] - -io[1].core_out[28] - -io[1].core_out[29] - -io[1].core_out[30] - -io[1].core_out[31] - -io[1].core_out[32] - -io[1].core_out[33] - -io[1].core_out[34] - -io[1].core_out[35] - -io[1].core_out[36] - -io[1].core_out[37] - -io[1].core_out[38] - -io[1].core_out[39] - -io[1].clk[0] - -io[1].clk[1] - -io[1].clk[2] - -io[1].clk[3] - -io[1].clk[4] - - -PLL.in_signal[0] - -PLL.in_signal[1] - -PLL.in_signal[2] - -PLL.in_signal[3] - -PLL.in_signal[4] - -PLL.in_signal[5] - -PLL.in_signal[6] - -PLL.in_signal[7] - -PLL.in_signal[8] - -PLL.in_signal[9] - -PLL.in_signal[10] - -PLL.in_signal[11] - -PLL.in_signal[12] - -PLL.in_signal[13] - -PLL.out_clock[0] - -PLL.out_clock[1] - -PLL.out_clock[2] - -PLL.out_clock[3] - -PLL.out_clock[4] - -PLL.out_clock[5] - -PLL.out_clock[6] - -PLL.out_clock[7] - -PLL.out_clock[8] - -PLL.out_clock[9] - -PLL.out_signal[0] - -PLL.out_signal[1] - -PLL.out_signal[2] - -PLL.out_signal[3] - -PLL.out_signal[4] - -PLL.out_signal[5] - -PLL.out_signal[6] - -PLL.out_signal[7] - -PLL.out_signal[8] - -PLL.out_signal[9] - -PLL.in_clock[0] - -PLL.in_clock[1] - - -LAB.data_in[0] -LAB.data_in[1] -LAB.data_in[2] -LAB.data_in[3] -LAB.data_in[4] -LAB.data_in[5] -LAB.data_in[6] -LAB.data_in[7] -LAB.data_in[8] -LAB.data_in[9] -LAB.data_in[10] -LAB.data_in[11] -LAB.data_in[12] -LAB.data_in[13] -LAB.data_in[14] -LAB.data_in[15] -LAB.data_in[16] -LAB.data_in[17] -LAB.data_in[18] -LAB.data_in[19] -LAB.data_in[20] -LAB.data_in[21] -LAB.data_in[22] -LAB.data_in[23] -LAB.data_in[24] -LAB.data_in[25] -LAB.data_in[26] -LAB.data_in[27] -LAB.data_in[28] -LAB.data_in[29] -LAB.data_in[30] -LAB.data_in[31] -LAB.data_in[32] -LAB.data_in[33] -LAB.data_in[34] -LAB.data_in[35] -LAB.data_in[36] -LAB.data_in[37] -LAB.data_in[38] -LAB.data_in[39] -LAB.data_in[40] -LAB.data_in[41] -LAB.data_in[42] -LAB.data_in[43] -LAB.data_in[44] -LAB.data_in[45] -LAB.data_in[46] -LAB.data_in[47] -LAB.data_in[48] -LAB.data_in[49] -LAB.data_in[50] -LAB.data_in[51] -LAB.data_in[52] -LAB.data_in[53] -LAB.data_in[54] -LAB.data_in[55] -LAB.data_in[56] -LAB.data_in[57] -LAB.data_in[58] -LAB.data_in[59] -LAB.data_in[60] -LAB.data_in[61] -LAB.data_in[62] -LAB.data_in[63] -LAB.data_in[64] -LAB.data_in[65] -LAB.data_in[66] -LAB.data_in[67] -LAB.data_in[68] -LAB.data_in[69] -LAB.data_in[70] -LAB.data_in[71] -LAB.data_in[72] -LAB.data_in[73] -LAB.data_in[74] -LAB.data_in[75] -LAB.data_in[76] -LAB.data_in[77] -LAB.data_in[78] -LAB.data_in[79] - -LAB.control_in[0] -LAB.control_in[1] -LAB.control_in[2] -LAB.control_in[3] -LAB.control_in[4] -LAB.control_in[5] -LAB.control_in[6] - -LAB.cin[0] - -LAB.sharein[0] - -LAB.data_out[0] -LAB.data_out[1] -LAB.data_out[2] -LAB.data_out[3] -LAB.data_out[4] -LAB.data_out[5] -LAB.data_out[6] -LAB.data_out[7] -LAB.data_out[8] -LAB.data_out[9] -LAB.data_out[10] -LAB.data_out[11] -LAB.data_out[12] -LAB.data_out[13] -LAB.data_out[14] -LAB.data_out[15] -LAB.data_out[16] -LAB.data_out[17] -LAB.data_out[18] -LAB.data_out[19] -LAB.data_out[20] -LAB.data_out[21] -LAB.data_out[22] -LAB.data_out[23] -LAB.data_out[24] -LAB.data_out[25] -LAB.data_out[26] -LAB.data_out[27] -LAB.data_out[28] -LAB.data_out[29] -LAB.data_out[30] -LAB.data_out[31] -LAB.data_out[32] -LAB.data_out[33] -LAB.data_out[34] -LAB.data_out[35] -LAB.data_out[36] -LAB.data_out[37] -LAB.data_out[38] -LAB.data_out[39] - -LAB.cout[0] - -LAB.shareout[0] - -LAB.clk[0] - -LAB.clk[1] - - -DSP.data_in[0] - -DSP.data_in[1] - -DSP.data_in[2] - -DSP.data_in[3] - -DSP.data_in[4] - -DSP.data_in[5] - -DSP.data_in[6] - -DSP.data_in[7] - -DSP.data_in[8] - -DSP.data_in[9] - -DSP.data_in[10] - -DSP.data_in[11] - -DSP.data_in[12] - -DSP.data_in[13] - -DSP.data_in[14] - -DSP.data_in[15] - -DSP.data_in[16] - -DSP.data_in[17] - -DSP.data_in[18] - -DSP.data_in[19] - -DSP.data_in[20] - -DSP.data_in[21] - -DSP.data_in[22] - -DSP.data_in[23] - -DSP.data_in[24] - -DSP.data_in[25] - -DSP.data_in[26] - -DSP.data_in[27] - -DSP.data_in[28] - -DSP.data_in[29] - -DSP.data_in[30] - -DSP.data_in[31] - -DSP.data_in[32] - -DSP.data_in[33] - -DSP.data_in[34] - -DSP.data_in[35] - -DSP.data_in[36] - -DSP.data_in[37] - -DSP.data_in[38] - -DSP.data_in[39] - -DSP.data_in[40] - -DSP.data_in[41] - -DSP.data_in[42] - -DSP.data_in[43] - -DSP.data_in[44] - -DSP.data_in[45] - -DSP.data_in[46] - -DSP.data_in[47] - -DSP.data_in[48] - -DSP.data_in[49] - -DSP.data_in[50] - -DSP.data_in[51] - -DSP.data_in[52] - -DSP.data_in[53] - -DSP.data_in[54] - -DSP.data_in[55] - -DSP.data_in[56] - -DSP.data_in[57] - -DSP.data_in[58] - -DSP.data_in[59] - -DSP.data_in[60] - -DSP.data_in[61] - -DSP.data_in[62] - -DSP.data_in[63] - -DSP.data_in[64] - -DSP.data_in[65] - -DSP.data_in[66] - -DSP.data_in[67] - -DSP.data_in[68] - -DSP.data_in[69] - -DSP.data_in[70] - -DSP.data_in[71] - -DSP.data_in[72] - -DSP.data_in[73] - -DSP.data_in[74] - -DSP.data_in[75] - -DSP.data_in[76] - -DSP.data_in[77] - -DSP.data_in[78] - -DSP.data_in[79] - -DSP.data_in[80] - -DSP.data_in[81] - -DSP.data_in[82] - -DSP.data_in[83] - -DSP.data_in[84] - -DSP.data_in[85] - -DSP.data_in[86] - -DSP.data_in[87] - -DSP.data_in[88] - -DSP.data_in[89] - -DSP.data_in[90] - -DSP.data_in[91] - -DSP.data_in[92] - -DSP.data_in[93] - -DSP.data_in[94] - -DSP.data_in[95] - -DSP.data_in[96] - -DSP.data_in[97] - -DSP.data_in[98] - -DSP.data_in[99] - -DSP.data_in[100] - -DSP.data_in[101] - -DSP.data_in[102] - -DSP.data_in[103] - -DSP.data_in[104] - -DSP.data_in[105] - -DSP.data_in[106] - -DSP.data_in[107] - -DSP.data_in[108] - -DSP.data_in[109] - -DSP.data_in[110] - -DSP.data_in[111] - -DSP.data_in[112] - -DSP.data_in[113] - -DSP.data_in[114] - -DSP.data_in[115] - -DSP.data_in[116] - -DSP.data_in[117] - -DSP.data_in[118] - -DSP.data_in[119] - -DSP.data_in[120] - -DSP.data_in[121] - -DSP.data_in[122] - -DSP.data_in[123] - -DSP.data_in[124] - -DSP.data_in[125] - -DSP.data_in[126] - -DSP.data_in[127] - -DSP.data_in[128] - -DSP.data_in[129] - -DSP.data_in[130] - -DSP.data_in[131] - -DSP.data_in[132] - -DSP.data_in[133] - -DSP.data_in[134] - -DSP.data_in[135] - -DSP.data_in[136] - -DSP.data_in[137] - -DSP.data_in[138] - -DSP.data_in[139] - -DSP.data_in[140] - -DSP.data_in[141] - -DSP.data_in[142] - -DSP.data_in[143] - -DSP.data_in[144] - -DSP.data_in[145] - -DSP.data_in[146] - -DSP.data_in[147] - -DSP.data_in[148] - -DSP.data_in[149] - -DSP.data_in[150] - -DSP.data_in[151] - -DSP.data_in[152] - -DSP.data_in[153] - -DSP.data_in[154] - -DSP.data_in[155] - -DSP.data_in[156] - -DSP.data_in[157] - -DSP.data_in[158] - -DSP.data_in[159] - -DSP.data_in[160] - -DSP.data_in[161] - -DSP.data_in[162] - -DSP.data_in[163] - -DSP.data_in[164] - -DSP.data_in[165] - -DSP.data_in[166] - -DSP.data_in[167] - -DSP.data_in[168] - -DSP.data_in[169] - -DSP.data_in[170] - -DSP.data_in[171] - -DSP.data_in[172] - -DSP.data_in[173] - -DSP.data_in[174] - -DSP.data_in[175] - -DSP.data_in[176] - -DSP.data_in[177] - -DSP.data_in[178] - -DSP.data_in[179] - -DSP.data_in[180] - -DSP.data_in[181] - -DSP.data_in[182] - -DSP.data_in[183] - -DSP.data_in[184] - -DSP.data_in[185] - -DSP.data_in[186] - -DSP.data_in[187] - -DSP.data_in[188] - -DSP.data_in[189] - -DSP.data_in[190] - -DSP.data_in[191] - -DSP.data_in[192] - -DSP.data_in[193] - -DSP.data_in[194] - -DSP.data_in[195] - -DSP.data_in[196] - -DSP.data_in[197] - -DSP.data_in[198] - -DSP.data_in[199] - -DSP.data_in[200] - -DSP.data_in[201] - -DSP.data_in[202] - -DSP.data_in[203] - -DSP.data_in[204] - -DSP.data_in[205] - -DSP.data_in[206] - -DSP.data_in[207] - -DSP.data_in[208] - -DSP.data_in[209] - -DSP.data_in[210] - -DSP.data_in[211] - -DSP.data_in[212] - -DSP.data_in[213] - -DSP.data_in[214] - -DSP.data_in[215] - -DSP.data_in[216] - -DSP.data_in[217] - -DSP.data_in[218] - -DSP.data_in[219] - -DSP.data_in[220] - -DSP.data_in[221] - -DSP.data_in[222] - -DSP.data_in[223] - -DSP.data_in[224] - -DSP.data_in[225] - -DSP.data_in[226] - -DSP.data_in[227] - -DSP.data_in[228] - -DSP.data_in[229] - -DSP.data_in[230] - -DSP.data_in[231] - -DSP.data_in[232] - -DSP.data_in[233] - -DSP.data_in[234] - -DSP.data_in[235] - -DSP.data_in[236] - -DSP.data_in[237] - -DSP.data_in[238] - -DSP.data_in[239] - -DSP.data_in[240] - -DSP.data_in[241] - -DSP.data_in[242] - -DSP.data_in[243] - -DSP.data_in[244] - -DSP.data_in[245] - -DSP.data_in[246] - -DSP.data_in[247] - -DSP.data_in[248] - -DSP.data_in[249] - -DSP.data_in[250] - -DSP.data_in[251] - -DSP.data_in[252] - -DSP.data_in[253] - -DSP.data_in[254] - -DSP.data_in[255] - -DSP.data_in[256] - -DSP.data_in[257] - -DSP.data_in[258] - -DSP.data_in[259] - -DSP.data_in[260] - -DSP.data_in[261] - -DSP.data_in[262] - -DSP.data_in[263] - -DSP.data_in[264] - -DSP.data_in[265] - -DSP.data_in[266] - -DSP.data_in[267] - -DSP.data_in[268] - -DSP.data_in[269] - -DSP.data_in[270] - -DSP.data_in[271] - -DSP.data_in[272] - -DSP.data_in[273] - -DSP.data_in[274] - -DSP.data_in[275] - -DSP.data_in[276] - -DSP.data_in[277] - -DSP.data_in[278] - -DSP.data_in[279] - -DSP.data_in[280] - -DSP.data_in[281] - -DSP.data_in[282] - -DSP.data_in[283] - -DSP.data_in[284] - -DSP.data_in[285] - -DSP.data_in[286] - -DSP.data_in[287] - -DSP.chain_in[0] - -DSP.chain_in[1] - -DSP.chain_in[2] - -DSP.chain_in[3] - -DSP.chain_in[4] - -DSP.chain_in[5] - -DSP.chain_in[6] - -DSP.chain_in[7] - -DSP.chain_in[8] - -DSP.chain_in[9] - -DSP.chain_in[10] - -DSP.chain_in[11] - -DSP.chain_in[12] - -DSP.chain_in[13] - -DSP.chain_in[14] - -DSP.chain_in[15] - -DSP.chain_in[16] - -DSP.chain_in[17] - -DSP.chain_in[18] - -DSP.chain_in[19] - -DSP.chain_in[20] - -DSP.chain_in[21] - -DSP.chain_in[22] - -DSP.chain_in[23] - -DSP.chain_in[24] - -DSP.chain_in[25] - -DSP.chain_in[26] - -DSP.chain_in[27] - -DSP.chain_in[28] - -DSP.chain_in[29] - -DSP.chain_in[30] - -DSP.chain_in[31] - -DSP.chain_in[32] - -DSP.chain_in[33] - -DSP.chain_in[34] - -DSP.chain_in[35] - -DSP.chain_in[36] - -DSP.chain_in[37] - -DSP.chain_in[38] - -DSP.chain_in[39] - -DSP.chain_in[40] - -DSP.chain_in[41] - -DSP.chain_in[42] - -DSP.chain_in[43] - -DSP.control_in[0] - -DSP.control_in[1] - -DSP.control_in[2] - -DSP.control_in[3] - -DSP.control_in[4] - -DSP.control_in[5] - -DSP.control_in[6] - -DSP.control_in[7] - -DSP.control_in[8] - -DSP.control_in[9] - -DSP.control_in[10] - -DSP.control_in[11] - -DSP.control_in[12] - -DSP.control_in[13] - -DSP.control_in[14] - -DSP.control_in[15] - -DSP.control_in[16] - -DSP.control_in[17] - -DSP.control_in[18] - -DSP.control_in[19] - -DSP.control_in[20] - -DSP.scan_a_in[0] - -DSP.scan_a_in[1] - -DSP.scan_a_in[2] - -DSP.scan_a_in[3] - -DSP.scan_a_in[4] - -DSP.scan_a_in[5] - -DSP.scan_a_in[6] - -DSP.scan_a_in[7] - -DSP.scan_a_in[8] - -DSP.scan_a_in[9] - -DSP.scan_a_in[10] - -DSP.scan_a_in[11] - -DSP.scan_a_in[12] - -DSP.scan_a_in[13] - -DSP.scan_a_in[14] - -DSP.scan_a_in[15] - -DSP.scan_a_in[16] - -DSP.scan_a_in[17] - -DSP.data_out_top[0] - -DSP.data_out_top[1] - -DSP.data_out_top[2] - -DSP.data_out_top[3] - -DSP.data_out_top[4] - -DSP.data_out_top[5] - -DSP.data_out_top[6] - -DSP.data_out_top[7] - -DSP.data_out_top[8] - -DSP.data_out_top[9] - -DSP.data_out_top[10] - -DSP.data_out_top[11] - -DSP.data_out_top[12] - -DSP.data_out_top[13] - -DSP.data_out_top[14] - -DSP.data_out_top[15] - -DSP.data_out_top[16] - -DSP.data_out_top[17] - -DSP.data_out_top[18] - -DSP.data_out_top[19] - -DSP.data_out_top[20] - -DSP.data_out_top[21] - -DSP.data_out_top[22] - -DSP.data_out_top[23] - -DSP.data_out_top[24] - -DSP.data_out_top[25] - -DSP.data_out_top[26] - -DSP.data_out_top[27] - -DSP.data_out_top[28] - -DSP.data_out_top[29] - -DSP.data_out_top[30] - -DSP.data_out_top[31] - -DSP.data_out_top[32] - -DSP.data_out_top[33] - -DSP.data_out_top[34] - -DSP.data_out_top[35] - -DSP.data_out_top[36] - -DSP.data_out_top[37] - -DSP.data_out_top[38] - -DSP.data_out_top[39] - -DSP.data_out_top[40] - -DSP.data_out_top[41] - -DSP.data_out_top[42] - -DSP.data_out_top[43] - -DSP.data_out_top[44] - -DSP.data_out_top[45] - -DSP.data_out_top[46] - -DSP.data_out_top[47] - -DSP.data_out_top[48] - -DSP.data_out_top[49] - -DSP.data_out_top[50] - -DSP.data_out_top[51] - -DSP.data_out_top[52] - -DSP.data_out_top[53] - -DSP.data_out_top[54] - -DSP.data_out_top[55] - -DSP.data_out_top[56] - -DSP.data_out_top[57] - -DSP.data_out_top[58] - -DSP.data_out_top[59] - -DSP.data_out_top[60] - -DSP.data_out_top[61] - -DSP.data_out_top[62] - -DSP.data_out_top[63] - -DSP.data_out_top[64] - -DSP.data_out_top[65] - -DSP.data_out_top[66] - -DSP.data_out_top[67] - -DSP.data_out_top[68] - -DSP.data_out_top[69] - -DSP.data_out_top[70] - -DSP.data_out_top[71] - -DSP.data_out_bot[0] - -DSP.data_out_bot[1] - -DSP.data_out_bot[2] - -DSP.data_out_bot[3] - -DSP.data_out_bot[4] - -DSP.data_out_bot[5] - -DSP.data_out_bot[6] - -DSP.data_out_bot[7] - -DSP.data_out_bot[8] - -DSP.data_out_bot[9] - -DSP.data_out_bot[10] - -DSP.data_out_bot[11] - -DSP.data_out_bot[12] - -DSP.data_out_bot[13] - -DSP.data_out_bot[14] - -DSP.data_out_bot[15] - -DSP.data_out_bot[16] - -DSP.data_out_bot[17] - -DSP.data_out_bot[18] - -DSP.data_out_bot[19] - -DSP.data_out_bot[20] - -DSP.data_out_bot[21] - -DSP.data_out_bot[22] - -DSP.data_out_bot[23] - -DSP.data_out_bot[24] - -DSP.data_out_bot[25] - -DSP.data_out_bot[26] - -DSP.data_out_bot[27] - -DSP.data_out_bot[28] - -DSP.data_out_bot[29] - -DSP.data_out_bot[30] - -DSP.data_out_bot[31] - -DSP.data_out_bot[32] - -DSP.data_out_bot[33] - -DSP.data_out_bot[34] - -DSP.data_out_bot[35] - -DSP.data_out_bot[36] - -DSP.data_out_bot[37] - -DSP.data_out_bot[38] - -DSP.data_out_bot[39] - -DSP.data_out_bot[40] - -DSP.data_out_bot[41] - -DSP.data_out_bot[42] - -DSP.data_out_bot[43] - -DSP.data_out_bot[44] - -DSP.data_out_bot[45] - -DSP.data_out_bot[46] - -DSP.data_out_bot[47] - -DSP.data_out_bot[48] - -DSP.data_out_bot[49] - -DSP.data_out_bot[50] - -DSP.data_out_bot[51] - -DSP.data_out_bot[52] - -DSP.data_out_bot[53] - -DSP.data_out_bot[54] - -DSP.data_out_bot[55] - -DSP.data_out_bot[56] - -DSP.data_out_bot[57] - -DSP.data_out_bot[58] - -DSP.data_out_bot[59] - -DSP.data_out_bot[60] - -DSP.data_out_bot[61] - -DSP.data_out_bot[62] - -DSP.data_out_bot[63] - -DSP.data_out_bot[64] - -DSP.data_out_bot[65] - -DSP.data_out_bot[66] - -DSP.data_out_bot[67] - -DSP.data_out_bot[68] - -DSP.data_out_bot[69] - -DSP.data_out_bot[70] - -DSP.data_out_bot[71] - -DSP.chain_out[0] - -DSP.chain_out[1] - -DSP.chain_out[2] - -DSP.chain_out[3] - -DSP.chain_out[4] - -DSP.chain_out[5] - -DSP.chain_out[6] - -DSP.chain_out[7] - -DSP.chain_out[8] - -DSP.chain_out[9] - -DSP.chain_out[10] - -DSP.chain_out[11] - -DSP.chain_out[12] - -DSP.chain_out[13] - -DSP.chain_out[14] - -DSP.chain_out[15] - -DSP.chain_out[16] - -DSP.chain_out[17] - -DSP.chain_out[18] - -DSP.chain_out[19] - -DSP.chain_out[20] - -DSP.chain_out[21] - -DSP.chain_out[22] - -DSP.chain_out[23] - -DSP.chain_out[24] - -DSP.chain_out[25] - -DSP.chain_out[26] - -DSP.chain_out[27] - -DSP.chain_out[28] - -DSP.chain_out[29] - -DSP.chain_out[30] - -DSP.chain_out[31] - -DSP.chain_out[32] - -DSP.chain_out[33] - -DSP.chain_out[34] - -DSP.chain_out[35] - -DSP.chain_out[36] - -DSP.chain_out[37] - -DSP.chain_out[38] - -DSP.chain_out[39] - -DSP.chain_out[40] - -DSP.chain_out[41] - -DSP.chain_out[42] - -DSP.chain_out[43] - -DSP.scan_a_out[0] - -DSP.scan_a_out[1] - -DSP.scan_a_out[2] - -DSP.scan_a_out[3] - -DSP.scan_a_out[4] - -DSP.scan_a_out[5] - -DSP.scan_a_out[6] - -DSP.scan_a_out[7] - -DSP.scan_a_out[8] - -DSP.scan_a_out[9] - -DSP.scan_a_out[10] - -DSP.scan_a_out[11] - -DSP.scan_a_out[12] - -DSP.scan_a_out[13] - -DSP.scan_a_out[14] - -DSP.scan_a_out[15] - -DSP.scan_a_out[16] - -DSP.scan_a_out[17] - -DSP.signal_out[0] - -DSP.signal_out[1] - -DSP.signal_out[2] - -DSP.signal_out[3] - -DSP.signal_out[4] - -DSP.signal_out[5] - -DSP.clk[0] - -DSP.clk[1] - -DSP.clk[2] - -DSP.clk[3] - - -M9K.data_addr_control_in[0] - -M9K.data_addr_control_in[1] - -M9K.data_addr_control_in[2] - -M9K.data_addr_control_in[3] - -M9K.data_addr_control_in[4] - -M9K.data_addr_control_in[5] - -M9K.data_addr_control_in[6] - -M9K.data_addr_control_in[7] - -M9K.data_addr_control_in[8] - -M9K.data_addr_control_in[9] - -M9K.data_addr_control_in[10] - -M9K.data_addr_control_in[11] - -M9K.data_addr_control_in[12] - -M9K.data_addr_control_in[13] - -M9K.data_addr_control_in[14] - -M9K.data_addr_control_in[15] - -M9K.data_addr_control_in[16] - -M9K.data_addr_control_in[17] - -M9K.data_addr_control_in[18] - -M9K.data_addr_control_in[19] - -M9K.data_addr_control_in[20] - -M9K.data_addr_control_in[21] - -M9K.data_addr_control_in[22] - -M9K.data_addr_control_in[23] - -M9K.data_addr_control_in[24] - -M9K.data_addr_control_in[25] - -M9K.data_addr_control_in[26] - -M9K.data_addr_control_in[27] - -M9K.data_addr_control_in[28] - -M9K.data_addr_control_in[29] - -M9K.data_addr_control_in[30] - -M9K.data_addr_control_in[31] - -M9K.data_addr_control_in[32] - -M9K.data_addr_control_in[33] - -M9K.data_addr_control_in[34] - -M9K.data_addr_control_in[35] - -M9K.data_addr_control_in[36] - -M9K.data_addr_control_in[37] - -M9K.data_addr_control_in[38] - -M9K.data_addr_control_in[39] - -M9K.data_addr_control_in[40] - -M9K.data_addr_control_in[41] - -M9K.data_addr_control_in[42] - -M9K.data_addr_control_in[43] - -M9K.data_addr_control_in[44] - -M9K.data_addr_control_in[45] - -M9K.data_addr_control_in[46] - -M9K.data_addr_control_in[47] - -M9K.data_addr_control_in[48] - -M9K.data_addr_control_in[49] - -M9K.data_addr_control_in[50] - -M9K.data_addr_control_in[51] - -M9K.data_addr_control_in[52] - -M9K.data_addr_control_in[53] - -M9K.data_addr_control_in[54] - -M9K.data_addr_control_in[55] - -M9K.data_addr_control_in[56] - -M9K.data_addr_control_in[57] - -M9K.data_addr_control_in[58] - -M9K.data_addr_control_in[59] - -M9K.data_addr_control_in[60] - -M9K.data_addr_control_in[61] - -M9K.data_addr_control_in[62] - -M9K.data_addr_control_in[63] - -M9K.data_addr_control_in[64] - -M9K.data_addr_control_in[65] - -M9K.data_addr_control_in[66] - -M9K.data_addr_control_in[67] - -M9K.data_addr_control_in[68] - -M9K.data_addr_control_in[69] - -M9K.data_addr_control_in[70] - -M9K.data_addr_control_in[71] - -M9K.data_addr_control_in[72] - -M9K.data_addr_control_in[73] - -M9K.data_addr_control_in[74] - -M9K.data_addr_control_in[75] - -M9K.data_addr_control_in[76] - -M9K.data_addr_control_in[77] - -M9K.data_addr_control_in[78] - -M9K.data_addr_control_in[79] - -M9K.data_addr_control_in[80] - -M9K.data_addr_control_in[81] - -M9K.data_addr_control_in[82] - -M9K.data_addr_control_in[83] - -M9K.data_addr_control_in[84] - -M9K.data_addr_control_in[85] - -M9K.data_addr_control_in[86] - -M9K.data_addr_control_in[87] - -M9K.data_addr_control_in[88] - -M9K.data_addr_control_in[89] - -M9K.data_addr_control_in[90] - -M9K.data_addr_control_in[91] - -M9K.data_addr_control_in[92] - -M9K.data_addr_control_in[93] - -M9K.data_addr_control_in[94] - -M9K.data_addr_control_in[95] - -M9K.data_addr_control_in[96] - -M9K.data_addr_control_in[97] - -M9K.data_addr_control_in[98] - -M9K.data_addr_control_in[99] - -M9K.data_addr_control_in[100] - -M9K.data_addr_control_in[101] - -M9K.data_addr_control_in[102] - -M9K.data_addr_control_in[103] - -M9K.data_out[0] - -M9K.data_out[1] - -M9K.data_out[2] - -M9K.data_out[3] - -M9K.data_out[4] - -M9K.data_out[5] - -M9K.data_out[6] - -M9K.data_out[7] - -M9K.data_out[8] - -M9K.data_out[9] - -M9K.data_out[10] - -M9K.data_out[11] - -M9K.data_out[12] - -M9K.data_out[13] - -M9K.data_out[14] - -M9K.data_out[15] - -M9K.data_out[16] - -M9K.data_out[17] - -M9K.data_out[18] - -M9K.data_out[19] - -M9K.data_out[20] - -M9K.data_out[21] - -M9K.data_out[22] - -M9K.data_out[23] - -M9K.data_out[24] - -M9K.data_out[25] - -M9K.data_out[26] - -M9K.data_out[27] - -M9K.data_out[28] - -M9K.data_out[29] - -M9K.data_out[30] - -M9K.data_out[31] - -M9K.data_out[32] - -M9K.data_out[33] - -M9K.data_out[34] - -M9K.data_out[35] - -M9K.control_out[0] - -M9K.control_out[1] - -M9K.control_out[2] - -M9K.clk_in[0] - -M9K.clk_in[1] - - -M144K.data_addr_control_in[0] - -M144K.data_addr_control_in[1] - -M144K.data_addr_control_in[2] - -M144K.data_addr_control_in[3] - -M144K.data_addr_control_in[4] - -M144K.data_addr_control_in[5] - -M144K.data_addr_control_in[6] - -M144K.data_addr_control_in[7] - -M144K.data_addr_control_in[8] - -M144K.data_addr_control_in[9] - -M144K.data_addr_control_in[10] - -M144K.data_addr_control_in[11] - -M144K.data_addr_control_in[12] - -M144K.data_addr_control_in[13] - -M144K.data_addr_control_in[14] - -M144K.data_addr_control_in[15] - -M144K.data_addr_control_in[16] - -M144K.data_addr_control_in[17] - -M144K.data_addr_control_in[18] - -M144K.data_addr_control_in[19] - -M144K.data_addr_control_in[20] - -M144K.data_addr_control_in[21] - -M144K.data_addr_control_in[22] - -M144K.data_addr_control_in[23] - -M144K.data_addr_control_in[24] - -M144K.data_addr_control_in[25] - -M144K.data_addr_control_in[26] - -M144K.data_addr_control_in[27] - -M144K.data_addr_control_in[28] - -M144K.data_addr_control_in[29] - -M144K.data_addr_control_in[30] - -M144K.data_addr_control_in[31] - -M144K.data_addr_control_in[32] - -M144K.data_addr_control_in[33] - -M144K.data_addr_control_in[34] - -M144K.data_addr_control_in[35] - -M144K.data_addr_control_in[36] - -M144K.data_addr_control_in[37] - -M144K.data_addr_control_in[38] - -M144K.data_addr_control_in[39] - -M144K.data_addr_control_in[40] - -M144K.data_addr_control_in[41] - -M144K.data_addr_control_in[42] - -M144K.data_addr_control_in[43] - -M144K.data_addr_control_in[44] - -M144K.data_addr_control_in[45] - -M144K.data_addr_control_in[46] - -M144K.data_addr_control_in[47] - -M144K.data_addr_control_in[48] - -M144K.data_addr_control_in[49] - -M144K.data_addr_control_in[50] - -M144K.data_addr_control_in[51] - -M144K.data_addr_control_in[52] - -M144K.data_addr_control_in[53] - -M144K.data_addr_control_in[54] - -M144K.data_addr_control_in[55] - -M144K.data_addr_control_in[56] - -M144K.data_addr_control_in[57] - -M144K.data_addr_control_in[58] - -M144K.data_addr_control_in[59] - -M144K.data_addr_control_in[60] - -M144K.data_addr_control_in[61] - -M144K.data_addr_control_in[62] - -M144K.data_addr_control_in[63] - -M144K.data_addr_control_in[64] - -M144K.data_addr_control_in[65] - -M144K.data_addr_control_in[66] - -M144K.data_addr_control_in[67] - -M144K.data_addr_control_in[68] - -M144K.data_addr_control_in[69] - -M144K.data_addr_control_in[70] - -M144K.data_addr_control_in[71] - -M144K.data_addr_control_in[72] - -M144K.data_addr_control_in[73] - -M144K.data_addr_control_in[74] - -M144K.data_addr_control_in[75] - -M144K.data_addr_control_in[76] - -M144K.data_addr_control_in[77] - -M144K.data_addr_control_in[78] - -M144K.data_addr_control_in[79] - -M144K.data_addr_control_in[80] - -M144K.data_addr_control_in[81] - -M144K.data_addr_control_in[82] - -M144K.data_addr_control_in[83] - -M144K.data_addr_control_in[84] - -M144K.data_addr_control_in[85] - -M144K.data_addr_control_in[86] - -M144K.data_addr_control_in[87] - -M144K.data_addr_control_in[88] - -M144K.data_addr_control_in[89] - -M144K.data_addr_control_in[90] - -M144K.data_addr_control_in[91] - -M144K.data_addr_control_in[92] - -M144K.data_addr_control_in[93] - -M144K.data_addr_control_in[94] - -M144K.data_addr_control_in[95] - -M144K.data_addr_control_in[96] - -M144K.data_addr_control_in[97] - -M144K.data_addr_control_in[98] - -M144K.data_addr_control_in[99] - -M144K.data_addr_control_in[100] - -M144K.data_addr_control_in[101] - -M144K.data_addr_control_in[102] - -M144K.data_addr_control_in[103] - -M144K.data_addr_control_in[104] - -M144K.data_addr_control_in[105] - -M144K.data_addr_control_in[106] - -M144K.data_addr_control_in[107] - -M144K.data_addr_control_in[108] - -M144K.data_addr_control_in[109] - -M144K.data_addr_control_in[110] - -M144K.data_addr_control_in[111] - -M144K.data_addr_control_in[112] - -M144K.data_addr_control_in[113] - -M144K.data_addr_control_in[114] - -M144K.data_addr_control_in[115] - -M144K.data_addr_control_in[116] - -M144K.data_addr_control_in[117] - -M144K.data_addr_control_in[118] - -M144K.data_addr_control_in[119] - -M144K.data_addr_control_in[120] - -M144K.data_addr_control_in[121] - -M144K.data_addr_control_in[122] - -M144K.data_addr_control_in[123] - -M144K.data_addr_control_in[124] - -M144K.data_addr_control_in[125] - -M144K.data_addr_control_in[126] - -M144K.data_addr_control_in[127] - -M144K.data_addr_control_in[128] - -M144K.data_addr_control_in[129] - -M144K.data_addr_control_in[130] - -M144K.data_addr_control_in[131] - -M144K.data_addr_control_in[132] - -M144K.data_addr_control_in[133] - -M144K.data_addr_control_in[134] - -M144K.data_addr_control_in[135] - -M144K.data_addr_control_in[136] - -M144K.data_addr_control_in[137] - -M144K.data_addr_control_in[138] - -M144K.data_addr_control_in[139] - -M144K.data_addr_control_in[140] - -M144K.data_addr_control_in[141] - -M144K.data_addr_control_in[142] - -M144K.data_addr_control_in[143] - -M144K.data_addr_control_in[144] - -M144K.data_addr_control_in[145] - -M144K.data_addr_control_in[146] - -M144K.data_addr_control_in[147] - -M144K.data_addr_control_in[148] - -M144K.data_addr_control_in[149] - -M144K.data_addr_control_in[150] - -M144K.data_addr_control_in[151] - -M144K.data_addr_control_in[152] - -M144K.data_addr_control_in[153] - -M144K.data_addr_control_in[154] - -M144K.data_addr_control_in[155] - -M144K.data_addr_control_in[156] - -M144K.data_addr_control_in[157] - -M144K.data_addr_control_in[158] - -M144K.data_addr_control_in[159] - -M144K.data_addr_control_in[160] - -M144K.data_addr_control_in[161] - -M144K.data_addr_control_in[162] - -M144K.data_addr_control_in[163] - -M144K.data_addr_control_in[164] - -M144K.data_addr_control_in[165] - -M144K.data_addr_control_in[166] - -M144K.data_addr_control_in[167] - -M144K.data_addr_control_in[168] - -M144K.data_addr_control_in[169] - -M144K.data_addr_control_in[170] - -M144K.data_addr_control_in[171] - -M144K.data_addr_control_in[172] - -M144K.data_addr_control_in[173] - -M144K.data_addr_control_in[174] - -M144K.data_addr_control_in[175] - -M144K.data_addr_control_in[176] - -M144K.data_addr_control_in[177] - -M144K.data_addr_control_in[178] - -M144K.data_addr_control_in[179] - -M144K.data_addr_control_in[180] - -M144K.data_addr_control_in[181] - -M144K.data_addr_control_in[182] - -M144K.data_addr_control_in[183] - -M144K.data_addr_control_in[184] - -M144K.data_addr_control_in[185] - -M144K.data_addr_control_in[186] - -M144K.data_addr_control_in[187] - -M144K.data_addr_control_in[188] - -M144K.data_addr_control_in[189] - -M144K.data_addr_control_in[190] - -M144K.data_addr_control_in[191] - -M144K.data_addr_control_in[192] - -M144K.data_addr_control_in[193] - -M144K.data_addr_control_in[194] - -M144K.data_addr_control_in[195] - -M144K.data_addr_control_in[196] - -M144K.data_addr_control_in[197] - -M144K.data_addr_control_in[198] - -M144K.data_addr_control_in[199] - -M144K.data_addr_control_in[200] - -M144K.data_addr_control_in[201] - -M144K.data_addr_control_in[202] - -M144K.data_addr_control_in[203] - -M144K.data_addr_control_in[204] - -M144K.data_addr_control_in[205] - -M144K.data_addr_control_in[206] - -M144K.data_addr_control_in[207] - -M144K.data_addr_control_in[208] - -M144K.data_addr_control_in[209] - -M144K.data_addr_control_in[210] - -M144K.data_addr_control_in[211] - -M144K.data_addr_control_in[212] - -M144K.data_addr_control_in[213] - -M144K.data_addr_control_in[214] - -M144K.data_addr_control_in[215] - -M144K.data_addr_control_in[216] - -M144K.data_addr_control_in[217] - -M144K.data_addr_control_in[218] - -M144K.data_addr_control_in[219] - -M144K.data_addr_control_in[220] - -M144K.data_addr_control_in[221] - -M144K.data_addr_control_in[222] - -M144K.data_addr_control_in[223] - -M144K.data_addr_control_in[224] - -M144K.data_addr_control_in[225] - -M144K.data_addr_control_in[226] - -M144K.data_addr_control_in[227] - -M144K.data_addr_control_in[228] - -M144K.data_addr_control_in[229] - -M144K.data_addr_control_in[230] - -M144K.data_addr_control_in[231] - -M144K.data_addr_control_in[232] - -M144K.data_addr_control_in[233] - -M144K.data_addr_control_in[234] - -M144K.data_addr_control_in[235] - -M144K.data_addr_control_in[236] - -M144K.data_addr_control_in[237] - -M144K.data_addr_control_in[238] - -M144K.data_addr_control_in[239] - -M144K.data_addr_control_in[240] - -M144K.data_addr_control_in[241] - -M144K.data_addr_control_in[242] - -M144K.data_addr_control_in[243] - -M144K.data_addr_control_in[244] - -M144K.data_addr_control_in[245] - -M144K.data_addr_control_in[246] - -M144K.data_addr_control_in[247] - -M144K.data_addr_control_in[248] - -M144K.data_addr_control_in[249] - -M144K.data_addr_control_in[250] - -M144K.data_addr_control_in[251] - -M144K.data_addr_control_in[252] - -M144K.data_addr_control_in[253] - -M144K.data_addr_control_in[254] - -M144K.data_addr_control_in[255] - -M144K.data_addr_control_in[256] - -M144K.data_addr_control_in[257] - -M144K.data_addr_control_in[258] - -M144K.data_addr_control_in[259] - -M144K.data_addr_control_in[260] - -M144K.data_addr_control_in[261] - -M144K.data_addr_control_in[262] - -M144K.data_addr_control_in[263] - -M144K.data_addr_control_in[264] - -M144K.data_addr_control_in[265] - -M144K.data_addr_control_in[266] - -M144K.data_addr_control_in[267] - -M144K.data_addr_control_in[268] - -M144K.data_addr_control_in[269] - -M144K.data_addr_control_in[270] - -M144K.data_addr_control_in[271] - -M144K.data_addr_control_in[272] - -M144K.data_addr_control_in[273] - -M144K.data_addr_control_in[274] - -M144K.data_addr_control_in[275] - -M144K.data_addr_control_in[276] - -M144K.data_addr_control_in[277] - -M144K.data_addr_control_in[278] - -M144K.data_addr_control_in[279] - -M144K.data_addr_control_in[280] - -M144K.data_addr_control_in[281] - -M144K.data_addr_control_in[282] - -M144K.data_addr_control_in[283] - -M144K.data_addr_control_in[284] - -M144K.data_addr_control_in[285] - -M144K.data_addr_control_in[286] - -M144K.data_addr_control_in[287] - -M144K.data_addr_control_in[288] - -M144K.data_addr_control_in[289] - -M144K.data_addr_control_in[290] - -M144K.data_addr_control_in[291] - -M144K.data_addr_control_in[292] - -M144K.data_addr_control_in[293] - -M144K.data_addr_control_in[294] - -M144K.data_addr_control_in[295] - -M144K.data_addr_control_in[296] - -M144K.data_addr_control_in[297] - -M144K.data_addr_control_in[298] - -M144K.data_addr_control_in[299] - -M144K.data_addr_control_in[300] - -M144K.data_addr_control_in[301] - -M144K.data_addr_control_in[302] - -M144K.data_addr_control_in[303] - -M144K.data_addr_control_in[304] - -M144K.data_addr_control_in[305] - -M144K.data_addr_control_in[306] - -M144K.data_addr_control_in[307] - -M144K.data_addr_control_in[308] - -M144K.data_addr_control_in[309] - -M144K.data_addr_control_in[310] - -M144K.data_addr_control_in[311] - -M144K.data_addr_control_in[312] - -M144K.data_addr_control_in[313] - -M144K.data_addr_control_in[314] - -M144K.data_addr_control_in[315] - -M144K.data_addr_control_in[316] - -M144K.data_addr_control_in[317] - -M144K.data_addr_control_in[318] - -M144K.data_addr_control_in[319] - -M144K.data_addr_control_in[320] - -M144K.data_addr_control_in[321] - -M144K.data_addr_control_in[322] - -M144K.data_addr_control_in[323] - -M144K.data_addr_control_in[324] - -M144K.data_addr_control_in[325] - -M144K.data_addr_control_in[326] - -M144K.data_addr_control_in[327] - -M144K.data_addr_control_in[328] - -M144K.data_addr_control_in[329] - -M144K.data_addr_control_in[330] - -M144K.data_addr_control_in[331] - -M144K.data_addr_control_in[332] - -M144K.data_addr_control_in[333] - -M144K.data_addr_control_in[334] - -M144K.data_addr_control_in[335] - -M144K.data_addr_control_in[336] - -M144K.data_addr_control_in[337] - -M144K.data_addr_control_in[338] - -M144K.data_addr_control_in[339] - -M144K.data_addr_control_in[340] - -M144K.data_addr_control_in[341] - -M144K.data_addr_control_in[342] - -M144K.data_addr_control_in[343] - -M144K.data_addr_control_in[344] - -M144K.data_addr_control_in[345] - -M144K.data_addr_control_in[346] - -M144K.data_addr_control_in[347] - -M144K.data_addr_control_in[348] - -M144K.data_addr_control_in[349] - -M144K.data_addr_control_in[350] - -M144K.data_addr_control_in[351] - -M144K.data_addr_control_in[352] - -M144K.data_addr_control_in[353] - -M144K.data_addr_control_in[354] - -M144K.data_addr_control_in[355] - -M144K.data_addr_control_in[356] - -M144K.data_addr_control_in[357] - -M144K.data_addr_control_in[358] - -M144K.data_addr_control_in[359] - -M144K.data_addr_control_in[360] - -M144K.data_addr_control_in[361] - -M144K.data_addr_control_in[362] - -M144K.data_addr_control_in[363] - -M144K.data_addr_control_in[364] - -M144K.data_addr_control_in[365] - -M144K.data_addr_control_in[366] - -M144K.data_addr_control_in[367] - -M144K.data_addr_control_in[368] - -M144K.data_addr_control_in[369] - -M144K.data_addr_control_in[370] - -M144K.data_addr_control_in[371] - -M144K.data_addr_control_in[372] - -M144K.data_addr_control_in[373] - -M144K.data_addr_control_in[374] - -M144K.data_addr_control_in[375] - -M144K.data_addr_control_in[376] - -M144K.data_addr_control_in[377] - -M144K.data_addr_control_in[378] - -M144K.data_addr_control_in[379] - -M144K.data_addr_control_in[380] - -M144K.data_addr_control_in[381] - -M144K.data_addr_control_in[382] - -M144K.data_addr_control_in[383] - -M144K.data_addr_control_in[384] - -M144K.data_addr_control_in[385] - -M144K.data_addr_control_in[386] - -M144K.data_addr_control_in[387] - -M144K.data_addr_control_in[388] - -M144K.data_addr_control_in[389] - -M144K.data_addr_control_in[390] - -M144K.data_addr_control_in[391] - -M144K.data_addr_control_in[392] - -M144K.data_addr_control_in[393] - -M144K.data_addr_control_in[394] - -M144K.data_addr_control_in[395] - -M144K.data_addr_control_in[396] - -M144K.data_addr_control_in[397] - -M144K.data_addr_control_in[398] - -M144K.data_addr_control_in[399] - -M144K.data_addr_control_in[400] - -M144K.data_addr_control_in[401] - -M144K.data_addr_control_in[402] - -M144K.data_addr_control_in[403] - -M144K.data_addr_control_in[404] - -M144K.data_addr_control_in[405] - -M144K.data_addr_control_in[406] - -M144K.data_addr_control_in[407] - -M144K.data_addr_control_in[408] - -M144K.data_addr_control_in[409] - -M144K.data_addr_control_in[410] - -M144K.data_addr_control_in[411] - -M144K.data_addr_control_in[412] - -M144K.data_addr_control_in[413] - -M144K.data_addr_control_in[414] - -M144K.data_addr_control_in[415] - -M144K.data_out[0] - -M144K.data_out[1] - -M144K.data_out[2] - -M144K.data_out[3] - -M144K.data_out[4] - -M144K.data_out[5] - -M144K.data_out[6] - -M144K.data_out[7] - -M144K.data_out[8] - -M144K.data_out[9] - -M144K.data_out[10] - -M144K.data_out[11] - -M144K.data_out[12] - -M144K.data_out[13] - -M144K.data_out[14] - -M144K.data_out[15] - -M144K.data_out[16] - -M144K.data_out[17] - -M144K.data_out[18] - -M144K.data_out[19] - -M144K.data_out[20] - -M144K.data_out[21] - -M144K.data_out[22] - -M144K.data_out[23] - -M144K.data_out[24] - -M144K.data_out[25] - -M144K.data_out[26] - -M144K.data_out[27] - -M144K.data_out[28] - -M144K.data_out[29] - -M144K.data_out[30] - -M144K.data_out[31] - -M144K.data_out[32] - -M144K.data_out[33] - -M144K.data_out[34] - -M144K.data_out[35] - -M144K.data_out[36] - -M144K.data_out[37] - -M144K.data_out[38] - -M144K.data_out[39] - -M144K.data_out[40] - -M144K.data_out[41] - -M144K.data_out[42] - -M144K.data_out[43] - -M144K.data_out[44] - -M144K.data_out[45] - -M144K.data_out[46] - -M144K.data_out[47] - -M144K.data_out[48] - -M144K.data_out[49] - -M144K.data_out[50] - -M144K.data_out[51] - -M144K.data_out[52] - -M144K.data_out[53] - -M144K.data_out[54] - -M144K.data_out[55] - -M144K.data_out[56] - -M144K.data_out[57] - -M144K.data_out[58] - -M144K.data_out[59] - -M144K.data_out[60] - -M144K.data_out[61] - -M144K.data_out[62] - -M144K.data_out[63] - -M144K.data_out[64] - -M144K.data_out[65] - -M144K.data_out[66] - -M144K.data_out[67] - -M144K.data_out[68] - -M144K.data_out[69] - -M144K.data_out[70] - -M144K.data_out[71] - -M144K.data_out[72] - -M144K.data_out[73] - -M144K.data_out[74] - -M144K.data_out[75] - -M144K.data_out[76] - -M144K.data_out[77] - -M144K.data_out[78] - -M144K.data_out[79] - -M144K.data_out[80] - -M144K.data_out[81] - -M144K.data_out[82] - -M144K.data_out[83] - -M144K.data_out[84] - -M144K.data_out[85] - -M144K.data_out[86] - -M144K.data_out[87] - -M144K.data_out[88] - -M144K.data_out[89] - -M144K.data_out[90] - -M144K.data_out[91] - -M144K.data_out[92] - -M144K.data_out[93] - -M144K.data_out[94] - -M144K.data_out[95] - -M144K.data_out[96] - -M144K.data_out[97] - -M144K.data_out[98] - -M144K.data_out[99] - -M144K.data_out[100] - -M144K.data_out[101] - -M144K.data_out[102] - -M144K.data_out[103] - -M144K.data_out[104] - -M144K.data_out[105] - -M144K.data_out[106] - -M144K.data_out[107] - -M144K.data_out[108] - -M144K.data_out[109] - -M144K.data_out[110] - -M144K.data_out[111] - -M144K.data_out[112] - -M144K.data_out[113] - -M144K.data_out[114] - -M144K.data_out[115] - -M144K.data_out[116] - -M144K.data_out[117] - -M144K.data_out[118] - -M144K.data_out[119] - -M144K.control_out[0] - -M144K.control_out[1] - -M144K.control_out[2] - -M144K.clk_in[0] - -M144K.clk_in[1] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_verify_rr_graph_titan/config/config.txt similarity index 65% rename from vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt rename to vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_verify_rr_graph_titan/config/config.txt index 8423ebd1e44..435cfd187ec 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/config.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_verify_rr_graph_titan/config/config.txt @@ -16,12 +16,13 @@ circuit_list_add=styr.blif arch_list_add=stratixiv_arch.timing.xml # Parse info and how to parse -parse_file=vpr_no_timing.txt +parse_file=vpr_fixed_chan_width.txt +parse_file=vpr_parse_second_file.txt # How to parse QoR info -qor_parse_file=qor_no_timing.txt +qor_parse_file=qor_rr_graph.txt # Pass requirements -pass_requirements_file=pass_requirements_no_timing.txt +pass_requirements_file=pass_requirements_verify_rr_graph.txt -script_params=-starting_stage vpr -read_rr_graph ../../../../config/stratixiv_arch.timing_11x8_rr_graph.xml -route_chan_width 20 +script_params=-starting_stage vpr -verify_rr_graph -rr_graph_ext .xml -route_chan_width 20 diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_verify_rr_graph_titan/config/golden_results.txt similarity index 100% rename from vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_read_rr_graph/config/golden_results.txt rename to vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_verify_rr_graph_titan/config/golden_results.txt diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt deleted file mode 100644 index 64966d2d89e..00000000000 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/config.txt +++ /dev/null @@ -1,27 +0,0 @@ -# -############################################ -# Configuration file for running experiments -############################################## - -# Path to directory of circuits to use -circuits_dir=benchmarks/blif/6 - -# Path to directory of architectures to use -archs_dir=arch/titan - -# Add circuits to list to sweep -circuit_list_add=styr.blif - -# Add architectures to list to sweep -arch_list_add=stratixiv_arch.timing.xml - -# Parse info and how to parse -parse_file=vpr_no_timing.txt - -# How to parse QoR info -qor_parse_file=qor_no_timing.txt - -# Pass requirements -pass_requirements_file=pass_requirements_no_timing.txt - -script_params=-starting_stage vpr -write_rr_graph stratixv_arch.timing_11x8_rr_graph.xml diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/golden_results.txt deleted file mode 100644 index 5865b921c93..00000000000 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_write_rr_graph/config/golden_results.txt +++ /dev/null @@ -1,2 +0,0 @@ -arch circuit script_params vtr_flow_elapsed_time error odin_synth_time max_odin_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_time placed_wirelength_est place_time place_quench_time min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time -stratixiv_arch.timing.xml styr.blif common 27.62 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 10 -1 -1 success v8.0.0-3029-g69c619cb1-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 8.4.0 on Linux-3.10.0-1127.18.2.el7.x86_64 x86_64 2021-01-07T14:18:26 lnissrv4.eng.utah.edu /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing 762884 10 10 168 178 1 62 30 11 8 88 io auto 0.55 338 0.07 0.00 20 737 16 0 0 100248. 1139.18 2.94 diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt index ab5495ddcf1..94c10f6b2ad 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt @@ -73,5 +73,4 @@ regression_tests/vtr_reg_strong/strong_fix_clusters regression_tests/vtr_reg_strong/strong_analytic_placer regression_tests/vtr_reg_strong/strong_place_quench_slack regression_tests/vtr_reg_strong/strong_post_routing_sync -regression_tests/vtr_reg_strong/strong_read_rr_graph -regression_tests/vtr_reg_strong/strong_write_rr_graph +regression_tests/vtr_reg_strong/strong_verify_rr_graph_titan From 630e13f5970869d0874f2784efddcc609aba9dae Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 9 Jan 2021 15:36:47 -0700 Subject: [PATCH 27/32] [VPR] Move side map as an internal data and built up when the object is created --- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 118 +++++++++++--------- 1 file changed, 64 insertions(+), 54 deletions(-) diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 75de8e51e9e..ab5c10a4ad8 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -291,8 +291,66 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { , rr_edge_metadata_(rr_edge_metadata) , strings_(strings) , empty_(strings_->intern_string(vtr::string_view(""))) - , report_error_(nullptr) {} + , report_error_(nullptr) { + // Initialize internal data + init_side_map(); + } + + /* A truth table to help understand the conversion from VPR side mask to uxsd side code + * + * index | LEFT BOTTOM RIGHT TOP | mask + * ======+======================+====== + * 1 | X | 0001 + * ======+======================+====== + * 2 | X | 0010 + * ======+======================+====== + * 3 | X X | 0011 + * ======+======================+====== + * 4 | X | 0100 + * ======+======================+====== + * 5 | X X | 0101 + * ======+======================+====== + * 6 | X X | 0110 + * ======+======================+====== + * 7 | X X X | 0111 + * ======+======================+====== + * 8 | X | 1000 + * ======+======================+====== + * 9 | X X | 1001 + * ======+======================+====== + * 10 | X X | 1010 + * ======+======================+====== + * 11 | X X X | 1011 + * ======+======================+====== + * 12 | X X | 1100 + * ======+======================+====== + * 13 | X X X | 1101 + * ======+======================+====== + * 14 | X X X | 1110 + * ======+======================+====== + * 15 | X X X X | 1111 + */ + private: + virtual void init_side_map() final { + side_map_[0] = uxsd::enum_loc_side::UXSD_INVALID; + side_map_[(1 << TOP)] = uxsd::enum_loc_side::TOP; + side_map_[(1 << RIGHT)] = uxsd::enum_loc_side::RIGHT; + side_map_[(1 << BOTTOM)] = uxsd::enum_loc_side::BOTTOM; + side_map_[(1 << LEFT)] = uxsd::enum_loc_side::LEFT; + side_map_[(1 << TOP) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_LEFT; + side_map_[(1 << TOP) | (1 << RIGHT)] = uxsd::enum_loc_side::TOP_RIGHT; + side_map_[(1 << TOP) | (1 << BOTTOM)] = uxsd::enum_loc_side::TOP_BOTTOM; + side_map_[(1 << RIGHT) | (1 << BOTTOM)] = uxsd::enum_loc_side::RIGHT_BOTTOM; + side_map_[(1 << RIGHT) | (1 << LEFT)] = uxsd::enum_loc_side::RIGHT_LEFT; + side_map_[(1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::BOTTOM_LEFT; + side_map_[(1 << TOP) | (1 << RIGHT) | (1 << BOTTOM)] = uxsd::enum_loc_side::TOP_RIGHT_BOTTOM; + side_map_[(1 << TOP) | (1 << RIGHT) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_RIGHT_LEFT; + side_map_[(1 << TOP) | (1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_BOTTOM_LEFT; + side_map_[(1 << RIGHT) | (1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::RIGHT_BOTTOM_LEFT; + side_map_[(1 << TOP) | (1 << RIGHT) | (1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_RIGHT_BOTTOM_LEFT; + } + public: void start_load(const std::function* report_error_in) final { // report_error_in should be invoked if RrGraphSerializer encounters // an error during the read. @@ -1698,67 +1756,16 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { return side_mask; } - /* A truth table to help understand the conversion from VPR side mask to uxsd side code - * - * index | LEFT BOTTOM RIGHT TOP | mask - * ======+======================+====== - * 1 | X | 0001 - * ======+======================+====== - * 2 | X | 0010 - * ======+======================+====== - * 3 | X X | 0011 - * ======+======================+====== - * 4 | X | 0100 - * ======+======================+====== - * 5 | X X | 0101 - * ======+======================+====== - * 6 | X X | 0110 - * ======+======================+====== - * 7 | X X X | 0111 - * ======+======================+====== - * 8 | X | 1000 - * ======+======================+====== - * 9 | X X | 1001 - * ======+======================+====== - * 10 | X X | 1010 - * ======+======================+====== - * 11 | X X X | 1011 - * ======+======================+====== - * 12 | X X | 1100 - * ======+======================+====== - * 13 | X X X | 1101 - * ======+======================+====== - * 14 | X X X | 1110 - * ======+======================+====== - * 15 | X X X X | 1111 - */ uxsd::enum_loc_side to_uxsd_loc_side(std::bitset sides) { - std::array side_map; - side_map[0] = uxsd::enum_loc_side::UXSD_INVALID; - side_map[(1 << TOP)] = uxsd::enum_loc_side::TOP; - side_map[(1 << RIGHT)] = uxsd::enum_loc_side::RIGHT; - side_map[(1 << BOTTOM)] = uxsd::enum_loc_side::BOTTOM; - side_map[(1 << LEFT)] = uxsd::enum_loc_side::LEFT; - side_map[(1 << TOP) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_LEFT; - side_map[(1 << TOP) | (1 << RIGHT)] = uxsd::enum_loc_side::TOP_RIGHT; - side_map[(1 << TOP) | (1 << BOTTOM)] = uxsd::enum_loc_side::TOP_BOTTOM; - side_map[(1 << RIGHT) | (1 << BOTTOM)] = uxsd::enum_loc_side::RIGHT_BOTTOM; - side_map[(1 << RIGHT) | (1 << LEFT)] = uxsd::enum_loc_side::RIGHT_LEFT; - side_map[(1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::BOTTOM_LEFT; - side_map[(1 << TOP) | (1 << RIGHT) | (1 << BOTTOM)] = uxsd::enum_loc_side::TOP_RIGHT_BOTTOM; - side_map[(1 << TOP) | (1 << RIGHT) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_RIGHT_LEFT; - side_map[(1 << TOP) | (1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_BOTTOM_LEFT; - side_map[(1 << RIGHT) | (1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::RIGHT_BOTTOM_LEFT; - side_map[(1 << TOP) | (1 << RIGHT) | (1 << BOTTOM) | (1 << LEFT)] = uxsd::enum_loc_side::TOP_RIGHT_BOTTOM_LEFT; // Error out when // - the side has no valid bits // - the side is beyond the mapping range: this is to warn any changes on side truth table which may cause the mapping failed if ((0 == sides.count()) - || (sides.to_ulong() > side_map.size() - 1)) { + || (sides.to_ulong() > side_map_.size() - 1)) { report_error( "Invalid side %ld", sides.to_ulong()); } - return side_map[sides.to_ulong()]; + return side_map_[sides.to_ulong()]; } e_direction from_uxsd_node_direction(uxsd::enum_node_direction direction) { @@ -1933,6 +1940,9 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { std::vector seg_index_; std::string temp_string_; + // Constant mapping which is frequently used + std::array side_map_; + // Output for loads, and constant data for writes. int* wire_to_rr_ipin_switch_; t_chan_width* chan_width_; From e5913c30757aa57be0ff16e3e944089a4c40efa2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 9 Jan 2021 17:37:04 -0700 Subject: [PATCH 28/32] [VPR] code format fix --- vpr/src/route/rr_graph_uxsdcxx_serializer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index ab5c10a4ad8..ec69af7c2f3 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -1940,7 +1940,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { std::vector seg_index_; std::string temp_string_; - // Constant mapping which is frequently used + // Constant mapping which is frequently used std::array side_map_; // Output for loads, and constant data for writes. From fab5445ab24057ee8f4ea06080d3efd459782f30 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 11 Jan 2021 16:00:58 -0700 Subject: [PATCH 29/32] [VPR] Add comments about the new node_side() APIs --- vpr/src/route/rr_graph_storage.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index c9c79e32fae..99513f7781b 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -197,18 +197,36 @@ class t_rr_graph_storage { } const char* node_direction_string(RRNodeId id) const; + /* THIS FUNCTION IS GOING TO BE DEPRECATED + * Return the first valid side for the node + */ e_side node_side(RRNodeId id) const { return get_node_side( vtr::array_view_id( node_storage_.data(), node_storage_.size()), id); } + + /* Return a bitmap for all the sides of a given node + * Currently, there are 4 sides: TOP, RIGHT, BOTTOM, LEFT + * The bit set is a 4-bit vector through which users can + * know on which sides the given nodes appear: + * For example, + * // See if the node is on TOP side + * if (true == node_sides(id)[TOP]) { + * } + * // See if the node appears ONLY on 1 side + * if (1 == node_sides(id).count()) { + * } + */ std::bitset node_sides(RRNodeId id) const { return get_node_sides( vtr::array_view_id( node_storage_.data(), node_storage_.size()), id); } + + /* Find if the given node appears on a specific side */ bool is_node_on_specific_side(RRNodeId id, e_side side) const { return is_node_on_specific_side( vtr::array_view_id( From f89faadd1d8a71c94b245c3a4ed981defb492bf7 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 27 Jan 2021 15:23:43 -0700 Subject: [PATCH 30/32] [VPR] Add comment about the 16 enum in node side --- vpr/src/route/rr_graph.xsd | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vpr/src/route/rr_graph.xsd b/vpr/src/route/rr_graph.xsd index decca0f9205..cdc60f654e4 100644 --- a/vpr/src/route/rr_graph.xsd +++ b/vpr/src/route/rr_graph.xsd @@ -234,6 +234,9 @@ + From 1ee77455c44a61458dd694eedfe148ff14017a77 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 27 Jan 2021 15:28:01 -0700 Subject: [PATCH 31/32] [VPR] Add comment about the multi-side query API of RRGraph --- vpr/src/route/rr_graph_storage.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 99513f7781b..77064cfa1d2 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -218,6 +218,12 @@ class t_rr_graph_storage { * // See if the node appears ONLY on 1 side * if (1 == node_sides(id).count()) { * } + * + * TODO: This function may be deprecated, depending its utilization + * in client functions, router, GUI etc. It offers a shortcut + * for developers who can check what sides a node appear on. + * However, such query can be done outside RRGraph by iterating + * over all the sides and using API is_node_on_specific_side() */ std::bitset node_sides(RRNodeId id) const { return get_node_sides( From 66b7e7658845cedf5a5da07d2e805b1e18f2c77f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 28 Jan 2021 12:22:53 -0700 Subject: [PATCH 32/32] [VPR] Remove buggy warning message from an API that is going to be deprecated --- vpr/src/route/rr_graph_storage.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 77064cfa1d2..647deebf777 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -648,16 +648,6 @@ class t_rr_graph_storage { rr_node_typename[node_data.type_]); } std::bitset side_tt = node_storage[id].dir_side_.sides; - if (1 < side_tt.count()) { - /* Throw a non-fatal error which is suppressable */ - VTR_LOG_WARN("Try to get one side for RR node '%d':\n\ttype='%s'\txlow,ylow=(%d,%d)\n\txhigh,yhigh=(%d,%d), which has multiple sides!", - size_t(id), - rr_node_typename[node_data.type_], - node_data.xlow_, - node_data.ylow_, - node_data.xhigh_, - node_data.yhigh_); - } for (const e_side& side : SIDES) { if (side_tt[size_t(side)]) { return side;