1-------------------------------------------------------------------------------
2-- Title      : Wishbone package
3-- Project    : General Cores
4-------------------------------------------------------------------------------
5-- File       : wishbone_pkg.vhd
6-- Company    : CERN
7-- Platform   : FPGA-generics
8-- Standard   : VHDL '93
9-------------------------------------------------------------------------------
10-- Copyright (c) 2011-2017 CERN
11--
12-- This source file is free software; you can redistribute it
13-- and/or modify it under the terms of the GNU Lesser General
14-- Public License as published by the Free Software Foundation;
15-- either version 2.1 of the License, or (at your option) any
16-- later version.
17--
18-- This source is distributed in the hope that it will be
19-- useful, but WITHOUT ANY WARRANTY; without even the implied
20-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21-- PURPOSE.  See the GNU Lesser General Public License for more
22-- details.
23--
24-- You should have received a copy of the GNU Lesser General
25-- Public License along with this source; if not, download it
26-- from http://www.gnu.org/licenses/lgpl-2.1.html
27-------------------------------------------------------------------------------
28
29library ieee;
30
31use ieee.std_logic_1164.all;
32use ieee.numeric_std.all;
33
34library work;
35use work.genram_pkg.all;
36
37package wishbone_pkg is
38
39  constant c_wishbone_address_width : integer := 32;
40  constant c_wishbone_data_width    : integer := 32;
41
42  subtype t_wishbone_address is
43    std_logic_vector(c_wishbone_address_width-1 downto 0);
44  subtype t_wishbone_data is
45    std_logic_vector(c_wishbone_data_width-1 downto 0);
46  subtype t_wishbone_byte_select is
47    std_logic_vector((c_wishbone_address_width/8)-1 downto 0);
48  subtype t_wishbone_cycle_type is
49    std_logic_vector(2 downto 0);
50  subtype t_wishbone_burst_type is
51    std_logic_vector(1 downto 0);
52
53  type t_wishbone_interface_mode is (CLASSIC, PIPELINED);
54  type t_wishbone_address_granularity is (BYTE, WORD);
55
56  type t_wishbone_master_out is record
57    cyc : std_logic;
58    stb : std_logic;
59    adr : t_wishbone_address;
60    sel : t_wishbone_byte_select;
61    we  : std_logic;
62    dat : t_wishbone_data;
63  end record t_wishbone_master_out;
64
65  subtype t_wishbone_slave_in is t_wishbone_master_out;
66
67  type t_wishbone_slave_out is record
68    ack   : std_logic;
69    err   : std_logic;
70    rty   : std_logic;
71    stall : std_logic;
72    int   : std_logic;
73    dat   : t_wishbone_data;
74  end record t_wishbone_slave_out;
75  subtype t_wishbone_master_in is t_wishbone_slave_out;
76
77  subtype t_wishbone_device_descriptor is std_logic_vector(255 downto 0);
78
79  type t_wishbone_byte_select_array is array(natural range <>) of t_wishbone_byte_select;
80  type t_wishbone_data_array is array(natural range <>) of t_wishbone_data;
81  type t_wishbone_address_array is array(natural range <>) of t_wishbone_address;
82  type t_wishbone_master_out_array is array (natural range <>) of t_wishbone_master_out;
83  --type t_wishbone_slave_in_array is array (natural range <>) of t_wishbone_slave_in;
84  subtype t_wishbone_slave_in_array is t_wishbone_master_out_array;
85  type t_wishbone_slave_out_array is array (natural range <>) of t_wishbone_slave_out;
86  --type t_wishbone_master_in_array is array (natural range <>) of t_wishbone_master_in;
87  subtype t_wishbone_master_in_array is t_wishbone_slave_out_array;
88
89  constant cc_dummy_address : std_logic_vector(c_wishbone_address_width-1 downto 0) :=
90    (others => 'X');
91  constant cc_dummy_data : std_logic_vector(c_wishbone_data_width-1 downto 0) :=
92    (others => 'X');
93  constant cc_dummy_sel : std_logic_vector(c_wishbone_data_width/8-1 downto 0) :=
94    (others => 'X');
95  constant cc_dummy_slave_in : t_wishbone_slave_in :=
96    ('0', '0', cc_dummy_address, cc_dummy_sel, 'X', cc_dummy_data);
97  constant cc_dummy_master_out : t_wishbone_master_out := cc_dummy_slave_in;
98
99  -- Dangerous! Will stall a bus.
100  constant cc_dummy_slave_out : t_wishbone_slave_out :=
101    ('X', 'X', 'X', 'X', 'X', cc_dummy_data);
102  constant cc_dummy_master_in : t_wishbone_master_in := cc_dummy_slave_out;
103
104  constant cc_dummy_address_array : t_wishbone_address_array(0 downto 0) := (0 => cc_dummy_address);
105
106  -- A generally useful function.
107  function f_ceil_log2(x   : natural) return natural;
108  function f_bits2string(s : std_logic_vector) return string;
109
110  function f_string2bits(s : string) return std_logic_vector;
111  function f_string2svl (s : string) return std_logic_vector;
112  function f_slv2string (slv : std_logic_vector) return string;
113
114  function f_string_fix_len( s : string; ret_len : natural := 10; fill_char : character := '0'; justify_right : boolean := true ) return string;
115  function f_hot_to_bin(x : std_logic_vector) return natural;
116
117  -- *** Wishbone slave interface functions ***
118  -- f_wb_wr:
119  -- processes an incoming write reqest to a register while honoring the select lines
120  -- valid modes are overwrite "owr", set "set" (bits are or'ed) and clear "clr" (bits are nand'ed)
121  function f_wb_wr(pval : std_logic_vector; ival : std_logic_vector; sel : std_logic_vector; mode : string := "owr") return std_logic_vector;
122------------------------------------------------------------------------------
123-- SDB declaration
124------------------------------------------------------------------------------
125
126  constant c_sdb_device_length : natural := 512;  -- bits
127  subtype  t_sdb_record is std_logic_vector(c_sdb_device_length-1 downto 0);
128  type     t_sdb_record_array is array(natural range <>) of t_sdb_record;
129
130  type t_sdb_product is record
131    vendor_id : std_logic_vector(63 downto 0);
132    device_id : std_logic_vector(31 downto 0);
133    version   : std_logic_vector(31 downto 0);
134    date      : std_logic_vector(31 downto 0);
135    name      : string(1 to 19);
136  end record t_sdb_product;
137
138  type t_sdb_component is record
139    addr_first : std_logic_vector(63 downto 0);
140    addr_last  : std_logic_vector(63 downto 0);
141    product    : t_sdb_product;
142  end record t_sdb_component;
143
144  constant c_sdb_endian_big    : std_logic := '0';
145  constant c_sdb_endian_little : std_logic := '1';
146  type     t_sdb_device is record
147    abi_class     : std_logic_vector(15 downto 0);
148    abi_ver_major : std_logic_vector(7 downto 0);
149    abi_ver_minor : std_logic_vector(7 downto 0);
150    wbd_endian    : std_logic;          -- 0 = big, 1 = little
151    wbd_width     : std_logic_vector(3 downto 0);  -- 3=64-bit, 2=32-bit, 1=16-bit, 0=8-bit
152    sdb_component : t_sdb_component;
153  end record t_sdb_device;
154
155  type t_sdb_msi is record
156    wbd_endian    : std_logic;          -- 0 = big, 1 = little
157    wbd_width     : std_logic_vector(3 downto 0);  -- 3=64-bit, 2=32-bit, 1=16-bit, 0=8-bit
158    sdb_component : t_sdb_component;
159  end record t_sdb_msi;
160
161  type t_sdb_bridge is record
162    sdb_child     : std_logic_vector(63 downto 0);
163    sdb_component : t_sdb_component;
164  end record t_sdb_bridge;
165
166  type t_sdb_integration is record
167    product : t_sdb_product;
168  end record t_sdb_integration;
169
170  type t_sdb_repo_url is record
171    repo_url : string(1 to 63);
172  end record t_sdb_repo_url;
173
174  type t_sdb_synthesis is record
175    syn_module_name  : string(1 to 16);
176    syn_commit_id    : string(1 to 32);
177    syn_tool_name    : string(1 to 8);
178    syn_tool_version : std_logic_vector(31 downto 0);
179    syn_date         : std_logic_vector(31 downto 0);
180    syn_username     : string(1 to 15);
181  end record t_sdb_synthesis;
182
183  -- If you have a Wishbone master that does not receive MSI,
184  -- list it in the layout as 'f_sdb_auto_msi(c_null_msi, false)'
185  constant c_null_msi : t_sdb_msi := (
186   wbd_endian    => c_sdb_endian_big,
187   wbd_width     => x"0",
188   sdb_component => (
189   addr_first    => x"0000000000000000",
190   addr_last     => x"0000000000000000",
191   product => (
192   vendor_id     => x"0000000000000000",
193   device_id     => x"00000000",
194   version       => x"00000000",
195   date          => x"00000000",
196   name          => "                   ")));
197
198  -- general crossbar building functions
199  function f_sdb_create_array(g_enum_dev_id  : boolean := false;
200                              g_dev_id_offs    : natural := 0;
201                              g_enum_dev_name  : boolean := false;
202                              g_dev_name_offs  : natural := 0;
203                              device           : t_sdb_device;
204                              instances        : natural := 1) return t_sdb_record_array;
205  function f_sdb_join_arrays(a : t_sdb_record_array; b : t_sdb_record_array) return t_sdb_record_array;
206  function f_sdb_extract_base_addr(sdb_record : t_sdb_record) return std_logic_vector;
207  function f_sdb_extract_end_addr(sdb_record : t_sdb_record)  return std_logic_vector;
208  function f_sdb_automap_array(sdb_array : t_sdb_record_array; start_offset : t_wishbone_address := (others => '0')) return t_sdb_record_array;
209  function f_align_addr_offset(offs : unsigned; this_rng : unsigned; prev_rng : unsigned) return unsigned;
210  function f_sdb_create_rom_addr(sdb_array : t_sdb_record_array) return t_wishbone_address;
211
212
213  -- Used to configure a device at a certain address
214  function f_sdb_embed_device(device : t_sdb_device; address : t_wishbone_address) return t_sdb_record;
215  function f_sdb_embed_bridge(bridge : t_sdb_bridge; address : t_wishbone_address) return t_sdb_record;
216  function f_sdb_embed_msi(msi : t_sdb_msi; address : t_wishbone_address) return t_sdb_record;
217  function f_sdb_embed_integration(integr : t_sdb_integration) return t_sdb_record;
218  function f_sdb_embed_repo_url(url : t_sdb_repo_url) return t_sdb_record;
219  function f_sdb_embed_synthesis(syn : t_sdb_synthesis) return t_sdb_record;
220
221  function f_sdb_extract_device(sdb_record : t_sdb_record) return t_sdb_device;
222  function f_sdb_extract_bridge(sdb_record : t_sdb_record) return t_sdb_bridge;
223  function f_sdb_extract_msi(sdb_record : t_sdb_record) return t_sdb_msi;
224  function f_sdb_extract_integration(sdb_record : t_sdb_record) return t_sdb_integration;
225  function f_sdb_extract_repo_url(sdb_record : t_sdb_record) return t_sdb_repo_url;
226  function f_sdb_extract_synthesis(sdb_record : t_sdb_record) return t_sdb_synthesis;
227
228  -- Automatic crossbar mapping functions
229  function f_sdb_auto_device(device : t_sdb_device; enable : boolean := true; name: string := "") return t_sdb_record;
230  function f_sdb_auto_bridge(bridge : t_sdb_bridge; enable : boolean := true; name: string := "") return t_sdb_record;
231  function f_sdb_auto_msi   (msi    : t_sdb_msi;    enable : boolean := true) return t_sdb_record;
232  function f_sdb_auto_layout(records: t_sdb_record_array)                               return t_sdb_record_array;
233  function f_sdb_auto_layout(slaves : t_sdb_record_array; masters : t_sdb_record_array) return t_sdb_record_array;
234  function f_sdb_auto_sdb   (records: t_sdb_record_array)                               return t_wishbone_address;
235  function f_sdb_auto_sdb   (slaves : t_sdb_record_array; masters : t_sdb_record_array) return t_wishbone_address;
236
237  -- For internal use by the crossbar
238  function f_sdb_bus_end(g_wraparound : boolean; g_layout : t_sdb_record_array; g_sdb_addr : t_wishbone_address; msi : boolean) return unsigned;
239  function f_sdb_embed_product(product         : t_sdb_product) return std_logic_vector;  -- (319 downto 8)
240  function f_sdb_embed_component(sdb_component : t_sdb_component; address : t_wishbone_address) return std_logic_vector;  -- (447 downto 8)
241  function f_sdb_extract_product(sdb_record    : std_logic_vector(319 downto 8)) return t_sdb_product;
242  function f_sdb_extract_component(sdb_record  : std_logic_vector(447 downto 8)) return t_sdb_component;
243
244------------------------------------------------------------------------------
245-- Components declaration
246-------------------------------------------------------------------------------
247
248  component wb_slave_adapter
249    generic (
250      g_master_use_struct  : boolean;
251      g_master_mode        : t_wishbone_interface_mode;
252      g_master_granularity : t_wishbone_address_granularity;
253      g_slave_use_struct   : boolean;
254      g_slave_mode         : t_wishbone_interface_mode;
255      g_slave_granularity  : t_wishbone_address_granularity);
256    port (
257      clk_sys_i  : in  std_logic;
258      rst_n_i    : in  std_logic;
259      sl_adr_i   : in  std_logic_vector(c_wishbone_address_width-1 downto 0) := cc_dummy_address;
260      sl_dat_i   : in  std_logic_vector(c_wishbone_data_width-1 downto 0)    := cc_dummy_data;
261      sl_sel_i   : in  std_logic_vector(c_wishbone_data_width/8-1 downto 0)  := cc_dummy_sel;
262      sl_cyc_i   : in  std_logic                                             := '0';
263      sl_stb_i   : in  std_logic                                             := '0';
264      sl_we_i    : in  std_logic                                             := '0';
265      sl_dat_o   : out std_logic_vector(c_wishbone_data_width-1 downto 0);
266      sl_err_o   : out std_logic;
267      sl_rty_o   : out std_logic;
268      sl_ack_o   : out std_logic;
269      sl_stall_o : out std_logic;
270      sl_int_o   : out std_logic;
271      slave_i    : in  t_wishbone_slave_in                                   := cc_dummy_slave_in;
272      slave_o    : out t_wishbone_slave_out;
273      ma_adr_o   : out std_logic_vector(c_wishbone_address_width-1 downto 0);
274      ma_dat_o   : out std_logic_vector(c_wishbone_data_width-1 downto 0);
275      ma_sel_o   : out std_logic_vector(c_wishbone_data_width/8-1 downto 0);
276      ma_cyc_o   : out std_logic;
277      ma_stb_o   : out std_logic;
278      ma_we_o    : out std_logic;
279      ma_dat_i   : in  std_logic_vector(c_wishbone_data_width-1 downto 0)    := cc_dummy_data;
280      ma_err_i   : in  std_logic                                             := '0';
281      ma_rty_i   : in  std_logic                                             := '0';
282      ma_ack_i   : in  std_logic                                             := '0';
283      ma_stall_i : in  std_logic                                             := '0';
284      ma_int_i   : in  std_logic                                             := '0';
285      master_i   : in  t_wishbone_master_in                                  := cc_dummy_slave_out;
286      master_o   : out t_wishbone_master_out);
287  end component;
288
289  component wb_async_bridge
290    generic (
291      g_simulation          : integer;
292      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
293      g_address_granularity : t_wishbone_address_granularity := WORD;
294      g_cpu_address_width   : integer);
295    port (
296      rst_n_i     : in    std_logic;
297      clk_sys_i   : in    std_logic;
298      cpu_cs_n_i  : in    std_logic;
299      cpu_wr_n_i  : in    std_logic;
300      cpu_rd_n_i  : in    std_logic;
301      cpu_bs_n_i  : in    std_logic_vector(3 downto 0);
302      cpu_addr_i  : in    std_logic_vector(g_cpu_address_width-1 downto 0);
303      cpu_data_b  : inout std_logic_vector(31 downto 0);
304      cpu_nwait_o : out   std_logic;
305      wb_adr_o    : out   std_logic_vector(c_wishbone_address_width - 1 downto 0);
306      wb_dat_o    : out   std_logic_vector(31 downto 0);
307      wb_stb_o    : out   std_logic;
308      wb_we_o     : out   std_logic;
309      wb_sel_o    : out   std_logic_vector(3 downto 0);
310      wb_cyc_o    : out   std_logic;
311      wb_dat_i    : in    std_logic_vector (c_wishbone_data_width-1 downto 0);
312      wb_ack_i    : in    std_logic;
313      wb_stall_i  : in    std_logic := '0');
314  end component;
315
316  component xwb_async_bridge
317    generic (
318      g_simulation          : integer;
319      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
320      g_address_granularity : t_wishbone_address_granularity := WORD;
321      g_cpu_address_width   : integer);
322    port (
323      rst_n_i     : in    std_logic;
324      clk_sys_i   : in    std_logic;
325      cpu_cs_n_i  : in    std_logic;
326      cpu_wr_n_i  : in    std_logic;
327      cpu_rd_n_i  : in    std_logic;
328      cpu_bs_n_i  : in    std_logic_vector(3 downto 0);
329      cpu_addr_i  : in    std_logic_vector(g_cpu_address_width-1 downto 0);
330      cpu_data_b  : inout std_logic_vector(31 downto 0);
331      cpu_nwait_o : out   std_logic;
332      master_o    : out   t_wishbone_master_out;
333      master_i    : in    t_wishbone_master_in);
334  end component;
335
336  component xwb_bus_fanout
337    generic (
338      g_num_outputs          : natural;
339      g_bits_per_slave       : integer;
340      g_address_granularity  : t_wishbone_address_granularity := WORD;
341      g_slave_interface_mode : t_wishbone_interface_mode      := CLASSIC);
342    port (
343      clk_sys_i : in  std_logic;
344      rst_n_i   : in  std_logic;
345      slave_i   : in  t_wishbone_slave_in;
346      slave_o   : out t_wishbone_slave_out;
347      master_i  : in  t_wishbone_master_in_array(0 to g_num_outputs-1);
348      master_o  : out t_wishbone_master_out_array(0 to g_num_outputs-1));
349  end component;
350
351  component xwb_crossbar
352    generic (
353      g_num_masters : integer;
354      g_num_slaves  : integer;
355      g_registered  : boolean;
356      g_address     : t_wishbone_address_array;
357      g_mask        : t_wishbone_address_array);
358    port (
359      clk_sys_i : in  std_logic;
360      rst_n_i   : in  std_logic;
361      slave_i   : in  t_wishbone_slave_in_array(g_num_masters-1 downto 0);
362      slave_o   : out t_wishbone_slave_out_array(g_num_masters-1 downto 0);
363      master_i  : in  t_wishbone_master_in_array(g_num_slaves-1 downto 0);
364      master_o  : out t_wishbone_master_out_array(g_num_slaves-1 downto 0);
365      sdb_sel_o : out std_logic_vector(g_num_masters-1 downto 0)); -- leave open!
366  end component;
367
368  -- Use the f_xwb_bridge_*_sdb to bridge a crossbar to another
369  function f_xwb_bridge_manual_sdb(     -- take a manual bus size
370    g_size     : t_wishbone_address;
371    g_sdb_addr : t_wishbone_address) return t_sdb_bridge;
372
373  function f_xwb_bridge_layout_sdb(     -- determine bus size from layout
374    g_wraparound : boolean := true;
375    g_layout     : t_sdb_record_array;
376    g_sdb_addr   : t_wishbone_address) return t_sdb_bridge;
377
378  function f_xwb_msi_manual_sdb(        -- take a manual bus size
379    g_size     : t_wishbone_address) return t_sdb_msi;
380
381  function f_xwb_msi_layout_sdb(     -- determine MSI size from layout
382    g_layout     : t_sdb_record_array) return t_sdb_msi;
383
384  component xwb_sdb_crossbar
385    generic (
386      g_num_masters : integer;
387      g_num_slaves  : integer;
388      g_registered  : boolean := false;
389      g_wraparound  : boolean := true;
390      g_layout      : t_sdb_record_array;
391      g_sdb_addr    : t_wishbone_address;
392      g_sdb_name    : string := "WB4-Crossbar-GSI   ");
393    port (
394      clk_sys_i     : in  std_logic;
395      rst_n_i       : in  std_logic;
396      slave_i       : in  t_wishbone_slave_in_array  (g_num_masters-1 downto 0);
397      slave_o       : out t_wishbone_slave_out_array (g_num_masters-1 downto 0);
398      msi_master_i  : in  t_wishbone_master_in_array (g_num_masters-1 downto 0) := (others => cc_dummy_master_in);
399      msi_master_o  : out t_wishbone_master_out_array(g_num_masters-1 downto 0);
400      master_i      : in  t_wishbone_master_in_array (g_num_slaves -1 downto 0);
401      master_o      : out t_wishbone_master_out_array(g_num_slaves -1 downto 0);
402      msi_slave_i   : in  t_wishbone_slave_in_array  (g_num_slaves -1 downto 0) := (others => cc_dummy_slave_in);
403      msi_slave_o   : out t_wishbone_slave_out_array (g_num_slaves -1 downto 0));
404  end component;
405
406  component xwb_register_link -- puts a register of delay between crossbars
407    port(
408      clk_sys_i : in  std_logic;
409      rst_n_i   : in  std_logic;
410      slave_i   : in  t_wishbone_slave_in;
411      slave_o   : out t_wishbone_slave_out;
412      master_i  : in  t_wishbone_master_in;
413      master_o  : out t_wishbone_master_out);
414  end component;
415
416  -- skidpad. acts like a fifo in wb flow control, but costs less
417  component wb_skidpad is
418  generic(
419     g_adrbits   : natural   := 32
420  );
421  Port(
422     clk_i        : std_logic;
423     rst_n_i      : std_logic;
424
425     push_i       : in  std_logic;
426     pop_i        : in  std_logic;
427     full_o       : out std_logic;
428     empty_o      : out std_logic;
429
430     adr_i        : in  std_logic_vector(g_adrbits-1 downto 0);
431     dat_i        : in  std_logic_vector(32-1 downto 0);
432     sel_i        : in  std_logic_vector(4-1 downto 0);
433     we_i         : in  std_logic;
434
435     adr_o        : out std_logic_vector(g_adrbits-1 downto 0);
436     dat_o        : out std_logic_vector(32-1 downto 0);
437     sel_o        : out std_logic_vector(4-1 downto 0);
438     we_o         : out std_logic
439  );
440  end component;
441
442  component sdb_rom is
443    generic(
444      g_layout  : t_sdb_record_array;
445      g_masters : natural;
446      g_bus_end : unsigned(63 downto 0);
447      g_sdb_name    : string := "WB4-Crossbar-GSI   ");
448    port(
449      clk_sys_i : in  std_logic;
450      master_i  : in  std_logic_vector(g_masters-1 downto 0);
451      slave_i   : in  t_wishbone_slave_in;
452      slave_o   : out t_wishbone_slave_out);
453  end component;
454
455  constant c_xwb_dma_sdb : t_sdb_device := (
456    abi_class     => x"0000",              -- undocumented device
457    abi_ver_major => x"01",
458    abi_ver_minor => x"00",
459    wbd_endian    => c_sdb_endian_big,
460    wbd_width     => x"7",                 -- 8/16/32-bit port granularity
461    sdb_component => (
462      addr_first  => x"0000000000000000",
463      addr_last   => x"000000000000001f",
464      product     => (
465        vendor_id => x"0000000000000651",  -- GSI
466        device_id => x"cababa56",
467        version   => x"00000001",
468        date      => x"20120518",
469        name      => "WB4-Streaming-DMA_0")));
470  component xwb_dma is
471    generic(
472      -- Value 0 cannot stream
473      -- Value 1 only slaves with async ACK can stream
474      -- Value 2 only slaves with combined latency <= 2 can stream
475      -- Value 3 only slaves with combined latency <= 6 can stream
476      -- Value 4 only slaves with combined latency <= 14 can stream
477      -- ....
478      logRingLen : integer := 4
479      );
480    port(
481      -- Common wishbone signals
482      clk_i       : in  std_logic;
483      rst_n_i     : in  std_logic;
484      slave_i     : in  t_wishbone_slave_in;
485      slave_o     : out t_wishbone_slave_out;
486      -- Master reader port
487      r_master_i  : in  t_wishbone_master_in;
488      r_master_o  : out t_wishbone_master_out;
489      -- Master writer port
490      w_master_i  : in  t_wishbone_master_in;
491      w_master_o  : out t_wishbone_master_out;
492      -- Pulsed high completion signal
493      interrupt_o : out std_logic
494      );
495  end component;
496
497  -- If you reset one clock domain, you must reset BOTH!
498  -- Release of the reset lines may be arbitrarily out-of-phase
499  component xwb_clock_crossing is
500    generic(
501      g_size : natural := 16);
502    port(
503      -- Slave control port
504      slave_clk_i    : in  std_logic;
505      slave_rst_n_i  : in  std_logic;
506      slave_i        : in  t_wishbone_slave_in;
507      slave_o        : out t_wishbone_slave_out;
508      -- Master reader port
509      master_clk_i   : in  std_logic;
510      master_rst_n_i : in  std_logic;
511      master_i       : in  t_wishbone_master_in;
512      master_o       : out t_wishbone_master_out;
513      -- Flow control back-channel for acks
514      slave_ready_o : out std_logic;
515      slave_stall_i : in  std_logic := '0');
516  end component;
517
518  -- g_size is in words
519  function f_xwb_dpram(g_size : natural) return t_sdb_device;
520  component xwb_dpram
521    generic (
522      g_size                  : natural;
523      g_init_file             : string                         := "";
524      g_must_have_init_file   : boolean                        := true;
525      g_slave1_interface_mode : t_wishbone_interface_mode      := CLASSIC;
526      g_slave2_interface_mode : t_wishbone_interface_mode      := CLASSIC;
527      g_slave1_granularity    : t_wishbone_address_granularity := WORD;
528      g_slave2_granularity    : t_wishbone_address_granularity := WORD);
529    port (
530      clk_sys_i : in  std_logic;
531      rst_n_i   : in  std_logic;
532      slave1_i  : in  t_wishbone_slave_in;
533      slave1_o  : out t_wishbone_slave_out;
534      slave2_i  : in  t_wishbone_slave_in;
535      slave2_o  : out t_wishbone_slave_out);
536  end component;
537
538  component xwb_dpram_mixed
539  generic(
540    g_size                  : natural := 16384;
541    g_init_file             : string  := "";
542    g_must_have_init_file   : boolean := true;
543    g_swap_word_endianness  : boolean := true;
544    g_slave1_interface_mode : t_wishbone_interface_mode;
545    g_slave2_interface_mode : t_wishbone_interface_mode;
546    g_dpram_port_a_width    : integer := 16;
547    g_dpram_port_b_width    : integer := 32;
548    g_slave1_granularity    : t_wishbone_address_granularity;
549    g_slave2_granularity    : t_wishbone_address_granularity);
550  port(
551    clk_slave1_i  : in std_logic;
552    clk_slave2_i  : in std_logic;
553    rst_n_i       : in std_logic;
554
555    slave1_i      : in  t_wishbone_slave_in;
556    slave1_o      : out t_wishbone_slave_out;
557    slave2_i      : in  t_wishbone_slave_in;
558    slave2_o      : out t_wishbone_slave_out);
559  end component;
560
561  -- Just like the DMA controller, but constantly at address 0
562  component xwb_streamer is
563    generic(
564      -- Value 0 cannot stream
565      -- Value 1 only slaves with async ACK can stream
566      -- Value 2 only slaves with combined latency = 2 can stream
567      -- Value 3 only slaves with combined latency = 6 can stream
568      -- Value 4 only slaves with combined latency = 14 can stream
569      -- ....
570      logRingLen : integer := 4
571    );
572    port(
573      -- Common wishbone signals
574      clk_i       : in  std_logic;
575      rst_n_i     : in  std_logic;
576      -- Master reader port
577      r_master_i  : in  t_wishbone_master_in;
578      r_master_o  : out t_wishbone_master_out;
579      -- Master writer port
580      w_master_i  : in  t_wishbone_master_in;
581      w_master_o  : out t_wishbone_master_out);
582  end component;
583
584
585  constant c_xwb_gpio_port_sdb : t_sdb_device := (
586    abi_class     => x"0000",              -- undocumented device
587    abi_ver_major => x"01",
588    abi_ver_minor => x"01",
589    wbd_endian    => c_sdb_endian_big,
590    wbd_width     => x"7",                 -- 8/16/32-bit port granularity
591    sdb_component => (
592      addr_first  => x"0000000000000000",
593      addr_last   => x"00000000000000ff",
594      product     => (
595        vendor_id => x"000000000000CE42",  -- CERN
596        device_id => x"441c5143",
597        version   => x"00000001",
598        date      => x"20121129",
599        name      => "WB-GPIO-Port       ")));
600
601
602  component wb_gpio_port
603    generic (
604      g_interface_mode         : t_wishbone_interface_mode      := CLASSIC;
605      g_address_granularity    : t_wishbone_address_granularity := WORD;
606      g_num_pins               : natural range 1 to 256;
607      g_with_builtin_tristates : boolean                        := false);
608    port (
609      clk_sys_i  : in    std_logic;
610      rst_n_i    : in    std_logic;
611      wb_sel_i   : in    std_logic_vector(c_wishbone_data_width/8-1 downto 0);
612      wb_cyc_i   : in    std_logic;
613      wb_stb_i   : in    std_logic;
614      wb_we_i    : in    std_logic;
615      wb_adr_i   : in    std_logic_vector(7 downto 0);
616      wb_dat_i   : in    std_logic_vector(c_wishbone_data_width-1 downto 0);
617      wb_dat_o   : out   std_logic_vector(c_wishbone_data_width-1 downto 0);
618      wb_ack_o   : out   std_logic;
619      wb_stall_o : out   std_logic;
620      gpio_b     : inout std_logic_vector(g_num_pins-1 downto 0);
621      gpio_out_o : out   std_logic_vector(g_num_pins-1 downto 0);
622      gpio_in_i  : in    std_logic_vector(g_num_pins-1 downto 0);
623      gpio_oen_o : out   std_logic_vector(g_num_pins-1 downto 0));
624  end component;
625
626  component xwb_gpio_port
627    generic (
628      g_interface_mode         : t_wishbone_interface_mode      := CLASSIC;
629      g_address_granularity    : t_wishbone_address_granularity := WORD;
630      g_num_pins               : natural range 1 to 256;
631      g_with_builtin_tristates : boolean);
632    port (
633      clk_sys_i  : in    std_logic;
634      rst_n_i    : in    std_logic;
635      slave_i    : in    t_wishbone_slave_in;
636      slave_o    : out   t_wishbone_slave_out;
637      desc_o     : out   t_wishbone_device_descriptor;
638      gpio_b     : inout std_logic_vector(g_num_pins-1 downto 0);
639      gpio_out_o : out   std_logic_vector(g_num_pins-1 downto 0);
640      gpio_in_i  : in    std_logic_vector(g_num_pins-1 downto 0);
641      gpio_oen_o : out   std_logic_vector(g_num_pins-1 downto 0));
642  end component;
643
644  constant c_xwb_i2c_master_sdb : t_sdb_device := (
645    abi_class     => x"0000",              -- undocumented device
646    abi_ver_major => x"01",
647    abi_ver_minor => x"01",
648    wbd_endian    => c_sdb_endian_big,
649    wbd_width     => x"7",                 -- 8/16/32-bit port granularity
650    sdb_component => (
651      addr_first  => x"0000000000000000",
652      addr_last   => x"00000000000000ff",
653      product     => (
654        vendor_id => x"000000000000CE42",  -- CERN
655        device_id => x"123c5443",
656        version   => x"00000001",
657        date      => x"20121129",
658        name      => "WB-I2C-Master      ")));
659
660
661  component wb_i2c_master
662    generic (
663      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
664      g_address_granularity : t_wishbone_address_granularity := WORD;
665      g_num_interfaces      : integer := 1);
666    port (
667      clk_sys_i    : in  std_logic;
668      rst_n_i      : in  std_logic;
669      wb_adr_i     : in  std_logic_vector(4 downto 0);
670      wb_dat_i     : in  std_logic_vector(31 downto 0);
671      wb_dat_o     : out std_logic_vector(31 downto 0);
672      wb_sel_i     : in  std_logic_vector(3 downto 0);
673      wb_stb_i     : in  std_logic;
674      wb_cyc_i     : in  std_logic;
675      wb_we_i      : in  std_logic;
676      wb_ack_o     : out std_logic;
677      wb_int_o     : out std_logic;
678      wb_stall_o   : out std_logic;
679      scl_pad_i    : in  std_logic_vector(g_num_interfaces-1 downto 0);
680      scl_pad_o    : out std_logic_vector(g_num_interfaces-1 downto 0);
681      scl_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0);
682      sda_pad_i    : in  std_logic_vector(g_num_interfaces-1 downto 0);
683      sda_pad_o    : out std_logic_vector(g_num_interfaces-1 downto 0);
684      sda_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0));
685  end component;
686
687  component xwb_i2c_master
688    generic (
689      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
690      g_address_granularity : t_wishbone_address_granularity := WORD;
691      g_num_interfaces      : integer := 1);
692    port (
693      clk_sys_i    : in  std_logic;
694      rst_n_i      : in  std_logic;
695      slave_i      : in  t_wishbone_slave_in;
696      slave_o      : out t_wishbone_slave_out;
697      desc_o       : out t_wishbone_device_descriptor;
698      scl_pad_i    : in  std_logic_vector(g_num_interfaces-1 downto 0);
699      scl_pad_o    : out std_logic_vector(g_num_interfaces-1 downto 0);
700      scl_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0);
701      sda_pad_i    : in  std_logic_vector(g_num_interfaces-1 downto 0);
702      sda_pad_o    : out std_logic_vector(g_num_interfaces-1 downto 0);
703      sda_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0));
704  end component;
705
706  component xwb_lm32
707    generic (
708      g_profile : string;
709      g_reset_vector : std_logic_vector(31 downto 0) := x"00000000";
710      g_sdb_address  : std_logic_vector(31 downto 0) := x"00000000");
711    port (
712      clk_sys_i : in  std_logic;
713      rst_n_i   : in  std_logic;
714      irq_i     : in  std_logic_vector(31 downto 0);
715      dwb_o     : out t_wishbone_master_out;
716      dwb_i     : in  t_wishbone_master_in;
717      iwb_o     : out t_wishbone_master_out;
718      iwb_i     : in  t_wishbone_master_in);
719  end component;
720
721  constant c_xwb_onewire_master_sdb : t_sdb_device := (
722    abi_class     => x"0000",              -- undocumented device
723    abi_ver_major => x"01",
724    abi_ver_minor => x"01",
725    wbd_endian    => c_sdb_endian_big,
726    wbd_width     => x"7",                 -- 8/16/32-bit port granularity
727    sdb_component => (
728      addr_first  => x"0000000000000000",
729      addr_last   => x"00000000000000ff",
730      product     => (
731        vendor_id => x"000000000000CE42",  -- CERN
732        device_id => x"779c5443",
733        version   => x"00000001",
734        date      => x"20121129",
735        name      => "WB-OneWire-Master  ")));
736
737  component wb_onewire_master
738    generic (
739      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
740      g_address_granularity : t_wishbone_address_granularity := WORD;
741      g_num_ports           : integer;
742      g_ow_btp_normal       : string                         := "1.0";
743      g_ow_btp_overdrive    : string                         := "5.0");
744    port (
745      clk_sys_i   : in  std_logic;
746      rst_n_i     : in  std_logic;
747      wb_cyc_i    : in  std_logic;
748      wb_sel_i    : in  std_logic_vector(c_wishbone_data_width/8-1 downto 0);
749      wb_stb_i    : in  std_logic;
750      wb_we_i     : in  std_logic;
751      wb_adr_i    : in  std_logic_vector(2 downto 0);
752      wb_dat_i    : in  std_logic_vector(c_wishbone_data_width-1 downto 0);
753      wb_dat_o    : out std_logic_vector(c_wishbone_data_width-1 downto 0);
754      wb_ack_o    : out std_logic;
755      wb_int_o    : out std_logic;
756      wb_stall_o  : out std_logic;
757      owr_pwren_o : out std_logic_vector(g_num_ports -1 downto 0);
758      owr_en_o    : out std_logic_vector(g_num_ports -1 downto 0);
759      owr_i       : in  std_logic_vector(g_num_ports -1 downto 0));
760  end component;
761
762  component xwb_onewire_master
763    generic (
764      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
765      g_address_granularity : t_wishbone_address_granularity := WORD;
766      g_num_ports           : integer;
767      g_ow_btp_normal       : string                         := "5.0";
768      g_ow_btp_overdrive    : string                         := "1.0");
769    port (
770      clk_sys_i   : in  std_logic;
771      rst_n_i     : in  std_logic;
772      slave_i     : in  t_wishbone_slave_in;
773      slave_o     : out t_wishbone_slave_out;
774      desc_o      : out t_wishbone_device_descriptor;
775      owr_pwren_o : out std_logic_vector(g_num_ports -1 downto 0);
776      owr_en_o    : out std_logic_vector(g_num_ports -1 downto 0);
777      owr_i       : in  std_logic_vector(g_num_ports -1 downto 0));
778  end component;
779
780  constant c_xwb_spi_sdb : t_sdb_device := (
781    abi_class     => x"0000",              -- undocumented device
782    abi_ver_major => x"01",
783    abi_ver_minor => x"01",
784    wbd_endian    => c_sdb_endian_big,
785    wbd_width     => x"7",                 -- 8/16/32-bit port granularity
786    sdb_component => (
787      addr_first  => x"0000000000000000",
788      addr_last   => x"000000000000001F",
789      product     => (
790        vendor_id => x"000000000000CE42",  -- CERN
791        device_id => x"e503947e",       -- echo "WB-SPI.Control     " | md5sum | cut -c1-8
792        version   => x"00000001",
793        date      => x"20121116",
794        name      => "WB-SPI.Control     ")));
795
796  component wb_spi
797    generic (
798      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
799      g_address_granularity : t_wishbone_address_granularity := WORD;
800      g_divider_len         : integer := 16;
801      g_max_char_len        : integer := 128;
802      g_num_slaves          : integer := 8);
803    port (
804      clk_sys_i  : in  std_logic;
805      rst_n_i    : in  std_logic;
806      wb_adr_i   : in  std_logic_vector(4 downto 0);
807      wb_dat_i   : in  std_logic_vector(31 downto 0);
808      wb_dat_o   : out std_logic_vector(31 downto 0);
809      wb_sel_i   : in  std_logic_vector(3 downto 0);
810      wb_stb_i   : in  std_logic;
811      wb_cyc_i   : in  std_logic;
812      wb_we_i    : in  std_logic;
813      wb_ack_o   : out std_logic;
814      wb_err_o   : out std_logic;
815      wb_int_o   : out std_logic;
816      wb_stall_o : out std_logic;
817      pad_cs_o   : out std_logic_vector(g_num_slaves-1 downto 0);
818      pad_sclk_o : out std_logic;
819      pad_mosi_o : out std_logic;
820      pad_miso_i : in  std_logic);
821  end component;
822
823  component xwb_spi
824    generic (
825      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
826      g_address_granularity : t_wishbone_address_granularity := WORD;
827      g_divider_len         : integer := 16;
828      g_max_char_len        : integer := 128;
829      g_num_slaves          : integer := 8);
830    port (
831      clk_sys_i  : in  std_logic;
832      rst_n_i    : in  std_logic;
833      slave_i    : in  t_wishbone_slave_in;
834      slave_o    : out t_wishbone_slave_out;
835      desc_o     : out t_wishbone_device_descriptor;
836      pad_cs_o   : out std_logic_vector(g_num_slaves-1 downto 0);
837      pad_sclk_o : out std_logic;
838      pad_mosi_o : out std_logic;
839      pad_miso_i : in  std_logic);
840  end component;
841
842  component wb_simple_uart
843    generic (
844      g_with_virtual_uart   : boolean                        := false;
845      g_with_physical_uart  : boolean                        := true;
846      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
847      g_address_granularity : t_wishbone_address_granularity := WORD;
848      g_vuart_fifo_size     : integer := 1024);
849    port (
850      clk_sys_i  : in  std_logic;
851      rst_n_i    : in  std_logic;
852      wb_adr_i   : in  std_logic_vector(4 downto 0);
853      wb_dat_i   : in  std_logic_vector(31 downto 0);
854      wb_dat_o   : out std_logic_vector(31 downto 0);
855      wb_cyc_i   : in  std_logic;
856      wb_sel_i   : in  std_logic_vector(3 downto 0);
857      wb_stb_i   : in  std_logic;
858      wb_we_i    : in  std_logic;
859      wb_ack_o   : out std_logic;
860      wb_stall_o : out std_logic;
861      uart_rxd_i : in  std_logic := '1';
862      uart_txd_o : out std_logic);
863  end component;
864
865  component xwb_simple_uart
866    generic (
867      g_with_virtual_uart   : boolean                        := false;
868      g_with_physical_uart  : boolean                        := true;
869      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
870      g_address_granularity : t_wishbone_address_granularity := WORD;
871      g_vuart_fifo_size     : integer := 1024);
872    port (
873      clk_sys_i  : in  std_logic;
874      rst_n_i    : in  std_logic;
875      slave_i    : in  t_wishbone_slave_in;
876      slave_o    : out t_wishbone_slave_out;
877      desc_o     : out t_wishbone_device_descriptor;
878      uart_rxd_i : in  std_logic := '1';
879      uart_txd_o : out std_logic);
880  end component;
881
882  component wb_simple_pwm
883    generic (
884      g_num_channels        : integer range 1 to 8;
885      g_regs_size           : integer range 1 to 16 := 16;
886      g_default_period      : integer range 0 to 255 := 0;
887      g_default_presc       : integer range 0 to 255 := 0;
888      g_default_val         : integer range 0 to 255 := 0;
889      g_interface_mode      : t_wishbone_interface_mode      := PIPELINED;
890      g_address_granularity : t_wishbone_address_granularity := BYTE);
891    port (
892      clk_sys_i  : in  std_logic;
893      rst_n_i    : in  std_logic;
894      wb_adr_i   : in  std_logic_vector(5 downto 0);
895      wb_dat_i   : in  std_logic_vector(31 downto 0);
896      wb_dat_o   : out std_logic_vector(31 downto 0);
897      wb_cyc_i   : in  std_logic;
898      wb_sel_i   : in  std_logic_vector(3 downto 0);
899      wb_stb_i   : in  std_logic;
900      wb_we_i    : in  std_logic;
901      wb_ack_o   : out std_logic;
902      wb_stall_o : out std_logic;
903      pwm_o      : out std_logic_vector(g_num_channels-1 downto 0));
904  end component;
905
906  component xwb_simple_pwm
907    generic (
908      g_num_channels        : integer range 1 to 8;
909      g_regs_size           : integer range 1 to 16 := 16;
910      g_default_period      : integer range 0 to 255 := 0;
911      g_default_presc       : integer range 0 to 255 := 0;
912      g_default_val         : integer range 0 to 255 := 0;
913      g_interface_mode      : t_wishbone_interface_mode      := PIPELINED;
914      g_address_granularity : t_wishbone_address_granularity := BYTE);
915    port (
916      clk_sys_i : in  std_logic;
917      rst_n_i   : in  std_logic;
918      slave_i   : in  t_wishbone_slave_in;
919      slave_o   : out t_wishbone_slave_out;
920      pwm_o     : out std_logic_vector(g_num_channels-1 downto 0));
921  end component;
922
923  component wb_tics
924    generic (
925      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
926      g_address_granularity : t_wishbone_address_granularity := WORD;
927      g_period              : integer);
928    port (
929      rst_n_i    : in  std_logic;
930      clk_sys_i  : in  std_logic;
931      wb_adr_i   : in  std_logic_vector(3 downto 0);
932      wb_dat_i   : in  std_logic_vector(c_wishbone_data_width-1 downto 0);
933      wb_dat_o   : out std_logic_vector(c_wishbone_data_width-1 downto 0);
934      wb_cyc_i   : in  std_logic;
935      wb_sel_i   : in  std_logic_vector(c_wishbone_data_width/8-1 downto 0);
936      wb_stb_i   : in  std_logic;
937      wb_we_i    : in  std_logic;
938      wb_ack_o   : out std_logic;
939      wb_stall_o : out std_logic);
940  end component;
941
942  component xwb_tics
943    generic (
944      g_interface_mode      : t_wishbone_interface_mode      := CLASSIC;
945      g_address_granularity : t_wishbone_address_granularity := WORD;
946      g_period              : integer);
947    port (
948      clk_sys_i : in  std_logic;
949      rst_n_i   : in  std_logic;
950      slave_i   : in  t_wishbone_slave_in;
951      slave_o   : out t_wishbone_slave_out;
952      desc_o    : out t_wishbone_device_descriptor);
953  end component;
954
955  component wb_vic
956    generic (
957      g_interface_mode      : t_wishbone_interface_mode;
958      g_address_granularity : t_wishbone_address_granularity;
959      g_num_interrupts      : natural;
960      g_init_vectors        : t_wishbone_address_array := cc_dummy_address_array;
961      g_retry_timeout : integer := 0
962      );
963    port (
964      clk_sys_i    : in  std_logic;
965      rst_n_i      : in  std_logic;
966      wb_adr_i     : in  std_logic_vector(c_wishbone_address_width-1 downto 0);
967      wb_dat_i     : in  std_logic_vector(c_wishbone_data_width-1 downto 0);
968      wb_dat_o     : out std_logic_vector(c_wishbone_data_width-1 downto 0);
969      wb_cyc_i     : in  std_logic;
970      wb_sel_i     : in  std_logic_vector(c_wishbone_data_width/8-1 downto 0);
971      wb_stb_i     : in  std_logic;
972      wb_we_i      : in  std_logic;
973      wb_ack_o     : out std_logic;
974      wb_stall_o   : out std_logic;
975      irqs_i       : in  std_logic_vector(g_num_interrupts-1 downto 0);
976      irq_master_o : out std_logic);
977  end component;
978
979  constant c_xwb_vic_sdb : t_sdb_device := (
980    abi_class     => x"0000",              -- undocumented device
981    abi_ver_major => x"01",
982    abi_ver_minor => x"01",
983    wbd_endian    => c_sdb_endian_big,
984    wbd_width     => x"7",                 -- 8/16/32-bit port granularity
985    sdb_component => (
986      addr_first  => x"0000000000000000",
987      addr_last   => x"00000000000000ff",
988      product     => (
989        vendor_id => x"000000000000CE42",  -- CERN
990        device_id => x"00000013",
991        version   => x"00000002",
992        date      => x"20120113",
993        name      => "WB-VIC-Int.Control ")));
994
995  component xwb_vic
996    generic (
997      g_interface_mode      : t_wishbone_interface_mode;
998      g_address_granularity : t_wishbone_address_granularity;
999      g_num_interrupts      : natural;
1000      g_init_vectors        : t_wishbone_address_array := cc_dummy_address_array;
1001    g_retry_timeout : integer := 0);
1002
1003    port (
1004      clk_sys_i    : in  std_logic;
1005      rst_n_i      : in  std_logic;
1006      slave_i      : in  t_wishbone_slave_in;
1007      slave_o      : out t_wishbone_slave_out;
1008      irqs_i       : in  std_logic_vector(g_num_interrupts-1 downto 0);
1009      irq_master_o : out std_logic);
1010  end component;
1011
1012  constant c_wb_serial_lcd_sdb : t_sdb_device := (
1013    abi_class     => x"0000", -- undocumented device
1014    abi_ver_major => x"01",
1015    abi_ver_minor => x"00",
1016    wbd_endian    => c_sdb_endian_big,
1017    wbd_width     => x"7", -- 8/16/32-bit port granularity
1018    sdb_component => (
1019    addr_first    => x"0000000000000000",
1020    addr_last     => x"00000000000000ff",
1021    product => (
1022    vendor_id     => x"0000000000000651", -- GSI
1023    device_id     => x"b77a5045",
1024    version       => x"00000001",
1025    date          => x"20130222",
1026    name          => "SERIAL-LCD-DISPLAY ")));
1027  component wb_serial_lcd
1028    generic(
1029      g_cols : natural := 40;
1030      g_rows : natural := 24;
1031      g_hold : natural := 15; -- How many times to repeat a line  (for sharpness)
1032      g_wait : natural := 1); -- How many cycles per state change (for 20MHz timing)
1033    port(
1034      slave_clk_i  : in  std_logic;
1035      slave_rstn_i : in  std_logic;
1036      slave_i      : in  t_wishbone_slave_in;
1037      slave_o      : out t_wishbone_slave_out;
1038      di_clk_i     : in  std_logic;
1039      di_scp_o     : out std_logic;
1040      di_lp_o      : out std_logic;
1041      di_flm_o     : out std_logic;
1042      di_dat_o     : out std_logic);
1043  end component;
1044
1045  function f_wb_spi_flash_sdb(g_bits : natural) return t_sdb_device;
1046  component wb_spi_flash is
1047    generic(
1048      g_port_width             : natural   := 1;  -- 1 for EPCS, 4 for EPCQ
1049      g_addr_width             : natural   := 24; -- log of memory (24=16MB)
1050      g_idle_time              : natural   := 3;
1051      g_dummy_time             : natural   := 8;
1052      -- leave these at defaults if you have:
1053      --   a) slow clock, b) valid constraints, or c) registered in/outputs
1054      g_input_latch_edge       : std_logic := '1'; -- rising
1055      g_output_latch_edge      : std_logic := '0'; -- falling
1056      g_input_to_output_cycles : natural   := 1);  -- between 1 and 8
1057    port(
1058      clk_i     : in  std_logic;
1059      rstn_i    : in  std_logic;
1060      slave_i   : in  t_wishbone_slave_in;
1061      slave_o   : out t_wishbone_slave_out;
1062
1063      -- For properly constrained designs, set clk_out_i = clk_in_i.
1064      clk_out_i : in  std_logic;
1065      clk_in_i  : in  std_logic;
1066      ncs_o     : out std_logic;
1067      oe_o      : out std_logic_vector(g_port_width-1 downto 0);
1068      asdi_o    : out std_logic_vector(g_port_width-1 downto 0);
1069      data_i    : in  std_logic_vector(g_port_width-1 downto 0);
1070
1071      external_request_i : in  std_logic := '0'; -- JTAG wants to use SPI?
1072      external_granted_o : out std_logic);
1073  end component;
1074
1075  -----------------------------------------------------------------------------
1076  -- I2C to Wishbone bridge, following protocol defined with ELMA
1077  -----------------------------------------------------------------------------
1078  component wb_i2c_bridge is
1079    generic
1080    (
1081      -- FSM watchdog timeout, see Appendix A in the component documentation for
1082      -- an example of setting this generic
1083      g_fsm_wdt : positive
1084    );
1085    port
1086    (
1087      -- Clock, reset
1088      clk_i      : in  std_logic;
1089      rst_n_i    : in  std_logic;
1090
1091      -- I2C lines
1092      scl_i      : in  std_logic;
1093      scl_o      : out std_logic;
1094      scl_en_o   : out std_logic;
1095      sda_i      : in  std_logic;
1096      sda_o      : out std_logic;
1097      sda_en_o   : out std_logic;
1098
1099      -- I2C address
1100      i2c_addr_i : in  std_logic_vector(6 downto 0);
1101
1102      -- Status outputs
1103      -- TIP  : Transfer In Progress
1104      --        '1' when the I2C slave detects a matching I2C address, thus a
1105      --            transfer is in progress
1106      --        '0' when idle
1107      -- ERR  : Error
1108      --       '1' when the SysMon attempts to access an invalid WB slave
1109      --       '0' when idle
1110      -- WDTO : Watchdog timeout (single clock cycle pulse)
1111      --        '1' -- timeout of watchdog occured
1112      --        '0' -- when idle
1113      tip_o      : out std_logic;
1114      err_p_o    : out std_logic;
1115      wdto_p_o   : out std_logic;
1116
1117      -- Wishbone master signals
1118      wbm_stb_o  : out std_logic;
1119      wbm_cyc_o  : out std_logic;
1120      wbm_sel_o  : out std_logic_vector(3 downto 0);
1121      wbm_we_o   : out std_logic;
1122      wbm_dat_i  : in  std_logic_vector(31 downto 0);
1123      wbm_dat_o  : out std_logic_vector(31 downto 0);
1124      wbm_adr_o  : out std_logic_vector(31 downto 0);
1125      wbm_ack_i  : in  std_logic;
1126      wbm_rty_i  : in  std_logic;
1127      wbm_err_i  : in  std_logic
1128    );
1129  end component wb_i2c_bridge;
1130
1131  ------------------------------------------------------------------------------
1132  -- MultiBoot component
1133  ------------------------------------------------------------------------------
1134  component xwb_xil_multiboot is
1135    port
1136    (
1137      -- Clock and reset input ports
1138      clk_i   : in  std_logic;
1139      rst_n_i : in  std_logic;
1140
1141      -- Wishbone ports
1142      wbs_i   : in  t_wishbone_slave_in;
1143      wbs_o   : out t_wishbone_slave_out;
1144
1145      -- SPI ports
1146      spi_cs_n_o : out std_logic;
1147      spi_sclk_o : out std_logic;
1148      spi_mosi_o : out std_logic;
1149      spi_miso_i : in  std_logic
1150    );
1151  end component xwb_xil_multiboot;
1152
1153  constant c_xwb_xil_multiboot_sdb : t_sdb_device := (
1154    abi_class     => x"0000",              -- undocumented device
1155    abi_ver_major => x"01",
1156    abi_ver_minor => x"00",
1157    wbd_endian    => c_sdb_endian_big,
1158    wbd_width     => x"7",                 -- 8/16/32-bit port granularity
1159    sdb_component => (
1160      addr_first  => x"0000000000000000",
1161      addr_last   => x"000000000000001f",
1162      product     => (
1163        vendor_id => x"000000000000CE42",  -- CERN
1164        device_id => x"11da333d",          -- echo "WB-Xilinx-MultiBoot" | md5sum | cut -c1-8
1165        version   => x"00000001",
1166        date      => x"20140313",
1167        name      => "WB-Xilinx-MultiBoot")));
1168
1169  constant cc_dummy_sdb_device : t_sdb_device := (
1170    abi_class     => x"0000",              -- undocumented device
1171    abi_ver_major => x"01",
1172    abi_ver_minor => x"01",
1173    wbd_endian    => c_sdb_endian_big,
1174    wbd_width     => x"7",                 -- 8/16/32-bit port granularity
1175    sdb_component => (
1176      addr_first  => x"0000000000000000",
1177      addr_last   => x"00000000000000ff",
1178      product     => (
1179        vendor_id => x"000000000000CE42",  -- CERN
1180        device_id => x"ffffffff",
1181        version   => x"00000001",
1182        date      => x"20150722",
1183        name      => "Unused-Device      ")));
1184
1185
1186end wishbone_pkg;
1187
1188package body wishbone_pkg is
1189   -- f_wb_wr: processes a write reqest to a slave register with select lines. valid modes are "owr", "set" and "clr"
1190   function f_wb_wr(pval : std_logic_vector; ival : std_logic_vector; sel : std_logic_vector; mode : string := "owr") return std_logic_vector is
1191      variable n_sel     : std_logic_vector(pval'range);
1192      variable n_val     : std_logic_vector(pval'range);
1193      variable result 	 : std_logic_vector(pval'range);
1194   begin
1195     for i in pval'range loop
1196      n_sel(i) := sel((i-pval'low) / 8); -- subtract the low index for when register width > wishbone data width
1197      n_val(i) := ival(i-pval'low);
1198     end loop;
1199
1200     if(mode = "set") then
1201      result := pval or (n_val and n_sel);
1202     elsif (mode = "clr") then
1203      result := pval and not (n_val and n_sel);
1204     else
1205      result := (pval and not n_sel) or (n_val and n_sel);
1206     end if;
1207
1208     return result;
1209   end f_wb_wr;
1210
1211  function f_ceil_log2(x : natural) return natural is
1212  begin
1213    if x <= 1
1214    then return 0;
1215    else return f_ceil_log2((x+1)/2) +1;
1216    end if;
1217  end f_ceil_log2;
1218
1219  function f_sdb_embed_product(product : t_sdb_product)
1220    return std_logic_vector             -- (319 downto 8)
1221  is
1222    variable result : std_logic_vector(319 downto 8);
1223  begin
1224    result(319 downto 256) := product.vendor_id;
1225    result(255 downto 224) := product.device_id;
1226    result(223 downto 192) := product.version;
1227    result(191 downto 160) := product.date;
1228    for i in 0 to 18 loop               -- string to ascii
1229      result(159-i*8 downto 152-i*8) :=
1230        std_logic_vector(to_unsigned(character'pos(product.name(i+1)), 8));
1231    end loop;
1232    return result;
1233  end;
1234
1235  function f_sdb_extract_product(sdb_record : std_logic_vector(319 downto 8))
1236    return t_sdb_product
1237  is
1238    variable result : t_sdb_product;
1239  begin
1240    result.vendor_id := sdb_record(319 downto 256);
1241    result.device_id := sdb_record(255 downto 224);
1242    result.version   := sdb_record(223 downto 192);
1243    result.date      := sdb_record(191 downto 160);
1244    for i in 0 to 18 loop               -- ascii to string
1245      result.name(i+1) := character'val(to_integer(unsigned(sdb_record(159-i*8 downto 152-i*8))));
1246    end loop;
1247    return result;
1248  end;
1249
1250  function f_sdb_embed_component(sdb_component : t_sdb_component; address : t_wishbone_address)
1251    return std_logic_vector             -- (447 downto 8)
1252  is
1253    variable result : std_logic_vector(447 downto 8);
1254
1255    constant first : unsigned(63 downto 0) := unsigned(sdb_component.addr_first);
1256    constant last  : unsigned(63 downto 0) := unsigned(sdb_component.addr_last);
1257    variable base  : unsigned(63 downto 0) := (others => '0');
1258  begin
1259    base(address'length-1 downto 0) := unsigned(address);
1260
1261    result(447 downto 384) := std_logic_vector(base);
1262    result(383 downto 320) := std_logic_vector(base + last - first);
1263    result(319 downto 8)   := f_sdb_embed_product(sdb_component.product);
1264    return result;
1265  end;
1266
1267  function f_sdb_extract_component(sdb_record : std_logic_vector(447 downto 8))
1268    return t_sdb_component
1269  is
1270    variable result : t_sdb_component;
1271  begin
1272    result.addr_first := sdb_record(447 downto 384);
1273    result.addr_last  := sdb_record(383 downto 320);
1274    result.product    := f_sdb_extract_product(sdb_record(319 downto 8));
1275    return result;
1276  end;
1277
1278  function f_sdb_embed_device(device : t_sdb_device; address : t_wishbone_address)
1279    return t_sdb_record
1280  is
1281    variable result : t_sdb_record;
1282  begin
1283    result(511 downto 496) := device.abi_class;
1284    result(495 downto 488) := device.abi_ver_major;
1285    result(487 downto 480) := device.abi_ver_minor;
1286    result(479 downto 456) := (others => '0');
1287    result(455)            := device.wbd_endian;
1288    result(454 downto 452) := (others => '0');
1289    result(451 downto 448) := device.wbd_width;
1290    result(447 downto 8)   := f_sdb_embed_component(device.sdb_component, address);
1291    result(7 downto 0)     := x"01";    -- device
1292    return result;
1293  end;
1294
1295  function f_sdb_extract_device(sdb_record : t_sdb_record)
1296    return t_sdb_device
1297  is
1298    variable result : t_sdb_device;
1299  begin
1300    result.abi_class     := sdb_record(511 downto 496);
1301    result.abi_ver_major := sdb_record(495 downto 488);
1302    result.abi_ver_minor := sdb_record(487 downto 480);
1303    result.wbd_endian    := sdb_record(452);
1304    result.wbd_width     := sdb_record(451 downto 448);
1305    result.sdb_component := f_sdb_extract_component(sdb_record(447 downto 8));
1306
1307    assert sdb_record(7 downto 0) = x"01"
1308      report "Cannot extract t_sdb_device from record of type " & integer'image(to_integer(unsigned(sdb_record(7 downto 0)))) & "."
1309      severity failure;
1310
1311    return result;
1312  end;
1313
1314  function f_sdb_embed_msi(msi : t_sdb_msi; address : t_wishbone_address)
1315    return t_sdb_record
1316  is
1317    variable result : t_sdb_record;
1318  begin
1319    result(511 downto 456) := (others => '0');
1320    result(455)            := msi.wbd_endian;
1321    result(454 downto 452) := (others => '0');
1322    result(451 downto 448) := msi.wbd_width;
1323    result(447 downto 8)   := f_sdb_embed_component(msi.sdb_component, address);
1324    result(7 downto 0)     := x"03";    -- msi
1325    return result;
1326  end;
1327
1328  function f_sdb_extract_msi(sdb_record : t_sdb_record)
1329    return t_sdb_msi
1330  is
1331    variable result : t_sdb_msi;
1332  begin
1333    result.wbd_endian    := sdb_record(452);
1334    result.wbd_width     := sdb_record(451 downto 448);
1335    result.sdb_component := f_sdb_extract_component(sdb_record(447 downto 8));
1336
1337    assert sdb_record(7 downto 0) = x"03"
1338      report "Cannot extract t_sdb_msi from record of type " & integer'image(to_integer(unsigned(sdb_record(7 downto 0)))) & "."
1339      severity failure;
1340
1341    return result;
1342  end;
1343
1344  function f_sdb_embed_integration(integr : t_sdb_integration)
1345    return t_sdb_record
1346  is
1347    variable result : t_sdb_record;
1348  begin
1349    result(511 downto 320) := (others => '0');
1350    result(319 downto 8)   := f_sdb_embed_product(integr.product);
1351    result(7 downto 0)     := x"80"; -- integration record
1352    return result;
1353  end f_sdb_embed_integration;
1354
1355  function f_sdb_extract_integration(sdb_record : t_sdb_record)
1356    return t_sdb_integration
1357  is
1358    variable result : t_sdb_integration;
1359  begin
1360    result.product := f_sdb_extract_product(sdb_record(319 downto 8));
1361
1362    assert sdb_record(7 downto 0) = x"80"
1363    report "Cannot extract t_sdb_integration from record of type " & Integer'image(to_integer(unsigned(sdb_record(7 downto 0)))) & "."
1364    severity Failure;
1365
1366    return result;
1367  end f_sdb_extract_integration;
1368
1369  function f_sdb_embed_repo_url(url : t_sdb_repo_url)
1370    return t_sdb_record
1371  is
1372    variable result : t_sdb_record;
1373  begin
1374    result(511 downto 8) := f_string2svl(url.repo_url);
1375    result(  7 downto 0) := x"81"; -- repo_url record
1376    return result;
1377  end;
1378
1379  function f_sdb_extract_repo_url(sdb_record : t_sdb_record)
1380    return t_sdb_repo_url
1381  is
1382    variable result : t_sdb_repo_url;
1383  begin
1384    result.repo_url     := f_slv2string(sdb_record(511 downto 8));
1385
1386    assert sdb_record(7 downto 0) = x"81"
1387    report "Cannot extract t_sdb_repo_url from record of type " & Integer'image(to_integer(unsigned(sdb_record(7 downto 0)))) & "."
1388    severity Failure;
1389
1390    return result;
1391  end;
1392
1393  function f_sdb_embed_synthesis(syn : t_sdb_synthesis)
1394    return t_sdb_record
1395  is
1396    variable result : t_sdb_record;
1397  begin
1398    result(511 downto 384) := f_string2svl(syn.syn_module_name);
1399    result(383 downto 256) := f_string2bits(syn.syn_commit_id);
1400    result(255 downto 192) := f_string2svl(syn.syn_tool_name);
1401    result(191 downto 160) := syn.syn_tool_version;
1402    result(159 downto 128) := syn.syn_date;
1403    result(127 downto   8) := f_string2svl(syn.syn_username);
1404    result(  7 downto   0) := x"82"; -- synthesis record
1405    return result;
1406  end;
1407
1408  function f_sdb_extract_synthesis(sdb_record : t_sdb_record)
1409    return t_sdb_synthesis
1410  is
1411    variable result : t_sdb_synthesis;
1412  begin
1413    result.syn_module_name  := f_slv2string(sdb_record(511 downto 384));
1414    result.syn_commit_id    := f_bits2string(sdb_record(383 downto 256));
1415    result.syn_tool_name    := f_slv2string(sdb_record(255 downto 192));
1416    result.syn_tool_version := sdb_record(191 downto 160);
1417    result.syn_date         := sdb_record(159 downto 128);
1418    result.syn_username     := f_slv2string(sdb_record(127 downto   8));
1419
1420    assert sdb_record(7 downto 0) = x"82"
1421    report "Cannot extract t_sdb_repo_url from record of type " & Integer'image(to_integer(unsigned(sdb_record(7 downto 0)))) & "."
1422    severity Failure;
1423
1424    return result;
1425  end;
1426
1427  function f_sdb_embed_bridge(bridge : t_sdb_bridge; address : t_wishbone_address)
1428    return t_sdb_record
1429  is
1430    variable result : t_sdb_record;
1431
1432    constant first : unsigned(63 downto 0) := unsigned(bridge.sdb_component.addr_first);
1433    constant child : unsigned(63 downto 0) := unsigned(bridge.sdb_child);
1434    variable base  : unsigned(63 downto 0) := (others => '0');
1435  begin
1436    base(address'length-1 downto 0) := unsigned(address);
1437
1438    result(511 downto 448) := std_logic_vector(base + child - first);
1439    result(447 downto 8)   := f_sdb_embed_component(bridge.sdb_component, address);
1440    result(7 downto 0)     := x"02";    -- bridge
1441    return result;
1442  end;
1443
1444  function f_sdb_extract_bridge(sdb_record : t_sdb_record)
1445    return t_sdb_bridge
1446  is
1447    variable result : t_sdb_bridge;
1448  begin
1449    result.sdb_child     := sdb_record(511 downto 448);
1450    result.sdb_component := f_sdb_extract_component(sdb_record(447 downto 8));
1451
1452    assert sdb_record(7 downto 0) = x"02"
1453      report "Cannot extract t_sdb_bridge from record of type " & integer'image(to_integer(unsigned(sdb_record(7 downto 0)))) & "."
1454      severity failure;
1455
1456    return result;
1457  end;
1458
1459  function f_sdb_auto_device(device : t_sdb_device; enable : boolean := true; name: string := "")
1460    return t_sdb_record
1461  is
1462    constant c_zero  : t_wishbone_address := (others => '0');
1463    variable v_device: t_sdb_device := device;
1464    variable v_empty : t_sdb_record := (others => '0');
1465  begin
1466    v_empty(7 downto 0) := x"f1";
1467    if name /= "" then
1468      v_device.sdb_component.product.name := f_string_fix_len(name , 19, ' ', false);
1469    end if;
1470    if enable then
1471      v_empty := f_sdb_embed_device(v_device, c_zero);
1472    end if;
1473    return v_empty;
1474  end f_sdb_auto_device;
1475
1476  function f_sdb_auto_bridge(bridge : t_sdb_bridge; enable : boolean := true; name: string := "")
1477    return t_sdb_record
1478  is
1479    constant c_zero  : t_wishbone_address := (others => '0');
1480    variable v_bridge: t_sdb_bridge := bridge;
1481    variable v_empty : t_sdb_record := (others => '0');
1482  begin
1483    v_empty(7 downto 0) := x"f2";
1484    if name /= "" then
1485      v_bridge.sdb_component.product.name := f_string_fix_len(name , 19, ' ', false);
1486    end if;
1487    if enable then
1488      v_empty := f_sdb_embed_bridge(v_bridge, c_zero);
1489    end if;
1490    return v_empty;
1491  end f_sdb_auto_bridge;
1492
1493  function f_sdb_auto_msi(msi : t_sdb_msi; enable : boolean := true)
1494    return t_sdb_record
1495  is
1496    constant c_zero  : t_wishbone_address := (others => '0');
1497    variable v_empty : t_sdb_record := (others => '0');
1498  begin
1499    v_empty(7 downto 0) := x"f3";
1500    if enable then
1501      return f_sdb_embed_msi(msi, c_zero);
1502    else
1503      return v_empty;
1504    end if;
1505  end f_sdb_auto_msi;
1506
1507  subtype t_usdb_address is unsigned(63 downto 0);
1508  type t_usdb_address_array is array(natural range <>) of t_usdb_address;
1509
1510  -- We map devices by placing the smallest ones first.
1511  -- This is guaranteed to pack the maximum number of devices in the smallest space.
1512  -- If a device has an address != 0, we leave it alone and let the crossbar confirm
1513  -- that the address does not cause a conflict.
1514  function f_sdb_auto_layout_helper(records : t_sdb_record_array)
1515    return t_usdb_address_array
1516  is
1517    alias c_records : t_sdb_record_array(records'length-1 downto 0) is records;
1518    constant c_zero : t_usdb_address := (others => '0');
1519
1520    constant c_used_entries : natural := c_records'length + 1;
1521    constant c_rom_entries  : natural := 2**f_ceil_log2(c_used_entries);
1522    constant c_rom_bytes    : natural := c_rom_entries * c_sdb_device_length / 8;
1523
1524    variable v_component : t_sdb_component;
1525    variable v_sizes     : t_usdb_address_array(c_records'length downto 0);
1526    variable v_address   : t_usdb_address_array(c_records'length downto 0);
1527    variable v_bus_map   : std_logic_vector(c_records'length downto 0) := (others => '0');
1528    variable v_bus_cursor: unsigned(63 downto 0) := (others => '0');
1529    variable v_msi_map   : std_logic_vector(c_records'length downto 0) := (others => '0');
1530    variable v_msi_cursor: unsigned(63 downto 0) := (others => '0');
1531    variable v_increment : unsigned(63 downto 0) := (others => '0');
1532    variable v_type      : std_logic_vector(7 downto 0);
1533  begin
1534    -- First, extract the length of the devices, ignoring those not to be mapped
1535    for i in c_records'range loop
1536      v_component := f_sdb_extract_component(c_records(i)(447 downto 8));
1537      v_sizes(i)   := unsigned(v_component.addr_last);
1538      v_address(i) := unsigned(v_component.addr_first);
1539
1540      -- Silently round up to a power of two; the crossbar will give a warning for us
1541      for j in 62 downto 0 loop
1542        v_sizes(i)(j) := v_sizes(i)(j+1) or v_sizes(i)(j);
1543      end loop;
1544
1545      -- Only map devices/bridges at address zero
1546      if v_address(i) = c_zero then
1547        v_type := c_records(i)(7 downto 0);
1548        case v_type is
1549          when x"01" => v_bus_map(i) := '1';
1550          when x"02" => v_bus_map(i) := '1';
1551          when x"03" => v_msi_map(i) := '1';
1552          when others => null;
1553        end case;
1554      end if;
1555    end loop;
1556
1557    -- Assign the SDB record a spot as well
1558    v_address(c_records'length) := (others => '0');
1559    v_sizes(c_records'length) := to_unsigned(c_rom_bytes-1, 64);
1560    v_bus_map(c_records'length) := '1';
1561
1562    -- Start assigning addresses
1563    for j in 0 to 63 loop
1564      v_increment := (others => '0');
1565      v_increment(j) := '1';
1566
1567      for i in 0 to c_records'length loop
1568        if v_bus_map(i) = '1' and v_sizes(i)(j) = '0' then
1569          v_bus_map(i) := '0';
1570          v_address(i) := v_bus_cursor;
1571          v_bus_cursor := v_bus_cursor + v_increment;
1572        end if;
1573        if v_msi_map(i) = '1' and v_sizes(i)(j) = '0' then
1574          v_msi_map(i) := '0';
1575          v_address(i) := v_msi_cursor;
1576          v_msi_cursor := v_msi_cursor + v_increment;
1577        end if;
1578      end loop;
1579
1580      -- Round up to the next required alignment
1581      if v_bus_cursor(j) = '1' then
1582        v_bus_cursor := v_bus_cursor + v_increment;
1583      end if;
1584      if v_msi_cursor(j) = '1' then
1585        v_msi_cursor := v_msi_cursor + v_increment;
1586      end if;
1587    end loop;
1588
1589    return v_address;
1590  end f_sdb_auto_layout_helper;
1591
1592  function f_sdb_auto_layout(records : t_sdb_record_array)
1593    return t_sdb_record_array
1594  is
1595    alias    c_records : t_sdb_record_array(records'length-1 downto 0) is records;
1596    variable v_typ     : std_logic_vector(7 downto 0);
1597    variable v_result  : t_sdb_record_array(c_records'range) := c_records;
1598    constant c_address : t_usdb_address_array := f_sdb_auto_layout_helper(c_records);
1599    variable v_address : t_wishbone_address;
1600  begin
1601    -- Put the addresses into the mapping
1602    for i in v_result'range loop
1603      v_typ     := c_records(i)(7 downto 0);
1604      v_address := std_logic_vector(c_address(i)(t_wishbone_address'range));
1605
1606      case v_typ is
1607        when x"01" => v_result(i) := f_sdb_embed_device(f_sdb_extract_device(v_result(i)), v_address);
1608        when x"02" => v_result(i) := f_sdb_embed_bridge(f_sdb_extract_bridge(v_result(i)), v_address);
1609        when x"03" => v_result(i) := f_sdb_embed_msi   (f_sdb_extract_msi   (v_result(i)), v_address);
1610        when others => null;
1611      end case;
1612    end loop;
1613
1614    return v_result;
1615  end f_sdb_auto_layout;
1616
1617  function f_sdb_auto_layout(slaves : t_sdb_record_array; masters : t_sdb_record_array)
1618    return t_sdb_record_array
1619  is begin
1620    return f_sdb_auto_layout(masters & slaves);
1621  end f_sdb_auto_layout;
1622
1623  function f_sdb_auto_sdb(records : t_sdb_record_array)
1624    return t_wishbone_address
1625  is
1626    alias    c_records : t_sdb_record_array(records'length-1 downto 0) is records;
1627    constant c_address : t_usdb_address_array(c_records'length downto 0) := f_sdb_auto_layout_helper(c_records);
1628  begin
1629    return std_logic_vector(c_address(c_records'length)(t_wishbone_address'range));
1630  end f_sdb_auto_sdb;
1631
1632  function f_sdb_auto_sdb(slaves : t_sdb_record_array; masters : t_sdb_record_array)
1633    return t_wishbone_address
1634  is begin
1635    return f_sdb_auto_sdb(masters & slaves);
1636  end f_sdb_auto_sdb;
1637
1638--**************************************************************************************************************************--
1639-- START MAT's NEW FUNCTIONS FROM 18th Oct 2013
1640------------------------------------------------------------------------------------------------------------------------------
1641
1642
1643   function f_sdb_create_array(g_enum_dev_id    : boolean := false;
1644                            g_dev_id_offs    : natural := 0;
1645                            g_enum_dev_name  : boolean := false;
1646                            g_dev_name_offs  : natural := 0;
1647                            device           : t_sdb_device;
1648                            instances        : natural := 1)
1649   return t_sdb_record_array is
1650      variable result   : t_sdb_record_array(instances-1 downto 0);
1651      variable i,j, pos : natural;
1652      variable dev, newdev      : t_sdb_device;
1653      variable serial_no : string(1 to 3);
1654      variable text_possible : boolean := false;
1655   begin
1656      dev := device;
1657
1658      report "### Creating " & integer'image(instances) & " x " & dev.sdb_component.product.name
1659      severity note;
1660      for i in 0 to instances-1 loop
1661         newdev := dev;
1662         if(g_enum_dev_id) then
1663            dev.sdb_component.product.device_id :=
1664            std_logic_vector( unsigned(dev.sdb_component.product.device_id)
1665                              + to_unsigned(i+g_dev_id_offs, dev.sdb_component.product.device_id'length));
1666         end if;
1667         if(g_enum_dev_name) then
1668         -- find end of name
1669
1670            for j in dev.sdb_component.product.name'length downto 1 loop
1671               if(dev.sdb_component.product.name(j) /= ' ') then
1672                  pos := j;
1673                  exit;
1674               end if;
1675            end loop;
1676         -- convert i+g_dev_name_offs to string
1677            serial_no := f_string_fix_len(integer'image(i+g_dev_name_offs), serial_no'length);
1678            report "### Now: " & serial_no & " of " & dev.sdb_component.product.name severity note;
1679         -- check if space is sufficient
1680            assert (serial_no'length+1 <= dev.sdb_component.product.name'length - pos)
1681            report "Not enough space in namestring of sdb_device " & dev.sdb_component.product.name
1682            & " to add serial number " & serial_no & ". Space available " &
1683            integer'image(dev.sdb_component.product.name'length-pos-1) & ", required "
1684            & integer'image(serial_no'length+1)
1685            severity Failure;
1686         end if;
1687         if(g_enum_dev_name) then
1688            newdev.sdb_component.product.name(pos+1) := '_';
1689            for j in 1 to serial_no'length loop
1690               newdev.sdb_component.product.name(pos+1+j) := serial_no(j);
1691            end loop;
1692         end if;
1693
1694      -- insert
1695         report "### to: " & newdev.sdb_component.product.name severity note;
1696         result(i) := f_sdb_embed_device(newdev, (others=>'0'));
1697      end loop;
1698      return result;
1699   end f_sdb_create_array;
1700
1701   function f_sdb_join_arrays(a : t_sdb_record_array; b : t_sdb_record_array) return t_sdb_record_array is
1702      variable result   : t_sdb_record_array(a'length+b'length-1 downto 0);
1703      variable i : natural;
1704   begin
1705      for i in 0 to a'left loop
1706         result(i) := a(i);
1707      end loop;
1708      for i in 0 to b'left loop
1709         result(i+a'length) := b(i);
1710      end loop;
1711      return result;
1712   end f_sdb_join_arrays;
1713
1714
1715   function f_sdb_extract_base_addr(sdb_record : t_sdb_record) return std_logic_vector is
1716   begin
1717      return sdb_record(447 downto 384);
1718   end f_sdb_extract_base_addr;
1719
1720   function f_sdb_extract_end_addr(sdb_record : t_sdb_record) return std_logic_vector is
1721   begin
1722      return sdb_record(383 downto 320);
1723   end f_sdb_extract_end_addr;
1724
1725
1726   function f_align_addr_offset(offs : unsigned; this_rng : unsigned; prev_rng : unsigned)
1727   return unsigned is
1728      variable this_pow, prev_pow   : natural;
1729      variable start, env, result : unsigned(63 downto 0) := (others => '0');
1730   begin
1731      start(offs'left downto 0) := offs;
1732      --calculate address envelopes (next power of 2) for previous and this component and choose the larger one
1733      this_pow := f_hot_to_bin(std_logic_vector(this_rng));
1734      prev_pow := f_hot_to_bin(std_logic_vector(prev_rng));
1735      -- no max(). thank you very much, std_numeric :-/
1736      if(this_pow >= prev_pow) then
1737         env(this_pow) := '1';
1738      else
1739         env(prev_pow) := '1';
1740      end if;
1741      --round up to the next multiple of the envelope...
1742      if(prev_rng /= 0) then
1743         result := start + env - (start mod env);
1744      else
1745         result := start;   --...except for first element, result is start.
1746      end if;
1747      return result;
1748   end f_align_addr_offset;
1749
1750
1751 -- generates aligned address map for an sdb_record_array, accepts optional start offset
1752   function f_sdb_automap_array(sdb_array : t_sdb_record_array; start_offset : t_wishbone_address := (others => '0'))
1753   return t_sdb_record_array is
1754      constant len         : natural := sdb_array'length;
1755      variable this_rng    : unsigned(63 downto 0) := (others => '0');
1756      variable prev_rng    : unsigned(63 downto 0) := (others => '0');
1757      variable prev_offs   : unsigned(63 downto 0) := (others => '0');
1758      variable this_offs   : unsigned(63 downto 0) := (others => '0');
1759      variable device      : t_sdb_device;
1760      variable bridge      : t_sdb_bridge;
1761      variable sdb_type    : std_logic_vector(7 downto 0);
1762      variable i           : natural;
1763      variable result      : t_sdb_record_array(sdb_array'length-1 downto 0); -- last
1764   begin
1765
1766      prev_offs(start_offset'left downto 0) := unsigned(start_offset);
1767      --traverse the array
1768      for i in 0 to len-1 loop
1769         -- find the fitting extraction function by evaling the type byte.
1770         -- could also use the component, but it's safer to use Wes' embed and extract functions.
1771         sdb_type := sdb_array(i)(7 downto 0);
1772         case sdb_type is
1773            --device
1774            when x"01"  => device      := f_sdb_extract_device(sdb_array(i));
1775                           this_rng    := unsigned(device.sdb_component.addr_last) - unsigned(device.sdb_component.addr_first);
1776                           this_offs   := f_align_addr_offset(prev_offs, this_rng, prev_rng);
1777                           result(i)   := f_sdb_embed_device(device, std_logic_vector(this_offs(31 downto 0)));
1778            --bridge
1779            when x"02"  => bridge      := f_sdb_extract_bridge(sdb_array(i));
1780                           this_rng    := unsigned(bridge.sdb_component.addr_last) - unsigned(bridge.sdb_component.addr_first);
1781                           this_offs   := f_align_addr_offset(prev_offs, this_rng, prev_rng);
1782                           result(i)   := f_sdb_embed_bridge(bridge, std_logic_vector(this_offs(31 downto 0)) );
1783            --other
1784            when others => result(i) := sdb_array(i);
1785         end case;
1786         -- doesnt hurt because this_* doesnt change if its not a device or bridge
1787         prev_rng    := this_rng;
1788         prev_offs   := this_offs;
1789      end loop;
1790      report "##* " & integer'image(sdb_array'length) & " Elements, last address: " & f_bits2string(std_logic_vector(this_offs+this_rng)) severity Note;
1791      return result;
1792   end f_sdb_automap_array;
1793
1794
1795  -- find place for sdb rom on crossbar and return address. try to put it in an address gap.
1796   function f_sdb_create_rom_addr(sdb_array : t_sdb_record_array) return t_wishbone_address is
1797      constant len                  : natural := sdb_array'length;
1798      constant rom_bytes            : natural := (2**f_ceil_log2(sdb_array'length + 1)) * (c_sdb_device_length / 8);
1799      variable result               : t_wishbone_address  := (others => '0');
1800      variable this_base, this_end  : unsigned(63 downto 0)          := (others => '0');
1801      variable prev_base, prev_end  : unsigned(63 downto 0)          := (others => '0');
1802      variable rom_base             : unsigned(63 downto 0)          := (others => '0');
1803      variable sdb_type             : std_logic_vector(7 downto 0);
1804   begin
1805      --traverse the array
1806      for i in 0 to len-1 loop
1807         sdb_type := sdb_array(i)(7 downto 0);
1808         if(sdb_type = x"01" or sdb_type = x"02") then
1809            -- get
1810            this_base := unsigned(f_sdb_extract_base_addr(sdb_array(i)));
1811            this_end  := unsigned(f_sdb_extract_end_addr(sdb_array(i)));
1812            if(unsigned(result) = 0) then
1813               rom_base := f_align_addr_offset(prev_base, to_unsigned(rom_bytes-1, 64), (prev_end-prev_base));
1814               if(rom_base + to_unsigned(rom_bytes, 64) <= this_base) then
1815                  result := std_logic_vector(rom_base(t_wishbone_address'left downto 0));
1816               end if;
1817            end if;
1818            prev_base := this_base;
1819            prev_end  := this_end;
1820         end if;
1821      end loop;
1822      -- if there was no gap to fit the sdb rom, place it at the end
1823      if(unsigned(result) = 0) then
1824            result := std_logic_vector(f_align_addr_offset(this_base, to_unsigned(rom_bytes-1, 64),
1825                                       this_end-this_base)(t_wishbone_address'left downto 0));
1826      end if;
1827      return result;
1828   end f_sdb_create_rom_addr;
1829------------------------------------------------------------------------------------------------------------------------------
1830-- END MAT's NEW FUNCTIONS FROM  18th Oct 2013
1831------------------------------------------------------------------------------------------------------------------------------
1832
1833  function f_sdb_bus_end(
1834    g_wraparound : boolean;
1835    g_layout     : t_sdb_record_array;
1836    g_sdb_addr   : t_wishbone_address;
1837    msi          : boolean) return unsigned
1838  is
1839    alias c_layout : t_sdb_record_array(g_layout'length-1 downto 0) is g_layout;
1840
1841    -- How much space does the ROM need?
1842    constant c_used_entries : natural := c_layout'length + 1;
1843    constant c_rom_entries  : natural := 2**f_ceil_log2(c_used_entries);  -- next power of 2
1844    constant c_sdb_bytes    : natural := c_sdb_device_length / 8;
1845    constant c_rom_bytes    : natural := c_rom_entries * c_sdb_bytes;
1846
1847    variable result : unsigned(63 downto 0) := (others => '0');
1848    variable typ    : std_logic_vector(7 downto 0);
1849    variable last   : unsigned(63 downto 0);
1850  begin
1851    if not msi then
1852      -- The ROM will be an addressed slave as well
1853      result := (others => '0');
1854      result(g_sdb_addr'range) := unsigned(g_sdb_addr);
1855      result := result + to_unsigned(c_rom_bytes, 64) - 1;
1856    end if;
1857
1858    for i in c_layout'range loop
1859      typ  := c_layout(i)(7 downto 0);
1860      last := unsigned(f_sdb_extract_component(c_layout(i)(447 downto 8)).addr_last);
1861      case typ is
1862        when x"01" => if not msi and last > result then result := last; end if;
1863        when x"02" => if not msi and last > result then result := last; end if;
1864        when x"03" => if     msi and last > result then result := last; end if;
1865        when others => null;
1866      end case;
1867    end loop;
1868
1869    -- round result up to a power of two -1
1870    for i in 62 downto 0 loop
1871      result(i) := result(i) or result(i+1);
1872    end loop;
1873
1874    if not g_wraparound then
1875      result := (others => '0');
1876      for i in 0 to c_wishbone_address_width-1 loop
1877        result(i) := '1';
1878      end loop;
1879    end if;
1880
1881    return result;
1882  end f_sdb_bus_end;
1883
1884  function f_xwb_bridge_manual_sdb(
1885    g_size     : t_wishbone_address;
1886    g_sdb_addr : t_wishbone_address) return t_sdb_bridge
1887  is
1888    variable result : t_sdb_bridge;
1889  begin
1890    result.sdb_child                                      := (others => '0');
1891    result.sdb_child(c_wishbone_address_width-1 downto 0) := g_sdb_addr;
1892
1893    result.sdb_component.addr_first                                     := (others => '0');
1894    result.sdb_component.addr_last                                      := (others => '0');
1895    result.sdb_component.addr_last(c_wishbone_address_width-1 downto 0) := g_size;
1896
1897    result.sdb_component.product.vendor_id := x"0000000000000651";  -- GSI
1898    result.sdb_component.product.device_id := x"eef0b198";
1899    result.sdb_component.product.version   := x"00000001";
1900    result.sdb_component.product.date      := x"20120511";
1901    result.sdb_component.product.name      := "WB4-Bridge-GSI     ";
1902
1903    return result;
1904  end f_xwb_bridge_manual_sdb;
1905
1906  function f_xwb_bridge_layout_sdb(     -- determine bus size from layout
1907    g_wraparound : boolean := true;
1908    g_layout     : t_sdb_record_array;
1909    g_sdb_addr   : t_wishbone_address) return t_sdb_bridge
1910  is
1911    variable address : t_wishbone_address;
1912  begin
1913    address := std_logic_vector(f_sdb_bus_end(g_wraparound, g_layout, g_sdb_addr, false)(address'range));
1914    return f_xwb_bridge_manual_sdb(address, g_sdb_addr);
1915  end f_xwb_bridge_layout_sdb;
1916
1917  function f_xwb_msi_manual_sdb(
1918    g_size     : t_wishbone_address) return t_sdb_msi
1919  is
1920    variable result : t_sdb_msi;
1921  begin
1922    result.wbd_endian := '0';
1923    result.wbd_width  := x"7";
1924
1925    result.sdb_component.addr_first                                     := (others => '0');
1926    result.sdb_component.addr_last                                      := (others => '0');
1927    result.sdb_component.addr_last(c_wishbone_address_width-1 downto 0) := g_size;
1928
1929    result.sdb_component.product.vendor_id := x"0000000000000651";  -- GSI
1930    result.sdb_component.product.device_id := x"aa7bfb3c";
1931    result.sdb_component.product.version   := x"00000001";
1932    result.sdb_component.product.date      := x"20160422";
1933    result.sdb_component.product.name      := "WB4-MSI-Bridge-GSI ";
1934
1935    return result;
1936  end f_xwb_msi_manual_sdb;
1937
1938  function f_xwb_msi_layout_sdb(     -- determine MSI size from layout
1939    g_layout     : t_sdb_record_array) return t_sdb_msi
1940  is
1941    constant zero : t_wishbone_address := (others => '0');
1942    variable address : t_wishbone_address;
1943  begin
1944    address := std_logic_vector(f_sdb_bus_end(true, g_layout, zero, true)(address'range));
1945    return f_xwb_msi_manual_sdb(address);
1946  end f_xwb_msi_layout_sdb;
1947
1948  function f_xwb_dpram(g_size : natural) return t_sdb_device
1949  is
1950    variable result : t_sdb_device;
1951  begin
1952    result.abi_class     := x"0001";    -- RAM device
1953    result.abi_ver_major := x"01";
1954    result.abi_ver_minor := x"00";
1955    result.wbd_width     := x"7";       -- 32/16/8-bit supported
1956    result.wbd_endian    := c_sdb_endian_big;
1957
1958    result.sdb_component.addr_first := (others => '0');
1959    result.sdb_component.addr_last  := std_logic_vector(to_unsigned(g_size*4-1, 64));
1960
1961    result.sdb_component.product.vendor_id := x"000000000000CE42";  -- CERN
1962    result.sdb_component.product.device_id := x"66cfeb52";
1963    result.sdb_component.product.version   := x"00000001";
1964    result.sdb_component.product.date      := x"20120305";
1965    result.sdb_component.product.name      := "WB4-BlockRAM       ";
1966
1967    return result;
1968  end f_xwb_dpram;
1969
1970  function f_bits2string(s : std_logic_vector) return string is
1971    --- extend length to full hex nibble
1972    variable result : string((s'length+7)/4 downto 1);
1973    variable s_norm : std_logic_vector(result'length*4-1 downto 0) := (others=>'0');
1974    variable cut : natural;
1975    variable nibble: std_logic_vector(3 downto 0);
1976    constant len : natural := result'length;
1977  begin
1978    s_norm(s'length-1 downto 0) := s;
1979    for i in len-1 downto 0 loop
1980      nibble := s_norm(i*4+3 downto i*4);
1981      case nibble is
1982        when "0000" => result(i+1) := '0';
1983        when "0001" => result(i+1) := '1';
1984        when "0010" => result(i+1) := '2';
1985        when "0011" => result(i+1) := '3';
1986        when "0100" => result(i+1) := '4';
1987        when "0101" => result(i+1) := '5';
1988        when "0110" => result(i+1) := '6';
1989        when "0111" => result(i+1) := '7';
1990        when "1000" => result(i+1) := '8';
1991        when "1001" => result(i+1) := '9';
1992        when "1010" => result(i+1) := 'a';
1993        when "1011" => result(i+1) := 'b';
1994        when "1100" => result(i+1) := 'c';
1995        when "1101" => result(i+1) := 'd';
1996        when "1110" => result(i+1) := 'e';
1997        when "1111" => result(i+1) := 'f';
1998        when others => result(i+1) := 'X';
1999      end case;
2000    end loop;
2001
2002    -- trim leading 0s
2003    strip : for i in result'length downto 1 loop
2004      cut := i;
2005      exit strip when result(i) /= '0';
2006    end loop;
2007
2008    return "0x" & result(cut downto 1);
2009  end f_bits2string;
2010
2011  -- Converts string (hex number, without leading 0x) to std_logic_vector
2012  function f_string2bits(s : string) return std_logic_vector is
2013    constant len : natural := s'length;
2014    variable slv : std_logic_vector(s'length*4-1 downto 0);
2015    variable nibble : std_logic_vector(3 downto 0);
2016  begin
2017    for i in 0 to len-1 loop
2018      case s(i+1) is
2019        when '0' => nibble := X"0";
2020        when '1' => nibble := X"1";
2021        when '2' => nibble := X"2";
2022        when '3' => nibble := X"3";
2023        when '4' => nibble := X"4";
2024        when '5' => nibble := X"5";
2025        when '6' => nibble := X"6";
2026        when '7' => nibble := X"7";
2027        when '8' => nibble := X"8";
2028        when '9' => nibble := X"9";
2029        when 'a' => nibble := X"A";
2030        when 'A' => nibble := X"A";
2031        when 'b' => nibble := X"B";
2032        when 'B' => nibble := X"B";
2033        when 'c' => nibble := X"C";
2034        when 'C' => nibble := X"C";
2035        when 'd' => nibble := X"D";
2036        when 'D' => nibble := X"D";
2037        when 'e' => nibble := X"E";
2038        when 'E' => nibble := X"E";
2039        when 'f' => nibble := X"F";
2040        when 'F' => nibble := X"F";
2041        when others => nibble := "XXXX";
2042      end case;
2043      if s'ascending then
2044        slv(slv'length-(i*4)-1 downto slv'length-(i+1)*4) := nibble;
2045      else
2046        slv(((i+1)*4)-1 downto i*4) := nibble;
2047      end if;
2048    end loop;
2049    return slv;
2050  end f_string2bits;
2051
2052  -- Converts string to ascii (std_logic_vector)
2053  function f_string2svl (s : string) return std_logic_vector is
2054    constant len : natural := s'length;
2055    variable slv : std_logic_vector((s'length * 8) - 1 downto 0);
2056  begin
2057    for i in 0 to len-1 loop
2058      slv(slv'high-i*8 downto (slv'high-7)-i*8) :=
2059        std_logic_vector(to_unsigned(character'pos(s(i+1)), 8));
2060    end loop;
2061    return slv;
2062  end f_string2svl;
2063
2064  -- Converts ascii (std_logic_vector) to string
2065  function f_slv2string (slv : std_logic_vector) return string is
2066    constant len : natural := slv'length;
2067    variable s : string(1 to slv'length/8);
2068  begin
2069    for i in 0 to (len/8)-1 loop
2070      s(i+1) := character'val(to_integer(unsigned(slv(slv'high-i*8 downto (slv'high-7)-i*8))));
2071    end loop;
2072    return s;
2073  end f_slv2string;
2074
2075    -- pads a string of unknown length to a given length (useful for integer'image)
2076  function f_string_fix_len ( s : string; ret_len : natural := 10; fill_char : character := '0'; justify_right : boolean := true ) return string is
2077      variable ret_v : string (1 to ret_len);
2078      constant pad_len : integer := ret_len - s'length ;
2079      variable pad_v : string (1 to abs(pad_len));
2080   begin
2081      if pad_len < 1 then
2082         ret_v := s(ret_v'range);
2083      else
2084         pad_v := (others => fill_char);
2085         if justify_right then
2086           ret_v := pad_v & s;
2087         else
2088           ret_v := s & pad_v ;
2089         end if;
2090      end if;
2091      return ret_v;
2092   end f_string_fix_len;
2093
2094   -- do not synthesize
2095   function f_hot_to_bin(x : std_logic_vector) return natural is
2096      variable rv : natural;
2097   begin
2098      rv := 0;
2099      -- if there are few ones set in _x_ then the most significant will be
2100      -- translated to bin
2101      for i in 0 to x'left loop
2102         if x(i) = '1' then
2103           rv := i+1;
2104         end if;
2105      end loop;
2106      return rv;
2107  end function;
2108
2109  function f_wb_spi_flash_sdb(g_bits : natural) return t_sdb_device is
2110    variable result : t_sdb_device := (
2111      abi_class     => x"0000", -- undocumented device
2112      abi_ver_major => x"01",
2113      abi_ver_minor => x"02",
2114      wbd_endian    => c_sdb_endian_big,
2115      wbd_width     => x"7", -- 8/16/32-bit port granularity
2116      sdb_component => (
2117      addr_first    => x"0000000000000000",
2118      addr_last     => x"0000000000ffffff",
2119      product => (
2120      vendor_id     => x"0000000000000651", -- GSI
2121      device_id     => x"5cf12a1c",
2122      version       => x"00000002",
2123      date          => x"20140417",
2124      name          => "SPI-FLASH-16M-MMAP ")));
2125  begin
2126    result.sdb_component.addr_last := std_logic_vector(to_unsigned(2**g_bits-1, 64));
2127    return result;
2128  end f_wb_spi_flash_sdb;
2129
2130end wishbone_pkg;
2131