Forum: FPGA, VHDL & Co. ZYBO Zynq-7000 Development Board - erste Schritte


von Elminjo A. (elminjo)


Angehängte Dateien:

Lesenswert?

Hallo,

meine ersten Schritte auf einem FPGA + Vivado.

Ziel des Projektes ist ein Roboterarm in der Art: 
http://letsmakerobots.com/robot/project/micro-servo-robot

Mein persönliches Ziel, VHDL-2008 verstehen.

Meine Bitte an die Profis sind vor allem Tips wie es besser geht. 
Codemäßig und Stilmäßig.

Ein PWM Signal habe ich schon mal generiert, das war nicht so schwer, 
als nächstes kam dann das auslesen eines ADCs mittels i2c (PmodAD2 - 4 
channel 12-bit A/D converter)

Den i2c habe ich hinbekommen, zumindest dass ich den ADC adressiere und 
der mir dann jeweils nach Acks die Kanäle nacheinander ausgibt.

ich habe vier LEDs auf dem Board da versuche ich im Moment die ersten 
4-Bits des 1.Kanals auf die LEDs zu legen um zu verstehen wie ich Daten 
grundsätzlich abgreife. Funktioniert leider nicht wirklich.

Als Bild füge ich mal den Stand der Dinge als Schematics ein und den 
Code als zip.
Zum programmieren nehme ich notepad++ das erleichtert mir die Arbeit 
finde ich.

Im Moment sind pwm und i2c noch in zwei Projekten getrennt.

Hier ist auch mal mein PWM signal
top_modul
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity pwm_top is
5
port ( 
6
       -- Inputs
7
       Clk_125MHz : in std_logic;
8
       btn_0 : in std_logic;      -- Steuerung PWM
9
       btn_1 : in std_logic;      -- Steuerung PWM
10
       
11
       -- Outputs
12
       led_0 : out std_logic;
13
       led_1 : out std_logic;
14
       je_0 : out std_logic        -- Ausgang zum Servo
15
     );
16
end pwm_top;
17
18
architecture Archi of pwm_top is
19
    signal Clk_75MHz, Clk_500kHz, Clk_12_288MHz, Clk_3_072MHz, Clk_250kHz, Clk_48kHz : std_logic;
20
21
begin
22
  ClockTree:    entity work.ClockTree   port map ( Clk_125MHz, Clk_75MHz, Clk_12_288MHz, Clk_3_072MHz, Clk_500kHz, Clk_250kHz, Clk_48kHz );
23
  pwm:          entity work.pwm  port map (btn_0, btn_1, led_0, led_1, Clk_48kHz, je_0); --generic map ( tastgrad => 50 ) 
24
end Archi;

pwm
1
library IEEE; use IEEE.STD_LOGIC_1164.ALL, IEEE.NUMERIC_STD.ALL;
2
library UNISIM; use UNISIM.VComponents.all;
3
4
entity pwm is
5
-- generic ( tastgrad : integer := 960);
6
7
port   (
8
    btn_0, btn_1 : in std_logic;
9
        led_0, led_1 : out std_logic;  
10
        Clk_48kHz : in std_logic;
11
        pwm : out std_logic
12
    );
13
       
14
end pwm;
15
16
architecture Archi of pwm is
17
    signal counter1 : unsigned(9 downto 0);
18
    signal tastgrad : integer := 48;
19
    signal tastgradnext : integer := 0;
20
    signal button : std_logic;
21
begin
22
23
tastgradnext <= tastgrad +10 when btn_0 else tastgrad-10;
24
button <= (btn_0 xor btn_1);
25
tastgrad <= tastgradnext when rising_edge(button);
26
27
    process begin
28
        wait until rising_edge(Clk_48kHz);  
29
        
30
        counter1 <= counter1 + 1;
31
       
32
        pwm <= '1' when 0 <= counter1 and counter1 < tastgrad else '0';
33
         
34
        if counter1 = 10d"960" then
35
           counter1 <= 10d"0";
36
         end if;
37
 
38
        
39
    end process;
40
41
end Archi;

von Antti L. (xilant)


Lesenswert?

tjah aber wo ist dann das Problem? Wenn keins dann kannst ja einfach 
ruhig weitermachen mit zynq?

von Elminjo A. (elminjo)


Lesenswert?

Das Problem ist dass die LEDs 0 und 2 nie leuchten und 1 und 3 nur 
flackern. Und das unabhängig vom Wert den der ADC liefert.

Code: i2c_out.vhd
1
library IEEE; use IEEE.STD_LOGIC_1164.ALL, IEEE.NUMERIC_STD.ALL;
2
library UNISIM; use UNISIM.VComponents.all;
3
4
entity i2c_out is
5
 Port   ( 
6
        Clk : in std_logic;
7
        SDA : out std_logic;
8
        SCL : out std_logic;
9
    bitCounter : out unsigned(4 downto 0);               -- 0 bis 18         0,1 = x    2,3 = CH,  4-18=Data
10
    CHcounter : out unsigned(1 downto 0)                -- 
11
12
        );
13
end i2c_out;
14
15
architecture Behavioral of i2c_out is
16
    type ROM is array (0 to 26) of std_logic_vector(7 downto 0);                                                 
17
18
-- i2c Rom: 
19
--        8E = Start
20
--        FF = Idle
21
--        06 = 0 oder Ack
22
--        F6 = 1
23
--        17 = Stop
24
signal UM_INIT : ROM := (   X"FF", X"FF", X"FF", X"FF", X"17", X"FF", X"FF", X"FF", X"8E",                         -- Initialisierung
25
                            X"06", X"F6", X"06", X"F6", X"06", X"06", X"06",        X"F6",      X"F6",                -- Adressierung     rom_id = 10 - 18
26
                            -- Adresse                                              -R          - Ack von ADC
27
                            X"F6", X"F6", X"F6", X"F6", X"F6", X"F6", X"F6",X"F6",       X"06",                -- ch 1           rom_id = 18 - 26  bits: 0-8
28
              --  x      x     0       1                                                                       rom_id = 20,21 CH_ID
29
                            -- Daten von ADC ChI   Bit 11-8                                 - Ack von Master                 rom_id = 22-26 D11-D9          bits: 9-17
30
                            others => X"00");
31
32
signal counterB : integer := 3;
33
signal counterR : integer := 0;
34
35
signal frameCounter : integer := 0;             -- 0 bis 1
36
37
begin
38
39
    
40
    process begin
41
        wait until rising_edge(Clk);
42
43
  
44
        if counterB = 3 then
45
            SCL <= UM_INIT(counterR)(counterB);
46
            SDA <= UM_INIT(counterR)(counterB+4);
47
            counterB <= 2;
48
49
        elsif counterB = 2 then
50
            SCL <= UM_INIT(counterR)(counterB);
51
            SDA <= UM_INIT(counterR)(counterB+4);
52
            counterB <= 1;
53
            
54
        elsif counterB = 1 then
55
            SCL <= UM_INIT(counterR)(counterB);
56
            SDA <= UM_INIT(counterR)(counterB+4);
57
            counterB <= 0;
58
59
        elsif counterB = 0 then
60
            SCL <= UM_INIT(counterR)(counterB);
61
            SDA <= UM_INIT(counterR)(counterB+4);
62
            
63
      
64
      
65
            if counterR /= 26 then                  -- wenn Counter kleiner 26 dann weiter
66
                counterB <= 3;
67
                counterR <= counterR + 1;
68
            else                                    
69
                if bitCounter /= 5d"18" then
70
          bitCounter <= bitCounter + 1;
71
                    counterB <= 3;
72
                    counterR <= 18;
73
                    if frameCounter = 0 then
74
                        frameCounter <= 1;
75
                    else
76
                        frameCounter <= 0;
77
                        if CHcounter /= 2d"3" then
78
                            CHcounter <= CHcounter + 2d"1";
79
                        else
80
                            CHcounter <= 2d"0";
81
                        end if;
82
                    end if;
83
        else
84
          bitCounter <= 5d"0";
85
        end if;
86
            end if;
87
        end if;
88
    end process;                         
89
end Behavioral;


Code: SDA_read.vhd
1
library IEEE; use IEEE.STD_LOGIC_1164.ALL, IEEE.NUMERIC_STD.ALL;
2
3
entity SDA_read is
4
    port   ( 
5
      SDA : in std_logic;
6
      SCL : in std_logic;
7
      bitCounter : in unsigned(4 downto 0);
8
            data : out std_logic_vector(11 downto 0)
9
      );
10
end SDA_read;
11
12
architecture Archi of SDA_read is
13
14
begin
15
  
16
  -- data_en <= '1' when (bitCounter > 3 and bitCounter < 8) or (bitCounter > 9 and bitCounter < 18);
17
  
18
19
  process begin
20
    wait until rising_edge(SCL);
21
        if bitCounter = 5d"4" then
22
            data(0) <= SDA;
23
        elsif bitCounter = 5d"5" then
24
          data(1) <= SDA;
25
        elsif bitCounter = 5d"6" then
26
          data(2) <= SDA;
27
        elsif bitCounter = 5d"7" then
28
          data(3) <= SDA;
29
        elsif bitCounter = 5d"10" then
30
          data(4) <= SDA;
31
        elsif bitCounter = 5d"11" then
32
          data(5) <= SDA;
33
        elsif bitCounter = 5d"12" then
34
          data(6) <= SDA;
35
        elsif bitCounter = 5d"13" then
36
          data(7) <= SDA;
37
        elsif bitCounter = 5d"14" then
38
          data(8) <= SDA;
39
        elsif bitCounter = 5d"15" then
40
          data(9) <= SDA;
41
        elsif bitCounter = 5d"16" then
42
          data(10) <= SDA;
43
        elsif bitCounter = 5d"17" then
44
          data(11) <= SDA;
45
               end if;
46
47
  end process;
48
end Archi;


Code: CH_read.vhd
1
library IEEE; use IEEE.STD_LOGIC_1164.ALL, IEEE.NUMERIC_STD.ALL;
2
3
entity CH_read is
4
-- später soll der Kanal übergeben werden
5
--    generic ( 
6
--      CH : unsigned(1 downto 0)
7
--            );
8
  port   (
9
      data : in std_logic_vector(11 downto 0);
10
      CHs : in unsigned(1 downto 0);
11
      SCL : in std_logic;
12
            dataout : out std_logic_vector(11 downto 0)
13
14
      );
15
end CH_read;
16
17
architecture Archi of CH_read is
18
19
begin
20
  
21
  process begin
22
     wait until rising_edge(SCL);
23
      if CHs = 2d"0" then
24
        dataout <= data;
25
      end if;
26
  end process;
27
end Archi;


Code: led_out.vhd
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity led_out is
5
Port   (
6
        data : in std_logic_vector(11 downto 0);
7
        led : out std_logic_vector(3 downto 0)
8
        );
9
end led_out;
10
11
architecture Behavioral of led_out is
12
13
begin
14
    led <= data(3 downto 0);
15
16
end Behavioral;

von Antti L. (xilant)


Lesenswert?

tjah warum machst du dir leben soo kompliziert ??

1) PS7 I2C auf EMIO
2) I2C als external bus
3) C code schreiben, prüfen das all OK

und DANACH weiter.

0 lines of VHDL nix zu prüfen nichts was nicht gehen kann.

nur C code..

von Elminjo A. (elminjo)


Lesenswert?

Und wie soll ich VHDL verstehen wenn ich alles in C schreibe?

Inzwischen geht alles so wie ich es mir vorstelle.

von Antti L. (xilant)


Lesenswert?

na für VHDL brauchst du ja aber kein ZYNQ :)

Am besten ist leider SIMULATION, da brauchst du überhaupt keine 
hardware. Ist aber langweilig, ich weiss. Aber für lernen ist simulation 
gut. muss nur gut verstehen was ist synthisierbar, was nicht.

von Burkhard K. (buks)


Lesenswert?

Du wirst nicht darum herumkommen, Deinen Entwurf zu simulieren und die 
Funktion der einzelnen Module zu verifizieren.

Ausserdem solltest Du Dich mit VHDL-Coding-Guidelines vertraut machen. 
Z.B. verwendest Du ein Konstrukt namens "positional association" in 
Deinen Port Mappings - eine wunderbare Möglichkeit sich ins eigene Bein 
zu schiessen (bei "named association" hilft Dir der Parser, fehlerhafte 
Mappings zu finden - bei positional tappst Du einfach im Dunkeln).

Dann fällt mir auf, dass Dein Code keine FSMs beschreibt.
[vhdl]wait until rising_edge(Clk_48kHz);[/vdhl]
mag synthetisierbar sein, aber bist Du sicher welche Schaltung die 
Synthese tatsächlich daraus macht.

Und du wirst die Arbeitsweise des ADCs verifizieren müssen:
 - liegt tatsächlich die vorgesehene SCL Frequenz an?
 - Wird ACK richtig erkannt?
 - Werden die Bits an die richtige Position im Datenvektor übertragen 
usw.
 - Welche Datenwerte erhälst Du für Vdd bzw. GND am ADC Eingang?

BTW: Du hast die LEDs mit den LSBs Deines Datenwortes verbunden, 
abhängig von der Wandlungsgeschwindigkeit dürfte das für das Flackern 
veranwortlich sein.

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.