Fix scan_gates to consider correctly gates with an inverted output. Refactor the checks in infix_to_postfix for invalid postfix expressions.
This commit is contained in:
parent
0ec0c92eae
commit
d002ba353b
|
|
@ -569,11 +569,22 @@ static void move_inputs(struct gate_data *curr, struct gate_data *prev)
|
||||||
prev->finished = TRUE;
|
prev->finished = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scan_gates(DSTRING *lhs)
|
static void scan_gates(DSTRING *lhs, int optimize)
|
||||||
{
|
{
|
||||||
struct gate_data *current = NULL, *previous = NULL, *last_curr = NULL;
|
struct gate_data *current = NULL, *previous = NULL, *last_curr = NULL;
|
||||||
struct gate_data *prev = NULL;
|
struct gate_data *prev = NULL;
|
||||||
|
|
||||||
|
if (optimize < 1) {
|
||||||
|
current = last_gate;
|
||||||
|
if (ds_get_length(lhs) > 0) {
|
||||||
|
assert(current->finished == FALSE);
|
||||||
|
tfree(current->outp);
|
||||||
|
current->outp = TMALLOC(char, ds_get_length(lhs) + 1);
|
||||||
|
strcpy(current->outp, ds_get_buf(lhs));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
current = first_gate;
|
current = first_gate;
|
||||||
while (current) {
|
while (current) {
|
||||||
int is_gate = (current->type == '&'
|
int is_gate = (current->type == '&'
|
||||||
|
|
@ -581,7 +592,8 @@ static void scan_gates(DSTRING *lhs)
|
||||||
|| current->type == '|');
|
|| current->type == '|');
|
||||||
previous = current->prev;
|
previous = current->prev;
|
||||||
if (is_gate && current->is_possible) {
|
if (is_gate && current->is_possible) {
|
||||||
if (previous && previous->type == current->type) {
|
if (previous && previous->type == current->type
|
||||||
|
&& previous->is_not == current->is_not) {
|
||||||
if (eq(current->ins->name, previous->outp)) {
|
if (eq(current->ins->name, previous->outp)) {
|
||||||
move_inputs(current, previous);
|
move_inputs(current, previous);
|
||||||
}
|
}
|
||||||
|
|
@ -608,6 +620,7 @@ static void scan_gates(DSTRING *lhs)
|
||||||
prev = current->prev;
|
prev = current->prev;
|
||||||
while (prev) {
|
while (prev) {
|
||||||
if (prev->type == current->type
|
if (prev->type == current->type
|
||||||
|
&& prev->is_not == current->is_not
|
||||||
&& prev->finished == FALSE
|
&& prev->finished == FALSE
|
||||||
&& strncmp(prev->outp, TMP_PREFIX, TMP_LEN) == 0
|
&& strncmp(prev->outp, TMP_PREFIX, TMP_LEN) == 0
|
||||||
&& eq(current->ins->name, prev->outp)) {
|
&& eq(current->ins->name, prev->outp)) {
|
||||||
|
|
@ -748,36 +761,44 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p)
|
||||||
nlist = add_name_entry("first", NULL);
|
nlist = add_name_entry("first", NULL);
|
||||||
ds_clear(postfix_p);
|
ds_clear(postfix_p);
|
||||||
while ( ( ltok = lexer_scan(lx) ) != 0 ) { // start while ltok loop
|
while ( ( ltok = lexer_scan(lx) ) != 0 ) { // start while ltok loop
|
||||||
if (ltok == LEX_ID && last_tok == LEX_ID) {
|
if (last_tok == -1) { // check starting token
|
||||||
fprintf(stderr, "ERROR (1) no gate operator between two identifiers\n");
|
if (!(ltok == LEX_ID || ltok == '~' || ltok == '(')) {
|
||||||
|
fprintf(stderr, "ERROR (1) invalid starting token\n");
|
||||||
status = 1;
|
status = 1;
|
||||||
goto err_return;
|
goto err_return;
|
||||||
}
|
}
|
||||||
if (lex_gate_op(ltok)) {
|
} else {
|
||||||
if (lex_gate_op(last_tok)) {
|
if (last_tok == LEX_ID) { // check follower of an ID
|
||||||
fprintf(stderr, "ERROR (2) two consecutive gate operators\n");
|
if (!(lex_gate_op(ltok) || ltok == ')')) {
|
||||||
|
fprintf(stderr, "ERROR (2) incorrect token after ID\n");
|
||||||
status = 1;
|
status = 1;
|
||||||
goto err_return;
|
goto err_return;
|
||||||
} else if (last_tok != LEX_ID && last_tok != ')') {
|
}
|
||||||
fprintf(stderr, "ERROR (2a) gate operator not after ID or rparen\n");
|
} else if (lex_gate_op(last_tok)) { // check follower of a gate op
|
||||||
|
if (!(ltok == LEX_ID || ltok == '~' || ltok == '(')) {
|
||||||
|
fprintf(stderr, "ERROR (3) incorrect token after gate op\n");
|
||||||
|
status = 1;
|
||||||
|
goto err_return;
|
||||||
|
}
|
||||||
|
} else if (last_tok == '~') { // check follower of ~
|
||||||
|
if (!(ltok == LEX_ID || ltok == '(')) {
|
||||||
|
fprintf(stderr, "ERROR (4) incorrect token after \'~\'\n");
|
||||||
|
status = 1;
|
||||||
|
goto err_return;
|
||||||
|
}
|
||||||
|
} else if (last_tok == '(') { // check follower of lparen
|
||||||
|
if (!(ltok == LEX_ID || ltok == '~' || ltok == '(')) {
|
||||||
|
fprintf(stderr, "ERROR (5) incorrect token after lparen\n");
|
||||||
|
status = 1;
|
||||||
|
goto err_return;
|
||||||
|
}
|
||||||
|
} else if (last_tok == ')') { // check follower of rparen
|
||||||
|
if (!(ltok == ')' || lex_gate_op(ltok))) {
|
||||||
|
fprintf(stderr, "ERROR (6) incorrect token after rparen\n");
|
||||||
status = 1;
|
status = 1;
|
||||||
goto err_return;
|
goto err_return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (last_tok == '~' && ltok != LEX_ID && ltok != '(') {
|
|
||||||
fprintf(stderr, "ERROR (3) \'~\' is not followed by an ID or lparen\n");
|
|
||||||
status = 1;
|
|
||||||
goto err_return;
|
|
||||||
}
|
|
||||||
if (ltok == '~' && (last_tok == LEX_ID || last_tok == ')')) {
|
|
||||||
fprintf(stderr, "ERROR (4) \'~\' follows an ID or rparen\n");
|
|
||||||
status = 1;
|
|
||||||
goto err_return;
|
|
||||||
}
|
|
||||||
if (ltok == ')' && (lex_gate_op(last_tok) || last_tok == '~')) {
|
|
||||||
fprintf(stderr, "ERROR (5) incomplete infix sub-expression\n");
|
|
||||||
status = 1;
|
|
||||||
goto err_return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
last_tok = ltok;
|
last_tok = ltok;
|
||||||
|
|
@ -797,6 +818,11 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p)
|
||||||
}
|
}
|
||||||
} else if (ltok == ')') {
|
} else if (ltok == ')') {
|
||||||
rparen_count++;
|
rparen_count++;
|
||||||
|
if (rparen_count > lparen_count) {
|
||||||
|
fprintf(stderr, "ERROR (9a) mismatched rparen\n");
|
||||||
|
status = 1;
|
||||||
|
goto err_return;
|
||||||
|
}
|
||||||
while ( stack.top != -1 && !eq(stack.array[stack.top], "(") ) {
|
while ( stack.top != -1 && !eq(stack.array[stack.top], "(") ) {
|
||||||
ds_cat_printf(postfix_p, " %s", pop(&stack, &status));
|
ds_cat_printf(postfix_p, " %s", pop(&stack, &status));
|
||||||
if (status) {
|
if (status) {
|
||||||
|
|
@ -832,19 +858,19 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p)
|
||||||
goto err_return;
|
goto err_return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "ERROR (6) unexpected infix token %d \'%s\'\n",
|
fprintf(stderr, "ERROR (7) unexpected infix token %d \'%s\'\n",
|
||||||
ltok, lx->lexer_buf);
|
ltok, lx->lexer_buf);
|
||||||
status = 1;
|
status = 1;
|
||||||
goto err_return;
|
goto err_return;
|
||||||
}
|
}
|
||||||
} // end while ltok loop
|
} // end while ltok loop
|
||||||
if (lex_gate_op(last_tok) || last_tok == '~') {
|
if (lex_gate_op(last_tok) || last_tok == '~') {
|
||||||
fprintf(stderr, "ERROR (7) incomplete infix expression\n");
|
fprintf(stderr, "ERROR (8) incomplete infix expression\n");
|
||||||
status = 1;
|
status = 1;
|
||||||
goto err_return;
|
goto err_return;
|
||||||
}
|
}
|
||||||
if (lparen_count != rparen_count) {
|
if (lparen_count != rparen_count) {
|
||||||
fprintf(stderr, "ERROR (8) mismatched parentheses\n");
|
fprintf(stderr, "ERROR (9) mismatched parentheses\n");
|
||||||
status = 1;
|
status = 1;
|
||||||
goto err_return;
|
goto err_return;
|
||||||
}
|
}
|
||||||
|
|
@ -966,7 +992,7 @@ err_return:
|
||||||
/* Start of logicexp parser */
|
/* Start of logicexp parser */
|
||||||
static void aerror(char *s);
|
static void aerror(char *s);
|
||||||
static BOOL amatch(int t);
|
static BOOL amatch(int t);
|
||||||
static BOOL bparse(char *line, BOOL new_lexer);
|
static BOOL bparse(char *line, BOOL new_lexer, int optimize);
|
||||||
|
|
||||||
static int lookahead = 0;
|
static int lookahead = 0;
|
||||||
static int number_of_instances = 0;
|
static int number_of_instances = 0;
|
||||||
|
|
@ -1061,7 +1087,7 @@ static BOOL amatch(int t)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL bstmt_postfix(void)
|
static BOOL bstmt_postfix(int optimize)
|
||||||
{
|
{
|
||||||
/* A stmt is: output_name_id = '{' expr '}' */
|
/* A stmt is: output_name_id = '{' expr '}' */
|
||||||
DS_CREATE(lhs, 32);
|
DS_CREATE(lhs, 32);
|
||||||
|
|
@ -1113,7 +1139,7 @@ static BOOL bstmt_postfix(void)
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
goto bail_out;
|
goto bail_out;
|
||||||
}
|
}
|
||||||
scan_gates(&lhs);
|
scan_gates(&lhs, optimize);
|
||||||
gen_scanned_gates(first_gate);
|
gen_scanned_gates(first_gate);
|
||||||
lookahead = lex_scan();
|
lookahead = lex_scan();
|
||||||
while (lookahead != '}') {
|
while (lookahead != '}') {
|
||||||
|
|
@ -1156,7 +1182,7 @@ static char *get_logicexp_tmodel_delays(
|
||||||
return ds_get_buf(mname);
|
return ds_get_buf(mname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL bparse(char *line, BOOL new_lexer)
|
static BOOL bparse(char *line, BOOL new_lexer, int optimize)
|
||||||
{
|
{
|
||||||
BOOL ret_val = TRUE;
|
BOOL ret_val = TRUE;
|
||||||
DS_CREATE(stmt, LEX_BUF_SZ);
|
DS_CREATE(stmt, LEX_BUF_SZ);
|
||||||
|
|
@ -1171,7 +1197,7 @@ static BOOL bparse(char *line, BOOL new_lexer)
|
||||||
while (lookahead != '\0') {
|
while (lookahead != '\0') {
|
||||||
ds_clear(&stmt);
|
ds_clear(&stmt);
|
||||||
ds_cat_str(&stmt, parse_lexer->lexer_buf);
|
ds_cat_str(&stmt, parse_lexer->lexer_buf);
|
||||||
if (!bstmt_postfix()) {
|
if (!bstmt_postfix(optimize)) {
|
||||||
cleanup_parser();
|
cleanup_parser();
|
||||||
ret_val= FALSE;
|
ret_val= FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1233,8 +1259,9 @@ static BOOL expect_token(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL f_logicexp(char *line)
|
BOOL f_logicexp(char *line, int optimize)
|
||||||
{
|
{
|
||||||
|
/* If optimize > 0 then perform optimizations in scan_gates */
|
||||||
int t, num_ins = 0, num_outs = 0, i;
|
int t, num_ins = 0, num_outs = 0, i;
|
||||||
char *endp;
|
char *endp;
|
||||||
BOOL ret_val = TRUE;
|
BOOL ret_val = TRUE;
|
||||||
|
|
@ -1319,7 +1346,7 @@ BOOL f_logicexp(char *line)
|
||||||
}
|
}
|
||||||
(void) add_sym_tab_entry(parse_lexer->lexer_buf,
|
(void) add_sym_tab_entry(parse_lexer->lexer_buf,
|
||||||
SYM_TMODEL, &parse_lexer->lexer_sym_tab);
|
SYM_TMODEL, &parse_lexer->lexer_sym_tab);
|
||||||
ret_val = bparse(line, FALSE);
|
ret_val = bparse(line, FALSE, optimize);
|
||||||
|
|
||||||
current_lexer = NULL;
|
current_lexer = NULL;
|
||||||
if (!ret_val) {
|
if (!ret_val) {
|
||||||
|
|
|
||||||
|
|
@ -280,6 +280,7 @@ static int ps_udevice_msgs = 0; // Controls the verbosity of U* warnings
|
||||||
If ps_udevice_exit is non-zero then exit when u_process_instance fails
|
If ps_udevice_exit is non-zero then exit when u_process_instance fails
|
||||||
*/
|
*/
|
||||||
static int ps_udevice_exit = 0;
|
static int ps_udevice_exit = 0;
|
||||||
|
static int ps_scan_gates_optimize = 1; // Allow optimization in scan_gates
|
||||||
static int ps_tpz_delays = 0; // For tristate delays
|
static int ps_tpz_delays = 0; // For tristate delays
|
||||||
static int ps_with_inverters = 0; // For ff/latch control inputs
|
static int ps_with_inverters = 0; // For ff/latch control inputs
|
||||||
static int ps_with_tri_inverters = 0; // For inv3/inv3a data inputs
|
static int ps_with_tri_inverters = 0; // For inv3/inv3a data inputs
|
||||||
|
|
@ -965,6 +966,9 @@ void initialize_udevice(char *subckt_line)
|
||||||
if (!cp_getvar("ps_udevice_exit", CP_NUM, &ps_udevice_exit, 0)) {
|
if (!cp_getvar("ps_udevice_exit", CP_NUM, &ps_udevice_exit, 0)) {
|
||||||
ps_udevice_exit = 0;
|
ps_udevice_exit = 0;
|
||||||
}
|
}
|
||||||
|
if (!cp_getvar("ps_scan_gates_optimize", CP_NUM, &ps_scan_gates_optimize, 0)) {
|
||||||
|
ps_scan_gates_optimize = 1;
|
||||||
|
}
|
||||||
/* If non-zero use inverters with ff/latch control inputs */
|
/* If non-zero use inverters with ff/latch control inputs */
|
||||||
if (!cp_getvar("ps_with_inverters", CP_NUM, &ps_with_inverters, 0)) {
|
if (!cp_getvar("ps_with_inverters", CP_NUM, &ps_with_inverters, 0)) {
|
||||||
ps_with_inverters = 0;
|
ps_with_inverters = 0;
|
||||||
|
|
@ -4318,7 +4322,7 @@ BOOL u_process_instance(char *nline)
|
||||||
if (ps_ports_and_pins & 4) {
|
if (ps_ports_and_pins & 4) {
|
||||||
printf("TRANS_IN %s\n", nline);
|
printf("TRANS_IN %s\n", nline);
|
||||||
}
|
}
|
||||||
behav_ret = f_logicexp(nline);
|
behav_ret = f_logicexp(nline, ps_scan_gates_optimize);
|
||||||
if (!behav_ret && current_subckt) {
|
if (!behav_ret && current_subckt) {
|
||||||
fprintf(stderr, "ERROR in %s\n", current_subckt);
|
fprintf(stderr, "ERROR in %s\n", current_subckt);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#ifndef INCLUDED_LOGICEXP_H
|
#ifndef INCLUDED_LOGICEXP_H
|
||||||
#define INCLUDED_LOGICEXP_H
|
#define INCLUDED_LOGICEXP_H
|
||||||
|
|
||||||
BOOL f_logicexp(char *line);
|
BOOL f_logicexp(char *line, int optimize);
|
||||||
BOOL f_pindly(char *line);
|
BOOL f_pindly(char *line);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue