Hallo,
ich will gerne einen FPGA mit dem Datenbus eines Mikrocontrollers
verbinden.
Ich habe nun also 10 Adressleitungen sowie 8 Datenleitungen mit dem FPGA
verbunden, ausserdem noch WE, OE und CE.
Nun sollen in dem FPGA mehrere "Register" erstellt werden, wo ich was
speichern kann, und der Inhalt dieser Register beeinflusst dann
bestimmte Vorgänge im FPGA (z.B. macht der FPGA eine 12 Phasen PWM, und
über ein entsprechendes 16 Bit breites Register soll der Tastgrad davon
eingestellt werden können).
Jetzt habe ich dazu mehrere Fragen.
Erstmal: wie mache ich das Interface zum Datenbus, dass es auch sicher
funktioniert?
Ich habe folgendes:
1 | entity test is
|
2 | port(
|
3 | clk : in std_ulogic;
|
4 | d : inout std_logic_vector(7 downto 0);
|
5 | a : in std_logic_vector(9 downto 0);
|
6 | we : in std_logic;
|
7 | oe : in std_logic;
|
8 | ce : in std_logic
|
9 | );
|
10 | end project;
|
11 |
|
12 | architecture behv of test is
|
13 | signal dat : std_logic_vector(7 downto 0);
|
14 | begin
|
15 | process begin
|
16 | wait until rising_edge(CLK);
|
17 | if ce = '0' then
|
18 | if oe = '0' then
|
19 | d <= dat;
|
20 | end if;
|
21 | if we = '0' then
|
22 | dat <= d;
|
23 | end if;
|
24 | else
|
25 | d <= (others => 'Z');
|
26 | end if;
|
27 | end process;
|
28 | end architecture;
|
das soll mal als erster Test dienen, ob ich ein einzelnes Byte im FPGA
speichern und wieder raus lesen kann. Wird es so funktionieren?
Des Weiteren soll natürlich jetzt Abhängig von der angelegten Adresse
der Wert in unterschiedlichen Registern abgelegt werden. Das hier
1 | entity test is
|
2 | port(
|
3 | clk : in std_ulogic;
|
4 | d : inout std_logic_vector(7 downto 0);
|
5 | a : in std_logic_vector(9 downto 0);
|
6 | we : in std_logic;
|
7 | oe : in std_logic;
|
8 | ce : in std_logic
|
9 | );
|
10 | end project;
|
11 |
|
12 | architecture behv of test is
|
13 | signal r0 : std_logic_vector(7 downto 0);
|
14 | signal r1 : std_logic_vector(7 downto 0);
|
15 | signal r2 : std_logic_vector(7 downto 0);
|
16 | begin
|
17 | process begin
|
18 | wait until rising_edge(CLK);
|
19 | if ce = '0' then
|
20 | if oe = '0' then
|
21 | case to_integer(unsigned(a)) is
|
22 | when 0 =>
|
23 | d <= r0;
|
24 | when 1 =>
|
25 | d <= r1;
|
26 | when 2 =>
|
27 | d <= r2;
|
28 | when others =>
|
29 | null;
|
30 | end case;
|
31 | end if;
|
32 | if we = '0' then
|
33 | case to_integer(unsigned(a)) is
|
34 | when 0 =>
|
35 | r0 <= d;
|
36 | when 1 =>
|
37 | r1 <= d;
|
38 | when 2 =>
|
39 | r2 <= d;
|
40 | when others =>
|
41 | null;
|
42 | end case;
|
43 | end if;
|
44 | else
|
45 | d <= (others => 'Z');
|
46 | end if;
|
47 | end process;
|
48 | end architecture;
|
funktioniert vielleicht, aber ist sehr unelegant. Gibt es dafür eine
einfachere Schreibweise?
Noch was:
Der Mikrocontroller, der das ganze steuern soll, ist ein LPC2378. Es
kann durchaus auch vorkommen, dass ein Register mehr als 8 Bits breit
ist; z.B. eben bei der PWM - der Tastgrad wird über 16 Bits eingestellt.
Ich kann wohl im Programm des Mikrocontrollers einen 16 Bit
Speicherzugriff realisieren; doch wie schaut dies dann aus Sicht des
FPGAs aus? Wie muss ich mit den Registern hantieren, um am Schluss den
korrekten 16 Bit Wert zu erhalten?
Ich hoffe, ihr könnt mir ein paar Tipps geben. Bin gespannt :)