retorno de banco de prueba del sumador de serie VHDL UUUU

1

Hace algunas semanas diseñé este sumador en serie, luego lo dejé pasar por un tiempo y ahora me gustaría indicar si funciona o no ...

Así que el diseño es este this

Y le informo el banco de pruebas que he intentado escribir por mi cuenta, cada vez que trato de hacer un banco de pruebas por mi cuenta siempre tengo problemas, ya que no tengo en cuenta las cosas relacionadas con la sincronización.

Entonces ... debajo está el código

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;

entity tb_serialAdder is
end entity tb_serialAdder;

architecture arch of tb_serialAdder is

    component serialAdder
        generic(n : natural := 4);
        port(x : in std_logic_vector(n - 1 downto 0);
             y : in std_logic_vector(n - 1 downto 0);
             clk : in std_logic;
             load : in std_logic;
             clr : in std_logic;
             z : out std_logic_vector(n - 1 downto 0));
    end component;

    signal clk, load, clr : std_logic;
    signal x, y , z : std_logic_vector(3 downto 0);
    constant clk_period : time := 10 ns;
begin

    serialAdderComp : serialAdder
        generic map(n => 4)
        port map(x => x, y => y, clk => clk, load => load, clr => clr, z => z);

    clk_proc : process is
    begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
    end process clk_proc;

    process is
        file out_file : text open write_mode is "output_serial_adder.txt";
        variable line_out : line;
    begin
        clr <= '1';
        wait for clk_period;
        clr <= '0';
        wait for clk_period;
        x <= "0101";
        y <= "0111";
        load <= '1';
        wait for clk_period;
        load <= '0';
        wait for clk_period;
        wait for 5*clk_period;
        write(line_out,z);
        writeline(out_file,line_out);
        wait;
    end process;    

end architecture arch;

Cuando comienzo la prueba (la sintaxis es correcta), entonces lo que veo es UUUU .

Lo que me preocupa probablemente sea: 1. El diseño es incorrecto ... (creo que es incorrecto al 65%) 2. El banco de pruebas está mal ... (pero no entiendo por qué ... excepto que podría ser un problema de sincronización).

Por favor ... ¿alguna pista?

Actualización:

Probablemente sea mejor que incluya el código de mi sumador serial ...

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;

entity serialAdder is
    generic(n : natural := 4);
    port(x : in std_logic_vector(n - 1 downto 0);
         y : in std_logic_vector(n - 1 downto 0);
         clk : in std_logic;
         load : in std_logic;
         clr : in std_logic;
         z : out std_logic_vector(n - 1 downto 0));
end entity serialAdder;

architecture arch of serialAdder is
    signal x_reg : std_logic_vector(n - 1 downto 0);
    signal y_reg : std_logic_vector(n - 1 downto 0);
    signal z_reg : std_logic_vector(n - 1 downto 0);
    signal c_reg : std_logic;
begin
    process(clk) is --handling of registers "x" and "y", synchronous
    begin

        if rising_edge(clk) then
            if clr = '1' then --clear all the registers, and flip flop
                x_reg <= (others => '0');
                y_reg <= (others => '0');
                c_reg <= '0';
                z_reg <= (others => '0');
            elsif load = '1' then
                x_reg <= x;
                y_reg <= y;
            else --execute sum
                x_reg <= '0' & x_reg(n - 1 downto 1); --right input register shift
                y_reg <= '0' & y_reg(n - 1 downto 1);       

                --full adder logic      
                z_reg <= (x_reg(0) xor y_reg(0) xor c_reg) & z_reg(n - 1 downto 1); --right shift and adding a new bit
                c_reg <= (c_reg and x_reg(0)) or (c_reg and y_reg(0)) or (x_reg(0) and y_reg(0)); --carry update
            end if;
        end if;
    end process;

    z <= z_reg; --update of the output

end architecture arch;

Actualización 2 ...

He modificado el banco de pruebas como se sugiere, el resultado es el siguiente:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;

entity tb_serialAdder is
end entity tb_serialAdder;

architecture arch of tb_serialAdder is

    component serialAdder
        generic(n : natural := 4);
        port(x : in std_logic_vector(n - 1 downto 0);
             y : in std_logic_vector(n - 1 downto 0);
             clk : in std_logic;
             load : in std_logic;
             clr : in std_logic;
             z : out std_logic_vector(n - 1 downto 0));
    end component;

    signal clk, load, clr : std_logic;
    signal x, y , z : std_logic_vector(3 downto 0);
    constant clk_period : time := 10 ns;
