OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [VHDL/] [trace.vhd] - Diff between revs 66 and 99

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 66 Rev 99
Line 1... Line 1...
--===========================================================================--
--===========================================================================--
--
--                                                                           --
--  S Y N T H E Z I A B L E    Real Time Trace   C O R E
--                Synthesizable Hardware Trace Capture                       --
--
--                                                                           --
--  www.OpenCores.Org - May 2003
--===========================================================================--
--  This core adheres to the GNU public license  
 
--
--
-- File name      : trace.vhd
-- File name      : trace.vhd
--
--
-- entity name    : trace
--  Entity name    : trace
--
--
-- Purpose        : Implements a trace buffer
--  Purpose        : Implements a hardware real-time trace buffer for system09.
 
--                   Captures all the CPU bus cycles to a block RAM trace buffer.
 
--                   A trigger condition may be used to start or stop a trace 
 
--                   capture. The trigger condition is determined by the address,
 
--                   data and control, comparator and qualifier registers.
 
--                   The comparator registers determine the level of the signals 
 
--                   to trigger on. The qualifier registers determine if the 
 
--                   comparison is to be made for that bit (qualifier bit set) 
 
--                   or not (qualifier bit cleared). The hardware trace capture 
 
--                   module has 9 x 8 bit registers and 5 trace buffers. Separate 
 
--                   chip selects are provided for the register bank and trace 
 
--                   buffer bank. The individual trace buffers are selected via 
 
--                   the bank select register. Trace buffers may be read by the 
 
--                   CPU but are only written to when tracing CPU bus cycles.
 
--                   The lowest trace buffer address always points to the start
 
--                   of the trace capture. This is achieved by adding an offset
 
--                   to the buffer address which points to the last cycle captured. 
--
--
-- Dependencies   : ieee.Std_Logic_1164
-- Dependencies   : ieee.Std_Logic_1164
--                  ieee.std_logic_unsigned
--                  ieee.std_logic_unsigned
--
--
-- Author         : John E. Kent      
-- Author         : John E. Kent      
--
--
--===========================================================================----
--  Email          : dilbert57@opencores.org      
--
 
-- Revision History:
 
--
 
-- Date:          Revision         Author
 
-- 19 June 2004     0.1              John Kent
 
--
 
--===========================================================================----
 
--
--
-- Register Memory Map
--  Web            : http://opencores.org/project,system09
--
--
-- $00 - Address Comparitor High Byte
--  Description    : Register Memory Map
-- $01 - Address Comparitor Low byte
 
-- $02 - Data    Comparitor
 
-- $03 - Control Comparitor
 
-- $04 - Address Qualifier High Byte
 
-- $05 - Address Qualifier Low byte
 
-- $06 - Data    Qualifier
 
-- $07 - Control Qualifier
 
--
--
-- Address, Data and Control signals must match in the Comparitor registers 
--                   Register Bank(CS_R)
-- Matches are qualified by setting a bit in the Qualifier registers
--                   Base + $00 - Address Comparitor High Byte
 
--                   Base + $01 - Address Comparitor Low byte
 
--                   Base + $02 - Data    Comparitor
 
--                   Base + $03 - Control Comparitor
 
--                   Base + $04 - Address Qualifier High Byte
 
--                   Base + $05 - Address Qualifier Low byte
 
--                   Base + $06 - Data    Qualifier
 
--                   Base + $07 - Control Qualifier
 
--                   Base + $08 - Buffer  Bank Select
 
--                                Bits[2..0] Select Buffer Bank 0 to 4
 
--                  
 
--                   Buffer Bank (CS_B)
 
--                   Bank 0 - CPU Address high trace buffer
 
--                   Bank 1 - CPU Address low trace buffer
 
--                   Bank 2 - CPU Data output (write) trace buffer
 
--                   Bank 3 - CPU Data input (read) trace buffer
 
--                   Bank 4 - CPU Control signal trace buffer
 
-- 
 
--                   Address, Data and Control signals 
 
--                   must match in the Comparitor registers 
 
--                   Matches are qualified by setting a bit 
 
--                   in the Qualifier registers
--
--
-- Control Comparitor / Qualify (write)
--                   Control Comparitor / Control Qualify Write
-- b0 - r/w        1=read   0=write
-- b0 - r/w        1=read   0=write
-- b1 - vma        1=valid  0=invalid
-- b1 - vma        1=valid  0=invalid
-- b5 - trace      1=enable 0=disable
-- b5 - trace      1=enable 0=disable
-- b6 - pre/post   1=before 0=after
-- b6 - pre/post   1=before 0=after
-- b7 - irq output 1=match  0=mismatch
-- b7 - irq output 1=match  0=mismatch
--
--
-- Control Qualifier Read
-- Control Qualifier Read
-- b7 - match flag
--                   b7 - Interrupt Flag (unmasked)
 
-- 
 
--  Copyright (C) 2004 - 2010 John Kent
 
--
 
--  This program is free software: you can redistribute it and/or modify
 
--  it under the terms of the GNU General Public License as published by
 
--  the Free Software Foundation, either version 3 of the License, or
 
--  (at your option) any later version.
 
--
 
--  This program is distributed in the hope that it will be useful,
 
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
--  GNU General Public License for more details.
 
--
 
--  You should have received a copy of the GNU General Public License
 
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
--
 
--===========================================================================--
 
--                                                                           --
 
--                            Revision History                               --
 
--                                                                           --
 
--===========================================================================--
 
--
 
-- Version  Date        Author        Description
 
--
 
-- 0.1      2004-06-19  John E. Kent  Initial version
 
-- 0.2      2010-08-09  John E. Kent  Updated header and added GPL
 
--                                    Added trigger on read or write data
 
--                                    (not just write data).
 
