Pourquoi ce Verilog englobe 30 macrocellules et des centaines de termes de produits?

8

J'ai un projet qui consomme 34 macrocellules d'un Xilinx Coolrunner II. J'ai remarqué que j'avais une erreur et je l'ai retrouvée:

assign rlever = RL[0] ? 3'b000 :
                RL[1] ? 3'b001 :
                RL[2] ? 3'b010 :
                RL[3] ? 3'b011 :
                RL[4] ? 3'b100 :
                RL[5] ? 3'b101 :
                RL[6] ? 3'b110 :
                        3'b111;

assign llever = LL[0] ? 3'b000 :
                LL[1] ? 3'b001 :
                LL[2] ? 3'b010 :
                LL[3] ? 3'b011 :
                LL[4] ? 3'b100 :
                LL[5] ? 3'b101 :
                        3'b110 ;

L'erreur est que rleveret lleversont un bit de large, et j'ai besoin qu'ils soient de trois bits de large. Que je suis bête. J'ai changé le code pour être:

wire [2:0] rlever ...
wire [2:0] llever ...

donc il y avait assez de morceaux. Cependant, lorsque j'ai reconstruit le projet, ce changement m'a coûté plus de 30 macrocellules et des centaines de termes de produit. Quelqu'un peut-il expliquer ce que j'ai fait de mal?

(La bonne nouvelle est qu'il simule maintenant correctement ... :-P)

ÉDITER -

Je suppose que je suis frustré parce qu'au moment où je pense commencer à comprendre Verilog et le CPLD, quelque chose se passe qui montre clairement que je n'ai aucune compréhension.

assign outp[0] = inp[0] | inp[2] | inp[4] | inp[6];
assign outp[1] = inp[1] | inp[2] | inp[5] | inp[6];
assign outp[2] = inp[3] | inp[4] | inp[5] | inp[6];

La logique pour implémenter ces trois lignes se produit deux fois. Cela signifie que chacune des 6 lignes de Verilog consomme environ 6 macrocellules et 32 ​​termes de produit chacun .

EDIT 2 - Conformément à la suggestion de @ ThePhoton sur le commutateur d'optimisation, voici les informations des pages récapitulatives produites par ISE:

Synthesizing Unit <mux1>.
    Related source file is "mux1.v".
    Found 3-bit 1-of-9 priority encoder for signal <code>.
Unit <mux1> synthesized.
(snip!)
# Priority Encoders                                    : 2
 3-bit 1-of-9 priority encoder                         : 2

Il est donc clair que le code a été reconnu comme quelque chose de spécial. Cependant, la conception consomme encore d'énormes ressources.

EDIT 3 -

J'ai fait un nouveau schéma comprenant uniquement le multiplexeur que @thePhoton a recommandé. La synthèse a produit une utilisation insignifiante des ressources. J'ai également synthétisé le module recommandé par @Michael Karas. Cela a également produit une utilisation insignifiante. Donc, un peu de raison prévaut.

De toute évidence, mon utilisation des valeurs de levier provoque la consternation. Plus à venir.

Édition finale

Le design n'est plus fou. Cependant, je ne sais pas ce qui s'est passé. J'ai fait beaucoup de changements afin d'implémenter de nouveaux algorithmes. Un facteur contributif était une «ROM» de 111 éléments de 15 bits. Cela a consommé un nombre modeste de macrocellules mais beaucoupdes termes du produit - presque tous ceux disponibles sur le xc2c64a. Je cherche ça mais je ne l'avais pas remarqué. Je crois que mon erreur a été cachée par l'optimisation. Les «leviers» dont je parle sont utilisés pour sélectionner des valeurs dans la ROM. Je suppose que lorsque j'ai implémenté le codeur de priorité 1 bit (interrompu), ISE a optimisé une partie de la ROM. Ce serait tout à fait une astuce, mais c'est la seule explication à laquelle je peux penser. Cette optimisation a considérablement réduit l'utilisation des ressources et m'a endormi en m'attendant à une certaine ligne de base. Lorsque j'ai corrigé l'encodeur prioritaire (conformément à ce fil,) j'ai vu les frais généraux de l'encodeur prioritaire et de la ROM qui avaient été précédemment optimisés et je l'ai attribué exclusivement à l'ancien.

Après tout cela, j'étais bon sur les macrocellules mais j'avais épuisé mes conditions de produit. La moitié de la ROM était un luxe, vraiment, car ce n'était que la composition de 2 de la première moitié. J'ai supprimé les valeurs négatives, en les remplaçant ailleurs par un simple calcul. Cela m'a permis d'échanger des macrocellules pour des conditions de produit.

Pour l'instant, cette chose s'inscrit dans le xc2c64a; J'ai utilisé respectivement 81% et 84% de mes macrocellules et termes de produit. Bien sûr, maintenant je dois le tester pour m'assurer qu'il fait ce que je veux ...

Merci à ThePhoton et Michael Karas pour l'aide. En plus du soutien moral qu'ils m'ont apporté pour m'aider à résoudre ce problème, j'ai appris du document Xilinx publié par ThePhoton et j'ai mis en œuvre l'encodeur prioritaire suggéré par Michael.

Tony Ennis
la source
tous les points d'interrogation n'impliquent-ils pas effectivement un multiplexeur, et structurellement, vous les avez également mis en cascade? Combien de macro-cellules vous attendiez-vous à ce qu'il prenne?
vicatcu
Je ne sais pas combien de macrocellules la construction devrait consommer. Cependant, étant donné que mon projet consomme actuellement 34 macrocellules, y compris ces deux multiplexeurs «1 bit», et qu'il s'agit d'une petite partie du projet, je suis surpris par ce résultat.
Tony Ennis
Quel outil utilisez-vous?
The Photon
ISE de Xilinx ...
Tony Ennis
Dans le code de votre édition, je pense que vous voulez |au lieu de ||.
The Photon

Réponses:

7

Le code que vous montrez est essentiellement un encodeur prioritaire. Autrement dit, il a une entrée de nombreux signaux, et sa sortie indique lequel de ces signaux est défini, en donnant la priorité au signal défini le plus à gauche si plusieurs sont définis.

Cependant, je vois des définitions contradictoires du comportement standard pour ce circuit dans les deux endroits que j'ai vérifiés.

Selon Wikipedia , le codeur de priorité standard numérote ses entrées de 1. Autrement dit, si le bit d'entrée le moins significatif est défini, il génère 1, et non 0. Le codeur de priorité Wikipédia génère 0 lorsqu'aucun des bits d'entrée n'est défini.

Le Guide de l'utilisateur XST de Xilinx (p. 80), cependant, définit un encodeur prioritaire plus proche de ce que vous avez codé. Les entrées sont numérotées à partir de 0, donc lorsque le lsb de l'entrée est défini, il donne une sortie 0. Cependant, la définition Xilinx ne donne aucune spécification pour la sortie lorsque tous les bits d'entrée sont effacés (votre code affichera 3'd7).

