macsim/src/arch/rvmpb.c
// Load from memory with check for memory mapped devices
// Maybe replaced by a core specific version with extended memory mapping
Load from memory with check for memory mapped devices
Maybe replaced by a core specific version with extended memory mapping
Load from memory with check for memory mapped devices Maybe replaced by a core specific version with extended memory mapping
static inline int_fast16_t memory_load_u64(node_t *node, unsigned access_type, 
    addr_t addr, uint64_t *dest)
{
    if (addr>=0xc0000000) {
        if (addr<0xd8000000) {
            assert ((RISCV_LOADBUF_SIZE & (RISCV_LOADBUF_SIZE-1)) == 0);
            rank_t source = (addr>>16)-0xc000;
            if (source == node->rank) {
                return generic_memory_load_u64(node, access_type, 
                    0xd8000000+(addr&0xffff), dest);
            } else {
                if (source >= conf_max_rank) fatal("MPB access to unavailable core %xh", node);
                addr_t ofs = addr & (RISCV_LOADBUF_SIZE-1);
                addr_t base = addr & (0x00010000 - RISCV_LOADBUF_SIZE);
                addr_t len = memory_access_len[access_type];
                if ((source == node->core.riscv.loadbuf_rank)
                    && (base == node->core.riscv.loadbuf_base)
                    && (ofs+len <= RISCV_LOADBUF_SIZE))
                {
                    memcpy(dest, node->core.riscv.loadbuf+ofs, len);
                    return 1;
                } else {
                    node->core.riscv.loadbuf_rank = source;
                    node->core.riscv.loadbuf_base = base;
                    if (node->core.riscv.mpb_send_pos < RISCV_LOADBUF_SIZE) {
                        node->core.riscv.loadbuf_pos = RISCV_LOADBUF_SIZE;
                    } else {
                        node->core.riscv.loadbuf_pos = 0;
                        if (!node->noc_send_flit(node, source, base | RISCV_FLIT_LOAD)) {
                            node->state = CS_SEND_BLOCKED;
                            return IC_BLOCKED;
                        }
                    }
                    node->state = CS_RECV_BLOCKED;
                    return IC_BLOCKED;
                }
            }
        } else if (addr>=0xd9000000) {
            fatal("#%lu °%d @%x: Memory load from address %lx", 
                node->cycle, node->rank, node->pc, addr);
        }
    }
    return generic_memory_load_u64(node, access_type, addr, dest);
}
static inline int_fast16_t memory_load_u64 ( node_t * node , unsigned access_type , addr_t addr , uint64_t * dest ) { if ( addr >= 0xc0000000 ) { if ( addr < 0xd8000000 ) { assert ( ( RISCV_LOADBUF_SIZE & ( RISCV_LOADBUF_SIZE - 1 ) ) == 0 ) ; rank_t source = ( addr >> 16 ) - 0xc000 ; if ( source == node -> rank ) { return generic_memory_load_u64 ( node , access_type , 0xd8000000 + ( addr & 0xffff ) , dest ) ; } else { if ( source >= conf_max_rank ) fatal ( " " , node ) ; addr_t ofs = addr & ( RISCV_LOADBUF_SIZE - 1 ) ; addr_t base = addr & ( 0x00010000 - RISCV_LOADBUF_SIZE ) ; addr_t len = memory_access_len [ access_type ] ; if ( ( source == node -> core . riscv . loadbuf_rank ) && ( base == node -> core . riscv . loadbuf_base ) && ( ofs + len <= RISCV_LOADBUF_SIZE ) ) { memcpy ( dest , node -> core . riscv . loadbuf + ofs , len ) ; return 1 ; } else { node -> core . riscv . loadbuf_rank = source ; node -> core . riscv . loadbuf_base = base ; if ( node -> core . riscv . mpb_send_pos < RISCV_LOADBUF_SIZE ) { node -> core . riscv . loadbuf_pos = RISCV_LOADBUF_SIZE ; } else { node -> core . riscv . loadbuf_pos = 0 ; if ( ! node -> noc_send_flit ( node , source , base | RISCV_FLIT_LOAD ) ) { node -> state = CS_SEND_BLOCKED ; return IC_BLOCKED ; } } node -> state = CS_RECV_BLOCKED ; return IC_BLOCKED ; } } } else if ( addr >= 0xd9000000 ) { fatal ( " , node -> cycle , node -> rank , node -> pc , addr ) ; } } return generic_memory_load_u64 ( node , access_type , addr , dest ) ; }
Load from memory with check for memory mapped devices
Maybe replaced by a core specific version with extended memory mapping
Load from memory with check for memory mapped devices Maybe replaced by a core specific version with extended memory mapping
// must be a power of 2 // hit // fill load buffer here, if faster transfers with less flits should be simulated //                    memory_read(nodes[source], 0xd8000000+base, //                        node->core.riscv.loadbuf, RISCV_LOADBUF_SIZE); // Don't start a request, as the node is busy with // responding to a load request. // By setting rank but not pos one_cycle() knows to  // start the request directly after the respond is finished. // Therefore it is guaranteed that a request does not // interrupt a response. // send a message and wait for the receive // else fallthrough: private access to own MPB