Saturday, 29 July 2017

VHDL frequency counter square wave signal with seven segment display Xilinx spartan 3 development board implementation


FILES DOWNLOAD

FSM master control
 library IEEE;  
 use IEEE.STD_LOGIC_1164.ALL;  
 use IEEE.numeric_std.ALL;  
 entity low_freq_counter is  
  port (  
 clk, reset: in std_logic;  
 start : in std_logic;  
 si: in std_logic;  
 bcd3, bcd2, bcd1 , bcd0 : out std_logic_vector (3 downto 0 );  
 an: out std_logic_vector (3 downto 0) ;-- to enable cathode   
 sseg : out std_logic_vector ( 7 downto 0)-- display  
 ) ;  
 end low_freq_counter;  
 architecture arch of low_freq_counter is  
 type state_type is (idle, count, frq, b2b);  
 signal state_reg, state_next : state_type;  
 signal prd: std_logic_vector (9 downto 0 ) ;  
 signal dvsr , dvnd, quo : std_logic_vector (19 downto 0) ;  
 signal prd_start , div_start , b2b_start : std_logic;  
 signal prd_done_tick , div_done_tick , b2b_done_tick : std_logic;  
 signal to_sseg3,to_sseg2,to_sseg1,to_sseg0 : std_logic_vector (3 downto 0) ;  
 begin  
 bcd3<=to_sseg3;  
 bcd2<=to_sseg2;  
 bcd1<=to_sseg1;  
 bcd0<=to_sseg0;  
 --_._._._._._._._.._._._._._._._._._.._._._._._._._._._._.._._._._._._._._._.._._.-.--.-.--.-.- -  
 -- component i n s t a n t i a t i o n  
 --.- ._.-..-._.-.._.-._..-.-.._.-.-..-._.-.._.-..-.-.-.-.-.-.-.-.-.-..-.-.-.-.-.-.-.-.-. ---------  
  -- i n s t a n t i a t e p e r i o d c o u n t e r  
 prd_count_unit: entity work.period_counter  
 port map(clk=>clk, reset=>reset , start=>prd_start , si=>si,  
 ready=>open, done_tick=>prd_done_tick , prd=>prd);  
 --i n s t a n t i a t e d i v is i o n c i r c u i t  
 div_unit : entity work.div  
 generic map(W=>20, CBIT => 5 )  
 port map(clk=>clk, reset=>reset , start=>div_start ,  
 dvsr=>dvsr , dvnd=>dvnd, quo=>quo, rmd=>open,  
 ready=>open, done_tick=>div_done_tick);  
 -- i n s t a n t i a t e  
 bin2bcd_unit : entity work.bin2bcd  
 port map  
 --b i n a r y - t o -BCD c o n v e r t o r  
 (clk=>clk, reset=>reset , start=>b2b_start,  
 bin=>quo (12 downto 0) , ready=>open,  
 done_tick=>b2b_done_tick,  
 bcd3=>to_sseg3, bcd2=>to_sseg2, bcd1=>to_sseg1, bcd0=>to_sseg0);  
 -- 7 seg display   
 disp_unit : entity work.disp_hex_mux -- display module with hexadecimal values port map   
 port map(  
 clk=>clk, reset=>'0', -- clear and reset  
 hex3=>to_sseg3 , hex2=>to_sseg2, --last display disabled set to 0000  
 hex1=>to_sseg1 , hex0=>to_sseg0,   
 dp_in=>"0111" , an=>an, sseg=>sseg) ; --place to put the decimal point  
 -- s i g n a l w i d t h e x t e n s i o n  
 dvnd <= std_logic_vector ( to_unsigned ( 1000000,20) );  
 dvsr <= "0000000000" & prd;  
 --  
 -- m a s t e r FSM  
 process ( clk , reset )  
 begin  
 if reset = '1' then  
 state_reg <= idle ;  
 elsif ( clk'event and clk = '1' ) then  
 state_reg <= state_next ;  
 end if ;  
 end process ;  
 process ( state_reg , start ,  
 prd_done_tick,div_done_tick,b2b_done_tick)  
 begin  
 state_next <= state_reg ;  
 prd_start <= '0' ;  
 div_start <= '0' ;  
 b2b_start <= '0' ;  
 case state_reg is  
 when idle =>  
 if start = '1' then  
 state_next <= count ;  
 prd_start <='1';  
 end if ;  
 when count =>  
 if ( prd_done_tick = '1' ) then  
 div_start <= '1' ;  
 state_next <= frq ;  
 end if ;  
 when frq=>  
 if ( div_done_tick = '1' ) then  
 b2b_start <= '1' ;  
 state_next <= b2b ;  
 end if ;  
 when b2b =>  
 if ( b2b_done_tick = '1') then  
 state_next <= idle ;  
 end if ;  
 end case ;  
 end process ;  
 end arch;  



PERIOD COUNTER MODULE
 library IEEE;  
 use IEEE.STD_LOGIC_1164.ALL;  
 use IEEE.numeric_std.ALL;  
 entity period_counter is  
 port (  
 clk , reset : in std_logic ;  
 start , si : in std_logic ;  
 ready , done_tick : out std_logic ;  
 prd : out std_logic_vector ( 9 downto 0)  
 );  
 end period_counter ;  
 architecture arch of period_counter is  
 constant CLK_MS_COUNT: integer := 3003; -- 1 ms t i c k  my clock speed 3Mhz period 3.33x10e-7 -------- so we want 3.33x10e-7 (x)= 1 ms  
 type state_type is ( idle , waite , count , done ) ;  
 signal state_reg , state_next : state_type ;  
 signal t_reg , t_next : unsigned (15 downto 0 ) ;  
 signal p_reg , p_next : unsigned ( 9 downto 0) ;  
 signal delay_reg : std_logic ;  
 signal edge : std_logic ;  
 begin  
 --s t a t e and d a t a r e g is t e r  
 process ( clk , reset )  
 begin  
 if reset = '1' then  
 state_reg <= idle ;  
 t_reg <= ( others => '0' ) ;  
 p_reg <= ( others => '0' ) ;  
 delay_reg <= '0' ;  
 elsif ( clk'event and clk = '1' ) then  
 state_reg <= state_next ;  
 t_reg <= t_next ;  
 p_reg <= p_next ;  
 delay_reg <= si ;  
 end if ;  
 end process ;  
 -- edge d e t e c t i o n c i r c u i t  
 edge <= ( not delay_reg ) and si ;  
 -- f s m d n e x t - s t a t e l o g i c / d a t a p a t h o p e r a t i o n s  
 process ( start , edge , state_reg , t_reg , t_next , p_reg )  
 begin  
 ready <= '0' ;  
 done_tick <= '0' ;  
 state_next <= state_reg ;  
 p_next <= p_reg ;  
 t_next <= t_reg ;  
 case state_reg is  
 when idle =>  
 ready <= '1' ;  
 if ( start = '1' ) then  
 state_next <= waite ;  
 end if ;  
 when waite => -- w a i t for t h e f i r s t edge  
 if ( edge = '1' ) then  
 state_next <= count ;  
 t_next <= ( others => '0' ) ;  
 p_next <= ( others => '0' ) ;  
 end if ;  
 when count =>  
 if ( edge = '1' ) then -- 2 n d edge a r r i v e d  
 state_next <= done ;  
 else -- o t h e r w i s e count  
 if (t_reg = CLK_MS_COUNT-1) then -- l m s t i c k  
 t_next <= ( others => '0' ) ;  
 p_next <= p_reg + 1;  
 else  
 t_next <= t_reg + 1;  
 end if ;  
 end if ;  
 when done =>  
 done_tick <= '1' ;  
 state_next <= idle ;  
 end case ;  
 end process ;  
 prd <= std_logic_vector(p_reg);  
 end arch ;  

DIVISION MODULE
 Library ieee ;  
 use ieee.std_logic_1164.all;  
 use ieee.numeric_std.all;  
 entity div is  
 generic (  
 W:integer:=8;  
 CBIT:integer:=4 -- CBIT=log2 (W)+l  
 ) ;  
 port (  
 clk,reset:in std_logic;  
 start : in std_logic;  
 dvsr , dvnd : in std_logic_vector (W-1 downto 0 ) ;  
 ready , done_tick : out std_logic;  
 quo , rmd: out std_logic_vector (W-1 downto 0)  
 ) ;  
 end div ;  
 architecture arch of div is  
 type state_type is ( idle , op , last , done ) ;  
 signal state_reg , state_next : state_type ;  
 signal rh_reg , rh_next : unsigned(W-1 downto 0) ;  
 signal rl_reg , rl_next : std_logic_vector (W-1 downto 0) ;  
 signal rh_tmp : unsigned(W - 1 downto 0) ;  
 signal d_reg , d_next : unsigned(W - 1 downto 0 ) ;  
 signal q_bit : std_logic;  
 signal n_reg , n_next : unsigned (CBIT - 1 downto 0) ;  
 begin  
 -- f s m d s t a t e a n d d a t a r e g is t e r s  
 process ( clk , reset )  
 begin  
 if reset = '1' then  
 state_reg <= idle ;  
 rh_reg <= ( others => '0' ) ;  
 rl_reg <= ( others => '0' ) ;  
 d_reg <= ( others => '0' ) ;  
 n_reg <= ( others => '0' ) ;  
 elsif (clk'event and clk='1') then  
 state_reg <= state_next ;  
 rh_reg <= rh_next ;  
 rl_reg <= rl_next ;  
 d_reg <= d_next ;  
 n_reg <= n_next ;  
 end if ;  
 end process ;  
 -- f s m d n e x t - s t a t e l o g i c and d a t a p a t h l o g i c  
 process ( state_reg , n_reg , rh_reg , rl_reg , d_reg ,  
 start , dvsr , dvnd , q_bit , rh_tmp , n_next )  
 begin  
 ready <= '0' ;  
 done_tick <= '0' ;  
 state_next <= state_reg ;  
 rh_next <= rh_reg ;  
 rl_next <= rl_reg ;  
 d_next <= d_reg ;  
 n_next <= n_reg ;  
 case state_reg is  
 when idle =>  
 ready <= '1';  
 if start = '1' then  
 rh_next <= ( others => '0' ) ;  
 rl_next <= dvnd ; --div i d e n d  
 d_next <= unsigned ( dvsr ) ; --div is o r  
 n_next <= to_unsigned ( W + 1 , CBIT); -- i n d e x  
 state_next <= op ;  
 end if ;  
 when op =>  
 --shift r h and r l left  
 rl_next <= rl_reg ( W - 2 downto 0 ) & q_bit ;  
 rh_next <= rh_tmp(W-2 downto 0 ) & rl_reg ( W - 1 ) ;  
 -- d e c r e a s e i n d e x  
 n_next <= n_reg - 1;  
 if ( n_next = 1 ) then  
 state_next <= last ;  
 end if ;  
 when last =>  
 rl_next <= rl_reg ( W - 2 downto 0 ) & q_bit ;  
 rh_next <= rh_tmp ;  
 state_next <= done ;  
  -- last i t e r a t i o n  
 when done =>  
 state_next <= idle ;  
 done_tick <= '1' ;  
 end case ;  
 end process ;  
 --compare and s u b t r a c t  
 process ( rh_reg , d_reg )  
 begin  
 if rh_reg >= d_reg then  
 rh_tmp <= rh_reg - d_reg ;  
 q_bit <= '1' ;  
 else  
 rh_tmp <= rh_reg;  
 q_bit <= '0' ;  
 end if ;  
 end process ;  
 --o u t p u t  
 quo <= rl_reg;  
 rmd <= std_logic_vector (rh_reg) ;  
 end arch;  

BINARY TO BCD CONVERSION MODULE

 library IEEE;  
 use IEEE.STD_LOGIC_1164.ALL;  
 use ieee. numeric_std.all ;  
 entity bin2bcd is  
 port (  
 clk: in std_logic;  
 reset : in std_logic;  
 start : in std_logic ;  
 bin: in std_logic_vector (12 downto 0) ;  
 bcd3,bcd2,bcd1,bcd0: out std_logic_vector( 3 downto 0);  
 ready, done_tick: out std_logic   
 ) ;  
 end bin2bcd ;  
 architecture arch of bin2bcd is  
 type state_type is (idle, op, done);  
 signal state_reg , state_next : state_type;  
 signal p2s_reg, p2s_next: std_logic_vector (12 downto 0 ) ;  
 signal n_reg , n_next : unsigned (3 downto 0) ;  
 signal bcd3_reg, bcd2_reg, bcd1_reg, bcd0_reg:unsigned (3 downto 0 ) ;  
 signal bcd3_next, bcd2_next, bcd1_next , bcd0_next :unsigned (3 downto 0) ;  
 signal bcd3_tmp ,bcd2_tmp, bcd1_tmp, bcd0_tmp:unsigned (3 downto 0) ;  
 begin  
 -- s t a t e and d a t a r e g is t e r s  
 process (clk , reset)  
 begin  
 if reset='1' then  
 state_reg <= idle;  
 p2s_reg <= ( others => '0' ) ;  
 n_reg <= ( others => '0' ) ;  
 bcd3_reg <= ( others => '0' ) ;  
 bcd2_reg <= ( others => '0' ) ;  
 bcd1_reg <= ( others => '0' ) ;  
 bcd0_reg <= ( others => '0' ) ;  
 elsif (clk'event and clk= '1') then  
 state_reg <= state_next;  
 p2s_reg <= p2s_next ;  
 n_reg <= n_next;  
 bcd3_reg <= bcd3_next ;  
 bcd2_reg <= bcd2_next ;  
 bcd1_reg <= bcd1_next;  
 bcd0_reg <= bcd0_next ;--elsif (clk'event and clk= '1') then  
 end if ;  
 end process ;  
 -- f s m d n e x t - s t a t e l o g i c / d a t a p a t h o p e r a t i o n s  
 process (state_reg ,start ,p2s_reg ,n_reg ,n_next,bin,bcd0_reg,bcd1_reg,bcd2_reg,bcd3_reg,bcd0_tmp,bcd1_tmp,bcd2_tmp,bcd3_tmp)  
 begin  
 state_next <= state_reg;  
 ready <= '0' ;  
 done_tick <= '0' ;  
 p2s_next <= p2s_reg;  
 bcd0_next <= bcd0_reg;  
 bcd1_next <= bcd1_reg;  
 bcd2_next <= bcd2_reg;  
 bcd3_next <= bcd3_reg;  
 n_next <= n_reg;  
 case state_reg is  
 when idle =>  
 ready <= '1' ;  
 if start='1' then  
 state_next <= op;  
 bcd3_next <= ( others => '0' ) ;  
 bcd2_next <= ( others => '0' ) ;  
 bcd1_next <= ( others => '0' ) ;  
 bcd0_next <= ( others => '0' ) ;  
 n_next <= "1101" ; -- i n d e x  
 p2s_next <= bin; -- i n p u t s h if t r e g is t e r  
 state_next <= op;  
 end if ;  
 when op =>  
 -- s h if t i n b i n a r y b i i  
 p2s_next <= p2s_reg(11 downto 0 ) & '0' ;  
 -- s h if t 4 BCD d i g i t s  
 bcd0_next <= bcd0_tmp (2 downto 0) & p2s_reg (12) ;  
 bcd1_next <= bcd1_tmp (2 downto 0) & bcd0_tmp (3) ;  
 bcd2_next <= bcd2_tmp (2 downto 0) & bcd1_tmp (3) ;  
 bcd3_next <= bcd3_tmp (2 downto 0) & bcd2_tmp (3) ;  
 n_next <= n_reg - 1;  
 if (n_next=0) then  
 state_next <= done;  
 end if ;  
 when done =>  
 state_next <= idle;  
 done_tick <= '1';  
 end case;  
 end process ;  
 -- d a t a p a t h f u n c t i o n u n i t s  
 -- f o u r BCD a d j u s t m e n t c i r c u i t s  
 bcd0_tmp <= bcd0_reg + 3 when bcd0_reg > 4 else  
 bcd0_reg ;  
 bcd1_tmp <= bcd1_reg + 3 when bcd1_reg > 4 else  
 bcd1_reg ;  
 bcd2_tmp <= bcd2_reg + 3 when bcd2_reg > 4 else  
 bcd2_reg;  
 bcd3_tmp <= bcd3_reg + 3 when bcd3_reg > 4 else  
 bcd3_reg;  
 -- o u t p u t  
 bcd0 <= std_logic_vector(bcd0_reg);  
 bcd1 <= std_logic_vector(bcd1_reg);  
 bcd2 <= std_logic_vector(bcd2_reg ) ;  
 bcd3 <= std_logic_vector(bcd3_reg);  
 end arch;  



SEVEN SEGMENT DISPLAY MODULE

 library ieee;  
 use ieee.std_logic_1164.all;  
 use ieee.numeric_std.all ;  
 entity disp_hex_mux is  
 port(  
 clk, reset: in std_logic;  
 hex3, hex2, hex1 ,hex0 : in std_logic_vector (3 downto 0 ) ;  
 dp_in : in std_logic_vector (3 downto 0) ;  
 an: out std_logic_vector (3 downto 0) ;  
 sseg : out std_logic_vector ( 7 downto 0)  
 );  
 end disp_hex_mux ;  
 architecture arch of disp_hex_mux is  
 -- each 7 - s e g l e d enabled ( 2 ^ 3 / 4 ) * 2 . 5 n s 3Mhz /2^x=800Hz solve and x=11.87 but seems to work better at x=9  
 constant N: integer :=9;-- time we want the display to hold on visible was 3 qorked with fifo buffer before, change it to 18  
 signal q_reg , q_next : unsigned (N-1 downto 0) ;  
 signal sel : std_logic_vector (1 downto 0) ;  
 signal hex: std_logic_vector (3 downto 0) ;  
 signal dp: std_logic;  
 begin  
 -- register to switch between cathodes  
 process (clk , reset)  
 begin  
 if reset='1' then  
 q_reg <= ( others => '0' ) ;  
 elsif (clk'event and clk='1') then  
 q_reg <= q_next;  
 end if ;  
 end process;  
 -- n e x t - s t a t e l o g i c for t h e c o u n t e r  
 q_next <= q_reg + 1 ;  
 -- 2 MSBs o f c o u n t e r t o c o n t r o l 4 - t o - l m u l t i p l e x in g  
 sel <= std_logic_vector (q_reg(N-1 downto N-2)) ;  
 process (sel , hex0 , hex1 , hex2, hex3, dp_in)  
 begin --seven segment display multiplexed  
 case sel is  
 when "00" =>  
 an <= "0001" ;  
 hex <= hex0;  
 dp <= dp_in(0);  
 when "01" =>  
 an <= "0010" ;  
 hex <= hex1;  
 dp <= dp_in(1);  
 when "10" =>  
 an <= "0100" ;  
 hex <= hex2;  
 dp <= dp_in(2);  
 when others =>  
 an <= "1000" ;  
 hex <= hex3;  
 dp <= dp_in(3);  
 end case ;  
 end process;  
 --hex - t o - 7- s e g in e IZ t I e d decoding  
 -- Use a with-select statement to light up relevant LEDs   
      -------------------------------------------------  
      -- Encoder   
      -------------------------------------------------  
      -- HEX-to-seven-segment decoder   
      -- segment encoding   
      --   0   
      --   ---   
      -- 5 |  | 1  
      --   --- <------6  
      -- 4 |  | 2  
      --   ---   
      --   3  
 with hex select --6542130  
 sseg(6 downto 0)<=  
                               "1000000" when "0000",--0  
                               "1110011" when "0001",--1  
                               "0101000" when "0010",--2  
                               "0110000" when "0011",--3  
                               "0010011" when "0100",--4  
                               "0010100" when "0101",--5  
                               "0000100" when "0110",--6  
                               "1110010" when "0111",--7  
                               "0000000" when "1000",--8  
                               "0010000" when "1001",--9  
                               "0000010" when "1010",--a  
                               "0000101" when "1011",--b  
                               "0101101" when "1100",--c  
                               "0100001" when "1101",--d  
                               "0001110" when "1110",--e  
                               "0001110" when others;--f  
 --d e c i m a l p o in t  
 sseg(7) <= dp;  
 end arch;  

CONSTRAINT FILE
 NET "clk" LOC = "P54" ;  
 #8I/Os_2 (Input)  
 NET "reset" LOC = "p94" ;  
 NET "start" LOC = "p93" ;  
 NET "si" LOC = "p86" ;  
 #16I/Os_1 (output)  
 NET "bcd0[0]" LOC = "p126" ;  
 NET "bcd0[1]" LOC = "p125" ;  
 NET "bcd0[2]" LOC = "p124" ;  
 NET "bcd0[3]" LOC = "p123" ;  
 NET "bcd1[0]" LOC = "p122" ;  
 NET "bcd1[1]" LOC = "p117" ;  
 NET "bcd1[2]" LOC = "p116" ;  
 NET "bcd1[3]" LOC = "p113" ;  
 NET "bcd2[0]" LOC = "p112" ;  
 NET "bcd2[1]" LOC = "p106" ;  
 NET "bcd2[2]" LOC = "p105" ;  
 NET "bcd2[3]" LOC = "p104" ;  
 NET "bcd3[0]" LOC = "p103" ;  
 NET "bcd3[1]" LOC = "p98" ;  
 NET "bcd3[2]" LOC = "p97" ;  
 NET "bcd3[3]" LOC = "p96" ;  
 #8I/Os_2 (Input)  
 NET "an[0]" LOC = "p71" ;  
 NET "an[1]" LOC = "p75" ;  
 NET "an[2]" LOC = "p77" ;  
 NET "an[3]" LOC = "p82" ;  
 #16I/Os_2  
 NET "sseg[7]" LOC = "p60"  ;  
 NET "sseg[6]" LOC = "p63"  ;  
 NET "sseg[5]" LOC = "p67" ;  
 NET "sseg[4]" LOC ="p70"  ;  
 NET "sseg[3]" LOC ="p74" ;  
 NET "sseg[3]" LOC = "p76" ;  
 NET "sseg[2]" LOC = "p81"  ;  
 NET "sseg[0]" LOC = "p83" ;  

TUTORIAL ON HOW TO ADD CLOCK TIMING CONSTRAINTS IN A MODULE

No comments:

Post a Comment