Hallo,
ich habe nun zum ersten mal auf einem selber gebauten Board einen FPGA
und uC miteinander verbunden via 8 Bit breiten Daten- und Adressbus.
Und soweit funktioniert alles perfekt!
Nun habe ich aber ein paar fragen.
Grundsätzlich: der uC führt das interne CPU-Taktsignal nach aussen, und
dieses ist mit dem FPGA verbunden. Alle Signale vom uC sind zu diesem
Taktsignal synchron, weshalb ich mir dachte, dass ich die
Einsynchronisierung der einzelnen Signale sparen kann (was ich hier im
Forum gelesen habe - anscheinend ist das zulässig).
So, ich habe im FPGA nun verschiedene "Register", auf die der uC
zugreifen kann, wo bestimmte Daten gelesen oder geschrieben werden.
Mit folgendem Code wird dies realisiert:
1 | signal q : std_logic_vector(7 downto 0);
|
2 | signal register1 : std_logic_vector(7 downto 0);
|
3 | signal register2 : std_logic_vector(7 downto 0);
|
4 |
|
5 | process begin --write
|
6 | wait until falling_edge(clk);
|
7 | if ce = '0' and oe = '1' and we = '0' then
|
8 | if adressbus = 0 then
|
9 | register1 <= datenbus;
|
10 | elsif adressbus = 1 then
|
11 | register2 <= datenbus;
|
12 | end if;
|
13 | end if;
|
14 | end process;
|
15 |
|
16 | process begin --read
|
17 | wait until falling_edge(clk);
|
18 | if ce = '0' and oe = '0' and we = '1' then
|
19 | if adressbus = 0 then
|
20 | q <= register1;
|
21 | elsif adressbus = 1 then
|
22 | q <= register2;
|
23 | else
|
24 | q <= (others => '0');
|
25 | end if;
|
26 | end if;
|
27 | end process;
|
28 |
|
29 | datenbus <= q when ce = '0' and oe = '0' and we = '1' else (others => 'Z');
|
so könnte man das beliebig weiter stricken und für jedes Register eine
if-Abfrage machen. Das gefällt mir aber nicht so recht; geht das auch
irgendwie eleganter?
dann, die nächste Frage. Ich habe in einem Register die Bits INTEN,
SWINT, IRQF, SRST und TST. Jedes der Bits ist in Wirklichkeit natürlich
ein Signal im FPGA, womit sich dann irgendwelche Dinge ein-, aus- oder
umschalten lassen. Was ist besser:
1 | process begin --write
|
2 | wait until falling_edge(clk);
|
3 | if ce = '0' and oe = '1' and we = '0' then
|
4 | if adressbus = 3 then
|
5 | INTEN <= datenbus(0);
|
6 | SWINT <= datenbus(1);
|
7 | IRQF <= datenbus(2);
|
8 | SRST <= datenbus(3);
|
9 | TST <= datenbus(4);
|
10 | end if;
|
11 | end if;
|
12 | end process;
|
13 |
|
14 | process begin --read
|
15 | wait until falling_edge(clk);
|
16 | if ce = '0' and oe = '0' and we = '1' then
|
17 | if adressbus = 3 then
|
18 | q <= "000" & TST & SRST & IRQF & SWINT & INTEN;
|
19 | else
|
20 | q <= (others => '0');
|
21 | end if;
|
22 | end if;
|
23 | end process;
|
oder das:
1 | process begin --write
|
2 | wait until falling_edge(clk);
|
3 | if ce = '0' and oe = '1' and we = '0' then
|
4 | if adressbus = 3 then
|
5 | testregister <= datenbus;
|
6 | end if;
|
7 | end if;
|
8 | end process;
|
9 |
|
10 | process begin --read
|
11 | wait until falling_edge(clk);
|
12 | if ce = '0' and oe = '0' and we = '1' then
|
13 | if adressbus = 3 then
|
14 | q <= testregister;
|
15 | else
|
16 | q <= (others => '0');
|
17 | end if;
|
18 | end if;
|
19 | end process;
|
20 |
|
21 | INTEN <= testregister(0);
|
22 | SWINT <= testregister(1);
|
23 | IRQF <= testregister(2);
|
24 | SRST <= testregister(3);
|
25 | TST <= testregister(4);
|
Funktionieren tut, gemäss meinen Experimenten, beides. Aber ich bin
sicher, wenn es funktioniert, muss es noch nicht unbedingt gut sein :-)
Ich bin gespannt auf eure Posts.