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