237 lines
12 KiB
C++
237 lines
12 KiB
C++
#include <cassert>
|
|
#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<int> in_edge_ids, std::vector<int> 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<int> /*in_edge_ids*/, std::vector<int> /*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;
|
|
}
|
|
}
|