N-Stufiges Flip Flop erzeugen

OP #7911433
Lesenswert?

Hallo zusammen,

ich würde gerne in VHDL ein n-Stufiges Flip Flop erzeugen, wobei ich den Parameter n über ein generic weitergeben wollte.

Ich habe mir zwei Codebeispiele überlegt, wobei beim ersten Codebespiel in der Simulation mit Vivado beim Ergebnis "X" auftauchen, also anscheinend mehrere Quellen für das Signal.

Kann bitte jemand die Codebeispiele bewerten oder hat evtl. noch einen besseren Vorschlag.

Vielen Dank im Voraus Daniel

Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #7911461
Lesenswert?

Daniel P. schrieb:

ich würde gerne in VHDL ein n-Stufiges Flip Flop erzeugen,

Du willst aus mehreren Flipflops ein n-stufiges Schieberegister erzeugen, oder? Und über dieses Schieberegister willst du ein Signal um n Takte verzögern.

wobei ich den Parameter n über ein generic weitergeben wollte.

Das geht für 1 Bit einfach so:

1
:
2
generic n : integer range 2 to 16 := 2;
3
:
4
:
5
signal sr: std_logic_vector (n-1 downto 0)
6
:
7
sr <= sr(n-2 downto 2) & inbit  when rising_edge(clk); -- schiebt nach links
8
:
9
outbit <= sr(n-1);
10
:

Und für Vektoren geht es in etwa so:

1
:
2
generic n : integer := 2;
3
:
4
type slv16_array  is array (n-1 downto 0) of std_logic_vector(15 downto 0);
5
signal vsr : slv16_array := (others => (others => '0'));
6
:
7
vsr <= vsr(n-2 downto 2) & invect when rising_edge(clk); -- liest ein und schiebt nach links
8
outvect <= vsr(n-1);
9
:

Wenn die Länge des Schieberegisters zur Laufzeit umgeschaltet werden soll, dann sieht es für 1 Bit so aus:

1
:
2
signal n : integer range 2 to 16 := 2; -- min. 2 Bit, max. 16 Bit lang
3
signal sr: std_logic_vector (15 downto 0); -- muss für maximale Länge ausgelegt sein
4
:
5
sr <= sr(n-2 downto 2) & inbit  when rising_edge(clk); -- schiebt nach links
6
:
7
outbit <= sr(n-1);
8
:

Die Schieberegister-Zeile mit dem "when rising_edge()" kann man natürlich auch auf die lange Art mit einem Prozess schreiben:

1
process begin
2
   wait until rising_edge(clk);
3
   sr <= sr(n-2 downto 2) & inbit; -- schiebt nach links
4
end process;

Oder die traditionelle, ganz ausführliche Art aus dem letzten Jahrtausend:

1
process (clk)
2
begin
3
   if rising_edge(clk) then
4
      sr <= sr(n-2 downto 2) & inbit; -- schiebt nach links
5
   end if;
6
end process;

also anscheinend mehrere Quellen für das Signal.

Für welches Signal?

OP #7911543
Lesenswert?

Sorry für die Verwirrung: Zum Hintergrund. Ich bekomme als Eingangssignal einen 16Bit Zeitstempel. In Abhängigkeit von einem Generic (in meinem Beispiel die Konstante c_clk_del) möchte ich den Zeitstempel um die Anzahl "c_clk_del" Takte verzögern. Das ganze muss nicht zur Laufzeit umgeschaltet werden.

Lothar M. schrieb:

also anscheinend mehrere Quellen für das Signal.

Für welches Signal?

time_stamp(0)

OP #7911597
Lesenswert?

Danke für die Hilfe, habe mich für folgende Lösung entschieden:

1
type slv16_array  is array (n-1 downto 0) of std_logic_vector(15 downto 0);
2
signal vsr : slv16_array := (others => (others => '0'));
3
signal vsr_out : std_logic_vector(15 downto 0);
4
generic n : natural := 2;
5
vsr <= vsr(n-2 downto 0) & invec when rising_edge(clk);  
6
vsr_out <= vsr(n-1) when n > 0 else
7
           invec;
#7912473
Lesenswert?

Bradward B. schrieb:

Auf den default-wert in Zeile 2 ist nach der Synthese kein Verlass.

Prinzipiell ja, aber sowas prüft man einmal, ob das vom jeweiligen Synthesetool richtig umsetzt wird. Und das Synthesetool wechselt man nicht so oft wie die Socken...

Ich hatte den Fall bei Lattice Diamond neulich, wo ich meinen Code etwas umformulieren musste:

Ein

1
    type config_type is array( 0 to 15) of  std_ulogic_vector( 7 downto 0);
2
    constant default_config : config_type :=
3
    (
4
        0      => "11110000",
5
        others => ( others => '0')
6
    );
7

8
    constant default_config_array : config_array_t := ( others => ( default_config));

wird später partiell überschrieben, aber die default_config wurde nur komplett mit '0' initialisiert.

Nach ausformulieren:

1
    signal config_array : config_array_t := default_config_array;
2

3
begin
4

5
    -- needed for Lattice LSE
6
    -- otherwise byte 0 is not correct inialized
7
    --config_array( 0)    <= default_config; -- is used
8
    config_array( 1)    <= default_config;
9
    config_array( 2)    <= default_config;
10
    ...
11

12
    module_i0: entity work.module
13
    port map
14
    (
15
        clk          => clk,                    -- : in    std_ulogic;
16
        ...
17
        config       => config_array( 0),       -- : out   config_type;
18
        ...
19
    );

klappte es wie gewünscht...

(Firma: Starfleet) #7912475
Lesenswert?

Auf den default-wert in Zeile 2 ist nach der Synthese kein Verlass.

Prinzipiell ja, aber sowas prüft man einmal, ob das vom jeweiligen Synthesetool richtig umsetzt wird. Und das Synthesetool wechselt man nicht so oft wie die Socken...

Hm, erzähl das mal einem Barfüßler ;-)

Ich seh hier eher das Problem der Architektur, gibt man einen Reset-Value an, nimmt das Synthesetool oft keine Schieberegister.Makros wie SRL16 (bspw. Xilinx Spartan) auch wenn es in der konkreten FPGA-Architektur möglich wäre. Aber der TO wollte ja lt. Headline ohnehin ("riesige") FF statt schlanke Schiebeketten.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren