Forum: FPGA, VHDL & Co. Undefined Signals nach Synthese


von Matthias (Gast)


Lesenswert?

Hallo,

ich hänge hier schon länger an dem Problem, dass ein Signal, das in der 
funktionalen Simulation brav auf '0' geht in der gate-level Simulation 
auf 'U' geht. Ich hab das Problem soweit verfolgen können, dass ich 
annehme, dass es an fehlerhaftem Lesen von einem bidirektionalen Port 
liegt. Von dort pflanzt sich das undefined durch die Logik fort.

Hier der Code der Komponente, die von dem bidirektionalen Port liest 
bzw. darauf schreibt. Die Daten, die vom outbuffer auf dq geschrieben 
werden, passen. Die Werte, die an dq anliegen, passen auch. Der inbuffer 
ist das erste Signal bei dem undefined auftaucht und zwar genau dann, 
wenn von dq in inbuffer eingelesen wird.


------------------------------------------------------------------------ 
---
library IEEE;
use IEEE.std_logic_1164.all;

entity data_path is
  generic (
    data_width : natural := 16);
  port (
    clk, reset : in    std_logic;
    wr_data    : in    std_logic_vector(data_width-1 downto 0);
    rd_data    : out   std_logic_vector(data_width-1 downto 0);
    dq         : inout std_logic_vector(data_width-1 downto 0);
    rd_wr_data   : in    std_logic;
    wr_wr_data   : in    std_logic;
    rd_mem_data : in std_logic;
    wr_mem_data : in std_logic);

end data_path;

architecture rtl of data_path is
  signal inbuffer  : std_logic_vector(data_width-1 downto 0);
  signal outbuffer : std_logic_vector(data_width-1 downto 0);
begin  -- rtl

  -- purpose: does the data shifting through the data path
  -- type   : sequential
  -- inputs : CLK, RESET
  -- outputs:
  DATA_PATH : process (CLK, RESET)
  begin  -- process DATA_PATH
    if RESET = '1' then
      rd_data <= (others => '0');
      inbuffer <= (others => '0');
      outbuffer <= (others => '0');
    elsif CLK'event and CLK = '1' then

      if rd_wr_data = '1' then
        outbuffer <= wr_data;
        dq <= (others => 'Z');
      elsif wr_wr_data = '1' then
        dq <= outbuffer;
        inbuffer <= inbuffer;
      elsif rd_mem_data = '1' then
        inbuffer <= dq;
        outbuffer <= outbuffer;
      elsif wr_mem_data = '1' then
        rd_data <= inbuffer;
        outbuffer <= outbuffer;
        dq <= (others => 'Z');
      end if;
    end if;
  end process DATA_PATH;

end rtl;

------------------------------------------------------------------------ 
---


Muss ich das anders schreiben, damit Quartus versteht und macht, was ich 
will? Das würde für mich am ehesten zu dem Verhalten passen, dass das 
Design in der funktionalen Simulation keine undefinierten Signale 
erzeugt, während es nach der Synthese da Probleme gibt.

Danke schon mal,
Matthias

von Jan M. (mueschel)


Lesenswert?

Hast du denn eine Testbench, die an dq auch ein Signal anlegt, wenn 
davon gelesen wird?
Ansonsten müsste auf den ersten Blick alles stimmen.

von Matthias F. (flint)


Lesenswert?

Nachdem es ein SDRAM-Interface ist benutze ich einfach dasselbe 
SDRAM-Modell, das ich auch schon für die funktionale Simulation benutzt 
habe. Da kommen auch die richtigen Werte wieder aus dem Speicher heraus, 
die vorher hineingeschrieben wurden.

von Jan M. (mueschel)


Lesenswert?

Wenn du wr_wr_data setzt, werden Daten in dq geschrieben. Setzt du 
anschließend rd_mem_data, liegen die Daten immer noch an!
Schreibe am besten einen eigenen Prozess für dq, und benutze intern nur 
inbuffer und outbuffer.

Ich weiß allerdings nicht, warum die funktionale Simulation funktioniert 
- eigentlich sollte hier der Konflikt sichtbar sein in Form von 'X'.

von Matthias (Gast)


Lesenswert?

wr_wr_data und rd_mem_data zb kommen nicht in Folge, sonst würde es 
klarerweise zu einem Problem kommen. Der inbuffer ist für das Einlesen 
der Daten zuständig, der outbuffer für das Schreiben.

Die Sequenz beim Einlesen ist also, dass zuerst rd_mem_data gesetzt wird 
und im Cycle darauf wr_mem_data.

Im Moment suche ich doch eher wieder in Richtung Timing-Problem.

von Matthias F. (flint)


Lesenswert?

Ok, jetzt denke ich, ich weiß, was es ist, nämlich eine deftige 
Setup-Time Verletzung an den Registern, die die Daten übernehmen sollen. 
Ich hätte (laut Micron Simulationsmodell) ein wenig Spielraum, die Clock 
zum Speicher nach hinten zu verschieben, ca 1,5 ns, da hab ich schon 
eine PLL dafür. Das reicht aber nicht, ich müsste das Input Delay from 
Pin to Register auf <= 3ns bringen. Diese Quartus Option kapier ich aber 
ehrlich gesagt nicht ganz, weiß jemand, was man da für den Cyclone 2 
einstellen muss, um in diese Richtung zu kommen? Nachdem ich 
arbeitsbedingt eher mit Xilinx arbeite kenne ich mich mit der Altera Sw 
nicht gut aus.

Ich habe mal einfach die Option Fast Input Register genommen, da haben 
die Ausgänge zwar brav Daten ausgegeben und das Speichermodell beim 
Auslesen die richtigen Werte zurückgeschickt, aber die Input Register 
haben die Daten aus irgendeinem Grund nicht übernommen.

von Matthias F. (flint)


Lesenswert?

Da ich immer noch an dem Problem hänge, möchte ich noch mal fragen, ob 
sich hier wer mit Quartus und Cyclone 2 auskennt. Irgendwie schaffe ich 
es nicht, das zu realisieren, was ich will.

Ich habe es jetzt mit input- und outputregistern versucht, wie gesagt, 
da kommen anscheinend nicht einmal Daten am input register an. Mir ist 
nicht ganz klar, wieso, vielleicht kann mir da ja jemand auf die Sprünge 
helfen.

Ansonsten habe ich aber noch weitere Möglichkeiten, das Timing 
hinzubekommen. Wenn ich die Inputregister nicht schneller bekomme kann 
ich immer noch an der Clock für den SDRAM zu drehen. Das ist mit der 
instanziierten PLL kein Problem. Ich müsste dann aber auch die 
Outputregister etwas verzögern, ca 2ns, damit sie ordentlich bei der 
clockflanke anliegen. Und da steig ich durch die Altera Dokumentation 
nicht durch. Es gibt die "Delay from output register to output pin" 
Option im Assignment Editor, die aber nur die Werte 0 und 1 annehmen 
kann. Bei der Synthese meldet Quartus aber, dass die Delay Chain nicht 
verwendet wird und der Wert von 1 auf 0 zurückgesetzt wird.

Also nehme ich an, dass es da noch eine zweite Option gibt, die ich 
setzen muss. Nur finde ich dazu nix und, wie gesagt, ich steig durch die 
Altera Dokumentation nicht so richtig durch.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.