Forum: FPGA, VHDL & Co. Daten aus RAM zyklisch in VHDL lesen und parallel ausgeben


von shottky (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute!

Ich habe ein RAM Baustein in VHDL implementiert, den ich via SPI von 
extern seriell beschreibe und auch seriell auslesen kann.
Jetzt ist es jedoch so, dass ich für meine Applikation ständig 6 Werte 
von meinen gesamten RAM-Daten als Initialisierungswerte für den 
Programmablauf meiner Applikation benötige.

Kann mir jemand einen Tipp geben, wie ich so einen  „Datendemultiplexer“ 
programmieren kann, der mir zyklisch die Daten aus den ersten Sechs 
Adressen herausliest und nach außen gibt?
Zur besseren Verdeutlichung habe ich euch ein kleines Blockschaltbild 
des benötigten „Datendemultiplexers“ beigefügt.
Oder gibt es so etwas in der Richtung schon im Netz? Ich selber habe 
leider noch nichts dergleichen gefunden…

Vielen Dank schon mal!
Shottky

von Christian R. (supachris)


Lesenswert?

Da reicht doch ein Zähler an den Lese-Adressleitungen des RAMs. Dazu 6 x 
32 FlipFlops, die bei entsprechendem Zählerstand die Daten des RAM 
speichern. Die FPGA-internen BlockRAMs sind sowieso Dual Port, in deinem 
Fall bräuchtest du anscheinend sogar nur "simple Dual Port", also nur 
eine Schreib- und eine Leseseite.

von shottky (Gast)


Lesenswert?

Also ich habe eine kleine Statemachine implementiert, die nacheinander 
die Adressen ausgibt und die Eingangswerte der jeweiligen Adresse an den 
Ausgang weiterschalten bzw. in den Ausgang speichern soll.

Problem ist jedoch, dass die Werte nur für einen Takt ausgegeben werden. 
Der Wert am Ausgang wird also wieder gelöscht.

Hat da jemand eine Idee? Muss ich die Werte zwischenspeichern und dann 
erst dem Ausgang zuweisen?

Gruß Shottky

Hier mein VHDL-Code:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
use IEEE.std_logic_unsigned.all;
5
use work.mytype.all;
6
7
entity autom_demux is
8
port (
9
    clk   : in  STD_LOGIC;
10
    reset   : in  STD_LOGIC;  
11
    set:   in  STD_LOGIC;  
12
    INPUT : in std_logic_vector(31 downto 0);
13
    ADDR : out  STD_LOGIC_VECTOR (4 downto 0);
14
    OUTPUT_0 : out  STD_LOGIC_VECTOR (15 downto 0);
15
    OUTPUT_1 : out  STD_LOGIC_VECTOR (31 downto 0);
16
    OUTPUT_2 : out  STD_LOGIC_VECTOR (31 downto 0);
17
    OUTPUT_3 : out  STD_LOGIC;
18
    OUTPUT_4 : out  STD_LOGIC_VECTOR (2 downto 0);
19
    OUTPUT_5 : out  STD_LOGIC;
20
    OUTPUT_6 : out  STD_LOGIC
21
     );
22
    
23
    
24
end autom_demux;
25
26
27
ARCHITECTURE a OF autom_demux IS
28
   TYPE STATE_TYPE IS (state0, state1, state2, state3, state4, state5, state6, state7);
29
   SIGNAL state   : STATE_TYPE;
30
31
BEGIN
32
   
33
  PROCESS (clk, reset)
34
   BEGIN
35
      IF reset = '0' THEN
36
         state <= state0;
37
      ADDR(4 downto 0) <= "00000";
38
      ELSIF (clk'EVENT AND clk = '1') THEN
39
         CASE state IS
40
            WHEN state0=>
41
               IF set = '1' THEN
42
                  state <= state1;
43
            ADDR(4 downto 0) <= "00001";
44
               ELSE
45
                  state <= state0;
46
            ADDR(4 downto 0) <= "00000";
47
               END IF;
48
            WHEN state1=>
49
               IF set = '1' THEN
50
                  state <= state2;
51
            ADDR(4 downto 0) <= "00010";
52
               ELSE
53
                  state <= state1;
54
            ADDR(4 downto 0) <= "00001";
55
               END IF;
56
            WHEN state2=>
57
               IF set = '1' THEN
58
                  state <= state3;
59
            ADDR(4 downto 0) <= "00011";
60
               ELSE
61
                  state <= state2;
62
            ADDR(4 downto 0) <= "00010";
63
               END IF;
64
            WHEN state3=>
65
               IF set = '1' THEN
66
                  state <= state4;
67
            ADDR(4 downto 0) <= "00100";
68
               ELSE
69
                  state <= state3;
70
            ADDR(4 downto 0) <= "00011";
71
               END IF;
72
            WHEN state4=>
73
               IF set = '1' THEN
74
                  state <= state5;
75
            ADDR(4 downto 0) <= "00101";
76
               ELSE
77
                  state <= state4;
78
            ADDR(4 downto 0) <= "00100";
79
               END IF;
80
            WHEN state5=>
81
               IF set = '1' THEN
82
                  state <= state6;
83
            ADDR(4 downto 0) <= "00110";
84
               ELSE
85
                  state <= state5;
86
            ADDR(4 downto 0) <= "00101";
87
               END IF;
88
            WHEN state6=>
89
               IF set = '1' THEN
90
                  state <= state7;
91
            ADDR(4 downto 0) <= "00111";
92
               ELSE
93
                  state <= state6;
94
            ADDR(4 downto 0) <= "00110";
95
               END IF;
96
            WHEN state7=>
97
               IF set = '1' THEN
98
                  state <= state0;
99
            ADDR(4 downto 0) <= "00000";
100
               ELSE
101
                  state <= state7;
102
            ADDR(4 downto 0) <= "00111";
103
               END IF;
104
         END CASE;
105
      END IF;
106
   END PROCESS;
107
   
108
   PROCESS (state)
109
   BEGIN
110
      CASE state IS
111
         WHEN state0 =>
112
            OUTPUT_0 <= INPUT(15 downto 0);
113
         WHEN state1 =>
114
            OUTPUT_1 <= INPUT(31 downto 0);
115
         WHEN state2 =>
116
            OUTPUT_2 <= INPUT(31 downto 0);
117
         WHEN state3 =>
118
            OUTPUT_3 <= INPUT(0);
119
         WHEN state4 =>
120
            OUTPUT_4 <= INPUT(2 downto 0);
121
         WHEN state5 =>
122
            OUTPUT_5 <= INPUT(0);
123
         WHEN state6 =>
124
            OUTPUT_6 <= INPUT(0);
125
         WHEN state7 =>
126
            NULL;
127
      END CASE;
128
   END PROCESS;
129
   
130
END a;

von Duke Scarring (Gast)


Lesenswert?

shottky schrieb:
> Also ich habe eine kleine Statemachine implementiert, die nacheinander
> die Adressen ausgibt und die Eingangswerte der jeweiligen Adresse an den
> Ausgang weiterschalten bzw. in den Ausgang speichern soll.
>
> Problem ist jedoch, dass die Werte nur für einen Takt ausgegeben werden.
> Der Wert am Ausgang wird also wieder gelöscht.
Dann muß da noch ein WAIT-State dazwischen. Der muß solange warten, bis 
die Daten aus dem RAM angekommen sind.

> Hier mein VHDL-Code:
>
> library IEEE;
> use IEEE.STD_LOGIC_1164.ALL;
> use IEEE.NUMERIC_STD.ALL;
> use IEEE.std_logic_unsigned.all;
Nimm mal bitte die std_logic_unsigned raus. Sihe hier:
Beitrag "Re: IEEE.STD_LOGIC_ARITH.ALL obsolete"

Duke

von shottky (Gast)


Lesenswert?

Danke für deine Antwort!

Du meinst einfach ein paar Takte zwischen dem Anlegen der Adresse und 
Ausgeben der Daten (von der Adresse) warten? Wieviele Takte sollten dies 
sein?

von Duke Scarring (Gast)


Lesenswert?

shottky schrieb:
> Du meinst einfach ein paar Takte zwischen dem Anlegen der Adresse und
> Ausgeben der Daten (von der Adresse) warten? Wieviele Takte sollten dies
> sein?
Sehe ich das richtig, daß Du FPGA-internen RAM verwenden willst? Bei 
internem RAM sind die Daten üblicherweise im nächsten Takt verfügbar.

Hast Du schon eine Testbench? Damit läßt sich schön die Funktionalität 
des Codes zeigen.

Duke

von shottky (Gast)


Lesenswert?

Ja richig es ist ein RAM aus der LPM-Library.
Eine Testbench habe ich nicht. Nutze SignalTap.

Gruß

von Falk B. (falk)


Lesenswert?

@ shottky (Gast)

>Ja richig es ist ein RAM aus der LPM-Library.
>Eine Testbench habe ich nicht. Nutze SignalTap.

Selber Schuld. Eine Testbench würde dir in 10 Minuten das Verhalten des 
Codes klar zeigen.

Beitrag "Latente Phobie gegenüber VHDL-Simulationen"

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.