Forum: FPGA, VHDL & Co. Signal in mehrereh Processen ansprechen.


von peter (Gast)


Lesenswert?

Danke Michael Fischer (Datum: 20.05.2014 18:37)
----------------------------
D.h. das Signal RamAddr wird an mehreren Stellen beschrieben. So etwas
ist erlaubt wenn das in einem "process" gemacht wird, aber nicht wenn
es von mehreren Prozessen versucht wird.
------------------------------

Ich dachte wenn ich die in "architecture" reinsetze das sie überall 
angesprochen werden können.

Danke.
Gruss

von Duke Scarring (Gast)


Lesenswert?

Hallo Lernresistenter!
(lies Bücher, lern zitieren, lern den Unterschied zwischen Programm und 
Beschriebung...)

peter schrieb:
> das sie überall
> angesprochen werden können
Lesen ja, schreiben nein.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

peter schrieb:
> Ich dachte wenn ich die in "architecture" reinsetze das sie überall
> angesprochen werden können.
Es geht ja nur beim Zuweisen schief. Genauer gesagt dann, wenn aus zwei 
Prozessen das selbe Signal getrieben wird:
1
    process (b) begin
2
       if b='1' then 
3
          c<='0'; 
4
       else 
5
          c<='1'; 
6
       end if;
7
    end process;
8
9
    process (a) begin
10
       if a='1' then 
11
          c<='0'; 
12
       else 
13
          c<='1'; 
14
       end if;
15
    end process;
Wie denkst du denn, dass sowas in realer Hardware innerhalb eines 
FPGAs aussehen sollte? Dass einfach die Ausgänge von ein paar Flipflops 
oder LUTs zusammengeschaltet werden und dann der Stärkere gewinnt?

Nicht mal sowas geht, obwohl hier eigentlich kein Konflikt vorliegt:
1
    process (a) begin
2
       if a='1' then 
3
          c<='1'; 
4
       end if;
5
    end process;
6
7
    process (a) begin
8
       if a='0' then 
9
          c<='0'; 
10
       end if;
11
    end process;
Und warum?
Weil der Synthesizer hier mit seiner Mustererkennung zwei Latches 
erzeugt und die dann nicht zusammenschalten kann...

: Bearbeitet durch Moderator
von Fpgakuechle K. (Gast)


Lesenswert?

Duke Scarring schrieb:

>  lern den Unterschied zwischen Programm und
> Beschriebung...)
>
> peter schrieb:
>> das sie überall
>> angesprochen werden können
> Lesen ja, schreiben nein.

(1)oben die Beachtung des Unterschieds zwischen Programm und 
Beschreibung eingefordert und unten dann  "Signal schreiben" (Software) 
statt "Signal treiben" (Hardware) verwendet.

(2)Und es ist sehr wohl möglich ein Signal von mehreren processes aus 
zuzuweisen.
Für diesen Fall kennt VHDL die resolution function (Auflösungsfunktion), 
in der Bibliothek an dem Schlüsselwort resolved erkennbar.
Siehe bspw. dort: 
http://www.ida.liu.se/~TDTS01/lectures/14/lect3.frm.pdf

Anders wäre es in VHDL nicht möglich open collector, wired or, PullUp 
etc. zu simulieren. (was man aber immer wieder braucht bspw. für VME-BUS 
IRQ-system oder I2C ACK)


Und genau diese Auflösungsfunktion ist der Unterschied zwischen 
std_logic und std_ulogic (u steht für unresolved).
Siehe: 
http://objectmix.com/vhdl/208460-what-difference-between-types-std_logic-std_ulogic.html
Also ein signal vom typ std_logic kann mehrere Quellen haben, std_ulogic 
nicht (simulator bricht mit error ab).

Ein deutsches Buch das diese Simulatordetails beschreibt ist ISBN 
3-540-59143-5 (auf S.110 ff.) Allerdings ein sehr "akademisches" Buch 
mit überwiegenden Focus auf Simulation und damit IMHO für FPGA-Designer 
nur bedingt hilfreich).

Das dergleichen aber von der Synthese verweigert wird, wenn es die 
Zielhardware nicht zuläßt hat Lothar in seinem Post dargestellt.