--                                    Rearranged register and buffer bank decoding
 
--                                    Added Generics for data width and buffer size
--
--
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_unsigned.all;
 
 
entity trace is
entity trace is
 
  generic (
 
    BUFF_SIZE     : integer := 9;          -- Buffer Address Bits (B4=9, B16=11)
 
    DATA_WIDTH    : integer := 8           -- Data Width
 
  )
        port (
        port (
         clk           : in  std_logic;
    clk           : in  std_logic;         -- CPU bus clock
    rst           : in  std_logic;
    rst           : in  std_logic;         -- Reset
    rs            : in  std_logic;        -- register select
    cs_r          : in  std_logic;             -- Register bank chip select
    bs            : in  std_logic;        -- bank select
    cs_b          : in  std_logic;             -- Buffer bank chip select
    rw            : in  std_logic;
    rw            : in  std_logic;         -- Read not Write
         vma           : in  std_logic;
    addr          : in  std_logic_vector((2*DATA_WIDTH)-1 downto 0); -- CPU address / Trace buffer address in
    addr          : in  std_logic_vector(15 downto 0);
    data_in       : in  std_logic_vector(DATA_WIDTH-1 downto 0);     -- CPU data out (write)/ Trace data in
    data_in       : in  std_logic_vector(7 downto 0);
    data_out      : out std_logic_vector(DATA_WIDTH-1 downto 0);     -- Trace data out (read)
         reg_data_out  : out std_logic_vector(7 downto 0);
    irq           : out std_logic;
         buff_data_out : out std_logic_vector(7 downto 0);
    cpu_vma       : in  std_logic;                                   -- CPU VMA / Trace buffer VMA in
    cpu_data_in   : in  std_logic_vector(7 downto 0);
    cpu_data_in   : in  std_logic_vector(DATA_WIDTH-1 downto 0)      -- CPU read data in
         irq           : out std_logic
 
  );
  );
end;
end;
 
 
architecture trace_arch of trace is
architecture trace_arch of trace is
 
 
signal clk_n      : std_logic;
--
signal irq_out    : std_logic;
-- Registers
signal qual_write : std_logic;
--
signal qual_read  : std_logic;
signal comp_addr_hi : std_logic_vector(DATA_WIDTH-1 downto 0); -- Address High Comparator  Reg
--
signal comp_addr_lo : std_logic_vector(DATA_WIDTH-1 downto 0); -- Address Low  Comparator  Reg
-- bank select
signal comp_data    : std_logic_vector(DATA_WIDTH-1 downto 0); -- Data         Comparator  Reg
--
signal comp_ctrl    : std_logic_vector(DATA_WIDTH-1 downto 0); -- Control Sig  Comparator  Reg
signal bank_reg : std_logic_vector(7 downto 0);
signal qual_addr_hi : std_logic_vector(DATA_WIDTH-1 downto 0); -- Address High Qualifier   Reg
 
signal qual_addr_lo : std_logic_vector(DATA_WIDTH-1 downto 0); -- Address Low  Qualifier   Reg
--
signal qual_data    : std_logic_vector(DATA_WIDTH-1 downto 0); -- Data         Qualifier   Reg
-- Trigger registers
signal qual_ctrl    : std_logic_vector(DATA_WIDTH-1 downto 0); -- Control Sig  Qualifier   Reg
--
signal bank_reg     : std_logic_vector(DATA_WIDTH-1 downto 0); -- Trace Buffer Bank Select Reg
signal comp_addr_hi : std_logic_vector(7 downto 0);
signal reg_data_out : std_logic_vector(DATA_WIDTH-1 downto 0); -- Register Data Output
signal comp_addr_lo : std_logic_vector(7 downto 0);
 
signal qual_addr_hi : std_logic_vector(7 downto 0);
--
signal qual_addr_lo : std_logic_vector(7 downto 0);
-- Trace enable, counter and offset registers
signal comp_data    : std_logic_vector(7 downto 0);
--
signal qual_data    : std_logic_vector(7 downto 0);
signal trace_en     : std_logic;
signal comp_ctrl    : std_logic_vector(7 downto 0);
signal trace_count  : std_logic_vector(BUFF_SIZE-1 downto 0);
signal qual_ctrl    : std_logic_vector(7 downto 0);
signal trace_offset : std_logic_vector(BUFF_SIZE-1 downto 0);
signal match_flag   : std_logic;
 
 
--
--
-- Buffer address
-- Trace counter
--
--
signal buf_addr     : std_logic_vector(BUFF_SIZE-1 downto 0);
signal trace_clk        : std_logic;
 
signal trace_rst        : std_logic;
 
signal trace_stb        : std_logic;
 
signal trace_we         : std_logic;
 
signal trace_count      : std_logic_vector(9 downto 0);
 
signal trace_offset     : std_logic_vector(9 downto 0);
 
 
 
signal trace_data_out_0 : std_logic_vector(7 downto 0);
 
signal trace_data_out_1 : std_logic_vector(7 downto 0);
 
signal trace_data_out_2 : std_logic_vector(7 downto 0);
 
signal trace_data_out_3 : std_logic_vector(7 downto 0);
 
signal trace_data_out_4 : std_logic_vector(7 downto 0);
 
signal trace_data_out_5 : std_logic_vector(7 downto 0);
 
 
 
signal buff_stb         : std_logic_vector(5 downto 0);
 
signal buff_we          : std_logic;
 
signal buff_addr        : std_logic_vector(9 downto 0);
 
 
 
signal buff_data_out_0 : std_logic_vector(7 downto 0);
 
signal buff_data_out_1 : std_logic_vector(7 downto 0);
 
signal buff_data_out_2 : std_logic_vector(7 downto 0);
 
