Question

Je l'ai fait une simulation du comportement de mon code, et il fonctionne parfaitement. Les résultats sont tels que prévus. Quand je synthétise mon code et de le transférer à un FPGA et spartiate 3e essayer d'analyser à l'aide ChipScope, les résultats ne sont pas encore à ce que je me serais attendu. Qu'ai-je fait mal? http://pastebin.com/XWMekL7r

Était-ce utile?

La solution

Votre problème est avec des lignes 13-16, et définir des valeurs initiales pour les registres d'état:

 reg    [OUTPUT_WIDTH-1:0] previousstate = 0;              
 reg    [OUTPUT_WIDTH-1:0] presentstate = 1;
 reg    [6:0] fib_number_cnt = 1;  
 reg    [OUTPUT_WIDTH-1:0] nextstate = 1; 

Ceci est un équivalent à écrire une déclaration « initiale » l'attribution de ces valeurs, qui n'est pas synthétisable - il n'y a pas une telle chose comme une valeur par défaut dans le matériel. Lorsque vous mettez votre conception à l'intérieur d'un FPGA, tous ces registres prendra des valeurs aléatoires.

Au lieu de cela, vous devez initialiser ces compteurs / états à l'intérieur de votre bloc toujours, lorsque la réinitialisation est élevé.

always @(posedge clk or posedge reset)
  if (reset) begin
     previousstate <= 0;
     presentstate <= 1;
     ... etc ...
  end

Réponse aux questions de suivi:

Lorsque vous initialisez le code comme ça, rien du tout se passe dans le matériel - il se complètement ignoré, comme si vous avez mis dans une déclaration d'affichage $. L'outil de synthèse ignore tous les simulation uniquement des constructions, tout en vous donnant généralement une sorte de mise en garde à ce sujet (cela dépend vraiment de l'outil).

Maintenant, le blocage et la question non-blocage nécessite une très longue réponse :). Je vais vous diriger vers ce document de SNUG-2000, qui est probablement le meilleur papier jamais écrit sur le sujet. Il répond à votre question, ainsi que beaucoup d'autres sur le sujet. Par la suite, vous comprendrez pourquoi en utilisant des instructions de blocage dans la logique séquentielle est considérée comme une mauvaise pratique, et pourquoi votre code fonctionne très bien avec le blocage des déclarations de toute façon.

http://cs.haifa.ac.il /courses/verilog/cummings-nonblocking-snug99.pdf


Plus de réponses:

Comme d'habitude « modèle » à la création d'une logique comme la vôtre est d'avoir deux blocs, toujours une définition de la logique, et une définissant les flops. Dans le premier cas, vous utilisez des instructions de blocage pour mettre en œuvre la logique, et dans celui-ci vous verrouiller (ou réinitialiser) la valeur générée. Donc, quelque chose comme ceci:

wire some_input;

// Main logic (use blocking statements)
reg state, next_state;
always @*
  if (reset) next_state = 1'b0;
  else begin
    // your state logic
    if (state) next_state = some_input;
    else next_state = 1'b0;
  end

// Flops (use non-blocking)
always @(posedge clock)
  if (reset) state <= 1'b0;
  else state <= next_state;

Notez que j'utilise une réinitialisation synchrone, mais vous pouvez utiliser async si nécessaire.

Autres conseils

Les lignes 13-16 sont corrects. "Reg [6: 0] fib_number_cnt = 1;" est pas la même que l'utilisation de la déclaration « initiale ». Lisez le guide de synthèse Xilinx pour une description plus détaillée de la façon d'initialiser les registres.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top