Skip to content

Commit

Permalink
Timestamp offset (#25)
Browse files Browse the repository at this point in the history
* Make timestamp offset configurable
  • Loading branch information
hsadok authored Aug 30, 2024
1 parent 89d3287 commit bee5ab0
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 28 deletions.
4 changes: 2 additions & 2 deletions hardware/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ declare -a tests=(
# 'test_cpu_to_fpga'
# 'test_queue_manager'
# 'test_prefetch_rb'
# 'test_timestamp'
'test_rate_limiter'
'test_timestamp'
# 'test_rate_limiter'
# 'sketch'
)

Expand Down
1 change: 1 addition & 0 deletions hardware/src/constants.sv
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ typedef struct packed {

typedef struct packed {
logic [319:0] pad1;
logic [63:0] offset;
logic enable; // Set to 1 to enable timestamping.
logic [62:0] pad2;
logic [63:0] config_id;
Expand Down
16 changes: 10 additions & 6 deletions hardware/src/timestamp.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
/// (in number of cycles). Must be explicitly enabled using the configuration
/// interface. Otherwise this module does nothing.
module timestamp #(
parameter TIMESTAMP_WIDTH=32,
parameter TIMESTAMP_OFFSET=(112+32) // Bytes 4--7 of IPv4 header.
parameter TIMESTAMP_WIDTH=32
)(
input logic clk,
input logic rst,
Expand Down Expand Up @@ -49,12 +48,16 @@ module timestamp #(
output logic conf_ts_ready
);

localparam REVERSED_OFFSET = 512 - TIMESTAMP_OFFSET - TIMESTAMP_WIDTH;

logic [8:0] offset;
logic [8:0] reversed_offset;

logic [TIMESTAMP_WIDTH-1:0] timestamp_counter;
logic [TIMESTAMP_WIDTH-1:0] rtt;
logic timestamp_enabled;

assign reversed_offset = 512 - TIMESTAMP_WIDTH - offset * 8;

always @(posedge clk) begin
if (rst) begin
timestamp_counter <= 0;
Expand All @@ -64,6 +67,7 @@ always @(posedge clk) begin

if (conf_ts_valid) begin
timestamp_enabled <= conf_ts_data.enable;
offset <= conf_ts_data.offset;
$display("Enable timestamp");
end
end
Expand All @@ -89,18 +93,18 @@ always_comb begin
tx_in_pkt_ready = tx_out_pkt_ready;

rtt = timestamp_counter -
rx_in_pkt_data[REVERSED_OFFSET +: TIMESTAMP_WIDTH];
rx_in_pkt_data[reversed_offset +: TIMESTAMP_WIDTH];

if (timestamp_enabled) begin
// Timestamp TX packets.
if (tx_in_pkt_sop) begin
tx_out_pkt_data[REVERSED_OFFSET +: TIMESTAMP_WIDTH]
tx_out_pkt_data[reversed_offset +: TIMESTAMP_WIDTH]
= timestamp_counter;
end

// Write RTT to RX packets.
if (rx_in_pkt_sop) begin
rx_out_pkt_data[REVERSED_OFFSET +: TIMESTAMP_WIDTH] = rtt;
rx_out_pkt_data[reversed_offset +: TIMESTAMP_WIDTH] = rtt;
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions hardware/tests/test_timestamp.sv
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ always @(posedge clk) begin
automatic timestamp_config_t configuration = 0;
configuration.enable = 1;
configuration.config_id = TIMESTAMP_CONFIG_ID;
configuration.offset = TIMESTAMP_OFFSET / 8;
conf_ts_data <= configuration;
conf_ts_valid <= 1;
end else if (cnt == 20) begin
Expand Down Expand Up @@ -172,8 +173,7 @@ hyper_pipe #(
);

timestamp #(
.TIMESTAMP_WIDTH(TIMESTAMP_WIDTH),
.TIMESTAMP_OFFSET(TIMESTAMP_OFFSET)
.TIMESTAMP_WIDTH(TIMESTAMP_WIDTH)
) timestamp_inst (
.clk (clk),
.rst (rst),
Expand Down
30 changes: 25 additions & 5 deletions software/examples/ensogen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ static void print_usage(const char* program_name) {
" [--rtt-hist-offset HIST_OFFSET]\n"
" [--rtt-hist-len HIST_LEN]\n"
" [--stats-delay STATS_DELAY]\n"
" [--pcie-addr PCIE_ADDR]\n\n"
" [--pcie-addr PCIE_ADDR]\n"
" [--timestamp-offset]\n\n"

" PCAP_FILE: Pcap file with packets to transmit.\n"
" RATE_NUM: Numerator of the rate used to transmit packets.\n"
Expand All @@ -150,9 +151,11 @@ static void print_usage(const char* program_name) {
" performance penalty.\n"
" --stats-delay: Delay between displayed stats in milliseconds\n"
" (default: %d).\n"
" --pcie-addr: Specify the PCIe address of the NIC to use.\n",
" --pcie-addr: Specify the PCIe address of the NIC to use.\n"
" --timestamp-offset: Specify the packet offset to place the timestamp\n"
" on (default: %d).\n",
program_name, DEFAULT_CORE_ID, DEFAULT_NB_QUEUES, DEFAULT_HIST_OFFSET,
DEFAULT_HIST_LEN, DEFAULT_STATS_DELAY);
DEFAULT_HIST_LEN, DEFAULT_STATS_DELAY, enso::kDefaultRttOffset);
}

