Овој семестар на факултет слушам многу интересен предмет,PLD и FPGA,поточно опишуваме хардвер во програмскиот јазик VHDL.Со користење на секвенцијални,паралелни и прироритетни наредби секој може да напише код за било кое опишување на хардвер.Во продолжение ќе поставам слики,шеми,кодови како да се изработи бројач имплементиран на FPGA (приказ на секунди,но и со милисекунди).Конфигурационите фајлови се напишани во Xilinx's ISE околината,со мапирањето на пиновите на модулот Cmod S6 - FPGA модулот,iMPACT се користи за програмирање на модулот.
Дел од кодот е искористен од интерната скрипта од самиот предмет,дел сам го допишав.Овој модул Cmod S6 е базиран на Xilinx Spartan S6 генерација на FPGA.На самата плочка има ROM,USB интерфејс за поврзување на PC,46 влезно/излезни пинови што се доволни за било која апликација,осцилатор од 8 MHz и 1 Hz,напојувања за FPGA-то и останатите компоненти.
Искористив 4in1 7 сегментни дисплеи,во мојов случај се со заедничка катода,анодите на дисплеите се поврзани сите заедно и секој пин води кон Cmod S6-ката.Заедничките катоди се поврзани преку BC547 транзистори кон маса.Дисплејот е набавен од Логинг електроникс уште пред неколку години и седи за вакви намени(протипирање),може да се искористи и дисплеј со заедничка анода,но тогаш треба да се сменат делови од кодот,пример: when "0000" => segments <= "11111100"; е код за заедничка катода,а ова би било точно доколку сакаме да е со заедничка анода - when "0000" => segments <= "00000011"; односно ги претвораме сите '0' во '1' и обратно.Треба да се направи и промена во деловите за активација на цифрите - act_dis = "0001" ,овој код е за заедничка катода,па треба и тука да се направи конверзија од '0' во '1' и обратно.
Шемата ќе ја поставам малце подоцна,ќе треба да ја нацртам.
Слики од изработениот прототип -
изглед на Cmod S6 Spartan 6 module
-Слики од готовиот бројач-
Кодови во VHDL -
Код за конвертор на BCD во 7 сегментен дисплеј со 4 дисплеи
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ssd is
port(
bcd : IN STD_LOGIC_VECTOR(3 downto 0);
act_display : IN STD_LOGIC_VECTOR(3 downto 0);
segments : OUT STD_LOGIC_VECTOR(7 downto 0);
sel : OUT STD_LOGIC_VECTOR(3 downto 0)
);
end ssd;
architecture Behavioral of ssd is
begin
process(bcd)
begin
case bcd is
when "0000" => segments <= "11111100";
when "0001" => segments <= "01100000";
when "0010" => segments <= "11011010";
when "0011" => segments <= "11110010";
when "0100" => segments <= "01100110";
when "0101" => segments <= "10110110";
when "0110" => segments <= "10111110";
when "0111" => segments <= "11100000";
when "1000" => segments <= "11111110";
when "1001" => segments <= "11110110";
when OTHERS => segments <= "00000000";
end case;
end process;
process(act_display)
begin
sel <= act_display;
end process;
end Behavioral;
Код за бројач на милисекунди и секунди
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity timer_99 is
port(
clk,rst : in std_logic;
bcd_counter : out std_logic_vector(3 downto 0);
SSD_Digit : out std_logic_vector (7 downto 0);
SSD_Anodes : out std_logic_vector(3 downto 0)
);
end timer_99;
architecture Behavioral of timer_99 is
component ssd IS port (
bcd : in std_logic_vector(3 downto 0);
act_display : in std_logic_vector(3 downto 0);
segments : out std_logic_vector(7 downto 0);
sel : out std_logic_vector(3 downto 0)
);
end component;
signal value : std_logic_vector(3 downto 0);
signal digit0 : std_logic_vector(3 downto 0);
signal digit1 : std_logic_vector(3 downto 0);
signal digit2 : std_logic_vector(3 downto 0);
signal digit3 : std_logic_vector(3 downto 0);
signal act_dis : std_logic_vector(3 downto 0) := "1110";
signal ticks : integer range 8000000 downto 0 := 0;
signal anodeChangeTicks : integer range 160000 downto 0 := 0;
begin
PROCESS(clk,rst)
begin
if(rst = '1') then
digit0 <= "0000";
digit1 <= "0000";
digit2 <= "0000";
digit3 <= "0000";
elsif(clk' event and clk='1') then
if(ticks = 80000) then
if(digit0 = "1001") then
digit0 <= "0000";
if(digit1 = "1001") then
digit1 <= "0000";
if(digit2 = "1001") then
digit2 <= "0000";
if(digit3 = "1001") then
digit3 <= "0000";
else
digit3 <= digit3 + 1;
end if;
else digit2 <= digit2 + 1;
end if;
else
digit1 <= digit1 + 1;
end if;
else
digit0 <= digit0 + 1;
end if;
ticks <= 0;
else
ticks <= ticks + 1;
end if;
if(anodeChangeTicks = 50000) then
if(act_dis = "0001") then
act_dis <= "0010";
value <= digit1;
elsif(act_dis = "0010") then
act_dis <= "0100";
value <= digit2;
elsif(act_dis = "0100") then
act_dis <= "1000";
value <= digit3;
else
act_dis <= "0001";
value <= digit0;
end if;
anodeChangeTicks <= 0;
else
anodeChangeTicks <= anodeChangeTicks + 1;
end if;
end if;
end process;
U1 : ssd port map(value,act_dis,SSD_Digit,SSD_Anodes);
bcd_counter <= digit1;
end Behavioral;
Мапирање на пиновите на Cmod S6 модулот -
NET "SSD_Digit[0]" LOC = "D14";
NET "SSD_Digit[1]" LOC = "E14";
NET "SSD_Digit[2]" LOC = "B3";
NET "SSD_Digit[3]" LOC = "C13";
NET "SSD_Digit[4]" LOC = "D13";
NET "SSD_Digit[5]" LOC = "E13";
NET "SSD_Digit[6]" LOC = "A2";
NET "SSD_Digit[7]" LOC = "A3";
NET "SSD_Anodes[0]" LOC = "G13";
NET "SSD_Anodes[1]" LOC = "D1";
NET "SSD_Anodes[2]" LOC = "C1";
NET "SSD_Anodes[3]" LOC = "B1";
NET "clk" LOC = "N8";
NET "rst" LOC = "P8";
NET "bcd_counter[0]" LOC = "N3";
NET "bcd_counter[1]" LOC = "P3";
NET "bcd_counter[2]" LOC = "N4";
NET "bcd_counter[3]" LOC = "P4";