Domanda

Io sono la progettazione del cambio universale operatore aritmetico. C'è un modo migliore per raggiungerlo oltre ad utilizzare il multiplexer a 32 bit (decoder) in modo presentato muggito?

ENTITY isra IS 
PORT (
  clk:    in std_logic;
  rst:    in std_logic;
  di:     in std_logic_vector (31 downto 0);
  sel:    in std_logic_vector (31  downto 0);
  res:    out std_logic_vector (31 downto 0) := (others => '0')
);
END isra;


PROCESS
  BEGIN
    WAIT UNTIL clk'EVENT AND clk = '1';
    IF rst = '1' THEN
      res <= (others => '0');
    ELSE
    CASE sel IS
        when X"00000001"  => res <= to_stdlogicvector(to_bitvector(a) sra 1);
        when X"00000002"  => res <= to_stdlogicvector(to_bitvector(a) sra 2);
        ...
        when X"0000001F"  => res <= to_stdlogicvector(to_bitvector(a) sra 31);
        when others => res <= (others => '0');
    END CASE;
END IF;
END PROCESS;
È stato utile?

Soluzione

Usa indicizzazione?

PROCESS
  VARIABLE shift_count : INTEGER RANGE 0 TO 31;
BEGIN
  IF rst = '1' THEN
    res <= (others => '0');
  ELSIF RISING_EDGE(clk) THEN
    shift_count := to_integer(sel);
    FOR I IN 0 TO 31 LOOP
      IF I + shift_count < 32 THEN
        res(I) <= din(I + shift_count);
      ELSE
        res(I) <= din(31); -- for logical shift right, use '0' instead
      END IF;
    END LOOP;
  END IF;
END PROCESS;

Questa versione è molto più facile da parametrizzare in un generico.

Ricorda che VHDL è una descrizione comportamentale, essa non specifica un mux. Il compilatore in grado di generare i disegni differenti a seconda che si ottimizza per dimensioni, velocità, consentono pipelining, ecc.

Si noti che 5 2: 1 MUX possono implementare questo in una zona molto più piccolo di un singolo 32: 1 MUX. Se questo non è il blocco che limita la frequenza di clock, che potrebbe essere preferibile.

Si noti inoltre che l'input sel è troppo ampia, ha solo bisogno di essere 5 bit.

Altri suggerimenti

È possibile utilizzare la funzione SRA senza loop o istruzioni case:

res <= to_stdlogicvector(to_bitvector(di) sra to_integer(sel));

Si noti che è necessario effettuare sel un unsigned, non uno std_logic_vector:

sel: in unsigned (31  downto 0);

Nel caso in cui non si vuole questo, si può ancora lanciare sel in un unsigned. È inoltre necessario noi numeric_bit:

use ieee.numeric_bit.all;

Ben dal punto di vista hardware, per spostare destra in un singolo orologio un numero variabile di posizioni, ogni bit è un singolo flip-flop con uno dei 32 possibili valori basati su una selezione. Quindi, da questo punto di vista, questo è come lo fai.

I renderebbe sel == 0 un caso e ne fanno un passthrough, però. Logicamente, questo ha più senso che l'impostazione di tutto per zeri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top