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