1 |
2 |
dimamali |
------------------------------------------------------------------------------
|
2 |
|
|
-- This file is a part of the GRLIB VHDL IP LIBRARY
|
3 |
|
|
-- Copyright (C) 2003, Gaisler Research
|
4 |
|
|
--
|
5 |
|
|
-- This program is free software; you can redistribute it and/or modify
|
6 |
|
|
-- it under the terms of the GNU General Public License as published by
|
7 |
|
|
-- the Free Software Foundation; either version 2 of the License, or
|
8 |
|
|
-- (at your option) any later version.
|
9 |
|
|
--
|
10 |
|
|
-- This program is distributed in the hope that it will be useful,
|
11 |
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13 |
|
|
-- GNU General Public License for more details.
|
14 |
|
|
--
|
15 |
|
|
-- You should have received a copy of the GNU General Public License
|
16 |
|
|
-- along with this program; if not, write to the Free Software
|
17 |
|
|
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18 |
|
|
-----------------------------------------------------------------------------
|
19 |
|
|
-- Entity: pcitrace
|
20 |
|
|
-- File: pcitrace.vhd
|
21 |
|
|
-- Author: Jiri Gaisler - Gaisler Research
|
22 |
|
|
-- Description: PCI trace buffer
|
23 |
|
|
------------------------------------------------------------------------------
|
24 |
|
|
|
25 |
|
|
library ieee;
|
26 |
|
|
use ieee.std_logic_1164.all;
|
27 |
|
|
|
28 |
|
|
library grlib;
|
29 |
|
|
use grlib.amba.all;
|
30 |
|
|
use grlib.stdlib.all;
|
31 |
|
|
use grlib.devices.all;
|
32 |
|
|
library techmap;
|
33 |
|
|
use techmap.gencomp.all;
|
34 |
|
|
|
35 |
|
|
library gaisler;
|
36 |
|
|
use gaisler.pci.all;
|
37 |
|
|
|
38 |
|
|
entity pcitrace is
|
39 |
|
|
generic (
|
40 |
|
|
depth : integer range 6 to 12 := 8;
|
41 |
|
|
iregs : integer := 1;
|
42 |
|
|
memtech : integer := DEFMEMTECH;
|
43 |
|
|
pindex : integer := 0;
|
44 |
|
|
paddr : integer := 0;
|
45 |
|
|
pmask : integer := 16#f00#
|
46 |
|
|
);
|
47 |
|
|
port (
|
48 |
|
|
rst : in std_ulogic;
|
49 |
|
|
clk : in std_ulogic;
|
50 |
|
|
pciclk : in std_ulogic;
|
51 |
|
|
pcii : in pci_in_type;
|
52 |
|
|
apbi : in apb_slv_in_type;
|
53 |
|
|
apbo : out apb_slv_out_type
|
54 |
|
|
);
|
55 |
|
|
end;
|
56 |
|
|
|
57 |
|
|
architecture rtl of pcitrace is
|
58 |
|
|
|
59 |
|
|
constant REVISION : amba_version_type := 0;
|
60 |
|
|
|
61 |
|
|
constant pconfig : apb_config_type := (
|
62 |
|
|
|
63 |
|
|
1 => apb_iobar(paddr, pmask));
|
64 |
|
|
|
65 |
|
|
type reg_type is record
|
66 |
|
|
sample : std_ulogic;
|
67 |
|
|
armed : std_ulogic;
|
68 |
|
|
busy : std_ulogic;
|
69 |
|
|
timeout : std_logic_vector(depth-1 downto 0);
|
70 |
|
|
admask : std_logic_vector(31 downto 0);
|
71 |
|
|
adpattern : std_logic_vector(31 downto 0);
|
72 |
|
|
sigmask : std_logic_vector(15 downto 0);
|
73 |
|
|
sigpattern : std_logic_vector(15 downto 0);
|
74 |
|
|
count : std_logic_vector(7 downto 0);
|
75 |
|
|
end record;
|
76 |
|
|
|
77 |
|
|
type pci_reg_type is record
|
78 |
|
|
sample : std_ulogic;
|
79 |
|
|
armed : std_ulogic;
|
80 |
|
|
sync : std_ulogic;
|
81 |
|
|
start : std_ulogic;
|
82 |
|
|
timeout : std_logic_vector(depth-1 downto 0);
|
83 |
|
|
baddr : std_logic_vector(depth-1 downto 0);
|
84 |
|
|
count : std_logic_vector(7 downto 0);
|
85 |
|
|
end record;
|
86 |
|
|
|
87 |
|
|
signal r, rin : reg_type;
|
88 |
|
|
signal csad, csctrl : std_ulogic;
|
89 |
|
|
signal pr, prin : pci_reg_type;
|
90 |
|
|
signal bufout : std_logic_vector(47 downto 0);
|
91 |
|
|
signal pciad : std_logic_vector(31 downto 0);
|
92 |
|
|
signal vcc : std_ulogic;
|
93 |
|
|
signal pcictrlin, pcictrl : std_logic_vector(15 downto 0);
|
94 |
|
|
|
95 |
|
|
begin
|
96 |
|
|
|
97 |
|
|
vcc <= '1';
|
98 |
|
|
|
99 |
|
|
comb: process(pcii, apbi, rst, r, pr, bufout)
|
100 |
|
|
variable v : reg_type;
|
101 |
|
|
variable rdata : std_logic_vector(31 downto 0);
|
102 |
|
|
variable paddr : std_logic_vector(3 downto 0);
|
103 |
|
|
variable vcsad, vcssig : std_ulogic;
|
104 |
|
|
begin
|
105 |
|
|
v := r; vcsad := '0'; vcssig := '0'; rdata := (others => '0');
|
106 |
|
|
v.sample := r.armed and not pr.armed; v.busy := pr.sample;
|
107 |
|
|
if (r.sample and pr.armed) = '1' then v.armed := '0'; end if;
|
108 |
|
|
|
109 |
|
|
--registers
|
110 |
|
|
paddr := apbi.paddr(15) & apbi.paddr(4 downto 2);
|
111 |
|
|
if apbi.penable = '1' then
|
112 |
|
|
if (apbi.pwrite and apbi.psel(pindex)) = '1' then
|
113 |
|
|
case paddr is
|
114 |
|
|
when "0000" => v.admask := apbi.pwdata;
|
115 |
|
|
when "0001" => v.sigmask := apbi.pwdata(15 downto 0);
|
116 |
|
|
when "0010" => v.adpattern := apbi.pwdata;
|
117 |
|
|
when "0011" => v.sigpattern := apbi.pwdata(15 downto 0);
|
118 |
|
|
when "0100" => v.timeout := apbi.pwdata(depth-1 downto 0);
|
119 |
|
|
when "0101" => v.armed := '1';
|
120 |
|
|
when "0111" => v.count := apbi.pwdata(7 downto 0);
|
121 |
|
|
when others =>
|
122 |
|
|
if apbi.paddr(15 downto 14) = "10" then vcsad := '1';
|
123 |
|
|
elsif apbi.paddr(15 downto 14) = "11" then vcssig := '1'; end if;
|
124 |
|
|
end case;
|
125 |
|
|
end if;
|
126 |
|
|
case paddr is
|
127 |
|
|
when "0000" => rdata := r.admask;
|
128 |
|
|
when "0001" => rdata(15 downto 0) := r.sigmask;
|
129 |
|
|
when "0010" => rdata := r.adpattern;
|
130 |
|
|
when "0011" => rdata(15 downto 0) := r.sigpattern;
|
131 |
|
|
when "0100" => rdata(depth-1 downto 0) := r.timeout;
|
132 |
|
|
when "0101" => rdata(0) := r.busy;
|
133 |
|
|
when "0110" => rdata(3 downto 0) := conv_std_logic_vector(depth, 4);
|
134 |
|
|
when "0111" =>
|
135 |
|
|
rdata(depth-1+16 downto 16) := pr.baddr;
|
136 |
|
|
rdata(15 downto 0) := pr.count & r.count;
|
137 |
|
|
when others =>
|
138 |
|
|
if apbi.paddr(15 downto 14) = "10" then
|
139 |
|
|
vcsad := '1'; rdata := bufout(31 downto 0);
|
140 |
|
|
elsif apbi.paddr(15 downto 14) = "11" then
|
141 |
|
|
vcssig := '1'; rdata(15 downto 0) := bufout(47 downto 32);
|
142 |
|
|
end if;
|
143 |
|
|
end case;
|
144 |
|
|
end if;
|
145 |
|
|
|
146 |
|
|
if rst = '0' then
|
147 |
|
|
v.sample := '0'; v.armed := '0'; v.admask := (others => '0');
|
148 |
|
|
v.sigmask := (others => '0'); v.adpattern := (others => '0');
|
149 |
|
|
v.sigpattern := (others => '0'); v.timeout := (others => '0');
|
150 |
|
|
end if;
|
151 |
|
|
|
152 |
|
|
csad <= vcsad; csctrl <= vcssig; apbo.prdata <= rdata; rin <= v;
|
153 |
|
|
|
154 |
|
|
end process;
|
155 |
|
|
|
156 |
|
|
comb2 : process(r, pr, pciclk, pcii, pcictrl, rst)
|
157 |
|
|
variable v : pci_reg_type;
|
158 |
|
|
constant z : std_logic_vector(47 downto 0) := (others => '0');
|
159 |
|
|
begin
|
160 |
|
|
v := pr; v.sync := (r.sample and not pr.armed);
|
161 |
|
|
if (pr.sample = '1') then
|
162 |
|
|
v.baddr := pr.baddr + 1;
|
163 |
|
|
if ((((pcii.ad & pcictrl) xor (r.adpattern & r.sigpattern)) and (r.admask & r.sigmask)) = z) then
|
164 |
|
|
if pr.count = "00000000" then v.start := '0';
|
165 |
|
|
else v.count := pr.count -1; end if;
|
166 |
|
|
end if;
|
167 |
|
|
if (pr.start = '0') then
|
168 |
|
|
v.timeout := pr.timeout - 1;
|
169 |
|
|
if (v.timeout(depth-1) and not pr.timeout(depth-1)) = '1' then
|
170 |
|
|
v.sample := '0'; v.armed := '0';
|
171 |
|
|
end if;
|
172 |
|
|
end if;
|
173 |
|
|
end if;
|
174 |
|
|
|
175 |
|
|
if pr.sync = '1' then
|
176 |
|
|
v.start := '1'; v.sample := '1'; v.armed := '1';
|
177 |
|
|
v.timeout := r.timeout; v.count := r.count;
|
178 |
|
|
end if;
|
179 |
|
|
|
180 |
|
|
if rst = '0' then
|
181 |
|
|
v.sample := '0'; v.armed := '0'; v.start := '0';
|
182 |
|
|
v.timeout := (others => '0'); v.baddr := (others => '0');
|
183 |
|
|
v.count := (others => '0');
|
184 |
|
|
end if;
|
185 |
|
|
prin <= v;
|
186 |
|
|
end process ;
|
187 |
|
|
|
188 |
|
|
pcictrlin <= pcii.rst & pcii.idsel & pcii.frame & pcii.trdy & pcii.irdy &
|
189 |
|
|
pcii.devsel & pcii.gnt & pcii.stop & pcii.lock & pcii.perr &
|
190 |
|
|
pcii.serr & pcii.par & pcii.cbe;
|
191 |
|
|
|
192 |
|
|
apbo.pconfig <= pconfig;
|
193 |
|
|
apbo.pindex <= pindex;
|
194 |
|
|
apbo.pirq <= (others => '0');
|
195 |
|
|
|
196 |
|
|
seq: process (clk)
|
197 |
|
|
begin
|
198 |
|
|
if clk'event and clk = '1' then r <= rin; end if;
|
199 |
|
|
end process seq;
|
200 |
|
|
|
201 |
|
|
pseq: process (pciclk)
|
202 |
|
|
begin
|
203 |
|
|
if pciclk'event and pciclk = '1' then pr <= prin; end if;
|
204 |
|
|
end process ;
|
205 |
|
|
|
206 |
|
|
ir : if iregs = 1 generate
|
207 |
|
|
pseq: process (pciclk)
|
208 |
|
|
begin
|
209 |
|
|
if pciclk'event and pciclk = '1' then
|
210 |
|
|
pcictrl <= pcictrlin; pciad <= pcii.ad;
|
211 |
|
|
end if;
|
212 |
|
|
end process ;
|
213 |
|
|
end generate;
|
214 |
|
|
|
215 |
|
|
noir : if iregs = 0 generate
|
216 |
|
|
pcictrl <= pcictrlin; pciad <= pcii.ad;
|
217 |
|
|
end generate;
|
218 |
|
|
|
219 |
|
|
admem : syncram_2p generic map (tech => memtech, abits => depth, dbits => 32)
|
220 |
|
|
port map (clk, csad, apbi.paddr(depth+1 downto 2), bufout(31 downto 0),
|
221 |
|
|
pciclk, pr.sample, pr.baddr, pciad);
|
222 |
|
|
|
223 |
|
|
ctrlmem : syncram_2p generic map (tech => memtech, abits => depth, dbits => 16)
|
224 |
|
|
port map (clk, csctrl, apbi.paddr(depth+1 downto 2), bufout(47 downto 32),
|
225 |
|
|
pciclk, pr.sample, pr.baddr, pcictrl);
|
226 |
|
|
|
227 |
|
|
end;
|