Le guide d'utilisation de Xilinx, bien sûr, déterminera ce que le logiciel de synthèse Xilinx attend. Le point principal est qu'une directive spéciale (*priority_extract ="force"*)est requise pour que XST reconnaisse cette structure et génère des résultats de synthèse optimaux.

Voici la forme recommandée par Xilinx pour un encodeur de priorité 8 à 3:

(* priority_extract="force" *)
module v_priority_encoder_1 (sel, code);
input [7:0] sel;
output [2:0] code;
reg [2:0] code;
always @(sel)
begin
    if (sel[0]) code = 3b000;
    else if (sel[1]) code = 3b001;
    else if (sel[2]) code = 3b010;
    else if (sel[3]) code = 3b011;
    else if (sel[4]) code = 3b100;
    else if (sel[5]) code = 3b101;
    else if (sel[6]) code = 3b110;
    else if (sel[7]) code = 3b111;
    else code = 3bxxx;
end
endmodule

Si vous pouvez réorganiser votre logique environnante pour vous permettre d'utiliser le style de codage recommandé par Xilinx, c'est probablement la meilleure façon d'obtenir un meilleur résultat.

Je pense que vous pouvez l'obtenir en instanciant le module d'encodeur Xilinx avec

v_priority_encoder_1 pe_inst (.sel({~|{RL[6:0]}, RL[6:0]}), .code(rlever));

Je n'ai pas réuni tous les bits de RL[6:0]pour obtenir un 8e bit d'entrée qui déclenchera la sortie 3'b111 lorsque tous les bits RL sont bas.

Pour la lleverlogique, vous pouvez probablement réduire l'utilisation des ressources en créant un module de codeur modifié, en suivant le modèle Xilinx, mais en ne nécessitant que 7 bits d'entrée (vos 6 bits de LLplus un bit supplémentaire qui monte haut lorsque les 6 autres sont tous bas).

L'utilisation de ce modèle suppose que la version d'ISE que vous utilisez utilise le moteur de synthèse XST. Il semble qu'ils changent d'outils de synthèse à chaque révision majeure d'ISE, alors vérifiez que le document que j'ai lié correspond bien à votre version d'ISE. Sinon, vérifiez le style recommandé dans votre documentation pour voir ce que votre outil attend.

Le photon
la source
Merci, cela prendra du temps à digérer. Mon ISE utilise XST bien que je ne sache pas quelle version.
Tony Ennis
La clé est d'avoir (* priority_extract="force" *)et probablement aussi explicitement d'inclure la sortie indifférente même si vous couvrez toutes les entrées possibles. (Sans cela, XST essaie probablement de générer une table de recherche complète, c'est pourquoi tant de termes de produit) Essayez d'abord d'ajouter l'option ne vous souciez pas. Si cela ne fonctionne pas, essayez d'utiliser le passe-partout Xilinx exactement.
Le Photon
J'ai implémenté une extraction complète du code ci-dessus et je n'ai pas obtenu de résultat amélioré. Les pages de résumé ISE indiquent qu'un MUX a été reconnu, bien que la reconnaissance ne soit pas aussi forte que pour d'autres constructions. Je posterai les informations pertinentes dans quelques minutes.
Tony Ennis
modifier - ignorer le commentaire ci-dessus à propos de «forte reconnaissance» - il est là, je l'ai juste raté la nuit dernière; J'ai refait le travail et la réalité fonctionne correctement.
Tony Ennis
6

La réponse de ThePhoton est excellente. Je voudrais ajouter ici quelques informations supplémentaires pour votre considération. Cela découle du fait que même si nous avons des appareils FPGA et CPLD de pointe utilisant des HDL et des outils de systhés, il peut être instructif de regarder de près les choses conçues il y a des années. Restez avec moi pendant que je passe par là jusqu'à ma recommandation à la fin.

Il existe des parties logiques discrètes qui exécutent la fonction de codage prioritaire. La logique mise en œuvre par ces pièces existe depuis longtemps lorsqu'il était essentiel de réduire le nombre de transistors au strict minimum. Vous pouvez rechercher sur le Web des pièces logiques avec des numéros de pièce génériques tels que 74HC148 ou MC14532B pour trouver des fiches techniques qui incluent des diagrammes logiques équivalents pour ces pièces. Le diagramme ci-dessous est un exemple tiré de la fiche technique TI de la pièce 74HC148 .

entrez la description de l'image ici

Cette logique implémente la table de vérité suivante (tirée de la même fiche technique):

entrez la description de l'image ici

Notez que la famille de pièces ci-dessus utilise des signaux d'entrée actifs faibles. Une autre fiche technique pour la partie ON Semiconductor MC14532B montre une table de vérité pour la fonction d'encodeur utilisant des signaux d'entrée élevés actifs similaires à votre exemple Verilog.

entrez la description de l'image ici

La même fiche technique montre les équations logiques du MC14532B comme suit:

entrez la description de l'image ici

Vous voudrez peut-être envisager de coder des équations similaires directement dans votre code Verilog pour voir comment il se compare à votre exemple actuel. Il est très probable qu'il en résulte un résultat beaucoup plus favorable.

Michael Karas
la source
Merci, je vais le faire. Ce problème me tue. Je crois qu'il synthétisait plus efficacement auparavant. Et puis j'ai changé quelque chose. / selfbonk
Tony Ennis
Merci, je l'ai mis en œuvre. Malheureusement, cela n'a pas fait de différence matérielle.
Tony Ennis
Bonne réponse. Voyons à Tony combien de termes de produit il devrait avoir besoin pour implémenter cette logique. Tony, si vous utilisez le passe-partout de Xilinx ou les équations de Michael, et que vous générez toujours des centaines de termes de produit, alors vous devez rechercher un changement subtil ailleurs dans votre code qui pourrait avoir causé le problème; ou bien examinez très attentivement le fichier journal de synthèse pour voir si quelque chose se produit auquel vous ne vous attendez pas.
The Photon
Je suis entièrement d'accord avec @ThePhoton. J'ai arrosé quelque chose. Je suis aussi sûr que possible que cela fonctionnait auparavant - je n'ai même pas remarqué la consommation si faible. Eh bien, c'est une bonne excuse pour commencer à comprendre davantage les informations récapitulatives.
Tony Ennis