signal buff_data_out_3 : std_logic_vector(7 downto 0);
 
signal buff_data_out_4 : std_logic_vector(7 downto 0);
 
signal buff_data_out_5 : std_logic_vector(7 downto 0);
 
 
 
signal mux_stb         : std_logic_vector(5 downto 0);
--
 
-- Block RAM buffer Mux signals
 
--
 
signal mux_stb      : std_logic;
 
signal mux_addr     : std_logic_vector(BUFF_SIZE-1 downto 0);
signal mux_we          : std_logic;
signal mux_we          : std_logic;
signal mux_addr        : std_logic_vector(9 downto 0);
 
 
 
 
--
 
-- Block RAM trace buffer data outputs
 
--
 
signal buf_data_out_0 : std_logic_vector(DATA_WIDTH-1 downto 0);
 
signal buf_data_out_1 : std_logic_vector(DATA_WIDTH-1 downto 0);
 
signal buf_data_out_2 : std_logic_vector(DATA_WIDTH-1 downto 0);
 
signal buf_data_out_3 : std_logic_vector(DATA_WIDTH-1 downto 0);
 
signal buf_data_out_4 : std_logic_vector(DATA_WIDTH-1 downto 0);
 
signal buf_data_out   : std_logic_vector(DATA_WIDTH-1 downto 0);
 
 
 
--
 
-- Various other signals
 
--
 
signal irq_out      : std_logic;  -- Interrupt Request signal (unmasked)
 
signal qual_write   : std_logic;  -- Qualifier Control Register Write Strobe
 
signal qual_read    : std_logic;  -- Qualifier Control Register Read Strobe
 
signal trigger      : std_logic;  -- Event Trigger derived from bus comparator 
signal ctrl_in         : std_logic_vector(7 downto 0);
signal ctrl_in         : std_logic_vector(7 downto 0);
signal trigger         : std_logic;
 
 
 
component ram1k
--
 
-- Block RAM Trace buffer
 
-- For Spartan 2 these will be B4  RAMs ( 512 Bytes)
 
-- For Spartan 3 these will be B16 RAMs (2048 Bytes)
 
--
 
component trace_ram
    Port (
    Port (
            -- Port A is 8 bit
 
       WB_CLK_I  : in  std_logic;
       WB_CLK_I  : in  std_logic;
       WB_RST_I  : in  std_logic;
       WB_RST_I  : in  std_logic;
       WB_ADR_I  : in  std_logic_vector (9 downto 0);
       WB_ADR_I  : in  std_logic_vector (BUFF_SIZE-1 downto 0);
       WB_DAT_O  : out std_logic_vector (7 downto 0);
       WB_DAT_O  : out std_logic_vector (DATA_WIDTH-1 downto 0);
       WB_DAT_I  : in  std_logic_vector (7 downto 0);
       WB_DAT_I  : in  std_logic_vector (DATA_WIDTH-1 downto 0);
            WB_WE_I   : in  std_logic;
            WB_WE_I   : in  std_logic;
       WB_STB_I  : in  std_logic
       WB_STB_I  : in  std_logic
    );
    );
end component;
end component;
 
 
 
--
component BUFG
-- Start of Architecture
  port (
--
     i: in std_logic;
 
          o: out std_logic
 
  );
 
end component;
 
 
 
begin
begin
 
 
--
--
-- Bank 1 = Trace buffer cpu control out
-- Instantiate (Port Map) Block RAM trace buffers
 
--
 
 
 
--
 
-- Bank 0 - Trace buffer for CPU address high bits
--
--
my_trace_buffer_1 : ram1k port map (
trace_buffer_0 : trace_ram port map (
       WB_CLK_I  => clk,
       WB_CLK_I  => clk,
       WB_RST_I  => rst,
       WB_RST_I  => rst,
       WB_ADR_I  => mux_addr,
       WB_ADR_I  => mux_addr,
       WB_DAT_O  => buff_data_out_1,
       WB_DAT_O  => buf_data_out_0,
       WB_DAT_I  => ctrl_in(7 downto 0),
       WB_DAT_I  => addr((2*DATA_WIDTH)-1 downto DATA_WIDTH),
            WB_WE_I   => mux_we,
            WB_WE_I   => mux_we,
       WB_STB_I  => mux_stb(1)
       WB_STB_I  => mux_stb
    );
    );
 
 
--
--
-- Trace buffer 2 is cpu address out high
-- Bank 1 - Trace buffer for CPU address low bits
--
--
my_trace_buffer_2 : ram1k port map (
trace_buffer_1 : trace_ram port map (
       WB_CLK_I  => clk,
       WB_CLK_I  => clk,
       WB_RST_I  => rst,
       WB_RST_I  => rst,
       WB_ADR_I  => mux_addr,
       WB_ADR_I  => mux_addr,
       WB_DAT_O  => buff_data_out_2,
       WB_DAT_O  => buf_data_out_1,
       WB_DAT_I  => addr(15 downto 8),
       WB_DAT_I  => addr(DATA_WIDTH-1 downto 0),
            WB_WE_I   => mux_we,
            WB_WE_I   => mux_we,
       WB_STB_I  => mux_stb(2)
       WB_STB_I  => mux_stb
    );
    );
 
 
--
--
-- Trace buffer 3 is cpu address out low
-- Bank 2 - Trace buffer for CPU data out (write)
--
--
my_trace_buffer_3 : ram1k port map (
trace_buffer_2 : trace_ram port map (
       WB_CLK_I  => clk,
       WB_CLK_I  => clk,
       WB_RST_I  => rst,
       WB_RST_I  => rst,
       WB_ADR_I  => mux_addr,
       WB_ADR_I  => mux_addr,
       WB_DAT_O  => buff_data_out_3,
       WB_DAT_O  => buf_data_out_2,
       WB_DAT_I  => addr(7 downto 0),
       WB_DAT_I  => data_in(DATA_WIDTH-1 downto 0),
            WB_WE_I   => mux_we,
            WB_WE_I   => mux_we,
       WB_STB_I  => mux_stb(3)
       WB_STB_I  => mux_stb
    );
    );
 
 
