Hallo Leute, ich nochmal. Ich möchte mein Audio-Projekt in einen Spartan3 400 Tq144 reinquetschen. Ich bekomme es nur hin wenn ich alle optimierungen (area) an habe und große teile des designs weg lasse. Das problem ist die MAC-Einheit. Hier mal der Code : --------------------------------------------- -- -- Data Muxers (Input and Coefficient) -- --------------------------------------------- -- -- Muxer for MAC-Input A (Audio-Data) and AMEM-Write-Data -- process (clk, res, sdc_a_data_src, input, sdc_b_rdata, sdc_mac_out) begin if res = '1' then sdc_a_wdata <= (others => '0'); elsif clk'event and clk = '1' then case sdc_a_data_src is when "00" => sdc_a_wdata <= std_logic_vector (input); when "01" => sdc_a_wdata <= sdc_b_rdata; when "10" => sdc_a_wdata <= std_logic_vector (sdc_mac_val_32); when "11" => sdc_a_wdata <= (others => '0'); when others => sdc_a_wdata <= (others => '0'); end case; end if; end process; -- -- Muxer for Output of SDSP Core (MAC-Output or BMEM) -- process (clk, res, sdc_output_src) begin if res = '1' then sdc_toutput <= (others => '0'); elsif clk'event and clk = '1' then case sdc_output_src is when "00" => sdc_toutput <= sdc_mac_out; when "01" => sdc_toutput <= signed (sdc_b_rdata); when others => NULL; end case; end if; end process; -- -- Coeff-Muxer (can be CMEM, 1.0, 0.0, -1.0 ) -- process (clk, res, sdc_c_rdata, sdc_coeff_routing, sdc_ena_coeff_reg) begin if res = '1' then sdc_mac_coeff <= X"00000000"; elsif clk'event and clk = '1' then if sdc_ena_coeff_reg = '1' then case sdc_coeff_routing is when "00" => sdc_mac_coeff <= signed (sdc_c_rdata); when "01" => sdc_mac_coeff <= X"01000000"; when "10" => sdc_mac_coeff <= X"00000000"; when "11" => sdc_mac_coeff <= X"FFFFFFFF"; when others => NULL; end case; end if; end if; end process; --------------------------------------------- -- -- MAC-Unit -- --------------------------------------------- -- -- MAC-Unit itself -- process (clk, res, sdc_ena_macres, sdc_ena_mac, sdc_mac_val) begin if res = '1' then sdc_mac_val <= (others => '0'); elsif clk'event and clk = '1' then -- Reset Accumulator if sdc_ena_macres = '1' then sdc_mac_val <= (others => '0'); sdc_mac_val_tmp <= (others => '0'); end if; -- Enable Operation if sdc_ena_mac = '1' then sdc_mac_val_tmp <= ( signed (sdc_a_wdata) * signed (sdc_mac_coeff) ); -- sdc_mac_val <= sdc_mac_val + ( signed (sdc_a_wdata) * signed (sdc_mac_coeff) ); end if; -- Enable Acuumulate if sdc_ena_mac_add = '1' then sdc_mac_val <= sdc_mac_val + sdc_mac_val_tmp; end if; end if; end process; -- -- Hard-Clipping of 64-Bit Result of MAC-Accumulator -- -- Clipping is done on the bits 55..24 (we have 8 bit headroom at multiply) -- process (clk, res, sdc_mac_val) begin if res = '1' then -- sdc_mac_val_32 <= (others => '0'); elsif clk'event and clk = '1' then -- dependend on sign if sdc_mac_val (63) = '1' then -- check only the 9 highest bits of relevant data if std_logic_vector (sdc_mac_val (63 downto 55)) = "111111111" then -- in range sdc_mac_val_32 <= sdc_mac_val (55 downto 24); else -- out of range sdc_mac_val_32 <= X"80000000"; end if; else -- check only the 9 highest bits of relevant data if std_logic_vector (sdc_mac_val (63 downto 55)) = "000000000" then -- in range sdc_mac_val_32 <= sdc_mac_val (55 downto 24); else -- out of range sdc_mac_val_32 <= X"7fffffff"; end if; end if; end if; end process; -- process (clk, res, sdc_mac_val) -- begin -- if res = '1' then -- sdc_mac_val_32 <= (others => '0'); -- elsif clk'event and clk = '1' then -- sdc_mac_val_32 <= sdc_mac_val (55 downto 24) when (std_logic_vector (sdc_mac_val (63 downto 55)) = "111111111") else -- sdc_mac_val (55 downto 24) when (std_logic_vector (sdc_mac_val (63 downto 55)) = "000000000") else -- X"80000000" when sdc_mac_val (63) = '1' else -- X"7fffffff"; -- end if; -- end process; -- -- Hard-Clipping of 32-Bit Result to 24 Bit Result (for I2S-Output is 24 Bit Wide, may add an Enable signal to give mre control over clipping) -- process (clk, res, sdc_mac_val_32) begin if res = '1' then sdc_mac_out <= (others => '0'); elsif clk'event and clk = '1' then -- dependend on sign if sdc_mac_val_32 (31) = '1' then -- check only the 9 highest bits of relevant data if std_logic_vector (sdc_mac_val_32 (31 downto 23)) = "111111111" then -- in range sdc_mac_out <= sdc_mac_val_32; else -- out of range sdc_mac_out <= X"ff800000"; end if; else -- check only the 9 highest bits of relevant data if std_logic_vector (sdc_mac_val_32 (31 downto 23)) = "000000000" then -- in range sdc_mac_out <= sdc_mac_val_32; else -- out of range sdc_mac_out <= X"007fffff"; end if; end if; end if; end process; Das ist das Herzstück meines DAPs. Und genau im Multiplizierer (+Addierer) liegt das Problem. Je nachdem welche Teile ich weglasse (oder auch nicht) lässt sich das Projekt synthetisieren (oder eben auch nicht). Wenn es nicht geht meldet mir ISE "Congestion on subnet ...." Also Verstopfung mangels interconnects. Welche Möglichkeiten habe ich außer einem Core-Generator zu bemühen ? Ich möchte das ganze design nicht unbedingt neumachen müssen, und das Hauptproblem ist die MAC-Einheit. Wie kann man den Multiplizierer verbessern (Pipelining ?) ? Im Moment bekomme ich noch keine Simulation mit dem ISE hin (bin zu doof dafür) um Vergleichen zu können. Wäre schön wenn mir jemand helfen könnte. Das Implementierungs Problem habe ich nur auf dem S3-400 auf dem S3-1000 nicht (anscheinend genug platz) ... Gruß Rene
Hallo, wozu brauchst Du enable Signale für Multiplikation und Addition? Lass sie doch immer machen, was sie sollen. Du weist dann genau, wie lange sie dauern, von daher sollte es doch kein Problem sein... Damit hättest Du schon mal die Enable-Signale eingespart. Als nächstes würde ich reset-Path rausnehmen -- das sind auch Muxer (es kann zwar verschieden implementiert sein, aber da sparst Du Logic Cells). Den synchronen Reset würde ich überarbeiten, so wie es da steht ist einfach unüblich (denke ich) -- Reset Accumulator if sdc_ena_macres = '1' then sdc_mac_val <= (others => '0'); sdc_mac_val_tmp <= (others => '0'); end if; -- Enable Operation if sdc_ena_mac = '1' then sdc_mac_val_tmp <= ( signed (sdc_a_wdata) *signed(sdc_mac_coeff)); end if; Was passiert, wenn sdc_ena_carres='1' und sdc_ena_mac='1' ist? Ist einfach unsauber und dann musst Du halt wissen, welche Zuweisung als letzte steht -- würde ich so nicht machen. Und noch eine "Anregung": wenn Du nur mit audio arbeitest, glaube ich nicht, dass Du sowas "Großes" brauchst, vielleicht tut es auch was serielles? Die Multiplikation in Hardware ist zwar schön und gut, ist aber räumlich sehr eingeschränkt (z.B. nur nah an BlockRams). Dann ist es auch klar, dass es irgendwann mal zu Routing-problemen kommen kann. Machs gut, Kest
hallo kest,
erstmal danke für die antwort und die tipps.
>vielleicht tut es auch was serielles?
an sowas dachte ich auch schon, aber ... wie macht man sowas genau ?
gruß
rene
ich nochmal ... habe noch etwas gebaut und gebastelt und bin dabei (durch hinweise von kest) auf die idee gekommen u.a. das 2 fache hardclipping durch ein einfaches zu ersetzen, das ganze als kombinatorische logik um mir somit in dem kritischen pfad etwas luft zu machen. außerdem habe ich die info (multiplizierer liegen nahe blockrams) verwurstet und im gesamten design den lese-daten bus für die blockrams eingespart. plus noch ein paar anderere kleinere optimierungen und "weglassen". es hatte erfolg ... ich kann (fast) das komplette ursprüngliche design jetzt sogar in einen spartan3 200 unterbringen und es läuft. freu freu :-) jetzt werd ich mich an den synth machen :-)) nun meine zwei erkenntnisse : dadurch das das design trotz routingprobleme selbst auf einem kleineren fpga lauffähig ist denke ich, das ich "nur" die mac-einheit tauschen muß (und den micro-code anpassen muß) und schon dürfte das routing-problem umgangen sein. außerdem dürfte (im falle eines seriellen multiplizierers) die effektive geschwindigkeit des designs steigen (die 4 multiplizierer ziehen durch das routing die mögliche meximalgeschwindigkeit des systems runter). bei erweiterung des designs (und verwendung eines 400'er spartans) dürfte/müsste/sollte es weniger implementierungsprobleme durch "enstpannteres routing" geben. sehe ich die o.g. punkte richtig ? (von dem bischen was man zu den infos sagen kann)) dank nochmal an kest. gruß rene
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.