copyleft: gplv3 added and set repo to public
[calu.git] / cpu / src / extension_timer_b.vhd
1 --   `Deep Thought', a softcore CPU implemented on a FPGA
2 --
3 --  Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4 --  Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5 --  Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6 --  Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7 --  Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
8 --
9 --  This program is free software: you can redistribute it and/or modify
10 --  it under the terms of the GNU General Public License as published by
11 --  the Free Software Foundation, either version 3 of the License, or
12 --  (at your option) any later version.
13 --
14 --  This program is distributed in the hope that it will be useful,
15 --  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 --  GNU General Public License for more details.
18 --
19 --  You should have received a copy of the GNU General Public License
20 --  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
22 library IEEE;
23 use IEEE.std_logic_1164.all;
24 use IEEE.numeric_std.all;
25 use IEEE.STD_LOGIC_ARITH.ALL;
26 use IEEE.STD_LOGIC_UNSIGNED.ALL;
27
28 use work.common_pkg.all;
29 use work.core_pkg.all;
30
31
32 use work.mem_pkg.all;
33 use work.extension_pkg.all;
34 use work.extension_timer_pkg.all;
35
36 architecture behav of extension_timer is
37
38 signal w1_st_co, w1_st_co_nxt, w2_im_val, w2_im_val_nxt : gp_register_t;
39 signal w3_im_notused, w3_im_notused_nxt, w4_im_notused, w4_im_notused_nxt : gp_register_t;
40
41 begin
42
43 syn : process (clk, reset)
44 begin
45    if (reset = RESET_VALUE) then
46                         w1_st_co <= (others => '0');
47                         w2_im_val <= (others => '0');
48                         w3_im_notused <= (others => '0');
49                         w4_im_notused <= (others => '0');
50         elsif rising_edge(clk) then
51                         w1_st_co <= w1_st_co_nxt;
52                         w2_im_val <= w2_im_val_nxt;
53                         w3_im_notused <= w3_im_notused_nxt;
54                         w4_im_notused <= w4_im_notused_nxt;
55    end if;
56 end process syn;
57
58 -------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------
59
60 gwriten : process (ext_reg, w1_st_co, w2_im_val, w3_im_notused, w4_im_notused)
61 variable tmp_data : gp_register_t;
62 begin
63         w1_st_co_nxt <= w1_st_co;
64         w2_im_val_nxt <= w2_im_val;
65         w3_im_notused_nxt <= w3_im_notused;
66         w4_im_notused_nxt <= w4_im_notused;
67
68         -- timer logic
69         if (w1_st_co(0) = '1') then -- timer enabled?
70                 w2_im_val_nxt <= std_logic_vector(IEEE.numeric_std.unsigned(w2_im_val) + 1);
71                 -- n00b overflow (logic elements sparen...)
72                 if(w2_im_val(31) = '1') then 
73                         w1_st_co_nxt(16) <= '1';
74                 end if;
75         end if;
76
77         if ext_reg.sel = '1' and ext_reg.wr_en = '1' then
78                 tmp_data := (others =>'0');                     
79                 for i in 0 to 3 loop
80                         if ext_reg.byte_en(i) = '1' then
81                                 tmp_data(((i+1)*byte_t'length-1) downto i*byte_t'length) := ext_reg.data(((i+1)*byte_t'length-1) downto i*byte_t'length);
82                         end if;
83                 end loop;
84
85                 case ext_reg.addr(1 downto 0) is
86                 when "00" => -- status/config
87                         w1_st_co_nxt <= tmp_data;
88                 when "01" => -- timer value
89                         w2_im_val_nxt <= tmp_data;
90                 when "10" => null;
91                 when "11" => null;
92                 when others => null;
93                 end case;
94         end if;
95 end process gwriten;
96
97 gread : process (clk, ext_reg, w1_st_co, w2_im_val, w3_im_notused, w4_im_notused)
98 variable tmp_data : gp_register_t;
99 begin
100         tmp_data := (others => '0');
101         if ext_reg.sel = '1' and ext_reg.wr_en = '0' then
102                 case ext_reg.addr(1 downto 0) is
103                 when "00" => put_word_be(tmp_data, w1_st_co, ext_reg.byte_en);
104                 when "01" => put_word_be(tmp_data, w2_im_val, ext_reg.byte_en);
105                 when "10" => put_word_be(tmp_data, w3_im_notused, ext_reg.byte_en);
106                 when "11" => put_word_be(tmp_data, w4_im_notused, ext_reg.byte_en);
107                 when others => null;
108                 end case;
109         end if;
110         data_out <= tmp_data;
111 end process gread;
112
113 -------------------------- LESEN UND SCHREIBEN ENDE ---------------------------------------------------------------
114 -------------------------- INTERNE VERARBEITUNG ANFANG ------------------------------------------------------------
115 -------------------------- INTERNE VERARBEITUNG ENDE --------------------------------------------------------------
116 end behav;