--
--
-- Trace buffer 4 is cpu data out
-- Bank 3 - Trace buffer for CPU data in (read)
--
--
my_trace_buffer_4 : ram1k port map (
trace_buffer_3 : trace_ram port map (
       WB_CLK_I  => clk,
       WB_CLK_I  => clk,
       WB_RST_I  => rst,
       WB_RST_I  => rst,
       WB_ADR_I  => mux_addr,
       WB_ADR_I  => mux_addr,
       WB_DAT_O  => buff_data_out_4,
       WB_DAT_O  => buf_data_out_3,
       WB_DAT_I  => data_in(7 downto 0),
       WB_DAT_I  => cpu_data_in(DATA_WIDTH-1 downto 0),
            WB_WE_I   => mux_we,
            WB_WE_I   => mux_we,
       WB_STB_I  => mux_stb(4)
       WB_STB_I  => mux_stb
    );
    );
 
 
--
--
-- Trace buffer 5 is cpu data in
-- Bank 4 - Trace buffer for CPU control bits
--
--
my_trace_buffer_5 : ram1k port map (
trace_buffer_4 : trace_ram port map (
       WB_CLK_I  => clk,
       WB_CLK_I  => clk,
       WB_RST_I  => rst,
       WB_RST_I  => rst,
       WB_ADR_I  => mux_addr,
       WB_ADR_I  => mux_addr,
       WB_DAT_O  => buff_data_out_5,
       WB_DAT_O  => buf_data_out_4,
       WB_DAT_I  => cpu_data_in(7 downto 0),
       WB_DAT_I  => ctrl_in(DATA_WIDTH-1 downto 0),
            WB_WE_I   => mux_we,
            WB_WE_I   => mux_we,
       WB_STB_I  => mux_stb(5)
       WB_STB_I  => mux_stb
    );
    );
 
 
 
 
--clk_buffer : BUFG port map(
 
--      i => clk_n,
 
--         o => trace_clk
 
--   );  
 
 
 
--------------------------------
 
--
 
-- write page bank register
 
--
 
--------------------------------
 
bank_reg_write : process( clk, rst, rs, rw, data_in, bank_reg)
 
begin
 
        if clk'event and clk = '0' then
 
                if rst = '1' then
 
                        bank_reg <= "00000000";
 
                else
 
                        if rs='1' and rw='0' then
 
                                bank_reg <= data_in;
 
                        else
 
                           bank_reg <= bank_reg;
 
                        end if;
 
                end if;
 
        end if;
 
end process;
 
 
 
 
 
--------------------------------
--------------------------------
--
--
-- read page buffers
-- Assign control signal input
--
--
--------------------------------
--------------------------------
 
 
buffer_read : process(  bs, bank_reg,
trace_ctrl_assign : process( irq_out, qual_ctrl, rw, cpu_vma )
                                                                buff_data_out_0, buff_data_out_1, buff_data_out_2, buff_data_out_3,
 
                                                                buff_data_out_4, buff_data_out_5 )
 
variable count : integer;
 
begin
begin
        for count in 0 to 5 loop
  ctrl_in(0) <= rw;
                buff_stb(count) <= '0';
  ctrl_in(1) <= cpu_vma;
        end loop;
  ctrl_in(7 downto 2) <= (others=>'0');
 
 
        case bank_reg(2 downto 0) is
 
        when "000" =>
 
                buff_stb(0)   <= bs;
 
                buff_data_out <= buff_data_out_0;
 
        when "001" =>
 
           buff_stb(1)   <= bs;
 
                buff_data_out <= buff_data_out_1;
 
        when "010" =>
 
                buff_stb(2)   <= bs;
 
                buff_data_out <= buff_data_out_2;
 
        when "011" =>
 
                buff_stb(3)   <= bs;
 
                buff_data_out <= buff_data_out_3;
 
        when "100" =>
 
                buff_stb(4)   <= bs;
 
                buff_data_out <= buff_data_out_4;
 
        when "101" =>
 
                buff_stb(5)   <= bs;
 
                buff_data_out <= buff_data_out_5;
 
   when others =>
 
                buff_data_out <= "00000000";
 
        end case;
 
 
 
        reg_data_out <= bank_reg;
 
 
 
end process;
end process;
 
 
--------------------------------
--------------------------------
--
--
-- write control registers
-- Write Trace Registers
--
--
--------------------------------
--------------------------------
trace_write : process( clk, rst, bs, rw, addr, data_in, qual_write,
 
                      comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
trace_reg_write : process( clk, rst, cs_r, rw, addr, data_in )
                      qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl )
 