#define CMD_OPT_HELP "help"
Expand All @@ -167,6 +170,7 @@ static void print_usage(const char* program_name) {
#define CMD_OPT_RTT_HIST_LEN "rtt-hist-len"
#define CMD_OPT_STATS_DELAY "stats-delay"
#define CMD_OPT_PCIE_ADDR "pcie-addr"
#define CMD_OPT_TIMESTAMP_OFFSET "timestamp-offset"

// Map long options to short options.
enum {
Expand All @@ -182,6 +186,7 @@ enum {
CMD_OPT_RTT_HIST_LEN_NUM,
CMD_OPT_STATS_DELAY_NUM,
CMD_OPT_PCIE_ADDR_NUM,
CMD_OPT_TIMESTAMP_OFFSET_NUM
};

static const char short_options[] = "";
Expand All @@ -199,6 +204,8 @@ static const struct option long_options[] = {
{CMD_OPT_RTT_HIST_LEN, required_argument, NULL, CMD_OPT_RTT_HIST_LEN_NUM},
{CMD_OPT_STATS_DELAY, required_argument, NULL, CMD_OPT_STATS_DELAY_NUM},
{CMD_OPT_PCIE_ADDR, required_argument, NULL, CMD_OPT_PCIE_ADDR_NUM},
{CMD_OPT_TIMESTAMP_OFFSET, required_argument, NULL,
CMD_OPT_TIMESTAMP_OFFSET_NUM},
{0, 0, 0, 0}};

struct parsed_args_t {
Expand All @@ -218,6 +225,7 @@ struct parsed_args_t {
uint32_t rtt_hist_len;
uint32_t stats_delay;
std::string pcie_addr;
uint8_t timestamp_offset;
};

static int parse_args(int argc, char** argv,
Expand All @@ -235,6 +243,7 @@ static int parse_args(int argc, char** argv,
parsed_args.rtt_hist_offset = DEFAULT_HIST_OFFSET;
parsed_args.rtt_hist_len = DEFAULT_HIST_LEN;
parsed_args.stats_delay = DEFAULT_STATS_DELAY;
parsed_args.timestamp_offset = enso::kDefaultRttOffset;

while ((opt = getopt_long(argc, argv, short_options, long_options,
&long_index)) != EOF) {
Expand Down Expand Up @@ -276,6 +285,15 @@ static int parse_args(int argc, char** argv,
case CMD_OPT_PCIE_ADDR_NUM:
parsed_args.pcie_addr = optarg;
break;
case CMD_OPT_TIMESTAMP_OFFSET_NUM: {
int timestamp_offset = atoi(optarg);
if (timestamp_offset < 0 || timestamp_offset > 60) {
std::cerr << "Invalid timestamp offset" << std::endl;
return -1;
}
parsed_args.timestamp_offset = (uint8_t)timestamp_offset;
break;
}
default:
return -1;
}
Expand Down Expand Up @@ -448,6 +466,7 @@ struct RxArgs {
bool enable_rtt;
bool enable_rtt_history;
int socket_fd;
uint8_t timestamp_offset;
};

struct TxStats {
Expand Down Expand Up @@ -550,7 +569,7 @@ inline uint64_t receive_pkts(const struct RxArgs& rx_args,
uint16_t pkt_aligned_len = nb_flits * 64;

if (rx_args.enable_rtt) {
uint32_t rtt = enso::get_pkt_rtt(pkt);
uint32_t rtt = enso::get_pkt_rtt(pkt, rx_args.timestamp_offset);
rx_stats.rtt_sum += rtt;

if (rx_args.enable_rtt_history) {
Expand Down Expand Up @@ -784,14 +803,15 @@ int main(int argc, char** argv) {
enso::enable_device_round_robin(socket_fd);

if (parsed_args.enable_rtt) {
enso::enable_device_timestamp(socket_fd);
enso::enable_device_timestamp(socket_fd, parsed_args.timestamp_offset);
} else {
enso::disable_device_timestamp(socket_fd);
}

RxArgs rx_args;
rx_args.enable_rtt = parsed_args.enable_rtt;
rx_args.enable_rtt_history = parsed_args.enable_rtt_history;
rx_args.timestamp_offset = parsed_args.timestamp_offset;
rx_args.socket_fd = socket_fd;

std::cout << "Running RX on core " << sched_getcpu() << std::endl;
Expand Down
6 changes: 5 additions & 1 deletion software/include/enso/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#ifndef SOFTWARE_INCLUDE_ENSO_CONFIG_H_
#define SOFTWARE_INCLUDE_ENSO_CONFIG_H_

#include <enso/consts.h>
#include <enso/internals.h>

namespace enso {
Expand Down Expand Up @@ -73,9 +74,12 @@ int insert_flow_entry(struct NotificationBufPair* notification_buf_pair,
*
* @param notification_buf_pair Notification buffer to send configuration
* through.
* @param offset Packet offset to place the timestamp, default is
* `kDefaultRttOffset` bytes.
* @return 0 if configuration was successful, -1 otherwise.
*/
int enable_timestamp(struct NotificationBufPair* notification_buf_pair);
int enable_timestamp(struct NotificationBufPair* notification_buf_pair,
uint8_t offset = kDefaultRttOffset);

/**
* @brief Disables hardware timestamping.
Expand Down
5 changes: 3 additions & 2 deletions software/include/enso/consts.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ constexpr uint32_t kAlignedDscBufPairSize =
constexpr uint32_t kNsPerTimestampCycle = 5;

/**
* @brief Offset of the RTT when timestamp is enabled (in bytes).
* @brief Default timestamp offset of the RTT when timestamp is enabled (in
* bytes). Uses bytes 4--7 of IPv4 header.
*/
constexpr uint32_t kPacketRttOffset = 18;
constexpr uint8_t kDefaultRttOffset = 18;

/**
* @brief Maximum number of flits (64 byte chunks) that the hardware can send
Expand Down
6 changes: 4 additions & 2 deletions software/include/enso/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@ struct alignas(kCacheLineSize) stats_t {
* To convert from number of cycles to ns. Do `cycles * kNsPerTimestampCycle`.
*
* @param pkt Packet to retrieve the RTT from.
* @param rtt_offset Offset in bytes where the RTT is stored.
* @return Return RTT measure for the packet in number of cycles. If timestamp
* is not enabled on the NIC, the value returned is undefined.
*/
inline uint32_t get_pkt_rtt(const uint8_t* pkt) {
uint32_t rtt = *((uint32_t*)(pkt + kPacketRttOffset));
inline uint32_t get_pkt_rtt(
const uint8_t* pkt, const uint8_t rtt_offset = kDefaultRttOffset) {
uint32_t rtt = *((uint32_t*)(pkt + rtt_offset));
return be32toh(rtt);
}

Expand Down
7 changes: 6 additions & 1 deletion software/include/enso/pipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,21 @@ class Device {
*
* @note This setting applies to all pipes that share the same hardware
* device.
*
* @see DisableTimeStamping
* @see get_pkt_rtt
*
* @param offset Packet offset to place the timestamp, default is
* `kDefaultRttOffset` bytes.
*/
int EnableTimeStamping();
int EnableTimeStamping(uint8_t offset = kDefaultRttOffset);

/**
* @brief Disables hardware time stamping.
*
* @note This setting applies to all pipes that share the same hardware
* device.
*
* @see EnableTimeStamping
*/
int DisableTimeStamping();
Expand Down
3 changes: 2 additions & 1 deletion software/include/enso/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#define SOFTWARE_INCLUDE_ENSO_SOCKET_H_

#include <arpa/inet.h>
#include <enso/consts.h>
#include <linux/types.h>

namespace enso {
Expand Down Expand Up @@ -104,7 +105,7 @@ uint32_t get_completions(int ref_sockfd);
/*
* Enable hardware timestamping for the device. This applies to all sockets.
*/
int enable_device_timestamp(int ref_sockfd);
int enable_device_timestamp(int ref_sockfd, uint8_t offset = kDefaultRttOffset);

/*
* Disable hardware timestamping for the device. This applies to all sockets.
Expand Down
11 changes: 9 additions & 2 deletions software/src/enso/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ struct __attribute__((__packed__)) TimestampConfig {
uint64_t signal;
uint64_t config_id;
uint64_t enable;
uint8_t pad[40];
uint64_t offset;
uint8_t pad[32];
};

struct __attribute__((__packed__)) RateLimitConfig {
Expand Down Expand Up @@ -119,12 +120,18 @@ int insert_flow_entry(struct NotificationBufPair* notification_buf_pair,
return send_config(notification_buf_pair, (struct TxNotification*)&config);
}

int enable_timestamp(struct NotificationBufPair* notification_buf_pair) {
int enable_timestamp(struct NotificationBufPair* notification_buf_pair,
uint8_t offset) {
if (offset > 60) {
return -1;
}

TimestampConfig config;

config.signal = 2;
config.config_id = TIMESTAMP_CONFIG_ID;
config.enable = -1;
config.offset = offset;

return send_config(notification_buf_pair, (struct TxNotification*)&config);
}
Expand Down
4 changes: 2 additions & 2 deletions software/src/enso/pipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,8 @@ void Device::ProcessCompletions() {
}
}

int Device::EnableTimeStamping() {
return enable_timestamp(&notification_buf_pair_);
int Device::EnableTimeStamping(uint8_t offset) {
return enable_timestamp(&notification_buf_pair_, offset);
}

int Device::DisableTimeStamping() {
Expand Down
5 changes: 3 additions & 2 deletions software/src/enso/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,12 @@ void free_enso_pipe(int sockfd, size_t len) {
advance_pipe(&(open_sockets[sockfd].enso_pipe), len);
}

int enable_device_timestamp(int ref_sockfd) {
int enable_device_timestamp(int ref_sockfd, uint8_t offset) {
if (nb_open_sockets == 0) {
return -2;
}
return enable_timestamp(open_sockets[ref_sockfd].notification_buf_pair);
return enable_timestamp(open_sockets[ref_sockfd].notification_buf_pair,
offset);
}

int disable_device_timestamp(int ref_sockfd) {
Expand Down

0 comments on commit bee5ab0

Please sign in to comment.