Forum: FPGA, VHDL & Co. Altera CycloneI ATARI-FPGA


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von mega-hz (Gast)


Lesenswert?

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.

von Wolfram F. (mega-hz)


Lesenswert?

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
von user (Gast)


Lesenswert?

trigger_we <= data;
oder
  trigger_we(7 downto 0) <= data(7 downto 0);

beides macht das gleiche hier.

von Wolfram F. (mega-hz)


Lesenswert?

ok, danke!
Dann habe ich ja hier schonmal richtig gedacht.

von Georg A. (georga)


Lesenswert?

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.

von Wolfram F. (mega-hz)


Lesenswert?

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
von Georg A. (georga)


Lesenswert?

> 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.

von Wolfram F. (mega-hz)


Lesenswert?

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
von Wolfram F. (mega-hz)


Angehängte Dateien:

Lesenswert?

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...)

von Rick D. (rickdangerus)


Lesenswert?

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"

von Rick D. (rickdangerus)


Lesenswert?

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.

von Wolfram F. (mega-hz)


Lesenswert?

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.

von Wolfram F. (mega-hz)


Lesenswert?

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"

von Wolfram F. (mega-hz)


Lesenswert?

das manche Pins auf VCC oder GND oder nicht benutzt sind,
ist z.Z. richtig.

von Rick D. (rickdangerus)


Angehängte Dateien:

Lesenswert?

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...

von Rick D. (rickdangerus)


Lesenswert?

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.

von Wolfram F. (mega-hz)


Lesenswert?

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;

von Wolfram F. (mega-hz)


Lesenswert?

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.

von Rick D. (rickdangerus)


Angehängte Dateien:

Lesenswert?

Irgendwas passiert da im Adressbreich um 0xD3xx herum, aber ob es das 
ist, was dir vorschwebt, weiß ich nicht...

von Wolfram F. (mega-hz)


Lesenswert?

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.

von Rick D. (rickdangerus)


Lesenswert?

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.

von Wolfram F. (mega-hz)


Lesenswert?

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.

von Rick D. (rickdangerus)


Lesenswert?

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
Noch kein Account? Hier anmelden.