begin
begin
  if clk'event and clk = '0' then
  if clk'event and clk = '0' then
    if rst = '1' then
 
                  comp_addr_hi <= "00000000";
 
                  comp_addr_lo <= "00000000";
 
                  comp_data    <= "00000000";
 
                  comp_ctrl    <= "00000000";
 
                  qual_addr_hi <= "00000000";
 
                  qual_addr_lo <= "00000000";
 
                  qual_data    <= "00000000";
 
                  qual_ctrl    <= "00000000";
 
                  qual_write  <= '0';
                  qual_write  <= '0';
    elsif buff_stb(0) = '1' and rw = '0' then
    if rst = '1' then
           case addr(2 downto 0) is
      comp_addr_hi <= (others=>'0');
                when "000" =>
      comp_addr_lo <= (others=>'0');
 
      comp_data    <= (others=>'0');
 
      comp_ctrl    <= (others=>'0');
 
      qual_addr_hi <= (others=>'0');
 
      qual_addr_lo <= (others=>'0');
 
      qual_data    <= (others=>'0');
 
      qual_ctrl    <= (others=>'0');
 
      bank_reg     <= (others=>'0');
 
    elsif cs_r = '1' and rw = '0' then
 
      case addr(3 downto 0) is
 
      when "0000" =>
                  comp_addr_hi <= data_in;
                  comp_addr_hi <= data_in;
                  comp_addr_lo <= comp_addr_lo;
      when "0001" =>
                  comp_data    <= comp_data;
 
                  comp_ctrl    <= comp_ctrl;
 
                  qual_addr_hi <= qual_addr_hi;
 
                  qual_addr_lo <= qual_addr_lo;
 
                  qual_data    <= qual_data;
 
                  qual_ctrl    <= qual_ctrl;
 
                  qual_write  <= '0';
 
                when "001" =>
 
                  comp_addr_hi <= comp_addr_hi;
 
                  comp_addr_lo <= data_in;
                  comp_addr_lo <= data_in;
                  comp_data    <= comp_data;
      when "0010" =>
                  comp_ctrl    <= comp_ctrl;
 
                  qual_addr_hi <= qual_addr_hi;
 
                  qual_addr_lo <= qual_addr_lo;
 
                  qual_data    <= qual_data;
 
                  qual_ctrl    <= qual_ctrl;
 
                  qual_write  <= '0';
 
                when "010" =>
 
                  comp_addr_hi <= comp_addr_hi;
 
                  comp_addr_lo <= comp_addr_lo;
 
                  comp_data    <= data_in;
                  comp_data    <= data_in;
                  comp_ctrl    <= comp_ctrl;
      when "0011" =>
                  qual_addr_hi <= qual_addr_hi;
 
                  qual_addr_lo <= qual_addr_lo;
 
                  qual_data    <= qual_data;
 
                  qual_ctrl    <= qual_ctrl;
 
                  qual_write  <= '0';
 
                when "011" =>
 
                  comp_addr_hi <= comp_addr_hi;
 
                  comp_addr_lo <= comp_addr_lo;
 
                  comp_data    <= comp_data;
 
                  comp_ctrl    <= data_in;
                  comp_ctrl    <= data_in;
                  qual_addr_hi <= qual_addr_hi;
      when "0100" =>
                  qual_addr_lo <= qual_addr_lo;
 
                  qual_data    <= qual_data;
 
                  qual_ctrl    <= qual_ctrl;
 
                  qual_write  <= '0';
 
                when "100" =>
 
                  comp_addr_hi <= comp_addr_hi;
 
                  comp_addr_lo <= comp_addr_lo;
 
                  comp_data    <= comp_data;
 
                  comp_ctrl    <= comp_ctrl;
 
                  qual_addr_hi <= data_in;
                  qual_addr_hi <= data_in;
                  qual_addr_lo <= qual_addr_lo;
      when "0101" =>
                  qual_data    <= qual_data;
 
                  qual_ctrl    <= qual_ctrl;
 
                  qual_write  <= '0';
 
                when "101" =>
 
                  comp_addr_hi <= comp_addr_hi;
 
                  comp_addr_lo <= comp_addr_lo;
 
                  comp_data    <= comp_data;
 
                  comp_ctrl    <= comp_ctrl;
 
                  qual_addr_hi <= qual_addr_hi;
 
                  qual_addr_lo <= data_in;
                  qual_addr_lo <= data_in;
                  qual_data    <= qual_data;
      when "0110" =>
                  qual_ctrl    <= qual_ctrl;
 
                  qual_write  <= '0';
 
                when "110" =>
 
                  comp_addr_hi <= comp_addr_hi;
 
                  comp_addr_lo <= comp_addr_lo;
 
                  comp_data    <= comp_data;
 
                  comp_ctrl    <= comp_ctrl;
 
                  qual_addr_hi <= qual_addr_hi;
 
                  qual_addr_lo <= qual_addr_lo;
 
                  qual_data    <= data_in;
                  qual_data    <= data_in;
                  qual_ctrl    <= qual_ctrl;
      when "0111" =>
                  qual_write  <= '0';
 
--              when "111" =>
 
      when others =>
 
                  comp_addr_hi <= comp_addr_hi;
 
                  comp_addr_lo <= comp_addr_lo;
 
                  comp_data    <= comp_data;
 
                  comp_ctrl    <= comp_ctrl;
 
                  qual_addr_hi <= qual_addr_hi;
 
                  qual_addr_lo <= qual_addr_lo;
 
                  qual_data    <= qual_data;
 
                  qual_ctrl    <= data_in;
                  qual_ctrl    <= data_in;
                  qual_write  <= '1';
                  qual_write  <= '1';
 
      when others =>
 
        bank_reg     <= data_in;
                end case;
                end case;
         else
 
                  comp_addr_hi <= comp_addr_hi;
 
                  comp_addr_lo <= comp_addr_lo;
 
                  comp_data    <= comp_data;
 
                  comp_ctrl    <= comp_ctrl;
 
                  qual_addr_hi <= qual_addr_hi;
 
                  qual_addr_lo <= qual_addr_lo;
 
                  qual_data    <= qual_data;
 
                  qual_ctrl    <= qual_ctrl;
 
                  qual_write  <= '0';
 
         end if;
         end if;
  end if;
  end if;
end process;
end process;
 
 
 
