Descrever o funcionamento da unidade de controle;
Projetar a unidade de controle para a ULA, FD e Gerador de Imediato.
A nossa abordagem considera que:
As instruções do Tipo R definem a operação da ULA através do funct 3 e funct 7;
As instruções do Tipo I e S definem a operação da ULA através do opcode e funct 3;
As instruções do Tipo B definem a operação da ULA através do opcode e funct 3;
Os pontos de controle do fluxo de dados dependem somente do opcode.
Assim, podemos fazer a decodificação dos pontos de controle do FD separadamente e fazer duas decodificações para a operação da ULA, escolhendo qual usar baseado no tipo de instrução definida pelo opcode.
O diagrama abaixo, mostra essa implementação.
A Unidade de Controle da ULA é composta por dois decodificadores e pelo MUX que seleciona qual resultado da decodificação utilizar.
Para projetar essa unidade, vamos começar analisando os dois decodificadores.
A unidade de controle da ULA é um circuito decodificador implementado com lógica combinacional. Como todo decodificador, ele converte os sinais de entrada (opcode e funct) em um código de saída (ULActrl).
Para que essa conversão seja feita, necessitamos correlacionar todas as entradas e os resultados que elas geram na saída.
O sinal de saída, ULActrl, tem 3 pontos de controle, com as seguintes funções:
InverteB:
Seleção:
Isso pode ser visto, com detalhes, no circuito da ULA do RISCV, mostrado abaixo.
Para compatibilidade com o descrito no livro texto, utilizaremos a seguinte ordenação para os bits da palavra de controle da ULA:
| Bit | Função |
|---|---|
| bit 2 | InverteB |
| bit 1 | bit 1 da seleção do MUX |
| bit 0 | bit 0 da seleção do MUX |
No caso dos sinais de entrada, temos dois conjuntos:
O funct 7 e funct 3, que é utilizado somente nas instruções do tipo R. Seus valorem estão definidos no green card.
O opcode e funct 3, que é utilizado nas instruções do tipo I, S e B. Seus valorem estão definidos no green card.
Para projetar o circuito da Unidade de Controle da ULA, precisamos definir qual operação deve ser executada para cada instrução.
Considerando somente as instruções do grupo A, temos as seguintes operações:
| Instrução | Tipo | Operação da ULA |
|---|---|---|
| AND | R | E lógico |
| OR | R | OU lógico |
| ADD | R | Soma |
| SUB | R | Subtração |
| SLT | R | Subtração |
| LW | I | Soma |
| SW | S | Soma |
| BEQ | B | Subtração |
Inicialmente, precisamos definir o estado de cada bit do ULActrl para cada operação da ULA. O resultado será o conjunto dos sinais de saída da unidade de controle da ULA.
Considerando o nosso conjunto de instruções e a sequência de bits definida anteriormente (livro texto) e repetida abaixo, podemos resumir a codificação do ULActrl para as operações:
| Função | ULActrl |
|---|---|
| AND | |
| OR | |
| ADD | |
| SUB | |
| SLT |
| Bit | Função | Observação |
|---|---|---|
| bit 2 | InverteB | Ativa o Carry In do bit 0 |
| bit 1 | bit 1 da seleção do MUX | |
| bit 0 | bit 0 da seleção do MUX |
Solução:
A solução está na tabela e no esquema mostrados abaixo.
| Função | ULActrl |
|---|---|
| AND | 000 |
| OR | 001 |
| ADD | 010 |
| SUB | 110 |
| SLT | 111 |
Para projetar este decodificador, precisamos relacionar a entrada, dada pelo opcode e funct 3, com a saída, dada pelo ULActrl. Para tanto, utilizaremos a tabela abaixo para relacionar esses vetores de entrada com os respectivos vetores de saída.
| Instrução | Operação da ULA | opcode | Funct 3 | ULActrl |
|---|---|---|---|---|
| LW | Soma | |||
| SW | Soma | |||
| BEQ | Subtração |
Para projetar este decodificador, precisamos relacionar a entrada, dada pelo funct 7 e funct 3, com a saída, dada pelo ULActrl. Para tanto, utilizaremos a tabela abaixo para relacionar esses vetores de entrada com os respectivos vetores de saída.
| Instrução | Operação da ULA | funct 7 | funct 3 | ULActrl |
|---|---|---|---|---|
| AND | E lógico | |||
| OR | OU lógico | |||
| ADD | Soma | |||
| SUB | Subtração | |||
| SLT | Subtração |
De posse dessas duas tabelas, preenchidas, podemos tratar a relação entre cada bit de saída com as entradas como sendo uma tabela da verdade individual, o que evita erros de implementação.
Responder o quiz de participação, no blackboard, em:
Conteúdos > Participação > Aula_16_Quiz-P1
De acordo com o tipo de instrução, os bits do imediato estão distribuídos de forma diferente dentro da instrução.

Para reordenar esses bits e conseguir o imediato necessário para a execução, pode-se usar a concatenação em VHDL e MUXes para selecionar o resultado adequado à instrução sendo executada.
No caso das instruções do grupo A, precisaremos de MUXes de 4 entradas. Por isso, deixamos dois bits na palavra de controle para executar essa seleção.
Uma solução mais otimizada utilizaria MUXes de tamanhos diferentes, permitindo economizar hardware. Isso é interessante em implementações simples (pequenas) do RISC V.
A imagem abaixo mostra o mapeamento do tamanho desses MUXes.

Uma vez implementados e testados os decodificadores da ULA, vamos implementar a Unidade de Controle do Fluxo de Dados.
Da mesma forma que na implementação dos decodificadores da ULA, teremos que levantar todas entradas e saídas necessárias para este controlador.
Ele deve atuar em todos os pontos de controle do fluxo de dados.
Inicialmente, para entender o problema, devemos levantar a quantidade de pontos de controle do FD.
Em seguida, devemos analisar os efeitos da ativação e desativação de cada ponto de controle do FD e resumir em uma tabela.
O próximo passo é relacionar esses efeitos com o funcionamento de cada instrução (ou tipo de instrução) a ser executada.
Finalmente, chegamos à etapa mais emocionante: a construção da tabela relacionando as entradas e saídas desejadas. Para facilitar o trabalho, a leitura do Apêndice C do livro texto, em especial o ítem C2, será de grande valia.
De posse dessa tabela preenchida, podemos criar o código VHDL.
Inicialmente, precisamos definir o conteúdo da palavra de controle. O desenho do FD está na figura abaixo.
Para manter um padrão, utilizaremos os nomes já descritos no desenho. Liste, da esquerda (MSB) para a direita (LSB), todos os pontos de controle e os seus nomes. Esses serão os nossos sinais de saída.
Os sinais de entrada são os bits que definem a instrução a ser executada. Eles são:
Campo de opcode (bit 6 até bit 0) da instrução;
Campo de funct 3 (bit 14 até bit 12) da instrução.
Para facilitar o trabalho, temos, abaixo, a tabela com as instruções e os pontos de controle. Basta preencher, para cada instrução, quais os pontos ativos.
| Instrução | opcode | funct_3 | MUX_Ger_Im | Hab_Escr_Reg | MUX_Rs2_Im | Tipo_R | MUX_ULA_MEM | BEQ | HabLerMEM | HabEscrMEM |
|---|---|---|---|---|---|---|---|---|---|---|
| AND | 0110011 | 111 | ||||||||
| OR | 0110011 | 110 | ||||||||
| ADD | 0110011 | 000 | ||||||||
| SUB | 0110011 | 000 | ||||||||
| SLT | 0110011 | 010 | ||||||||
| LW | 0000011 | 010 | ||||||||
| SW | 0100011 | 010 | ||||||||
| BEQ | 1100111 | 000 |
Com a tabela preenchida, para todas as instruções, devemos levantar as equações para a ativação de cada ponto de controle. A forma mais simples é fazer a ativação do ponto de controle através da lógica OR entre as instruções que ativam esse ponto. Ou seja, na coluna de um ponto de controle, toda instrução que tiver o valor 1 preenchido, fará parte dessa lógica OR.
Responder o quiz de participação, no blackboard, em:
Conteúdos > Participação > Aula_16_Quiz-P2
De posse das equações, ou circuito, deve ser feita:
A implementação em VHDL;
O teste de funcionamento;
A integração com o Fluxo de Dados e seu teste completo:
Na aba de Projetos, junto com a descrição do Projeto 2, temos os programas de teste que serão utilizados na avaliação do funcionamento do RISC V.
Esta atividade faz parte da entrega intermediária. Utilizem o horário de atendimento para avaliar o andamento e funcionamento do seu projeto.
Esta Atividade deverá ser entregue através do Blackboard!