---
# System prepended metadata

title: Laboratorio 1 Taller de Diseño Digital

---

# Laboratorio 1 Taller de Diseño Digital

## 1. Abreviaturas y definiciones
- **ALU**: Aritmetic-Logic Unit
- **CLA**: Carry-Look-Ahead Adder
- **FA**: Full-Adder
- **FPGA**: Field Programmable Gate Arrays
- **MUX**: Multiplexor
- **RCA**: Ripple-Carry Adder
- **SV**: System Verilog



## 2. Referencias

[1]D. E. Laboratory, 1 Bit Full Adder using Logic Gates. direccion: https://www.iitg.ac.in/cseweb/vlab/Digital-System-Lab/fa_lg.php?id=9

[2] Llombart, V. (2006) Ampliación de Estructura de Computadores, Digital Electronics Laboratory. 3° de Ingeniería Informática. Available at: https://docplayer.es/5248364-5-1-1-sumadores-con-anticipacion-de-acarreo-g-i-a-i-b-i-c-i-c-i-1-p-i-g-i-s-i-p-i-c-i-1-c-0-g-0-c-1-p-0.html

[3] RealDigital. *“Representations of Logic Operations”* . [Online]. Available: https://www.realdigital.org/doc/e127ebfa82dbc904b5c0dac5d1adce8e. 






## 3. Desarrollo

### 3.1 Circuitos digitales discretos  

#### 1. Criterios de diseño
Se deben diseñar 2 bloques: un decodificador 2 a 4 encargado de seleccionar cuál columna del teclado debe responder, y un codificador de prioridad 4 a 2 que debe indicar a cuál fila pertenece la tecla que se está presionando. Para diseñar dichos bloques se construye una tabla de verdad para cada uno, y se construyen mapas de Karnaugh que permitan obtener la función lógica en su forma más sencilla. A continuación se muestran las tablas de verdad para el decodificador con las respectivas funciones que las describen.