------------------------------------------
--
--
-- trap data output mux
-- Read Trace Register (output mux)
--
--
trace_read : process( buff_stb, rw, addr, qual_read,
------------------------------------------
 
trace_reg_read : process( addr, rw, cs_r,
                     comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
                     comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
                     qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl,
                     qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl,
                                                        match_flag )
                          bank_reg, irq_out )
begin
begin
   case addr(2 downto 0) is
 
        when "000" =>
 
           buff_data_out_0  <= comp_addr_hi;
 
                qual_read <= '0';
                qual_read <= '0';
 
  case addr(3 downto 0) is
 
  when "0000" =>
 
    reg_data_out <= comp_addr_hi;
 
  when "0001" =>
 
    reg_data_out <= comp_addr_lo;
 
  when "0010" =>
 
    reg_data_out <= comp_data;
 
  when "0011" =>
 
    reg_data_out <= comp_ctrl;
 
  when "0100" =>
 
    reg_data_out <= qual_addr_hi;
 
  when "0101" =>
 
    reg_data_out <= qual_addr_lo;
 
  when "0110" =>
 
    reg_data_out <= qual_data;
 
  when "0111" =>
 
    qual_read    <= cs_r and rw;
 
    reg_data_out(6 downto 0) <= qual_ctrl(6 downto 0);
 
    reg_data_out(7) <= irq_out;
 
  when others =>
 
    reg_data_out <= bank_reg;
 
  end case;
 
 
 
end process;
 
 
 
 
 
--------------------------------
 
--
 
-- Read Trace Buffers
 
--
 
--------------------------------
 
 
 
trace_buf_read : process( bank_reg, buf_data_out_0, buf_data_out_1,
 
                          buf_data_out_2, buf_data_out_3, buf_data_out_4 )
 
begin
 
  case bank_reg(2 downto 0) is
 
  when "000" =>
 
    buf_data_out <= buf_data_out_0;
        when "001" =>
        when "001" =>
           buff_data_out_0  <= comp_addr_lo;
    buf_data_out <= buf_data_out_1;
                qual_read <= '0';
 
        when "010" =>
        when "010" =>
           buff_data_out_0  <= comp_data;
    buf_data_out <= buf_data_out_2;
                qual_read <= '0';
 
        when "011" =>
        when "011" =>
           buff_data_out_0  <= comp_ctrl;
    buf_data_out <= buf_data_out_3;
                qual_read <= '0';
 
        when "100" =>
        when "100" =>
           buff_data_out_0  <= qual_addr_hi;
    buf_data_out <= buf_data_out_4;
                qual_read <= '0';
 
        when "101" =>
 
           buff_data_out_0  <= qual_addr_lo;
 
                qual_read <= '0';
 
        when "110" =>
 
           buff_data_out_0  <= qual_data;
 
                qual_read <= '0';
 
--      when "111" =>
 
   when others =>
   when others =>
                qual_read <= buff_stb(0) and rw;
    buf_data_out <= (others=>'0');
           buff_data_out_0(6 downto 0) <= qual_ctrl(6 downto 0);
 
                buff_data_out_0(7) <= match_flag;
 
        end case;
        end case;
end process;
end process;
 
 
mux_proc : process( bs, rw,
--------------------------------
                    trace_count, buff_addr,
--
                                                  trace_we,   buff_we,
-- Read Registers or Buffers
                                                  trace_stb,  buff_stb )
--
 
--------------------------------
 
 
 
trace_read : process( cs_r, reg_data_out, buf_data_out )
begin
begin
 
  if cs_r = '1' then
 
    data_out = reg_data_out;
 
  else
 
    data_out = buf_data_out;
 
  else
 
end process;
 
 
        if bs='0' and rw='1' then
 
 
------------------------------------------------------------------------
 
--
 
-- Multiplex the trace buffer between the trace capture and the CPU read
 
--
 
------------------------------------------------------------------------
 
 
 
trace_buf_mux : process( cs_b, trace_count, trace_en, buf_addr )
 
begin
 
  if cs_b = '0' then
                mux_addr <= trace_count;
                mux_addr <= trace_count;
                mux_we   <= trace_we;
    mux_we   <= '1';
                mux_stb  <= trace_stb & trace_stb & trace_stb & trace_stb & trace_stb & trace_stb;
    mux_stb  <= trace_en;
        else
        else
                mux_addr <= buff_addr;
    mux_addr <= buf_addr;
                mux_we   <= buff_we;
    mux_we   <= '0';
                mux_stb  <= buff_stb;
    mux_stb  <= '1';
        end if;
        end if;
 
 
end process;
end process;
 
 
 
------------------------------
--
--
-- Trigger hardware
-- Trigger comparator process
--
--
trace_match : process( Clk, rst, rw, buff_stb, addr, vma, match_flag, data_in,
------------------------------
 
 
 
trace_trigger : process( clk, rst, cs_r, addr, rw, cpu_vma, data_in, cpu_data_in,
                      comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
                      comp_addr_hi, comp_addr_lo, comp_data, comp_ctrl,
                                                         qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl)
                                                         qual_addr_hi, qual_addr_lo, qual_data, qual_ctrl)
variable match         : std_logic;
variable hit          : std_logic;
variable match_addr_hi : std_logic;
variable miss_addr_hi : std_logic;
variable match_addr_lo : std_logic;
variable miss_addr_lo : std_logic;
variable match_data    : std_logic;
variable miss_data_rd : std_logic;
variable match_ctrl    : std_logic;
variable miss_data_wr : std_logic;
 
