--Program for Programmable Interval Timer.. library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity code_8253 is port ( clk0: in STD_LOGIC; clk1: in STD_LOGIC; clk2: in STD_LOGIC; clk: in STD_LOGIC; reset: in STD_LOGIC; gate0: in STD_LOGIC; gate1: in STD_LOGIC; gate2: in STD_LOGIC; a0: in STD_LOGIC; a1: in STD_LOGIC; cs_n: in STD_LOGIC; rd_n: in STD_LOGIC; wr_n: in STD_LOGIC; out0: out STD_LOGIC; out1: out STD_LOGIC; out2: out STD_LOGIC; data: inout STD_LOGIC_vector (7 downto 0) ); end code_8253; architecture code_8253_arch of code_8253 is signal load0 : std_logic; signal load1 : std_logic; signal load2 : std_logic; signal read0 : std_logic; signal read1 : std_logic; signal read2 : std_logic; signal loadmw : std_logic; signal noop : std_logic; signal count_latch : std_logic; signal lsb : std_logic; signal msb : std_logic; signal mode : std_logic_vector (2 downto 0); signal bcd_binary : std_logic; signal rd_wr_int : std_logic_vector (4 downto 0); signal mode_word : std_logic_vector (7 downto 0); signal sel_cnt0 : std_logic; signal sel_cnt1 : std_logic; signal sel_cnt2 : std_logic; signal sc : std_logic_vector (1 downto 0); signal rl : std_logic_vector (1 downto 0); signal mode_cw : std_logic_vector (2 downto 0); signal count0 : std_logic_vector (15 downto 0); signal count1 : std_logic_vector (15 downto 0); signal count2 : std_logic_vector (15 downto 0); begin rd_wr_int <=(cs_n & rd_n & wr_n & a0 & a1); --process for decoding read/write operatioon process (rd_wr_int) begin case rd_wr_int is when "01000" => load0 <= '1';load1 <= '0';load2 <= '0';loadmw <= '0';read0 <= '0';read1 <= '0'; read2 <= '0';noop <= '0'; when "01001" => load0 <= '0';load1 <= '1';load2 <= '0';loadmw <= '0';read0 <= '0';read1 <= '0'; read2 <= '0';noop <= '0'; when "01010" => load0 <= '0';load1 <= '0';load2 <= '1';loadmw <= '0';read0 <= '0';read1 <= '0'; read2 <= '0';noop <= '0'; when "01011" => load0 <= '0';load1 <= '0';load2 <= '0';loadmw <= '1';read0 <= '0';read1 <= '0'; read2 <= '0';noop <= '0'; when "00100" => load0 <= '0';load1 <= '0';load2 <= '0';loadmw <= '0';read0 <= '1';read1 <= '0'; read2 <= '0';noop <= '0'; when "00101" => load0 <= '0';load1 <= '0';load2 <= '0';loadmw <= '0';read0 <= '0';read1 <= '1'; read2 <= '0';noop <= '0'; when "00110" => load0 <= '0';load1 <= '0';load2 <= '0';loadmw <= '0';read0 <= '0';read1 <= '0'; read2 <= '1';noop <= '0'; when others => load0 <= '0';load1 <= '0';load2 <= '0';loadmw <= '0';read0 <= '0';read1 <= '0'; read2 <= '0';noop <= '1'; end case; end process; -- process for loading the mode word process (clk, reset) begin if (reset ='1') then mode_word <= (others => '0'); elsif (clk'event and clk= '1') then if (loadmw = '1') then mode_word <= data; end if; end if; end process; sc <= (mode_word(7) & mode_word(6)); rl <= (mode_word(5) & mode_word(4)); mode_cw <= (mode_word(3) & mode_word(2) & mode_word(1)); bcd_binary <= mode_word(0); --process for decoding the control word process(sc, rl, mode_cw) begin case sc is when "00" => sel_cnt0 <= '1';sel_cnt1 <= '0';sel_cnt2 <= '0'; when "01" => sel_cnt0 <= '0';sel_cnt1 <= '1';sel_cnt2 <= '0'; when "10" => sel_cnt0 <= '0';sel_cnt1 <= '0';sel_cnt2 <= '1'; when others => sel_cnt0 <= '0';sel_cnt1 <= '0';sel_cnt2 <= '0'; end case; if (rl = "00") then count_latch <= '1'; else count_latch <= '0'; end if; lsb <= rl(0); msb <= rl(1); case mode_cw is when "000" => mode <= "000"; when "001" => mode <= "001"; when "010" => mode <= "010"; when "011" => mode <= "011"; when "100" => mode <= "100"; when "101" => mode <= "101"; when "110" => mode <= "110"; when "111" => mode <= "111"; when others => mode <= "000"; end case; end process; --process for actual counter [counter0] process (clk0, reset) begin if (reset = '1') then count0 <= (others => '0'); elsif (clk0'event and clk0= '1') then if (load0 = '1') then if (lsb = '1') then count0( 7 downto 0) <= data; end if; if (msb = '1') then count0 ( 15 downto 8) <= data; end if; else if (mode = "000") then if (gate0 = '1') then count0 <= count0 - 1; end if; end if; end if; end if; end process; out0 <= '1' when count0 = "0000000000000000" else '0'; --process for actual counter [counter1] process (clk1, reset) begin if (reset = '1') then count1 <= (others => '0'); elsif (clk1'event and clk1= '1') then if (load1 = '1') then if (lsb = '1') then count1( 7 downto 0) <= data; end if; if (msb = '1') then count1 ( 15 downto 8) <= data; end if; else if (mode = "000") then if (gate1 = '1') then count1 <= count1 - 1; end if; end if; end if; end if; end process; out1 <= '1' when count1 = "0000000000000000" else '0'; --process for actual counter [counter2] process (clk2, reset) begin if (reset = '1') then count2 <= (others => '0'); elsif (clk2'event and clk2= '1') then if (load2 = '1') then if (lsb = '1') then count2( 7 downto 0) <= data; end if; if (msb = '1') then count2 ( 15 downto 8) <= data; end if; else if (mode = "000") then if (gate2 = '1') then count2 <= count2 - 1; end if; end if; end if; end if; end process; out2 <= '1' when count2 = "0000000000000000" else '0'; end code_8253_arch; configuration code_8253_c of code_8253 is for code_8253_arch end for; end code_8253_c;