7.1. Trabajo de prácticas: Multiplicador serie

7.1.1. Objetivos

El objetivo general de este trabajo es la realización de un multiplicador serie e implementarlo en la tarjeta DE10-Lite. El multiplicador tomará dos datos de cuatro bits y los multiplicará. El resultado se debe presentar en 16 bits.

Este trabajo se realizará individualmente.

7.1.2. Introducción

La especificación funcional del multiplicador serie es la siguiente:

  • Entradas:

    \(x = (x_{n-1}, \cdots x_{1},x_{0}) \; x_i \in \{0,1\}\); \(0 \leq x \leq 2^n – 1\)

    \(y = (y_{m-1}, \cdots y_{1},y_{0}) \; y_i \in \{0,1\}\); \(0 \leq y \leq 2^m – 1\)

  • Salida: \(p = (p_{m+n-1}, \cdots p_1, p_0) \; p_k \in \{0,1\}\); \(0 \leq p \leq (2^n – 1) (2^m – 1)\)

  • Función:

../../_images/image17.png

Para la realización de un multiplicador serie utilizamos la siguiente expresión:

../../_images/image18.png

en la que 1/2 significa un desplazamiento hacia la derecha. Esta ecuación se resuelve aplicando el siguiente pseudo-código:

i = 4;
p_high = 0;
p_low = y_in;
op: p = p_high & p_low;
if p(0) = 1 then {p_high = p_high + x_in};
     p = p >>1;
     p_high = p[15:8];
     p_low = p [7:0];
     i = i -1;
 if (i != 0) then {goto op};
 resultado = p;

Advertencia

En la operación :math: p_high = p_high + x_in hay que tener en cuenta el posible desbordamiento.

el número de iteraciones es igual al numero de bits de la variable \(y\). Un ejemplo que resuelve el producto de 9x9 (1001x1001 = 0101 0001) sería el siguiente:

Paso#

índice

valor de p

Comentario

1

i = 4

0000 1001

p se inicializa con el valor de y: (\(p_h = 0 \; p_l = y\))

2

i = 4

1001 1001
0100 1100
\(p(0) = 1 \Rightarrow p_h = p_h + x\)
\(p \gg 1\) desplaza p a la derecha (\(p = \frac{1}{2} p\))

3

i = 3

0100 1100
0010 0110
\(p(0) = 0 \Rightarrow p_h = p_h\)
\(p \gg 1\) desplaza p a la derecha (\(p = \frac{1}{2} p\))

4

i = 2

0010 0110
0001 0011
\(p(0) = 0 \Rightarrow p_h = p_h\)
\(p \gg 1\) desplaza p a la derecha (\(p = \frac{1}{2} p\))

5

i = 1

1010 0011
0101 0001
\(p(0) = 1 \Rightarrow p_h = p_h + x\)
\(p \gg 1\) desplaza p a la derecha (\(p = \frac{1}{2} p\))

i = 0

0101 0001

Resultado final

7.1.3. Esquema general del multiplicador

El circuito multiplicador estará constituido por la unidad de control y por una unidad de data-path, según se muestra en la Figura 7.1.

../../_images/image20.png

Figura 7.1 Diagrama de bloques del Multiplicador serie con la unidad de control y la unidad de data-path.

La unidad de control generará dos señales. La señal de inicio indicará que comenzamos la realización de un nuevo producto y la señal de enable activará el proceso de multiplicación, habilitando un contador que hará la función del indice i en el algoritmo de multiplicación.

7.1.3.1. Definición del data-path

Las operaciones necesarias son una suma (en el caso que \(p(0) = 1\) se suma x y si \(p(0) = 0\) se suma 0) y un desplazamiento hacia la derecha (que se consigue conectando correctamente las salidas del sumador). La realización de este circuito se hace siguiendo el siguiente diagrama de bloques, que corresponde al data-path del multiplicador serie:

../../_images/image19.png

Figura 7.2 Diagrama de bloques del data-path del multiplicador serie.

