257 lines
7.2 KiB
C++
257 lines
7.2 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include "sdcparse.hpp"
|
|
|
|
using namespace sdcparse;
|
|
|
|
void print_string_group(const StringGroup& group);
|
|
void print_from_to_group(const StringGroup& from, const StringGroup& to);
|
|
|
|
class PrintCallback : public 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 { lineno_ = line_num; }
|
|
|
|
void create_clock(const CreateClock& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
printf("create_clock -period %f -waveform {%f %f} ",
|
|
cmd.period,
|
|
cmd.rise_edge,
|
|
cmd.fall_edge);
|
|
if(cmd.is_virtual) {
|
|
printf("-name %s",
|
|
cmd.name.c_str());
|
|
} else {
|
|
print_string_group(cmd.targets);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void set_io_delay(const SetIoDelay& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
if(cmd.type == IoDelayType::INPUT) {
|
|
printf("set_input_delay");
|
|
} else {
|
|
printf("set_output_delay");
|
|
}
|
|
printf(" -clock %s", cmd.clock_name.c_str());
|
|
|
|
if (cmd.is_max) {
|
|
printf(" -max");
|
|
}
|
|
if (cmd.is_min) {
|
|
printf(" -min");
|
|
}
|
|
printf(" %f ", cmd.delay);
|
|
print_string_group(cmd.target_ports);
|
|
printf("\n");
|
|
|
|
}
|
|
void set_clock_groups(const SetClockGroups& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
printf("set_clock_groups");
|
|
if(cmd.type == ClockGroupsType::EXCLUSIVE) {
|
|
printf(" -exclusive");
|
|
}
|
|
for(const auto& clk_grp : cmd.clock_groups) {
|
|
printf(" -group ");
|
|
print_string_group(clk_grp);
|
|
}
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
void set_false_path(const SetFalsePath& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
printf("set_false_path ");
|
|
print_from_to_group(cmd.from, cmd.to);
|
|
printf("\n");
|
|
}
|
|
void set_min_max_delay(const SetMinMaxDelay& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
if(cmd.type == MinMaxType::MAX) {
|
|
printf("set_max_delay");
|
|
} else {
|
|
printf("set_min_delay");
|
|
}
|
|
printf(" %f ", cmd.value);
|
|
print_from_to_group(cmd.from, cmd.to);
|
|
printf("\n");
|
|
}
|
|
void set_multicycle_path(const SetMulticyclePath& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
printf("set_multicycle_path %d ", cmd.mcp_value);
|
|
if(cmd.is_setup) {
|
|
printf("-setup ");
|
|
}
|
|
if(cmd.is_hold) {
|
|
printf("-hold ");
|
|
}
|
|
print_from_to_group(cmd.from, cmd.to);
|
|
printf("\n");
|
|
}
|
|
void set_clock_uncertainty(const SetClockUncertainty& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
printf("set_clock_uncertainty ");
|
|
if(cmd.is_setup) {
|
|
printf("-setup ");
|
|
}
|
|
if(cmd.is_hold) {
|
|
printf("-hold ");
|
|
}
|
|
print_from_to_group(cmd.from, cmd.to);
|
|
printf(" %f ", cmd.value);
|
|
printf("\n");
|
|
}
|
|
void set_clock_latency(const SetClockLatency& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
printf("set_clock_latency ");
|
|
if(cmd.type == ClockLatencyType::SOURCE) {
|
|
printf("-source ");
|
|
}
|
|
if(cmd.is_early) {
|
|
printf("-early ");
|
|
}
|
|
if(cmd.is_late) {
|
|
printf("-late ");
|
|
}
|
|
printf("%f ", cmd.value);
|
|
print_string_group(cmd.target_clocks);
|
|
printf("\n");
|
|
}
|
|
void set_disable_timing(const SetDisableTiming& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
printf("set_disable_timing ");
|
|
print_from_to_group(cmd.from, cmd.to);
|
|
printf("\n");
|
|
|
|
}
|
|
void set_timing_derate(const SetTimingDerate& cmd) override {
|
|
printf("#%s:%d\n", filename_.c_str(), lineno_);
|
|
printf("set_timing_derate ");
|
|
if(cmd.is_early) {
|
|
printf("-early ");
|
|
}
|
|
if(cmd.is_late) {
|
|
printf("-late ");
|
|
}
|
|
|
|
if(cmd.derate_nets) {
|
|
printf("-net_delay ");
|
|
}
|
|
if(cmd.derate_cells) {
|
|
printf("-cell_delay ");
|
|
}
|
|
printf("%f ", cmd.value);
|
|
print_string_group(cmd.cell_targets);
|
|
printf("\n");
|
|
}
|
|
|
|
//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, "Custom Error");
|
|
if(curr_lineno > 0) {
|
|
fprintf(stderr, " at line %d", curr_lineno);
|
|
}
|
|
if(near_text != "") {
|
|
if(near_text == "\n") {
|
|
fprintf(stderr, " near '\\n'");
|
|
} else if(near_text == "\n\r") {
|
|
fprintf(stderr, " near '\\n\\r'");
|
|
} else {
|
|
fprintf(stderr, " near '%s'", near_text.c_str());
|
|
}
|
|
}
|
|
fprintf(stderr, ": %s\n", msg.c_str());
|
|
error_ = true;
|
|
}
|
|
|
|
bool error() { return error_; }
|
|
|
|
private:
|
|
std::string filename_ = "";
|
|
int lineno_ = 0;
|
|
bool error_ = false;
|
|
|
|
};
|
|
|
|
int main(int argc, char **argv) {
|
|
if(argc != 2) {
|
|
fprintf(stderr, "Usage: %s filename.sdc\n", argv[0]);
|
|
fprintf(stderr, "\n");
|
|
fprintf(stderr, "Reads in an SDC file into internal data structures\n");
|
|
fprintf(stderr, "and then prints it out\n");
|
|
exit(1);
|
|
}
|
|
|
|
PrintCallback callback;
|
|
sdc_parse_filename(argv[1], callback);
|
|
|
|
if(callback.error()) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void print_string_group(const StringGroup& group) {
|
|
const char *start_token, *end_token;
|
|
if(group.type == StringGroupType::STRING) {
|
|
start_token = "{";
|
|
end_token = "}";
|
|
|
|
} else if (group.type == StringGroupType::CLOCK) {
|
|
start_token = "[get_clocks {";
|
|
end_token = "}]";
|
|
|
|
} else if (group.type == StringGroupType::PORT) {
|
|
start_token = "[get_ports {";
|
|
end_token = "}]";
|
|
|
|
} else if (group.type == StringGroupType::CELL) {
|
|
start_token = "[get_cells {";
|
|
end_token = "}]";
|
|
} else if (group.type == StringGroupType::PIN) {
|
|
start_token = "[get_pins {";
|
|
end_token = "}]";
|
|
|
|
} else {
|
|
printf("Unsupported sdc string group type\n");
|
|
exit(1);
|
|
}
|
|
|
|
if(!group.strings.empty()) {
|
|
printf("%s", start_token);
|
|
for(size_t i = 0; i < group.strings.size(); ++i) {
|
|
printf("%s", group.strings[i].c_str());
|
|
|
|
if(i != group.strings.size() - 1) {
|
|
printf(" ");
|
|
}
|
|
}
|
|
printf("%s", end_token);
|
|
}
|
|
}
|
|
|
|
void print_from_to_group(const StringGroup& from, const StringGroup& to) {
|
|
if(!from.strings.empty()) {
|
|
printf("-from ");
|
|
print_string_group(from);
|
|
}
|
|
|
|
if(!to.strings.empty()) {
|
|
printf(" -to ");
|
|
print_string_group(to);
|
|
}
|
|
}
|
|
|