diff --git a/1ano/2semestre/lsd/pratica05/BasicWatch/BasicWatch.vhd b/1ano/2semestre/lsd/pratica05/BasicWatch/BasicWatch.vhd new file mode 100644 index 0000000..f6a0723 --- /dev/null +++ b/1ano/2semestre/lsd/pratica05/BasicWatch/BasicWatch.vhd @@ -0,0 +1,176 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; + +entity BasicWatch is + port(SW : in std_logic_vector(0 downto 0); + CLOCK_50 : in std_logic; + KEY : in std_logic_vector(3 downto 0); + HEX2 : out std_logic_vector(6 downto 0); + HEX3 : out std_logic_vector(6 downto 0); + HEX4 : out std_logic_vector(6 downto 0); + HEX5 : out std_logic_vector(6 downto 0); + HEX6 : out std_logic_vector(6 downto 0); + HEX7 : out std_logic_vector(6 downto 0); + LEDG : out std_logic_vector(8 downto 8)); +end BasicWatch; + +architecture Structural of BasicWatch is + + -- Global enable signal + signal s_enable : std_logic; + + -- Global reset signal + signal s_globalRst : std_logic; + + -- Individual reset for the seconds counters ('1' while setting min/hours) + signal s_sReset : std_logic; + + -- Control signals + signal s_mode : std_logic; -- s_mode='0'-normal operation; s_mode='1'-set min/hours + signal s_hSet : std_logic; -- s_hSet='1'-set (fast increment) hours + signal s_mSet : std_logic; -- s_mSet='1'-set (fast increment) minutes + + -- Base 4 Hz clock signal + signal s_clk4Hz : std_logic; + + -- Global enable (always '1' while setting min/hours; + -- otherwise always repeating '1', '0', '0', '0') + signal s_globalEnb : std_logic; + + -- Binary values of each counter + signal s_sUnitsBin, s_sTensBin : std_logic_vector(3 downto 0); + signal s_mUnitsBin, s_mTensBin : std_logic_vector(3 downto 0); + signal s_hUnitsBin, s_hTensBin : std_logic_vector(3 downto 0); + signal s_hUnitsMax : natural := 9; + + -- Terminal count flags of each counter + signal s_sUnitsTerm, s_sTensTerm : std_logic; + signal s_mUnitsTerm, s_mTensTerm : std_logic; + signal s_hUnitsTerm : std_logic; + + -- Enable signals of each counter + signal s_sUnitsEnb, s_sTensEnb : std_logic; + signal s_mUnitsEnb, s_mTensEnb : std_logic; + signal s_hUnitsEnb, s_hTensEnb : std_logic; + +begin + s_globalRst <= not KEY(3); + s_sReset <= s_globalRst or s_mode; + s_enable <= SW(0); + + s_mode <= not KEY(2); + s_hSet <= not KEY(1); + s_mSet <= not KEY(0); + + clk_div_4hz : entity work.ClkDividerN(RTL) + generic map(k => 12500000) + port map(clkIn => CLOCK_50, + clkOut => s_clk4Hz); + + clk_enb_gen : entity work.ClkEnableGenerator(RTL) + port map(clkIn4Hz => s_clk4Hz, + mode => s_mode, + clkEnable => s_globalEnb, + tick1Hz => LEDG(8)); + + s_sUnitsEnb <= '1'; + + s_units_cnt : entity work.Counter4Bits(RTL) + port map(MAX => 9, + reset => s_sReset, + clk => s_clk4Hz, + enable1 => s_globalEnb, + enable2 => s_sUnitsEnb, + valOut => s_sUnitsBin, + termCnt => s_sUnitsTerm); + + s_sTensEnb <= s_sUnitsTerm; + + s_tens_cnt : entity work.Counter4Bits(RTL) + port map(MAX => 5, + reset => s_sReset, + clk => s_clk4Hz, + enable1 => s_globalEnb, + enable2 => s_sTensEnb, + valOut => s_sTensBin, + termCnt => s_sTensTerm); + + s_mUnitsEnb <= ((s_sTensTerm and s_sUnitsTerm) and not s_mode) or + (s_mode and s_mSet); + + m_units_cnt : entity work.Counter4Bits(RTL) + port map(MAX => 9, + reset => s_globalRst, + clk => s_clk4Hz, + enable1 => s_globalEnb, + enable2 => s_mUnitsEnb, + valOut => s_mUnitsBin, + termCnt => s_mUnitsTerm); + + s_mTensEnb <= (s_mUnitsTerm and s_mUnitsEnb); + + m_tens_cnt : entity work.Counter4Bits(RTL) + port map(MAX => 5, + reset => s_globalRst, + clk => s_clk4Hz, + enable1 => s_globalEnb, + enable2 => s_mTensEnb, + valOut => s_mTensBin, + termCnt => s_mTensTerm); + + s_hUnitsEnb <= ((s_mTensTerm and s_mTensEnb) and not s_mode) or + (s_mode and s_hSet); + + s_hUnitsMax <= 3 when (s_hTensBin = "0010") else 9; + + h_units_cnt : entity work.Counter4Bits(RTL) + port map(MAX => s_hUnitsMax, + reset => s_globalRst, + clk => s_clk4Hz, + enable1 => s_globalEnb, + enable2 => s_hUnitsEnb, + valOut => s_hUnitsBin, + termCnt => s_hUnitsTerm); + + s_hTensEnb <= (s_hUnitsTerm and s_hUnitsEnb); + + h_tens_cnt : entity work.Counter4Bits(RTL) + port map(MAX => 2, + reset => s_globalRst, + clk => s_clk4Hz, + enable1 => s_globalEnb, + enable2 => s_hTensEnb, + valOut => s_hTensBin, + termCnt => open); + + s_units_decod : entity work.Bin7SegDecoder(RTL) + port map(enable => s_enable, + binInput => s_sUnitsBin, + decOut_n => HEX2); + + s_tens_decod : entity work.Bin7SegDecoder(RTL) + port map(enable => s_enable, + binInput => s_sTensBin, + decOut_n => HEX3); + + m_units_decod : entity work.Bin7SegDecoder(RTL) + port map(enable => s_enable, + binInput => s_mUnitsBin, + decOut_n => HEX4); + + m_tens_decod : entity work.Bin7SegDecoder(RTL) + port map(enable => s_enable, + binInput => s_mTensBin, + decOut_n => HEX5); + + h_units_decod : entity work.Bin7SegDecoder(RTL) + port map(enable => s_enable, + binInput => s_hUnitsBin, + decOut_n => HEX6); + + h_tens_decod : entity work.Bin7SegDecoder(RTL) + port map(enable => s_enable, + binInput => s_hTensBin, + decOut_n => HEX7); +end Structural; diff --git a/1ano/2semestre/lsd/pratica05/BasicWatch/Bin7SegDecoder.vhd b/1ano/2semestre/lsd/pratica05/BasicWatch/Bin7SegDecoder.vhd new file mode 100644 index 0000000..bf0c9c4 --- /dev/null +++ b/1ano/2semestre/lsd/pratica05/BasicWatch/Bin7SegDecoder.vhd @@ -0,0 +1,35 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; + +entity Bin7SegDecoder is + port(enable : in std_logic; + binInput : in std_logic_vector(3 downto 0); + decOut_n : out std_logic_vector(6 downto 0)); +end Bin7SegDecoder; + +architecture RTL of Bin7SegDecoder is + + signal s_decOut_n : std_logic_vector(6 downto 0); + +begin + with binInput select + s_decOut_n <= "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 + + decOut_n <= s_decOut_n when (enable = '1') else + "0111111"; +end RTL; diff --git a/1ano/2semestre/lsd/pratica05/BasicWatch/ClkDividerN.vhd b/1ano/2semestre/lsd/pratica05/BasicWatch/ClkDividerN.vhd new file mode 100644 index 0000000..00cd9d6 --- /dev/null +++ b/1ano/2semestre/lsd/pratica05/BasicWatch/ClkDividerN.vhd @@ -0,0 +1,32 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; + +entity ClkDividerN is + generic(k : natural); + port(clkIn : in std_logic; + clkOut : out std_logic); +end ClkDividerN; + +architecture RTL of ClkDividerN is + + signal s_divCounter : natural; + +begin + assert(K >= 2); + + process(clkIn) + begin + if (rising_edge(clkIn)) then + if (s_divCounter = k - 1) then + clkOut <= '0'; + s_divCounter <= 0; + else + if (s_divCounter = (k / 2 - 1)) then + clkOut <= '1'; + end if; + s_divCounter <= s_divCounter + 1; + end if; + end if; + end process; +end RTL; diff --git a/1ano/2semestre/lsd/pratica05/BasicWatch/ClkEnableGenerator.vhd b/1ano/2semestre/lsd/pratica05/BasicWatch/ClkEnableGenerator.vhd new file mode 100644 index 0000000..2c0d307 --- /dev/null +++ b/1ano/2semestre/lsd/pratica05/BasicWatch/ClkEnableGenerator.vhd @@ -0,0 +1,29 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; + +entity ClkEnableGenerator is + port(clkIn4Hz : in std_logic; + mode : in std_logic; + clkEnable : out std_logic; + tick1Hz : out std_logic); +end ClkEnableGenerator; + +architecture RTL of ClkEnableGenerator is + + signal s_counter : unsigned(1 downto 0); + +begin + process(clkIn4Hz) + begin + if (rising_edge(clkIn4Hz)) then + s_counter <= s_counter + 1; + end if; + end process; + + clkEnable <= '1' when (mode ='1') else + '1' when (mode ='0') and (s_counter = "00") else + '0'; + + tick1Hz <= s_counter(1); +end RTL; diff --git a/1ano/2semestre/lsd/pratica05/BasicWatch/Counter4Bits.vhd b/1ano/2semestre/lsd/pratica05/BasicWatch/Counter4Bits.vhd new file mode 100644 index 0000000..45bd67a --- /dev/null +++ b/1ano/2semestre/lsd/pratica05/BasicWatch/Counter4Bits.vhd @@ -0,0 +1,43 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; + +entity Counter4Bits is + port(MAX : natural := 9; + reset : in std_logic; + clk : in std_logic; + enable1 : in std_logic; + enable2 : in std_logic; + valOut : out std_logic_vector(3 downto 0); + termCnt : out std_logic); +end Counter4Bits; + +architecture RTL of Counter4Bits is + + signal s_value : unsigned(3 downto 0); + +begin + process(reset, clk) + begin + if (rising_edge(clk)) then + if (reset = '1') then + s_value <= (others => '0'); + termCnt <= '0'; + elsif ((enable1 = '1') and (enable2 = '1')) then + if (to_integer(s_value) = MAX) then + s_value <= (others => '0'); + termCnt <= '0'; + else + s_value <= s_value + 1; + if (to_integer(s_value) = MAX - 1) then + termCnt <= '1'; + else + termCnt <= '0'; + end if; + end if; + end if; + end if; + end process; + + valOut <= std_logic_vector(s_value); +end RTL; diff --git a/1ano/2semestre/lsd/pratica05/BasicWatch/output_files/BasicWatch.sof b/1ano/2semestre/lsd/pratica05/BasicWatch/output_files/BasicWatch.sof new file mode 100644 index 0000000..ba81490 Binary files /dev/null and b/1ano/2semestre/lsd/pratica05/BasicWatch/output_files/BasicWatch.sof differ