Dort allerdings: 
http://web02.gonzaga.edu/faculty/talarico/cpen430/documents/vhdl-for-synthesis.pdf 
lässt man die Frage ob resolved signals zufriedend stellend 
synthetisierbar sind offen und empfiehlt um Probleme von vornherein 
auszuschliessen keine zwei Quellen ein Signal treiben zu lassen (S.13).

MfG,

von peter (Gast)


Lesenswert?

Jup danke.
Eure Beschreibungen gefallen mir.

So ausführlich mit den Konflikten steht es nicht im Buch bei mir.

Gruss

von peter (Gast)


Angehängte Dateien:

Lesenswert?

Jup dann kann das mit dem speicher_ram nicht funktionieren, weil es 2x 
zugewiesen wird :
1
Type ram_vec is ARRAY (0 to 127) OF unsigned(7 downto 0);
2
signal speicher_ram : ram_vec;
3
4
type Rom128x8 is array (0 to 127) of unsigned (7 downto 0); 
5
  constant Speicher_rom : Rom128x8 := (
6
    x"ff",  x"ff",  x"81",  x"82",  x"83",  x"11",  x"14",  x"17",
7
    x"ff",  x"ff",  x"ff",  x"23",  x"26",  x"29",  x"2c",  x"2f",
8
..................................

Danke.
Gruss

von peter (Gast)


Lesenswert?

Habe ich hier so einen Typischen Fall?
Wenn ich die Daten vom PC sende sw(2) kommt in den Ramzellen nur der 
Wert "128".
Wenn ich aber mit Sw(0) dem ROM ins RAM schreibe, kann ich die Daten vom 
RAM zum PC  übertragen mit sw(1).

Gruss
1
library IEEE; 
2
use IEEE.STD_LOGIC_1164.ALL; 
3
use IEEE.NUMERIC_STD.ALL; 
4
5
entity ram_array is
6
  Generic ( Quarz_Taktfrequenz : integer := 50000000;  
7
              Baudrate        : integer  := 9600 
8
          );      
9
  port(
10
    clk    : in  std_logic;
11
    sw     : in  std_logic_vector(3 downto 0);
12
    TXD    : out  STD_LOGIC; 
13
    RXD    : in   STD_LOGIC;
14
    led_g  : out  STD_LOGIC_VECTOR (7 downto 0)     
15
    );
16
end ram_array;
17
18
architecture Behavioral of ram_array is
19
20
signal rxd_sr  : std_logic_vector (3 downto 0) := "1111";        
21
signal rxsr    : std_logic_vector (7 downto 0) := "00000000";     
22
signal rxbitcnt : integer range 0 to 9 := 9;
23
signal rxcnt   : integer range 0 to (Quarz_Taktfrequenz/Baudrate)-1; 
24
signal RX_Data : STD_LOGIC_VECTOR (7 downto 0);  
25
26
signal txstart : std_logic := '0';
27
signal txsr    : std_logic_vector  (9 downto 0) := "1111111111";  
28
signal txbitcnt : integer range 0 to 10 := 10;
29
signal txcnt    : integer range 0 to (Quarz_Taktfrequenz/Baudrate)-1;
30
31
signal TX_Start : STD_LOGIC :='0';
32
signal TX_Data  : STD_LOGIC_VECTOR (7 downto 0);
33
signal TX_Wert  : STD_LOGIC_VECTOR (7 downto 0);
34
35
signal c : integer range 0 to 10000000 := 0; 
36
37
signal RomAddr: integer range 0 to 128 := 0; 
38
signal RamAddr: integer range 0 to 128 := 0; 
39
40
Type ram_vec is ARRAY (0 to 127) OF unsigned(7 downto 0);
41
signal speicher_ram : ram_vec;
42
43
type Rom128x8 is array (0 to 127) of unsigned (7 downto 0); 
44
  constant Speicher_rom : Rom128x8 := (
45
    x"ff",  x"ff",  x"81",  x"82",  x"83",  x"11",  x"14",  x"17",
46
    x"ff",  x"ff",  x"ff",  x"23",  x"26",  x"29",  x"2c",  x"2f",
47
    x"32",  x"36",  x"39",  x"3c",  x"3e",  x"40",  x"43",  x"46",
48
    x"48",  x"4b",  x"4d",  x"50",  x"52",  x"54",  x"57",  x"59",
49
    x"5b",  x"5d",  x"5f",  x"62",  x"64",  x"65",  x"67",  x"69",
50
    x"6b",  x"6d",  x"6e",  x"70",  x"71",  x"73",  x"74",  x"75",
51
    x"76",  x"77",  x"79",  x"79",  x"7a",  x"7b",  x"7c",  x"7d",
52
    x"7d",  x"7e",  x"7e",  x"7f",  x"7f",  x"7f",  x"7f",  x"7f",
53
    x"01",  x"02",  x"04",  x"08",  x"0e",  x"11",  x"14",  x"17",
54
    x"1a",  x"1d",  x"20",  x"23",  x"26",  x"29",  x"2c",  x"2f",
55
    x"32",  x"36",  x"39",  x"3c",  x"3e",  x"40",  x"43",  x"46",
56
    x"48",  x"4b",  x"4d",  x"50",  x"52",  x"54",  x"57",  x"59",
57
    x"5b",  x"5d",  x"5f",  x"62",  x"64",  x"65",  x"67",  x"69",
58
    x"6b",  x"6d",  x"6e",  x"70",  x"71",  x"73",  x"74",  x"75",
59
    x"76",  x"77",  x"79",  x"79",  x"7a",  x"7b",  x"7c",  x"7d",
60
    x"7d",  x"7e",  x"7e",  x"7f",  x"7f",  x"7f",  x"7f",  x"7f");
61
62
begin
63
64
process(clk)
65
begin
66
  if rising_edge(clk)  then
67
    c <= c+1; 
68
    tx_start <= '0';
69
    
70
    if (RomAddr < 128) and  (sw(0) = '1') then    -- rom ins ram kopieren wenn sw(0)='1' (funktioniert)
71
    speicher_ram(RomAddr) <= Speicher_rom(RomAddr); 
72
      RomAddr <= RomAddr + 1;     
73
  
74
    elsif (c=5000000 ) and (sw(1)='1') then -- ram senden mit rs232 wenn sw(1)='1' (funktioniert)                    
75
      c <= 0;   
76
      RamAddr <= RamAddr +1;      
77
      if (RamAddr < 128) then             
78
        TX_Data <= std_logic_vector(Speicher_ram(RamAddr)); 
79
        tx_start <= '1';
80
      end if;
81
      
82
    elsif (sw(2) = '1') and (RamAddr < 128) and (rx_data > "00000000") then  -- 128 Byte vom PC ins RAM lesen (es wird nur "128" in alle Zellen geschrieben)  
83
      speicher_ram(RamAddr) <= unsigned(rx_data); 
84
      RamAddr <= RamAddr + 1;   
85
      led_g <= rx_data;
86
      
87
    elsif   (sw(3)='1') then  -- adressen mit sw(3)='1' auf "0" setzen funktioniert 
88
      RamAddr <= 0;  
89
      RomAddr <= 0;        
90
    end if;
91
  end if;  
92
end process;
93
94
process(clk) ---rs232 empfangen
95
begin
96
  if rising_edge(clk) then 
97
    rxd_sr <= rxd_sr(rxd_sr'left-1 downto 0) & RXD;
98
    if (rxbitcnt<9) then   
99
       if(rxcnt<(Quarz_Taktfrequenz/Baudrate)-1) then 
100
          rxcnt    <= rxcnt+1;
101
       else
102
          rxcnt    <= 0; 
103
          rxbitcnt <= rxbitcnt+1;
104
          rxsr     <= rxd_sr(rxd_sr'left-1) & rxsr(rxsr'left downto 1); 
105
       end if;
106
    else 
107
       if (rxd_sr(3 downto 2) = "10") then                 
108
          rxcnt    <= ((Quarz_Taktfrequenz/Baudrate)-1)/2; 
109
          rxbitcnt <= 0;
110
       end if;
111
    end if;
112
  end if;      
113
end process;
114
RX_Data <= rxsr;   
115
  
116
process(clk) --- rs232 senden
117
begin
118
if rising_edge(clk) then 
119
  txstart <= TX_Start;
120
  if (TX_Start='1' and txstart='0') then 
121
     txcnt    <= 0;                      
122
     txbitcnt <= 0;                      
123
     txsr     <= '1' & TX_Data & '0';    
124
  else
125
     if(txcnt<(Quarz_Taktfrequenz/Baudrate)-1) then
126
        txcnt <= txcnt+1;
127
     else  
128
        if (txbitcnt<10) then
129
          txcnt    <= 0;
130
          txbitcnt <= txbitcnt+1;
131
          txsr     <= '1' & txsr(txsr'left downto 1);
132
        end if;
133
     end if;
134
  end if;
135
end if;    
136
end process;
137
TXD  <= txsr(0); 
138
      
139
end Behavioral;

von Duke Scarring (Gast)


Lesenswert?

peter schrieb:
> Habe ich hier so einen Typischen Fall?
> Wenn ich die Daten vom PC sende sw(2) kommt in den Ramzellen nur der
> Wert "128".
> Wenn ich aber mit Sw(0) dem ROM ins RAM schreibe, kann ich die Daten vom
> RAM zum PC  übertragen mit sw(1).
Was sagt die Simulation?

Duke

von peter (Gast)


Lesenswert?

Jup, die Simulation stürzt vom QuartusII ab auf meinem Window8 gleich 
nach dem starten. Habe jetzt schon veschiedene Quartusversionen geladen.

Danke.
Gruss

von peter (Gast)


Lesenswert?

Wenn ich jetzt das ROM/RAM Füllen zusammenfasse in einer IF , dann 
werden gemäß led_grün die Daten "rx_data"  vom Pc richig angenommen.

Wenn ich aber mit SW(1) die Daten zum PC schicke aus dem RAM , steht da 
nur "68" drin in allen Zellen.

GRuss
1
process(clk)
2
begin
3
  if rising_edge(clk)  then
4
    if (RomAddr < 128) and  (sw(0) = '1') then    
5
      speicher_ram(RomAddr) <= Speicher_rom(RomAddr); 
6
      RomAddr <= RomAddr + 1;     
7
    elsif (sw(2) = '1') and (RamAddr < 128) and (rx_data > "00000000") then    
8
      speicher_ram(RamAddr) <= unsigned(rx_data); 
9
      RamAddr <= RamAddr + 1;   
10
      led_g <= rx_data;
11
    end if;
12
    
13
    if (c<5000000 ) and (sw(1)='1') then        
14
      c <= c+1; 
15
      tx_start <= '0';
16
    else             
17
      c <= 0;   
18
      RamAddr <= RamAddr +1;      
19
      if (RamAddr < 128) then             
20
        TX_Data <= std_logic_vector(Speicher_ram(RamAddr)); 
21
        tx_start <= '1';
22
      end if;
23
    end if;
24
      
25
    if   (sw(3)='1') then   
26
      RamAddr <= 0;  
27
      RomAddr <= 0;        
28
    end if;
29
  end if;  
30
end process;

von peter (Gast)


Lesenswert?

Hmm...habe ich hier ein Denkfehler im Ablauf?
1
if (c<5000000 ) and (sw(1)='1') then        
2
      c <= c+1; 
3
      tx_start <= '0';
4
    else             
5
      c <= 0;   
6
      RamAddr <= RamAddr +1;      
7
      if (RamAddr < 128) then             
8
        TX_Data <= std_logic_vector(Speicher_ram(RamAddr)); 
9
        tx_start <= '1';
10
      end if;
11
    end if;

Danke.
Gruss

: Bearbeitet durch Moderator
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

peter schrieb:
> Hmm...habe ich hier ein Denkfehler im Ablauf?
Was ist noch mal das zugehörige Problem?

> RamAddr <= RamAddr +1;
Wie weit darf die denn laufen? Es ist dir schon klar, dass der Zähler in 
der realen Hardware einfach wieder bei 0 anfängt? Wir hatten das doch 
schon durchgekaut...

peter schrieb:
> die Simulation stürzt vom QuartusII ab auf meinem Window8 gleich nach
> dem starten.
Ändere das. du wirst ohne Simulator nicht weit kommen mit FPGAs. Schon 
der kleinste Fehler wird dich (und uns) tagelang beschäftigen.

> ----------------------------
> ...
> ----------------------------
Nimm bitte die VHDL Tags zum Formatieren des Quelltextes.

: Bearbeitet durch Moderator
von peter (Gast)


Lesenswert?

Jup danke.
Das ist mir klar.

WEnn zum PC gesendet wird fängt er wieder bei "0" an, das ist so gewollt 
das es im vorgegebenen Raster abläuft.

Gruss

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.