BCD to Binary (74145 yapmak)

Başlatan MC_Skywalker, 23 Eylül 2015, 11:55:53

MC_Skywalker

Bir dummy ön sayıcı eklemek gerekli sanırım. gözümüzün göreceği bir frekansa indirmek için.

alicavuslu

#16
Bunu iki şekilde yapabilirsiniz. Birincisinde 100.000.000 luk bir sayac saydırıp 1 sn beklersiniz. Daha sonra bu sayacı sıfırlar ve başka bir sayacı artırırsınız. Bu sayacıda case durumunda kontrol edersiniz.

İkincisinde (benim önerim) ise 1 sn'lik yeni bir clk oluşturmak. Daha sonra kodunuzuda clk yerine bu yeni clk değerini koyduğunuzda çalışacaktır.

MC_Skywalker

ikincisi daha mantıklı geldi. bununbaşka projelere include etmek durunuda olursa tadından yenmez 😊

MC_Skywalker

#18
Kafamı iyice karıştırdım.  1sn clk için kodda değişiklik yaptım ama kodu daha berbat ettim. Başvuru kitabı almam gerekli sanırım.

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

entity sayac1 is
    Port ( clk : in STD_LOGIC;
          led015 : out STD_LOGIC_VECTOR (15 downto 0));
end sayac1;

architecture Behavioral of sayac1 is
     signal counter: std_logic_vector(3 downto 0):= "0000";
     signal gecici: std_logic_vector(3 downto 0);
     signal pulse : std_logic := '0';
     signal count : integer range 0 to 99999999 := 0;

begin
     process(clk)
     begin
          if clk= '1' and clk'event then
              if count = 99999999 then
                       count <= 0;
                       pulse <= not pulse;
               else
			count <= count + 1;
               end if;
          end if;

     end process;
      gecici <= counter;
     
      process (gecici)
                           
                  begin
                  case gecici is
                       when "0000" =>  led015 <= "0000000000000001";  --0
                       when "0001" =>  led015 <= "0000000000000010";  --1
                       when "0010" =>  led015 <= "0000000000000100";  --2
                       when "0011" =>  led015 <= "0000000000001000";  --3
                       when "0100" =>  led015 <= "0000000000010000";  --4
                       when "0101" =>  led015 <= "0000000000100000";  --5
                       when "0110" =>  led015 <= "0000000001000000";  --6
                       when "0111" =>  led015 <= "0000000010000000";  --7
                       when "1000" =>  led015 <= "0000000100000000";  --8
                       when "1001" =>  led015 <= "0000001000000000";  --9
                       when "1010" =>  led015 <= "0000010000000000";  --10
                       when "1011" =>  led015 <= "0000100000000000";  --11
                       when "1100" =>  led015 <= "0001000000000000";  --12
                       when "1101" =>  led015 <= "0010000000000000";  --13
                       when "1110" =>  led015 <= "0100000000000000";  --14
                       when "1111" =>  led015 <= "1000000000000000";  --15
                       when others =>  led015 <= "0000000000000000";  --Hata         
                       end case;
          end process;
end Behavioral;


Edit:
Hatayı farkettim sistemi yanlış kurmuşum.

alicavuslu

Aslında sizin yaptığınız uygulama benim 1. tarif ettiğime uygulama olmaktadır. Benim bahsettiğim ikinci şekil aşağıdaki gibidir. Kodu sentezledim. Siz kart üzerinde test edip geri dönüş yaparsanız sevinirim.

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

entity sayac1 is
    Port ( clk : in STD_LOGIC;
          led015 : out STD_LOGIC_VECTOR (15 downto 0));
end sayac1;

architecture Behavioral of sayac1 is

    constant SYS_CLK_PERIOD : integer := 10; -- ns cinsinden
    constant NEW_CLK_PERIOD : integer := 100_000_000; -- ns cinsinden
    constant CLK_COUNT : integer := NEW_CLK_PERIOD / (2 * SYS_CLK_PERIOD);
         
    signal counter: std_logic_vector(3 downto 0):= "0000";
    signal gecici: std_logic_vector(3 downto 0);
    signal clk_new : std_logic := '0';
    signal count : integer range 0 to 99999999 := 0;

begin
     process(clk)
     begin
        if clk= '1' and clk'event then
            if count = CLK_COUNT - 1 then
                count <= 0;
                clk_new <= not clk_new;
            else
                count <= count + 1;
            end if;
        end if;
     end process;
     
     process(clk_new)
     begin
        if rising_edge(clk_new) then
            counter <= counter + 1;
        end if;
     end process;
     gecici <= counter;
     
      process (gecici)
                           
                  begin
                  case gecici is
                       when "0000" =>  led015 <= "0000000000000001";  --0
                       when "0001" =>  led015 <= "0000000000000010";  --1
                       when "0010" =>  led015 <= "0000000000000100";  --2
                       when "0011" =>  led015 <= "0000000000001000";  --3
                       when "0100" =>  led015 <= "0000000000010000";  --4
                       when "0101" =>  led015 <= "0000000000100000";  --5
                       when "0110" =>  led015 <= "0000000001000000";  --6
                       when "0111" =>  led015 <= "0000000010000000";  --7
                       when "1000" =>  led015 <= "0000000100000000";  --8
                       when "1001" =>  led015 <= "0000001000000000";  --9
                       when "1010" =>  led015 <= "0000010000000000";  --10
                       when "1011" =>  led015 <= "0000100000000000";  --11
                       when "1100" =>  led015 <= "0001000000000000";  --12
                       when "1101" =>  led015 <= "0010000000000000";  --13
                       when "1110" =>  led015 <= "0100000000000000";  --14
                       when "1111" =>  led015 <= "1000000000000000";  --15
                       when others =>  led015 <= "0000000000000000";  --Hata         
                       end case;
          end process;
