Hallo zusammen,
ich habe einen I2S-Transmitter, den ich mit einem AXI-Stream Interface
ausstatten möchte. Der Transmitter alleine lässt sich ohne Probleme
synthetisieren und funktioniert im FPGA wunderbar. Mit dem AXI-Stream
Interface kombiniert ergeben sich aber Timing Violations beim Worst
Negative Slack und beim Total Negativ Slack. Jetzt habe ich gelesen,
dass es u. U. daran liegen könnte, dass ich die Signale nicht ordentlich
einsynchronisiert habe. Daher habe ich mir mal die Erklärung vom Lothar
Miller angeschaut
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren
und versucht die Synchronisation für das Reset-Signal (für den Anfang)
meines Transmitters umzusetzen:
1 | entity AXIS_I2S is
|
2 | Generic ( WIDTH : INTEGER := 16
|
3 | );
|
4 | Port ( aclk : in STD_LOGIC;
|
5 | aresetn : in STD_LOGIC;
|
6 |
|
7 | -- AXI-Stream interface
|
8 | TDATA_RXD : in STD_LOGIC_VECTOR(31 downto 0);
|
9 | TREADY_RXD : out STD_LOGIC;
|
10 | TVALID_RXD : in STD_LOGIC;
|
11 |
|
12 | -- I2S interface
|
13 | MCLK : in STD_LOGIC;
|
14 | LRCLK : out STD_LOGIC;
|
15 | SCLK : out STD_LOGIC;
|
16 | SD : out STD_LOGIC
|
17 | );
|
18 | end AXIS_I2S;
|
19 |
|
20 | architecture AXIS_I2S_Arch of AXIS_I2S is
|
21 |
|
22 | type AXIS_State_t is (State_Reset, State_WaitForTransmitterReady, WaitForValid, WaitForBusy);
|
23 |
|
24 | signal CurrentState : AXIS_State_t := State_Reset;
|
25 |
|
26 | signal FIFO : STD_LOGIC_VECTOR(((2 * WIDTH) - 1) downto 0) := (others => '0');
|
27 |
|
28 | signal TransmitterValid : STD_LOGIC;
|
29 | signal TransmitterReady : STD_LOGIC;
|
30 | signal TransmitterResetN: STD_LOGIC_VECTOR(1 downto 0);
|
31 |
|
32 | component I2S_Transmitter is
|
33 | Generic ( WIDTH : INTEGER := 16
|
34 | );
|
35 | Port ( MCLK : in STD_LOGIC;
|
36 | ResetN : in STD_LOGIC;
|
37 | Ready : out STD_LOGIC;
|
38 | Valid : in STD_LOGIC;
|
39 | Data : in STD_LOGIC_VECTOR(((2 * WIDTH) - 1) downto 0);
|
40 | LRCLK : out STD_LOGIC;
|
41 | SCLK : out STD_LOGIC;
|
42 | SD : out STD_LOGIC
|
43 | );
|
44 | end component;
|
45 |
|
46 | begin
|
47 |
|
48 | Transmitter : I2S_Transmitter generic map( WIDTH => WIDTH
|
49 | )
|
50 | port map( MCLK => MCLK,
|
51 | ResetN => TransmitterResetN(1),
|
52 | Valid => TransmitterValid,
|
53 | Ready => TransmitterReady,
|
54 | Data => x"FF00FF00",
|
55 | LRCLK => LRCLK,
|
56 | SCLK => SCLK,
|
57 | SD => SD
|
58 | );
|
59 |
|
60 | -- Synchronize reset
|
61 | process(MCLK)
|
62 | begin
|
63 | if(rising_edge(MCLK)) then
|
64 | TransmitterResetN(0) <= aresetn;
|
65 | TransmitterResetN(1) <= TransmitterResetN(0);
|
66 | end if;
|
67 | end process;
|
68 |
|
69 | process(aclk)
|
70 | begin
|
71 | if(rising_edge(aclk)) then
|
72 | if(aresetn = '0') then
|
73 | CurrentState <= State_Reset;
|
74 | else
|
75 | case CurrentState is
|
76 | when State_Reset =>
|
77 | FIFO <= (others => '0');
|
78 | --TransmitterValid <= '0';
|
79 |
|
80 | CurrentState <= State_WaitForTransmitterReady;
|
81 |
|
82 | when State_WaitForTransmitterReady =>
|
83 | --TransmitterValid <= '0';
|
84 |
|
85 | --if(TransmitterReady = '1') then
|
86 | CurrentState <= WaitForValid;
|
87 | --else
|
88 | -- CurrentState <= State_WaitForTransmitterReady;
|
89 | --end if;
|
90 |
|
91 | when WaitForValid =>
|
92 | TREADY_RXD <= '1';
|
93 |
|
94 | if(TVALID_RXD = '1') then
|
95 | FIFO <= TDATA_RXD;
|
96 | CurrentState <= WaitForBusy;
|
97 | else
|
98 | CurrentState <= WaitForValid;
|
99 | end if;
|
100 |
|
101 | when WaitForBusy =>
|
102 | --TransmitterValid <= '1';
|
103 | TREADY_RXD <= '0';
|
104 |
|
105 | --if(TransmitterReady = '0') then
|
106 | CurrentState <= State_WaitForTransmitterReady;
|
107 | --else
|
108 | -- CurrentState <= WaitForBusy;
|
109 | --end if;
|
110 |
|
111 | end case;
|
112 | end if;
|
113 | end if;
|
114 | end process;
|
115 | end AXIS_I2S_Arch;
|
Das aktuelle Design ergibt einen WNS and TNS von -5,7 ns, sprich es wird
auch nicht funktionieren. Wo habe ich da den Denkfehler drin, bzw. muss
ich es ganz anders machen?
PS: Ja, ich weiß das man verschiedene Clock-Domainen meiden sollte, bzw.
es nicht ganz trivial ist (siehe mein Beispiel). Das Problem hier ist
allerdings, dass der AXI Bus des Systems leider auf einer komplett
anderen Frequenz läuft und das sich das mit dem I2S beißt (100 MHz AXI,
12,288 MHz I2S). Daher bleibt mir leider nichts anderes übrig.
Danke für ein paar Denkanstöße :)