variable miss_ctrl    : std_logic;
 
 
begin
begin
  match_addr_hi :=
  miss_addr_hi :=
           ((comp_addr_hi(7) xor addr(15)  ) and qual_addr_hi(7) ) or
           ((comp_addr_hi(7) xor addr(15)  ) and qual_addr_hi(7) ) or
                     ((comp_addr_hi(6) xor addr(14)  ) and qual_addr_hi(6) ) or
                     ((comp_addr_hi(6) xor addr(14)  ) and qual_addr_hi(6) ) or
                     ((comp_addr_hi(5) xor addr(13)  ) and qual_addr_hi(5) ) or
                     ((comp_addr_hi(5) xor addr(13)  ) and qual_addr_hi(5) ) or
                     ((comp_addr_hi(4) xor addr(12)  ) and qual_addr_hi(4) ) or
                     ((comp_addr_hi(4) xor addr(12)  ) and qual_addr_hi(4) ) or
                     ((comp_addr_hi(3) xor addr(11)  ) and qual_addr_hi(3) ) or
                     ((comp_addr_hi(3) xor addr(11)  ) and qual_addr_hi(3) ) or
                     ((comp_addr_hi(2) xor addr(10)  ) and qual_addr_hi(2) ) or
                     ((comp_addr_hi(2) xor addr(10)  ) and qual_addr_hi(2) ) or
                     ((comp_addr_hi(1) xor addr( 9)  ) and qual_addr_hi(1) ) or
                     ((comp_addr_hi(1) xor addr( 9)  ) and qual_addr_hi(1) ) or
                     ((comp_addr_hi(0) xor addr( 8)  ) and qual_addr_hi(0) );
                     ((comp_addr_hi(0) xor addr( 8)  ) and qual_addr_hi(0) );
  match_addr_lo :=
  miss_addr_lo :=
                     ((comp_addr_lo(7) xor addr( 7)  ) and qual_addr_lo(7) ) or
                     ((comp_addr_lo(7) xor addr( 7)  ) and qual_addr_lo(7) ) or
                     ((comp_addr_lo(6) xor addr( 6)  ) and qual_addr_lo(6) ) or
                     ((comp_addr_lo(6) xor addr( 6)  ) and qual_addr_lo(6) ) or
                     ((comp_addr_lo(5) xor addr( 5)  ) and qual_addr_lo(5) ) or
                     ((comp_addr_lo(5) xor addr( 5)  ) and qual_addr_lo(5) ) or
                     ((comp_addr_lo(4) xor addr( 4)  ) and qual_addr_lo(4) ) or
                     ((comp_addr_lo(4) xor addr( 4)  ) and qual_addr_lo(4) ) or
                     ((comp_addr_lo(3) xor addr( 3)  ) and qual_addr_lo(3) ) or
                     ((comp_addr_lo(3) xor addr( 3)  ) and qual_addr_lo(3) ) or
                     ((comp_addr_lo(2) xor addr( 2)  ) and qual_addr_lo(2) ) or
                     ((comp_addr_lo(2) xor addr( 2)  ) and qual_addr_lo(2) ) or
                     ((comp_addr_lo(1) xor addr( 1)  ) and qual_addr_lo(1) ) or
                     ((comp_addr_lo(1) xor addr( 1)  ) and qual_addr_lo(1) ) or
                     ((comp_addr_lo(0) xor addr( 0)  ) and qual_addr_lo(0) );
                     ((comp_addr_lo(0) xor addr( 0)  ) and qual_addr_lo(0) );
  match_data :=
  miss_data_wr :=
           ((comp_data(7)    xor data_in(7)) and qual_data(7)    ) or
           ((comp_data(7)    xor data_in(7)) and qual_data(7)    ) or
           ((comp_data(6)    xor data_in(6)) and qual_data(6)    ) or
           ((comp_data(6)    xor data_in(6)) and qual_data(6)    ) or
           ((comp_data(5)    xor data_in(5)) and qual_data(5)    ) or
           ((comp_data(5)    xor data_in(5)) and qual_data(5)    ) or
           ((comp_data(4)    xor data_in(4)) and qual_data(4)    ) or
           ((comp_data(4)    xor data_in(4)) and qual_data(4)    ) or
           ((comp_data(3)    xor data_in(3)) and qual_data(3)    ) or
           ((comp_data(3)    xor data_in(3)) and qual_data(3)    ) or
           ((comp_data(2)    xor data_in(2)) and qual_data(2)    ) or
           ((comp_data(2)    xor data_in(2)) and qual_data(2)    ) or
           ((comp_data(1)    xor data_in(1)) and qual_data(1)    ) or
           ((comp_data(1)    xor data_in(1)) and qual_data(1)    ) or
           ((comp_data(0)    xor data_in(0)) and qual_data(0)    );
           ((comp_data(0)    xor data_in(0)) and qual_data(0)    );
  match_ctrl :=
  miss_data_rd :=
 
     ((comp_data(7)    xor cpu_data_in(7)) and qual_data(7)    ) or
 
     ((comp_data(6)    xor cpu_data_in(6)) and qual_data(6)    ) or
 
     ((comp_data(5)    xor cpu_data_in(5)) and qual_data(5)    ) or
 
     ((comp_data(4)    xor cpu_data_in(4)) and qual_data(4)    ) or
 
     ((comp_data(3)    xor cpu_data_in(3)) and qual_data(3)    ) or
 
     ((comp_data(2)    xor cpu_data_in(2)) and qual_data(2)    ) or
 
     ((comp_data(1)    xor cpu_data_in(1)) and qual_data(1)    ) or
 
     ((comp_data(0)    xor cpu_data_in(0)) and qual_data(0)    );
 
  miss_ctrl :=
           ((comp_ctrl(0)    xor rw        ) and qual_ctrl(0)    ) or
           ((comp_ctrl(0)    xor rw        ) and qual_ctrl(0)    ) or
           ((comp_ctrl(1)    xor vma       ) and qual_ctrl(1)    );
     ((comp_ctrl(1)    xor cpu_vma   ) and qual_ctrl(1)    );
 
 
   match := not ( match_addr_hi or match_addr_lo or match_data or match_ctrl);
  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);
 
  trigger <= not(hit xor comp_ctrl(7));
 
 
    if clk'event and clk = '0' then
 
           if rst = '1' then
 
                  match_flag <= '0';
 
      elsif buff_stb(0) = '1' and rw = '0' then
 
                  match_flag <= '0';
 
      else
 
                  if match = comp_ctrl(7) then
 
                    match_flag <= '1';
 
                  else
 
                    match_flag <= match_flag;
 
                  end if;
 
 
 
                end if;
 
    end if;
 
         trigger <= match_flag;
 
  end process;
  end process;
 
 
