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
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.
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
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,
Jup danke. Eure Beschreibungen gefallen mir. So ausführlich mit den Konflikten steht es nicht im Buch bei mir. Gruss
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
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; |
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
Jup, die Simulation stürzt vom QuartusII ab auf meinem Window8 gleich nach dem starten. Habe jetzt schon veschiedene Quartusversionen geladen. Danke. Gruss
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; |
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.