# PIC 16 bits

Arquitetura aplicada sobre os microcontroladores PIC. Esses microcontroladores podem ser utilizados diretamente para demandas industriais e também para amantes de programação e eletrônica, possuindo grandes recursos de programação fornecidos por seus componentes e larga variedade de periféricos compatíveis.
As CPU's da família PIC24 integram características de um microcontrolador (MCU) de 16 bits e de um processador de sinais digitais (DSP). A arquitetura dos PIC24F é uma arquitetura Harvard modificada. Isso significa que o programa e as memórias de dados são acessados ​​por barramentos separados.
No entanto, existem mecanismos para armazenar e acessar dados constantes do espaço de memória do programa. Isso permite um uso mais eficiente da memória disponível no chip para algumas aplicações. Algumas instruções, especificamente as instruções do DSP de operandos duplos, permitem acessos duplos a partir da Memória de Acesso Aleatório (RAM) de dados durante o mesmo ciclo de instrução. Isso é um tremendo benefício para aplicativos DSP, como filtragem de sinal.

## Visão Geral

A maioria dos modos de endereçamento opera ortogonalmente em um conjunto de 16 registradores de uso geral de 16 bits, o que significa que todas as instruções suportam todos os modos de endereçamento.
Fontes de interrupção individuais podem ser programadas para um dos sete níveis de prioridade. Corrigida a latência de cinco ciclos, da entrada de solicitação de interrupção para a rotina de serviço de interrupção (ISR), fornece operação de aplicativo rápida. A pilha de interrupções faz parte da RAM on-chip e fornece verificação de limite automática para evitar underflow ou overflow.
Resumo:
* CPU única integrando funções MCU e DSP
* Arquitetura modificada de Harvard
* Suporta instruções de ciclo único, três operandos:
** A = B + C
* Dezesseis registradores de uso geral de 16 bits (W0: W15)
** (W15) opera como um apontador da pilha de software para interrupções e chamadas
* Resposta de interrupção rápida e determinista com múltiplas prioridades e vetores
* Pilha de software flexível com detecção de overflow
* Geradores de endereços duplos (AGU) permitem acesso simultâneo à memória de dados em ciclo único
A CPU dos PIC24F possui capacidade de processamento matemático fornecida pelo mecanismo DSP, acumuladores duplos de 40 bits, suporte a hardware para operações de divisão, barrel shifter, multiplicador 17 x 17, registradores de trabalho de 16 bits e uma variedade de modos de endereçamento de dados.
Acesso direto à memória (DMA) permite a transferência de dados sem sobrecarga entre vários periféricos e uma RAM DMA dedicada.
Entre o espaço de dados e a CPU tem dois barramentos de dados, X e Y. Para poder acessar dois locais ao mesmo tempo, um sempre virá da RAM de dados (memória X) e depois, do segundo virá de um subconjunto de RAM de dados reservado para a memória Y. Esse tipo de RAM de dados é chamado de porta dupla. Há apenas um conjunto de instruções em que usamos os barramentos de dados X e Y, as instruções da classe MAC.

## Conjunto de instruções

A CPU dos PIC24F consiste em 84 instruções diferentes. Se considerarmos os vários modos de endereçamento possíveis, existem quase 250 códigos de operação (opcodes) possíveis. A maioria das instruções pode ser programada em uma palavra de instrução. No entanto, 4 instruções requerem uma palavra de instrução adicional, estas são instruções como GOTO, que envolvem a especificação de um endereço de memória de programa de 24 bits.
A maioria das instruções é executada em um ciclo de instrução. As exceções são: alterações de fluxo de programa, instruções de tabela e movimentações de dados de palavra dupla. A instrução de divisão é uma instrução iterativa interruptível de ciclo único que precisa ser repetida 18 vezes.
A palavra de instrução de 24 bits habilita três instruções de operandos. Isso permite que dois operandos de origem sejam operados, com o resultado armazenado em um terceiro local em um único ciclo. Isso maximiza a eficiência do código no assembly e na linguagem C. As instruções desta aula são as instruções do DSP (destacadas em vermelho).
Existem 10 categorias de instruções:
* Movimento
* Matemática
* Lógica
* Rotação / Mudança
* Manipulação de Bit
* Comparação
* Programa / Fluxo
* Sombra / Pilha
* Controle
* DSP

