Hallo, dies ist mein erstes Projekt mit einem FPGA. Vorher habe ich VHDL auf nem 95144 PLD schon probiert, das Ding ist mit einigen Adressvergleichen aber ruckzuck voll. Ich habe mir eine Platine gemacht, auf dem Levelshifter für den 16 Bit breiten Adressbus sowie 8Bit breiten Datenbus für die Pegelanpassung draufsitzen. Ausserdem sind auf dem Board 12 7-Segment-Anzeigen, 16 LEDs, 8 Schalter sowie 2 Taster. Das ganze hängt an einem ATARI 800XL oder 130XE ! (Ja, die leben noch :-) ) Auf den oberen 6 Anzeigen wird eine über eine im Atari "freigemachte" Adresse die "Debug-Adresse" eingestellt, über die unteren 6 quasi das gleiche nochmal, allerdings mit zuschaltbaren "Triggerausgang", der mittels 74x123 ein längeres Taktsignal ausgibt, wenn auf die "Trigger-Adresse" zugegriffen wird. Diesen Ausgang kann man z.B. für das einschalten eines Freezers benutzen (als Taster-Simulation). Ausserdem gibt es die Möglichkeit, bei Trigger-Treffer einen kurzen Piepton einzuschalten. Die Anzeigen, LEDs, Schalter und Taster sind gemultiplext. Das funktioniert auch sehr gut. Weiterhin sind ein Platz für ein 29C040 Flash oder ein 128/512K SRAM sowie ein Platz für ein 27x64-512 Eprom / 28C256 EEprom auf der Platine. Das einblenden dieser Chips in einen bestimmten Speicherbereich vom Atari funktioniert auch problemlos. (Lesen und Schreiben) Nun hatte ich zeitweise über 200 Warnungen von Quartus bekommen, nach etlichen lesen im Forum bin ich dahintergekommen, daß es immer besser sei, bei steigender/fallender Flanke als bei "clk = '1'" den Block laufen zu lassen. das ganze Listing überarbeitet und siehe da, die ganzen bösen Latches waren weg. Es kommen noch viele Warnmeldungen, da einige Pins noch keine Funktion haben. Wo ich aber am meisten Probleme habe, ist das schreiben auf Speicherzellen, die vom FPGA verwaltet werden. Lesen geht 1a und fehlerfrei! Liegt es evt. an der Schreibweise? Was wäre richtig oder falsch bei folgenden Beispiel: if data_out_enable or adr >= x"D380" and adr <= x"D3FF" then if (data_out_enable) or ((adr >= x"D380") and (adr <= x"D3FF")) then if (data_out_enable = true) or ((adr >= x"D380") and (adr <= x"D3FF")) then gibt es hier Unterschiede, ob = true oder nicht da steht und obs in Klammer ist? hier noch eine Routine, die mir Kopfzerbrechen macht... Schreibwerte werden "manchmal!", meist aber garnicht verarbeitet! ------------------------------------------------------------------------ -- $D3F0 REGISTER-WRITE-ENABLE Byte übernehmen -- (nur bei #$55 werden Schreibzugriffe auf die DebugAdr-Register erlaubt) ------------------------------------------------------------------------ decode_d3f0: process(phi2short, rw, adr, data, run_ok, trigger_we) begin if falling_edge(phi2short) and (run_ok) then if (adr = x"D3F0") then if (rw = '0') then trigger_we <= data; else if (data = x"55") then dp(12) <= '1'; enable_trgset <= true; else dp(12) <= '0'; enable_trgset <= false; end if; end if; end if; end if; end process decode_d3f0; ---------------------------------------------------------------------- wobei phi2short der etwas verkürzte PHI2 Systemtakt des Ataris ist (1.77Mhz), run_ok ist ein signal, welches 2sekunden nach dem einschalten auf true geht. Dieser Timer ist nötig, da der Atari beim Powerup erst alle Adressen überschreibt. beim schreiben in D3F0 wird das Byte am Datenbus in trigger_we kopiert (hoffe ich) und beim lesen auf hex55 verglichen, wenn es 55 sein sollte, sollen die Triggeradressen beschreibbar sein (enable_trgset=true). Sollte es der Wert 55 sein, wird ein Dezimalpunkt (dp12) zur Kontrolle eingeschaltet. Warum DIESES nur selten funktioniert, ist mir ein Rätsel! Habe ich hier irgendwo einen Denkfehler ? Gruß, Wolfram.
mega-hz schrieb: > Hallo, > > dies ist mein erstes Projekt mit einem FPGA. > ....... > > Gruß, > Wolfram. Oh sorry, habe gerade gesehen, daß ich nicht eingeloggt war... Nu aber. Gibt es eigentlich einen Unterschied ob ich schreibe, trigger_we <= data; oder trigger_we(7 downto 0) <= data(7 downto 0); wenn beide 8 Bit breit sind? Gruß, Wolfram.
:
Bearbeitet durch User
trigger_we <= data; oder trigger_we(7 downto 0) <= data(7 downto 0); beides macht das gleiche hier.
Du bist noch etwas zu sehr C verhaftet ;) Für die Bedingung im IF braucht es keine Klammern. Dagegen aber sehr wohl für verbundene OR/ANDs, da AND im Gegensatz zu C nicht stärker als OR bindet. Allerdings sollte der Synthesizer dann auch Fehlermeldungen bringen. Du hast aber generell ein Problem mit dem Alter deines "Opfers". Damals war voll synchrones Design (alles flankengesteuert) aus Sparsamkeit selten und es hat alles munter mit fallenden, steigenden und phasenverschobenen/unsymmetrischen Takten kreuz und quer rumgewerkelt. Zudem war das Zeug schweinelahm, sodass Unsauberkeiten in der Signalführung (Ringing) oder leichte Setup/Hold-Verletzungen nicht so aufgefallen sind. Heutige Chips sind da grob 50-100mal schneller und können da Unsinn produzieren. Du solltest die Signale am FPGA mal mit einem Oszi anschauen und wirklich überprüfen, ob deine zeitlichen Annahmen mit den qualifizierenden Flanken und Steuersignalen dazu wirklich stimmen. Gefährlich sind auch Unterschwinger bei fallenden Flanken, weil die schnell wieder in den 1-Bereich reinschiessen. Wenn es mit Osziprobe besser wird, ist das ein typisches Zeichen dafür, selbst wenn man es auf dem Oszi nicht erkennen kann.
ich habe das ganze schon auf global_slow_slew_rate eingestellt, damit es nicht so steile flanken gibt, ein muss i.V. mit so einem alten Atari. Ich versteh nicht ganz, was an den Chips langsam sein soll wenn man bedenkt, daß die schnellsten signale nur 1.77Mhz sind (CLK) alles andere ist nochmal die hälfte... der Cylone1 ist zwar älter aber für diese Zwecke doch völlig ausreichend. (Denke ich so) Ich muss dazusagen, daß es bereits viel besser schon lief, aber irgendwas habe ich wohl geändert, was das schreiben fast nicht mehr zulässt. Ich finds einfach nicht...
:
Bearbeitet durch User
> damit es nicht so steile flanken gibt, Und selbst die werden noch viel steiler sein, als das Original. > was an den Chips langsam sein soll wenn man bedenkt, daß die > schnellsten signale nur 1.77Mhz sind (CLK) Mit alt meinte ich die Chips aus der Atari-Zeit. Wenn da ein Signal mal für 5ns durch Ringing kurz High wurde, ist das meist untergegangen... > was das schreiben fast nicht mehr zulässt. Fast nicht mehr klingt nach Timing/Signalintegritätsproblemen.
Ha, ich hab das Problem gelöst: Irgendwo hatte ich ja gelesen, man sollte Prozesse am Besten bei steigender/fallender Flanke des Taktes laufen lassen... Im Fall meines Bustreiber-Prozesses darf das aber nicht nur bei steigender Flanke passieren, sondern immer wenn der Takt HI ist! Allerdings gab es immer viele böse Latchesn wenn ich das so shrieb: if (phi2 = '1') then .... also hab ich if rising_edge(phi2) then geschrieben. Die Folge war, daß zwar keine Latches erzeugt wurden aber die Bustreiber waren nur sehr kurz "an". Nun habe ich herausgefunden (Danke HIAS), das die Latches erzeugt wurden, weil ich nicht alle Signale gesetzt hatte... Hier mal der alte falsche Code und dann der richtige: ---------------------------------------------------------------------- set_bustreiber: process(dout, dout_enable, ram_rom_access, phi2, rw) begin adress_en <= '0'; adress_dir <= '0'; if rising_edge(phi2) then if (rw = '1') then if (ram_rom_access = true) then data_en <= '1'; else if (dout_enable) then data_dir <= '1'; data_en <= '0'; data <= dout; else data_dir <= '0'; data_en <= '0'; data <= (others => '1'); end if; end if; end if; end if; end process set_bustreiber; --------------------------------------------------------------- der neue Code: ------------------------------------------------------------------------ set_bustreiber: process(data_out, data_out_enable, ram_rom_access, phi2, rw) begin data_dir <= '0'; data_en <= '0'; data <= (others => 'Z'); adress_en <= '0'; adress_dir <= '0'; if (phi2 = '1') then adress_en <= '0'; adress_dir <= '0'; if (rw = '1') then if (ram_rom_access = true) then data_en <= '1'; else if (data_out_enable) then data_dir <= '1'; data_en <= '0'; data <= data_out; end if; end if; end if; end if; end process set_bustreiber; ------------------------------------------------------------------------ - So,nun funktioniert es prima! @Georg: Ja, die Signale auf dem Atari haben uns jahrelang Nerven gekostet! Wenn man sich den Systemtakt anschaut, denkt man, ein 3jähriger hätte versucht, ne Sinuskurve zu malen :-) Irgendwann haben wir auch rausgefunden, daß nicht nur bedingt durch die schlechte Form des Taktes sondern auch durch eigentlich zu lange Hi-Zeit des Taktes oft Schreibprobleme (mit selbst entwickelter HW und moderneren Chips) gab. Nach einfügen eines 74LS123 wird dieser Takt nun etwas verkürtzt und gleichzeitig in Rechteck Form gebracht. Das die Ataris selber so gut und stabil laufen, kann man eigentlich nicht verstehen. Aber NMOS war was feines...
:
Bearbeitet durch User
Hallo, Da ich ein paar alte Projekt-Leichen zuende bringen möchte, muss ich diesen alten Text mal wieder hervorholen... Die oben beschriebene Platine mit dem FPGA läuft bis heute nicht so gewünscht. Das Hauptproblem ist folgendes: es soll bei Zugriff auf eine (irgendeine vorher definierte) Adresse -lesend,schreibend oder beides- diese ausgeblendet werden und "eigener" Inhalt eingeblendet werden, z.B. von einem Eprom. Das merkwürdige ist: in einem Speicherbereich von D300-D3FF welcher von einem GAL des ATARIs für eine 6520 PIA ausdekodiert ist (diese belegt D300-D303) funktioniert das einblenden eigener Inhalte, in dem Testfall ein Text der vom FPGA dort eingeblendet wird. Möchte ich nun aber einen 8 oder 16KB großen Block in einem anderen Bereich einblenden, hängt sich der ATARI auf. Aber nicht nur bei solchen größeren Speicherblöcken: Auch bei einer einzigen Adresse z.B. im 2000er Bereich funktioniert dies nicht. Dann steht dort nur FF und nicht der Wert der eingeblendet werden soll. Dies ist noch das einzige Problem, wäre das gelöst könnte man die Platine als super Debug/Entwicklungshilfe benutzen. Vielleicht kann ja mal jemand über das VHDL Listing schauen? (Manchmal programmiert man ja blind um den Fehler herum, wieder und wieder...)
Wolfram F. schrieb: > Vielleicht kann ja mal jemand über das VHDL Listing schauen? Wurde der Code schon mal mit einem VHDL-Simulator geprüft? Wolfram F. schrieb: > use IEEE.STD_LOGIC_ARITH.ALL; > use IEEE.NUMERIC_STD.ALL; Aua. Sowas schreit nach Fehlern durch unsachgemäß verwendete Datentypen: Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"
Sowas ist auch ungünstig:
1 | test : process(clk50, phi2, phi2short, option_test_quarz, option_test_schalter) |
2 | begin
|
3 | if falling_edge(clk50) then -- ok, der quarzoszillator funktioniert! |
4 | if (option_test_quarz = true) then |
5 | -- ...
|
6 | end if; |
7 | if falling_edge(phi2) then |
8 | if (option_test_schalter = true) then |
9 | -- ...
|
10 | end if; |
11 | end if; |
12 | end process test; |
1. Gehört in die Sensitivity list nur der Takt (und ein evtl. vorhandener asynchroner Reset) und nicht der ganze andere Kladderadatsch. 2. In einem Prozess auf zwei unterschiedliche Taktsignale zu reagieren stellt u.U. den Synthesizer auf eine harte Probe.
Rick D. schrieb: > Wolfram F. schrieb: >> Vielleicht kann ja mal jemand über das VHDL Listing schauen? > Wurde der Code schon mal mit einem VHDL-Simulator geprüft? Nein, müsste ich dann nicht auch den kompletten Atari simulieren? > Wolfram F. schrieb: >> use IEEE.STD_LOGIC_ARITH.ALL; >> use IEEE.NUMERIC_STD.ALL; Der Code sowie auch Quartus 11 stammen ja aus der Vergangenheit, warum sollte das nun nicht ok sein? Sowas ist auch ungünstig: test : process(clk50, phi2, phi2short, option_test_quarz, option_test_schalter) begin if falling_edge(clk50) then -- ok, der quarzoszillator funktioniert! if (option_test_quarz = true) then -- ... end if; if falling_edge(phi2) then if (option_test_schalter = true) then -- ... end if; end if; end process test; 1. Gehört in die Sensitivity list nur der Takt (und ein evtl. vorhandener asynchroner Reset) und nicht der ganze andere Kladderadatsch. 2. In einem Prozess auf zwei unterschiedliche Taktsignale zu reagieren stellt u.U. den Synthesizer auf eine harte Probe. Dies ist eigentlich nur eine Testroutine um während der Entwicklung eine Art Lebenszeichen anzuzeigen, daher der name test. Ich glaube nicht, daß sich dieser Codeabschnitt auf das eigentliche Problem deutet.
ich bekomme etliche Warnungen vom Quartus-Compiler, vielleicht kann man da etwas finden?
1 | Warning: Skipped module PowerPlay Power Analyzer due to the assignment FLOW_ENABLE_POWER_ANALYZER |
2 | Warning: Skipped module PowerPlay Power Analyzer due to the assignment FLOW_ENABLE_POWER_ANALYZER |
3 | Warning: Parallel compilation is not licensed and has been disabled |
4 | Warning (10540): VHDL Signal Declaration warning at ATARI_PBI_FPGA.vhd(83): used explicit default value for signal "IRQ" because signal was never assigned a value |
5 | Warning (10540): VHDL Signal Declaration warning at ATARI_PBI_FPGA.vhd(158): used explicit default value for signal "space" because signal was never assigned a value |
6 | Warning (10540): VHDL Signal Declaration warning at ATARI_PBI_FPGA.vhd(171): used explicit default value for signal "led11" because signal was never assigned a value |
7 | Warning (10540): VHDL Signal Declaration warning at ATARI_PBI_FPGA.vhd(172): used explicit default value for signal "led12" because signal was never assigned a value |
8 | Warning (10036): Verilog HDL or VHDL warning at ATARI_PBI_FPGA.vhd(192): object "portb" assigned a value but never read |
9 | Warning (10540): VHDL Signal Declaration warning at ATARI_PBI_FPGA.vhd(199): used explicit default value for signal "option_test_quarz" because signal was never assigned a value |
10 | Warning (10540): VHDL Signal Declaration warning at ATARI_PBI_FPGA.vhd(200): used explicit default value for signal "option_test_schalter" because signal was never assigned a value |
11 | Warning (10540): VHDL Signal Declaration warning at ATARI_PBI_FPGA.vhd(201): used explicit default value for signal "option_display" because signal was never assigned a value |
12 | Warning (10631): VHDL Process Statement warning at ATARI_PBI_FPGA.vhd(571): inferring latch(es) for signal or variable "option_flash_ram", which holds its previous value in one or more paths through the process |
13 | Warning (10492): VHDL Process Statement warning at ATARI_PBI_FPGA.vhd(722): signal "adr" is read inside the Process Statement but isn't in the Process Statement's sensitivity list |
14 | Warning (10492): VHDL Process Statement warning at ATARI_PBI_FPGA.vhd(722): signal "run_ok" is read inside the Process Statement but isn't in the Process Statement's sensitivity list |
15 | Warning: The following nodes have both tri-state and non-tri-state drivers |
16 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[0]" and its non-tri-state driver. |
17 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[1]" and its non-tri-state driver. |
18 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[2]" and its non-tri-state driver. |
19 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[3]" and its non-tri-state driver. |
20 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[4]" and its non-tri-state driver. |
21 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[5]" and its non-tri-state driver. |
22 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[6]" and its non-tri-state driver. |
23 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[7]" and its non-tri-state driver. |
24 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[8]" and its non-tri-state driver. |
25 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[9]" and its non-tri-state driver. |
26 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[10]" and its non-tri-state driver. |
27 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[11]" and its non-tri-state driver. |
28 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[12]" and its non-tri-state driver. |
29 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[13]" and its non-tri-state driver. |
30 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[14]" and its non-tri-state driver. |
31 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[15]" and its non-tri-state driver. |
32 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[16]" and its non-tri-state driver. |
33 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[17]" and its non-tri-state driver. |
34 | Warning: Inserted always-enabled tri-state buffer between "ram_rom_adr[18]" and its non-tri-state driver. |
35 | Warning: Inserted always-enabled tri-state buffer between "gpio[0]" and its non-tri-state driver. |
36 | Warning: Inserted always-enabled tri-state buffer between "gpio[1]" and its non-tri-state driver. |
37 | Warning: Inserted always-enabled tri-state buffer between "gpio[2]" and its non-tri-state driver. |
38 | Warning: Inserted always-enabled tri-state buffer between "gpio[3]" and its non-tri-state driver. |
39 | Warning: Inserted always-enabled tri-state buffer between "gpio[4]" and its non-tri-state driver. |
40 | Warning: Inserted always-enabled tri-state buffer between "gpio[5]" and its non-tri-state driver. |
41 | Warning: Inserted always-enabled tri-state buffer between "gpio[6]" and its non-tri-state driver. |
42 | Warning: Inserted always-enabled tri-state buffer between "gpio[7]" and its non-tri-state driver. |
43 | Warning: Inserted always-enabled tri-state buffer between "gpio[8]" and its non-tri-state driver. |
44 | Warning: Inserted always-enabled tri-state buffer between "gpio[9]" and its non-tri-state driver. |
45 | Warning: Inserted always-enabled tri-state buffer between "gpio[10]" and its non-tri-state driver. |
46 | Warning: Inserted always-enabled tri-state buffer between "gpio[11]" and its non-tri-state driver. |
47 | Warning: Inserted always-enabled tri-state buffer between "gpio[12]" and its non-tri-state driver. |
48 | Warning: Inserted always-enabled tri-state buffer between "gpio[13]" and its non-tri-state driver. |
49 | Warning: TRI or OPNDRN buffers permanently enabled |
50 | Warning: Node "ram_rom_adr[0]~synth" |
51 | Warning: Node "ram_rom_adr[1]~synth" |
52 | Warning: Node "ram_rom_adr[2]~synth" |
53 | Warning: Node "ram_rom_adr[3]~synth" |
54 | Warning: Node "ram_rom_adr[4]~synth" |
55 | Warning: Node "ram_rom_adr[5]~synth" |
56 | Warning: Node "ram_rom_adr[6]~synth" |
57 | Warning: Node "ram_rom_adr[7]~synth" |
58 | Warning: Node "ram_rom_adr[8]~synth" |
59 | Warning: Node "ram_rom_adr[9]~synth" |
60 | Warning: Node "ram_rom_adr[10]~synth" |
61 | Warning: Node "ram_rom_adr[11]~synth" |
62 | Warning: Node "ram_rom_adr[12]~synth" |
63 | Warning: Node "ram_rom_adr[13]~synth" |
64 | Warning: Node "ram_rom_adr[14]~synth" |
65 | Warning: Node "ram_rom_adr[15]~synth" |
66 | Warning: Node "ram_rom_adr[16]~synth" |
67 | Warning: Node "ram_rom_adr[17]~synth" |
68 | Warning: Node "ram_rom_adr[18]~synth" |
69 | Warning: Node "gpio[0]~synth" |
70 | Warning: Node "gpio[1]~synth" |
71 | Warning: Node "gpio[2]~synth" |
72 | Warning: Node "gpio[3]~synth" |
73 | Warning: Node "gpio[4]~synth" |
74 | Warning: Node "gpio[5]~synth" |
75 | Warning: Node "gpio[6]~synth" |
76 | Warning: Node "gpio[7]~synth" |
77 | Warning: Node "gpio[8]~synth" |
78 | Warning: Node "gpio[9]~synth" |
79 | Warning: Node "gpio[10]~synth" |
80 | Warning: Node "gpio[11]~synth" |
81 | Warning: Node "gpio[12]~synth" |
82 | Warning: Node "gpio[13]~synth" |
83 | Warning: Output pins are stuck at VCC or GND |
84 | Warning (13410): Pin "adress_en" is stuck at GND |
85 | Warning (13410): Pin "adress_dir" is stuck at GND |
86 | Warning (13410): Pin "ram1_ce" is stuck at VCC |
87 | Warning (13410): Pin "IRQ" is stuck at GND |
88 | Warning: Design contains 1 input pin(s) that do not drive logic |
89 | Warning (15610): No output dependent on input pin "rdy" |
das manche Pins auf VCC oder GND oder nicht benutzt sind, ist z.Z. richtig.
Wolfram F. schrieb: > Nein, müsste ich dann nicht auch den kompletten Atari simulieren? Jain. Ich simuliere immer nur soweit, das ich sehen kann, ob etwas funktioniert. Das muß nicht die komplette CPU oder Peripherie sein. Wenn ich ein Modul habe, was an einem Bus hängt, dann simuliere ich eben die Buszugriffe auf mein Modul. Falls die CPU als VHDL vorliegt, kann es auch einfacher sein, sich kleine Testprogramme in Assembler zu schreiben und die CPU gleich mit zu simulieren. >> Wolfram F. schrieb: >>> use IEEE.STD_LOGIC_ARITH.ALL; >>> use IEEE.NUMERIC_STD.ALL; > Der Code sowie auch Quartus 11 stammen ja aus der Vergangenheit, > warum sollte das nun nicht ok sein? Weil std_logic_arith und numeric_std an einigen Stellen nicht kompatibel zueinander sind. Hier kannst du auf beide Bibliotheken verzichten, weil gar nicht gerechnet wird. Und falls es doch was zu rechnen gibt, nimm die numeric_std (und nur die, keine arith _irgendwas), die ist in sich konsistent. > Dies ist eigentlich nur eine Testroutine um während der Entwicklung > eine Art Lebenszeichen anzuzeigen, daher der name test. Ja, mag sein, aber nur weil es eine Testroutine ist, sollte man nicht in schlechten Stil verfallen. Das färbt sonst ab. > Ich glaube nicht, daß sich dieser Codeabschnitt auf das eigentliche > Problem deutet. Richtig. Anbei eine rudimentäre Testbench, die nur ein paar Takte zur Verfügung stellt. Da müßten jetzt noch die zu verifizierenden Zugriffe drin abgebildet werden...
Wolfram F. schrieb: > ich bekomme etliche Warnungen vom Quartus-Compiler, Brauchbarer sind Warnungen von einem Simulator. Ich habe noch kein umfangreicheres Projekt gehabt, was ohne Warnungen durch einen Synthesizer gegangen ist. Wenn man seinen Code dann anpasst, poppen nur andere Warnungen auf... > Warning: Skipped module PowerPlay > Power Analyzer due to the assignment FLOW_ENABLE_POWER_ANALYZER > Warning: Skipped module PowerPlay Power Analyzer due to the assignment > FLOW_ENABLE_POWER_ANALYZER Eine Leistungsanalyse wird gebraucht, wenn die Stromversorgung optimiert werden muß. Hier m.E. nicht relevant. > Warning: Parallel compilation is not licensed and has been disabled Unwichtig, im Hobby hat man Zeit. > Warning (10540): VHDL Signal Declaration warning at > ATARI_PBI_FPGA.vhd(83): used explicit default value for signal "IRQ" > because signal was never assigned a value Die Default-Zuweisung an den Signalausgängen würde ich wegmachen. Verschiebe das besser in den Codeteil:
1 | signal ... |
2 | begin
|
3 | -- defaults
|
4 | trigger <= '0'; |
5 | IRQ <= '0'; |
6 | refresh <= '0'; |
7 | -- hier gehts weiter
|
8 | ...
|
> Warning (10036): Verilog HDL or VHDL warning at ATARI_PBI_FPGA.vhd(192): > object "portb" assigned a value but never read Dem sollte man nachgehen. Üblicherweise werden alle Signale gebraucht. BTW: Kannst du evtl. den Code vom PIA bereitstellen? Dann könnte man den gleich mit simulieren. > Warning (10540): VHDL Signal Declaration warning at > ATARI_PBI_FPGA.vhd(199): used explicit default value for signal > "option_test_quarz" because signal was never assigned a value > "option_test_schalter" because signal was never assigned a value > "option_display" because signal was never assigned a value > "option_flash_ram", which holds its previous value in one or more paths Hier würde ich das Signal ggf. in eine Konstante oder einen Generic umwandeln. Die Schalter werden ja nicht zur Laufzeit angepasst. > ATARI_PBI_FPGA.vhd(722): signal "adr" is read inside the Process > Statement but isn't in the Process Statement's sensitivity list Sowas ist ernstzunehmen, da hier Simulation und FPGA unterschiedlich reagieren. > Warning: The following nodes have both tri-state and non-tri-state > drivers Das klingt wild, ich überblicke es aber gerade nicht. Möglicherweise liegt es daran, das option_flash_ram ein Signal ist.
Hallo, hier die PIA vhdl:
1 | ----------------------------------------------------------------------------------
|
2 | -- PIA.vhd - 6520 PIA PORTB emulation logic |
3 | ----------------------------------------------------------------------------------
|
4 | |
5 | library IEEE; |
6 | use IEEE.STD_LOGIC_1164.ALL; |
7 | use IEEE.STD_LOGIC_ARITH.ALL; |
8 | use IEEE.NUMERIC_STD.ALL; |
9 | |
10 | library work; |
11 | use work.all; |
12 | |
13 | entity PIA is |
14 | Port ( |
15 | clk_register: in std_logic; |
16 | adr: in std_logic_vector(15 downto 0); |
17 | data_in: in std_logic_vector(7 downto 0); |
18 | rw: in std_logic; |
19 | reset_n_in: in std_logic; |
20 | portb: out std_logic_vector(7 downto 0) |
21 | );
|
22 | end PIA; |
23 | |
24 | architecture RTL of PIA is |
25 | |
26 | signal pia_crb2: std_logic; |
27 | signal pia_ddrb: std_logic_vector(7 downto 0); |
28 | signal pia_portb: std_logic_vector(7 downto 0); |
29 | |
30 | begin
|
31 | |
32 | -----------------------------------------------------------------------------
|
33 | -- PIA Emulation |
34 | -----------------------------------------------------------------------------
|
35 | emulate_pia: process(adr, clk_register, data_in, rw, reset_n_in, pia_portb, pia_ddrb) |
36 | begin
|
37 | if falling_edge(clk_register) then |
38 | if (reset_n_in = '0') then |
39 | pia_crb2 <= '0'; |
40 | pia_ddrb <= (others => '0'); |
41 | pia_portb <= (others => '0'); |
42 | else
|
43 | if (rw = '0') then |
44 | case adr is |
45 | when x"D301" => |
46 | if (pia_crb2 = '0') then |
47 | pia_ddrb <= data_in; |
48 | else
|
49 | pia_portb <= data_in; |
50 | end if; |
51 | when x"D303" => |
52 | pia_crb2 <= data_in(2); |
53 | when others => null; |
54 | end case; |
55 | end if; |
56 | end if; |
57 | end if; |
58 | -- simulate pull-ups on inputs (ddrb is set to 0) |
59 | portb <= pia_portb OR (NOT pia_ddrb); |
60 | |
61 | end process emulate_pia; |
62 | -----------------------------------------------------------------------------
|
63 | |
64 | |
65 | end RTL; |
Habe heute mal die beiden Zeilen
1 | >>> use IEEE.STD_LOGIC_ARITH.ALL; |
2 | >>> use IEEE.NUMERIC_STD.ALL; |
Im Haupt-VHDL und in PIA VHDL auskommentiert, hast Recht, wird garnicht gebraucht und läuft genauso.
Irgendwas passiert da im Adressbreich um 0xD3xx herum, aber ob es das ist, was dir vorschwebt, weiß ich nicht...
Rick D. schrieb: > Irgendwas passiert da im Adressbreich um 0xD3xx herum, aber ob es das > ist, was dir vorschwebt, weiß ich nicht... Ja, das ist richtig: Die PIA sitzt mit ihren 4 Aressen in D300-D303, der Bereich von D304-D3FF ist im Atari unbenutz, dort blende ich Register für Debug-Adresse und einiges mehr ein, auch zum Test einen kleinen Teil eines Eproms und Srams sowie etwas Text. Siehe Anfang vom Listing. Das merkwürdige ist, in diesem D3XX Bereich funktioniert das alles prima, wenn ich aber versuche z.B. ein anderes Betriebssystem-ROM in C000-FFFF oder ein Modul-ROM in A000-BFFF einzublenden, stürzt der Atari ab. Selbst, wenn ich nur in einer bestimmte Adresse z.B. 2000 bei Zugriff einen bestimmten Wert einblende, ist dieser nicht da. Dazu muss ich noch erwähnen: Es gibt im Atari eine Leitung die Refresh heisst. Wenn diese Leitung auf LOW gezogen wird, wird RAM und ROM (je nach Adressbereich) ausgeblendet. Genau das wird im D303-D3FF Bereich gemacht: Bei Zugriff REF setzen, damit ist der Speicherbereich "frei", dann "meine" Werte dort einblenden. Der Adressbereich des Ataris ist folgendermaßen aufgebaut: 0000-7FFF RAM 8000-9FFF RAM oder Steckmodul-ROM A000-BFFF RAM oder Steckmodul oder BASIC-ROM C000-CFFF RAM oder Betriebssystem-ROM D000-D7FF Hardware-Register D800-DFFF RAM oder Paralellbus E000-FFFF RAM oder Betriebssystem-ROM Ist diese Simulation in Quartus integriert? Gruß, Wolfram.
Wolfram F. schrieb: > Ist diese Simulation in Quartus integriert? Ich habe Modelsim verwendet. Das gab es m.E. früher auch mal bei Quartus/Altera bzw. ISE/Xilinx mit der Einschränkung für kleine Designs dazu. Xilinx ist später auf das eigene ISIM umgeschwenkt. Prinzipiell sollte jeder VHDL-Simulator funktionieren. Mit ghdl und gtkwave gibt es auch eine open source-Lösung.
Habe den Fehler gefunden! Die Leitung des ATARIs um Speicher auszublenden muss auf LOW gezogen werden. Da ich ursprünglich dafür einen Transistor geplant hatte es aber verworfen habe, war noch die Invertierung des FPGA Ausgangs drin. Habe nun den Status des Pins auf "Z" gemacht und die aktivierung auf "0" anstatt "1". Keine Abstürze mehr, zugriff auf alle Adressen! WAS für ein blöder Fehler! All die Jahre hätte der schon sinnvolle Dinge tun können... Danke für jegliche Tips! Gruß, Wolfram.
Danke für die Rückmeldung. Solche 'Kleinigkeiten' mit großer Auswirkung sind mir auch schon passiert :-( Hauptsache: Man lernt dazu...
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.