Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Licznik - post-route - pomóżcie znaleźć błąd

27 Sty 2009 14:27 1485 18
  • Poziom 12  
    Witam,

    Próbuje opisać układ realizujący następujące rzeczy:
    - zlicza impulsy clk do pewnej wartości i później od początku (np. od 0 do 100),
    - jeśli zliczy już wartość 100 na wyjściu jedynka przesuwana jest o jedną pozycję w lewo (count<=count(30 downto 0)&count(31);).

    Ciągle ma problem z tym, aby sygnał wyjściowy nie otrzymywał przypadkowych wartości. Z poprzednich postów wiem, że muszę sygnał wyjściowy zsynchronizować z clk.

    Oto mój opis:
    Code:

    architecture Behavioral of counter is

       signal counter            :    integer range 0 to 100 := 0;
       signal count_next         :    STD_LOGIC_VECTOR(31 downto 0)   :=   (0=>'1', others=>'0');
       signal count_reg          :    STD_LOGIC_VECTOR(31 downto 0);

    begin
       process (clk) is
       begin
          if (rising_edge(clk)) then
             if (counter=100) then
                counter<=0;
                count_next<=count_next(30 downto 0)&count_next(31);
             else
                counter<=counter+1;
             end if;
          end if;
       end process;
       
       process (clk) is
       begin
          if (rising_edge(clk)) then
             count_reg<=count_next;
          end if;
       end process;
       
       count<=count_reg;
       
    end Behavioral;


    Gdzie popełniam błąd (nadal na wyjściu count otrzymuje przypadkowe sygnały) ?

    Dziękuje za pomoc.
    Pozdrawiam
    Łukasz
  • Poziom 14  
    1.zapis
    Code:
    signal count_next         :    STD_LOGIC_VECTOR(31 downto 0)   :=   (0=>'1', others=>'0'); 
    
       

    jest zjadliwy podczas symulacji, lecz niesyntezowalny do rzeczywistego układu. wartość po reset'cie sprzętowym jest zazwyczaj zerowana. bezpiecznej jest zadać wartość początkowową wprowadzając globalny sygnał resetu.

    2. sygnał count_next nie wymaga już synchronizacji gdyż jest synchronizowany poprzez count_reg. mozesz go spokojnie wyrzucić na zewnątrz jak instrukcję współbieżną.

    3. zapis:
    Code:
    count_next<=count_next(30 downto 0)&count_next(31); 
    jest brzydki. lepiej pobrać dane o aktualnym stanie z sygnału count_reg.
  • Poziom 12  
    Dobrze zrozumiałem ?

    Code:
    architecture Behavioral of counter is
    

       signal counter            :    integer range 0 to 100 := 0;
       signal count_next         :    STD_LOGIC_VECTOR(31 downto 0);
       signal count_reg          :    STD_LOGIC_VECTOR(31 downto 0);

    begin
       process (reset,clk) is
       begin
          if (reset='1') then
             count_next<=(0=>'1',others=>'0');
          elsif (rising_edge(clk)) then
             if (counter=100) then
                counter<=0;
                count_next<=count_reg(30 downto 0)&count_reg(31);
             else
                counter<=counter+1;
             end if;
          end if;
       end process;
       
       count_reg<=count_next;
       
       count<=count_reg;
       
    end Behavioral;


    Jeszcze opisu nie symulowałem, tylko chciałem się zapytać czy dobrze zrozumiałem Twoje uwagi ?

    Pozdrawiam
    Łukasz
  • Poziom 14  
    prawie dobrze, lecz dalej synchronizuje count_next. chodziło mi o coś takiego:
    Code:

    count_next<= (0=> '1', others => '0') when RST='1' else
    count_reg(30 downto 0)&count_reg(31) when shifter='1' else count_reg;

    shifter jest sygnałem który jest ustawiany przy warunku counter=100. w przeciwnym razie jest zerowany
    całe przypisanie jest współbieżne.
  • Poziom 12  
    Poprawiony fragment opisu:
    Code:

    architecture Behavioral of counter is

       signal counter            :    integer range 0 to 100 := 0;
       signal shifter              :    STD_LOGIC;
       signal count_next         :    STD_LOGIC_VECTOR(31 downto 0);
       signal count_reg          :    STD_LOGIC_VECTOR(31 downto 0);

    begin
       process (clk) is
       begin
          if (rising_edge(clk)) then
             if (counter=100) then
                counter<=0;
                shifter<='1';
             else
                counter<=counter+1;
                shifter<='0';
             end if;
          end if;
       end process;
       
       count_next<= (0=> '1', others => '0') when reset='1' else
                    count_reg(30 downto 0)&count_reg(31) when shifter='1' else count_reg;
       
       count_reg<=count_next;
       
       count<=count_reg;
       
    end Behavioral;


    Czy teraz jest wszystko wporządku ?

    Pozdrawiam
    Łukasz
  • Poziom 14  
    już jest prawie dobrze :)
    jeszcze brakuje początkowej synchronizacji count_reg i powinno śmigać
    Code:
    process (clk) is 
    
       begin
          if (rising_edge(clk)) then
             count_reg<=count_next;
          end if;
       end process;     
  • Poziom 12  
    Teraz pojawia się problem po jednym pełnym obiegu licznika. Czyli jeśli licznik osiągnie wartość 100 i przechodzi do 0. Sygnał shifter przybiera wartość '1' (pierwszy raz ten sygnał osiąga tą wartość) i następuje próba współbieżnego przypisania:

    Code:

       count_next<= (0=> '1', others => '0') when reset='1' else
                    count_reg(30 downto 0)&count_reg(31) when shifter='1' else count_reg;


    Wydaje mi się, że tutaj pojawia się problem, gdyż przez czas trwania shifter='1' będzie następowała próba obracania sygnału count_reg w lewo (w nieskończoność).

    Licznik - post-route - pomóżcie znaleźć błąd

    Pozdrawiam
    Łukasz

    Zamiast wklejać do postu takiego giganta,
    proszę używać funkcji "Dodaj obrazek" - poprawiłem.
    [zumek]
  • Poziom 14  
    wszystko jest okey, zapomnieliśmy o paru rzeczach :)
    1.po resecie powinny być ustawiane wszystkie sygnały ( w naszym przypadku brakuje inicjalicaji countera, shiftera i najważniejszczego cnt_reg!)
    2.to co obserwujesz na symulacji jest skutkiem braku przypisania wartośći początkowej dla count_reg'a.
  • Poziom 12  
    Tylko, że podana sytuacja nie następuje po resecie, jak widać do momentu przepełnienia licznika wszystko pracuje poprawnie.

    Pozdrawiam
    Łukasz
  • Poziom 14  
    brakuje początkowego przypisania (dla potrzeby symulacji :))
    Code:

    signal count_reg         :    STD_LOGIC_VECTOR(31 downto 0)   :=   (others=>'0');
  • Poziom 12  
    ModelSim na to ;) :

    ** Error: (vsim-3601) Iteration limit reached at time 0 ps

    A wyjaśnienie na stronie Xilinx'a:

    http://www.xilinx.com/support/answers/19068.htm

    Nadal myślę, że to nie problem nadania wartości początkowej, tylko sposobu w jaki następuje przypisanie współbieżne.

    Pozdrawiam
    Łukasz
  • Poziom 14  
    nie jestem w stanie teg sprawdzić, lecz jestem przekonany że to powinno pujść. zweryfikuję to dopiero wieczorem...
    Code:
    architecture Behavioral of counter is 
    

       signal counter            :    integer range 0 to 100 := 0;
       signal shifter              :    STD_LOGIC := '0';
       signal count_next         :    STD_LOGIC_VECTOR(31 downto 0) := (others => '0');
       signal count_reg          :    STD_LOGIC_VECTOR(31 downto 0):= (others => '0');
     

    begin
       process (clk) is
       begin
          if (rising_edge(clk)) then
             if (counter=100) then
                counter<=0;
                shifter<='1';
             else
                counter<=counter+1;
                shifter<='0';
             end if;
          end if;
       end process;

    process (clk) is
       begin
          if (rising_edge(clk)) then
             count_reg<=count_next;
          end if;
       end process;

       
       count_next<= (0=> '1', others => '0') when reset='1' else
                    count_reg(30 downto 0)&count_reg(31) when shifter='1' else count_reg;
           
       count<=count_reg;
       
    end Behavioral;
  • Poziom 12  
    Tak działa (tak samo jak opis zamieszczony w pierwszym poscie). Niestety nadal jest głównym problem - przypadkowe wartości przy zmianie wartości sygnału count (symulacja post-route). Te przypadkowe wartości są nie do zaakceptowania :(.
  • Poziom 14  
    Code:
    Te przypadkowe wartości są nie do zaakceptowania . 

    wahania rzędu pikosekund są nie do zaakceptowania? dlaczego?
    w normalnym układzie takie szpilki przejdą niezauważalnie.
    w poprzednim topiku'u J.A sugerował ( i miał rację) że jest to stan przejściowy którego nie da się obejść, więc nie szukałbym rozwiązań do iluzorycznych wymgań :)
  • Poziom 12  
    J.A napisał, że to stan przejściowy, ale nigdzie nie zaznaczył, że nie można temu przeciwdziałać. Dokładnie co napisał poniżej:

    Cytat:

    chodzi o to, ze przy przejsciu licznika od wartosci np. ff do 100
    przez chwile na wejsciu ukladu porownujacego stan licznika
    i color_B(CONV_INTEGER(pwm_in) moze pojawic sie dowolna
    wartosc miedzy 0 a 1ff, zaleznie od opoznien sciezek i sygnalu
    zegarowego;
    jest to normalne i zwykle [ale nie zawsze] nie jest to grozne,
    jesli akurat w Twoim przypadku nie mozesz zaakceptowac takich
    szpilek, to musisz zmienic pwm_out z sygnalu czysto kombinacyjnego
    na rejestr, czyli zamiast:
    process (counter) is
    napisac:
    process (clk) is
    begin
    if (rising_edge(clk))


    Z pewnych względów chce uniknąć tych zmian sygnałów - pytam czy to możliwe, jeśli tak to jak to zrobić ? :)
  • Poziom 28  
    Lukee napisał:
    /.../

    dzieki wam przypominam sobie, co dawno temu umialem o vhdl ;);

    na poczatek - to ja nie pojmuje te komplikacje
    z count_reg, count_next, to mi przypomina styl
    pisania fsm, uzywanie go do zwyklego rejestru
    szeregowego wydaje mi sie przesada;
    ja to bym taki kod napisal najprosciej jak sie da
    Code:
    architecture Behavioral of counter is
    

     signal counter     : integer range 0 to 100 := 0;
     signal count_next  : STD_LOGIC_VECTOR(31 downto 0) := (0=>'1', others=>'0');
     
    begin
       process (clk) is
       begin
          if (rising_edge(clk)) then
             if (counter = 100) then
                counter <= 0;
                count_next <= count_next(30 downto 0) & count_next(31);
             else
                counter <= counter + 1;
             end if;
          end if;
       end process;

       count <= count_next;

    end Behavioral;  -- i tyle ...

    no jeszcze trzeba by dodac ten reset, co prawda i ise i quartus
    akceptuja zapis:
    signal count_next : STD_LOGIC_VECTOR(31 downto 0) := (0=>'1', others=>'0');
    i po power on counter_next bedzie mial prawidlowa wartosc, ale
    lepiej sie nie zdawac na uprzejma domyslnosc narzedzia z ktorym
    pracujemy, bo moze kiedys bedziemy kompilowac innym;

    co do chwilowych stanow przejsciowych, to cytat ktory
    przytoczyles dotyczyl innej sprawy;
    tutaj masz sytuacje, ze z zegarem jeden przerzutnik 'gasnie',
    drugi sie zapala, przez moment masz na wyjsciu albo '0',
    albo oba sa '1', zaleznie do ktorego pierwszy dotrze sygnal clk,
    i zaleznie od czasu podrozy sygnalu z wyjscia ff do pinu;
    jedyne co mozesz z tym zrobic, to poprosic ise, by rejestry
    ktore steruja wyjscia, umiescil w celach I/O, wtedy stany przejsciowe
    beda najkrotsze z mozliwych, byc moze niewidoczne w symulacji;
    jak to zrobic w ise nie wiem;
    a tak z ciekawosci - czemu Ci to przeszkadza ?

    J.A
  • Poziom 12  
    Zawsze opisywałem moduł tak jak J.A, niestety poprzedni post mnie zbił z tropu i przez chwilę myślałem :), że te przypisania count_reg, count_next coś dadzą, że tak jest poprawnie, etc :). O tym dlaczego mi to tak przeszkadza, może później, jak potestuje :)

    Dziękuje za pomoc i wyjaśnienie pewnych spraw :)

    Pozdrawiam
    Łukasz
  • Poziom 14  
    oba rozwiązania są jak najbardziej poprawne. w pierwszym poście pokazałeś kod który jest opisem w tzw. next-state logic, więc moje uwagi dotyczyły twojego kodu.
    w żadnen sposób nie przymuszałem do stosowania tej techniki i w żaden sposób nie sugerowałem że te rozwiązanie jest lepsze :D
    dla mnie opis wygląda o wiele bardziej przejrzyście i logiczniej. a to już są moje subiektywne odczucia :)
  • Poziom 28  
    _greis_ napisał:
    /.../w żaden sposób nie przymuszałem/.../

    mysle, ze Lukee piszac, ze poprzedni post go zbil z tropu
    mial na mysli moj post z watku o symulacji post&route;

    J.A