Logique OU réinitialisé et effacé?

Sep 16 2020

J'essaie de comprendre la meilleure pratique pour implémenter une réinitialisation (asynchrone appliquée, synchronisation effacée) et une entrée claire. J'ai un processus qui doit fonctionner sur une horloge dérivée de la logique (NCO) appelée code_clk, plus lente mais synchrone avec le clk réel. Le processus implique un registre de décalage de rétroaction linéaire qui doit être réinitialisé à tous les 1 pour commencer une séquence de génération de code une fois la réinitialisation levée. Cependant, tout au long de l'opération, le processus doit également être réinitialisé à tous les 1 lorsqu'un nouvel ensemble de prises (T1 et T2) est sélectionné pour la sortie, bien sûr afin de réinitialiser la séquence de génération de code et de s'assurer que le nouveau code est valide avec le nouveau robinets. Ceci est fait avec une entrée clr synchrone séparée qui est maintenue au niveau haut pendant un cycle d'horloge système unique pendant que les prises sont déplacées.

Voici mon code:

  process(code_clk, reset, clr)
  begin
    if(reset='0' or clr='1') then
      -- EARLY LFSR
      EG1(1 to 10) <= (others => '1');
      EG2(1 to 10) <= (others => '1');
      early_code   <= '0';
      delay_os     <= '0';
    elsif(falling_edge(code_clk)) then
      if(delay_os='0') then
        -- LFSR feedbacks for early code
        EG1(2 to 10) <= EG1(1 to 9);
        EG2(2 to 10) <= EG2(1 to 9);
        EG1(1) <= EG1(3) xor EG1(10);
        EG2(1) <= EG2(2) xor EG2(3) xor EG2(6) xor EG2(8) xor EG2(9) xor EG2(10);
        early_code <= EG1(10) xor EG2(T1) xor EG2(T2); -- C/A output of early LFSR
      else
        -- delay of code chips commanded - do not shift this time
        delay_os <= '0';
      end if;
      late_code   <= early_code; -- one half chip delay from prompt code
    elsif(rising_edge(code_clk)) then 
      prompt_code <= early code; -- one half chip delay from early code
    end if;
  end process;

Le type conditionnel if (reset = '0' ou clr = '1') me saute aux yeux comme étant un mauvais style. Cela semble être l'une de ces situations où la synthèse produira une logique inutile ou un retard de synchronisation parce que le chemin de réinitialisation n'est pas aussi simple. Puis-je faire cela ou devrais-je essayer autre chose? Le clair doit se produire immédiatement, donc je devrais soit faire fonctionner le processus de l'horloge système ou autre chose. Est-ce considéré comme une bonne pratique?

Réponses

2 Vance Sep 16 2020 at 18:50

Vos instincts pour le conditionnel sont corrects. Certains outils de synthèse peuvent comprendre ce que vous essayez de faire, mais beaucoup ne le feront pas car ce que vous avez écrit n'est pas un modèle établi, de sorte que les outils peuvent ne pas déduire ce que vous voulez de la manière dont vous le souhaitez. La manière standard (s'il y a une telle chose) / acceptée d'écrire ce que vous essayez d'accomplir est la suivante:

process(clk, reset)
begin
  if reset = '1' then  -- async reset
    -- your code here
  elsif Rising_edge(clk) then
    if sync_clr = '1' then  -- sync clear
      -- your code here
    end if;
  end if;
end process;

Je note que votre réinitialisation est active faible, ce qui a tendance à être mal vu dans le FPGA (plus à voir avec la lisibilité du code que les problèmes d'architecture réels).

Mais attendez! Pourquoi tout cela est-il vraiment important?

Cela dépend de l'architecture individuelle du FPGA que vous utilisez. Vous trouverez ci-dessous un extrait du schéma fonctionnel d'un module de logique adaptative Cyclone V.

En regardant les registres, vous pouvez voir qu'ils n'ont qu'un seul contrôle - CLR. En haut du diagramme, vous pouvez voir les signaux aclr [1: 0] entrant dans l'ALM. Lorsque vous inférez une réinitialisation asynchrone, c'est ce qui est défini. Notez que cet ALM a 4 registres mais seulement 2 signaux de réinitialisation qui sont partagés par les paires. Cela a une incidence sur le nombre d'ALM utilisés.

Vous pouvez également voir un signal d'effacement synchrone ( sclr ) et un signal de charge synchrone ( syncload ) entrant dans l'ALM. Ceux-ci sont partagés par les 4 registres. Ces circuits seront utilisés s'ils sont déduits dans le code. Le diagramme est suffisamment détaillé pour pouvoir comprendre le fonctionnement des signaux.

sclr est destiné à être actif haut. Il est inversé et AND avec des données qui alimentent l'entrée D des registres. Cela signifie qu'à l'état haut, 0 est envoyé à l'entrée D et Q est mis à jour à 0 lors du cycle d'horloge suivant.

syncload pilote un multiplexeur qui sélectionne les sorties des LUT ou datae0 qui provient de l'extérieur de l'ALM.

Notez qu'il n'y a pas d'ensemble asynchrone. Si vous avez écrit ceci, les outils seraient incapables de faire correspondre cela à l'architecture de l'appareil et de l'implémenter à la place à l'aide de LUT. C'est la même chose pour tous les contrôles qui ne font pas partie de l'architecture des appareils.

Xilinx a un livre blanc qui explique cela de manière beaucoup plus détaillée: https://www.xilinx.com/support/documentation/white_papers/wp275.pdf