El registro de salida mantendrá siempr el valor de p. Los multiplexores a su entrada se usan para inicializar p. El sumador realiza la operación de suma de la parte alta de p (\(p_h\)) con \(x\) o con 0, según sea el valor de \(p(0)\) que representa el valor de \(y(0)\).

La descripción VHDL del diseño se va a realizar en VHDL a partir del esquema de la Figura 7.2. A este circuito habrá que añadir un contador (no mostrado en la Figura 7.2) que indicaría el número de ciclos de reloj que necesita este circuito para tener el resultado final. El resultado final (p), se almacenará en un registro de 8 bits (no mostrado en la Figura 7.2).

7.1.3.2. Definición de la unidad de control

La unidad de control del multiplicador se realizará mediante una MEF que siga el siguiente diagrama de estados.

../../_images/image21.png

Figura 7.3 Diagrama de estados del control del Multiplicador serie.

7.1.4. Trabajo previo

Antes de realizar la descripción VHDL del multiplicador serie debe realizarse un esquema con los distintos elementos que lo van a componer. Para la descripción de la máquina de control se utilizará el VPL del Campus Virtual.

7.1.5. Trabajo de laboratorio

7.1.5.1. Describir la unidad de data-path en VHDL y y simular con Modelsim-Altera

En primer lugar se deberá describir en VHDL el data-path que se representa en la Figura 7.2 siguiendo la descripción del apartado definición del data-path. Los registros que aparecen en este esquema deben realizarse con el código VHDL del Listado 7.1 (registro de n bits).

En quartus se debe crear un proyecto nuevo con la denominación TrabajoPR1.qpf y seleccionando las opciones básicas utilizadas en las prácticas de la asignatura. En este proyecto lo primero que haremos es incluir la descripción realizada del data-path que denominaremos multiplier_datapath.vhd. Posteriormente procederemos a realizar su simulación según el apartado siguiente. Por ahora no será necesario incluir la máquina de control descrita en el VPL, ya que estableceremos la señales de control inicio y enable dándoles los valores pertinentes.

7.1.5.1.1. Simular este circuito usando Modelsim-Altera

Para hacer la simulación del data-path se debe declarar a multiplier_datapath.vhd como el top-level del circuito. Ademas, se deben incluir un contador de 4 pulsos de reloj que debe realizarse según el código VHDL del Listado 7.2. Añadir a Quartus las descripciones VHDL proporcionadas en el Campus Virtual: registro_enable.vhd ( Listado 7.1) y contador_k.vhd ( Listado 7.2). La simulación del data-path se realizará con el siguiente procedimiento:

  1. Crear un nuevo fichero de formas de onda con el University Wafeform VWF (Waveform.vwf).

  2. Introducir todos los pines del circuito en el diagrama de formas de onda.

  3. Ordenar las señales según se observa en la siguiente figura:

../../_images/image22.png

Figura 7.4 Señales para simular el data-path del multiplicador.

  1. Establecer el tiempo de simulación en 500 ns.

  2. Seleccionar para x_in, y_in y p_out el radix como “Unsigned Decimal”.

  3. Establecer una señal de reloj de 20 MHz y el resto de las señales tal como aparece en la figura siguiente:

../../_images/image23.png

Figura 7.5 Estímulos para simular el data-path del multiplicador.

  1. Realizar la simulación y comprueba que el resultado es el siguiente, donde se observa que al multiplicar 9x9 el resultado es 81.

../../_images/image24.png

Figura 7.6 Resultados de simulación del data-path del multiplicador.

7.1.5.2. Implementación en Quartus II

Una vez simulado el data-path, se deben incorporar el control descrito previamente en el VPL y el multiplicador_top en Quartus II. Para comprobar el funcionamiento correcto del multiplicador_top se pueden realizar simulaciones en EDAPlyground usando el testbench del Listado 7.5. En el Campus Virtual se proporciona la asignación de pines del circuito. La conexión de los pines se muestra en la siguiente Figura.

../../_images/image27.jpeg

Figura 7.7 Pin-out de la Práctica 6.

7.1.6. Entregables

