Reading the printout.

This commit is contained in:
Alan Mishchenko 2025-11-10 22:00:07 -08:00
parent 1b7912a247
commit 169e288fc4
2 changed files with 126 additions and 16 deletions

View File

@ -321,11 +321,12 @@ usage:
******************************************************************************/
int Abc_CommandGenWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern int miniver_translate(const char *input, char *out, size_t cap);
extern int miniver_translate(const char *input, char *out, size_t cap, int fShort);
char * pFileName = NULL;
int fShort = 1;
int c, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Fvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "Fsvh" ) ) != EOF )
{
switch ( c )
{
@ -338,6 +339,9 @@ int Abc_CommandGenWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
pFileName = argv[globalUtilOptind];
globalUtilOptind++;
break;
case 's':
fShort ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
@ -355,7 +359,7 @@ int Abc_CommandGenWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
int Size = 10000;
char * pStr = argv[globalUtilOptind];
char * pOutStr = ABC_CALLOC( char, Size+1 );
int RetValue = miniver_translate( pStr, pOutStr, Size );
int RetValue = miniver_translate( pStr, pOutStr, Size, fShort );
if ( !RetValue ) {
if ( fVerbose )
printf( "Entered Verilog design:\n%s", pOutStr );
@ -387,10 +391,11 @@ int Abc_CommandGenWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
}
return 0;
usage:
Abc_Print( -2, "\nusage: %%gen [-F file] [-vh] \"<mini_verilog_string>\"\n" );
Abc_Print( -2, "\nusage: %%gen [-F file] [-svh] \"<mini_verilog_string>\"\n" );
Abc_Print( -2, "\t generates the design from a mini-Verilog string\n" );
Abc_Print( -2, "\t-F file : optional file name to save the design in standard Verilog [default = unused]\n" );
Abc_Print( -2, "\t-v (if a file name is provided, Verilog is dumped into a file and not read into ABC)\n" );
Abc_Print( -2, "\t (if a file name is provided, Verilog is dumped into a file and not read into ABC)\n" );
Abc_Print( -2, "\t-s : prints Verilog using a shorter format [default = %s]\n", fShort ? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\n" );
@ -2129,4 +2134,3 @@ usage:
ABC_NAMESPACE_IMPL_END

View File

@ -179,6 +179,67 @@ static int print_decl_to_buf(char **p, size_t *left, const char *kw, decl_t *arr
return 0;
}
static int print_decl_single(char **p, size_t *left, const char *kw, const decl_t *decl) {
if (out_cat(p, left, " %s ", kw)) return 1;
if (decl->is_signed) {
if (out_cat(p, left, "signed ")) return 1;
}
if (decl->width > 1) {
if (out_cat(p, left, "[%d:0] ", decl->width - 1)) return 1;
}
if (out_cat(p, left, "%s;\n", decl->name)) return 1;
return 0;
}
static int print_decl_with_assign(char **p, size_t *left, const char *kw, const decl_t *decl, const char *rhs) {
if (out_cat(p, left, " %s ", kw)) return 1;
if (decl->is_signed) {
if (out_cat(p, left, "signed ")) return 1;
}
if (decl->width > 1) {
if (out_cat(p, left, "[%d:0] ", decl->width - 1)) return 1;
}
if (out_cat(p, left, "%s = %s;\n", decl->name, rhs)) return 1;
return 0;
}
static int print_inputs_short(char **p, size_t *left, decl_t *arr, int n) {
for (int i = 0; i < n; ) {
int w = arr[i].width;
int sg = arr[i].is_signed;
if (out_cat(p, left, " input ")) return 1;
if (sg) {
if (out_cat(p, left, "signed ")) return 1;
}
if (w > 1) {
if (out_cat(p, left, "[%d:0] ", w - 1)) return 1;
}
int j = i;
while (j < n && arr[j].width == w && arr[j].is_signed == sg) {
if (out_cat(p, left, "%s%s", j == i ? "" : ", ", arr[j].name)) return 1;
++j;
}
if (out_cat(p, left, ";\n")) return 1;
i = j;
}
return 0;
}
static decl_t *find_decl_by_name(decl_t *arr, int n, const char *name) {
for (int i = 0; i < n; ++i) {
if (!strcmp(arr[i].name, name))
return &arr[i];
}
return NULL;
}
static int has_assignment(const mv_ctx *ctx, const char *name) {
for (int i = 0; i < ctx->na; ++i)
if (!strcmp(ctx->assigns[i].lhs, name))
return 1;
return 0;
}
// Add spaces around every alphanumeric/underscore sequence for readability.
// Example: "a*b+16'b0" -> " a * b + 16 ' b0 "
static void format_rhs_readable(const char *in, char *out, size_t cap) {
@ -206,6 +267,20 @@ static void format_rhs_readable(const char *in, char *out, size_t cap) {
if (o < cap) out[o] = 0; else if (cap) out[cap-1] = 0;
}
static void trim_spaces(char *s) {
if (!s) return;
char *start = s;
while (*start && isspace((unsigned char)*start))
++start;
char *end = start + strlen(start);
while (end > start && isspace((unsigned char)*(end - 1)))
--end;
size_t len = (size_t)(end - start);
if (start != s)
memmove(s, start, len);
s[len] = 0;
}
// -----------------------------------------------------------------------------
// Parsing helpers that quote offending clauses
// -----------------------------------------------------------------------------
@ -380,7 +455,7 @@ lhs_done:;
// Translate a raw mini-Verilog string 'input' into standard Verilog.
// The function strips whitespace internally, parses, and writes into 'out' (cap bytes).
// Returns 0 on success, 1 on error. Errors are printed (no exit()).
int miniver_translate(const char *input, char *out, size_t cap) {
int miniver_translate(const char *input, char *out, size_t cap, int fShort) {
if (!input || !out || cap == 0) {
printf("Invalid arguments.\n");
return 1;
@ -458,15 +533,47 @@ int miniver_translate(const char *input, char *out, size_t cap) {
free(ctx); return 1;
}
if (print_decl_to_buf(&p, &left, "input", ctx->inputs, ctx->ni)) { free(ctx); return 1; }
if (print_decl_to_buf(&p, &left, "output", ctx->outputs, ctx->no)) { free(ctx); return 1; }
if (print_decl_to_buf(&p, &left, "wire", ctx->wires, ctx->nw)) { free(ctx); return 1; }
if (!fShort) {
if (print_decl_to_buf(&p, &left, "input", ctx->inputs, ctx->ni)) { free(ctx); return 1; }
if (print_decl_to_buf(&p, &left, "output", ctx->outputs, ctx->no)) { free(ctx); return 1; }
if (print_decl_to_buf(&p, &left, "wire", ctx->wires, ctx->nw)) { free(ctx); return 1; }
for (int i = 0; i < ctx->na; ++i) {
char rhs_sp[8192];
format_rhs_readable(ctx->assigns[i].rhs, rhs_sp, sizeof(rhs_sp));
if (out_cat(&p, &left, " assign %s = %s;\n", ctx->assigns[i].lhs, rhs_sp)) {
free(ctx); return 1;
char rhs_sp[8192];
format_rhs_readable(ctx->assigns[i].rhs, rhs_sp, sizeof(rhs_sp));
if (out_cat(&p, &left, " assign %s = %s;\n", ctx->assigns[i].lhs, rhs_sp)) {
free(ctx); return 1;
}
}
} else {
if (print_inputs_short(&p, &left, ctx->inputs, ctx->ni)) { free(ctx); return 1; }
for (int i = 0; i < ctx->nw; ++i) {
if (has_assignment(ctx, ctx->wires[i].name))
continue;
if (print_decl_single(&p, &left, "wire", &ctx->wires[i])) {
free(ctx); return 1;
}
}
for (int i = 0; i < ctx->na; ++i) {
char rhs_sp[8192];
format_rhs_readable(ctx->assigns[i].rhs, rhs_sp, sizeof(rhs_sp));
trim_spaces(rhs_sp);
const char *kw = "wire";
decl_t *decl = find_decl_by_name(ctx->outputs, ctx->no, ctx->assigns[i].lhs);
if (decl) {
kw = "output";
} else {
decl = find_decl_by_name(ctx->wires, ctx->nw, ctx->assigns[i].lhs);
}
if (decl) {
if (print_decl_with_assign(&p, &left, kw, decl, rhs_sp)) {
free(ctx); return 1;
}
} else {
if (out_cat(&p, &left, " assign %s = %s;\n", ctx->assigns[i].lhs, rhs_sp)) {
free(ctx); return 1;
}
}
}
}
if (out_cat(&p, &left, "endmodule\n")) {
@ -506,7 +613,7 @@ int main(int argc, char **argv) {
}
char out[10240];
int rc = miniver_translate(in, out, sizeof(out));
int rc = miniver_translate(in, out, sizeof(out), 0);
if (!rc) {
printf("%s", out);
}
@ -520,4 +627,3 @@ int main(int argc, char **argv) {
ABC_NAMESPACE_IMPL_END