## Mapa de Memória de Programa

O mapa da Memória do Programa inclui o vetor de reconfiguração, a tabela de vetores de interrupção, uma tabela de vetores alternativos, memória Flash de programa do usuário, EEPROM de dados e espaço de memória de configuração. O vetor Reset é uma instrução GOTO de 2 palavras e, portanto, é o único vetor que ocupa duas palavras. Todos os locais do vetor de interrupção são preenchidos com sua respectiva rotina de serviço de interrupção ou endereço ISR. Há uma tabela de vetores alternativos que pode ser habilitada pelo usuário. Ela fornece um conjunto completo de todos os vetores de interrupção e é uma ajuda durante a depuração do sistema.
A memória de programa FLASH de 24 bits do executável começa em 0x200 em todos os dispositivos PIC 16 bits e progride linearmente através do espaço de endereços do programa. O bloco EEPROM de dados de 16 bits está localizado na extremidade superior do espaço de memória do programa do usuário e pode ser acessado usando as instruções da tabela ou a Visibilidade do Espaço do Programa. O EEPROM de dados pode ser usado para armazenar constantes de aplicativos e outros dados parâmetros, como tabelas de consulta e constantes de calibração de sensores.
Finalmente, o mapa inclui espaço de memória de configuração, que só pode ser acessado usando as instruções da tabela. Os registros de configuração de dispositivos, usados ​​para configurar parâmetros básicos da operação do dispositivo, como a fonte de clock do sistema, estão localizados nesse espaço de endereço.

## Mapa de Memória de Dados

A memória de dados é composta por duas regiões principais: Próxima e Distante. Os dados armazenados no espaço próximo podem ser acessados ​​usando os modos de endereçamento direto, enquanto os dados no espaço distante só podem ser acessados ​​indiretamente por meio de ponteiros. Isso permite organizar as variáveis ​​da maneira mais eficiente. Além disso, a RAM é endereçável por byte. Os bytes baixos e altos de cada local de 16 bits possuem seu próprio endereço. O endereço da palavra é sempre associado ao endereço de byte baixo (número par).
O núcleo tem dois espaços de dados, X e Y. Esses espaços de dados podem ser considerados separados (para algumas instruções de DSP) ou como um intervalo de endereço linear unificado (para instruções de MCU). Os espaços de dados são acessados ​​usando duas Unidades de Geração de Endereço (AGUs) e caminhos de dados separados. Este recurso permite que certas instruções obtenham simultaneamente duas palavras da RAM, permitindo assim a execução eficiente de algoritmos DSP. As regiões de memória X e Y são separadas ao usar qualquer uma das instruções da classe DSP.
Por exemplo, se você estiver computando a saída de um filtro digital, seus dados de entrada poderão estar na memória de dados Y e seus coeficientes na memória de dados X, para que possam ser buscados simultaneamente.
O espaço de dados inclui 2 Kbytes de RAM DMA, que é usado principalmente para transferências de dados DMA, mas pode ser usado como RAM de propósito geral. Por fim, os 32 Kbytes superiores do mapa de memória de espaço de dados podem ser mapeados opcionalmente para o espaço de programa em qualquer limite de palavra de programa de 16 K definido. O recurso de mapeamento do espaço de programa a dados permite que qualquer instrução acesse o espaço do programa como se fosse espaço de dados.

## Modelo do programador

O modelo do programador consiste em 16 x 16-bit registradores de trabalho (W0 a W15), Status Register (SR), 2 x 40-bit acumuladores (ACCA e ACCB), Program Counter (PC), programa Space Visibility Page register (PSVPAG) , Registradores de registro de página de tabela de dados (TBLPAG), REPEAT e DO (DOSTART, DOEND, DCOUNT e RCOUNT).

### Registradores de trabalho

Os registradores de trabalho podem atuar como registradores de dados, endereço ou offset. Todos eles são mapeados na memória. Alguns deles possuem um registrador de sombra associado a eles. O registrador de sombra é usado como um registrador de retenção temporário e pode transferir seu conteúdo para ou de seu registrador de host quando algum evento ocorre em um único ciclo. Nenhum dos registradores de sombra está acessível diretamente. Quando uma operação de byte é executada em um registrador de trabalho, somente o Byte Menos Significativo do registrador de destino é afetado. No entanto, uma vantagem dos registradores de trabalho mapeados na memória é que ambos os Bytes Menos e Mais Significativo podem ser manipulados através de acessos de espaço de memória de dados em todo o byte.
W15 é o software dedicado Stack Pointer (SP). Ele é automaticamente modificado pelo processamento de exceções e pelas chamadas e retornos da sub-rotina. No entanto, W15 pode ser referenciado por qualquer instrução da mesma maneira que todos os outros registros W. Isso simplifica a leitura, gravação e manipulação do Ponteiro de Pilha (por exemplo, criação de quadros de pilha). O W14 foi dedicado como um Stack Frame Pointer, conforme definido pelas instruções LNK e ULNK. No entanto, W14 pode ser referenciado por qualquer instrução da mesma maneira que todos os outros registros W. O ponteiro de pilha sempre aponta para a primeira palavra livre disponível e cresce de endereços inferiores para endereços mais altos. Ele pré-decrementa para pops de pilha (leituras) e pós-incrementos para empilhamento de pilha (gravações).

## Recursos do DSP

O registro de status é dividido em duas partes: status MCU e status DSP. Os bits de status MCU são: MCU ALU Carry / Borrow bit (C), MCU ALU Zero bit (Z), MCU ALU Overflow bit (OV), MCU ALU Bit negativo (N), REPEAT Loop Active bit (RA) e os bits de status do nível de prioridade de interrupção da CPU.
Os acumuladores são registradores de 40 bits que recebem o resultado de 32 bits da multiplicação de dois números de 16 bits e fornecem um extra de 8 'bits de proteção' para overflow. A segunda metade do registro de status é onde pode-se encontrar todos os bits relacionados ao overflow e à saturação. DC é o bit MCU ALU Half Carry / Borrow, DA é o bit Do Loop Active, SAB é o bit de saturação do status SA ou SB Combined Accumulator, OAB é o status OA ou OB Combined Accumulator Overflow Status, SB é o status de saturação do acumulador B bit, SA é o bit de Status de Saturação do Acumulador A, OB é o bit de Status de Sobrecarga do Acumulador B e, por último, OA é o bit de Status de Sobrecarga do Acumulador.

## PC, PSV, DO e REPEAT

O contador do programa é de 23 bits; o bit menos significativo é zero porque o contador de programa sempre aumenta em dois. Como os intervalos de endereços para os espaços de dados e programas são 16 e 24 bits, respectivamente, um método é necessário para criar um endereço de programa de 23 ou 24 bits a partir de registros de dados de 16 bits. A solução depende do método de interface a ser usado. Para operações de tabela, o registrador de Página de Tabela (TBLPAG) é usado para definir uma região de palavra de 32K dentro do espaço do programa. Para remapear operações, o registro de Visibilidade de Espaço do Programa (PSVPAG) é usado para definir uma página de 16K no espaço do programa.
RCOUNT é o contador de repetição REPEAT, é onde especifica-se quantas vezes deseja que o loop REPEAT seja executado. DCOUNT é o Contador de Loop do DO, o DOSTART é o Endereço de Início do Loop e o DOEND é o fim do Loop do DO. Por fim, o CORCON, Core Control Register, é onde configura-se as diferentes opções para o mecanismo de DSP.

## Janela Visibilidade do Espaço do Programa

