blob: 9440f6fc16e0dafe0eb2b2b710c3a8c2ed3aa4bb [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// TODO: Only here until code is ported to use top generator
module tlul_xbar_usb (
input clk_i,
input rst_ni,
// Host accepter
input tlul_pkg::tl_h2d_t tl_h_i [tl_main_pkg::N_HOST],
output tlul_pkg::tl_d2h_t tl_h_o [tl_main_pkg::N_HOST],
// Device sender
output tlul_pkg::tl_h2d_t tl_d_o [tl_main_pkg::N_DEVICE],
input tlul_pkg::tl_d2h_t tl_d_i [tl_main_pkg::N_DEVICE]
);
import tlul_pkg::*;
import tl_main_pkg::*;
//
// Core D interface connects to Sram, Uart, Gpio, DebugMem and error
//
localparam int unsigned N_CORE_D_DEVICE = 5;
typedef enum logic [2:0] {
CoreDToSram = 3'h0,
CoreDToUart = 3'h1,
CoreDToGpio = 3'h2,
CoreDToDebugMem = 3'h3,
CoreDToSpiDevice = 3'h4,
CoreDToErr = 3'h5
} core_d_dsp_e;
core_d_dsp_e dev_select_core_d;
tl_h2d_t tl_core_d_h2d [N_CORE_D_DEVICE];
tl_d2h_t tl_core_d_d2h [N_CORE_D_DEVICE];
tlul_socket_1n #(
.N (N_CORE_D_DEVICE),
.HReqPass (1'b0), // register just outside of core
.HRspPass (1'b0), // register just outside of core
.DReqPass ({N_CORE_D_DEVICE{1'b1}}), // unregistered
.DRspPass ({N_CORE_D_DEVICE{1'b1}}), // unregistered
.HReqDepth (4'h2), // some elasticity
.HRspDepth (4'h2), // some elasticity
.DReqDepth ({N_CORE_D_DEVICE{4'h1}}), // minimal elasticity
.DRspDepth ({N_CORE_D_DEVICE{4'h1}}) // minimal elasticity
) core_d_socket_14 (
.clk_i (clk_i),
.rst_ni (rst_ni),
.tl_h_i (tl_h_i[TlCored]),
.tl_h_o (tl_h_o[TlCored]),
.tl_d_o (tl_core_d_h2d),
.tl_d_i (tl_core_d_d2h),
.dev_select (dev_select_core_d)
);
// address map lookup, will eventually be automated via configuration
assign dev_select_core_d =
((tl_h_i[TlCored].a_address & ~ADDR_MASK_RAM_MAIN) == ADDR_SPACE_RAM_MAIN) ? CoreDToSram :
((tl_h_i[TlCored].a_address & ~ADDR_MASK_UART) == ADDR_SPACE_UART) ? CoreDToUart :
((tl_h_i[TlCored].a_address & ~ADDR_MASK_GPIO) == ADDR_SPACE_GPIO) ? CoreDToGpio :
((tl_h_i[TlCored].a_address & ~ADDR_MASK_DEBUG_MEM) == ADDR_SPACE_DEBUG_MEM) ? CoreDToDebugMem :
((tl_h_i[TlCored].a_address & ~ADDR_MASK_SPI_DEVICE) == ADDR_SPACE_SPI_DEVICE) ? CoreDToSpiDevice :
CoreDToErr; // indicate to socket to return error
//
// Core I connects to SRAM and Debug Memory and error
// TODO: Add connection to bootrom
//
localparam int unsigned N_CORE_I_DEVICE = 2;
typedef enum logic [1:0] {
CoreIToSram = 2'h0,
CoreIToDebugMem = 2'h1,
CoreIToErr = 2'h2
} core_i_dsp_e;
core_i_dsp_e dev_select_core_i;
tl_h2d_t tl_core_i_h2d [N_CORE_I_DEVICE];
tl_d2h_t tl_core_i_d2h [N_CORE_I_DEVICE];
tlul_socket_1n #(
.N (N_CORE_I_DEVICE),
.HReqPass (1'b0), // register just outside of core
.HRspPass (1'b0), // register just outside of core
.DReqPass ({N_CORE_I_DEVICE{1'b1}}), // unregistered
.DRspPass ({N_CORE_I_DEVICE{1'b1}}), // unregistered
.HReqDepth (4'h2), // some elasticity
.HRspDepth (4'h2), // some elasticity
.DReqDepth ({N_CORE_I_DEVICE{4'h1}}), // minimal elasticity
.DRspDepth ({N_CORE_I_DEVICE{4'h1}}) // minimal elasticity
) core_i_socket_12 (
.clk_i (clk_i),
.rst_ni (rst_ni),
.tl_h_i (tl_h_i[TlCorei]),
.tl_h_o (tl_h_o[TlCorei]),
.tl_d_o (tl_core_i_h2d),
.tl_d_i (tl_core_i_d2h),
.dev_select (dev_select_core_i)
);
// address map lookup, will eventually be automated via configuration
assign dev_select_core_i =
((tl_h_i[TlCorei].a_address & ~ADDR_MASK_RAM_MAIN) == ADDR_SPACE_RAM_MAIN) ? CoreIToSram :
((tl_h_i[TlCorei].a_address & ~ADDR_MASK_DEBUG_MEM) == ADDR_SPACE_DEBUG_MEM) ? CoreIToDebugMem :
CoreIToErr; // indicate to socket to return error
//
// SRAM connects to Core I, Core D and Debug SBA
//
localparam int unsigned N_SRAM_HOST = 3;
typedef enum logic [1:0] {
SramFromCoreI = 2'h0,
SramFromCoreD = 2'h1,
SramFromDebugSba = 2'h2
} sram_host_e;
tl_h2d_t tl_sram_h_h2d [N_SRAM_HOST];
tl_d2h_t tl_sram_h_d2h [N_SRAM_HOST];
assign tl_sram_h_h2d[SramFromCoreI] = tl_core_i_h2d[CoreIToSram];
assign tl_sram_h_h2d[SramFromCoreD] = tl_core_d_h2d[CoreDToSram];
assign tl_sram_h_h2d[SramFromDebugSba] = tl_h_i[TlDmSba];
assign tl_core_i_d2h[CoreIToSram] = tl_sram_h_d2h[SramFromCoreI];
assign tl_core_d_d2h[CoreDToSram] = tl_sram_h_d2h[SramFromCoreD];
assign tl_h_o[TlDmSba] = tl_sram_h_d2h[SramFromDebugSba];
tlul_socket_m1 #(
.M (N_SRAM_HOST),
.HReqPass ({N_SRAM_HOST{1'b1}}), // unregistered
.HRspPass ({N_SRAM_HOST{1'b1}}), // unregistered
.HReqDepth ({N_SRAM_HOST{4'h1}}), // minimal elasticity
.HRspDepth ({N_SRAM_HOST{4'h1}}), // minimal elasticity
.DReqPass (1'b1), // unregistered
.DRspPass (1'b1), // unregistered
.DReqDepth (4'h1), // minimal elasticity
.DRspDepth (4'h1) // minimal elasticity
) sram_socket_31 (
.clk_i (clk_i),
.rst_ni (rst_ni),
.tl_h_i (tl_sram_h_h2d),
.tl_h_o (tl_sram_h_d2h),
.tl_d_o (tl_d_o[TlRamMain]),
.tl_d_i (tl_d_i[TlRamMain])
);
//
// Debug Memory connects to Core I and Core D
//
localparam int unsigned N_DEBUGMEM_HOST = 2;
typedef enum logic [0:0] {
DebugMemFromCoreI = 1'h0,
DebugMemFromCoreD = 1'h1
} debugmem_host_e;
tl_h2d_t tl_debugmem_h_h2d [N_DEBUGMEM_HOST];
tl_d2h_t tl_debugmem_h_d2h [N_DEBUGMEM_HOST];
assign tl_debugmem_h_h2d[DebugMemFromCoreI] = tl_core_i_h2d[CoreIToDebugMem];
assign tl_debugmem_h_h2d[DebugMemFromCoreD] = tl_core_d_h2d[CoreDToDebugMem];
assign tl_core_i_d2h[CoreIToDebugMem] = tl_debugmem_h_d2h[DebugMemFromCoreI];
assign tl_core_d_d2h[CoreDToDebugMem] = tl_debugmem_h_d2h[DebugMemFromCoreD];
tlul_socket_m1 #(
.M (N_DEBUGMEM_HOST),
.HReqPass ({N_DEBUGMEM_HOST{1'b1}}), // unregistered
.HRspPass ({N_DEBUGMEM_HOST{1'b1}}), // unregistered
.HReqDepth ({N_DEBUGMEM_HOST{4'h1}}), // minimal elasticity
.HRspDepth ({N_DEBUGMEM_HOST{4'h1}}), // minimal elasticity
.DReqPass (1'b1), // unregistered
.DRspPass (1'b1), // unregistered
.DReqDepth (4'h1), // minimal elasticity
.DRspDepth (4'h1) // minimal elasticity
) debugmem_socket_21 (
.clk_i (clk_i),
.rst_ni (rst_ni),
.tl_h_i (tl_debugmem_h_h2d),
.tl_h_o (tl_debugmem_h_d2h),
.tl_d_o (tl_d_o[TlDebugMem]),
.tl_d_i (tl_d_i[TlDebugMem])
);
// UART connects to Core D
// TODO: Connect to SBA as well?
assign tl_d_o[TlUart] = tl_core_d_h2d[CoreDToUart];
assign tl_core_d_d2h[CoreDToUart] = tl_d_i[TlUart];
// GPIO connects to Core D
// TODO: Connect to SBA as well?
assign tl_d_o[TlGpio] = tl_core_d_h2d[CoreDToGpio];
assign tl_core_d_d2h[CoreDToGpio] = tl_d_i[TlGpio];
// SPI Device
assign tl_d_o[TlSpiDevice] = tl_core_d_h2d[CoreDToSpiDevice];
assign tl_core_d_d2h[CoreDToSpiDevice] = tl_d_i[TlSpiDevice];
endmodule