trace_capture : process( clk, rst, qual_read, qual_write,
-----------------------------------------
                                                                 trigger, trace_stb, qual_ctrl, irq_out,
--
 
-- Trace buffer capture on event trigger
 
--
 
-----------------------------------------
 
 
 
trace_capture : process( clk, rst, addr, qual_write,
 
                         trigger, trace_en, qual_ctrl, irq_out,
                         trace_count, trace_offset )
                         trace_count, trace_offset )
variable irq_tmp : std_logic;
 
begin
begin
  if clk'event and clk = '1' then
  if clk'event and clk = '1' then
    if rst = '1' then
    if rst = '1' then
                trace_count  <= "0000000000";
      trace_count  <= (others=>'0');
                trace_offset <= "0000000000";
      trace_offset <= (others=>'0');
                trace_stb    <= qual_ctrl(6);
      trace_en     <= '0';
 
      irq_out      <= '0';
         else
         else
           --
           --
                -- zero in bit 6 of the qalifier control register
      -- qualifier control register bit 6 = zero
                -- means start capture after trigger point.
                -- means start capture after trigger point.
                --
                --
                if qual_ctrl(6) = '0' then
                if qual_ctrl(6) = '0' then
 
 
                        if trace_stb = '0' then
        --
                                trace_stb    <= trigger;
        -- Activate trace on a trigger condition
                                irq_tmp      := irq_out;
        -- Deactive trace when the buffer is full
 
        --
 
        if trace_en = '0' then
 
          trace_en     <= trigger;
 
        elsif trace_count = trace_offset then
                                trace_offset <= trace_count;
                                trace_offset <= trace_count;
                        else
          trace_en     <= '0';
                                if trace_count = trace_offset then
 
                                        trace_stb <= '0';
 
                                        irq_tmp   := '1';
 
                                else
 
                                        trace_stb  <= trace_stb;
 
                                        irq_tmp    := irq_out;
 
                                end if;
 
                                trace_offset <= trace_offset;
 
                        end if;
                        end if;
 
 
                        if qual_read = '1' then
        --
 
        -- Set IRQ on trace buffer full
 
        -- Reset IRQ on qualifier control register write
 
        --
 
        if qual_write = '1' then
                                irq_out <= '0';
                                irq_out <= '0';
                        else
        elsif trace_count = trace_offset then
                                irq_out <= irq_tmp;
          irq_out   <= '1';
                        end if;
                        end if;
 
 
           --
           --
                -- one in bit 6 of the qalifier control register
      -- qualifier control register bit 6 = one
                -- means finish capture at trigger point.
                -- means finish capture at trigger point.
                --
                --
                else
                else
                if trace_stb = '0' then
        --
                                trace_stb    <= qual_write;
        -- Activate trace on qualifier control write
                                trace_offset <= trace_offset;
        -- Deactivate trace on a trigger condition
                                irq_tmp      := irq_out;
        --
                        else
        if trace_en = '0' then
                                if trigger = '1' then
          trace_en     <= qual_write;
 
        elsif trigger = '1' then
                                   trace_offset <= trace_count;
                                   trace_offset <= trace_count;
                                        trace_stb    <= '0';
          trace_en     <= '0';
                                        irq_tmp      := '1';
 
                                else
 
                                        trace_offset <= trace_offset;
 
                                        trace_stb    <= trace_stb;
 
                                        irq_tmp      := irq_out;
 
                                end if;
 
                        end if;
                        end if;
 
 
 
        --
 
        -- Set IRQ on a trigger condition
 
        -- Reset IRQ on qualifier control register write
 
        --
                        if qual_write = '1' then
                        if qual_write = '1' then
                                irq_out <= '0';
                                irq_out <= '0';
                        else
        elsif trigger = '1' then
                                irq_out <= irq_tmp;
          irq_out <= '1';
                        end if;
                        end if;
 
 
                end if;
                end if;
 
 
                trace_count <= trace_count + 1;
                trace_count <= trace_count + 1;
 
 
         end if;
         end if;
  end if;
  end if;
end process;
 
 
 
--
--
-- Tie up a few signals
  -- The IRQ output is qualified by the interrupt enable bit
 
  -- (bit 7 of the qualifier control register)
--
--
process( clk, rst, addr, vma, rw, irq_out, trace_offset, qual_ctrl, trace_stb )
 
begin
 
  trace_clk  <= clk;
 
  trace_rst  <= rst;
 
  trace_we   <= trace_stb;
 
  buff_addr  <= addr(9 downto 0) + trace_offset;
 
  buff_we    <= '0';
 
  irq        <= irq_out and qual_ctrl(7);
  irq        <= irq_out and qual_ctrl(7);
  ctrl_in(0) <= rw;
 
  ctrl_in(1) <= vma;
  --
  ctrl_in(7 downto 2) <= "000000";
  -- Trace buffer is offset by start address
 
  --
 
  buf_addr  <= addr(BUFF_SIZE-1 downto 0) + trace_offset;
 
 
end process;
end process;
 
 
end trace_arch;
end trace_arch;
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.