#header begin /* extern int ALLDONE; dissabled by GK 16/12/94 */ #include "SN74.h" #define DEPTH_EXPANSION 1 #define STAND_ALONE 0 #define ON 1 #define OFF 0 char *fifo_size_string[] = {"size",0}; char *fifo_cap_string[] = {"loads","capacitance",0}; #header end /* A series of pin compatible 9 bit wide fifos including CY7C421, CY7C425, CY7C429 and IDT7201. The size is included in the data base entry. */ #module CY7C429 (WrbarP1, D8P2, D3P3, D2P4, D1P5, D0P6, XIbarP7, FFbarP8, Q0P9, Q1P10, Q2P11, Q3P12, Q8P13, GNDP14, RbarP15, Q4P16, Q5P17, Q6P18, Q7P19, HFbarP20, EFbarP21, RESbarP22, RTbarP23, D7P24, D6P25, D5P26, D4P27, VccP28) #interrupt notempty, notfull #memory int thl_clr, thl, tlh, type; long mem[2048]; int mode; int iread,iwrite; int size; int read_enabled,write_enabled; long lastreadhigh, lastreadlow; long lastwritehigh, lastwritelow; long lastreshigh, lastreslow; long lastRThigh, lastRTlow; long lastdata; char typstr[10]; #memory end #class_memory char *tech[MAXNUMTECH+1]; int data_delay[MAXNUMTECH]; int x_delay[MAXNUMTECH]; int highz_delay[MAXNUMTECH]; int control_delay[MAXNUMTECH]; int half_delay[MAXNUMTECH]; int empty_delay[MAXNUMTECH]; int expand_delay[MAXNUMTECH]; int recovery[MAXNUMTECH]; int pulse_width[MAXNUMTECH]; int setup[MAXNUMTECH]; int setup_clr[MAXNUMTECH]; int hold[MAXNUMTECH]; int fifo_size; float idrive[MAXNUMTECH]; float ishort[MAXNUMTECH]; float incap,outcap; #class_memory end #output Q0P9 Q1P10 Q2P11 Q3P12 Q4P16 Q5P17 Q6P18 Q7P19 Q8P13 #function (D0P6, D1P5, D2P4, D3P3, D4P27, D5P26, D6P25, D7P24, D8P2) if (VALP(RESbarP22) == HIGH) { /* lprintf(stdout, "\n fifo.hl -> seen instance %s\n",INST_NAME); */ if (CURRENT_TIME < lastwritehigh + hold[type]) { lprintf(stdout, "data hold violation in %s at time %d\n", INST_NAME,CURRENT_TIME); mem[iwrite] = 0x15555; } lastdata = CURRENT_TIME + setup[type]; } #function end #function (WrbarP1) int i, ipos, full; /* lprintf(stdout, "\n fifo.hl -> seen instance %s called by Wrbar \n",INST_NAME); */ if (write_enabled) { full = (((iwrite + 4096 - iread) % 4096) == fifo_size); if ((VALP(WrbarP1)) == HIGH) { if ((VALP(RESbarP22)) == HIGH) { if (CURRENT_TIME < (lastwritelow + pulse_width[type])) lprintf(stdout," write low pulse width in %s too short (%d)\n", INST_NAME,CURRENT_TIME-lastreslow); if (!full) { ipos = iwrite % fifo_size; if (CURRENT_TIME > lastdata) { if (VALP(D8P2) == X){ lprintf(stdout,"\n ** ERR fifo.hl writing X into memory \n"); /* ALLDONE == -1; dissabled by GK 16/12/94 */ } mem[ipos] = (VALP(D8P2)&3) << 16; for(i=0;i<4;i++) mem[ipos] |= ((VALP(portptrs[5-i])&3) << (2*i)) | ((VALP(portptrs[26-i])&3) << (8 + 2*i)); } else { lprintf(stdout, "data setup violation in %s for at time %d\n", INST_NAME,CURRENT_TIME); mem[ipos] = 0x15555; } if ((mode == DEPTH_EXPANSION) && ((iwrite % fifo_size) == (fifo_size -1))) { /* writing to last physical location */ write_enabled = 0; NEW_VAL(HFbarP20,expand_delay[type],HIGH); } if (iwrite == iread) { /* CHECK THIS CODE going to hack it */ NEW_VAL(EFbarP21,empty_delay[type],HIGH); if (read_enabled) INTERRUPT(notempty,empty_delay[type]); else iwrite = (iwrite +1) % 4096; /* code by thomas NEW_VAL(EFbarP21,empty_delay[type],HIGH); iwrite = (iwrite +1) % 4096; */ } else iwrite = (iwrite +1) % 4096; } } /* lprintf(stdout," write ptr %d %s",iwrite,INST_NAME); */ lastwritehigh = CURRENT_TIME; } else if ((VALP(WrbarP1)) == LOW) { if ((VALP(RESbarP22)) == HIGH) { if (CURRENT_TIME < (lastwritehigh + recovery[type])) lprintf(stdout," write high pulse width in %s too short (%d)\n", INST_NAME,CURRENT_TIME-lastreshigh); if (!full) { if (((iwrite + 4096 - iread) % 4096) == fifo_size -1) NEW_VAL(FFbarP8,empty_delay[type],LOW); if ((((iwrite + 4096 - iread) % 4096) == fifo_size/2 -1) && (mode == STAND_ALONE)) NEW_VAL(HFbarP20,half_delay[type],LOW); if ((mode == DEPTH_EXPANSION) && ((iwrite % fifo_size) == (fifo_size -1))) /* writing to last physical location */ NEW_VAL(HFbarP20,expand_delay[type],LOW); } } lastwritelow = CURRENT_TIME; } } #function end #function (RbarP15) int i; long value; /* lprintf(stdout, "\n fifo.hl -> seen instance %s\n",INST_NAME); lprintf(stdout, "\n fifo.hl -> seen instance %s read_enabled %d RbarP15 %d \n",INST_NAME, read_enabled,VALP(RbarP15)); */ if (read_enabled) { if ((VALP(RbarP15)) == LOW) { if ((VALP(RESbarP22)) == HIGH) { if (CURRENT_TIME < (lastreadhigh + recovery[type])) lprintf(stdout," read high pulse width in %s is too short (%d)\n", INST_NAME,CURRENT_TIME-lastreshigh); if (iwrite != iread) { /* if not empty */ value = mem[iread % fifo_size]; if (x_delay[type] >= data_delay[type]){ lprintf(stdout," \n **ERROR fifo.hlc x_delay %d >= data_delay %d \n", x_delay[type],data_delay[type]); /* ALLDONE == -1; dissabled by GK 16/12/94 */ } if ( ((value >> 16) & 3) == 1){ lprintf(stdout," \n **ERROR fifo.hlc reading X value \n"); /* ALLDONE == -1; dissabled by GK 16/12/94 */ } /* lprintf(stdout," fifo.hl -> driving node q8 to %d %s \n", ((value >> 16) & 3),INST_NAME); */ NEW_VAL(Q8P13,x_delay[type],X); NEW_VAL(Q8P13,data_delay[type],(value >> 16) & 3); for(i=0;i<4;i++) { NEW_VAL(portptrs[8 + i],x_delay[type],X); NEW_VAL(portptrs[15 + i],x_delay[type],X); NEW_VAL(portptrs[8 + i],data_delay[type], (value >> (2*i)) & 3); NEW_VAL(portptrs[15 + i],data_delay[type], (value >> (8 + 2*i)) & 3); } if (iwrite == iread + 1) NEW_VAL(EFbarP21,empty_delay[type],LOW); if ((mode == DEPTH_EXPANSION) && ((iread % fifo_size) == (fifo_size -1))) /* reading from last physical location */ NEW_VAL(HFbarP20,expand_delay[type],LOW); } } lastreadlow = CURRENT_TIME; } else if ((VALP(RbarP15)) == HIGH) { if (CURRENT_TIME < (lastreadlow + pulse_width[type])) lprintf(stdout," read low pulse width in %s is too short (%d)\n", INST_NAME,CURRENT_TIME-lastreslow); if (iwrite != iread) { /* if not empty */ for(i=0;i<5;i++) { NEW_VAL(portptrs[8 + i],x_delay[type],X); NEW_VAL(portptrs[8 + i],highz_delay[type],TRISTATE); if (i < 4) { NEW_VAL(portptrs[15 + i],x_delay[type],X); NEW_VAL(portptrs[15 + i],highz_delay[type],TRISTATE); } } if ((((iwrite + 4096 - iread) % 4096) == fifo_size/2) && (mode == STAND_ALONE)) NEW_VAL(HFbarP20,half_delay[type],HIGH); if ((mode == DEPTH_EXPANSION) && ((iread % fifo_size) == (fifo_size -1))) { /* reading from last physical location */ read_enabled = 0; NEW_VAL(HFbarP20,expand_delay[type],HIGH); } if (((iwrite + 4096 - iread) % 4096) == fifo_size) { NEW_VAL(FFbarP8,empty_delay[type],HIGH); if (write_enabled) INTERRUPT(notfull,empty_delay[type]); else iread = (iread +1) % 4096; } else iread = (iread +1) % 4096; } lastreadhigh = CURRENT_TIME; } } #function end #function (notempty) int i, value; if ((VALP(RbarP15)) == LOW) { if ((VALP(RESbarP22)) == HIGH) { /* This is read bubble through mode */ /* See page 5-53 of Cypress Dook */ value = mem[iread % fifo_size]; NEW_VAL(Q8P13,x_delay[type],X); NEW_VAL(Q8P13,data_delay[type],(value >> 16) & 3); for(i=0;i<4;i++) { NEW_VAL(portptrs[8 + i],x_delay[type],X); NEW_VAL(portptrs[15 + i],x_delay[type],X); NEW_VAL(portptrs[8 + i],data_delay[type], (value >> (2*i)) & 3); NEW_VAL(portptrs[15 + i],data_delay[type], (value >> (8 + 2*i)) & 3); } if ((mode == DEPTH_EXPANSION) && ((iread % fifo_size) == (fifo_size -1))) /* reading from last physical location */ NEW_VAL(HFbarP20,expand_delay[type],LOW); NEW_VAL(EFbarP21,empty_delay[type],LOW); } lastreadlow = CURRENT_TIME; } iwrite = (iwrite +1) % 4096; lprintf(stdout, "\n fifo.hl -> inst %s called by notempty writepts %d\n",INST_NAME,iwrite); #function end #function (notfull) if ((VALP(WrbarP1)) == LOW) { if ((VALP(RESbarP22)) == HIGH) { /* This is write bubble through mode */ /* See page 5-53 of Cypress Dook */ NEW_VAL(FFbarP8,empty_delay[type],LOW); if ((mode == DEPTH_EXPANSION) && ((iwrite % fifo_size) == (fifo_size -1))) /* writing to last physical location */ NEW_VAL(HFbarP20,expand_delay[type],LOW); } lastwritelow = CURRENT_TIME; } iread = (iread +1) % 4096; #function end #function (RESbarP22) /* lprintf(stdout, "\n fifo.hl -> seen instance %s\n",INST_NAME); */ if (VALP(RESbarP22) == LOW) { /* Beginning of reset cycle */ NEW_VAL(EFbarP21,control_delay[type],LOW); NEW_VAL(HFbarP20,control_delay[type],HIGH); NEW_VAL(FFbarP8,control_delay[type],HIGH); if (CURRENT_TIME < (lastreshigh + recovery[type])) lprintf(stdout," reset high pulse width in %s is too short (%d)\n", INST_NAME,CURRENT_TIME-lastreshigh); lastreslow = CURRENT_TIME; iread = 0; iwrite = 0; } else if (VALP(RESbarP22) == HIGH) { /* End of reset cycle */ if (CURRENT_TIME < (lastreslow + pulse_width[type])) lprintf(stdout," reset low pulse width in %s is too short (%d)\n", INST_NAME,CURRENT_TIME-lastreslow); if ((VALP(RbarP15) == LOW) || (CURRENT_TIME < lastreadhigh + setup_clr[type])) lprintf(stdout, "reset setup violation in %s for Rbar at time %d\n", INST_NAME,CURRENT_TIME); lastreadhigh = CURRENT_TIME; if ((VALP(WrbarP1) == LOW) || (CURRENT_TIME < lastwritehigh + setup_clr[type])) lprintf(stdout, "reset setup violation in %s for Wbar at time %d\n", INST_NAME,CURRENT_TIME); lastwritehigh = CURRENT_TIME; read_enabled = write_enabled = ON; if (VALP(XIbarP7) == HIGH) { mode = DEPTH_EXPANSION; if (VALP(RTbarP23) == HIGH) read_enabled = write_enabled = OFF; } else mode = STAND_ALONE; lastreshigh = CURRENT_TIME; } #function end #function (RTbarP23) if ((mode == STAND_ALONE) && (VALP(RESbarP22) == HIGH)) { if ((VALP(WrbarP1) == HIGH) && (VALP(RbarP15) == HIGH)) { if ((VALP(RTbarP23)) == LOW) { if (CURRENT_TIME < (lastRThigh + recovery[type])) lprintf(stdout," retransmit high pulse width in %s is too short (%d)\n", INST_NAME,CURRENT_TIME-lastRThigh); iwrite = iwrite - iread; iread = 0; if (iwrite == 0) NEW_VAL(EFbarP21,control_delay[type],LOW); else NEW_VAL(EFbarP21,control_delay[type],HIGH); if (iwrite >= fifo_size) NEW_VAL(FFbarP8,control_delay[type],LOW); else NEW_VAL(FFbarP8,control_delay[type],HIGH); if (iwrite >= fifo_size/2) NEW_VAL(HFbarP20,control_delay[type],LOW); else NEW_VAL(HFbarP20,control_delay[type],HIGH); lastRTlow = CURRENT_TIME; } else if ((VALP(RTbarP23)) == HIGH) { if (CURRENT_TIME < (lastRTlow + pulse_width[type])) lprintf(stdout," retransmit low pulse width in %s is too short (%d)\n", INST_NAME,CURRENT_TIME-lastreslow); lastreadhigh = CURRENT_TIME; lastwritehigh = CURRENT_TIME; lastRThigh = CURRENT_TIME; } } else lprintf(stdout," illegal retransmit cycle in %s, Wbar or Rbar is low\n", INST_NAME); } #function end #function (XIbarP7) if ((mode == DEPTH_EXPANSION) && (VALP(XIbarP7) == HIGH)) { if ((!read_enabled) && (!write_enabled)) write_enabled = 1; else if ((!read_enabled) && (write_enabled)) read_enabled = 1; else if ((read_enabled) && (!write_enabled)) write_enabled = 1; else lprintf(stdout," illegal XIbar when enabled for read and write in %s\n", INST_NAME); } #function end #print begin lprintf(stdout," rdptr= %d, wrptr= %d mode= %d read_en= %d write_en= %d size= %d type= %s\n", iread, iwrite, mode, read_enabled, write_enabled, size, typstr); #print end #init begin DESENSITIZE(Q0P9); DESENSITIZE(Q1P10); DESENSITIZE(Q2P11); DESENSITIZE(Q3P12); DESENSITIZE(Q4P16); DESENSITIZE(Q5P17); DESENSITIZE(Q6P18); DESENSITIZE(Q7P19); DESENSITIZE(Q8P13); lastdata = 0; lastreadhigh = lastwritehigh = lastreshigh = lastRThigh = -1000; lastreadlow = lastwritelow = lastreslow = lastRTlow = -1000; iwrite = iread = 0; mode = STAND_ALONE; #init end #operator class_attribute(char *name, char *value) int i; char ntech[20]; float fv[15]; if (matches(name,tech_ttl_string)) { sscanf(value,"%s%f%f%f%f%f%f%f%f%f%f%f%f%f%f",ntech,&fv[0],&fv[1], &fv[2],&fv[3],&fv[4],&fv[5],&fv[6],&fv[7],&fv[8],&fv[9], &fv[10],&fv[11],&fv[12],&fv[13]); if ((i= add_ttl_tech(ntech,tech)) >=0){ data_delay[i] = ONENANOSEC*fv[0]; x_delay[i] = ONENANOSEC*fv[1]; highz_delay[i] = ONENANOSEC*fv[2]; control_delay[i] = ONENANOSEC*fv[3]; half_delay[i] = ONENANOSEC*fv[4]; empty_delay[i] = ONENANOSEC*fv[5]; expand_delay[i] = ONENANOSEC*fv[6]; recovery[i] = ONENANOSEC*fv[7]; pulse_width[i] = ONENANOSEC*fv[8]; setup[i] = ONENANOSEC*fv[9]; setup_clr[i] = ONENANOSEC*fv[10]; hold[i] = ONENANOSEC*fv[11]; idrive[i] = fv[12]; ishort[i] = fv[13]; } else TOO_MANY_TECH_MESG; } else if (matches(name,fifo_size_string)) sscanf(value,"%d",&fifo_size); else if (matches(name,fifo_cap_string)) { sscanf(value,"%f%f",&incap,&outcap); } #operator end #operator init_ttl_loads() int i; if ((ATTR("type")) == NULL) type = atotech("30",tech); else type = atotech(ATTR("type"),tech); if (type < 0) { type = 0; lprintf(stdout,"USING tech -%s for %s",tech[0],INST_NAME); if (!tech[0]) lprintf(stdout,", all delays 0\n"); else lprintf(stdout,"\n"); } size = fifo_size; for (i=0;i<7;i++) ADD_CAP(portptrs[i],incap); for (i=21;i<27;i++) ADD_CAP(portptrs[i],incap); ADD_CAP(portptrs[14],incap); for (i=7;i<13;i++) ADD_CAP(portptrs[i],outcap); for (i=15;i<21;i++) ADD_CAP(portptrs[i],outcap); if (tech[type]) strcpy(typstr,tech[type]); else strcpy(typstr,"NULL"); #operator end #operator calculate_ttl_delay() int i; for (i=7;i<13;i++) CHECK_TTL_LOAD(portptrs[i],tech[type],idrive[type]); for (i=15;i<21;i++) CHECK_TTL_LOAD(portptrs[i],tech[type],idrive[type]); #operator end #module end #equate CY7C421 CY7C429 #equate CY7C425 CY7C429 #equate IDT7201 CY7C429 #header begin #undef DEPTH_EXPANSION #undef STAND_ALONE #undef ON #undef OFF #header end