Skip to content

Commit

Permalink
Add SDF parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Blebowski authored and nickg committed Sep 15, 2024
1 parent cab979f commit 736d099
Show file tree
Hide file tree
Showing 46 changed files with 3,581 additions and 14 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ include thirdparty/Makemodule.am
include src/Makemodule.am
include src/cov/Makemodule.am
include src/psl/Makemodule.am
include src/sdf/Makemodule.am
include src/rt/Makemodule.am
include src/jit/Makemodule.am
include src/vhpi/Makemodule.am
Expand Down
14 changes: 14 additions & 0 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include "thread.h"
#include "type.h"
#include "vlog/vlog-phase.h"
#include "sdf/sdf-phase.h"
#include "sdf/sdf-util.h"

#include <assert.h>
#include <ctype.h>
Expand Down Expand Up @@ -2485,6 +2487,18 @@ void analyse_file(const char *file, jit_t *jit, unit_registry_t *ur)
}
}
break;

case SOURCE_SDF:
{
sdf_file_t *sdf_file = sdf_parse(file, 0);
progress("analysed SDF file: %s", file);

if (sdf_file != NULL) {
warnf("SDF is not yet supported");
sdf_file_free(sdf_file);
}
}
break;
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/elab.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef struct _elab_ctx {
unit_registry_t *registry;
lower_unit_t *lowered;
cover_data_t *cover;
sdf_file_t *sdf;
void *context;
driver_set_t *drivers;
hash_t *modcache;
Expand Down Expand Up @@ -1397,6 +1398,7 @@ static void elab_inherit_context(elab_ctx_t *ctx, const elab_ctx_t *parent)
ctx->library = ctx->library ?: parent->library;
ctx->out = ctx->out ?: parent->out;
ctx->cover = parent->cover;
ctx->sdf = parent->sdf;
ctx->inst = ctx->inst ?: parent->inst;
ctx->modcache = parent->modcache;
ctx->depth = parent->depth + 1;
Expand Down Expand Up @@ -2246,7 +2248,8 @@ void elab_set_generic(const char *name, const char *value)
generic_override = new;
}