7.1.6.1. Trabajo previo

Por hacer

ET1.1. Memoria de trabajo incluyendo el diagrama de ejecución del multiplicador.

ET1.2. Diagrama de bloques completo del Multiplicador serie.

7.1.6.2. Trabajo VPL y de laboratorio

Por hacer

ET1.3. Realizar la descripción VHDL de la unidad de control del Multiplicador serie usando el VPL del Campus Virtual.

ET1.4. Realizar la descripción VHDL funcional del data-path del multiplicador serie del apartado Describir la unidad de data-path en VHDL y y simular con Modelsim-Altera.

ET1.5. Implementación del multiplicador serie en la tarjeta DE10-Lite.

7.1.7. Listados VHDL

Lista 7.1 Código VHDL de un registro de n bits con reset y enable (registro_enable.vhd)
-- Ver en el campus Virtual de la Asignatura
Lista 7.2 Código VHDL de un contador de k pulsos de reloj (contador_k).
-- Ver en el campus Virtual de la Asignatura
Lista 7.3 ENTITY del multiplicador_top.vhd.
ENTITY multiplier_top IS
  PORT(
     x_in        : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
     y_in        : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
     start_in    : IN STD_LOGIC;
     product_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
     done_out    : OUT STD_LOGIC;
     reset_n     : IN STD_LOGIC ;
     clock       : IN STD_LOGIC);
END multiplier_top;
Lista 7.4 Fichero VHDL TrabajoPR1.vhd.
-- Ver en el campus Virtual de la Asignatura
Lista 7.5 Testbench del multiplicador serie (multiplier_tb).
--Electronica Digital 2º curso EITE/ULPGC
--Para usar únicamente en los Trabajos de asignatura
--Tesbecnh sencillo para multiplicador serie

library ieee;
  use ieee.std_logic_1164.all;
  use WORK.ALL;
  
entity multiplier_tb is
end multiplier_tb;

architecture tb of multiplier_tb is
  component multiplier
    generic(n : INTEGER := 4;  -- number of bits in operands
            m : INTEGER := 2); 
    port (start_in : in  std_logic;
          x_in     : in  std_logic_vector (3 downto 0);
          y_in     : in  std_logic_vector (3 downto 0);
          clock    : in  std_logic;
          p_out    : out std_logic_vector (7 downto 0);
          done_out : out std_logic;
          reset_n  : in  std_logic);
  end component;
  signal start_in   : std_logic;
  signal x_in       : std_logic_vector (3 downto 0);
  signal y_in       : std_logic_vector (3 downto 0);
  signal clock      : std_logic;
  signal p_out      : std_logic_vector (7 downto 0);
  signal done_out   : std_logic;
  signal reset_n    : std_logic;
  signal TbClock    : std_logic := '0';
  signal TbSimEnded : std_logic := '0';
  constant TbPeriod : time := 40 ns; 
begin
  dut : multiplier
    generic map (4, 2)
    port map (start_in => start_in,
              x_in     => x_in,
              y_in     => y_in,
              clock    => clock,
              p_out    => p_out,
              done_out => done_out,
              reset_n  => reset_n);
  TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
  clock <= TbClock;
  stimuli : process
  begin
    start_in <= '0';
    x_in <= (others => '0');
    y_in <= (others => '0');
    reset_n <= '1';
    wait for 20 ns;
    reset_n <= '0';  -- Se hace un reset del sistema
    wait for 60 ns;
    reset_n <= '1';
    wait for 80 ns;
    x_in <= "1001";  -- Se hace el producto de 9x6
    y_in <= "0110";
    start_in <= '1';
    wait for 6 * TbPeriod;
    start_in <= '0';
    wait for 6 * TbPeriod;
    x_in <= "0101";   -- Se hace el producto de 5x9
    y_in <= "1001";
    start_in <= '1';
    wait for 6 * TbPeriod;
    start_in <= '0';
    wait for 6 * TbPeriod;
    -- Stop the clock and hence terminate the simulation
    TbSimEnded <= '1';
    wait;
  end process;
end tb;