-- OTAZKY ?????? -- 1. Jak porovnat 'counter = "1001"' aniz by se nemohl rozhodmout mezi redefinici v unsigned/1164? -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -- ENTITY ------------------------------ entity BCD_COUNTER is port ( CLK : in std_logic; CE : in std_logic; RESET : in std_logic; DIGIT : out std_logic_vector (3 downto 0); OVER : out std_logic ); end BCD_COUNTER; -- ARCHITECTURE ------------------------------ architecture BCD_COUNTER_ARCH of BCD_COUNTER is begin -- process ----------- BCD: process (CLK, CE, RESET) variable counter: std_logic_vector (3 downto 0) := "0000"; variable overflow: std_logic := '0'; -- func function IS9 (vect : std_logic_vector) return BOOLEAN is constant nine: std_logic_vector (3 downto 0) := "1001"; begin for i in 3 downto 0 loop if vect(i) /= nine(i) then return false; end if; end loop; return true; end IS9; begin if RESET = '1' then counter := "0000"; overflow := '0'; elsif CE = '1' and CLK'event and CLK = '1' then overflow := '0'; -- reset overflow, 1 clk period has passed since it was set -- Have we reached 9? (=> overflow & reset) if IS9(counter) then counter := "0000"; overflow := '1'; else -- counter is smaller than 9 (=> increment) counter := counter + 1; overflow := '0'; end if; -- if overlfow end if; -- distinguish signals -- output the result OVER <= overflow; DIGIT <= counter after 10 ns; end process BCD; end BCD_COUNTER_ARCH; -- ARCHITECTURE ------------------------------ -- stovky desitky jednotky -- |||| |||| |||| -- |||| |||| |||| -- +--++++--+ +--++++--+ +--++++--+ -- | DIGIT | +--+ | DIGIT | | DIGIT | -- | | |& |---+ | | | | ----|OVER2 CE|--| | +-|OVER1 CE|--+--|OVER0 CE|----- '1' -- | 2| | |-+ | 1| | | 0| -- +--^-----+ +--+ | +--^-----+ | +--^-----+ -- | | | | | -- | | | | | -- | +---------------+ | -- | | | -- +--------------------+--------------+----------- CLK -- BCD2 BCD1 BCD0 -- The design is not correct: when CE==0, -- either OVER0==1 until CE becomes 1 again (and the 0th counter switches from 9 to 0) -- or OVER0==1 until the falling edge of the clock pulse that caused it to become 9, thus -- the valid overflow is ignored by BCD1. -- There shall be CE2 = OVER1&CE0, CE1 = OVER0&CE0. library ieee; use ieee.std_logic_1164.all; entity TEST_BCD is end TEST_BCD; architecture TEST_BCD_ARCH of TEST_BCD is signal jednotky:std_logic_vector (3 downto 0); signal desitky :std_logic_vector (3 downto 0); signal stovky :std_logic_vector (3 downto 0); -- signal CLK : std_logic; signal CE0 : std_logic; signal CE2 : std_logic; -- = over0 and over1 signal RESET : std_logic; signal OVER0 : std_logic; signal OVER1 : std_logic; signal OVER2 : std_logic; component BCD_COUNTER port ( CLK : in std_logic; CE : in std_logic; RESET : in std_logic; DIGIT : out std_logic_vector (3 downto 0); OVER : out std_logic ); end component; begin jedn: BCD_COUNTER port map (CLK, CE0, RESET, jednotky, OVER0); des : BCD_COUNTER port map (CLK, OVER0, RESET, desitky, OVER1); sto : BCD_COUNTER port map (CLK, CE2, RESET, stovky, OVER2);-- CE2=over0&over1 GET_CE2: process (OVER0, OVER1) begin CE2 <= OVER0 and OVER1 after 5 ns; end process; P_CLK: process -- period T = 20 ns begin CLK <= '0'; wait for 15 ns; -- must be clk T > then delay of the AND (GET_CE2:) CLK <= '1'; wait for 5 ns; end process P_CLK; P_CE: process begin RESET<= '0'; CE0 <= '1'; -- initially on wait for 2 ms; -- stop counting after 009 reached CE0 <= '0'; wait for 70 ns; -- enable counting again CE0 <= '1'; end process P_CE; end TEST_BCD_ARCH;