2017-02-28 6 views
0

Je crée une mémoire vive de 64 octets en utilisant deux registres d'adresses 3 bits et une barre transversale des registres 3 bits en utilisant deux décodeurs 3to8. Voici le code VHDL:registres multipiles 8 bits connectés à la même sortie (VHDL)

library ieee; 
use ieee.std_logic_1164.all; 

entity ram88 is 
    port(a : in std_logic_vector (2 downto 0); 
     s0: in std_logic; 
     s1: in std_logic; 
     s: in std_logic; 
     e: in std_logic; 
     io_in: in std_logic_vector (7 downto 0); 
     io_out:out std_logic_vector (7 downto 0)); 

end ram88; 

architecture behavior of ram88 is 

    component reg3 is 
    port(a : in std_logic_vector (2 downto 0); 
      ss,e : in std_logic; --st and enable 
      b : out std_logic_vector (2 downto 0)); 
    end component; 

    component reg8 is 
    port(a : in std_logic_vector (7 downto 0); 
      ss,e : in std_logic; --st and enable 
      b : out std_logic_vector (7 downto 0)); 
    end component; 

    component decod8 is 
    port(a : in std_logic_vector (2 downto 0); 
      b : out std_logic_vector (7 downto 0)); 
    end component; 

    signal e1 : std_logic := '1'; 
    signal l0, l1 : std_logic_vector (2 downto 0); 
    signal ll0, ll1 : std_logic_vector (7 downto 0); 
    type arr2d is array (7 downto 0, 7 downto 0) of std_logic; 
    signal andij, fin_s, fin_e : arr2d; 

begin 

    e1 <= '1'; 

    reg0: reg3 port map (a => a, ss => s0, e => e1, b => l0); 
    reg1: reg3 port map (a => a, ss => s1, e => e1, b => l1); 
    decod0: decod8 port map(a => l0, b => ll0); 
    decod1: decod8 port map(a => l1, b => ll1); 

    mem_blks_ii: 
    for ii in 0 to 7 generate 
    mem_blks_jj: 
    for jj in 0 to 7 generate 
     andij(ii,jj) <= ll0(ii) and ll1(jj); 
     fin_s(ii,jj) <= andij(ii,jj) and s; 
     fin_e(ii,jj) <= andij(ii,jj) and e; 
     regij: reg8 port map(a=> io_in, ss=> fin_s(ii,jj), e => fin_e(ii,jj), b => io_out); 
    end generate mem_blks_jj; 
    end generate mem_blks_ii; 


end behavior; 

Puis-je utiliser l'unité de test suivant pour la simulation. Il définit la valeur 00000001 à l'adresse mémoire 000x000. A la fin, il récupère la valeur en réglant le signal de validation:

library ieee; 
use ieee.std_logic_1164.all; 

entity ram88_bench is 

end ram88_bench; 

architecture behavior of ram88_bench is 

    component ram88 
    port(a : in std_logic_vector (2 downto 0); 
     s0: in std_logic; 
     s1: in std_logic; 
     s: in std_logic; 
     e: in std_logic; 
     io_in: in std_logic_vector (7 downto 0); 
     io_out:out std_logic_vector (7 downto 0)); 
    end component; 

    signal abar : std_logic_vector (2 downto 0); 
    signal s0bar, s1bar, sbar, ebar: std_logic; 
    signal io_in_bar, io_out_bar: std_logic_vector (7 downto 0); 

begin 

    ram0: ram88 port map(a=>abar, s0=> s0bar, s1=> s1bar 
         , s=> sbar, e=> ebar 
         , io_in => io_in_bar, io_out=> io_out_bar); 

    process 
    begin 

    -- set (0,1) for access point in memory 
    abar <= "000"; 
    s0bar <= '1'; 
    s1bar <= '0'; 
    wait for 2 fs; 
    s0bar <= '0'; 

    abar <= "000"; 
    s1bar <= '1'; 
    wait for 2 fs; 
    s1bar <= '0'; 

    -- store the value ... 
    ebar <= '1'; 
    sbar <= '1'; 
    io_in_bar <= "00000001"; 
    wait for 2 fs; 
    sbar <= '0'; 

    ---- temporary clear the value before retrieval 
    --sbar <= '0'; 
    --ebar <= '0'; 
    ---- io_in_bar <= "00000000";  
    --wait for 2 fs; 

    --retrieve the value ???? 
    ebar <= '1'; 
    sbar <= '0'; 
    wait for 6 fs; 

    wait; 

    end process; 

end behavior; 

Le problème est que la valeur io_out_bar est forcé d'inconnues « 0X » au lieu de 00.000.001 prévu à la fin de la simulation! Je ne pouvais pas comprendre pourquoi mais je suppose que puisque tous les registres RAM 8 bits sont connectés à la même sortie, il ne peut pas être déterminé lequel est la vraie valeur que nous devons récupérer. Comment puis-je résoudre ce problème?

+2

Sélectionnez-en un à l'aide d'un multiplexeur. Une alternative est d'utiliser la logique tristate, mais ce n'est pas valable dans tous les FPGA modernes que je connais. –

Répondre

3