![](https://i.imgur.com/ObZJIis.png)



Seguidamente se muestran las tablas de verdad para las salidas A y B del codificador de prioridad 4 a 2, donde A corresponde al bit más significativo. Para la salida A:

![](https://i.imgur.com/Awotkpb.png)


![](https://i.imgur.com/TY8GAp1.png)




Para la salida B:

![](https://i.imgur.com/tdjEoNX.png)




![](https://i.imgur.com/67iTAHa.png)




Una vez resueltos los mapas de Karnaugh se procede a construir con compuertas las funciones lógicas. El decodificador diseñado es el siguiente:

![](https://i.imgur.com/5PWGyg8.png)


El codificador diseñado es el siguiente:

![](https://i.imgur.com/YCcv0ey.png)




Con los circuitos ya diseñados, se conectan los pines correspondientes a las columnas en el teclado como salidas del decodificador y los pines correspondientes a las filas como entradas al codificador. Es importante hacer la siguiente aclaración: para efectos de este diseño, se considera la columna 0 como la columna más a la izquierda del teclado, y se enumeran de izquierda a derecha. Para las filas, se considera la fila 0 como la fila más arriba del teclado, y se enumeran hacia abajo.

### 3.2 Módulo "leds"
#### 1. Encabezado del módulo
```SystemVerilog
module module_leds (
    input  logic   push_button_1,     
    input  logic   push_button_2,
    input  logic   push_button_3,
    input  logic   push_button_4,
    input  logic   [0:3] sw_0_3,
    input  logic   [0:3] sw_4_7,
    input  logic   [0:3] sw_8_11,
    input  logic   [0:3] sw_12_15,
    output logic   [0:3] leds_1,
    output logic   [0:3] leds_2,
    output logic   [0:3] leds_3,
    output logic   [0:3] leds_4,
);
```
#### 2. Parámetros
- Este bloque no contiene parámetros.

#### 3. Entradas y salidas:
- `push_button_1`: Botón que permite apagar el primer grupo de LEDs.
- `push_button_2`: Botón que permite apagar el segundo grupo de LEDs.
- `push_button_3`: Botón que permite apagar el tercer grupo de LEDs.
- `push_button_4`: Botón que permite apagar el cuarto grupo de LEDs.
- `sw_0_3`: Array que contiene la información de las posiciones (encendido o apagado) del primer grupo de switches. Permite encender o apagar los LEDs del primer grupo.
- `sw_4_7`: Array que contiene la información de las posiciones (encendido o apagado) del segundo grupo de switches. Permite encender o apagar los LEDs del segundo grupo.
- `sw_8_11`: Array que contiene la información de las posiciones (encendido o apagado) del tercer grupo de switches. Permite encender o apagar los LEDs del tercer grupo.
- `sw_12_15`: Array que contiene la información de las posiciones (encendido o apagado) del cuarto grupo de switches. Permite encender o apagar los LEDs del cuarto grupo.
- `leds_1`: Array que contiene la información sobre los valores lógicos del primer grupo de LEDs.
- `leds_2`: Array que contiene la información sobre los valores lógicos del segundo grupo de LEDs.
- `leds_3`: Array que contiene la información sobre los valores lógicos del tercer grupo de LEDs.
- `leds_4`: Array que contiene la información sobre los valores lógicos del cuarto grupo de LEDs.

#### 4. Criterios de diseño
Para el diseño, primeramente se describe un ciclo "for" que recorre los 4 valores del array de switches, y transmite esa información al array de LEDs. Por ejemplo, si el valor en la posición 0 del array de switches es 1, esa misma posición 0 debe definirse en 1 en el array de LEDs. De lo contrario, esa posición se define en 0. En otras palabras, se obtiene la información de encendido o apagado de un grupo de switches y controla el grupo de LEDs asociado: si el switch 0 está en posición encendido en la FPGA, el LED 0 debe encenderse. El ciclo "for" se repite para los 4 grupos de switches y LEDs, de esta forma se asocian los 16 interruptores con los 16 LEDs de la FPGA y, a su vez, se dividen en 4 grupos de 4. Estos 4 ciclos "for" tienen la misma identación para que corran en paralelo.

Para los botones, se abre una condición "if": si el botón correspondiente se encuentra en valor lógico 1, se apaga el grupo de LEDs al que está asociado. Se repite este código para los 4 botones (4 grupos de LEDs). Estas condiciones "if" también tienen la misma identación que los ciclos "for" descritos anteriormente, para que los eventos corran en paralelo.

#### 5. Testbench
Las pruebas realizadas son bastante sencillas: inicialmente se definen los botones en valor lógico 0 y se definen unos switches de cada grupo en posición encendido. El grupo 1 tiene en su array [1,0,0,0]. El grupo 2 tiene [1,1,0,0]. El grupo 3 tiene [1,1,1,0]. Y el grupo 4 tiene [1,1,1,1]. A los 10 ns, se presiona el botón 0, y se apaga el grupo 1 de LEDs. A los 20 ns, se presiona el botón 2 y apaga el grupo 3 de LEDs. Al mismo tiempo, el botón 0 se ha mantenido presionado para verificar que al presionar 2 o más botones al mismo tiempo, se apaguen el grupo de LEDs correspondientes al mismo tiempo. A los 30 ns, se deja de presionar el botón 0, por lo que el grupo 1 de LEDS vuelve a encenderse y el grupo 3 de LEDs sigue apagado ya que no se ha dejado de presionar el botón 2. A los 40 ns, se deja de presionar el botón 2, por lo que se vuelve a encender el grupo 3 de LEDs. A los 50 ns, se termina la simulación. A continuación se muesta el gráfico obtenido de la simulación.

![](https://i.imgur.com/deNskAL.png)





### 3.3 Módulo "mux_4_1"
El modulo *module_mux_4_1* corresponde a un multiplexor de 4 entradas y 1 salida parametrizado. El valor de la salida `out` está determinado según el valor de los dos bits de selección de `sel`, siendo posible escoger entre los valores de `a`, `b`, `c` y `d`.

#### 1. Encabezado del módulo
```SystemVerilog
module module_mux_4_1 #(
    parameter ANCHO = 4
)(
    input logic [ANCHO - 1 : 0]     a,
    input logic [ANCHO - 1 : 0]     b,
    input logic [ANCHO - 1 : 0]     c,
    input logic [ANCHO - 1 : 0]     d,
    input logic [1 : 0]             sel,
    output logic [ANCHO - 1 : 0]    out
);
```
#### 2. Parámetros
- `ANCHO`: determina el ancho de datos (*bus width*) de las entradas y salida del mux

#### 3. Entradas y salidas:
- `a`: primera entrada del mux.
- `b`: segunda entrada del mux.
- `c`: tercera entrada del mux.
- `d`: cuarta entrada del mux.
- `sel`: entrada de los bits de selección.
- `out`: única salida del mux.
#### 4. Criterios de diseño
La tabla de verdad del mux 4 a 1 se muestra a continuación

![alt text](https://i.imgur.com/qACH4qD.png "Tabla verdad del mux")



La implementación se realizó con un solo bloque always para el valor de la salida del mux en función del valor actual de `sel`.

#### 5. Testbench
Los testbench se encuentran en `tb_module_mux_4_1_ancho_4.sv`,`tb_module_mux_4_1_ancho_8.sv` y `tb_module_mux_4_1_ancho_16.sv`. En estos testbench se genera una instancia del mux 4 a 1 y se crean entradas de ancho 4, 8 y 16, respectivamente. En cada prueba se realiza para las cuatro selecciones de entrada y para un conjunto de datos de entrada de 50 datos en cada caso.

La imagen que se muestra a continuación corresponde a la simulación post-síntesis. En ella se observa que la salida toma un valor indefinido por aproximadamente ~5.3 ns, posteriormente este valor cambia dado que está cambiando la entrada `a` y la selección se encuentra en *00*.

![alt text](https://i.imgur.com/3lB0co7.png "Post-Synthesis MUX 4 a 1")



### 3.4.1 Módulo "deco_7seg"
Este modulo recibe un valor binario de 4 bits y se encarga de mostrar su equivalente en hexadecimal en un display de siete segmentos. Por lo tanto vamos a describir primeramente el comportamiento de un FA.
#### 1. Encabezado del módulo
```SystemVerilog
module module_deco_7seg(
    input logic  [3:0]   data,
    input logic          dp,
    output logic [7:0]   seg
);
```
#### 2. Parámetros
Este modulo no posee parámetros.

#### 3. Entradas y salidas:
- `data`: este arreglo contiene los 4 bits de entrada a los cuales se les desea mostrar su equivalente en hexadecimal.
- `dp`: entrada que permite habilitar o deshabilitar el punto decimal del display.
- `seg`: corresponde al arreglo que contiene la información sobre cual segmento del display debe ser encendido.

#### 4. Criterios de diseño
Para generar el decodificador se tuvo en cuenta que los display de la FPGA utilizada son de lógica negativa, por lo que se activan con *ceros*. Por ende, se tiene la siguiente tabla de verdad para el decodificador para display de 7 segmentos

![alt text](https://i.imgur.com/lRBkK6f.png "Tabla verdad del decodificador")




#### 5. Testbench

El testbench se encuentra en `tb_module_deco_7seg.sv`. En este archivo se comprueba el funcionamiento del decodificador para los 16 posibles valores que puede tomar la entrada `data`. La siguiente figura muestra una parte de la simulación post-síntesis. Donde se observa que al decodificador le toma alrededor de 5.4 ns en reflejar en la salida el cambio de la entrada.

![alt text](https://i.imgur.com/jzBa08g.png)



### 3.4.2 Módulo "deco_7seg_with_mux"
Este módulo permite mostrar un potencial valor en un display de 7 segmentos. Las entradas se encuentran multiplexadas por un mux de 4 a 1, en donde cada entrada tiene un ancho de palabra de 4 bits.
#### 1. Encabezado del módulo
```SystemVerilog
module module_deco_7seg_with_mux(
    input logic [3 : 0]     sw_1_4,
    input logic [3 : 0]     sw_5_8,
    input logic [3 : 0]     sw_9_12,
    input logic [3 : 0]     sw_13_16,
    input logic [1 : 0]     btn,
    output logic [7 : 0]    enable,
    output logic [7 : 0]    segments
);
```
#### 2. Parámetros
Este modulo no posee parámetros.

#### 3. Entradas y salidas:
- `sw_1_4`: valor binario de entrada del primer grupo de 4 switch de la FPGA.
- `sw_5_8`: valor binario de entrada del segundo grupo de 4 switch de la FPGA.
- `sw_9_12`: valor binario de entrada del tercer grupo de 4 switch de la FPGA.
- `sw_13_16`: valor binario de entrada del cuarto grupo de 4 switch de la FPGA.
- `btn`: arreglo que permite cambiar la selección del mux y así elegir cual de las cuatro entradas se mostrará.
- `enable`: arreglo que se utiliza para habilitar un solo display de la FPGA. 
- `segments`: arreglo que dicta cual de los segmentos se debe encender o apagar.

#### 4. Criterios de diseño
Al momento de realizar este módulo ya se contaba con los bloques del MUX 4 a 1 y el decodificador para display de 7 segmentos. Por lo tanto, solo fue necesario instanciar estos módulos con las variables antes definidas. Posteriormente, en el archivo de constraints `Nexys-4-Master_2.xdc` se mapearon los switches y botones de la FPGA con estas mismas variables.

#### 5. Testbench
Las pruebas fueron realizadas con el archivo `tb_module_deco_7seg_with_mux.sv`. En este testbench se prueban las 4 entradas con un valor distinto cada una. 

En la siguiente imagen se muestra la simulación post-síntesis.

![](https://i.imgur.com/xIOP41A.png)



En la figura anterior se observa que al bloque le toma aproximadamente ~7.5 ns en cambiar el valor del arreglo `segments`.

Asimismo se realizó la simulación post-implementación, la cual se muestra en la siguiente figura.

![](https://i.imgur.com/Lpt6p4R.png)



Aquí, por otro lado, se nota que al bloque le toma ~10.1 ns en reflejar el cambio de la entrada `sw_1_4` en la salida `segments`.

### 3.5.1 Módulo "Full_Adder"
Para el sumador tenemos 3 distintos tipos, el FA, RCA y CLA, estos 2 últimos se basan en "clonar" el módulo del FA cuantas veces seas necesarios para poder sumar 2 distintos valores de bits
#### 1. Encabezado del módulo
```SystemVerilog
module module_full_adder (


    input logic     A,             //Se defienen las entradas y salidas del sistema
    input logic     B,
    input logic     Cin,
    
    output logic    Cout,
    output logic    S

    );
    
    logic n1, n2, n3;            //Se definen los nodos que van a conectar las compuertas lógicas
    
    xor  xor_1 (n1, A, B);      //Se definen y conectan todas las compuertas  para cumplir con el sumador.
    xor  xor_2 (S, n1, Cin);
    and  and_1 (n2, n1, Cin);
    and  and_2 (n3, A, B);
    or   or_1  (Cout, n2, n3);
    
endmodule
```
#### 2. Parámetros
- Lista de parámetros

#### 3. Entradas y salidas:
- `A`: Aquí entra el primer bit a sumar.
- `B`: Entra el segundo bit que se sumará.
- `Cin`: Corresponde al bit de acarreo de entrada que tendrá el suamdor.
- `S`:Es el valor ya sumado entre los bits A y B además del acarreo de entrada.
- `Cout`: Si la suma presenta algun tipo de acarreo será representado por esta salida.

#### 4. Criterios de diseño
Para este diseño del FA nos basamos en varias diseños y tablas de internet de algunos libros para crear el modulo, entonces definimos unos nodos `n1,n2,n3` estos nodos se van a encargar de conectar las 5 compuertas lógicas, estás compuertas llevan dentro de sus valores primeramente la salida de esta y posterior a la salida vienen las entradas, de esta manera `xor xor_inst (out, in1, in2,....);`

![TablaFA](https://i.imgur.com/b8fxG6I.jpg) [1]

![](https://i.imgur.com/jHZjg19.jpg) [1]

Esta es la tabla de verdad y el circuito simplificado en el que nos basamos para realizar el módulo.



#### 5. Testbench
Para realizar las pruebas del FA se tomaron los 8 posibles casos según la tabla de verdad del circuito para verificar si la salida y el acarreo son los valores esperados, como se muestra en la siguiente imagen.

![](https://i.imgur.com/988tPLX.jpg)



### 3.5.2 Módulo "Ripple_Carry_Adder"


#### 1. Encabezado del módulo
```SystemVerilog
module module_ripple_carry_adder #(
    parameter ANCHO = 8 )(                    
    
    input logic     [ANCHO - 1 : 0]     A, 
    input logic     [ANCHO - 1 : 0]     B,
    output logic    [ANCHO  : 0]        S                                     
    );
```



#### 2. Parámetros
Para este sumador se define el paramatero `ANCHO` para escoger tamaño de las entradas y el tamaño de la salida.

#### 3. Entradas y salidas:
- `A`: Primer número binario de "n" bits que queremos sumar.
- `B`: Segundo número binario de "n" bits que deseamos sumar
- `S`: Salida de la suma entre las 2 entradas, posee un bit extra ya que toma en cuenta el acarreo.
#### 4. Criterios de diseño
Para el diseño de este sumador se utilizó la función `generate` de verilogla cual se encarga generar un numero "n" de FA para este caso se le definió un ancho de palabra de 8 bit por lo tanto la función se encarga de generar 8 FA que se conectan entre sí através del `Cout` definido en el modulo del FA, a continuación se muestra de una manera más gráfica.

![](https://i.imgur.com/f1GDDis.png) [2]



#### 5. Testbench

Para la prueba de funcionalidad del RCA se tomaron distintos valores para verificar su funcionalidad y la velocidad que le tomaba la sumador realizar ciertos calculos, a continuación se muestra lo mencionado

![](https://i.imgur.com/sJlSbeo.jpg)



Además de esto es muy importante tener el cuenta el tiempo que le toma al sumador desde el momento en el que entran las entradas hasta el momento en el que se logra realizar el calculo para RCA se tiene un valor de alrededor de **5,211 ns**.

![](https://i.imgur.com/gslLvyr.jpg)


Además de estos testbench se realizó la prueba de un RCA de frecuencia de 100 MHz con entradas de muestra de 64 bits para ver si el sumador era capaz de seguir la suma del caso en el que más acarreo hay, ese caso es cuando por ejemplo en la entrada `A` todos sus valores son 1 y cuando en `B` todos sus valores son ceros exceptuando el ultimo, esto va a generar un extensa cadena de acarreos. A continuación se presenta la simulación post-sintesis de este proceso.

![](https://i.imgur.com/jkNQ6QJ.jpg)


 Como se puede observar el sumador no es capaz de generar una respuesta para una entrada de 64 bits con el caso de mayor acarreo. Además podemos ver como se propaga el acarreo a lo largo del proceso en la siguiente imagen.
 
 ![](https://i.imgur.com/mQUhxxA.jpg)
 

 



### 3.5.3 Módulo "Carry_Look_Ahead_Adder"


#### 1. Encabezado del módulo

```SystemVerilog
module module_carry_look_ahead_adder #(
    parameter ANCHO = 8
    )(
    input  [ANCHO - 1 : 0]  A,                     
    input  [ANCHO - 1 : 0]  B,
    output [ANCHO : 0]      S
   );
```

#### 2. Parámetros
Se tiene el parametro `ANCHO` que se encarga de ver cuantos bits van a tener las entrada, para este caso `A` y `B` tienen 8 bits.

#### 3. Entradas y salidas:
- `A`: Primer número binario de "n" bits que queremos sumar.
- `B`: Segundo número binario de "n" bits que deseamos sumar
- `S`: Salida de la suma entre las 2 entradas, posee un bit extra ya que toma en cuenta el acarreo.

#### 4. Criterios de diseño
Para el diseño se partió de la base de lo que es y hace un CLA.

"Para ganar rapidez en el cálculo del resultado, que consisten en generar el acarreo para cada etapa sin esperar de que llegue de etapas anteriores, a este método se le llama anticipacióndeacarreo."[2]

![](https://i.imgur.com/HnJonGB.png) [2]

Dentro del modulo se definieron 3 operaciones princiales que fueron:

`G[j]   = A[j] & B[j];`
`P[j]   = A[j] | B[j];`
`C[j+1] = G[j] | (P[j] & C[j]);`

La primera se le conoce como **generador de acarreo** y simplemente es una operación `AND`, a la segunda se le conoce como **propagador de acarreo**. Con estas 2 operciones se obtiene la tercera que es el acarreo como tal del sumador.

#### 5. Testbench
Al igual que en el RCA se realizaron las mismas pruebas para comprobar su funcionalidad al 100%

![](https://i.imgur.com/qAU6JJR.jpg)


Además de esto tambien es necesario realizar una comparativa entre el RCA y el CLA para verificar cual de los 2 es más rápido a la hora de realizar un mismo cálculo. Teoricamente debería de ser un tiempo menor al RCA.

![](https://i.imgur.com/FTZXbMX.jpg)



Como se puede observar para el mismo caso del RCA, el CLA le toma **5,2 ns**. Hay una diferencia de **0,011 ns**, pero conforme el tamaño de palabra es más grande más se nota la diferencia de tiempos entre estos 2 tipos de sumadores.



### 3.6 Módulo "ALU"
#### 1. Encabezado del módulo
```SystemVerilog
module ALU #(
     parameter ANCHO = 4                        //Parametrizado del valor del tamaño de la ALU para cada entrada
)(
    input logic     [ANCHO - 1 : 0] ALUA,       //Se definen las entradas de la ALU según los nombres dados en el informe
    input logic     [ANCHO - 1 : 0] ALUB,       //Se definen las entradas de la ALU según los nombres dados en el informe
    input logic     [4 : 0]         ALUControl, //Se definen las entradas de la ALU según los nombres dados en el informe
    input logic     [1 : 0]         ALUFlagIn,  //Se definen las entradas de la ALU según los nombres dados en el informe
    output logic    [1 : 0]         C,          //Bandera de salida C
    output logic    [1 : 0]         Z,          //Bandera de salida Z
    output logic    [ANCHO - 1: 0]  ALUResult   //Se definen las salidas de la ALU según los nombres dados en el informe
   
);
```
#### 2. Parámetros
- `ANCHO`: determina el ancho de datos (*bus width*) de las entradas y salidas para la ALU parametrizable. 

#### 3. Entradas y salidas:
- `ALUA`: Entrada A, de *n* bits a operar.
- `ALUB`: Entrada B, de *n* bits a operar.
- `ALUControl`: Entrada hexadecimal para seleccionar la operación a realizar.
- `ALUFlagIn`: Bandera de entrada de 1 bit a utilizar en diferentes operaciones.
- `C`: Bandera de salida de 1 bit para las funciones de corrimiento que representa el último bit que salió en el corrimiento.
- `Z`: Bandera de salida de 1 bit, llamada de estado cero para todas las funciones, que se asigna en `0` si el resultado es distinto de `0` y en `1` si el resultado es igual a `0`.
- `ALUResult`: Salida de *n* bits que muestra el resultado de la operación realizada seleccionada por la ALU.

#### 4. Criterios de diseño
La ALU se interpretó como un MUX que selecciona cada función lógica o aritmética que opera a los valores A y B de *n* parámetros, por medio de la entrada del módulo **ALUControl**. Dentro de cada selección se encuentra el bloque de la operación que según indicaciones se hace al más alto nivel posible. Se utilizó el trabajo previo realizado para el módulo *MUX_4_1* y se modificaron los detalles específicos a un MUX con todas las entradas y las salidas. Implementado en System Verilog (SV) se ve como un *case* definido con cada valor hexadecimal como indican las instrucciones.


![alt text](https://i.imgur.com/Hk68Nbk.jpg)




Para cada función se diseñó de la siguiente forma:

- `and`: Para esta función se utilizó el operador `&` y se comprobó el funcionamiento mediante la siguiente tabla de verdad:

![alt text](https://i.imgur.com/CE6Hf4N.png) [3]

   

- `or`: Para la función or se utilizó el operador `|` y se comprobó el funcionamiento con la siguiente tabla de verdad:

![alt text](https://i.imgur.com/E4cz8BV.png) [3]

- `suma(en complemento a dos)`: Esta función se realizó con el operador simple de `+`, donde se sumó `ALUA`, `ALUB` y el valor de `ALUFlagIn`, que es el acarreo de entrada que posee la ALU. En el caso que la entrada fuera un número negativo la operación la realiza automatico en complemento a dos.
- `incrementar en uno el operando`: Para esta función se aplicó la adición de una unidad al valor que la entrada seleccionara, que era `ALUA` con la entrada `ALUFlagIn` = `0` y `ALUB` con `ALUFlagIn` = `1`.
- `decrementar en uno el operando`: Para esta función se aplicó la sustracción de una unidad al valor que la entrada seleccionara, que era `ALUA` con la entrada `ALUFlagIn` = `0` y `ALUB` con `ALUFlagIn` = `1`.

- `not (sobre un operando)`: Para esta función se llevó a cabo el mismo proceso de selección de operando que para las funciones anteriores relacionado al valor de `ALUFlagIn`. Se utilizó el operador `~` para aplicar la operación `not` sobre el valor. Se comprobó el funcionamiento mediante la siguiente tabla:

![](https://i.imgur.com/TaYoEG5.png) [3]

- `resta (en complemento a dos)`: Esta función se realizó con el operador simple de `-`, donde se restó `ALUA`, `ALUB` y el valor de `ALUFlagIn`, que es el acarreo de entrada que posee la ALU. Esta función lo hace directamente con complemento a dos.


- `xor`: La operación `xor` se llevó a cabo mediante el operador `^` que operaba las dos entradas de *n* bits. Se comprobó los resultados con la ayuda de la siguiente tabla:

![](https://i.imgur.com/Xi0DoPS.png) [3]

- `corrimiento a la izquierda del operando A`: Esta función se comprende de dos casos, cuando `ALUFlagIn` es `0` y cuando es `1`. Cuando es `0` se hace el corrimiento del valor de `ALUA` la cantidad que tenga establecida `ALUB` y esos espacios se rellenan con `0`. Para esta función se utilizó el operador `<<` que en SV ya se encuentra definido. 
En el segundo caso cuando `ALUFlagIn` es `1` se hace el mismo procedimiento con los valores de entradas, pero para este caso los espacios se rellenan con el valor de `1`, donde se tuvo que implementar un algoritmo de concatenación de números binarios para así lograr el valor esperado. Se adjunta en el Apéndice 1 un diagrama de como éste funciona.

- `corrimiento a la derecha del operando A.` Esta operación tiene el mismo procedimiento que la anterior solo que el corrimiento es a la derecha. Por lo que se utilizó el operador `>>` que en SV ya se encuentra definido. 
En el segundo caso cuando `ALUFlagIn` es `1` se hace el mismo procedimiento con los valores de entradas, pero para este caso los espacios se rellenan con el valor de `1`, donde se implementó un algoritmo de concatenación de números binarios para así lograr el valor esperado. Se adjunta en el Apéndice 2 un diagrama de como éste funciona.

Para ambos corrimientos se definió a `C` como la bandera de salida que me indica el último dígito que salió del proceso, tanto para la derecha como para la izquierda y cuando `ALUFlagIn` es `0` o `1`. Esta variable se asignaba mediante el análisis del valor de entrada antes de realizar la operación, mediante la operación de la variable de posición `ALUA[ANCHO - ALUB]` y `ALUA[ALUB - 1]`, respectivamente para cada corrimiento.

Y en general, para todas las funciones, se implementó la comprobación del resultado cuando es igual o diferente de `0`, mediante la bandera de salida de estado cero `Z`.





#### 5. Testbench
Este testbench se puede encontrar como `tb_module_ALU.sv`, y representa el resultado de la post síntesis de forma exhaustiva de cada una de las funciones a realizar, con valores de entrada de 4 bits solicitados, donde se comprobó el resultado de cada función realizada y también se comprobó los valores de las banderas y que su funcionamiento fuera correcto. Aquí se puede observar para la bandera de estado cero, `Z` es `1` cuando `ALUResult` es `0`. Al igual que para la bandera `C` que representa el último dígito que salió del corrimiento. De la misma forma que para todas las demás funciones.

![](https://i.imgur.com/UTATZex.png)











## Apendices:
### Apendice 1:
Para el corrimiento a la izquierda primero se realiza el corrimiento con el valor de `0` y la función antes mencionada, luego se calcula el valor mediante la lógica como la de la imagen de elevar el valor de `10` con un factor creciente hasta el número `n` de bits y por último se suma al valor antes desplazado. De esta forma se concatena el valor.

![](https://i.imgur.com/WhfdbYY.png)



### Apendice 2:

Para el corrimiento a la derecha primero se realiza el corrimiento con el valor de `0` y la función antes mencionada, luego se calcula el valor mediante la lógica como la de la imagen de elevar el valor de `10` con un factor decreciente hasta el número `0` y por último se suma al valor antes desplazado. De esta forma se concatena el valor.

![](https://i.imgur.com/nawQ1VB.png)

