/* Copyright (c) 1992, 1993 Regents of the University of California All rights reserved. Use and copying of this software and preparation of derivative works based upon this software are permitted. However, any distribution of this software or derivative works must include the above copyright notice. This software is made available AS IS, and neither the Electronics Research Laboratory or the Universify of California make any warranty about the software, its performance or its conformity to any specification. Author: Szu-Tsung Cheng, stcheng@ic.Berkeley.EDU 10/92 10/93 $Header: /projects/development/hsv/CVSRepository/vl2mv/src/parser/vl_edgedetector.c,v 1.2 2009/03/09 20:25:57 fabio Exp $ */ #include #include #include "util.h" #include "st.h" #include "array.h" #include "list.h" #include "set.h" #include "vl_types.h" #include "vl_defs.h" #include "vlr_int.h" #include "vl_fg_defs.h" #include "vl_create.h" #include "vl_write.h" #include "vl_write_util.h" #include "vl_vardecl.h" #include "vl_edgedetector.h" #include "verilog.h" extern int smartEvent; extern int set_notation; extern int implicitClocking; extern int vlTimedSystem; extern int vl_noTimers; vl_term *write_ored_edge_detector(file, event) FILE *file; vl_event_expr *event; { vl_term *retval; int i; lsGen gen; lsHandle handle; vl_event_expr *expr; array_t *edge_terms; assert(event->type == OrEventExpr); retval = new_term(NIL(vl_range), 0, -1); edge_terms = array_alloc(vl_term*, 0); for (gen=lsStart(event->list); lsNext(gen,(lsGeneric*)&expr,&handle)!=LS_NOMORE;) { vl_term *eterm; eterm = write_edge_detector(file, expr->expr, (expr->type==PosedgeEventExpr)?1: (expr->type==NegedgeEventExpr)?-1:0); array_insert_last(vl_term*, edge_terms, eterm); } (void)lsFinish(gen); fprintf(file, ".names "); for (i=0; iname->name); } fprintf(file, "%s\n", retval->name->name); fprintf(file, "%s 1\n", HSIS_DEFAULT); for (i=0; ilist); i++) fprintf(file, "0 "); fprintf(file, "0\n"); array_free(edge_terms); return retval; } vl_term *write_edge_detector(file, expr, sign) FILE *file; vl_expr *expr; int sign; { static int edge_detector_count=0; vl_term *retval=NIL(vl_term); vl_term *sig, *sig_prev; vl_id_range *id_sym; char buf[MAXSTRLEN]; int event_flag = 0; int hi, lo; int i; vl_id_range *event_id_sym; int nbits; char sigbuf[MAXSTRLEN], sigprebuf[MAXSTRLEN], eventbuf[MAXSTRLEN]; char *delta_counter = NIL(char); if (expr->type == IDExpr) { event_id_sym = expr->u.name; if (st_lookup(vl_currentModule->sig_st, event_id_sym->name, (char**)&id_sym)) get_hilo(id_sym, &hi, &lo); } else { vl_write_expr(file, expr, NIL(st_table)); event_id_sym = expr->term->name; hi = expr->term->hi; lo = expr->term->lo; } if (!st_lookup(vl_currentModule->sig_st, event_id_sym->name, (char**)&id_sym)) { if (expr->type == IDExpr) { sprintf(buf, "'%s': sensitive to undeclared variable %s", vl_currentModule->name->name, expr->u.name->name); yylineno = -1; compile_error(buf); } } else if (id_sym->flags & EventVar) { event_flag = 1; } if (implicitClocking && !vlTimedSystem) return retval; sig = vl_create_term(vl_copy_id_range(event_id_sym), 0, -1); sprintf(buf, "%s%s%s%x", sig->name->name, SEP_GATEPIN, PIN_DELAY, edge_detector_count++); sig_prev = create_rename_term(event_id_sym, buf, 0, -1); retval = new_term(NIL(vl_range), 0, -1); if (event_flag) { fprintf(file, ".names %s %s\n- %s%s\n", sig->name->name, retval->name->name, HSIS_EQUAL, sig->name->name); return retval; } nbits = (hiname->name); sprintf(sigprebuf, "%s", sig_prev->name->name); sprintf(eventbuf, "%s", retval->name->name); } else { sprintf(sigbuf, "%s%s%d%s", sig->name->name, SEP_LBITSELECT, i+lo, SEP_RBITSELECT); sprintf(sigprebuf, "%s%s%d%s", sig_prev->name->name, SEP_LBITSELECT, i+lo, SEP_RBITSELECT); sprintf(eventbuf, "%s%s%d%s", retval->name->name, SEP_LBITSELECT, i+lo, SEP_RBITSELECT); } fprintf(file, ".latch %s %s\n", sigbuf, sigprebuf); fprintf(file, ".r %s\n0\n", sigprebuf); if (sign > 0) { if ((vlTimedSystem || !implicitClocking) && !vl_noTimers) { delta_counter=new_deltaTimer(); fprintf(file, ".timers %s\n", delta_counter); } fprintf(file, ".names %s %s %s\n", sigprebuf, sigbuf, eventbuf); if (set_notation) { if ((vlTimedSystem || !implicitClocking) && !vl_noTimers){ fprintf(file, "%s 0\n", HSIS_DEFAULT); fprintf(file, "0 0 0 %s %s=0\n", HSIS_TIMER_SEP, delta_counter); fprintf(file, "0 1 1 %s %s==0\n", HSIS_TIMER_SEP, delta_counter); } else { fprintf(file, "%s 0\n", HSIS_DEFAULT); fprintf(file, "0 1 1\n"); } } else { fprintf(file, "0 0 0\n0 1 1\n1 0 0\n1 1 0\n"); } } else if (sign < 0) { if ((vlTimedSystem || !implicitClocking) && !vl_noTimers) { delta_counter=new_deltaTimer(); fprintf(file, ".timers %s\n", delta_counter); } fprintf(file, ".names %s %s %s\n", sigprebuf, sigbuf, eventbuf); if (set_notation) { if ((vlTimedSystem || !implicitClocking) && !vl_noTimers) { fprintf(file, "%s 0\n", HSIS_DEFAULT); fprintf(file, "1 1 0 %s %s=0\n", HSIS_TIMER_SEP, delta_counter); fprintf(file, "1 0 1 %s %s==0\n", HSIS_TIMER_SEP, delta_counter); } else { fprintf(file, "%s 0\n", HSIS_DEFAULT); fprintf(file, "1 0 1\n"); } } else { fprintf(file, "0 0 0\n0 1 0\n1 0 1\n1 1 0\n"); } } else if (sign==0) { if ((vlTimedSystem || !implicitClocking) && !vl_noTimers) { delta_counter=new_deltaTimer(); fprintf(file, ".timers %s\n", delta_counter); } fprintf(file, ".names %s %s %s\n", sigprebuf, sigbuf, eventbuf); if (event_flag && smartEvent) { if (set_notation) { fprintf(file, "%s 0\n", HSIS_DEFAULT); fprintf(file, "0 1 1\n"); } else { fprintf(file, "0 0 0\n0 1 1\n1 0 0\n1 1 0\n"); } } else { if (set_notation) { if ((vlTimedSystem || !implicitClocking) && !vl_noTimers) { fprintf(file, "0 0 0 %s %s=0\n", HSIS_TIMER_SEP, delta_counter); fprintf(file, "0 1 1 %s %s==0\n", HSIS_TIMER_SEP, delta_counter); fprintf(file, "1 1 0 %s %s=0\n", HSIS_TIMER_SEP, delta_counter); fprintf(file, "1 0 1 %s %s==0\n", HSIS_TIMER_SEP, delta_counter); } else { fprintf(file, "%s 0\n", HSIS_DEFAULT); fprintf(file, "1 0 1\n0 1 1\n"); } } else { fprintf(file, "0 0 0\n0 1 1\n1 0 1\n1 1 0\n"); } } } } if (hi >= lo) { vl_term *redresult; redresult = new_term(NIL(vl_range), 0, -1); retval->hi = hi; retval->lo = lo; vl_write_vector_bop(file, UorExpr, retval, NIL(vl_term), redresult); retval = redresult; } return retval; } char *new_deltaTimer() { static int delta_timer_counter=0; static char buf[MAXSTRLEN]; sprintf(buf, "%s%d", HSIS_DELTA_TIMER, delta_timer_counter++); return buf; }