Vous êtes question n'est pas un Minimal, Complete and Verifiable example et il aide à démontrer la solution. Certaines entités rapides et sales pour instanciation:

library ieee; 
use ieee.std_logic_1164.all; 

entity reg3 is 
    port (
     a:  in std_logic_vector (2 downto 0); 
     ss,e: in std_logic; 
     b:  out std_logic_vector (2 downto 0) 
    ); 
end entity; 

architecture foo of reg3 is 
begin 
    b <= a when ss = '1' and e = '1'; 
end architecture; 

library ieee; 
use ieee.std_logic_1164.all; 

entity decod8 is 
    port (
     a:  in std_logic_vector (2 downto 0); 
     b:  out std_logic_vector (7 downto 0) 
    ); 
end entity; 

architecture foo of decod8 is 
    use ieee.numeric_std.all; 
begin 
    process (a) 
     variable idx: natural range 0 to 7; 
    begin 
     idx := to_integer(unsigned(a)); 
     b <= (others => '0'); 
     b(idx) <= '1'; 
    end process; 
end architecture; 

library ieee; 
use ieee.std_logic_1164.all; 

entity reg8 is 
    port (
     a:  in std_logic_vector (7 downto 0); 
     ss,e: in std_logic; 
     b:  out std_logic_vector (7 downto 0) 
    ); 
end entity; 

architecture foo of reg8 is 
begin 
    b <= a when ss = '1' and e = '1'; 
end architecture;  

... Je suppose que puisque tous les registres de RAM 8bit sont connectés à la même sortie, il ne peut être déterminé que l'on est la valeur réelle que nous devons récupérer . Comment puis-je résoudre ce problème?

Vous supposez correctement, tous les 8 registres de bits lecteur io_out.

L'idée ici est de sélectionner seulement un à la fois en fonction de l'index fourni à la RAM. L'exemple utilise les mêmes adresses d'écriture des verrous l0 et l1, utilisés pour sélectionner 1 des 64 registres 8 bits pour la sortie.

Il est fait purement behaviorally, mais pourrait être fait avec Multiplexeur instanciés (sélecteurs):

architecture behavior of ram88 is 

    component reg3 is 
    port(a : in std_logic_vector (2 downto 0); 
      ss,e : in std_logic; --st and enable 
      b : out std_logic_vector (2 downto 0)); 
    end component; 

    component reg8 is 
    port(a : in std_logic_vector (7 downto 0); 
      ss,e : in std_logic; --st and enable 
      b : out std_logic_vector (7 downto 0)); 
    end component; 

    component decod8 is 
    port(a : in std_logic_vector (2 downto 0); 
      b : out std_logic_vector (7 downto 0)); 
    end component; 

    signal e1 : std_logic := '1'; 
    signal l0, l1 : std_logic_vector (2 downto 0); 
    signal ll0, ll1 : std_logic_vector (7 downto 0); 
    type arr2d is array (7 downto 0, 7 downto 0) of std_logic; 
    signal andij, fin_s, fin_e : arr2d; 
    type mux is array (7 downto 0, 7 downto 0) of -- ADDED 
       std_logic_vector (7 downto 0); 
    signal mux88: mux;        -- ADDED 
    signal idxii, idxjj: natural range 0 to 7;  -- ADDED 
    use ieee.numeric_std.all;      -- ADDED 

begin 

    e1 <= '1'; 

    idxii <= to_integer(unsigned(l0));    -- ADDED 
    idxjj <= to_integer(unsigned(l1));    -- ADDED 

    reg0: reg3 port map (a => a, ss => s0, e => e1, b => l0); 
    reg1: reg3 port map (a => a, ss => s1, e => e1, b => l1); 
    decod0: decod8 port map(a => l0, b => ll0); 
    decod1: decod8 port map(a => l1, b => ll1); 

    mem_blks_ii: 
    for ii in 0 to 7 generate 
    mem_blks_jj: 
    for jj in 0 to 7 generate 
     andij(ii,jj) <= ll0(ii) and ll1(jj); 
     fin_s(ii,jj) <= andij(ii,jj) and s; 
     fin_e(ii,jj) <= andij(ii,jj) and e; 
    -- regij: reg8 port map(a=> io_in, ss=> fin_s(ii,jj), e => fin_e(ii,jj), b => io_out); -- CHANGED 
    regij: reg8 port map(a=> io_in, ss=> fin_s(ii,jj), e => fin_e(ii,jj), b => mux88(ii,jj));  -- CHANGED 
    end generate mem_blks_jj; 
    end generate mem_blks_ii; 

    io_out <= mux88(idxii, idxjj); -- ADDED READBACK MUX 

end behavior; 

Et qui donne:

ram88_bench_fixed.png

RAM relue. La valeur std_logic_vector 8 by 8 by 8 bits a l'une des 64 valeurs b bits sélectionnées par les deux index ajoutés. Si vous deviez le construire à partir de composants instanciés, synthétisez et comptez où toutes les portes logiques sont à peu près de la même taille que les loquets utilisés pour la RAM et leurs tampons de ventilateur, et un peu plus grand que la direction d'écriture logique.

+0

Merci! Réponse très complète! – argasm