]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/bus_tumbl.vhd
Multiple patches
[fpga/lx-cpu1/lx-rocon.git] / hw / bus_tumbl.vhd
1 library ieee;
2
3 use ieee.std_logic_1164.all;
4 use ieee.std_logic_arith.all;
5 use ieee.std_logic_unsigned.all;
6 use ieee.numeric_std.all;
7 use work.mbl_pkg.all;
8 use work.lx_rocon_pkg.all;
9
10 -- Connects tumbl to the Master CPU
11
12 entity bus_tumbl is
13         port
14         (
15                 -- Clock
16                 clk_i        : in std_logic;
17                 -- Chip enable
18                 ce_i         : in std_logic;
19                 -- Global Reset
20                 reset_i      : in std_logic;
21                 -- Master CPU bus for the memory
22     bls_i        : in std_logic_vector(3 downto 0);
23     address_i    : in std_logic_vector(11 downto 0);
24     data_i       : in std_logic_vector(31 downto 0);
25     data_o       : out std_logic_vector(31 downto 0);
26                 -- Tumbl extrenal memory bus
27                 xmemb_sel_o  : out std_logic;
28                 xmemb_i      : in DMEMB2CORE_Type;
29                 xmemb_o      : out CORE2DMEMB_Type
30   );
31 end bus_tumbl;
32
33 architecture Behavioral of bus_tumbl is
34         -- Types
35         type TUMBL_Input_Type is record
36                 halt       : std_logic;
37                 int        : std_logic;
38                 trace      : std_logic;
39                 trace_kick : std_logic;
40         end record;
41
42         type TUMBL_State_Type is record
43                 pc         : std_logic_vector(31 downto 0);
44                 halted     : std_logic;
45                 halt_code  : std_logic_vector(4 downto 0);
46         end record;
47
48         -- Reset
49         signal tumbl_reset_s : std_logic;
50         -- Internals
51         signal tumbl_input_s : TUMBL_Input_Type;
52         signal tumbl_state_s : TUMBL_State_Type;
53
54         -- Internal memory signals
55         signal imem_en_s     : std_logic;
56         signal dmem_en_s     : std_logic;
57
58         signal imem_we_s     : std_logic_vector(3 downto 0);
59         signal dmem_we_s     : std_logic_vector(3 downto 0);
60
61         signal imem_data_o_s : std_logic_vector(31 downto 0);
62         signal dmem_data_o_s : std_logic_vector(31 downto 0);
63
64         -- Internal bus structure
65         -- 12 address bits: 2 bits for selection, 10 bits for address
66         --
67         -- Selection:
68         -- 00 - imem
69         -- 01 - dmem
70         -- 10 - reserved
71         -- 11 - registers
72
73         -- Registers
74         -- 0x000
75         --
76         -- Bit 0: RW - Reset
77         -- Bit 1: RW - Interrupt
78         -- Bit 2: RW - Halt
79         -- Bit 3: RW - Trace
80         -- Bit 4: R  - Halted
81
82         -- 0x001
83         -- Bit 0: W - Write 1 for trace kick
84
85         -- 0x002
86         -- Tumbl program counter (R)
87
88   -- 0x003
89         -- Halt code
90
91 begin
92
93         -- Wire it to the tumbl
94         I_TUMBL: lx_rocon_tumbl
95         generic map
96         (
97                 IMEM_ABITS_g         => 9,
98                 DMEM_ABITS_g         => 10,
99                 --
100                 USE_HW_MUL_g         => true,
101                 USE_BARREL_g         => true,
102                 COMPATIBILITY_MODE_g => false
103         )
104         port map
105         (
106                 clk_i        => clk_i,
107                 rst_i        => tumbl_reset_s,
108                 halt_i       => tumbl_input_s.halt,
109                 int_i        => tumbl_input_s.int,
110                 trace_i      => tumbl_input_s.trace,
111                 trace_kick_i => tumbl_input_s.trace_kick,
112
113                 pc_o         => tumbl_state_s.pc,
114                 halted_o     => tumbl_state_s.halted,
115                 halt_code_o  => tumbl_state_s.halt_code,
116
117                 -- Internal memory (instruction)
118                 imem_clk_i   => clk_i,
119     imem_en_i    => imem_en_s,
120     imem_we_i    => imem_we_s,
121     imem_addr_i  => address_i(8 downto 0),
122     imem_data_i  => data_i,
123     imem_data_o  => imem_data_o_s,
124
125                 -- Internal memory (data)
126                 dmem_clk_i   => clk_i,
127     dmem_en_i    => dmem_en_s,
128     dmem_we_i    => dmem_we_s,
129     dmem_addr_i  => address_i(9 downto 0),
130     dmem_data_i  => data_i,
131     dmem_data_o  => dmem_data_o_s,
132
133                 -- External memory bus
134                 xmemb_sel_o  => xmemb_sel_o,
135                 xmemb_i      => xmemb_i,
136                 xmemb_o      => xmemb_o
137         );
138
139 -- Enabling
140 enabling: process(ce_i, address_i)
141         begin
142
143                 if ce_i = '1' and address_i(11 downto 10) = "00" then
144                         imem_en_s <= '1';
145                 else
146                         imem_en_s <= '0';
147                 end if;
148
149                 if ce_i = '1' and address_i(11 downto 10) = "01" then
150                         dmem_en_s <= '1';
151                 else
152                         dmem_en_s <= '0';
153                 end if;
154
155         end process;
156
157 -- Wiring
158 wiring:
159         process(ce_i, bls_i, address_i, imem_en_s, imem_data_o_s, dmem_en_s,
160                                                                 dmem_data_o_s, tumbl_reset_s, tumbl_input_s, tumbl_state_s)
161         begin
162
163                 if imem_en_s = '1' then
164                         imem_we_s <= bls_i;
165                 else
166                         imem_we_s <= "0000";
167                 end if;
168
169                 if dmem_en_s = '1' then
170                         dmem_we_s <= bls_i;
171                 else
172                         dmem_we_s <= "0000";
173                 end if;
174
175                 if imem_en_s = '1' then
176                         data_o <= imem_data_o_s;
177                 elsif dmem_en_s = '1' then
178                         data_o <= dmem_data_o_s;
179                 elsif ce_i = '1' and address_i(11 downto 10) = "11" then
180                         if address_i(9 downto 0) = "0000000000" then
181                                 data_o(0) <= tumbl_reset_s;
182                                 data_o(1) <= tumbl_input_s.int;
183                                 data_o(2) <= tumbl_input_s.halt;
184                                 data_o(3) <= tumbl_input_s.trace;
185                                 data_o(4) <= tumbl_state_s.halted;
186                                 data_o(31 downto 5) <= (others => '0');
187                         elsif address_i(9 downto 0) = "0000000010" then
188                                 data_o <= tumbl_state_s.pc;
189                         elsif address_i(9 downto 0) = "0000000011" then
190                                 data_o(4 downto 0)  <= tumbl_state_s.halt_code;
191                                 data_o(31 downto 5) <= (others => '0');
192                         else
193                                 data_o <= (others => 'X');
194                         end if;
195                 else
196                         data_o <= (others => 'X');
197                 end if;
198
199         end process;
200
201 -- Transaction acknowledge and writing to registers
202 update:
203         process
204         begin
205
206                 -- Update
207                 wait until clk_i'event and clk_i = '1';
208
209                 tumbl_input_s.trace_kick <= '0';
210
211                 if reset_i = '1' then
212                         tumbl_reset_s            <= '1';
213                         tumbl_input_s.int        <= '0';
214                         tumbl_input_s.halt       <= '0';
215                         tumbl_input_s.trace      <= '0';
216
217                 else
218
219                         if ce_i = '1' and address_i(11 downto 10) = "11" then
220                                 if bls_i(0) = '1' then
221                                         if address_i(9 downto 0) = "0000000000" then
222                                                 tumbl_reset_s              <= data_i(0);
223                                                 tumbl_input_s.int          <= data_i(1);
224                                                 tumbl_input_s.halt         <= data_i(2);
225                                                 tumbl_input_s.trace        <= data_i(3);
226                                         elsif address_i(9 downto 0) = "0000000001" then
227                                                 if data_i(0) = '1' then
228                                                         tumbl_input_s.trace_kick <= '1';
229                                                 end if;
230                                         end if;
231                                 end if;
232                         end if;
233                 end if;
234
235         end process;
236
237 end Behavioral;