begin

    serialAdderComp : serialAdder
        generic map(n => 4)
        port map(x => x, y => y, clk => clk, load => load, clr => clr, z => z);

    clk_proc : process is
    begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
    end process clk_proc;

    sum_test : process is
        file out_file : text open write_mode is "output_serial_adder.txt";
        variable line_out : line;
    begin
        clr <= '1';
        wait for clk_period;
        clr <= '0';
        wait for clk_period;
        x <= "0101";
        y <= "0111";
        load <= '1';
        wait for clk_period;
        load <= '0';
        wait for 4*clk_period;
        write(line_out,z);
        writeline(out_file,line_out);
        wait;
    end process;    

end architecture arch;

Si comienzo la simulación con ModelSim (que utiliza internamente vsim i supongo) tanto la compilación como la simulación funcionan bien ... sin embargo, si intento con ncsim, algo sucede ... En primer lugar, cuando comienzo ncelab, dice que el componente serialAdder no está limitado, en segundo lugar, la salida siempre es UUUU ...

Todavía me falta algo, ¿alguna pista?

    
pregunta user8469759

2 respuestas

2

Mirando más de cerca tu código, veo que tienes dos procesos separados asignando valores a z_reg . Me sorprende que esto no te dé errores de compilación. Cuando los dos procesos intenten asignar valores diferentes, obtendremos U valores en la salida.

Sería mucho mejor escribir todo su código como un solo proceso. También sería mejor convertir todas las asignaciones a sus registros en asignaciones síncronas (es decir, en un borde del reloj), en lugar de tener una combinación de asignaciones asíncronas y síncronas. Utilice elsif y else para asegurarse de que las múltiples asignaciones a las variables se excluyan mutuamente.

Aquí hay una implementación optimizada de su sumador:

architecture arch of serialAdder is
  signal x_reg : std_logic_vector(n - 1 downto 0);
  signal y_reg : std_logic_vector(n - 1 downto 0);
  signal z_reg : std_logic_vector(n - 1 downto 0);
  signal c_reg : std_logic;
begin

  process (clk)
  begin
    if rising_edge(clk) then
      if clr = '1' then
        -- clear all registers
        x_reg <= (others => '0');
        y_reg <= (others => '0');
        z_reg <= (others => '0');
        c_reg <= '0';
      elsif load = '1' then
        -- load X and Y registers from inputs
        x_reg <= x;
        y_reg <= y;
      else
        -- shift all of the registers
        x_reg <= '0' & x_reg(n - 1 downto 1);
        y_reg <= '0' & y_reg(n - 1 downto 1);
        z_reg(n - 1 downto 1) <= z_reg(n - 2 downto 0) & '0';

        -- do the addition
        z_reg(0) <= x_reg(0) xor y_reg(0) xor c_reg;
        c_reg <= (c_reg and x_reg(0)) or (c_reg and y_reg(0)) or (x_reg(0) and y_reg(0));
      end if;
    end if;
  end process;

  -- update of the output
  z <= z_reg;

end architecture arch;

Seguimiento:

Corrí tus dos archivos a través de Modelsim como está, y la simulación funcionó bien para mí. Aquí está la pantalla de forma de onda:

Tengaencuentaquelasalidaesiguala"1100" donde la he circulado, que es el resultado correcto. Sin embargo, el archivo de salida contiene "0011", que es el valor de salida dos relojes más tarde, porque z_reg continúa cambiando.

No sé por qué sigues recibiendo "UUUU".

    
respondido por el Dave Tweed
0

Bien, si aún recibe este error:

En primer lugar, cuando inicio ncelab, dice que el componente serialAdder no está limitado

entonces ese es tu problema. Los componentes sin encuadernación significan que, básicamente, Incisiv sabe que hay un agujero en el diseño, pero no puede encontrar nada que encaje. En otras palabras, es simular el diseño como si su serialAdder no estuviera realmente allí. Si observa el diseño en la GUI de NCSim, verá que el bloque serialAdder está en una casilla negra (no hay contenido) y, por lo tanto, todas sus salidas se activan automáticamente con la "U".

En cuanto a la razón por la cual no está dando los errores de compilación que otra persona mencionó, es porque está usando std_logic (_vector), que es un tipo resuelto y permite varios controladores. La síntesis puede quejarse si tiene varios controladores, pero la simulación está perfectamente feliz con ella. Si desea obtener errores de compilación si accidentalmente tiene varios controladores de una señal, necesita usar std_ulogic (_vector).

    
respondido por el David Smith

Lea otras preguntas en las etiquetas