Forum: FPGA, VHDL & Co. shift reg + akkumulator, optimierungen möglich?


von ben (Gast)


Lesenswert?

Hi,

ich bin VHDL Anfänger, für ein Projekt benötige ich folgende Schaltung:

Ein 12 Bit Wort wird seriell in ein Shift Register geladen und liegt 
dann paralell hinter einem (asynchronen?) Register an.
Dieses 12 Bit Wort wird dann synchron zu einem Takt auf ein 16 Bit Wort 
auf addiert und das MSB ausgegeben. Den Akkumulator gibt es zwei mal mit 
gleichem input aber verschiedenen Takteingängen.

Leider passt das ganze nur knapp nicht in einen XC9572XL, deshalb meine 
Frage: Kan man da evtl. noch was optimieren?  Ist das ok, so wie ich die 
Flanken erkenne, oder hat das evtl. Nachteile?
Danke


12 Bit Serial in, Paralell out Shift Register with latch:
1
entity shift is
2
  port(C, CS, SI : in  std_logic;
3
        PO : out std_logic_vector(11 downto 0)
4
      );
5
end shift;
6
architecture archi of shift is
7
  signal tmp: std_logic_vector(11 downto 0);
8
  
9
  begin
10
    process (C, CS)
11
      begin
12
        if (C'event and C='1') then
13
          for i in 0 to 10 loop
14
            tmp(i+1) <= tmp(i);
15
          end loop;
16
          tmp(0) <= SI;
17
       
18
        end if;
19
      
20
      if (CS'event and CS='1') then
21
      PO <= tmp;
22
      end if;
23
    end process;
24
     
25
end archi;

16 Bit Accumulator with 12 bit paralell input:
1
entity accum is
2
    Port ( IN_BUS : in  STD_LOGIC_VECTOR (11 downto 0);
3
           CLK : in  STD_LOGIC;
4
           OUT_CLK : out  STD_LOGIC);
5
end accum;
6
7
architecture Behavioral of accum is
8
  signal tmp: STD_LOGIC_VECTOR (15 downto 0);
9
begin
10
11
    process (CLK)
12
      begin
13
      if(CLK='1' and CLK'event) then 
14
        tmp <= tmp + IN_BUS;
15
      end if;
16
    end process;
17
    
18
    OUT_CLK <= tmp(15);
19
    
20
end Behavioral;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

ben schrieb:
> Ist das ok, so wie ich die Flanken erkenne, oder hat das evtl. Nachteile?
Welche Flanken meinst du?

Das hier hat Nachteile:
(CLK='1' and CLK'event)
Denn du beachtest (in der Simulation) leider nicht den Zustand, der vor 
der Flanke da war. Wenn das ein schwaches 'H' war, dann reicht das dir 
schon für eine Flanke. Ein Flipflop erkennt aber keine Flanke bei diesem 
Wechsel. Kurz und gut: warum nimmst du nicht die Funktionen 
rising_edge() und falling_edge()?

Zu deinem Code:
1
    process (C, CS)
2
      begin
3
        if (C'event and C='1') then
4
          for i in 0 to 10 loop
5
            tmp(i+1) <= tmp(i);
6
          end loop;
7
          tmp(0) <= SI;
8
       
9
        end if;
10
      
11
      if (CS'event and CS='1') then
12
      PO <= tmp;
13
      end if;
14
    end process;
Schreib das besser in 2 Prozesse und sieh dir mal mein Schieberegister 
an:
1
    process (C) begin
2
       if (C'event and C='1') then
3
          tmp <= tmp(10 downto 0) & SI;
4
       end if;
5
   end process;
6
      
7
   process (CS) begin
8
      if (CS'event and CS='1') then
9
         PO <= tmp;
10
      end if;
11
   end process;
Extreme Hacker würden das sogar so schreiben:
1
   tmp <= tmp(10 downto 0) & SI when rising_edge(C);
2
   PO <= tmp  when rising_edge(CS);
Aber leider hilft dir das vermutlich nicht sehr beim Platz sparen.

ben schrieb:
> Leider passt das ganze nur knapp nicht in einen XC9572XL
Was fehlt denn? Wo klemmts?
Flipflops sollten eigetnlich ausreichend da sein...
Zeig doch mal dein ganzes Design.

von ben (Gast)


Angehängte Dateien:

Lesenswert?

hi vielen dank erstmal.

ich habe deinen vorschlag mit den getrennten prozessen umgesetzt.
Das Design benötigt nach wie vor 78 Macrocells, der XC9572XL hat aber 
nur 72. Der nächst größere ist XC95144XL, den gibts aber nur als TQ100 
(VQ44 währe schon schöner)

Im Anhang das vollständige Design...

Das ganze muss übrigens nur bis 3Mhz laufen...

Danke :-)

von ben (Gast)


Lesenswert?

hi, wollte nochmal fragen, ob noch jemand eine idee hat..

habe die xilinx application notes durchgewälzt, aber nichts gefunden...

danke

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wofür werden denn die ganzen Makrozellen verbraucht?
Die paar FFs reichen dafür allein noch nicht aus...

Implementier mal nur den Addierer und dann nur das Schieberegister, dann 
kommt da evtl. ein wenig Licht ins Dunkel.

von ben (Gast)


Lesenswert?

Also gerade mal Schieberegister und Akkumulator einzeln implementiert:

Shift: 24 Macrocells
Akkumulator: jeweils 27 Macrocells

 24+2*27 = 78

kommt also genau hin

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Kannst du dir erlauben, eine Registerstufe im Schieberegister zu sparen?
1
architecture archi of shift is
2
  signal tmp: std_logic_vector(11 downto 0);
3
  
4
  begin
5
    process (C)
6
    begin
7
      if (C'event and C='1') then
8
        tmp <= tmp(10 downto 0) & SI;
9
      end if;
10
    end process;
11
    
12
--  process (CS)
13
--  begin
14
--    if (CS'event and CS='1') then
15
        PO <= tmp;
16
--    end if;
17
--  end process;
18
     
19
end archi;
Hier sind dann allerdings während des Schiebevorgangs die Daten im PO 
korrupt.

von Der Besucher (Gast)


Lesenswert?

Lothar Miller schrieb:
> Kannst du dir erlauben, eine Registerstufe im Schieberegister zu 
sparen?architecture archi of shift is
>   signal tmp: std_logic_vector(11 downto 0);
>
>   begin
>     process (C)
>     begin
>       if (C'event and C='1') then
>         tmp <= tmp(10 downto 0) & SI;
>       end if;
>     end process;
>
> --  process (CS)
> --  begin
> --    if (CS'event and CS='1') then
>         PO <= tmp;
> --    end if;
> --  end process;
>
> end archi;
> Hier sind dann allerdings während des Schiebevorgangs die Daten im PO
> korrupt.

Hallo,

meiner Meinung nach sind auch bei der ürsprünglichen Übernahme von 
tmp-Register ins PO-Register die Daten genauso "korrupt" wie im 
tmp-Register selbst. Deswegen kann man auch gleich, wie du hier 
vorgeschlagen hast, das tmp-Register verwenden. Das Problem mit dem 
Clock-Skew hat man eben auch, wenn man das Register nochmal und nochmal 
und nochmal speichert. Also ist deine vorgeschlagene Lösung ohne 
"qualitaetseinbussen". Ausser, der Takt Verzögerung wird für irgendetwas 
benötigt, was ich mir aber kaum vorstellen kann.
Ich würde tmp gleich durch PO ersetzen.

Wichtiger ist glaube folgendes: Wurde SI einsynchronisiert? (habe jetzt 
nicht ins komplette Design geschaut)

Der Besucher

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Der Besucher schrieb:
> Wichtiger ist glaube folgendes: Wurde SI einsynchronisiert?
SI muss nicht einsynchronisiert werden, wenn es (wie z.B. beim SPI 
üblich) zum Takt synchron ist...

Mit meiner Änderung und der Fitter-Option -exhaust (Exhaustive Fit Mode) 
passt das Design dann in den 9572XL:
1
Design alles has been optimized and fit into device XC9572XL-5-PC44.

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.