[ DusanSukovic @ 17.07.2013. 18:46 ] @
Dopala mi je saka DIGILENT BASYS2 FPGA plocica razvojna, i zelim da uradim decimalni counter, koji treba da broji recimo od 0 do 9999 na LED displayu. Kako da uradim ovo? Hvala! |
[ DusanSukovic @ 17.07.2013. 18:46 ] @
[ bogdan.kecman @ 17.07.2013. 20:15 ] @
imas decimalni counter na 7seg-u u primerima za tu dev plocku
evo ti neki pocetak: hes2led.vhd: Code: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity hex2led is Port ( HEX : in STD_LOGIC_VECTOR (3 downto 0); LED :out STD_LOGIC_VECTOR (6 downto 0 )); end hex2led; architecture Behavioral of hex2led is begin -- -- segment encoding -- 0 -- --- -- 5 | | 1 -- --- <- 6 -- 4 | | 2 -- --- -- 3 with HEX SELect LED<= "1111001" when "0001", --1 "0100100" when "0010", --2 "0110000" when "0011", --3 "0011001" when "0100", --4 "0010010" when "0101", --5 "0000010" when "0110", --6 "1111000" when "0111", --7 "0000000" when "1000", --8 "0010000" when "1001", --9 "0001000" when "1010", --A "0000011" when "1011", --b "1000110" when "1100", --C "0100001" when "1101", --d "0000110" when "1110", --E "0001110" when "1111", --F "1000000" when others; --0 end Behavioral; dakle ovaj vhdl ti konvertuje ulazni 4 bitni broj u hex prikaz istog na 7seg-u (dakle 7bitni izlaz) dalje ti treba nesto ovako ten_counter.vhd: Code: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity ten_counter is Port ( clk : in STD_LOGIC; ce : in STD_LOGIC; rst : in STD_LOGIC; --active low dout : out STD_LOGIC_VECTOR (3 downto 0); co : out STD_LOGIC); end ten_counter; architecture Behavioral of ten_counter is signal count : std_logic_vector (3 downto 0) := "0000"; signal carryout : std_logic := '0'; begin process (clk, rst, ce, count, carryout) begin if (rst='0') then count <= (others=>'0'); carryout <= '0'; elsif (ce='1' and clk'event and clk='1') then if (count="1000") then count <= count +1; carryout <= '1'; -- count goes to 9, and set the co for the tens digit elsif (count = "1001") then --if count=9, then roll-over to 0 count <= (others=>'0'); carryout <= '0'; else count <= count+1; carryout <= '0'; end if; end if; end process; co <= carryout; dout <= count; end Behavioral; mislim da je prilicno jasan? isto to samo 100k 100_k_counter.vhd: Code: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity one_hundred_K_counter is Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; -- active low cken : in STD_LOGIC; dout_fast : out STD_LOGIC; -- 256 count dout_100k : out STD_LOGIC); end one_hundred_K_counter; architecture Behavioral of one_hundred_K_counter is signal count : std_logic_vector (16 downto 0) := "00000000000000000"; signal co : std_logic := '0'; begin process (clk, rst, count, cken) begin if (rst='0') then count <= (others=>'0'); elsif (cken ='1' and clk'event and clk='1') then if (count = "11000011010011111") then --if count=99,999 then roll-over to 0 count <= (others=>'0'); co <= '1'; elsif (count = "1100001101001111") then -- if count = 49,999 then count <= count+1; co <= '0'; else count <= count+1; end if; end if; end process; dout_100k <= co; dout_fast <= count(8); -- output a faster clock for use with the quad 7-segment display module end Behavioral; sixty_counter.vhd: Code: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity sixty_counter is Port ( clk : in STD_LOGIC; ce : in STD_LOGIC; rst : in STD_LOGIC; -- active low dout : out STD_LOGIC_VECTOR (3 downto 0); co : out STD_LOGIC); end sixty_counter; architecture Behavioral of sixty_counter is signal count : std_logic_vector (3 downto 0) := "0000"; signal carryout : std_logic := '0'; begin process (rst, count, carryout, ce, clk) begin if (rst='0') then count <= (others=>'0'); carryout <= '0'; elsif (ce='1' and clk'event and clk='1') then if (count = "0100") then -- prepare for rollover of minute digit at next clock count <= count+1; carryout <= '1'; elsif (count = "0101") then --if count=5, then roll-over to 0 count <= (others=>'0'); carryout <= '0'; else count <= count+1; carryout <= '0'; end if; end if; end process; co <= carryout; dout <= count; end Behavioral; i sve to spojis u top modul top.vhd: Code: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library UNISIM; use UNISIM.VComponents.all; -- this library is necessary because the CRII clock -- divider component is used entity top is Port ( clk : in STD_LOGIC; -- main clock (intended for 1 Mhz) sw0 : in STD_LOGIC; -- data_gate enable rst : in STD_LOGIC; -- active low, btn0 cken : in STD_LOGIC; -- active low, btn1 sseg : out STD_LOGIC_VECTOR (07 downto 0); -- output to quad 7-segment display sseg_sel : out STD_LOGIC_VECTOR (03 downto 0); -- selector for the 7-segment display leds : out STD_LOGIC_VECTOR (03 downto 0); -- LED outputs db : out STD_LOGIC_VECTOR (7 downto 0); -- following 5 lines are for LCD PMOD rs : out STD_LOGIC; rw : out STD_LOGIC; en : out STD_LOGIC ); end top; architecture Behavioral of top is component lcd Port (DB : out STD_LOGIC_VECTOR (7 downto 0); RS : out STD_LOGIC; RW : out STD_LOGIC; EN : out STD_LOGIC; CLK : in STD_LOGIC; RESET : in STD_LOGIC); end component; component hex2led Port ( HEX : in STD_LOGIC_VECTOR (3 downto 0); LED :out STD_LOGIC_VECTOR (6 downto 0 )); end component; component ten_counter Port (clk : in std_logic; rst : in std_logic; ce : in std_logic; dout : out std_logic_vector (3 downto 0); co : out std_logic); end component; component sixty_counter Port (clk : in std_logic; ce : in std_logic; rst : in std_logic; dout : out std_logic_vector (3 downto 0); co : out std_logic); end component; component one_hundred_k_counter Port (clk : in std_logic; cken : in std_logic; rst : in std_logic; dout_fast : out std_logic; dout_100k : out std_logic); end component; signal clkdv : std_logic ; -- output of clock divider signal lcd_A, lcd_B, lcd_C, lcd_D : std_logic_vector (6 downto 0); -- LCD data signal seconds, tens, minute_lsb, minute_msb : std_logic_vector (3 downto 0); signal sec_co, ten_co, sixty_co, minute_lsb_co : std_logic; -- carry out for counter digits signal lcd_cycle_reg : std_logic_vector (3 downto 0) := "0111"; -- used to cycle the select line for the LED digits signal second_clk : std_logic; signal minute_enable, ten_minute_enable: std_logic; signal fast_clk : std_logic; -- a fast clock to cycle the LED select line begin cr_clk_divider : clk_div10 port map ( CLKDV => CLKDV, -- Divide 1 Mhz to 100 kHz CLKIN => CLK ); lcd_driver : lcd port map ( DB => db, RS => rs, RW => rw, EN => en, CLK => clk, RESET => rst); -- ledX: to convert values to the 7-segment display format led1 : hex2led port map ( hex => seconds, Led => lcd_A ); led2 : hex2led port map ( hex => tens, Led => lcd_B ); led3 : hex2led port map ( hex => minute_lsb, Led => lcd_C ); led4 : hex2led port map ( hex => minute_msb, Led => lcd_D ); my_100k_counter : one_hundred_k_counter port map ( clk => clkdv, cken => cken, rst => rst, dout_fast => fast_clk, dout_100k => second_clk); seconds_counter : ten_counter port map ( clk => second_clk, ce => '1', rst => rst, dout => seconds, co => sec_co); tens_counter : sixty_counter port map ( clk => second_clk, ce => sec_co, rst => rst, dout => tens, co => ten_co); minute_enable <= ten_co and sec_co; ten_minute_enable <= minute_lsb_co and ten_co and sec_co; min_counter_lsb : ten_counter port map ( clk => second_clk, ce => minute_enable, rst => rst, dout => minute_lsb, co => minute_lsb_co ); min_counter_msb : ten_counter port map ( clk => second_clk, ce => ten_minute_enable, rst => rst, dout => minute_msb ); -- cycle between the 4 7-segment displays at a fast rate, so they appear enabled simultaneously lcd_cycle : process (fast_clk, rst, lcd_cycle_reg) begin if (rst='0') then lcd_cycle_reg <= "1110"; elsif (fast_clk'event and fast_clk='1') then lcd_cycle_reg (2 downto 0) <= lcd_cycle_reg (3 downto 1); lcd_cycle_reg (3) <= lcd_cycle_reg(0); end if; end process; sseg_sel <= lcd_cycle_reg; -- mux for the 4 outputs to the 7 segment display process (lcd_cycle_reg,lcd_A, lcd_B, lcd_C, lcd_D) begin case lcd_cycle_reg is when "0111" => sseg <= ('1'& lcd_A); when "1011" => sseg <= ('1'& lcd_B); when "1101" => sseg <= ('0'& lcd_C); when "1110" => sseg <= ('1'& lcd_D); when others => sseg <= "11111111"; end case; end process; leds(3) <= not (second_clk); -- second 'heartbeat' leds(2) <= '1'; -- disable this LED leds(1) <= '1'; -- disable this LED leds(0) <= not (sw0); -- led is active low, will light if data_Gate enabled end Behavioral; i to je to :D mega jednostavno ... samo ti jos treba da napravis ucf fajl gde assigneujes pinove na sseg(0-7) za lcd, sseg_sel(0-3), leds(0-3) rst, cken i sw0 i to je to da ne bude zabune, nisam ja pisao ove vhdl-ove, to je neki primer za cpld koji mi je prvi pao pod ruku koji radi to sto tebi treba [ DusanSukovic @ 17.07.2013. 21:08 ] @
Citat: bogdan.kecman: mega jednostavno ... samo ti jos treba da napravis ucf fajl gde assigneujes pinove na sseg(0-7) za lcd, sseg_sel(0-3), leds(0-3) rst, cken i sw0 i to je to Kako da assignujem ovo? Imas li ideju? Thanks!! [ bogdan.kecman @ 17.07.2013. 22:20 ] @
Mislim da ti treba neki manual sa osnovnim postavkama za vhdl/verilog i
za alat koji koristis (za xilinx je XISE, za druge neki drugi alati). U XISE-u se pravi UCF fajl u kome stoji koji pin je sta. E sad, ako ti ne napravis taj fajl on ce sam da assigneuje one pinove koji su mu "najlaksi" za rutiranje i to imas u finalnom izvestaju, ako su ti pinovi vec spojeni sa hw-om ili je tebi bitno sta je gde (da bi ti lakse rutirao) onda pravis UCF (za xilinx, za druge se fajl mozda drugacije zove). UCF iz tog primera izgleda ovako: nadam se da pomaze [ bogdan.kecman @ 17.07.2013. 22:31 ] @
btw, kreni odavde:
http://www.freerangefactory.org/dl/free_range_vhdl.pdf onda su ti dalje odlicne free knjige (svi linkovi su na free knjige, dakle autori su ih stavili on-line, nista piraterija): http://tams-www.informatik.uni...doc/cookbook/VHDL-Cookbook.pdf http://www.csee.umbc.edu/portal/help/VHDL/VHDL-Handbook.pdf http://users.ece.gatech.edu/sudha/book/starters-guide/ sad, mozda ti verilog bolje lezi od vhdl-a, sta znam, ja nijedan ni drugi ne znam dovoljno da mogu da ti dam neke prednosti i mane, meni licno oba rade ok, vhdl mi je malo logicniji (verilog previse lici na programski jezik a ti ne programiras elektroniku vec dizajniras gate-ove tako da "previse lici na programiranje" moze da bude velika mana) U svakom slucaju, ima i za verilog knjiga: http://www.freebookcentre.net/...cs/Verilog-Books-Download.html pogledaj obavezno http://www.angelfire.com/in/rajesh52/verilogvhdl.html [ darkominich @ 23.07.2013. 14:49 ] @
Ovako, prvo ces uraditi 14-bitni brojac, jer je 2^14=16384, zatim ces ga ograniciti da broji do 9999, posle toga normalno se vraca na nulu. Zatim je potrebno konvertovati binarne brojeve u decimalne. Da se ne bi maltretirao sa kolom za divide, a i radi manjeg utroska resursa, preporucujem ti http://en.wikipedia.org/wiki/Double_dabble (double dabble algorithm). Kasnije je potrebno brojeve konvetovati u 7-segment i obezbediti njihov ispis na LED displej. Takodje nisi rekao na koji vremenski interval bi se vrsile izmene cifara, pretpostavljam na jednu sekundu? To treba obezbediti clock dividerom. Ako ti treba pomoc oko koda ili logike, mozes mi se obratiti.
Copyright (C) 2001-2024 by www.elitesecurity.org. All rights reserved.
|