2010-09-17 4 views
0

Je souhaite décrire une entité qui peut fonctionner normalement ou être mise en mode test. La conception générale que j'ai est une entité de premier niveau qui enveloppe l'entité «réelle» et une entité de test.Habillage et commutation entre entités similaires en VHDL

J'essaie de trouver la meilleure façon de l'exprimer en VHDL, mais j'ai l'impression de trop compliquer les choses.

Tenir compte d'une petite entité de haut niveau (de façon réaliste, il y a beaucoup plus d'E/S):

entity toplevelobject is 
    port (
     in1 : inout std_logic; 
     in2 : inout std_logic; 
     out1 : out std_logic; 
     out2 : out std_logic; 
     testline : in std_logic; 
     testclk : in std_logic; 
    ); 

end toplevelobject; 

Ceci est censé basculer entre la fonctionnalité réelle et le mode de test en fonction de l'état de « testline "(test de moyens élevés). Notez que le module de test utilise en fait tout sauf clk comme sortie, même in_*.

architecture test_passthrough of toplevelobject is 
    -- This is the actual module 
    component real_module 
    port (
     in1 : in std_logic; 
     in2 : in std_logic; 
     out1 : out std_logic; 
     out2 : out std_logic; 
     clk : in std_logic; 
     -- Note absence of "testline" 
    ); 
    end component; 

    -- This is the test module, which will just put the clk 
    -- signal out on all pins, or play a tune, or something 
    component test_module 
    port (
     in1 : out std_logic; 
     in2 : out std_logic; 
     out1 : out std_logic; 
     out2 : out std_logic; 
     testclk : in std_logic; 
     -- Note absence of "testline" 
    ); 
    end component; 

    signal real_in1, real_in2 : std_logic; 
    signal real_out1, real_out2 : std_logic; 

    signal test_in1, test_in2 : std_logic; 
    signal test_out1, test_out2 : std_logic; 

begin 

    real_0 : real_module port map (
     in1 => real_in1, 
     in2 => real_in2, 
     out1 => real_out1, 
     out2 => real_out2, 
     clk => clk, 
    ); 

    test_0 : test_module port map (
     in1 => test_in1, 
     in2 => test_in2, 
     out1 => test_out1, 
     out2 => test_out2, 
     testclk => clk, 
    ); 

    -- Ports that are outputs on both don't need 
    -- much special attention 

    out1 <= real_out1 when testline = '0' else test_out1; 
    out2 <= real_out2 when testline = '0' else test_out2; 

end test_passthrough; 

J'ai donc quelques questions:

  • Pour les inout ports, dois-je avoir un grand processus avec une déclaration case ... when qui passe sur testline? Ou un processus pour chaque E/S avec une instruction if? Théoriquement, je pense que de nombreux processus plus petits sont exécutés simultanément et non séquentiellement, mais cela va-t-il réellement faire une différence dans la simulation ou la synthèse? Par exemple:

    passthrough_in1 : process(testline, in1, test_in1) is 
    begin 
        if testline = '0' then 
         real_in1 <= in1; 
        else 
         in1 <= test_in1; 
        end if; 
    end process passthrough_in1; 
    

... vs ...

passthrough_all : process(in1, test_in1, in2, test_in2, testline) is 

     case testline is 
      when '0' => 
       real_in1 <= in1; 
       real_in2 <= in2; 
      when '1' => 
       in1 <= test_in1; 
       in2 <= test_in2; 
     end case; 

    end process passthrough_all; 
  • Est-ce une approche saine d'esprit ou est-il quelque chose de plus simple?
  • Je suis confus au sujet de la sensibilité - ai-je besoin passthrough_in1 (ou même passthrough_all être sensibles à tout autre que testline
  • Ai-je besoin real_in1/test_in1 pour choisir entre les deux entités enveloppées Ou est-il une autre façon? dire « si testline est élevé, connectez test_module sortie in_1 au toplevelobject I/O in_1

Répondre

1

Si je vous comprends bien, votre testmodule pilote le (mal nommé - je suppose que dans le code réel, ils ont plus de sens :) dans les ports 1,2?

Si oui, vous devez faire quelque chose comme ceci:

real_in1 <= in1; 
in1 <= test_in1 when testline = '1' else 'Z'; 

De cette façon, en non-test-mode, le signal IN1 sera entraîné par un « Z », de sorte que le signal in1 approprié externe peut passer outre il.

Vous pouvez le représenter de diverses autres manières (comme les processus que vous avez décrits), qui devraient toutes être égales dans le simulateur. L'inconvénient de l'option «tout en un» est que vous devez garder à jour ce qui pourrait finir par être une énorme liste de sensibilité. Faire un processus par signal est juste un long processus de ce que j'ai fait ci-dessus. Pour économiser de l'effort de code et de copier/coller, vous pourriez potentiellement pousser ces deux lignes de code dans une entité qui leur est propre, puis l'utiliser plusieurs fois - dans ce cas, je mettrais l'instance et la table des ports sur une ligne, mais cela offenser certaines normes de codage ...

Tout cela suppose que j'ai bien compris le problème!

+0

Oui, ils ont plus de sens dans le vrai ... mais il y en a environ 60 :) Dans cet exemple, cependant, c'est plutôt qu'ils désignent des "broches qui seraient des entrées si c'était juste le vrai module". Je n'avais pas pensé à l'option 'Z' ... Je me suis dit que je devrais voir comment régler les trois états pour les broches sur mon appareil particulier, donc je devrais vérifier pour voir si cela sera le même dans la synthèse. Oh, et j'aime vraiment l'idée de l'entité "switcher" séparée ... même si elle ne sauvegarde pas de code, cela * signifie * que je peux corriger les erreurs en un seul endroit. – detly

+0

Un problème avec l'idée de "l'entité de commutation" est que certaines entrées ne sont que des signaux simples et que d'autres sont des vecteurs. Pourtant, c'est mieux que l'approche verbatim. – detly

+0

Créez un sélecteur qui accepte un vecteur std_logic_vector non contraint - qui fonctionnera alors pour tous les vecteurs. Pour les bits simples: passez-les dans le vecteur un (probablement avec un casting slv je pense) - ils seront vus comme un slv (0 à 0). Vous pouvez créer un wrapper single_bit pour faire cela pour vous, en fonction de l'emplacement de votre tolérance de casting :) –

0

Peut-être que je ne comprends pas bien ce que vous essayez de faire, mais dans un VHDL typique testbench:

  • Votre code "real_module" est laissé tel quel. Aucun changement n'y est apporté quand il est testé.
  • Un deuxième module, semblable à votre "toplevelobject" est fait. Ceci est généralement appelé un module de testbench.
  • Le testbench toplevelobject instancie real_module.
  • Le banc d'essai n'a généralement pas d'entrées et n'a pas vraiment besoin de sorties (en fonction de la situation et du logiciel de test utilisé).
  • La zone de test a une logique séquentielle qui pilote les entrées de real_module.
  • Si vous utilisez un logiciel de test tel que ModelSim, les entrées et les sorties de real_module peuvent être tracées dans le temps pour observer le comportement de real_module tel qu'il est piloté par votre testbench.

Quel logiciel utilisez-vous? Je peux trouver un vieil exemple de testbench dans un projet universitaire il y a quelques années si cela peut vous aider.

+0

Je pense que vous vous méprenez. Je veux en fait finir avec un appareil physique qui, lorsqu'il est en circuit, devrait entrer en mode de test lorsque la tension sur la broche de 'testline' est logique haute, sinon il fonctionne normalement. J'essaye de faire ceci sans déranger le VHDL existant pour le vrai module autant que c'est possible. – detly