#include #include "tatumparse.hpp" namespace tp = tatumparse; class PrintCallback : public tp::Callback { void start_parse() override { fprintf(stderr, "Starting parse\n"); } void filename(std::string fname) override { filename_ = fname; } void lineno(int line_num) override { line_no_ = line_num; } void finish_parse() override { fprintf(stderr, "Finished parse\n"); } void start_graph() override { fprintf(stdout, "timing_graph:\n"); } void add_node(int node_id, tp::NodeType type, std::vector in_edge_ids, std::vector out_edge_ids) override { fprintf(stdout, " node: %d", node_id); fprintf(stdout, "\n"); fprintf(stdout, " type:"); switch(type) { case tp::NodeType::SOURCE: fprintf(stdout, " SOURCE"); break; case tp::NodeType::SINK: fprintf(stdout, " SINK"); break; case tp::NodeType::IPIN: fprintf(stdout, " IPIN"); break; case tp::NodeType::OPIN: fprintf(stdout, " OPIN"); break; default: assert(false); } fprintf(stdout, "\n"); fprintf(stdout, " in_edges: "); for(auto edge : in_edge_ids) { fprintf(stdout, "%d ", edge); } fprintf(stdout, "\n"); fprintf(stdout, " out_edges: "); for(auto edge : out_edge_ids) { fprintf(stdout, "%d ", edge); } fprintf(stdout, "\n"); } void add_edge(int edge_id, tp::EdgeType type, int src_node_id, int sink_node_id, bool disabled) override { fprintf(stdout, " edge: %d\n", edge_id); fprintf(stdout, " type:"); switch(type) { case tp::EdgeType::PRIMITIVE_COMBINATIONAL: fprintf(stdout, " PRIMITIVE_COMBINATIONAL"); break; case tp::EdgeType::PRIMITIVE_CLOCK_LAUNCH : fprintf(stdout, " PRIMITIVE_CLOCK_LAUNCH"); break; case tp::EdgeType::PRIMITIVE_CLOCK_CAPTURE: fprintf(stdout, " PRIMITIVE_CLOCK_CAPTURE"); break; case tp::EdgeType::INTERCONNECT : fprintf(stdout, " INTERCONNECT"); break; default: assert(false); } fprintf(stdout, "\n"); fprintf(stdout, " src_node: %d\n", src_node_id); fprintf(stdout, " sink_node: %d\n", sink_node_id); if(disabled) { fprintf(stdout, " disabled: true\n"); } } void finish_graph() override { fprintf(stdout, "# end timing_graph\n"); } void start_constraints() override { fprintf(stdout, "timing_constraints:\n"); } void add_clock_domain(int domain_id, std::string name) override { fprintf(stdout, " type: CLOCK domain: %d name: \"%s\"\n", domain_id, name.c_str()); } void add_clock_source(int node_id, int domain_id) override { fprintf(stdout, " type: CLOCK_SOURCE node: %d domain: %d\n", node_id, domain_id); } void add_constant_generator(int node_id) override { fprintf(stdout, " type: CONSTANT_GENERATOR node: %d\n", node_id); } void add_max_input_constraint(int node_id, int domain_id, float constraint) override { fprintf(stdout, " type: MAX_INPUT_CONSTRAINT node: %d domain: %d constraint: %g\n", node_id, domain_id, constraint); } void add_min_input_constraint(int node_id, int domain_id, float constraint) override { fprintf(stdout, " type: MIN_INPUT_CONSTRAINT node: %d domain: %d constraint: %g\n", node_id, domain_id, constraint); } void add_max_output_constraint(int node_id, int domain_id, float constraint) override { fprintf(stdout, " type: MAX_OUTPUT_CONSTRAINT node: %d domain: %d constraint: %g\n", node_id, domain_id, constraint); } void add_min_output_constraint(int node_id, int domain_id, float constraint) override { fprintf(stdout, " type: MIN_OUTPUT_CONSTRAINT node: %d domain: %d constraint: %g\n", node_id, domain_id, constraint); } void add_setup_constraint(int src_domain_id, int sink_domain_id, int capture_node, float constraint) override { fprintf(stdout, " type: SETUP_CONSTRAINT src_domain: %d sink_domain: %d capture_node: %d constraint: %g\n", src_domain_id, sink_domain_id, capture_node, constraint); } void add_hold_constraint(int src_domain_id, int sink_domain_id, int capture_node, float constraint) override { fprintf(stdout, " type: HOLD_CONSTRAINT src_domain: %d sink_domain: %d capture_node: %d constraint: %g\n", src_domain_id, sink_domain_id, capture_node, constraint); } void add_setup_uncertainty(int src_domain_id, int sink_domain_id, float uncertainty) override { fprintf(stdout, " type: SETUP_UNCERTAINTY src_domain: %d sink_domain: %d uncertainty: %g\n", src_domain_id, sink_domain_id, uncertainty); } void add_hold_uncertainty(int src_domain_id, int sink_domain_id, float uncertainty) override { fprintf(stdout, " type: HOLD_UNCERTAINTY src_domain: %d sink_domain: %d uncertainty: %g\n", src_domain_id, sink_domain_id, uncertainty); } void add_early_source_latency(int domain_id, float latency) override { fprintf(stdout, " type: EARLY_SOURCE_LATENCY domain: %d latency: %g\n", domain_id, latency); } void add_late_source_latency(int domain_id, float latency) override { fprintf(stdout, " type: LATE_SOURCE_LATENCY domain: %d latency: %g\n", domain_id, latency); } void finish_constraints() override { fprintf(stdout, "# end timing_constraints\n"); } void start_delay_model() override { fprintf(stdout, "delay_model:\n"); } void add_edge_delay(int edge_id, float min_delay, float max_delay) override { fprintf(stdout, " edge_id: %d min_delay: %g max_delay: %g\n", edge_id, min_delay, max_delay); } void add_edge_setup_hold_time(int edge_id, float setup_time, float hold_time) override { fprintf(stdout, " edge_id: %d setup_time: %g hold_time: %g\n", edge_id, setup_time, hold_time); } void finish_delay_model() override { fprintf(stdout, "# end delay_model\n"); } void start_results() override { fprintf(stdout, "analysis_result:\n"); } void add_node_tag(tp::TagType type, int node_id, int launch_domain_id, int capture_domain_id, float time) override { fprintf(stdout, " type: "); switch(type) { case tp::TagType::SETUP_LAUNCH_CLOCK: fprintf(stdout, "SETUP_LAUNCH_CLOCK"); break; case tp::TagType::SETUP_CAPTURE_CLOCK: fprintf(stdout, "SETUP_CAPTURE_CLOCK"); break; case tp::TagType::HOLD_LAUNCH_CLOCK: fprintf(stdout, "HOLD_LAUNCH_CLOCK"); break; case tp::TagType::HOLD_CAPTURE_CLOCK: fprintf(stdout, "HOLD_CAPTURE_CLOCK"); break; default: assert(false); } fprintf(stdout, " node: %d launch_domain: %d capture_domain: %d time: %g\n", node_id, launch_domain_id, capture_domain_id, time); } void add_edge_slack(tp::TagType type, int edge_id, int launch_domain_id, int capture_domain_id, float slack) override { fprintf(stdout, " type: "); switch(type) { case tp::TagType::SETUP_SLACK: fprintf(stdout, "SETUP_SLACK"); break; case tp::TagType::HOLD_SLACK: fprintf(stdout, "HOLD_SLACK"); break; default: assert(false); } fprintf(stdout, " edge: %d launch_domain: %d capture_domain: %d time: %g\n", edge_id, launch_domain_id, capture_domain_id, slack); } void add_node_slack(tp::TagType type, int node_id, int launch_domain_id, int capture_domain_id, float slack) override { fprintf(stdout, " type: "); switch(type) { case tp::TagType::SETUP_SLACK: fprintf(stdout, "SETUP_SLACK"); break; case tp::TagType::HOLD_SLACK: fprintf(stdout, "HOLD_SLACK"); break; default: assert(false); } fprintf(stdout, " node: %d launch_domain: %d capture_domain: %d time: %g\n", node_id, launch_domain_id, capture_domain_id, slack); } void finish_results() override { fprintf(stdout, "# end analysis_results\n"); } void parse_error(const int curr_lineno, const std::string& near_text, const std::string& msg) override { fprintf(stderr, "%s:%d: Parse error: %s", filename_.c_str(), curr_lineno, msg.c_str()); if(!near_text.empty()) { fprintf(stderr, " near '%s'", near_text.c_str()); fprintf(stderr, "\n"); } else { if(msg.find('\n') == std::string::npos) { fprintf(stderr, "\n"); } } } private: std::string filename_; int line_no_; }; class NopCallback : public tp::Callback { public: //Start of parsing void start_parse() override {} //Sets current filename void filename(std::string fname) override { filename_ = fname; } //Sets current line number void lineno(int /*line_num*/) override {} void start_graph() override {} void add_node(int /*node_id*/, tp::NodeType /*type*/, std::vector /*in_edge_ids*/, std::vector /*out_edge_ids*/) override {} void add_edge(int /*edge_id*/, tp::EdgeType /*type*/, int /*src_node_id*/, int /*sink_node_id*/, bool /*disabled*/) override {} void finish_graph() override {} void start_constraints() override {} void add_clock_domain(int /*domain_id*/, std::string /*name*/) override {} void add_clock_source(int /*node_id*/, int /*domain_id*/) override {} void add_constant_generator(int /*node_id*/) override {} void add_max_input_constraint(int /*node_id*/, int /*domain_id*/, float /*constraint*/) override {} void add_min_input_constraint(int /*node_id*/, int /*domain_id*/, float /*constraint*/) override {} void add_max_output_constraint(int /*node_id*/, int /*domain_id*/, float /*constraint*/) override {} void add_min_output_constraint(int /*node_id*/, int /*domain_id*/, float /*constraint*/) override {} void add_setup_constraint(int /*src_domain_id*/, int /*sink_domain_id*/, int /*capture_node*/, float /*constraint*/) override {} void add_hold_constraint(int /*src_domain_id*/, int /*sink_domain_id*/, int /*capture_node*/, float /*constraint*/) override {} void add_setup_uncertainty(int /*src_domain_id*/, int /*sink_domain_id*/, float /*uncertainty*/) override {} void add_hold_uncertainty(int /*src_domain_id*/, int /*sink_domain_id*/, float /*uncertainty*/) override {} void add_early_source_latency(int /*domain_id*/, float /*latency*/) override {} void add_late_source_latency(int /*domain_id*/, float /*latency*/) override {} void finish_constraints() override {} void start_delay_model() override {} void add_edge_delay(int /*edge_id*/, float /*min_delay*/, float /*max_delay*/) override {} void add_edge_setup_hold_time(int /*edge_id*/, float /*setup_time*/, float /*hold_time*/) override {} void finish_delay_model() override {} void start_results() override {} void add_node_tag(tp::TagType /*type*/, int /*node_id*/, int /*launch_domain_id*/, int /*capture_domain_id*/, float /*time*/) override {} void add_edge_slack(tp::TagType /*type*/, int /*edge_id*/, int /*launch_domain_id*/, int /*capture_domain_id*/, float /*slack*/) override {} void add_node_slack(tp::TagType /*type*/, int /*node_id*/, int /*launch_domain_id*/, int /*capture_domain_id*/, float /*slack*/) override {} void finish_results() override {} //End of parsing void finish_parse() override {} //Error during parsing void parse_error(const int curr_lineno, const std::string& near_text, const std::string& msg) override { fprintf(stderr, "%s:%d: Parse error: %s", filename_.c_str(), curr_lineno, msg.c_str()); if(!near_text.empty()) { fprintf(stderr, " near '%s'", near_text.c_str()); fprintf(stderr, "\n"); } else { if(msg.find('\n') == std::string::npos) { fprintf(stderr, "\n"); } } } private: std::string filename_; }; int main(int argc, char** argv) { //PrintCallback cb; NopCallback cb; if(argc == 2) { if(std::string(argv[1]) == "-") { tp::tatum_parse_file(stdin, cb); } else { tp::tatum_parse_filename(argv[1], cb); } } else { fprintf(stderr, "Invalid command line\n"); return 1; } }