Files
Toooba/src_SSITH_P3/src_BSV/SoC_Map.bsv
2025-02-20 17:45:58 +00:00

320 lines
11 KiB
Plaintext

// Copyright (c) 2013-2019 Bluespec, Inc. All Rights Reserved
package SoC_Map;
// ================================================================
// This module defines the overall 'address map' of the SoC, showing
// the addresses serviced by each slave IP, and which addresses are
// memory vs. I/O.
// ***** WARNING! WARNING! WARNING! *****
// During system integration, this address map should be identical to
// the system interconnect settings (e.g., routing of requests between
// masters and slaves). This map is also needed by software so that
// it knows how to address various IPs.
// This module contains no state; it just has constants, and so can be
// freely instantiated at multiple places in the SoC module hierarchy
// at no hardware cost. It allows this map to be defined in one
// place and shared across the SoC.
// ================================================================
// This version of SoC_Map is for the DARPA SSITH GFE
// Our "Near_Mem_IO" corresponds to "CLINT" in Rocket
// ================================================================
// Exports
export SoC_Map_Struct (..), soc_map_struct;
export SoC_Map_IFC (..), mkSoC_Map;
export N_External_Interrupt_Sources;
export n_external_interrupt_sources;
export irq_num_uart16550_0;
// ================================================================
// Bluespec library imports
import Routable :: *; // For Range
// ================================================================
// Project imports
import Fabric_Defs :: *; // Only for type Fabric_Addr
// ================================================================
// Top-level-struct version of the SoC Map for RISCY-OOO
typedef struct {
Bit #(64) near_mem_io_addr_base;
Bit #(64) near_mem_io_addr_size;
Bit #(64) boot_rom_addr_base;
Bit #(64) boot_rom_addr_size;
Bit #(64) main_mem_addr_base;
Bit #(64) main_mem_addr_size;
Bit #(64) pc_reset_value;
} SoC_Map_Struct
deriving (FShow);
SoC_Map_Struct soc_map_struct =
SoC_Map_Struct {
near_mem_io_addr_base: 'h_1000_0000,
near_mem_io_addr_size: 'h_0001_0000,
boot_rom_addr_base: 'h_7000_0000,
boot_rom_addr_size: 'h_0000_1000,
main_mem_addr_base: 'h_C000_0000,
main_mem_addr_size: 'h_C000_0000,
pc_reset_value: 'h_7000_0000 // = boot_rom_addr_base
};
// ================================================================
function Bool addr_function(Fabric_Addr base, Fabric_Addr size, Fabric_Addr addr);
return (base <= addr) && (addr < (base + size));
endfunction
// ================================================================
// Interface and module for the address map
interface SoC_Map_IFC;
(* always_ready *) method Range#(Wd_Addr) m_plic_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_near_mem_io_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_flash_mem_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_ethernet_0_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_dma_0_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_timer_0_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_uart16550_0_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_gpio_0_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_boot_rom_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_ddr4_0_uncached_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_ddr4_0_cached_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_mem0_controller_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_soc_config_addr_range;
(* always_ready *)
method Bool m_is_mem_addr (Fabric_Addr addr);
(* always_ready *)
method Bool m_is_IO_addr (Fabric_Addr addr, Bool imem_not_dmem);
(* always_ready *)
method Bool m_is_near_mem_IO_addr (Fabric_Addr addr);
(* always_ready *) method Bit #(64) m_pc_reset_value;
(* always_ready *) method Bit #(64) m_mtvec_reset_value;
(* always_ready *) method Bit #(64) m_nmivec_reset_value;
endinterface
// ================================================================
(* synthesize *)
module mkSoC_Map (SoC_Map_IFC);
// ----------------------------------------------------------------
// PLIC
let plic_addr_range = Range {
base: 'h_0C00_0000,
size: 'h_0040_0000 // 4M
};
// ----------------------------------------------------------------
// Near_Mem_IO (CLINT)
let near_mem_io_addr_range = Range {
base: 'h_1000_0000,
size: 'h_0001_0000 // 64K
};
// ----------------------------------------------------------------
// Flash Mem
let flash_mem_addr_range = Range {
base: 'h_4000_0000,
size: 'h_0800_0000 // 128M
};
// ----------------------------------------------------------------
// Ethernet 0
let ethernet_0_addr_range = Range {
base: 'h_6210_0000,
size: 'h_0004_0000 // 256K
};
// ----------------------------------------------------------------
// DMA 0
let dma_0_addr_range = Range {
base: 'h_6220_0000,
size: 'h_0001_0000 // 64K
};
// ----------------------------------------------------------------
// Timer
let timer_0_addr_range = Range {
base: 'h_5000_0000,
size: 'h_0001_0000 // 64K
};
// ----------------------------------------------------------------
// UART 0
let uart16550_0_addr_range = Range {
base: 'h_6230_0000,
size: 'h_0000_1000 // 4K
};
// ----------------------------------------------------------------
// GPIO 0
let gpio_0_addr_range = Range {
base: 'h_6FFF_0000,
size: 'h_0001_0000 // 64K
};
// ----------------------------------------------------------------
// Boot ROM
let boot_rom_addr_range = Range {
base: 'h_7000_0000,
size: 'h_0000_1000 // 4K
};
// ----------------------------------------------------------------
// DDR memory 0 uncached
let ddr4_0_uncached_addr_range = Range {
base: 'h_8000_0000,
size: 'h_4000_0000 // 1G
};
// ----------------------------------------------------------------
// DDR memory 0 cached
let ddr4_0_cached_addr_range = Range {
base: 'h_C000_0000,
size: 'h_C000_0000 // 3G
};
// ----------------------------------------------------------------
// SoC Config addresses
let soc_config_addr_range = Range {
base: 'h_0000_1000,
size: 'h_0000_1000 // 4K
};
// ----------------------------------------------------------------
function fn_is_flash_regs_addr = addr_function('h6240_0000, 'h1000);
function fn_is_uart1_addr = addr_function('h6230_0000, 'h1000);
function fn_is_i2c_addr = addr_function('h6231_0000, 'h1000);
function fn_is_spi_addr = addr_function('h6232_0000, 'h1000);
function fn_is_uart2_addr = addr_function('h6236_0000, 'h1000);
function fn_is_gpio1_addr = addr_function('h6233_0000, 'h1000);
function fn_is_gpio2_addr = addr_function('h6237_0000, 'h1000);
function fn_is_xdma_control = addr_function('h2000_0000, 'h1000_0000);
function fn_is_xdma_ecam = addr_function('h3000_0000, 'h1000_0000);
// ----------------------------------------------------------------
// Memory address predicate
// Identifies memory addresses in the Fabric.
// (Caches needs this information to cache these addresses.)
function Bool fn_is_mem_addr (Fabric_Addr addr);
return ( inRange(ddr4_0_cached_addr_range, addr)
);
endfunction
// ----------------------------------------------------------------
// I/O address predicate
// Identifies I/O addresses in the Fabric.
// (Caches needs this information to avoid cacheing these addresses.)
function Bool fn_is_IO_addr (Fabric_Addr addr, Bool imem_not_dmem);
return ( inRange(boot_rom_addr_range, addr)
|| inRange(ddr4_0_uncached_addr_range, addr)
|| inRange(flash_mem_addr_range, addr)
|| inRange(soc_config_addr_range, addr)
|| ( (! imem_not_dmem)
&& ( inRange(plic_addr_range, addr)
|| inRange(near_mem_io_addr_range, addr)
|| inRange(ethernet_0_addr_range, addr)
|| inRange(dma_0_addr_range, addr)
|| inRange(timer_0_addr_range, addr)
|| inRange(uart16550_0_addr_range, addr)
|| inRange(gpio_0_addr_range, addr)
|| fn_is_flash_regs_addr (addr)
|| fn_is_uart1_addr (addr)
|| fn_is_i2c_addr (addr)
|| fn_is_spi_addr (addr)
|| fn_is_uart2_addr (addr)
|| fn_is_gpio1_addr (addr)
|| fn_is_gpio2_addr (addr)
|| fn_is_xdma_control (addr)
|| fn_is_xdma_ecam (addr)
)
)
);
endfunction
// ----------------------------------------------------------------
// PC, MTVEC and NMIVEC reset values
Bit #(64) pc_reset_value = boot_rom_addr_range.base;
Bit #(64) mtvec_reset_value = 'h1000; // TODO
Bit #(64) nmivec_reset_value = ?; // TODO
// ================================================================
// INTERFACE
method Range#(Wd_Addr) m_plic_addr_range = plic_addr_range;
method Range#(Wd_Addr) m_near_mem_io_addr_range = near_mem_io_addr_range;
method Range#(Wd_Addr) m_flash_mem_addr_range = flash_mem_addr_range;
method Range#(Wd_Addr) m_ethernet_0_addr_range = ethernet_0_addr_range;
method Range#(Wd_Addr) m_dma_0_addr_range = dma_0_addr_range;
method Range#(Wd_Addr) m_timer_0_addr_range = timer_0_addr_range;
method Range#(Wd_Addr) m_uart16550_0_addr_range = uart16550_0_addr_range;
method Range#(Wd_Addr) m_gpio_0_addr_range = gpio_0_addr_range;
method Range#(Wd_Addr) m_boot_rom_addr_range = boot_rom_addr_range;
method Range#(Wd_Addr) m_ddr4_0_uncached_addr_range = ddr4_0_uncached_addr_range;
method Range#(Wd_Addr) m_ddr4_0_cached_addr_range = ddr4_0_cached_addr_range;
method Range#(Wd_Addr) m_mem0_controller_addr_range = ddr4_0_cached_addr_range;
method Range#(Wd_Addr) m_soc_config_addr_range = soc_config_addr_range;
method Bool m_is_mem_addr (Fabric_Addr addr) = fn_is_mem_addr (addr);
method Bool m_is_IO_addr (Fabric_Addr addr, Bool imem_not_dmem) = fn_is_IO_addr (addr, imem_not_dmem);
method Bool m_is_near_mem_IO_addr (Fabric_Addr addr) = inRange (near_mem_io_addr_range, addr);
method Bit #(64) m_pc_reset_value = pc_reset_value;
method Bit #(64) m_mtvec_reset_value = mtvec_reset_value;
method Bit #(64) m_nmivec_reset_value = nmivec_reset_value;
endmodule
// ================================================================
// Interrupt request numbers (== index in to vector of
// interrupt-request lines in Core)
typedef 16 N_External_Interrupt_Sources;
Integer n_external_interrupt_sources = valueOf (N_External_Interrupt_Sources);
Integer irq_num_uart16550_0 = 0;
// ================================================================
endpackage