1 |
99 |
davidgb |
--===========================================================================--
|
2 |
|
|
-- --
|
3 |
|
|
-- Synthesizable Hardware Trace Capture --
|
4 |
|
|
-- --
|
5 |
|
|
--===========================================================================--
|
6 |
|
|
--
|
7 |
|
|
-- File name : trace.vhd
|
8 |
|
|
--
|
9 |
|
|
-- Entity name : trace
|
10 |
|
|
--
|
11 |
|
|
-- Purpose : Implements a hardware real-time trace buffer for system09.
|
12 |
|
|
-- Captures all the CPU bus cycles to a block RAM trace buffer.
|
13 |
|
|
-- A trigger condition may be used to start or stop a trace
|
14 |
|
|
-- capture. The trigger condition is determined by the address,
|
15 |
|
|
-- data and control, comparator and qualifier registers.
|
16 |
|
|
-- The comparator registers determine the level of the signals
|
17 |
|
|
-- to trigger on. The qualifier registers determine if the
|
18 |
|
|
-- comparison is to be made for that bit (qualifier bit set)
|
19 |
|
|
-- or not (qualifier bit cleared). The hardware trace capture
|
20 |
|
|
-- module has 9 x 8 bit registers and 5 trace buffers. Separate
|
21 |
|
|
-- chip selects are provided for the register bank and trace
|
22 |
|
|
-- buffer bank. The individual trace buffers are selected via
|
23 |
|
|
-- the bank select register. Trace buffers may be read by the
|
24 |
|
|
-- CPU but are only written to when tracing CPU bus cycles.
|
25 |
|
|
-- The lowest trace buffer address always points to the start
|
26 |
|
|
-- of the trace capture. This is achieved by adding an offset
|
27 |
|
|
-- to the buffer address which points to the last cycle captured.
|
28 |
|
|
--
|
29 |
|
|
-- Dependencies : ieee.Std_Logic_1164
|
30 |
|
|
-- ieee.std_logic_unsigned
|
31 |
|
|
--
|
32 |
|
|
-- Author : John E. Kent
|
33 |
|
|
--
|
34 |
|
|
-- Email : dilbert57@opencores.org
|
35 |
|
|
--
|
36 |
|
|
-- Web : http://opencores.org/project,system09
|
37 |
|
|
--
|
38 |
|
|
-- Description : Register Memory Map
|
39 |
|
|
--
|
40 |
|
|
-- Register Bank(CS_R)
|
41 |
|
|
-- Base + $00 - Address Comparitor High Byte
|
42 |
|
|
-- Base + $01 - Address Comparitor Low byte
|
43 |
|
|
-- Base + $02 - Data Comparitor
|
44 |
|
|
-- Base + $03 - Control Comparitor
|
45 |
|
|
-- Base + $04 - Address Qualifier High Byte
|
46 |
|
|
-- Base + $05 - Address Qualifier Low byte
|
47 |
|
|
-- Base + $06 - Data Qualifier
|
48 |
|
|
-- Base + $07 - Control Qualifier
|
49 |
|
|
-- Base + $08 - Buffer Bank Select
|
50 |
|
|
-- Bits[2..0] Select Buffer Bank 0 to 4
|
51 |
|
|
--
|
52 |
|
|
-- Buffer Bank (CS_B)
|
53 |
|
|
-- Bank 0 - CPU Address high trace buffer
|
54 |
|
|
-- Bank 1 - CPU Address low trace buffer
|
55 |
|
|
-- Bank 2 - CPU Data output (write) trace buffer
|
56 |
|
|
-- Bank 3 - CPU Data input (read) trace buffer
|
57 |
|
|
-- Bank 4 - CPU Control signal trace buffer
|
58 |
|
|
--
|
59 |
|
|
-- Address, Data and Control signals
|
60 |
|
|
-- must match in the Comparitor registers
|
61 |
|
|
-- Matches are qualified by setting a bit
|
62 |
|
|
-- in the Qualifier registers
|
63 |
|
|
--
|
64 |
|
|
-- Control Comparitor / Control Qualify Write
|
65 |
|
|
-- b0 - r/w 1=read 0=write
|
66 |
|
|
-- b1 - vma 1=valid 0=invalid
|
67 |
|
|
-- b5 - trace 1=enable 0=disable
|
68 |
|
|
-- b6 - pre/post 1=before 0=after
|
69 |
|
|
-- b7 - irq output 1=match 0=mismatch
|
70 |
|
|
--
|
71 |
|
|
-- Control Qualifier Read
|
72 |
|
|
-- b7 - Interrupt Flag (unmasked)
|
73 |
|
|
--
|
74 |
|
|
-- Copyright (C) 2004 - 2010 John Kent
|
75 |
|
|
--
|
76 |
|
|
-- This program is free software: you can redistribute it and/or modify
|
77 |
|
|
-- it under the terms of the GNU General Public License as published by
|
78 |
|
|
-- the Free Software Foundation, either version 3 of the License, or
|
79 |
|
|
-- (at your option) any later version.
|
80 |
|
|
--
|
81 |
|
|
-- This program is distributed in the hope that it will be useful,
|
82 |
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
83 |
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
84 |
|
|
-- GNU General Public License for more details.
|
85 |
|
|
--
|
86 |
|
|
-- You should have received a copy of the GNU General Public License
|
87 |
|
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
88 |
|
|
--
|
89 |
|
|
--===========================================================================--
|
90 |
|
|
-- --
|
91 |
|
|
-- Revision History --
|
92 |
|
|
-- --
|
93 |
|
|
--===========================================================================--
|
94 |
|
|
--
|
95 |
|
|
-- Version Date Author Description
|
96 |
|
|
--
|
97 |
|
|
-- 0.1 2004-06-19 John E. Kent Initial version
|
98 |
|
|
-- 0.2 2010-08-09 John E. Kent Updated header and added GPL
|
99 |
|
|
-- Added trigger on read or write data
|
100 |
|
|
-- (not just write data).
|
101 |
|
|
-- Rearranged register and buffer bank decoding
|
102 |
|
|
-- Added Generics for data width and buffer size
|
103 |
|
|
--
|
104 |
|
|
library ieee;
|
105 |
|
|
use ieee.std_logic_1164.all;
|
106 |
|
|
use ieee.std_logic_unsigned.all;
|
107 |
|
|
|
108 |
|
|
entity trace is
|
109 |
|
|
generic (
|
110 |
|
|
BUFF_SIZE : integer := 9; -- Buffer Address Bits (B4=9, B16=11)
|
111 |
|
|
DATA_WIDTH : integer := 8 -- Data Width
|
112 |
|
|
)
|
113 |
|
|
port (
|
114 |
|
|
clk : in std_logic; -- CPU bus clock
|
115 |
|
|
rst : in std_logic; -- Reset
|
116 |
|
|
cs_r : in std_logic; -- Register bank chip select
|
117 |
|
|
cs_b : in std_logic; -- Buffer bank chip select
|
118 |
|
|
rw : in std_logic; -- Read not Write
|
119 |
|
|
addr : in std_logic_vector((2*DATA_WIDTH)-1 downto 0); -- CPU address / Trace buffer address in
|
120 |
|
|
data_in : in std_logic_vector(DATA_WIDTH-1 downto 0); -- CPU data out (write)/ Trace data in
|
121 |
|
|
data_out : out std_logic_vector(DATA_WIDTH-1 downto 0); -- Trace data out (read)
|
122 |
|
|
irq : out std_logic;
|
123 |
|
|
cpu_vma : in std_logic; -- CPU VMA / Trace buffer VMA in
|
124 |
|
|
cpu_data_in : in std_logic_vector(DATA_WIDTH-1 downto 0) -- CPU read data in
|
125 |
|
|
);
|
126 |
|
|
end;
|
127 |
|
|
|
128 |
|
|
architecture trace_arch of trace is
|
129 |
|
|
|
130 |
|
|
--
|
131 |
|
|
-- Registers
|
132 |
|
|
--
|
133 |
|
|
signal comp_addr_hi : std_logic_vector(DATA_WIDTH-1 downto 0); -- Address High Comparator Reg
|
134 |
|
|
signal comp_addr_lo : std_logic_vector(DATA_WIDTH-1 downto 0); -- Address Low Comparator Reg
|
135 |
|
|
signal comp_data : std_logic_vector(DATA_WIDTH-1 downto 0); -- Data Comparator Reg
|
136 |
|
|
signal comp_ctrl : std_logic_vector(DATA_WIDTH-1 downto 0); -- Control Sig Comparator Reg
|
137 |
|
|
signal qual_addr_hi : std_logic_vector(DATA_WIDTH-1 downto 0); -- Address High Qualifier Reg
|
138 |
|
|
signal qual_addr_lo : std_logic_vector(DATA_WIDTH-1 downto 0); -- Address Low Qualifier Reg
|
139 |
|
|
signal qual_data : std_logic_vector(DATA_WIDTH-1 downto 0); -- Data Qualifier Reg
|
140 |
|
|
signal qual_ctrl : std_logic_vector(DATA_WIDTH-1 downto 0); -- Control Sig Qualifier Reg
|
141 |
|
|
signal bank_reg : std_logic_vector(DATA_WIDTH-1 downto 0); -- Trace Buffer Bank Select Reg
|
142 |
|
|
signal reg_data_out : std_logic_vector(DATA_WIDTH-1 downto 0); -- Register Data Output
|
143 |
|
|
|
144 |
|
|
--
|
145 |
|
|
-- Trace enable, counter and offset registers
|
146 |
|
|
--
|
147 |
|
|
signal trace_en : std_logic;
|
148 |
|
|
signal trace_count : std_logic_vector(BUFF_SIZE-1 downto 0);
|
149 |
|
|
signal trace_offset : std_logic_vector(BUFF_SIZE-1 downto 0);
|
150 |
|
|
|
151 |
|
|
--
|
152 |
|
|
-- Buffer address
|
153 |
|
|
--
|
154 |
|
|
signal buf_addr : std_logic_vector(BUFF_SIZE-1 downto 0);
|
155 |
|
|
|
156 |
|
|
--
|
157 |
|
|
-- Block RAM buffer Mux signals
|
158 |
|
|
--
|
159 |
|
|
signal mux_stb : std_logic;
|
160 |
|
|
signal mux_addr : std_logic_vector(BUFF_SIZE-1 downto 0);
|
161 |
|
|
signal mux_we : std_logic;
|
162 |
|
|
|
163 |
|
|
--
|
164 |
|
|
-- Block RAM trace buffer data outputs
|
165 |
|
|
--
|
166 |
|
|
signal buf_data_out_0 : std_logic_vector(DATA_WIDTH-1 downto 0);
|
167 |
|
|
signal buf_data_out_1 : std_logic_vector(DATA_WIDTH-1 downto 0);
|
168 |
|
|
signal buf_data_out_2 : std_logic_vector(DATA_WIDTH-1 downto 0);
|
169 |
|
|
signal buf_data_out_3 : std_logic_vector(DATA_WIDTH-1 downto 0);
|
170 |
|
|
signal buf_data_out_4 : std_logic_vector(DATA_WIDTH-1 downto 0);
|
171 |
|
|
signal buf_data_out : std_logic_vector(DATA_WIDTH-1 downto 0);
|
172 |
|
|
|
173 |
|
|
--
|
174 |
|
|
-- Various other signals
|
175 |
|
|
--
|
176 |
|
|
signal irq_out : std_logic; -- Interrupt Request signal (unmasked)
|
177 |
|
|
signal qual_write : std_logic; -- Qualifier Control Register Write Strobe
|
178 |
|
|
signal qual_read : std_logic; -- Qualifier Control Register Read Strobe
|
179 |
|
|
signal trigger : std_logic; -- Event Trigger derived from bus comparator
|
180 |
|
|
signal ctrl_in : std_logic_vector(7 downto 0);
|
181 |
|
|
|
182 |
|
|
--
|
183 |
|
|
-- Block RAM Trace buffer
|
184 |
|
|
-- For Spartan 2 these will be B4 RAMs ( 512 Bytes)
|
185 |
|
|
-- For Spartan 3 these will be B16 RAMs (2048 Bytes)
|
186 |
|
|
--
|
187 |
|
|
component trace_ram
|
188 |
|
|
Port (
|
189 |
|
|
WB_CLK_I : in std_logic;
|
190 |
|
|
WB_RST_I : in std_logic;
|
191 |
|
|
WB_ADR_I : in std_logic_vector (BUFF_SIZE-1 downto 0);
|
192 |
|
|
WB_DAT_O : out std_logic_vector (DATA_WIDTH-1 downto 0);
|
193 |
|
|
WB_DAT_I : in std_logic_vector (DATA_WIDTH-1 downto 0);
|
194 |
|
|
WB_WE_I : in std_logic;
|
195 |
|
|
WB_STB_I : in std_logic
|
196 |
|
|
);
|
197 |
|
|
end component;
|
198 |
|
|
|
199 |
|
|
--
|
200 |
|
|
-- Start of Architecture
|
201 |
|
|
--
|
202 |
|
|
begin
|
203 |
|
|
|
204 |
|
|
--
|
205 |
|
|
-- Instantiate (Port Map) Block RAM trace buffers
|
206 |
|
|
--
|
207 |
|
|
|
208 |
|
|
--
|
209 |
|
|
-- Bank 0 - Trace buffer for CPU address high bits
|
210 |
|
|
--
|
211 |
|
|
trace_buffer_0 : trace_ram port map (
|
212 |
|
|
WB_CLK_I => clk,
|
213 |
|
|
WB_RST_I => rst,
|
214 |
|
|
WB_ADR_I => mux_addr,
|
215 |
|
|
WB_DAT_O => buf_data_out_0,
|
216 |
|
|
WB_DAT_I => addr((2*DATA_WIDTH)-1 downto DATA_WIDTH),
|
217 |
|
|
WB_WE_I => mux_we,
|
218 |
|
|
WB_STB_I => mux_stb
|
219 |
|
|
);
|
220 |
|
|
|
221 |
|
|
--
|
222 |
|
|
-- Bank 1 - Trace buffer for CPU address low bits
|
223 |
|
|
--
|
224 |
|
|
trace_buffer_1 : trace_ram port map (
|
225 |
|
|
WB_CLK_I => clk,
|
226 |
|
|
WB_RST_I => rst,
|
227 |
|
|
WB_ADR_I => mux_addr,
|
228 |
|
|
WB_DAT_O => buf_data_out_1,
|
229 |
|
|
WB_DAT_I => addr(DATA_WIDTH-1 downto 0),
|
230 |
|
|
WB_WE_I => mux_we,
|
231 |
|
|
WB_STB_I => mux_stb
|
232 |
|
|
);
|
233 |
|
|
|
234 |
|
|
--
|
235 |
|
|
-- Bank 2 - Trace buffer for CPU data out (write)
|
236 |
|
|
--
|
237 |
|
|
trace_buffer_2 : trace_ram port map (
|
238 |
|
|
WB_CLK_I => clk,
|
239 |
|
|
WB_RST_I => rst,
|
240 |
|
|
WB_ADR_I => mux_addr,
|
241 |
|
|
WB_DAT_O => buf_data_out_2,
|
242 |
|
|
WB_DAT_I => data_in(DATA_WIDTH-1 downto 0),
|
243 |
|
|
WB_WE_I => mux_we,
|
244 |
|
|
WB_STB_I => mux_stb
|
245 |
|
|
);
|
246 |
|
|
|
247 |
|
|
--
|
248 |
|
|
-- Bank 3 - Trace buffer for CPU data in (read)
|
249 |
|
|
--
|
250 |
|
|
trace_buffer_3 : trace_ram port map (
|
251 |
|
|
WB_CLK_I => clk,
|
252 |
|
|
WB_RST_I => rst,
|
253 |
|
|
WB_ADR_I => mux_addr,
|
254 |
|
|
WB_DAT_O => buf_data_out_3,
|
255 |
|
|
WB_DAT_I => cpu_data_in(DATA_WIDTH-1 downto 0),
|
256 |
|
|
WB_WE_I => mux_we,
|
257 |
|
|
WB_STB_I => mux_stb
|
258 |
|
|
);
|
259 |
|
|
|
260 |
|
|
--
|
261 |
|
|
-- Bank 4 - Trace buffer for CPU control bits
|
262 |
|
|
--
|
263 |
|
|
trace_buffer_4 : trace_ram port map (
|
264 |
|
|
WB_CLK_I => clk,
|
265 |
|
|
WB_RST_I => rst,
|
266 |
|
|
WB_ADR_I => mux_addr,
|
267 |
|
|
WB_DAT_O => buf_data_out_4,
|
268 |
|
|
WB_DAT_I => ctrl_in(DATA_WIDTH-1 downto 0),
|
269 |
|
|
WB_WE_I => mux_we,
|
270 |
|
|
WB_STB_I => mux_stb
|
271 |
|
|
);
|
272 |
|
|
|
273 |
|
|
--------------------------------
|
274 |
|
|
--
|
275 |
|
|
-- Assign control signal input
|
276 |
|
|
--
|
277 |
|
|
--------------------------------
|
278 |
|
|
|
279 |
|
|
trace_ctrl_assign : process( irq_out, qual_ctrl, rw, cpu_vma )
|
280 |
|
|
begin
|
281 |
|
|
ctrl_in(0) <= rw;
|
282 |
|
|
ctrl_in(1) <= cpu_vma;
|
283 |
|
|
ctrl_in(7 downto 2) <= (others=>'0');
|
284 |
|
|
end process;
|
285 |
|
|
|
286 |
|
|
--------------------------------
|
287 |
|
|
--
|
288 |
|
|
-- Write Trace Registers
|
289 |
|
|
--
|
290 |
|
|
--------------------------------
|
291 |
|
|
|
292 |
|
|
trace_reg_write : process( clk, rst, cs_r, rw, addr, data_in )
|
293 |
|
|
begin
|
294 |
|
|
if clk'event and clk = '0' then
|
295 |
|
|
qual_write <= '0';
|
296 |
|
|
if rst = '1' then
|
297 |
|
|
comp_addr_hi <= (others=>'0');
|
298 |
|
|
comp_addr_lo <= (others=>'0');
|
299 |
|
|
comp_data <= (others=>'0');
|
300 |
|
|
comp_ctrl <= (others=>'0');
|
301 |
|
|
qual_addr_hi <= (others=>'0');
|
302 |
|
|
qual_addr_lo <= (others=>'0');
|
303 |
|
|
qual_data <= (others=>'0');
|
304 |
|
|
qual_ctrl <= (others=>'0');
|
305 |
|
|
bank_reg <= (others=>'0');
|
306 |
|
|
elsif cs_r = '1' and rw = '0' then
|
307 |
|
|
case addr(3 downto 0) is
|
308 |
|
|
when "0000" =>
|
309 |
|
|
comp_addr_hi <= data_in;
|
310 |
|
|
when "0001" =>
|
311 |
|
|
comp_addr_lo <= data_in;
|
312 |
|
|
when "0010" =>
|
313 |
|
|
comp_data <= data_in;
|
314 |
|
|
when "0011" =>
|
315 |
|
|
comp_ctrl <= data_in;
|
316 |
|
|
when "0100" =>
|
317 |
|
|
qual_addr_hi <= data_in;
|
318 |
|
|
when "0101" =>
|
319 |
|
|
qual_addr_lo <= data_in;
|
320 |
|
|
when "0110" =>
|
321 |
|
|
qual_data <= data_in;
|
322 |
|
|
when "0111" =>
|
323 |
|
|
qual_ctrl <= data_in;
|
324 |
|
|
qual_write <= '1';
|
325 |
|
|
when others =>
|
326 |
|
|
bank_reg <= data_in;
|
327 |
|
|
end case;
|
328 |
|
|
end if;
|
329 |
|
|
end if;
|
330 |
|
|
end process;
|
331 |
|
|
|
332 |
|
|
------------------------------------------
|
333 |
|
|
--
|
334 |
|
|
-- Read Trace Register (output mux)
|
335 |
|
|
--
|
336 |
|
|
------------------------------------------
|
337 |
|
|
trace_reg_read : process( addr, rw, cs_r,
|
338 |
|
|
comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
|
339 |
|
|
qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl,
|
340 |
|
|
bank_reg, irq_out )
|
341 |
|
|
begin
|
342 |
|
|
qual_read <= '0';
|
343 |
|
|
case addr(3 downto 0) is
|
344 |
|
|
when "0000" =>
|
345 |
|
|
reg_data_out <= comp_addr_hi;
|
346 |
|
|
when "0001" =>
|
347 |
|
|
reg_data_out <= comp_addr_lo;
|
348 |
|
|
when "0010" =>
|
349 |
|
|
reg_data_out <= comp_data;
|
350 |
|
|
when "0011" =>
|
351 |
|
|
reg_data_out <= comp_ctrl;
|
352 |
|
|
when "0100" =>
|
353 |
|
|
reg_data_out <= qual_addr_hi;
|
354 |
|
|
when "0101" =>
|
355 |
|
|
reg_data_out <= qual_addr_lo;
|
356 |
|
|
when "0110" =>
|
357 |
|
|
reg_data_out <= qual_data;
|
358 |
|
|
when "0111" =>
|
359 |
|
|
qual_read <= cs_r and rw;
|
360 |
|
|
reg_data_out(6 downto 0) <= qual_ctrl(6 downto 0);
|
361 |
|
|
reg_data_out(7) <= irq_out;
|
362 |
|
|
when others =>
|
363 |
|
|
reg_data_out <= bank_reg;
|
364 |
|
|
end case;
|
365 |
|
|
|
366 |
|
|
end process;
|
367 |
|
|
|
368 |
|
|
|
369 |
|
|
--------------------------------
|
370 |
|
|
--
|
371 |
|
|
-- Read Trace Buffers
|
372 |
|
|
--
|
373 |
|
|
--------------------------------
|
374 |
|
|
|
375 |
|
|
trace_buf_read : process( bank_reg, buf_data_out_0, buf_data_out_1,
|
376 |
|
|
buf_data_out_2, buf_data_out_3, buf_data_out_4 )
|
377 |
|
|
begin
|
378 |
|
|
case bank_reg(2 downto 0) is
|
379 |
|
|
when "000" =>
|
380 |
|
|
buf_data_out <= buf_data_out_0;
|
381 |
|
|
when "001" =>
|
382 |
|
|
buf_data_out <= buf_data_out_1;
|
383 |
|
|
when "010" =>
|
384 |
|
|
buf_data_out <= buf_data_out_2;
|
385 |
|
|
when "011" =>
|
386 |
|
|
buf_data_out <= buf_data_out_3;
|
387 |
|
|
when "100" =>
|
388 |
|
|
buf_data_out <= buf_data_out_4;
|
389 |
|
|
when others =>
|
390 |
|
|
buf_data_out <= (others=>'0');
|
391 |
|
|
end case;
|
392 |
|
|
end process;
|
393 |
|
|
|
394 |
|
|
--------------------------------
|
395 |
|
|
--
|
396 |
|
|
-- Read Registers or Buffers
|
397 |
|
|
--
|
398 |
|
|
--------------------------------
|
399 |
|
|
|
400 |
|
|
trace_read : process( cs_r, reg_data_out, buf_data_out )
|
401 |
|
|
begin
|
402 |
|
|
if cs_r = '1' then
|
403 |
|
|
data_out = reg_data_out;
|
404 |
|
|
else
|
405 |
|
|
data_out = buf_data_out;
|
406 |
|
|
else
|
407 |
|
|
end process;
|
408 |
|
|
|
409 |
|
|
|
410 |
|
|
------------------------------------------------------------------------
|
411 |
|
|
--
|
412 |
|
|
-- Multiplex the trace buffer between the trace capture and the CPU read
|
413 |
|
|
--
|
414 |
|
|
------------------------------------------------------------------------
|
415 |
|
|
|
416 |
|
|
trace_buf_mux : process( cs_b, trace_count, trace_en, buf_addr )
|
417 |
|
|
begin
|
418 |
|
|
if cs_b = '0' then
|
419 |
|
|
mux_addr <= trace_count;
|
420 |
|
|
mux_we <= '1';
|
421 |
|
|
mux_stb <= trace_en;
|
422 |
|
|
else
|
423 |
|
|
mux_addr <= buf_addr;
|
424 |
|
|
mux_we <= '0';
|
425 |
|
|
mux_stb <= '1';
|
426 |
|
|
end if;
|
427 |
|
|
|
428 |
|
|
end process;
|
429 |
|
|
|
430 |
|
|
------------------------------
|
431 |
|
|
--
|
432 |
|
|
-- Trigger comparator process
|
433 |
|
|
--
|
434 |
|
|
------------------------------
|
435 |
|
|
|
436 |
|
|
trace_trigger : process( clk, rst, cs_r, addr, rw, cpu_vma, data_in, cpu_data_in,
|
437 |
|
|
comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
|
438 |
|
|
qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl)
|
439 |
|
|
variable hit : std_logic;
|
440 |
|
|
variable miss_addr_hi : std_logic;
|
441 |
|
|
variable miss_addr_lo : std_logic;
|
442 |
|
|
variable miss_data_rd : std_logic;
|
443 |
|
|
variable miss_data_wr : std_logic;
|
444 |
|
|
variable miss_ctrl : std_logic;
|
445 |
|
|
|
446 |
|
|
begin
|
447 |
|
|
miss_addr_hi :=
|
448 |
|
|
((comp_addr_hi(7) xor addr(15) ) and qual_addr_hi(7) ) or
|
449 |
|
|
((comp_addr_hi(6) xor addr(14) ) and qual_addr_hi(6) ) or
|
450 |
|
|
((comp_addr_hi(5) xor addr(13) ) and qual_addr_hi(5) ) or
|
451 |
|
|
((comp_addr_hi(4) xor addr(12) ) and qual_addr_hi(4) ) or
|
452 |
|
|
((comp_addr_hi(3) xor addr(11) ) and qual_addr_hi(3) ) or
|
453 |
|
|
((comp_addr_hi(2) xor addr(10) ) and qual_addr_hi(2) ) or
|
454 |
|
|
((comp_addr_hi(1) xor addr( 9) ) and qual_addr_hi(1) ) or
|
455 |
|
|
((comp_addr_hi(0) xor addr( 8) ) and qual_addr_hi(0) );
|
456 |
|
|
miss_addr_lo :=
|
457 |
|
|
((comp_addr_lo(7) xor addr( 7) ) and qual_addr_lo(7) ) or
|
458 |
|
|
((comp_addr_lo(6) xor addr( 6) ) and qual_addr_lo(6) ) or
|
459 |
|
|
((comp_addr_lo(5) xor addr( 5) ) and qual_addr_lo(5) ) or
|
460 |
|
|
((comp_addr_lo(4) xor addr( 4) ) and qual_addr_lo(4) ) or
|
461 |
|
|
((comp_addr_lo(3) xor addr( 3) ) and qual_addr_lo(3) ) or
|
462 |
|
|
((comp_addr_lo(2) xor addr( 2) ) and qual_addr_lo(2) ) or
|
463 |
|
|
((comp_addr_lo(1) xor addr( 1) ) and qual_addr_lo(1) ) or
|
464 |
|
|
((comp_addr_lo(0) xor addr( 0) ) and qual_addr_lo(0) );
|
465 |
|
|
miss_data_wr :=
|
466 |
|
|
((comp_data(7) xor data_in(7)) and qual_data(7) ) or
|
467 |
|
|
((comp_data(6) xor data_in(6)) and qual_data(6) ) or
|
468 |
|
|
((comp_data(5) xor data_in(5)) and qual_data(5) ) or
|
469 |
|
|
((comp_data(4) xor data_in(4)) and qual_data(4) ) or
|
470 |
|
|
((comp_data(3) xor data_in(3)) and qual_data(3) ) or
|
471 |
|
|
((comp_data(2) xor data_in(2)) and qual_data(2) ) or
|
472 |
|
|
((comp_data(1) xor data_in(1)) and qual_data(1) ) or
|
473 |
|
|
((comp_data(0) xor data_in(0)) and qual_data(0) );
|
474 |
|
|
miss_data_rd :=
|
475 |
|
|
((comp_data(7) xor cpu_data_in(7)) and qual_data(7) ) or
|
476 |
|
|
((comp_data(6) xor cpu_data_in(6)) and qual_data(6) ) or
|
477 |
|
|
((comp_data(5) xor cpu_data_in(5)) and qual_data(5) ) or
|
478 |
|
|
((comp_data(4) xor cpu_data_in(4)) and qual_data(4) ) or
|
479 |
|
|
((comp_data(3) xor cpu_data_in(3)) and qual_data(3) ) or
|
480 |
|
|
((comp_data(2) xor cpu_data_in(2)) and qual_data(2) ) or
|
481 |
|
|
((comp_data(1) xor cpu_data_in(1)) and qual_data(1) ) or
|
482 |
|
|
((comp_data(0) xor cpu_data_in(0)) and qual_data(0) );
|
483 |
|
|
miss_ctrl :=
|
484 |
|
|
((comp_ctrl(0) xor rw ) and qual_ctrl(0) ) or
|
485 |
|
|
((comp_ctrl(1) xor cpu_vma ) and qual_ctrl(1) );
|
486 |
|
|
|
487 |
|
|
hit := not( miss_addr_hi or miss_addr_lo or (miss_data_rd and not(miss_ctrl) and rw) or (miss_data_wr and not(miss_ctrl) and not(rw)) or miss_ctrl);
|
488 |
|
|
trigger <= not(hit xor comp_ctrl(7));
|
489 |
|
|
|
490 |
|
|
end process;
|
491 |
|
|
|
492 |
|
|
-----------------------------------------
|
493 |
|
|
--
|
494 |
|
|
-- Trace buffer capture on event trigger
|
495 |
|
|
--
|
496 |
|
|
-----------------------------------------
|
497 |
|
|
|
498 |
|
|
trace_capture : process( clk, rst, addr, qual_write,
|
499 |
|
|
trigger, trace_en, qual_ctrl, irq_out,
|
500 |
|
|
trace_count, trace_offset )
|
501 |
|
|
begin
|
502 |
|
|
if clk'event and clk = '1' then
|
503 |
|
|
if rst = '1' then
|
504 |
|
|
trace_count <= (others=>'0');
|
505 |
|
|
trace_offset <= (others=>'0');
|
506 |
|
|
trace_en <= '0';
|
507 |
|
|
irq_out <= '0';
|
508 |
|
|
else
|
509 |
|
|
--
|
510 |
|
|
-- qualifier control register bit 6 = zero
|
511 |
|
|
-- means start capture after trigger point.
|
512 |
|
|
--
|
513 |
|
|
if qual_ctrl(6) = '0' then
|
514 |
|
|
|
515 |
|
|
--
|
516 |
|
|
-- Activate trace on a trigger condition
|
517 |
|
|
-- Deactive trace when the buffer is full
|
518 |
|
|
--
|
519 |
|
|
if trace_en = '0' then
|
520 |
|
|
trace_en <= trigger;
|
521 |
|
|
elsif trace_count = trace_offset then
|
522 |
|
|
trace_offset <= trace_count;
|
523 |
|
|
trace_en <= '0';
|
524 |
|
|
end if;
|
525 |
|
|
|
526 |
|
|
--
|
527 |
|
|
-- Set IRQ on trace buffer full
|
528 |
|
|
-- Reset IRQ on qualifier control register write
|
529 |
|
|
--
|
530 |
|
|
if qual_write = '1' then
|
531 |
|
|
irq_out <= '0';
|
532 |
|
|
elsif trace_count = trace_offset then
|
533 |
|
|
irq_out <= '1';
|
534 |
|
|
end if;
|
535 |
|
|
|
536 |
|
|
--
|
537 |
|
|
-- qualifier control register bit 6 = one
|
538 |
|
|
-- means finish capture at trigger point.
|
539 |
|
|
--
|
540 |
|
|
else
|
541 |
|
|
--
|
542 |
|
|
-- Activate trace on qualifier control write
|
543 |
|
|
-- Deactivate trace on a trigger condition
|
544 |
|
|
--
|
545 |
|
|
if trace_en = '0' then
|
546 |
|
|
trace_en <= qual_write;
|
547 |
|
|
elsif trigger = '1' then
|
548 |
|
|
trace_offset <= trace_count;
|
549 |
|
|
trace_en <= '0';
|
550 |
|
|
end if;
|
551 |
|
|
|
552 |
|
|
--
|
553 |
|
|
-- Set IRQ on a trigger condition
|
554 |
|
|
-- Reset IRQ on qualifier control register write
|
555 |
|
|
--
|
556 |
|
|
if qual_write = '1' then
|
557 |
|
|
irq_out <= '0';
|
558 |
|
|
elsif trigger = '1' then
|
559 |
|
|
irq_out <= '1';
|
560 |
|
|
end if;
|
561 |
|
|
|
562 |
|
|
end if;
|
563 |
|
|
|
564 |
|
|
trace_count <= trace_count + 1;
|
565 |
|
|
|
566 |
|
|
end if;
|
567 |
|
|
end if;
|
568 |
|
|
|
569 |
|
|
--
|
570 |
|
|
-- The IRQ output is qualified by the interrupt enable bit
|
571 |
|
|
-- (bit 7 of the qualifier control register)
|
572 |
|
|
--
|
573 |
|
|
irq <= irq_out and qual_ctrl(7);
|
574 |
|
|
|
575 |
|
|
--
|
576 |
|
|
-- Trace buffer is offset by start address
|
577 |
|
|
--
|
578 |
|
|
buf_addr <= addr(BUFF_SIZE-1 downto 0) + trace_offset;
|
579 |
|
|
|
580 |
|
|
end process;
|
581 |
|
|
|
582 |
|
|
end trace_arch;
|
583 |
|
|
|