¿Por qué está cambiando el tiempo de espera para los cambios lógicos en mi ALU de 32 bits?

0

Mi código para el cambio lógico a la derecha es el siguiente:

ENTITY Ror32 IS
PORT(
a_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END Ror32;

ARCHITECTURE ror_inAction OF Ror32 IS begin

    result(30 downto 0) <= a_in(31 downto 1);
    result(31) <= '0';

end ror_inAction;

Mi código para el desplazamiento a la izquierda es el siguiente:

ENTITY rol32 IS
PORT(
a_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END rol32;

ARCHITECTURE rol_inAction OF rol32 IS begin

    result(31 downto 1) <= a_in(30 downto 0);
    result(0) <= '0';

end rol_inAction;

Este es el circuito que quería programar:

Miprogramaparaeldiagramaanterioreselsiguiente:

ENTITYALUISPORT(a:INSTD_LOGIC_VECTOR(31DOWNTO0);b:INSTD_LOGIC_VECTOR(31DOWNTO0);op:INSTD_LOGIC_VECTOR(2DOWNTO0);result:OUTSTD_LOGIC_VECTOR(31DOWNTO0);cout:OUTSTD_LOGIC;zero:OUTSTD_LOGIC);ENDALU;ARCHITECTUREdescriptionOFALUIS--2-to-1MUXCOMPONENTmux2_1PORT(A,B:inSTD_LOGIC_VECTOR(31DOWNTO0);S:inSTD_LOGIC;Z:outSTD_LOGIC_VECTOR(31DOWNTO0));ENDCOMPONENT;--NOTCOMPONENTnot32PORT(x:INSTD_LOGIC_VECTOR(31DOWNTO0);y:OUTSTD_LOGIC_VECTOR(31DOWNTO0));ENDCOMPONENT;--ANDCOMPONENTand32PORT(a:INSTD_LOGIC_VECTOR(31DOWNTO0);b:INSTD_LOGIC_VECTOR(31DOWNTO0);cout:OUTSTD_LOGIC_VECTOR(31DOWNTO0));ENDCOMPONENT;--ORCOMPONENTor32PORT(a:INSTD_LOGIC_VECTOR(31DOWNTO0);b:INSTD_LOGIC_VECTOR(31DOWNTO0);cout:OUTSTD_LOGIC_VECTOR(31DOWNTO0));ENDCOMPONENT;--ADDERCOMPONENTadd32PORT(a_in:INSTD_LOGIC_VECTOR(31DOWNTO0);b_in:INSTD_LOGIC_VECTOR(31DOWNTO0);c_in:INSTD_LOGIC;result:OUTSTD_LOGIC_VECTOR(31DOWNTO0);c_out:OUTSTD_LOGIC);ENDCOMPONENT;--LEFT-SHIFTCOMPONENTrol32PORT(a_in:INSTD_LOGIC_VECTOR(31DOWNTO0);result:OUTSTD_LOGIC_VECTOR(31DOWNTO0));ENDCOMPONENT;--RIGHT-SHIFTCOMPONENTRor32PORT(a_in:INSTD_LOGIC_VECTOR(31DOWNTO0);result:OUTSTD_LOGIC_VECTOR(31DOWNTO0));ENDCOMPONENT;--6-to-1MUXCOMPONENTmux6to1PORT(A,B,C,D,E,F:inSTD_logic_vector(31downto0);S:instd_logic_vector(2downto0);O:outstd_logic_vector(31downto0));ENDCOMPONENT;--CheckresultCOMPONENTzeroCheckerPORT(Out_ALU:INSTD_LOGIC_VECTOR(31downto0);Out_Zero:OUTSTD_LOGIC);ENDCOMPONENT;--1-bitNOT-gateCOMPONENTnotGatePORT(ain:instd_logic;aout:outstd_logic);ENDCOMPONENT;-------IntermediateSignals--signalsgoingto2-to-1muxsignalB_inv:STD_LOGIC_VECTOR(31DOWNTO0);--signalcomingoutof2-to-1muxsignalB_res:STD_LOGIC_VECTOR(31DOWNTO0);--signalcomingoutofANDsignalAND_result:STD_LOGIC_VECTOR(31DOWNTO0);--signalcomingoutofORsignalOR_result:STD_LOGIC_VECTOR(31DOWNTO0);--signalcomingoutofADDsignalADD_result:STD_LOGIC_VECTOR(31DOWNTO0);--signalcomingoutofSUB--signalSUB_result:STD_LOGIC_VECTOR(31DOWNTO0);--signalcomingoutofROLsignalROL_result:STD_LOGIC_VECTOR(31DOWNTO0);--signalcomingoutofRORsignalROR_result:STD_LOGIC_VECTOR(31DOWNTO0);--signalpassingintoORgatesignalZero_check:STD_LOGIC;--signaltostoretheResultsignalRes_intermediate:STD_LOGIC_VECTOR(31DOWNTO0);----MappingsignalsandportsBEGINMuxNo1:mux2_1portmap(A=>b,B=>B_inv,S=>op(2),Z=>B_res);NotForB:not32portmap(x=>B,y=>B_inv);And_Block:and32portmap(a=>A,b=>B_res,cout=>AND_result);Or_Block:or32portmap(a=>A,b=>B_res,cout=>OR_result);Add_Block:add32portmap(a_in=>A,b_in=>B_res,c_in=>op(2),result=>ADD_result,c_out=>cout);Right_Block:Ror32portmap(a_in=>A,result=>ROR_result);Left_Block:rol32portmap(a_in=>A,result=>ROL_result);Final_Mux:mux6to1portmap(A=>AND_result,B=>OR_result,C=>ADD_result,D=>ADD_result,E=>Ror_result,F=>rol_result,S=>op,O=>Res_intermediate);Zero_OR:zeroCheckerportmap(Res_intermediate,Zero_check);FinalNot:notGateportmap(ain=>Zero_check,aout=>zero);result<=Res_intermediate;ENDdescription;

Porextrañoqueparezca,laseñaldeejecucióncambiaamedidaquecambiaelvalordeB(laentradaquenotieneconexiónconlasoperacionesdecambiológico).

CuandoelvalordeBesbajo,laejecuciónseconvierteenaltaactiva:

LaejecuciónseconvierteenbajaactivacuandoelvalordeBesmayor:

El sumador de 32 bits es la única entidad que trata explícitamente con la ejecución:

ENTITY add32 IS
PORT(
a_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
c_in:  IN STD_LOGIC;
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
c_out : OUT STD_LOGIC
);
END add32;

ARCHITECTURE add32_inAction OF add32 IS 
 component fulladd is
 port(
    a: IN STD_LOGIC;
     b: IN STD_LOGIC;
     cin: IN STD_LOGIC;
     sum: OUT STD_LOGIC;
     cout: OUT STD_LOGIC
     );
  end component;

-- signal wire:STD_LOGIC_VECTOR(30 DOWNTO 0);

    signal wire: STD_LOGIC_VECTOR(32 DOWNTO 0);

 begin

    wire(0) <= c_in;
    FA_f: for i in 0 to 31 generate
        FA_i: fulladd PORT MAP
        (a_in(i), b_in(i), wire(i), result(i), wire(i+1));
    end generate FA_f;

    c_out <= wire(32);
end add32_inAction;

No entiendo la causa de este comportamiento. En primer lugar, no entiendo cómo las operaciones de mi turno influencian a Carry-out. Además de eso, me parece aún más desconcertante que los cambios en B están cambiando el estado de la señal de Llevar a cabo. No escribí el código para que ocurra tal comportamiento.

EDITAR:

Gracias a la respuesta dada por Dave Tweed, ahora sé que conecté el bit de transferencia de la unidad Adder / Subtractor con el bit de transferencia de la ALU en mi archivo de nivel superior. Ahora lo estudiaré más de cerca.

EDIT 2:

Como Dave Tweed señaló, op(2) está conectado a Carrry-In y el Carry-Out de mi sumador está conectado al cout de mi ALU. Por lo tanto, cuando selecciono cualquier operación en la que op(2) es 1 (SUB, ROL y ROR), el resultado, IF generado, aparecerá en mi ventana de formas de onda. Esto se debe a que SUB (que genera el arrastre en la mayoría de los casos) ocurre en paralelo (al igual que todas las demás operaciones) y su arrastre está conectado al arrastre de la ALU, por lo que aparecerá en la ventana de formas de onda. .

    
pregunta a_sid

1 respuesta

2
  

No escribí el código para que ocurra tal comportamiento.

Sí, lo hiciste.

c_out de su Add_Block está siempre conectado directamente a cout de su ALU , independientemente del valor de op . Y el sumador siempre responde a los valores de las entradas A y B . Tenga en cuenta también que MuxNo1 siempre responde al valor de op(2) .

Lo que estás viendo es exactamente lo que escribiste. Probar las señales internas para ver por ti mismo. Este es un hábito que debes desarrollar siempre que las cosas no se comporten como se espera.

Comentario lateral: para empezar, VHDL es un lenguaje detallado, y has compuesto los asuntos en al menos un orden de magnitud al usar una gran cantidad de código fuente para describir lo que realmente es una función muy simple, hasta el punto en el que He ocultado por completo los detalles que llevaron al problema anterior. Debe aprender a utilizar el poder del lenguaje para que la funcionalidad real de un módulo sea lo más clara posible. Esto ayudará tanto a usted como a otras personas que necesitan leer su código.

Solo para darle una idea general, aquí se explica cómo se puede escribir la ALU como un único módulo conciso. Observe cómo cout obtiene implícitamente el valor correcto para cada valor de op .

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;

ENTITY ALU IS
  PORT (
    a      : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
    b      : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
    op     : IN  STD_LOGIC_VECTOR( 2 DOWNTO 0);
    result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
    cout   : OUT STD_LOGIC;
    zero   : OUT STD_LOGIC);
END ALU;

ARCHITECTURE description OF ALU IS
  ------- Intermediate Signals
  signal a_res: STD_LOGIC_VECTOR(32 DOWNTO 0);
  signal a_res: STD_LOGIC_VECTOR(32 DOWNTO 0);
  signal carry_in: STD_LOGIC_VECTOR(32 DOWNTO 0);
  signal res_intermediate: STD_LOGIC_VECTOR(32 DOWNTO 0);

BEGIN
  -- This is an extended version of A, required for add/subtract
  a_res <= "0" & a;
  -- This is your 2-to-1 mux and the "not B" function, extended
  b_res <= "0" & not b when op(2) = '1' else "0" & b;
  -- This is an extended version of carry-in
  carry_in <= X"00000000" & op(2);

  -- This is your 6-to-1 mux and the logic/arithmetic/shift functions
  process (a_res, b_res, carry_in)
  begin
    case op is
      when "000" => res_intermediate <= a_res and b_res;           -- AND
      when "001" => res_intermediate <= a_res or b_res;            -- OR
      when "010" => res_intermediate <= a_res + b_res + carry_in;  -- ADD
      when "110" => res_intermediate <= a_res + b_res + carry_in;  -- SUB
      when "101" => res_intermediate <= "0" & a_res(32 downto 1);  -- ROR
      when "100" => res_intermediate <= a_res(31 downto 0) & "0";  -- ROL
      when others => -- TBD         
    end case;
  end process;

  -- Zero checker and final NOT
  zero <= '1' when res_intermediate(31 downto 0) = X"00000000" else '0';

  -- Output assignments   
  result <= res_intermediate(31 downto 0);
  cout   <= res_intermediate(32);

END description;
    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas