Files
Toooba/src_Testbench/SoC/SoC_Map.bsv

297 lines
10 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.
// ================================================================
// Exports
export SoC_Map_Struct (..), soc_map_struct;
export SoC_Map_IFC (..), mkSoC_Map;
export Num_Masters;
export imem_master_num;
export dmem_master_num;
export Num_Slaves;
export boot_rom_slave_num;
export mem0_controller_slave_num;
export uart0_slave_num;
export N_External_Interrupt_Sources;
export n_external_interrupt_sources;
export irq_num_uart0;
// ================================================================
// Bluespec library imports
// None
// ================================================================
// 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) 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_0200_0000,
main_mem_addr_base: 'h_8000_0000,
main_mem_addr_size: 'h_1000_0000,
pc_reset_value: 'h_0000_1000
};
// ================================================================
// Interface and module for the address map
interface SoC_Map_IFC;
(* always_ready *) method Fabric_Addr m_near_mem_io_addr_base;
(* always_ready *) method Fabric_Addr m_near_mem_io_addr_size;
(* always_ready *) method Fabric_Addr m_near_mem_io_addr_lim;
(* always_ready *) method Fabric_Addr m_plic_addr_base;
(* always_ready *) method Fabric_Addr m_plic_addr_size;
(* always_ready *) method Fabric_Addr m_plic_addr_lim;
(* always_ready *) method Fabric_Addr m_uart0_addr_base;
(* always_ready *) method Fabric_Addr m_uart0_addr_size;
(* always_ready *) method Fabric_Addr m_uart0_addr_lim;
(* always_ready *) method Fabric_Addr m_boot_rom_addr_base;
(* always_ready *) method Fabric_Addr m_boot_rom_addr_size;
(* always_ready *) method Fabric_Addr m_boot_rom_addr_lim;
(* always_ready *) method Fabric_Addr m_mem0_controller_addr_base;
(* always_ready *) method Fabric_Addr m_mem0_controller_addr_size;
(* always_ready *) method Fabric_Addr m_mem0_controller_addr_lim;
(* always_ready *) method Fabric_Addr m_tcm_addr_base;
(* always_ready *) method Fabric_Addr m_tcm_addr_size;
(* always_ready *) method Fabric_Addr m_tcm_addr_lim;
(* always_ready *)
method Bool m_is_mem_addr (Fabric_Addr addr);
(* always_ready *)
method Bool m_is_IO_addr (Fabric_Addr addr);
(* 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);
// ----------------------------------------------------------------
// Near_Mem_IO (including CLINT, the core-local interruptor)
Fabric_Addr near_mem_io_addr_base = 'h_0200_0000;
Fabric_Addr near_mem_io_addr_size = 'h_0000_C000; // 48K
Fabric_Addr near_mem_io_addr_lim = near_mem_io_addr_base + near_mem_io_addr_size;
function Bool fn_is_near_mem_io_addr (Fabric_Addr addr);
return ((near_mem_io_addr_base <= addr) && (addr < near_mem_io_addr_lim));
endfunction
// ----------------------------------------------------------------
// PLIC
Fabric_Addr plic_addr_base = 'h_0C00_0000;
Fabric_Addr plic_addr_size = 'h_0040_0000; // 4M
Fabric_Addr plic_addr_lim = plic_addr_base + plic_addr_size;
function Bool fn_is_plic_addr (Fabric_Addr addr);
return ((plic_addr_base <= addr) && (addr < plic_addr_lim));
endfunction
// ----------------------------------------------------------------
// UART 0
Fabric_Addr uart0_addr_base = 'hC000_0000;
Fabric_Addr uart0_addr_size = 'h0000_0080; // 128
Fabric_Addr uart0_addr_lim = uart0_addr_base + uart0_addr_size;
function Bool fn_is_uart0_addr (Fabric_Addr addr);
return ((uart0_addr_base <= addr) && (addr < uart0_addr_lim));
endfunction
// ----------------------------------------------------------------
// Boot ROM
Fabric_Addr boot_rom_addr_base = 'h_0000_1000;
Fabric_Addr boot_rom_addr_size = 'h_0000_1000; // 4K
Fabric_Addr boot_rom_addr_lim = boot_rom_addr_base + boot_rom_addr_size;
function Bool fn_is_boot_rom_addr (Fabric_Addr addr);
return ((boot_rom_addr_base <= addr) && (addr < boot_rom_addr_lim));
endfunction
// ----------------------------------------------------------------
// Main Mem Controller 0
Fabric_Addr mem0_controller_addr_base = 'h_8000_0000;
Fabric_Addr mem0_controller_addr_size = 'h_1000_0000; // 256 MB
Fabric_Addr mem0_controller_addr_lim = mem0_controller_addr_base + mem0_controller_addr_size;
function Bool fn_is_mem0_controller_addr (Fabric_Addr addr);
return ((mem0_controller_addr_base <= addr) && (addr < mem0_controller_addr_lim));
endfunction
// ----------------------------------------------------------------
// Tightly-coupled memory ('TCM'; optional)
`ifdef Near_Mem_TCM
// Integer kB_per_TCM = 'h4; // 4KB
// Integer kB_per_TCM = 'h40; // 64KB
// Integer kB_per_TCM = 'h80; // 128KB
// Integer kB_per_TCM = 'h400; // 1 MB
Integer kB_per_TCM = 'h4000; // 16 MB
`else
Integer kB_per_TCM = 0;
`endif
Integer bytes_per_TCM = kB_per_TCM * 'h400;
Fabric_Addr tcm_addr_base = 'h_0000_0000;
Fabric_Addr tcm_addr_size = fromInteger (bytes_per_TCM);
Fabric_Addr tcm_addr_lim = tcm_addr_base + tcm_addr_size;
function Bool fn_is_tcm_addr (Fabric_Addr addr);
return ((tcm_addr_base <= addr) && (addr < tcm_addr_lim));
endfunction
// ----------------------------------------------------------------
// Memory address predicate
// Identifies memory addresses in the Fabric.
// (Caches need this information to cache these addresses.)
function Bool fn_is_mem_addr (Fabric_Addr addr);
return ( fn_is_mem0_controller_addr (addr)
|| fn_is_tcm_addr (addr)
);
endfunction
// ----------------------------------------------------------------
// I/O address predicate
// Identifies I/O addresses in the Fabric.
// (Caches need this information to avoid cacheing these addresses.)
function Bool fn_is_IO_addr (Fabric_Addr addr);
return ( fn_is_boot_rom_addr (addr)
|| fn_is_near_mem_io_addr (addr)
|| fn_is_plic_addr (addr)
|| fn_is_uart0_addr (addr)
);
endfunction
// ----------------------------------------------------------------
// PC, MTVEC and NMIVEC reset values
Bit #(64) pc_reset_value = boot_rom_addr_base;
Bit #(64) mtvec_reset_value = 'h1000; // TODO
Bit #(64) nmivec_reset_value = ?; // TODO
// ================================================================
// INTERFACE
method Fabric_Addr m_near_mem_io_addr_base = near_mem_io_addr_base;
method Fabric_Addr m_near_mem_io_addr_size = near_mem_io_addr_size;
method Fabric_Addr m_near_mem_io_addr_lim = near_mem_io_addr_lim;
method Fabric_Addr m_plic_addr_base = plic_addr_base;
method Fabric_Addr m_plic_addr_size = plic_addr_size;
method Fabric_Addr m_plic_addr_lim = plic_addr_lim;
method Fabric_Addr m_uart0_addr_base = uart0_addr_base;
method Fabric_Addr m_uart0_addr_size = uart0_addr_size;
method Fabric_Addr m_uart0_addr_lim = uart0_addr_lim;
method Fabric_Addr m_boot_rom_addr_base = boot_rom_addr_base;
method Fabric_Addr m_boot_rom_addr_size = boot_rom_addr_size;
method Fabric_Addr m_boot_rom_addr_lim = boot_rom_addr_lim;
method Fabric_Addr m_mem0_controller_addr_base = mem0_controller_addr_base;
method Fabric_Addr m_mem0_controller_addr_size = mem0_controller_addr_size;
method Fabric_Addr m_mem0_controller_addr_lim = mem0_controller_addr_lim;
method Fabric_Addr m_tcm_addr_base = tcm_addr_base;
method Fabric_Addr m_tcm_addr_size = tcm_addr_size;
method Fabric_Addr m_tcm_addr_lim = tcm_addr_lim;
method Bool m_is_mem_addr (Fabric_Addr addr) = fn_is_mem_addr (addr);
method Bool m_is_IO_addr (Fabric_Addr addr) = fn_is_IO_addr (addr);
method Bool m_is_near_mem_IO_addr (Fabric_Addr addr) = fn_is_near_mem_io_addr (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
// ================================================================
// Count and master-numbers of masters in the fabric.
typedef 2 Num_Masters;
Integer imem_master_num = 0;
Integer dmem_master_num = 1;
// ================================================================
// Count and slave-numbers of slaves in the fabric.
typedef 3 Num_Slaves;
Integer boot_rom_slave_num = 0;
Integer mem0_controller_slave_num = 1;
Integer uart0_slave_num = 2;
// ================================================================
// 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_uart0 = 0;
// ================================================================
endpackage