]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/bus_tumbl.vhd
Correct FPGA bus design for external CPU read cycle.
[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 imem_en_r     : std_logic;
57         signal dmem_en_s     : std_logic;
58         signal dmem_en_r     : std_logic;
59
60         signal imem_we_s     : std_logic_vector(3 downto 0);
61         signal dmem_we_s     : std_logic_vector(3 downto 0);
62
63         signal imem_data_o_s : std_logic_vector(31 downto 0);
64         signal dmem_data_o_s : std_logic_vector(31 downto 0);
65
66         -- Control registers read access
67         signal tumbl_reg_en_control_r   : std_logic;
68         signal tumbl_reg_en_pc_r        : std_logic;
69         signal tumbl_reg_en_halt_code_r : std_logic;
70
71         -- Internal bus structure
72         -- 12 address bits: 2 bits for selection, 10 bits for address
73         --
74         -- Selection:
75         -- 00 - imem
76         -- 01 - dmem
77         -- 10 - reserved
78         -- 11 - registers
79
80         -- Registers
81         -- 0x000
82         --
83         -- Bit 0: RW - Reset
84         -- Bit 1: RW - Interrupt
85         -- Bit 2: RW - Halt
86         -- Bit 3: RW - Trace
87         -- Bit 4: R  - Halted
88
89         -- 0x001
90         -- Bit 0: W - Write 1 for trace kick
91
92         -- 0x002
93         -- Tumbl program counter (R)
94
95   -- 0x003
96         -- Halt code
97
98 begin
99
100         -- Wire it to the tumbl
101         I_TUMBL: lx_rocon_tumbl
102         generic map
103         (
104                 IMEM_ABITS_g         => 9,
105                 DMEM_ABITS_g         => 10,
106                 --
107                 USE_HW_MUL_g         => true,
108                 USE_BARREL_g         => true,
109                 COMPATIBILITY_MODE_g => false
110         )
111         port map
112         (
113                 clk_i        => clk_i,
114                 rst_i        => tumbl_reset_s,
115                 halt_i       => tumbl_input_s.halt,
116                 int_i        => tumbl_input_s.int,
117                 trace_i      => tumbl_input_s.trace,
118                 trace_kick_i => tumbl_input_s.trace_kick,
119
120                 pc_o         => tumbl_state_s.pc,
121                 halted_o     => tumbl_state_s.halted,
122                 halt_code_o  => tumbl_state_s.halt_code,
123
124                 -- Internal memory (instruction)
125                 imem_clk_i   => clk_i,
126     imem_en_i    => imem_en_s,
127     imem_we_i    => imem_we_s,
128     imem_addr_i  => address_i(8 downto 0),
129     imem_data_i  => data_i,
130     imem_data_o  => imem_data_o_s,
131
132                 -- Internal memory (data)
133                 dmem_clk_i   => clk_i,
134     dmem_en_i    => dmem_en_s,
135     dmem_we_i    => dmem_we_s,
136     dmem_addr_i  => address_i(9 downto 0),
137     dmem_data_i  => data_i,
138     dmem_data_o  => dmem_data_o_s,
139
140                 -- External memory bus
141                 xmemb_sel_o  => xmemb_sel_o,
142                 xmemb_i      => xmemb_i,
143                 xmemb_o      => xmemb_o
144         );
145
146 -- Enabling
147 enabling: process(ce_i, address_i)
148         begin
149
150                 if ce_i = '1' and address_i(11 downto 10) = "00" then
151                         imem_en_s <= '1';
152                 else
153                         imem_en_s <= '0';
154                 end if;
155
156                 if ce_i = '1' and address_i(11 downto 10) = "01" then
157                         dmem_en_s <= '1';
158                 else
159                         dmem_en_s <= '0';
160                 end if;
161
162         end process;
163
164 -- Wiring
165 wiring:
166         process(ce_i, bls_i, address_i, imem_en_s, imem_data_o_s, dmem_en_s,
167                 dmem_data_o_s, tumbl_reset_s, tumbl_input_s, tumbl_state_s,
168                 imem_en_r, dmem_en_r, tumbl_reg_en_control_r, tumbl_reg_en_pc_r,
169                 tumbl_reg_en_halt_code_r)
170         begin
171
172                 if imem_en_s = '1' then
173                         imem_we_s <= bls_i;
174                 else
175                         imem_we_s <= "0000";
176                 end if;
177
178                 if dmem_en_s = '1' then
179                         dmem_we_s <= bls_i;
180                 else
181                         dmem_we_s <= "0000";
182                 end if;
183
184                 if imem_en_r = '1' then
185                         data_o <= imem_data_o_s;
186                 elsif dmem_en_r = '1' then
187                         data_o <= dmem_data_o_s;
188                 elsif tumbl_reg_en_control_r = '1' then
189                         data_o(0) <= tumbl_reset_s;
190                         data_o(1) <= tumbl_input_s.int;
191                         data_o(2) <= tumbl_input_s.halt;
192                         data_o(3) <= tumbl_input_s.trace;
193                         data_o(4) <= tumbl_state_s.halted;
194                         data_o(31 downto 5) <= (others => '0');
195                 elsif tumbl_reg_en_pc_r = '1' then
196                         data_o <= tumbl_state_s.pc;
197                 elsif tumbl_reg_en_halt_code_r = '1' then
198                         data_o(4 downto 0)  <= tumbl_state_s.halt_code;
199                         data_o(31 downto 5) <= (others => '0');
200                 else
201                         data_o <= (others => 'X');
202                 end if;
203
204         end process;
205
206 -- Transaction acknowledge and writing to registers
207 update:
208         process
209         begin
210
211                 -- Update
212                 wait until clk_i'event and clk_i = '1';
213
214                 imem_en_r <= imem_en_s;
215                 dmem_en_r <= dmem_en_s;
216
217                 tumbl_reg_en_control_r   <= '0';
218                 tumbl_reg_en_pc_r        <= '0';
219                 tumbl_reg_en_halt_code_r <= '0';
220
221                 tumbl_input_s.trace_kick <= '0';
222
223                 if reset_i = '1' then
224                         tumbl_reset_s            <= '1';
225                         tumbl_input_s.int        <= '0';
226                         tumbl_input_s.halt       <= '0';
227                         tumbl_input_s.trace      <= '0';
228
229                 else
230
231                         if ce_i = '1' and address_i(11 downto 10) = "11" then
232                                 if bls_i(0) = '1' then
233                                         if address_i(9 downto 0) = "0000000000" then
234                                                 tumbl_reset_s              <= data_i(0);
235                                                 tumbl_input_s.int          <= data_i(1);
236                                                 tumbl_input_s.halt         <= data_i(2);
237                                                 tumbl_input_s.trace        <= data_i(3);
238                                         elsif address_i(9 downto 0) = "0000000001" then
239                                                 if data_i(0) = '1' then
240                                                         tumbl_input_s.trace_kick <= '1';
241                                                 end if;
242                                         end if;
243                                 end if;
244
245
246                                 if address_i(9 downto 0) = "0000000000" then
247                                         tumbl_reg_en_control_r   <= '1';
248                                 elsif address_i(9 downto 0) = "0000000010" then
249                                         tumbl_reg_en_pc_r        <= '1';
250                                 elsif address_i(9 downto 0) = "0000000011" then
251                                         tumbl_reg_en_halt_code_r <= '1';
252                                 end if;
253                         end if;
254                 end if;
255
256         end process;
257
258 end Behavioral;