end Behavioral;

MC_Skywalker

#20
kod sıkıntızı çalışıyor.
benim yazmaya çalıştığım kodu şu çizime göre yapmaya çalışım fakat kodda sinyal bağlatısını unutuğum yerler var.



alicavuslu

#21
Hocam şimdi bu kondu yeni clock siynalini port map kullanarak elde ederseniz bu işi tam anlamıyla gerçekleştirmiş olursunuz...

mesaj birleştirme:: 28 Eylül 2015, 21:23:18

Sizin kodda aşağıdaki düzenlemeyi yaparsanız resimdeki gibi kodlamış olursunuz.

     process(clk)
     begin
          if clk= '1' and clk'event then
              if count = 99999999 then
                       count <= 0;
                       counter <= counter + 1;
               else
         count <= count + 1;
               end if;
          end if;

     end process;

MC_Skywalker

Düzeltmeyi uyguladuktan sonra kod istediğim gibi çalıştı. YArdımlarınız için teşekürler.
http://youtu.be/TQ9zQvuOYa4

alicavuslu

Kodları aşağıdaki gibi de kullanabilirsiniz. Durum makinesi yerine bir kaydırmalı saklayıcı ile ledlerdeki değerlerin kaymasını sağlayabiliriz.

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

entity sayac1 is
    Port ( clk : in STD_LOGIC;
          led015 : out STD_LOGIC_VECTOR (15 downto 0));
end sayac1;

architecture Behavioral of sayac1 is

    constant SYS_CLK_PERIOD : integer := 10; -- ns cinsinden
    constant NEW_CLK_PERIOD : integer := 100_000_000; -- ns cinsinden
    constant CLK_COUNT : integer := NEW_CLK_PERIOD / (2 * SYS_CLK_PERIOD);
         
    signal counter: std_logic_vector(3 downto 0):= "0000";
    signal gecici: std_logic_vector(3 downto 0);
    signal clk_new : std_logic := '0';
    signal count : integer range 0 to 99999999 := 0;
    signal r_led015 : STD_LOGIC_VECTOR (15 downto 0):= X"0001";

begin
     process(clk)
     begin
        if clk= '1' and clk'event then
            if count = CLK_COUNT - 1 then
                count <= 0;
                clk_new <= not clk_new;
            else
                count <= count + 1;
            end if;
        end if;
     end process;
     
     process(clk_new)
     begin
        if rising_edge(clk_new) then
            r_led015 <= r_led015(14 downto 0) & r_led015(15);
        end if;
     end process;
     led015 <= r_led015;

end Behavioral;

MC_Skywalker

Shift registerler biraz çalışmam lazım okulda kendilerine pek alışamamıştım.

alicavuslu

VHDL ile bu işlemi sadece aşağıdaki kod ile yapıyoruz. Koddanda görüleceği üzere bitleri sağa doğru 1 kaydırıyoruz ve en soldaki biti en sağa ekliyoruz.

r_led015 <= r_led015(14 downto 0) & r_led015(15);

MC_Skywalker

#26
VHDL kodların derli toplu kısa açıklamalarının olduğu bir döküman varmıdır.  google amca ile toplamak biraz uzun sürüyor.

Bu arada VIVADOWeb, 2015.3 Güncellemesi yaptı Yeniden Lisans istedi. 2015.2 güncellemesini yaparken istememişti.

alicavuslu

VHDL kodlarının hepsinin bir arada bulunduğu bir site aşağıdaki linktedir. Lisansı ise muhtemelene tekrardan almanız gerekebilir.

http://www.ics.uci.edu/~jmoorkan/vhdlref/

MC_Skywalker

#28
Webten bulduğum kodları Basys3 e göre düzenleyio denemeye devam.

----------------------------------------------------------------------------------
-- Create Date: 11.10.2015 18:10:28
-- Create eden: MC_Skywalker scpecialist@yahoo.com
-- Module Name: 16bitYASayici - Behavioral
-- Project Name: 16 bit yukarı aşağı sayıcı
-- Target Devices: Atrix-7 XC7A35T-1 
-- Tool Versions: Vivado 2015.3
-- Description: Hızı optimize edilmedi.  
-- Dependencies: 
-- Revision:
-- Revision 0.01 - File Created
----------------------------------------------------------------------------------

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

entity onalti is
    Port ( clk100 : in STD_LOGIC;
           anh : in STD_LOGIC;
           led015 : out STD_LOGIC_VECTOR (15 downto 0));
end onalti;

architecture Behavioral of onalti is
            signal prescaller : integer range 0 to 800000:=0;
            signal sonuc : integer range 0 to 65535:=0;
begin
    led015<=STD_LOGIC_VECTOR(to_unsigned(sonuc,16));
        process(clk100)
            begin
            if(clk100'event and clk100='1') then
             if(prescaller<800000) then
                prescaller<=prescaller+1;
             else
                prescaller<=0;
            end if;       
            
            if(prescaller=0) then
            case anh is
                when '1' =>
                    if(sonuc<65535) then
                       sonuc<=sonuc+1;
                    else
                       sonuc<=0;
                    end if;
                when '0' =>
                    if(sonuc>0) then
                       sonuc<=Sonuc-1;
                    else
                       sonuc<=65535;
                    end if;
            end case;
            end if;
            end if;
        end process;                        
end Behavioral;


http://youtu.be/EQbJrg95WK4




alicavuslu

65535 değerini bir constant'a atayarak hızı ayarlama paremetresi olarak tanımlayabilirsiniz.

constant SPEED : integer := 65535;

Yada bu değeri butonlar ile kontrol edebilirsiniz. Butona bastıkca hızlanan başka bir butona bastıkça yavaşlayan.