Erster ernster Versuch- kann mal jemand drüberschauen?

#1134242
Lesenswert?

Hallo!
Das ist mein erster, ernster Versuch mit VHDL ;)

Ich habe versucht den TWI- Prescaler der Mega AVRs (48/88/168- bestimmt 
auch viele andere) nachzubauen.

Ich finde, dass das schon mal ganz toll aussieht, aber ist es das auch?
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4

5
entity i2c_ce_gen is
6
    Port ( CLK_I : in  STD_LOGIC;
7
           RST_I : in STD_LOGIC;
8
           CE_I : in  STD_LOGIC;
9
           TWPS_I : in  STD_LOGIC_VECTOR (1 downto 0);
10
           TWBR_I : in  STD_LOGIC_VECTOR (7 downto 0);
11
           CE_O : out  STD_LOGIC);
12
end i2c_ce_gen;
13

14
architecture Behavioral of i2c_ce_gen is
15

16
signal prescale : integer range 0 to 32767;
17
signal prescale_cmp : integer range 0 to 32767;
18
signal sub_prescale : integer range 1 to 64;
19
signal twbr_temp : integer range 0 to 255;
20

21
begin
22

23
process (CLK_I)
24
begin
25
  --[CLKSYNC] sync process
26
  if rising_edge(CLK_I) then
27
    --[RESET]sync reset
28
    if RST_I = '1' then
29
      CE_O <= '0';
30
      prescale <= 0;
31
      prescale_cmp <= 0;
32
      sub_prescale <= 1;
33
    else
34
      --avr style prescaler selection
35
      case TWPS_I is
36
        when "00" => sub_prescale <= 1;
37
        when "01" => sub_prescale <= 4;
38
        when "10" => sub_prescale <= 16;
39
        when "11" => sub_prescale <= 64;
40
        when others => null;
41
      end case;
42
      --avr style prescale count register
43
      twbr_temp <= to_integer( unsigned(TWBR_I));
44
      --calculation of compare value (avr style)
45
      prescale_cmp <= 15 + 2 * twbr_temp * sub_prescale;
46
      
47
      --[CE] to cascade prescalers
48
      if CE_I = '1' then
49
        prescale <= prescale + 1;
50
        --[COMP] comparator
51
        if prescale = prescale_cmp then
52
          CE_O <= '1';
53
          prescale <= 0;
54
        else
55
          CE_O <= '0';
56
        end if; --/[COMP]
57
      end if; --/[CE]
58
    end if; --/[RESET]
59
  end if; --/[CLKSYNC]
60
end process;
61
end Behavioral;
#1134406
Lesenswert?

Ich würde sagen, da gibts erstmal nichts zu meckern.
Du solltest aber bei der Synthese mal nachschauen, was hieraus gemacht 
wird:
> prescale_cmp <= 15 + 2  twbr_temp  sub_prescale;
Da sub_prescale ja nur Zweierpotenzen als Wert annehmen kann, braucht es 
hier ja keinen Multiplizierer - ich weiß nur nicht, ob das 
Synthese-Programm das auch erkennt. Falls nicht, kannst du den Code 
etwas umstellen um ihm auf die Sprünge zu helfen.
#1134475
Lesenswert?

Jan M. wrote:

>> prescale_cmp <= 15 + 2  twbr_temp  sub_prescale;
> Da sub_prescale ja nur Zweierpotenzen als Wert annehmen kann, braucht es
> hier ja keinen Multiplizierer - ich weiß nur nicht, ob das
> Synthese-Programm das auch erkennt. Falls nicht, kannst du den Code
> etwas umstellen um ihm auf die Sprünge zu helfen.

Ok, da habe ich noch nicht dran gedacht.
Wie wird denn ein "left shift" synthetisiert (Mux, Schieberegister oder 
ganz anders)?

> Für den ersten Versuch sieht es echt gut aus.

