Estou construindo uma CPU simples de 16 bits no Logisim e tenho a ALU pronta e os códigos de operação que eu quero ter. Agora, acho realmente difícil encontrar a codificação correta para os comandos, para que os diferentes subcircuitos (por exemplo, lógica, aritmética) não precisem de todos os fios de controle (que constroem a codificação) como entrada, mas o mínimo possível. Existem estratégias ou métodos que ajudam com um design eficiente de código de operação?
thx antecipadamente
cpu
computer-architecture
Benjoyo
fonte
fonte
Respostas:
Eu acho que é uma boa abordagem estudar alguns outros conjuntos de instruções.
Um pequeno seria o MSP430 da TI, é um processador de 16 bits com cerca de 22 instruções.
http://www.physics.mcmaster.ca/phys3b06/MSP430/MSP430_Instruction_Set_Summary.pdf
Você também pode procurar nos AVRs da Atmel, eles também possuem um conjunto de instruções bastante pequeno.
Em um pequeno projeto meu, tentei desenvolver um simples processador de 32 bits em VHDL com um pequeno conjunto de instruções (14 instruções):
http://www.blog-tm.de/?p=80
Devido ao meu tempo livre atual, ele não está totalmente concluído. As instruções são implementadas, mas duas não são testadas e talvez alguns sinalizadores de status estejam ausentes.
fonte
Estude (mas não replique) a abordagem ARM para codificação de instruções. É fortemente orientado a prefixos (como a abordagem de árvore de Huffman recomendada por Dzarda) e altamente uniforme em termos de onde o registrador seleciona parte da instrução.
A abordagem sem imaginação, porém confiável, é enumerar todos os sinais de controle você possui, que provavelmente terão mais de 16 bits, e tentar executar a minimização lógica do estilo do mapa de Karnaugh neles.
fonte
Uma vez eu tentei fazer uma CPU de 4 bits com núcleo de comprimento de instrução de 8 bits no Logisim. Acabou com uma máquina de estado simples, mais do que uma CPU, realmente.
Coisas aleatórias para procurar
Excelente vídeo no Computerphile sobre árvores Huffman:
fonte
O ISA que escrevi para a classe já teve um código operacional de 4 bits, assim:
1XXX ALU instructions 01XX jump, jump register, call etc 001X branch not equal, branch equal zero 000X 0 - load, 1 - store
Em vez de ser o mais ideal, esse é um dos estilos mais fáceis de construir / projetar portões, porque o sinal de entrada de um único bit pode controlar inteiramente qual caminho lógico é seguido. Como alternativa, você pode codificar com Huffman seus símbolos mais usados e zerá-los para obter um código operacional de comprimento fixo.
fonte
Uma coisa que você precisa considerar é se deve permitir qualquer forma de instrução com várias palavras ou qualquer coisa que possa "agir" como uma instrução com várias palavras; se o fizer, convém considerar se deve usar palavras de instruções adicionais após a instrução principal ou prefixar as palavras antes dela. Permitir prefixos e palavras subsequentes pode aumentar a complexidade do tratamento de interrupções, mas pode evitar a necessidade de ajustar instruções raramente usadas no mesmo espaço de código de operação que as usadas com freqüência.
Se as instruções são buscadas no ciclo antes de serem executadas, pode-se ter uma instrução de "ramificação condicional" que faz com que a próxima palavra de instrução seja ignorada ou então seu conteúdo é transferido diretamente para o contador do programa; esse design pode adicionar uma complexidade extra à interrupção do seqüenciamento, mas pode facilitar a necessidade de usar grande parte do espaço do código de operação para instruções de "ramificação", "salto" e "chamada", permitindo uma variedade muito maior de condições de ramificação do que seria possível. Como uma ramificação obtida geralmente requer um ciclo morto após a execução da instrução, independentemente da origem do endereço, ter o endereço da palavra seguinte que foi buscada, mas não será executada, não custa mais Tempo.
Embora a remoção do endereço de destino das instruções de ramificação reduza a quantidade de espaço do código de operação que eles consomem, um formato de código de operação de 16 bits ainda é bastante restrito. O uso de instruções de prefixo pode ajudar com isso. Se, por exemplo, alguém quiser ter 32 registros, permitir que qualquer registro seja especificado independentemente como origem1, origem2 e destino exigiria 15 bits no código de operação, permitindo um total impressionante de duas instruções. Não é muito útil. Por outro lado, seria capaz de usar qualquer um dos 32 registros para cada um dos três operandos. Pode-se equilibrar os dois objetivos fazendo com que qualquer operação da ALU que não seja precedida por um prefixo use oito bits para fazer duas de dezesseis seleções de registro, mas uma operação da ALU que segue imediatamente um prefixo use alguns bits no prefixo junto com oito da instrução a seguir, para permitir a seleção independente de ambas as fontes e o destino do conjunto completo de 32. As instruções que usam os registros superiores precisariam de duas palavras / ciclos em vez de um, mas em alguns casos essa troca poderia valer a pena. A maior dificuldade com o uso de prefixos é que é preciso impedir que uma interrupção ocorra entre um prefixo e a próxima instrução ou garantir que, se ocorrer uma interrupção, a instrução após o prefixo ainda use os registros corretos [por exemplo, tendo o programa -counter save logic armazena o endereço da última instrução sem prefixo executada]. mas, em alguns casos, essa troca poderia valer a pena. A maior dificuldade com o uso de prefixos é que é preciso impedir que uma interrupção ocorra entre um prefixo e a próxima instrução ou garantir que, se ocorrer uma interrupção, a instrução após o prefixo ainda use os registros corretos [por exemplo, tendo o programa -counter save logic armazena o endereço da última instrução sem prefixo executada]. mas, em alguns casos, essa troca poderia valer a pena. A maior dificuldade com o uso de prefixos é que é preciso impedir que uma interrupção ocorra entre um prefixo e a próxima instrução ou garantir que, se ocorrer uma interrupção, a instrução após o prefixo ainda use os registros corretos [por exemplo, tendo o programa -counter save logic armazena o endereço da última instrução sem prefixo executada].
O uso de instruções com várias palavras dificultará alguns aspectos do design, mas poderá reduzir a necessidade de tomar outras decisões difíceis.
fonte
Esse cara tem os melhores detalhes para entender a fiação rígida da parte codificada de um decodificador, o que explica as linhas de controle de uma CPU codificada: http://minnie.tuhs.org/CompArch/Tutes/week03.html Como você pode ver, sua A opção em Opcodes realmente afeta o quão complexa é a lógica de decodificação.
fonte