Commit 5d3708ac authored by Bartosz Podrygajlo's avatar Bartosz Podrygajlo

Realtime channel emulation for shm_radio

parent 4b61f140
add_library(actor actor.c)
target_include_directories(actor PUBLIC ./)
target_link_libraries(actor PUBLIC thread-pool)
# Only include header files due to issues with ODR in threadPool binaries
target_include_directories(actor PUBLIC ./ ../threadPool/)
if (ENABLE_TESTS)
add_subdirectory(tests)
endif()
......@@ -50,6 +50,7 @@ typedef enum {
#define CHANMODEL_FREE_RSQRT_6 1<<1
#define CHANMODEL_FREE_RSQRT_NTAPS 1<<2
#define CHANMODEL_FREE_AMPS 1<<3
#define SHR3 (jz = jsr, jsr ^= (jsr << 13), jsr ^= (jsr >> 17), jsr ^= (jsr << 5), jz + jsr)
typedef enum {
CORR_LEVEL_LOW,
......
add_library(shm_radio MODULE shm_radio.c)
add_library(shm_radio MODULE shm_radio.c noise_device.c)
set_target_properties(shm_radio PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
target_link_libraries(shm_radio PRIVATE shm_td_iq_channel)
target_link_libraries(shm_radio PRIVATE SIMU shm_td_iq_channel actor)
add_dependencies(shm_radio generate_T)
......@@ -2,13 +2,14 @@
This implements a shared memory realtime and near-realtime radio interface.
This is performed using `shm_td_iq_channel` which handles the shared memory
interface.
interface.
# Limitations
- Only 1gNB to 1nrUE
- Only 1rx and 1tx antennas
- No channel modelling
- Only 1gNB to 1nrUE: gNB as a server, UE as a client.
- Server only accepts connections during device bringup. This means that
restarting the client will not make it reconnect, the server has to be
restarted as well.
# Usage
......@@ -17,3 +18,8 @@ On the UE and gNB: use `device.name shm_radio` command line argument.
Additionally on gNB use `shm_radio.role server` and optionally
`shm_radio.timescale <timescale>` to set the timescale. Timescale 1.0
is the default and means realtime.
Channel modelling can be enabled by adding `shm_radio.chanmod 1` to the
command line and should work the same as channel modelling in rfsimulator,
see rfsimulator [documentation](../rfsimulator/README.md), provided that your
CPU is fast enough.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <pthread.h>
#include <errno.h>
#include "noise_device.h"
// Use block size equal to cache size
#define BLOCK_SIZE (64 / sizeof(float)) // 4 bytes per float
// Use a power of 2 for block size length
#define NUM_BLOCKS (8192)
#define NOISE_VECTOR_LENGTH (BLOCK_SIZE * NUM_BLOCKS)
static struct {
pthread_t noise_device_thread;
float noise[NOISE_VECTOR_LENGTH] __attribute__((aligned(64)));
float noise_power;
bool running;
} state;
static uint32_t jz, jsr = 123456789;
static uint32_t random_uint(void)
{
return SHR3;
}
static void generate_one_block_noise(int write_block_index, float noise_power)
{
// Generate noise vector
float block[BLOCK_SIZE];
for (int i = 0; i < BLOCK_SIZE; i++) {
block[i] = noise_power * gaussZiggurat(0, 1);
}
// Write block to noise vector
memcpy(state.noise + write_block_index * BLOCK_SIZE, block, sizeof(block));
}
void *noise_device_thread_function(void *arg)
{
while (state.running) {
// Generate noise vector
generate_one_block_noise(random_uint() % NUM_BLOCKS, state.noise_power);
usleep(10000);
}
return NULL;
}
void init_noise_device(float noise_power)
{
for (int i = 0; i < NUM_BLOCKS; i++) {
generate_one_block_noise(i, noise_power);
}
int ret = pthread_create(&state.noise_device_thread, NULL, noise_device_thread_function, NULL);
AssertFatal(ret == 0, "pthread_create failed: %d, errno %d (%s)\n", ret, errno, strerror(errno));
}
void free_noise_device(void)
{
state.running = false;
pthread_join(state.noise_device_thread, NULL);
}
void get_noise_vector(float *noise_vector, int length)
{
int start_block = random_uint() % NUM_BLOCKS;
while (length > 0) {
int copy_size = min(length, (NUM_BLOCKS - start_block) * BLOCK_SIZE);
memcpy(noise_vector, &state.noise[start_block * BLOCK_SIZE], copy_size * sizeof(float));
start_block = 0;
length -= copy_size;
noise_vector += copy_size;
}
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef NOISE_DEVICE_H
#define NOISE_DEVICE_H
#include "SIMULATION/TOOLS/sim.h"
void init_noise_device(float noise_power);
void free_noise_device(void);
void get_noise_vector(float *noise_vector, int length);
#endif
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment