Gast
#733544
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