diff --git a/README.md b/README.md index ea7de569576fe94857bdfa92ebdbf76ec53d4a8a..c003e0ff5d8b3e080e9acb4a2817059c331b58d8 100644 --- a/README.md +++ b/README.md @@ -774,7 +774,7 @@ $ git checkout SCALP-USER-v0.5.1 **For the design with the NoC Scalp :** ``` -$ git checkout SCALP-ROUTER-v0.1 +$ git checkout SCALP_ROUTER_SLOW-v0.2 ``` **If you have not gone through the scalp\_safe\_petalinux firmware creation section, please go to section [Copy Scalp board files](#copy-scalp-board-files).** @@ -821,7 +821,7 @@ $ git checkout SCALP-USER-v0.5.1 **For the design with the NoC Scalp :** ``` -$ git checkout SCALP-ROUTER-v0.1 +$ git checkout SCALP_ROUTER_SLOW-v0.2 ``` ### Create a new Scalp User Petalinux project from a BSP @@ -1628,3 +1628,167 @@ $ petalinux-package --bsp -p /home/jo/Documents/Projets/Hepia/scalp_project/scal }; }; ``` + +### Scalp library header + +```cpp +#ifndef __SCALP_HH__ +#define __SCALP_HH__ + +#include <cstdint> +#include <cstddef> +#include <atomic> + +#define SCALP_ROUTER_UIO_DEV "/dev/uio0" +#define SCALP_ROUTER_MMAP_SIZE 0x1000 +#define SCALP_HDR_SIZE 3 +#define SCALP_MAX_SP_SIZE 64 +#define SCALP_TX_FIFO_SIZE 1024 + +using namespace std; + +namespace libscalp +{ + struct scalp_noc_regs + { + public : + std::atomic<uint32_t> wr_data; + std::atomic<uint32_t> rd_data; + // Same register, but different access + std::atomic<uint32_t> ctrl; + std::atomic<uint32_t> set_ctrl; + std::atomic<uint32_t> clr_ctrl; + // + std::atomic<uint32_t> status; + std::atomic<uint32_t> txwr_datacnt; + std::atomic<uint32_t> txrd_datacnt; + std::atomic<uint32_t> rxwr_datacnt; + std::atomic<uint32_t> rxrd_datacnt; + std::atomic<uint32_t> loc_netaddr; + }; + + enum ctrl_reg_fields + { + E_WR_VALID = 0x1, + E_WR_LAST = 0x2, + E_WR_READY = 0x4, + E_WR_NEXT = 0x8, + E_RESET_ALL_FIFO = 0x10, + E_WR_H0 = 0x20, + E_WR_H1 = 0x40, + E_WR_H2 = 0x80, + E_WR_PLD = 0x100, + E_WR_NEW_PACKET = 0x200, + E_RD_NEXT = 0x400, + E_RD_NEW_PACKET = 0x800 + }; + + enum status_reg_fields + { + E_RD_VALID = 0x1, + E_RD_LAST = 0x2, + E_TX_PROG_FULL = 0x4, + E_RX_PROG_FULL = 0x8, + E_RD_WAIT_NEXT = 0x10 + }; + + class uio + { + private : + int32_t _uiofd; + + public : + explicit uio(const char * dev); + ~uio(); + void unmask_interrupt(); + void wait_interrupt(uint32_t timeout_ms); + friend class uio_mmap; + }; + + class uio_mmap + { + private : + size_t _size; + void * _ptr; + + public : + uio_mmap(const uio &u, uint32_t index, size_t size); + uio_mmap(uio *u, uint32_t index, size_t size); + ~uio_mmap(); + size_t size() const { return _size; } + void *get_ptr() const { return _ptr; } + }; + + void * scalp_noc_init (const char *dev, void **devuio, void **mmap_regs); + bool scalp_noc_set_locaddr (void *regs, uint32_t x, uint32_t y, uint32_t z); + uint32_t scalp_noc_get_locaddr (void *regs); + void scalp_noc_free (void *devuio, void *mmap_regs); + bool scalp_noc_data_is_valid (void *regs, bool new_packet); + uint32_t scalp_noc_read_data (void *regs, bool *is_last, bool new_packet, bool *nodata); + uint32_t scalp_noc_read_packet (void *regs, uint32_t *scalp_packet, bool blocking); + bool scalp_noc_ready_for_data(void *regs, bool new_packet); + bool scalp_noc_write_data (void *regs, uint32_t data, bool is_last, bool new_packet); + bool scalp_noc_write_packet (void *regs, uint32_t *scalp_packet, uint32_t size); + uint32_t scalp_noc_create_packet (void *regs, uint32_t x, uint32_t y, uint32_t z, uint32_t *payload, uint32_t payload_size, uint32_t *packet); +}; + +extern "C" +{ + void * sn_init(const char *dev, void **devuio, void **mmap_regs) + { + return libscalp::scalp_noc_init(dev, devuio, mmap_regs); + } + + uint32_t sn_set_locaddr(void *regs, uint32_t x, uint32_t y, uint32_t z) + { + return (uint32_t)(libscalp::scalp_noc_set_locaddr(regs, x, y, z)); + } + + uint32_t sn_get_locaddr(void *regs) + { + return libscalp::scalp_noc_get_locaddr(regs); + } + + void sn_free(void *devuio, void *mmap_regs) + { + return libscalp::scalp_noc_free(devuio, mmap_regs); + } + + uint32_t sn_data_is_valid(void *regs, bool new_packet) + { + return (uint32_t)(libscalp::scalp_noc_data_is_valid(regs, new_packet)); + } + + uint32_t sn_read_data(void *regs, bool *is_last, bool new_packet, bool *nodata) + { + return libscalp::scalp_noc_read_data(regs, is_last, new_packet, nodata); + } + + uint32_t sn_read_packet(void *regs, uint32_t *scalp_packet, bool blocking) + { + return libscalp::scalp_noc_read_packet(regs, scalp_packet, blocking); + } + + uint32_t sn_ready_for_data(void *regs, bool new_packet) + { + return (uint32_t)(libscalp::scalp_noc_ready_for_data(regs, new_packet)); + } + + uint32_t sn_write_data(void *regs, uint32_t data, bool is_last, bool new_packet) + { + return (uint32_t)(libscalp::scalp_noc_write_data(regs, data, is_last, new_packet)); + } + + uint32_t sn_write_packet(void *regs, uint32_t *scalp_packet, uint32_t size) + { + return (uint32_t)(libscalp::scalp_noc_write_packet(regs, scalp_packet, size)); + } + + uint32_t sn_create_packet(void *regs, uint32_t x, uint32_t y, uint32_t z, uint32_t *payload, uint32_t payload_size, uint32_t *packet) + { + return (uint32_t)(libscalp::scalp_noc_create_packet(regs, x, y , z, payload, payload_size, packet)); + } +} + +#endif +```