Erster ernster Versuch ;)
Davor gab es auch schon so manchen Müll :)

> Hast Du auch eine
> Testbench dazu, um den Block funktional verifizieren zu können?

Bin ich gerade dran, die ersten Versuche sehen schon brauchbar aus.

Danke,
Heiko.
#1134661
Lesenswert?

Heiko Lechner wrote:
> Jan M. wrote:
>
>>> prescale_cmp <= 15 + 2  twbr_temp  sub_prescale;
>> Da sub_prescale ja nur Zweierpotenzen als Wert annehmen kann, braucht es
>> hier ja keinen Multiplizierer - ich weiß nur nicht, ob das
>> Synthese-Programm das auch erkennt. Falls nicht, kannst du den Code
>> etwas umstellen um ihm auf die Sprünge zu helfen.
>
> Ok, da habe ich noch nicht dran gedacht.
> Wie wird denn ein "left shift" synthetisiert (Mux, Schieberegister oder
> ganz anders)?

Es muss nichts wirklich geschoben werden, nur die richtigen Bits 
ausgewaehlt - es gibt also einen 4-zu-1-mux, der je nach Prescaler 
entweder Bit0, 2,4 oder 6 von twbr_temp auf Bit0 von prescale_cmp legt 
(zuzueglich Addition natuerlich).
#1135591
Lesenswert?

Jan M. wrote:

> Es muss nichts wirklich geschoben werden, nur die richtigen Bits
> ausgewaehlt - es gibt also einen 4-zu-1-mux, der je nach Prescaler
> entweder Bit0, 2,4 oder 6 von twbr_temp auf Bit0 von prescale_cmp legt
> (zuzueglich Addition natuerlich).

Es wird tatsächlich ein Multiplizierer generiert.

Ich habe es nun geändert zu:
1
--avr style prescaler selection
2
case TWPS_I is
3
  when "00" => sub_prescale <= 0; -- x<<0 == x*1
4
  when "01" => sub_prescale <= 2; -- x<<2 == x*4
5
  when "10" => sub_prescale <= 4; -- x<<4 == x*16
6
  when "11" => sub_prescale <= 6; -- x<<6 == x*64
7
  when others => null;
8
end case;  
9
--avr style prescale count register
10
twbr_temp <= to_integer( unsigned(TWBR_I));
11
--calculation of compare value (avr style)
12
prescale_cmp <= 15 + to_integer(to_unsigned(twbr_temp,8) sll (sub_prescale+1));

Allerdings ist die "Multiplizierer- Variante" bis auf den Multiplizierer 
ressourcensparender.
Moderator (Firma: Titel) Persönliche Seite #1135595
Lesenswert?

Das:
1
--avr style prescaler selection
2
case TWPS_I is
3
  when "00" => sub_prescale <= 0; -- x<<0 == x*1
4
  when "01" => sub_prescale <= 2; -- x<<2 == x*4
5
  when "10" => sub_prescale <= 4; -- x<<4 == x*16
6
  when "11" => sub_prescale <= 6; -- x<<6 == x*64
7
  when others => null;
8
end case;

ginge aber auch so:
1
  sub_prescale <=  to_integer(unsigned(TWPS_I & '0'));
Gast #1136048
Lesenswert?

@Heiko:
> Kann die case Anweisung denn zu weniger "optimierten" Synthetisierungen
> führen (etwas übersichtlicher finde ich es schon)?

Ja, kann. Die Wege der Synthesetools sind manchmal unergründlich :-(
Ich würde nur auf Platz optimieren, wenn es triftige Gründe gibt. Sicher 
muß man die Ressourcen nicht verschwenden, aber bei 
Entwicklungsprojekten, wo es nicht auf Masse oder Platz, sondern auf 
Zeit ankommt, hat man einfach keine Zeit ewig rumzuoptimieren.

Lieber lesebarer hinschreiben, da hat man später (manchmal) mehr davon.

Duke

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren