2015-09-20 2 views
1

Ce code est supposé incrémenter un compteur (sortir en LED) lorsqu'un bouton est enfoncé et le décrémenter lorsque l'autre est enfoncé. Cela fonctionne correctement avec la décrémentation mais à l'incrémentation, les LED sont changées en configuration aléatoire. Je utilise ce tableau: http://www.ebay.com/itm/111621868286. L'affectation des broches est: Pourquoi ce code ne fonctionne que partiellement?

Les connexions:

Après avoir échangé les affectations de broches pour les boutons du comportement reste le même.

+0

Ce serait probablement mieux demandé au site d'échange de pile électronique. –

+1

Je pense que c'est plus lié à la programmation qu'à la conception électronique. J'utilise un tableau avec un design de référence donc le problème n'est pas électronique mais de programmation. – Chumanista

+0

Strictement parlant, il s'agit encore de conception matérielle, pas de programmation. Verilog est un langage de description * hardware *, pas un langage de programmation (logiciel). La ligne est quelque peu floue, cependant. –

Répondre

2

Comme d'autres l'ont déjà fait remarquer, vous devriez synchroniser avec le CLK_50M et vous devriez rebondir vos entrées (certains FPGA le font automatiquement pour vous, consultez votre manuel).

La raison pour laquelle vous voyez une fonctionnalité partielle provient de la façon dont le synthétiseur interprète le RTL. Si la liste de sensibilité est déclenchée par un front et que ce signal est référencé dans le corps du bloc always, alors le synthétiseur pense qu'il s'agit d'un signal asynchrone sensible au niveau. Ceci est prévu pour la réinitialisation asynchrone & définie (parfois nommé clear & preset). La conception ASIC utilise généralement des flops avec une réinitialisation asynchrone dans la plupart des cas. Les FPGA ont tendance à avoir un nombre limité de flops avec un jeu ou un repos asynchrone, donc vérifiez votre manuel et utilisez avec parcimonie.

Avec votre code, Negative est l'horloge et Positive est traitée comme une entrée asynchrone haute active.

Modifiez le code en un équivalent comportemental fonctionnel (en simulation) vu ci-dessous, puis Positive sera l'horloge et Negative sera l'entrée haute asynchrone active.

[email protected](posedge Positive or posedge Negative) 
begin 
    if(Negative == 1) 
     LED <= LED - 1; 
    else 
     LED <= LED + 1; 
end 

Il y a plusieurs ressources pour l'apprentissage Verilog disponible en ligne (utilisez votre moteur de recherche préféré), et j'ai des ressources affichées sur my profile bien plus visant à SystemVerilog.
Voici un code pseudo pour vous diriger dans la bonne direction pour votre projet:

always @(posedge CLK_50M) 
begin 
    past_Positive <= Positive; 
    // ... 
    case({/* ... , */ past_Positive,Positive}) 
    4'b0001 : LED <= LED + 1; 
    4'b0100 : LED <= LED - 1; 
    // ... 
    endcase 
end 
1

Vous n'avez pas de circuit anti-rebond ou de logique. Un commutateur mécanique va beaucoup rebondir physiquement, donc votre horloge 50MHz va voir beaucoup, beaucoup de transitions sur le signal d'entrée, conduisant à un comportement erratique.

J'ai oublié de mentionner que vous n'utilisez même pas cette horloge 50MHz dans une conception synchrone. Au contraire, vous recherchez de manière asynchrone les transitions.

Vous avez besoin d'un filtre passe-bas quelque part. Mis en œuvre avec des composants analogiques sur le signal d'entrée, ou en tant que compteur dans le matériel.

+0

Cela n'explique pas pourquoi le côté négatif fonctionne (double enregistrement parfois, mais fonctionne) mais positif ne fonctionne pas. – Chumanista

+0

Cela peut être dû à une petite différence mécanique dans les contacts. Essayez de changer les broches ou les contacts et voir si cela inverse le comportement. –

+0

J'ai fait. Après avoir changé les broches, le comportement reste le même. – Chumanista

1

Tout d'abord, mettre à jour la conception à une conception synchrone où l'état ne change que au front montant du CLK_50M, comme

[email protected](posedge CLK_50M) 
begin 
    ... 
end 

Ensuite, ajoutez la logique logique de rebond pour les deux entrées de commutation; voir contact bounce. Cela peut être fait avec un petit module que vous écrivez vous-même; c'est un bon exercice.

La sortie de la logique de rebond de contact peut alors être utilisée pour la détection de changement, pour faire une seule indication de cycle chaque fois qu'un contact est pressé, et cette indication peut ensuite être utilisée pour mettre à jour le compteur.

+0

Pourriez-vous recommander une bonne source pour apprendre Verilog des bases? – Chumanista

+1

Désolé, mais je préfère VHDL comme HDL; mais les critiques pour Verilog à [amazon.com] (http://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords=verilog) sont probablement un bon point de départ. –