Skocz do zawartości

Kurs FPGA - #6 - rejestry przesuwne w VHDL


Pomocna odpowiedź

  • 9 miesiące później...

Witam

Mam problem z rejestrem przesuwnym, ponieważ nie do końca rozumiem jak działa to przesunięcie bitów bo jest ten licznik itd. który odlicza czas do przesunięcia no i dalej jest problem z tym przesunięciem co mi uniemożliwia przesuwanie w drugą stronę bo tego nie rozumiem. Prosiłbym o dokładniejsze wytłumaczenie co się dzieje w tej linijce:

rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(7 downto 1);

Pozdrawiam

30 minut temu, PanDer napisał:

Mam problem z rejestrem przesuwnym, ponieważ nie do końca rozumiem jak działa to przesunięcie bitów bo jest ten licznik itd. który odlicza czas do przesunięcia no i dalej jest problem z tym przesunięciem co mi uniemożliwia przesuwanie w drugą stronę bo tego nie rozumiem. Prosiłbym o dokładniejsze wytłumaczenie co się dzieje w tej linijce:


rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(7 downto 1);

Rozumiem, że komentarz jaki jest w kursie nad tą linijką nie pomaga?

             -- tutaj jest przeprowadzana esencja procesu przesuwania przeprowadzanego w rejestrze przesuwnym;
             -- nastepuje przeklejenie najmlodszego bitu na najstarsza pozycje.
             rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(7 downto 1);

W drugą stronę musisz przykleić najstarszy bit na najmłodszą pozycję.
 

rej_przesuwny <= rej_przesuwny(6 downto 0) & rej_przesuwny(7);

 

  • Pomogłeś! 1

@PanDer dobrze się składa, przez ostatnie 2 dni nadrabiałem zaległości z VHDL. Tu masz kod, który służy do przełączania segmentów wyświetlacza na płytce z kursu. Możesz się posiłkować tym, ale sprowadza się to do tego co podał @pmochocki W jego rozwiązaniu zwróć szczególnie uwagę na indeksowanie.

shifter : process(reset, clk) begin
	if (reset = '1') then
		shift_reg <= (others => '1');
		shift_reg(0) <= '0';
		bcd_copy(3 downto 0) <= bcd(3 downto 0);
	elsif rising_edge(clk) then
		shift_reg <= shift_reg(N-2 downto 0) & shift_reg(N-1); --rejestr działający w drugą stronę
				
		if (shift_reg = "101") then
			bcd_copy(3 downto 0) <= bcd(3 downto 0);
		elsif (shift_reg = "011") then
			bcd_copy(3 downto 0) <= bcd(7 downto 4);
		elsif (shift_reg = "110") then
			bcd_copy(3 downto 0) <= bcd(11 downto 8);
		end if;

 

  • 2 lata później...

Witam serdecznie od dwóch dni próbuje wykonać rejestr bez przesuwania danych na poczatek. Mam pomaranczowa plytke.

Bez przesuwania diody stoja w miejscu na 3 ostatnich bitach:

rej_przesuwny <=  rej_przesuwny(7 downto 0);

czy wystarczy tylko przekształcić tą linijkę, lub też umieścić ją w innym miejscu:

rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(7 downto 1);

czy trzeba stosować pętle for, delay lub inne zabiegi. Tego jeszcze nie było w tym kurie wiec nawet nie wiem jak to napisać. Jakaś drobna podpowiedź bardzo by się przydała.

rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(7 downto 1);
rej_przesuwny <= not rej_przesuwny;

diody migaja na przemian. Rozbijałem na pojedyńcze bity ale też nie wychodzi.

Pewnie dało by się na wiele sposobów.

Świetny kurs. Nie miałem pojęcia że da się tworzyć połączenia między pinami programowo bez przewodów.

 

 

(edytowany)

Nie bardzo rozumiem sformułowane pytania, ale postaram się jakoś odpowiedzieć.

Dnia 25.06.2024 o 20:31, Mateuszek111 napisał:

czy trzeba stosować pętle for, delay lub inne zabiegi.

Zwróć uwagę, że na to, że kod obsługi rejestru w kursie został umieszczony w procesie, którego lista czułości zawiera sygnał zegarowy.
Kod wewnątrz instrukcji warunkowej

if rising_edge(Clk) then

wykonuje się co takt zegara. Dodatkowo, jest tam druga instrukcja warunkowa

if (licznik = LICZNIK_LIMIT) then

która powoduje, że właściwy kod zmiany zawartości rejestru jest wykonywany co określony interwał czasowy (gdy licznik de facto taktów zegara osiągnie zakładaną wartość).


Coś takiego:

rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(7 downto 1);
rej_przesuwny <= not rej_przesuwny;

jest w tym przypadku dokładnie równoważne

rej_przesuwny <= not rej_przesuwny;

ze względu na sposób „zachowania się" sygnałów w procesach w VHDL. Można tutaj spróbować poczytać np. o różnicach pomiędzy zmiennymi a sygnałami, może to trochę rozjaśni zagadnienie.

Edytowano przez piotr96
Zbędny przecinek.
  • Lubię! 2
  • 2 tygodnie później...

Bardzo dziekuje za pomoc. Użyłem zmiennej i kombinowałem tak długo aż się udało. W ucf diody mam ponumerowane od 7 bitu w doł aby rejestr przesuwał się w prawo (Chyba tak jest na pomarańczowej płytce). Żeby diody się zapaliły na początku, rej przesuwny musiałem ustawić na wartość "A0". Tylko nie rozumiem dlaczego dopiero jak ustawiłem warunek "przesunięcia poza rejestr" zmiennej zmiana na 10 to ostatnia dioda zgasła(Inkrementacja zmiennej następuje z dwóch warunków?). I co się tutaj dzieje że diody znikają:

 rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(6 downto 0);

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity rejestr_przesuwny is
    Port ( Clk : in STD_LOGIC;
             LED : out STD_LOGIC_VECTOR (7 downto 0));
end rejestr_przesuwny;

architecture Behavioral of rejestr_przesuwny is

signal rej_przesuwny : STD_LOGIC_VECTOR(7 downto 0) := X"A0";

constant LICZNIK_LIMIT : integer := 12000000;

signal licznik : STD_LOGIC_VECTOR(24 downto 0);

signal zmiana: STD_LOGIC_VECTOR(4 downto 0);


begin

zliczanie_i_przesuwanie : process(Clk)
    begin
        if rising_edge(Clk) then
           if (licznik = LICZNIK_LIMIT) then
                
                licznik <= (others => '0');
                 
                
                 rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(7 downto 1);
                 
                 zmiana <= zmiana +1;
                

                 
            else
                licznik <= licznik + 1;
            end if;
            if (zmiana  = 6) then
                    rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(6 downto 0);
                
                zmiana <= zmiana + 1;
            end if;
            
            if (zmiana = 7) then
                rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(6 downto 0);
                zmiana <= zmiana +1;
            end if;
            if (zmiana = 10) then
                rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(6 downto 0);
                zmiana <= zmiana + 1;
            end if;
            if (zmiana = 12) then
                rej_przesuwny <= X"A0";
                zmiana <= zmiana - 12;
            end if;
        end if;
        
end process zliczanie_i_przesuwanie;

LED <= rej_przesuwny;

end Behavioral;

Mnie ten kurs pomaga lepiej zrozumieć operacje na bitach, system binarny i heksadecymalny. Dziękuje że jesteście 🙂

Przepraszam za błędy( Tutaj nie zmienna tylko sygnał powinienem pisać chyba) i chaos w pisowni.

Poniższa instrukcja:

rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(6 downto 0);

jest równoważna w rozbiciu na fragmenty wektora:

rej_przesuwny(7) <= rej_przesuwny(0);
rej_przesuwny(6 downto 0) <= rej_przesuwny(6 downto 0);

Czyli najmłodszy bit jest przepisywany w miejsce najstarszego, a reszta wektora zostaje bez zmian.

 

6 godzin temu, Mateuszek111 napisał:

Tutaj nie zmienna tylko sygnał powinienem pisać chyba)

Tak, tutaj używane są sygnały, a nie zmienne.

 

Co do reszty, to ponownie nie bardzo rozumiem pytań, mogę tylko napisać, że:

if (zmiana  = 6) then
  	rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(6 downto 0);
	zmiana <= zmiana + 1;
end if;

if (zmiana = 7) then
  	rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(6 downto 0);
	zmiana <= zmiana +1;
end if;
if (zmiana = 10) then
  	rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(6 downto 0);
	zmiana <= zmiana + 1;
end if;

jest równoważne:

if (zmiana  = 6 or zmiana = 7 or zmiana = 10) then
  	rej_przesuwny <= rej_przesuwny(0) & rej_przesuwny(6 downto 0);
	zmiana <= zmiana + 1;
end if;

 

  • Lubię! 2

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...