2010-03-02 16 views
1

J'ai pris l'habitude de développer beaucoup de bancs de test et j'utilise les boucles() et while() à des fins de test. C'est très bien. Le problème est que j'ai pris l'habitude de coder des circuits qui devraient être synthétisables. XST et d'autres refusent de synthétiser le code (sans modification supplémentaire aux paramètres de synthèse) tels que:Comment ne pas utiliser while() boucles dans verilog (pour la synthèse)?

while (num < test_number) 
    begin 
    . 
    . 
    . 
    num = num+1; 
    end 

C'est mauvais style de codage, car au synthétiseur test_num est un entier avec une valeur 2^32! ou il le voit comme paramètre illimité. De toute façon, c'est une mauvaise habitude de codage. Mais j'ai tellement l'habitude de faire ça en C et testbenches. Quel serait l'équivalent synthétisable du code du segment de code ci-dessus?

Merci!

+1

Cela dépend de ce que vous faites. Qu'est-ce qui se passe habituellement dans vos boucles while? – Marty

+0

C'est un ensemble d'addition et de division, suivi d'une mise à jour du compteur. –

Répondre

1

Vous devez avoir une horloge pour le contrôler pour démarrer.

always @(posedge clk or negedge rst_n) 
    if (!rst_n) 
    num <= 32'b0; // or whatever your width is. 
    else 
    if (num < test_number) 
     num <= num + 1'b1; 
+0

Cela semble être une bonne solution. Mais la boucle while() était initialement dans une tâche. Si je passe le clk à la tâche, il ne semble pas que sa valeur soit mise à jour. Mais attendez, si j'utilise une tâche, ai-je même besoin d'un port clk pour la tâche, ou puis-je utiliser le clk sans le passer en argument? –

+1

Les tâches et les fonctions ont accès aux variables, entrées et sorties déclarées dans le même module que la tâche. Les arguments sont passés dans les tâches et fonctions par valeur (c'est-à-dire par copie) une fois que la tâche commence. Les arguments de sortie sont copiés lorsque la tâche existe. Par conséquent, ne passez pas l'horloge dans la tâche. –

1

Si votre outil de synthèse ne supporte pas while ou for boucles, alors ne pas utiliser une boucle. Développez simplement votre code.

wire [1:0] addr; 
reg [3:0] wren; 

always @(posedge clk) begin 
    wren[0] <= (addr == 2'd0); 
    wren[1] <= (addr == 2'd1); 
    wren[2] <= (addr == 2'd2); 
    wren[3] <= (addr == 2'd3); 
end 

Je ne connais pas XST, mais certains outils de synthèse font des boucles de soutien (Synopsys, par exemple).

+1

Je sais que XST autoriserait les boucles, mais il a une limite sur le nombre d'itérations. Le mien est mis un conservateur 64. Vous pouvez bien sûr changer cette limite, mais avoir une boucle avec plus de 100 itérations pour la synthèse ne semble pas être une bonne idée, même si elle est autorisée. Quelle est la limite par défaut de DC sur le nombre d'itérations. Cela vous réchauffe-t-il si vous utilisez un temps() ou pour() pour la synthèse? –

+0

Je sais que DC autorise les boucles 'for'. Je n'ai jamais essayé de synthétiser une boucle 'while', mais la documentation contient plusieurs exemples de boucles' while 'synthétisables. Je ne sais pas quelle est la limite des itérations. – toolic

+0

-1 pour conseiller la rupture de DRY (inutilement) – Earlz

3

Les outils de synthèse varient mais généralement une boucle peut être synthétisée tant que le nombre d'itérations est connu de l'outil de synthèse. Ainsi,

for (i = 0; i < 10; i = i + 1) 

est OK parce que l'outil sait qu'il ya 10 itérations de la boucle. Mais

reg [10:0] r; 
for (i = 0; i < r; i = i + 1) 

n'est pas OK car r est une valeur de variable r inconnue au moment de la synthèse. Pensez aux boucles dans le code RTL comme créant un nombre fixe connu de copies d'un morceau de logique.