Qualquer segmento de 32 Kbytes de memória de programa (Flash) pode ser mapeado em memória de dados (RAM). Uma vez mapeado, é lido como se estivesse realmente lá. Esse modo de operação é chamado de PSV (Visibilidade do Espaço do Programa) e fornece acesso de dados constantes armazenados no espaço da Memória de Programa sem a necessidade de usar instruções especiais.

### Por que vários barramentos de endereços?

A equação 1 representa uma operação típica do tipo DSP, na qual várias operações precisam ser executadas em um loop dentro de um único ciclo.
(1)
$y[n]=\textstyle \sum _{k=0}^{N-1}h[k]*x[n-k]\displaystyle$
* Em um único ciclo, uma instrução DSP requer:
** Uma busca de memória de programa
** Dois dados de memória lêem h [k], x [n-k]
** Uma memória de dados escreve y (n)
* Unidades geradoras de endereço X e Y (AGUs) permitem
** Duas leituras simultâneas da memória de dados
* PSV permite
** 32 KB de memória de programa a ser mapeada na memória de dados X para que as leituras possam ser da memória de programa abundante, mas tratadas como memória de dados escassa
** Ideal para tabelas de consulta, como coeficientes de filtro digital h [k]

## Acumuladores de 40 bits

* Dois acumuladores de 40 bits (ACCA ou A, ACCB ou B)
** Todas as palavras (ACCxU, ACCxH, ACCxL) são mapeadas individualmente pela memória
** 8 bits de guarda (ACCxU)
*** Fornecer maior faixa dinâmica
*** Preservar o bit de sinal
** Detectar condições de estouro
** Forneça saturação quando necessário
** Dados dentro e fora são realizados através de instruções especiais
*** LAC - carrega o número de 16 bits no acumulador de 40 bits
*** SAC - armazena o número de 40 bits no espaço de 16 bits
Cada um dos dois acumuladores de 40 bits, A e B, é composto de um byte superior e duas palavras de 16 bits. O byte superior, Acumulator Upper, fornece 8 bits extras de guarda que podem ser úteis ao executar uma longa série de operações no acumulador. Quando o acumulador é carregado pela execução de uma instrução LAC ou como resultado de uma instrução de multiplicação de DSP, o registro Superior de Acumulador contém bits de extensão de sinal. No entanto, à medida que se executa operações no conteúdo do acumulador, é bem possível que o resultado da operação possa “crescer” ou transbordar para os bits de proteção superior do acumulador, desde que, é claro, o modo de saturação selecionado permita esta. Quando isso ocorre, os bits de proteção fornecem margem computacional para operar com precisão com esses números maiores. Como os acumuladores são mapeados na memória, cada registrador pode ser alternativamente acessado como um local geral de memória de dados usando as instruções do MCU.

## Instruções do acumulador

Todas as instruções são de ciclo único e não suportam write-back de pré-busca ou acumulador.
Os acumuladores são de 40 bits, enquanto os caminhos de dados são de 16 bits.
| Instrução | | Operação |
| ADD | Soma Acumuladores | ACCn = ACCn + ACCm |
| ADD | Soma 16-bit com sinal com Acumulador | ACCn = ACCn + #lit16 |
| LAC | Carrega Acumulador | ACCn = X |
| NEG | Inverte Acumulador | ACCn = -ACCn |
| SAC | Armazena Acumulador | X = ACCn |
| SAC.R | Armazena Acumulador arredondado | X = (round)ACCn |
| SFTAC | Deslocamento Aritmética do Acumulador by lit | ACCn = shift(#lit4)ACCn |
| SFTAC | Deslocamento Aritmética do Acumulador by (Wn) | ACCn = shift(Wn)ACCn |
| SUB | Subtrai Acumuladores | ACCn = ACCn - ACCm |
* Carregar o acumulador de 40 bits do espaço de 16 bits
** Preenchimento Zero
** Extensão de sinal
* Armazene o acumulador de 40 bits no espaço de 16 bits
** Arredondamento
** Saturação de gravação de dados