/*----------------------------------------------------------------*\ Ficheiro: CHIP.C Alteração: 03-05-96 Alterado por: A. Esteves Contém as funções que necessitam de comunicarcom o exterior do chip (linhas de controlo). Presume-se que nos shifts, o transputer introduz zeros. \*----------------------------------------------------------------*/ #include "datadef.h" /*#################################################################*/ /*## TagAbove: ##*/ /*## Faz a migracao das tags de cada PE para o PE seguinte, do ##*/ /*## PE "de cima" para o PE "de baixo". ##*/ /*#################################################################*/ void TagAbove(void) { WORD tag_out; /* Activar a linha TAG_DOWN que sai deste chip com o valor da tag do ultimo PE do chip: */ tag_out = tag[1] & (WORD)1; /* Passar ultima tag para o 1.o PE do chip seguinte */ if (tag_out) EFLAGS_OUT[num_chip] |= TAGDOWNBELOW; /* flag TagDown=1 */ else EFLAGS_OUT[num_chip] &= (!TAGDOWNBELOW); /* flag TagDown=0 */ /* Fazer o deslocamento dentro do chip: */ tag[1] = tag[1] >> 1;/* Faz o deslocamento do 2.o bloco de PEs */ /* Ir buscar a tag que sai do 1.o bloco. */ tag_out = tag[0] & (WORD)1; tag_out = tag_out << 31; tag[1] = tag[1] | tag_out; /* Introduzi-la no 2.o bloco */ tag[0] = tag[0] >> 1;/* Faz o deslocamento do 1.o bloco de PEs */ /* Ir buscar a tag que vem do chip anterior (TagAbove) */ tag_out = (EFLAGS_IN[num_chip] & TAGUPABOVE) ? 0x80000000 : 0; tag[0] = tag[0] | tag_out; /* Introduzi-la no 1o bloco */ } /*#################################################################*/ /*## TagBelow: ##*/ /*## Faz a migracao das tags de cada PE para o PE anterior, do ##*/ /*## PE "de baixo" para o PE "de cima". ##*/ /*#################################################################*/ void TagBelow(void) { WORD tag_out; /* Activar a linha TAG_UP que sai deste chip com o valor da tag do primeiro PE do chip: */ tag_out = tag[0] & (WORD)0x80000000; /* Passar primeira tag para o ultimo PE do chip anterior*/ if (tag_out) EFLAGS_OUT[num_chip] |= TAGUPABOVE; else EFLAGS_OUT[num_chip] &= (!TAGUPABOVE); /* Fazer o deslocamento dentro do chip: */ tag[0] = tag[0] << 1;/* Faz o deslocamento do 1.o bloco de PEs */ /* Ir buscar a tag que sai do 2.o bloco */ tag_out = tag[1] >> 31; tag[0] = tag[0] | tag_out; /* Introduzi-la no 1.o bloco */ tag[1] = tag[1] << 1;/* Faz o deslocamento do 2.o bloco de PEs */ /* Ir buscar a tag que vem do chip seguinte (TagBelow) */ tag_out = (EFLAGS_IN[num_chip] & TAGDOWNBELOW) ? 1 : 0; tag[1] = tag[1] | tag_out; /* Introduzi-la no 2.o bloco */ } /*#################################################################*/ /* Chip_Alt_IN() */ /* Actualiza a variavel WORD AltIn[SIZE] usada no modulo PE_ROM.C */ /* nas funcoes ..alt.. em operacoes logicas. Utiliza-se a variavel */ /* AltIn visto que todos os 64 PE's precisam do valor desta linha. */ /* Atencao, precisa de ser alterada se a palavra for <> de 32 bits.*/ /* Ver ALT_FIRST_LOGIC no paper ALU FUNCTION DEFINITION. */ /* Ver tambem Chip_ALT_LATCH ( SET/RESET ) */ /*#################################################################*/ void Chip_ALT_IN(void) { unsigned int i, bit, mask; AltIn[0] = AltIn[1] = 0; /* Nunca esquecer esta inicializacao! */ /* Colocar na variavel bit o valor do sinal processor_above[ALT_OUT] (ver ALT_FIRST_LOGIC). Colocar em bit o valor de ALT_IN que vem do chip de cima. Se o sinal for <> de 0 ajustar o seu valor para que possa ser usado nas operacoes logicas. */ bit = (EFLAGS_IN[num_chip] & ALTINOUT) ? 0x80000000 : 0; mask = 0x80000000; /* Mascara para usar nas tags. */ /* Primeiros 32 PEs */ for (i=0; i < PALAVRA; i++) { /* AltIn (PE) = AltIn (PE anterior) ^ tag_in */ /* bit = AltIn (PE anterior) */ AltIn[0] = (AltIn[0] | ((bit ^ tag[0]) & mask)); /* Guardar o valor de alt_in para passar ao PE seguinte. */ bit = AltIn[0] & mask; /* shift de 1 para a direita para processar o PE seguinte. */ mask >>= 1; /* Transportar o alt_in do PE anterior para o PE seguinte. Resguardar o caso em que se esta' no ultimo PE. Nesse caso, nao devemos fazer shift ou vamos perder o bit. */ if (i < (PALAVRA-1)) bit >>= 1; } /* Segundo bloco de PEs */ if (bit) bit = 0x80000000; mask = 0x80000000; /* Mascara para usar nas tags. */ for (i=0; i < PALAVRA; i++) { /* AltIn (PE) = AltIn (PE anterior) ^ tag_in */ /* bit = AltIn (PE anterior) */ AltIn[1] = (AltIn[1] | ((bit ^ tag[1]) & mask)); /* Guardar o valor de alt_in para passar ao PE seguinte. */ bit = AltIn[1] & mask; /* shift de 1 para a direita para processar o PE seguinte. */ mask >>= 1; /* Transportar o alt_in do PE anterior para o PE seguinte. Resguardar o caso em que se esta' no ultimo PE. Nesse caso, nao devemos fazer shift ou vamos perder o bit. */ if (i < (PALAVRA-1)) bit >>= 1; } /* Propagar o valor da variavel bit (alt_in) para o primeiro PE do CHIP seguinte onde sera' usado como sendo o sinal processor_above[ALT_OUT] (ver ALT_FIRST_LOGIC). */ if (bit) EFLAGS_OUT[num_chip] |= ALTINOUT; else EFLAGS_OUT[num_chip] &= (!ALTINOUT); } /*#################################################################*/ /* Chip_ENABLE() */ /* Actualiza a variavel WORD Enable[SIZE] usada no modulo PE_ROM.C */ /* nas funcoes ..alt.. em operacoes logicas. Utiliza-se a variavel */ /* Enable visto que todos os 64 PE's precisam do valor desta linha.*/ /* Ver tambem Chip_ENABLE_LATCH ( SET/RESET ) */ /*#################################################################*/ void Chip_ENABLE(void) { /* Para esta funcao, descobrir as expressoes logicas como se fez para a funcao chip_alt_in */ Enable[1]=Enable[0]=(EFLAGS_IN[num_chip] & ENABLEINOUT)?WORD_UM:0; } /*#################################################################*/ /* Chip_FIRST_IN() */ /* Usada pela funcao first (void). */ /* Actualiza a variavel WORD FirstIn[SIZE] usada no modulo PE_ROM.C*/ /* na funcao first() em operacoes logicas. Utiliza-se a variavel */ /* FirstIn visto que todos os 64 PE's precisam do valor desta linha*/ /* Atencao, precisa de ser alterada se a palavra for <> de 32 bits */ /* Ver ALT_FIRST_LOGIC no paper ALU FUNCTION DEFINITION. */ /* Ver tb. Chip_FIRST_LATCH ( SET/RESET ) */ /*#################################################################*/ void Chip_FIRST_IN(void) { unsigned int i, bit, mask; FirstIn[0] = FirstIn[1] = 0;/*Nunca esquecer esta inicializacao*/ /* Colocar na variavel bit o valor do sinal processor_above[FIRST_OUT] (ver ALT_FIRST_LOGIC). Por em bit o valor de FIRST_IN que vem do chip de cima. Se o sinal for <> de 0 ajustar o seu valor para que possa ser usado nas operacoes logicas. */ bit = (EFLAGS_IN[num_chip] & FIRSTINOUT) ? 0x80000000 : 0; mask = 0x80000000; /* Mascara para usar nas tags. */ /* Primeiros 32 PEs */ for (i=0; i < PALAVRA; i++) { /* FirstIn (PE) = FirstIn (PE anterior) & ~tag_in */ /* bit = FirstIn (PE anterior) */ FirstIn[0] = (FirstIn[0] | ((bit & (~tag[0])) & mask)); /* Guardar o valor de first_in para passar ao PE seguinte. */ bit = FirstIn[0] & mask; /* shift de 1 para a direita para processar o PE seguinte. */ mask >>= 1; /* Transportar o first_in do PE anterior para o PE seguinte. Resguardar o caso em que se esta' no ultimo PE. Nesse caso, nao devemos fazer shift ou vamos perder o bit. */ if (i < (PALAVRA-1)) bit >>= 1; } /* Segundo bloco de PEs */ if (bit) bit = 0x80000000; mask = 0x80000000; /* Mascara para usar nas tags. */ for (i=0; i < PALAVRA; i++) { /* FirstIn (PE) = FirstIn (PE anterior) & ~tag_in */ /* bit = FirstIn (PE anterior) */ FirstIn[1] = (FirstIn[1] | ((bit & (~tag[1])) & mask)); /* Guardar o valor de first_in para passar ao PE seguinte. */ bit = FirstIn[1] & mask; /* shift de 1 para a direita para processar o PE seguinte. */ mask >>= 1; /* Transportar o first_in do PE anterior para o PE seguinte. Resguardar o caso em que se esta no ultimo PE. Nesse caso, nao devemos fazer shift ou vamos perder o bit. */ if (i < (PALAVRA-1)) bit >>= 1; } /* Propagar o valor da variavel bit (first_in) para o primeiro PE do CHIP seguinte onde sera' usado como sendo o sinal processor_above[first_OUT] (ver ALT_FIRST_LOGIC). */ if (bit) EFLAGS_OUT[num_chip] |= FIRSTINOUT; else EFLAGS_OUT[num_chip] &= (!FIRSTINOUT); } /*#################################################################*/ /* Chip_ALT_LATCH ( SET/RESET ) */ /* Actualiza a variavel WORD AltIn[SIZE] usada no modulo PE_ROM.C */ /* nas funcoes ...alt... que fazem SET ou RESET desta linha. */ /* Ver "6. OTHER SIGNALS" no paper ALU FUNCTION DEFINITION. */ /*#################################################################*/ void Chip_ALT_LATCH ( int X ) { switch (X) { case SET : AltIn[0] = AltIn[1] = WORD_UM; EFLAGS_OUT[num_chip] |= ALTINOUT; EFLAGS_IN[num_chip] |= ALTINOUT; break; case RESET : AltIn[0] = AltIn[1] = 0; EFLAGS_OUT[num_chip] &= (!ALTINOUT); EFLAGS_IN[num_chip] &= (!ALTINOUT); break; default : erro ("\nERRO na funcao Chip_ALT_LATCH() \n"); } } /*#################################################################*/ /* Chip_ENABLE_LATCH ( SET/RESET ) */ /* Actualiza a variavel WORD Enable[SIZE] usada no modulo PE_ROM.C */ /* nas funcoes ...alt... que fazem SET ou RESET desta linha. */ /* Ver "6. OTHER SIGNALS" no paper ALU FUNCTION DEFINITION. */ /*#################################################################*/ void Chip_ENABLE_LATCH ( int X) { /* Isto e' feito em grupos de 16 PEs, pois FIRST e' comum a grupos de 16 PEs */ switch (X) { case SET: Enable[0] = Enable[1] = WORD_UM; EFLAGS_OUT[num_chip] |= ENABLEINOUT; EFLAGS_IN[num_chip] |= ENABLEINOUT; break; case RESET: Enable[0] = Enable[1] = 0; EFLAGS_OUT[num_chip] &= (!ENABLEINOUT); EFLAGS_IN[num_chip] &= (!ENABLEINOUT); break; default: erro ("\nERRO na funcao Chip_ENABLE_LATCH() \n"); } } /*#################################################################*/ /* Chip_FIRST_LATCH ( SET/RESET ) */ /* Usada pelas funcoes init_first0 (void) e init_first1 (void) no */ /* modulo PE_ROM.C. */ /* Ver "6. OTHER SIGNALS" no paper ALU FUNCTION DEFINITION. */ /*#################################################################*/ void Chip_FIRST_LATCH ( int X ) { /* Isto e' feito em grupos de 16 PEs, pois FIRST e' comum a grupos de 16 PEs */ EFLAGS_OUT[num_chip] &= (!FIRSTINOUT); switch (X) { case SET: FirstIn[0] = FirstIn[1] = WORD_UM; /* EFLAGS_OUT[num_chip] |= FIRSTINOUT; */ EFLAGS_IN[num_chip] |= FIRSTINOUT; break; case RESET: FirstIn[0] = FirstIn[1] = 0; /* EFLAGS_OUT[num_chip] &= (!FIRSTINOUT); */ EFLAGS_IN[num_chip] &= (!FIRSTINOUT); break; default: erro ( "\nERRO na funcao Chip_FIRST_LATCH() \n"); } } /*#################################################################*/