À première vue, vous vous attendez à ce que le code source VHDL ci-dessous se comporte comme un registre à décalage. Dans ce q, au fil du temps serait
"UUUU0", "UUU00", "UU000", "U0000", "00000", ....
mais c'est toujours U
après cinq (ou plus) cycles d'horloge consécutifs.
Pourquoi est-ce?
Ce code est en fait une version beaucoup plus simplifiée d'une simulation beaucoup plus compliquée. Mais cela démontre les symptômes que je vois.
Il présente ce résultat intéressant et inattendu lors de la simulation sous ModelSim et ActiveHDL, je n'ai pas essayé d'autres simulateurs et j'aimerais (deuxièmement pour une explication de la cause) savoir si d'autres agissent de la même manière.
Pour répondre correctement à cette question, vous devez comprendre que:
- Je sais que ce n'est pas la meilleure façon de mettre en place un registre à décalage
- Je sais que pour la synthèse RTL, cela devrait avoir une réinitialisation.
- Je sais qu'un tableau de std_logic est un std_logic_vector.
- Je sais que l'opérateur d'agrégation,
&
.
Ce que j'ai également trouvé:
- Si l'affectation
temp(0)<='0';
est déplacée à l'intérieur du processus, cela fonctionne. - Si la boucle est déroulée (voir le code commenté), cela fonctionne.
Je répéterai qu'il s'agit d'une version très simplifiée d'une conception beaucoup plus compliquée (pour un processeur pipeliné), configurée pour afficher uniquement les résultats de simulation inattendus. Les types de signaux réels ne sont qu'une simplification. Pour cette raison, vous devez considérer vos réponses avec le code dans le formulaire tel quel.
Je suppose que l'optimiseur du moteur de simulation VHDL ne prend pas la peine (ou peut-être selon les spécifications) d'exécuter les expressions à l'intérieur de la boucle car aucun signal extérieur ne change, bien que je puisse réfuter cela en plaçant la boucle non enveloppée dans une boucle.
Je m'attends donc à ce que la réponse à cette question soit davantage liée aux normes de simulation VHDL de la syntaxe VHDL inexplicite et à la façon dont les moteurs de simulation VHDL effectuent leurs optimisations, plutôt que si un exemple de code donné est la meilleure façon de faire quelque chose ou non.
Et maintenant, au code que je simule:
library ieee;
use ieee.std_logic_1164.all;
entity test_simple is
port (
clk : in std_logic;
q : out std_logic
);
end entity;
architecture example of test_simple is
type t_temp is array(4 downto 0) of std_logic;
signal temp : t_temp;
begin
temp(0) <= '0';
p : process (clk)
begin
if rising_edge(clk) then
for i in 1 to 4 loop
temp(i) <= temp(i - 1);
end loop;
--temp(1) <= temp(0);
--temp(2) <= temp(1);
--temp(3) <= temp(2);
--temp(4) <= temp(3);
end if;
end process p;
q <= temp(4);
end architecture;
Et le banc d'essai:
library ieee;
use ieee.std_logic_1164.all;
entity Bench is
end entity;
architecture tb of bench is
component test_simple is
port (
clk : in std_logic;
q : out std_logic
);
end component;
signal clk:std_logic:='0';
signal q:std_logic;
signal rst:std_logic;
constant freq:real:=100.0e3;
begin
clk<=not clk after 0.5 sec / freq;
TB:process
begin
rst<='1';
wait for 10 us;
rst<='0';
wait for 100 us;
wait;
end process;
--Note: rst is not connected
UUT:test_simple port map (clk=>clk,q=>q) ;
end architecture;
temp(0)
car aucun "événement" n'est associé à la constante littérale. Placer l'affectation à l'intérieur du process
crée une association avec les événements d'horloge qui le fait fonctionner. Je me demande si l'ajout d'une after
clause à la cession serait une solution de contournement potentielle.