Files
Jungfraujoch/fpga/hls/data_collection_fsm.cpp
2024-07-06 09:34:44 +02:00

147 lines
4.9 KiB
C++

// Copyright (2019-2023) Paul Scherrer Institute
#include "hls_jfjoch.h"
void data_collection_fsm(AXI_STREAM &eth_in,
STREAM_512 &data_out,
hls::stream<axis_addr> &addr_in,
hls::stream<axis_addr> &addr_out,
volatile ap_uint<1> &in_run,
volatile ap_uint<1> &in_cancel,
volatile ap_uint<1> &out_idle,
ap_uint<32> mode,
ap_uint<32> energy_kev,
ap_uint<32> nframes,
ap_uint<5> nmodules,
ap_uint<4> nstorage_cells,
ap_uint<8> nsummation,
ap_uint<8> sqrtmult,
volatile rcv_state_t &data_collection_state) {
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE axis register both port=eth_in
#pragma HLS INTERFACE axis register both port=data_out
#pragma HLS INTERFACE axis register both port=addr_in
#pragma HLS INTERFACE axis register both port=addr_out
#pragma HLS INTERFACE ap_none register port=in_run
#pragma HLS INTERFACE ap_none register port=in_cancel
#pragma HLS INTERFACE ap_none register port=out_idle
#pragma HLS INTERFACE ap_none register port=mode
#pragma HLS INTERFACE ap_none register port=energy_kev
#pragma HLS INTERFACE ap_none register port=nframes
#pragma HLS INTERFACE ap_none register port=nmodules
#pragma HLS INTERFACE ap_none register port=nstorage_cells
#pragma HLS INTERFACE ap_none register port=nsummation
#pragma HLS INTERFACE ap_none register port=sqrtmult
#pragma HLS INTERFACE ap_none register port=data_collection_state
#pragma HLS PIPELINE II=1 style=flp
packet_512_t packet_in;
packet_512_t packet_out;
axis_addr addr;
static rcv_state_t rcv_state = RCV_WAIT_FOR_START;
#pragma HLS RESET variable=rcv_state
switch (rcv_state) {
case RCV_WAIT_FOR_START:
if (in_run.read() == 1) {
rcv_state = RCV_WAIT_FOR_START_LOW;
out_idle = 0;
} else if (!addr_in.empty()) {
addr_in.read();
rcv_state = RCV_FLUSH_IDLE;
out_idle = 1;
} else
out_idle = 1;
break;
case RCV_FLUSH_IDLE:
eth_in >> packet_in;
if (packet_in.last) {
out_idle = 1;
rcv_state = RCV_WAIT_FOR_START;
}
break;
case RCV_WAIT_FOR_START_LOW:
out_idle = 0;
if (in_run.read() == 0)
rcv_state = RCV_START;
break;
case RCV_START:
out_idle = 0;
packet_out.data = 0;
ACT_REG_MODE(packet_out.data) = mode;
ACT_REG_ENERGY_KEV_FLOAT(packet_out.data) = energy_kev;
ACT_REG_NFRAMES(packet_out.data) = nframes;
ACT_REG_NMODULES(packet_out.data) = nmodules;
ACT_REG_NSTORAGE_CELLS(packet_out.data) = nstorage_cells + 1;
ACT_REG_NSUMMATION(packet_out.data) = nsummation;
ACT_REG_SQRTMULT(packet_out.data) = sqrtmult;
packet_out.user = 0;
packet_out.last = 1;
packet_out.dest = 0;
packet_out.id = 1;
data_out << packet_out;
rcv_state = RCV_INIT;
break;
case RCV_INIT:
out_idle = 0;
if (in_cancel.read() == 1)
rcv_state = RCV_LAST;
else if (!addr_in.empty()) {
addr_in >> addr;
if (addr.frame_number >= nframes - 1 + DELAY_FRAMES_STOP_AND_QUIT)
rcv_state = RCV_FLUSH;
else {
addr_out << addr;
rcv_state = RCV_GOOD;
}
}
break;
case RCV_GOOD:
out_idle = 0;
eth_in >> packet_in;
packet_in.user = 0;
packet_in.id = 0;
data_out << packet_in;
if (packet_in.last)
rcv_state = RCV_INIT;
break;
case RCV_IGNORE:
out_idle = 0;
eth_in >> packet_in;
if (packet_in.last)
rcv_state = RCV_INIT;
break;
case RCV_FLUSH:
out_idle = 0;
eth_in >> packet_in;
if (packet_in.last)
rcv_state = RCV_LAST;
break;
case RCV_LAST:
out_idle = 0;
addr.last = 1;
addr_out << addr;
// Finish data collection
packet_out.data = 0;
packet_out.dest = 0;
packet_out.id = 1; // Special packet
packet_out.last = 1;
packet_out.user = 1;
data_out << packet_out;
rcv_state = RCV_WAIT_FOR_START;
break;
}
data_collection_state = rcv_state;
}