tree_t elab(object_t *top, jit_t *jit, unit_registry_t *ur, cover_data_t *cover)
tree_t elab(object_t *top, jit_t *jit, unit_registry_t *ur, cover_data_t *cover,
sdf_file_t *sdf)
{
make_new_arena();

Expand Down Expand Up @@ -2276,6 +2279,7 @@ tree_t elab(object_t *top, jit_t *jit, unit_registry_t *ur, cover_data_t *cover)
.cover = cover,
.library = work,
.jit = jit,
.sdf = sdf,
.registry = ur,
.modcache = hash_new(16),
.dotted = lib_name(work),
Expand Down
170 changes: 169 additions & 1 deletion src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ VHDL_ID ({LOWER}|{UPPER})(_?({LOWER}|{UPPER}|[0-9]))*
BAD_ID ({LOWER}|{UPPER}|_)({LOWER}|{UPPER}|[0-9_])*
EXID \\([^\\\n]|\\\\)*\\
VLOG_ID [a-zA-Z_]([a-zA-Z0-9_$])*
/* TODO: Add "escaped_character" handling to SDF ID */
/* TODO: According to spec, identifier could even start with number*/
SDF_ID ([a-zA-Z$_])([a-zA-Z$_0-9])*
SYSTASK \$[a-zA-Z_$]([a-zA-Z0-9_$])*
STRING (\"([^\"\n]|\"\")*\")|(\%([^\"\n\%]|\%\%)*\%)
BADSTRING (\"([^\"\n]|\"\")*)|(\%([^\"\n\%]|\%\%)*)
Expand Down Expand Up @@ -129,8 +132,10 @@ VLOG_NUMBER {INTEGER}?\'[bhd]{HEX}
UDP_LEVEL [01xX?bB]
UDP_EDGE [rRfFpPnN*]
UDP_INDICATOR "("{UDP_LEVEL}{UDP_LEVEL}")"
SCALAR_ZERO ('b0|'B0|1'b0|1'B0)
SCALAR_ONE ('b1|'B1|1'b1|1'B1)

%x COMMENT C_COMMENT PSL VLOG UDP
%x COMMENT C_COMMENT PSL VLOG UDP SDF SDF_EXPR

ENTITY ?i:entity
IS ?i:is
Expand Down Expand Up @@ -274,6 +279,59 @@ NONDET ?i:nondet
NONDET_V ?i:nondet_vector
UNION ?i:union

INTERCONNECT ?i:interconnect
DELAYFILE ?i:delayfile
SDFVERSION ?i:sdfversion
DESIGN ?i:design
DATE ?i:date
VENDOR ?i:vendor
PROGRAM ?i:program
VERSION ?i:version
DIVIDER ?i:divider
VOLTAGE ?i:voltage
TEMPERATURE ?i:temperature
TIMESCALE ?i:timescale
CELL ?i:cell
CELLTYPE ?i:celltype
INSTANCE ?i:instance
ABSOLUTE ?i:absolute
PATHPULSE ?i:pathpulse
PATHPULSEP ?i:pathpulsepercent
INCREMENT ?i:increment
IOPATH ?i:iopath
DELAY ?i:delay
SETUP ?i:setup
HOLD ?i:hold
SETUPHOLD ?i:setuphold
RECOVERY ?i:recovery
REMOVAL ?i:removal
RECREM ?i:recrem
WIDTH ?i:width
PERIOD ?i:period
SKEW ?i:skew
BIDIRSKEW ?i:bidirectskew
NOCHANGE ?i:nochange
NETDELAY ?i:netdelay
DEVICE ?i:device
COND ?i:cond
CONDELSE ?i:condelse
PATHCONSTRAINT ?i:PATHCONSTRAINT
PERIODCONSTRAINT ?i:PERIODCONSTRAINT
SUM ?i:SUM
DIFF ?i:DIFF
SKEWCONSTRAINT ?i:SKEWCONSTRAINT
ARRIVAL ?i:ARRIVAL
DEPARTURE ?i:DEPARTURE
SLACK ?i:SLACK
WAVEFORM ?i:WAVEFORM
NAME ?i:NAME
EXCEPTION ?i:EXCEPTION
TIMINGCHECK ?i:TIMINGCHECK
TIMINGENV ?i:TIMINGENV
RETAIN ?i:RETAIN
SCOND ?i:SCOND
CCOND ?i:CCOND

%%

{SYNTH_OFF} { TOKEN(tSYNTHOFF); }
Expand Down Expand Up @@ -614,6 +672,106 @@ UNION ?i:union
<PSL>{SEVERITY} { TOKEN(tSEVERITY); }
<PSL>{REPORT} { TOKEN(tREPORT); }


% /* SDF rules separated from rest for better maintainability */

% /* SDF hierarchical_identifier may conflict with SDF keywords ->
Must be scanned in separate mode! Tokens that may be lookahead
after an identifier must be scanned too. */
<SDF,SDF_EXPR>"!" { TOKEN(tBANG); }
<SDF,SDF_EXPR>{TICK} { TOKEN(tTICK); }
<SDF,SDF_EXPR>"<<" { TOKEN(tLTLT); }
<SDF,SDF_EXPR>">>" { TOKEN(tGTGT); }
<SDF,SDF_EXPR>"<=" { TOKEN(tLE); }
<SDF,SDF_EXPR>">=" { TOKEN(tGE); }
<SDF,SDF_EXPR>"&&" { TOKEN(tDBLAMP); }
<SDF,SDF_EXPR>"~&" { TOKEN(tTILDEAMP); }
<SDF,SDF_EXPR>"~|" { TOKEN(tTILDEBAR); }
<SDF,SDF_EXPR>"^~" { TOKEN(tTILDECARET); }
<SDF,SDF_EXPR>"~^" { TOKEN(tTILDECARET); }
<SDF,SDF_EXPR>"%" { TOKEN(tPERCENT); }
<SDF,SDF_EXPR>"||" { TOKEN(tLOGOR); }
<SDF,SDF_EXPR>"^" { TOKEN(tCARET); }
<SDF,SDF_EXPR>"==" { TOKEN(tLOGEQ); }
<SDF,SDF_EXPR>"!=" { TOKEN(tLOGNEQ); }
<SDF,SDF_EXPR>"===" { TOKEN(tCASEEQ); }
<SDF,SDF_EXPR>"!==" { TOKEN(tCASENEQ); }

<SDF,SDF_EXPR>"//" { comment_caller = YY_START; BEGIN(COMMENT); }
<SDF,SDF_EXPR>"/*" { comment_caller = YY_START;
BEGIN(C_COMMENT);
}

<SDF,SDF_EXPR>{SCALAR_ZERO} { TOKEN(tSCALARZERO); }
<SDF,SDF_EXPR>{SCALAR_ONE} { TOKEN(tSCALARONE); }

% /* TODO: Crosscheck SDF definition of decimal */
<SDF,SDF_EXPR>{DECIMAL} { return parse_decimal_literal(yytext); }

% /* VLOG_STRING is defined almost equally as SDF qstring */
<SDF>{VLOG_STRING} { return parse_string(yytext); }

<SDF>{DELAYFILE} { TOKEN(tDELAYFILE); }
<SDF>{SDFVERSION} { TOKEN(tSDFVERSION); }
<SDF>{DESIGN} { TOKEN(tDESIGN); }
<SDF>{DATE} { TOKEN(tDATE); }
<SDF>{VENDOR} { TOKEN(tVENDOR); }
<SDF>{PROGRAM} { TOKEN(tPROGRAM); }
<SDF>{VERSION} { TOKEN(tVERSION); }
<SDF>{DIVIDER} { TOKEN(tDIVIDER); }
<SDF>{VOLTAGE} { TOKEN(tVOLTAGE); }
<SDF>{PROCESS} { TOKEN(tPROCESS); }
<SDF>{TEMPERATURE} { TOKEN(tTEMPERATURE); }
<SDF>{TIMESCALE} { TOKEN(tTIMESCALE); }
<SDF>{CELL} { TOKEN(tCELL); }
<SDF>{CELLTYPE} { TOKEN(tCELLTYPE); }
<SDF>{INSTANCE} { TOKEN(tINSTANCE); }
<SDF>{DELAY} { TOKEN(tDELAY); }
<SDF>{ABSOLUTE} { TOKEN(tABSOLUTE); }
<SDF>{PATHPULSE} { TOKEN(tPATHPULSE); }
<SDF>{PATHPULSEP} { TOKEN(tPATHPULSEP); }
<SDF>{INCREMENT} { TOKEN(tINCREMENT); }
<SDF>{IOPATH} { TOKEN(tIOPATH); }
<SDF>"posedge" { TOKEN(tPOSEDGE); }
<SDF>"negedge" { TOKEN(tNEGEDGE); }
<SDF>{SETUP} { TOKEN(tSETUP); }
<SDF>{HOLD} { TOKEN(tHOLD); }
<SDF>{SETUPHOLD} { TOKEN(tSETUPHOLD); }
<SDF>{RECOVERY} { TOKEN(tRECOVERY); }
<SDF>{REMOVAL} { TOKEN(tREMOVAL); }
<SDF>{RECREM} { TOKEN(tRECREM); }
<SDF>{WIDTH} { TOKEN(tWIDTH); }
<SDF>{PERIOD} { TOKEN(tPERIOD); }
<SDF>{SKEW} { TOKEN(tSKEW); }
<SDF>{BIDIRSKEW} { TOKEN(tBIDIRSKEW); }
<SDF>{NOCHANGE} { TOKEN(tNOCHANGE); }
<SDF>{PORT} { TOKEN(tPORT); }
<SDF>{INTERCONNECT} { TOKEN(tINTERCONNECT); }
<SDF>{NETDELAY} { TOKEN(tNETDELAY); }
<SDF>{DEVICE} { TOKEN(tDEVICE); }
<SDF>{COND} { TOKEN(tSDFCOND); }
<SDF>{CONDELSE} { TOKEN(tSDFCONDELSE); }
<SDF>{PATHCONSTRAINT} { TOKEN(tPATHCONSTR); }
<SDF>{PERIODCONSTRAINT} { TOKEN(tPERIODCONSTR); }
<SDF>{SUM} { TOKEN(tSUM); }
<SDF>{DIFF} { TOKEN(tDIFF); }
<SDF>{SKEWCONSTRAINT} { TOKEN(tSKEWCONSTR); }
<SDF>{ARRIVAL} { TOKEN(tARRIVAL); }
<SDF>{DEPARTURE} { TOKEN(tDEPARTURE); }
<SDF>{SLACK} { TOKEN(tSLACK); }
<SDF>{WAVEFORM} { TOKEN(tWAVEFORM); }
<SDF>{NAME} { TOKEN(tNAME); }
<SDF>{EXCEPTION} { TOKEN(tEXCEPTION); }
<SDF>{LABEL} { TOKEN(tLABEL); }
<SDF>{TIMINGCHECK} { TOKEN(tTIMINGCHECK); }
<SDF>{TIMINGENV} { TOKEN(tTIMINGENV); }
<SDF>{RETAIN} { TOKEN(tRETAIN); }
<SDF>{SCOND} { TOKEN(tSCOND); }
<SDF>{CCOND} { TOKEN(tCCOND); }

<SDF,SDF_EXPR>{SDF_ID} { yylval.str = xstrdup(yytext); TOKEN(tID); }


<INITIAL,PSL>{UTF8_MB} { warn_utf8(yytext); REJECT; }

<INITIAL,PSL>{VHDL_ID} { return parse_id(yytext); }
Expand Down Expand Up @@ -951,6 +1109,16 @@ void scan_as_udp(void)
BEGIN(UDP);
}

void scan_as_sdf(void)
{
BEGIN(SDF);
}

void scan_as_sdf_expr(void)
{
BEGIN(SDF_EXPR);
}

bool is_scanned_as_psl(void)
{
return (YY_START == PSL);
Expand Down
14 changes: 11 additions & 3 deletions src/nvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "common.h"
#include "cov/cov-api.h"
#include "diag.h"
#include "eval.h"
#include "jit/jit-llvm.h"
#include "jit/jit.h"
#include "lib.h"
Expand Down Expand Up @@ -365,6 +364,7 @@ static int elaborate(int argc, char **argv, cmd_state_t *state)
{ "dump-vcode", optional_argument, 0, 'v' },
{ "cover", optional_argument, 0, 'c' },
{ "cover-spec", required_argument, 0, 's' },
{ "sdf", required_argument, 0, 'f' },
{ "verbose", no_argument, 0, 'V' },
{ "no-save", no_argument, 0, 'N' },
{ "jit", no_argument, 0, 'j' },
Expand All @@ -374,7 +374,7 @@ static int elaborate(int argc, char **argv, cmd_state_t *state)

bool use_jit = DEFAULT_JIT, no_save = false;
cover_mask_t cover_mask = 0;
char *cover_spec_file = NULL;
char *cover_spec_file = NULL, *sdf_args = NULL;
int cover_array_limit = 0;
const int next_cmd = scan_cmd(2, argc, argv);
int c, index = 0;
Expand Down Expand Up @@ -415,6 +415,9 @@ static int elaborate(int argc, char **argv, cmd_state_t *state)
case 's':
cover_spec_file = optarg;
break;
case 'f':
sdf_args = optarg;
break;
case 0:
// Set a flag
break;
Expand Down Expand Up @@ -448,6 +451,11 @@ static int elaborate(int argc, char **argv, cmd_state_t *state)
cover_load_spec_file(cover, cover_spec_file);
}

if (sdf_args != NULL) {
// TODO: Pass min-max spec to underlying sdf_parse somehow
analyse_file(sdf_args, NULL, NULL);
}

if (state->registry != NULL) {
unit_registry_free(state->registry);
state->registry = NULL;
Expand All @@ -463,7 +471,7 @@ static int elaborate(int argc, char **argv, cmd_state_t *state)

jit_enable_runtime(state->jit, false);

tree_t top = elab(obj, state->jit, state->registry, cover);
tree_t top = elab(obj, state->jit, state->registry, cover, NULL);
if (top == NULL)
return EXIT_FAILURE;

Expand Down
2 changes: 1 addition & 1 deletion src/phase.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void bounds_check(tree_t top);

// Elaborate a top level design unit
tree_t elab(object_t *top, jit_t *jit, unit_registry_t *ur,
cover_data_t *cover);
cover_data_t *cover, sdf_file_t *sdf);

// Set the value of a top-level generic
void elab_set_generic(const char *name, const char *value);
Expand Down
1 change: 1 addition & 0 deletions src/prim.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef struct _ident *ident_t;
typedef struct _tree *tree_t;
typedef struct _type *type_t;
typedef struct _vlog_node *vlog_node_t;
typedef struct _sdf_file sdf_file_t;
typedef struct loc loc_t;
typedef struct _fbuf fbuf_t;
typedef struct _hash hash_t;
Expand Down
2 changes: 1 addition & 1 deletion src/rt/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ static int shell_cmd_elaborate(ClientData cd, Tcl_Interp *interp,

jit_enable_runtime(sh->jit, false);

tree_t top = elab(tree_to_object(unit), sh->jit, sh->registry, NULL);
tree_t top = elab(tree_to_object(unit), sh->jit, sh->registry, NULL, NULL);
if (top == NULL)
return TCL_ERROR;

Expand Down
Loading

0 comments on commit 736d099

Please sign in to comment.