mirror of
https://github.com/fairwaves/UHD-Fairwaves.git
synced 2025-11-01 20:43:47 +00:00
Compare commits
3 Commits
1.0.4
...
fifo_ctrl_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b1348ee97 | ||
|
|
63e2ee1967 | ||
|
|
89394c9a58 |
@@ -22,7 +22,8 @@ module settings_fifo_ctrl
|
||||
parameter XPORT_HDR = 1, //extra transport hdr line
|
||||
parameter PROT_DEST = 0, //protocol framer destination
|
||||
parameter PROT_HDR = 1, //needs a protocol header?
|
||||
parameter ACK_SID = 0 //stream ID for packet ACK
|
||||
parameter ACK_SID = 0, //stream ID for packet ACK
|
||||
parameter DEPTH = 6 //size of fifo in addr bit width
|
||||
)
|
||||
(
|
||||
//clock and synchronous reset for all interfaces
|
||||
@@ -75,16 +76,17 @@ module settings_fifo_ctrl
|
||||
wire [63:0] in_command_ticks, out_command_ticks;
|
||||
wire [31:0] in_command_hdr, out_command_hdr;
|
||||
wire [31:0] in_command_data, out_command_data;
|
||||
wire in_command_has_time, out_command_has_time;
|
||||
wire command_fifo_full, command_fifo_empty;
|
||||
wire command_fifo_read, command_fifo_write;
|
||||
wire [15:0] command_fifo_occupied;
|
||||
|
||||
shortfifo #(.WIDTH(129)) command_fifo (
|
||||
longfifo #(.WIDTH(128), .SIZE(DEPTH)) command_fifo (
|
||||
.clk(clock), .rst(reset), .clear(clear),
|
||||
.datain({in_command_ticks, in_command_hdr, in_command_data, in_command_has_time}),
|
||||
.dataout({out_command_ticks, out_command_hdr, out_command_data, out_command_has_time}),
|
||||
.datain({in_command_ticks, in_command_hdr, in_command_data}),
|
||||
.dataout({out_command_ticks, out_command_hdr, out_command_data}),
|
||||
.write(command_fifo_write), .full(command_fifo_full), //input interface
|
||||
.empty(command_fifo_empty), .read(command_fifo_read) //output interface
|
||||
.empty(command_fifo_empty), .read(command_fifo_read), //output interface
|
||||
.occupied(command_fifo_occupied)
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@@ -95,13 +97,15 @@ module settings_fifo_ctrl
|
||||
wire [31:0] in_result_data, out_result_data;
|
||||
wire result_fifo_full, result_fifo_empty;
|
||||
wire result_fifo_read, result_fifo_write;
|
||||
wire [15:0] result_fifo_occupied;
|
||||
|
||||
shortfifo #(.WIDTH(64)) result_fifo (
|
||||
longfifo #(.WIDTH(64), .SIZE(DEPTH)) result_fifo (
|
||||
.clk(clock), .rst(reset), .clear(clear),
|
||||
.datain({in_result_hdr, in_result_data}),
|
||||
.dataout({out_result_hdr, out_result_data}),
|
||||
.write(result_fifo_write), .full(result_fifo_full), //input interface
|
||||
.empty(result_fifo_empty), .read(result_fifo_read) //output interface
|
||||
.empty(result_fifo_empty), .read(result_fifo_read), //output interface
|
||||
.occupied(result_fifo_occupied)
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@@ -139,7 +143,6 @@ module settings_fifo_ctrl
|
||||
assign in_command_ticks = in_ticks_reg;
|
||||
assign in_command_data = in_data_reg;
|
||||
assign in_command_hdr = in_hdr_reg;
|
||||
assign in_command_has_time = has_tsf_reg;
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
@@ -244,18 +247,24 @@ module settings_fifo_ctrl
|
||||
always @(posedge clock)
|
||||
vita_time_reg <= vita_time;
|
||||
|
||||
wire late;
|
||||
wire late, now;
|
||||
`ifndef FIFO_CTRL_NO_TIME
|
||||
time_compare time_compare(
|
||||
.time_now(vita_time_reg), .trigger_time(command_ticks_reg), .late(late));
|
||||
.time_now(vita_time_reg), .trigger_time(command_ticks_reg), .late(late), .now(now));
|
||||
`else
|
||||
assign late = 1;
|
||||
assign now = 1;
|
||||
`endif
|
||||
|
||||
//these config flags are available only in the LOAD_CMD state (where we wait)
|
||||
wire time_wait = out_command_hdr[9];
|
||||
wire skip_late = out_command_hdr[10]; //TODO (implement)
|
||||
reg cmd_was_late;
|
||||
|
||||
//action occurs in the event state and when there is fifo space (should always be true)
|
||||
//the third condition is that all peripherals in the perfs signal are ready/active high
|
||||
//the fourth condition is that is an event time has been set, action is delayed until that time
|
||||
wire time_ready = (out_command_has_time)? late : 1;
|
||||
wire time_ready = (time_wait)? (late || now) : 1;
|
||||
wire action = (cmd_state == EVENT_CMD) && ~result_fifo_full && perfs_ready && time_ready;
|
||||
|
||||
assign command_fifo_read = action;
|
||||
@@ -275,6 +284,7 @@ module settings_fifo_ctrl
|
||||
command_ticks_reg <= out_command_ticks;
|
||||
command_hdr_reg <= out_command_hdr;
|
||||
command_data_reg <= out_command_data;
|
||||
cmd_was_late <= late; //TODO do something with
|
||||
end
|
||||
|
||||
EVENT_CMD: begin // poking and peeking happens here!
|
||||
@@ -332,11 +342,14 @@ module settings_fifo_ctrl
|
||||
localparam WRITE_VRT_SID = 2;
|
||||
localparam WRITE_RB_HDR = 3;
|
||||
localparam WRITE_RB_DATA = 4;
|
||||
localparam WRITE_RB_DATA2 = 5;
|
||||
localparam WRITE_RB_DATA3 = 6;
|
||||
|
||||
//the state for the start of packet condition
|
||||
localparam WRITE_PKT_HDR = (PROT_HDR)? WRITE_PROT_HDR : WRITE_VRT_HDR;
|
||||
|
||||
reg [2:0] out_state;
|
||||
reg [31:0] last_result_hdr;
|
||||
|
||||
assign out_valid = ~result_fifo_empty;
|
||||
assign result_fifo_read = out_data[33] && writing;
|
||||
@@ -344,9 +357,11 @@ module settings_fifo_ctrl
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
out_state <= WRITE_PKT_HDR;
|
||||
last_result_hdr <= 32'b0;
|
||||
end
|
||||
else if (writing && out_data[33]) begin
|
||||
out_state <= WRITE_PKT_HDR;
|
||||
last_result_hdr <= out_result_hdr;
|
||||
end
|
||||
else if (writing) begin
|
||||
out_state <= out_state + 1;
|
||||
@@ -357,7 +372,7 @@ module settings_fifo_ctrl
|
||||
//-- assign to output fifo interface
|
||||
//------------------------------------------------------------------
|
||||
wire [31:0] prot_hdr;
|
||||
assign prot_hdr[15:0] = 16; //bytes in proceeding vita packet
|
||||
assign prot_hdr[15:0] = 24; //bytes in proceeding vita packet
|
||||
assign prot_hdr[16] = 1; //yes frame
|
||||
assign prot_hdr[18:17] = PROT_DEST;
|
||||
assign prot_hdr[31:19] = 0; //nothing
|
||||
@@ -370,12 +385,14 @@ module settings_fifo_ctrl
|
||||
WRITE_VRT_SID: out_data_int <= ACK_SID;
|
||||
WRITE_RB_HDR: out_data_int <= out_result_hdr;
|
||||
WRITE_RB_DATA: out_data_int <= out_result_data;
|
||||
WRITE_RB_DATA2: out_data_int <= last_result_hdr;
|
||||
WRITE_RB_DATA3: out_data_int <= {result_fifo_occupied, command_fifo_occupied};
|
||||
default: out_data_int <= 0;
|
||||
endcase //state
|
||||
end
|
||||
|
||||
assign out_data[35:34] = 2'b0;
|
||||
assign out_data[33] = (out_state == WRITE_RB_DATA);
|
||||
assign out_data[33] = (out_state == WRITE_RB_DATA3);
|
||||
assign out_data[32] = (out_state == WRITE_PKT_HDR);
|
||||
assign out_data[31:0] = out_data_int;
|
||||
|
||||
@@ -389,7 +406,7 @@ module settings_fifo_ctrl
|
||||
command_fifo_empty, command_fifo_full, //2
|
||||
command_fifo_read, command_fifo_write, //2
|
||||
addr, //8
|
||||
strobe_reg, strobe, poke, out_command_has_time //4
|
||||
strobe_reg, strobe, poke, time_wait //4
|
||||
};
|
||||
|
||||
endmodule //settings_fifo_ctrl
|
||||
|
||||
@@ -448,7 +448,7 @@ module umtrx_core
|
||||
// Buffer Pool Status -- Slave #5
|
||||
|
||||
//compatibility number -> increment when the fpga has been sufficiently altered
|
||||
localparam compat_num = {16'd9, 16'd1}; //major, minor
|
||||
localparam compat_num = {16'd9, 16'd2}; //major, minor
|
||||
|
||||
wire [31:0] irq_readback = {16'b0, aux_ld2, aux_ld1, button, spi_ready, 12'b0};
|
||||
|
||||
|
||||
@@ -29,11 +29,16 @@
|
||||
using namespace uhd;
|
||||
using namespace uhd::transport;
|
||||
|
||||
//command policy flags
|
||||
static const size_t POKE32_CMD = (1 << 8);
|
||||
static const size_t PEEK32_CMD = 0;
|
||||
static const size_t PEEK32_CMD = 0; //no flag set
|
||||
static const size_t TIME_WAIT_CMD = (1 << 9);
|
||||
static const size_t SKIP_LATE_CMD = (1 << 10);
|
||||
|
||||
static const double ACK_TIMEOUT = 0.5;
|
||||
static const double MASSIVE_TIMEOUT = 10.0; //for when we wait on a timed command
|
||||
static const boost::uint32_t MAX_SEQS_OUT = 15;
|
||||
static const boost::uint32_t FIFO_DEPTH = 64;
|
||||
static const boost::uint32_t MAX_SEQS_OUT = FIFO_DEPTH-1;
|
||||
|
||||
#define SPI_DIV SR_SPI_CORE + 0
|
||||
#define SPI_CTRL SR_SPI_CORE + 1
|
||||
@@ -50,6 +55,12 @@ public:
|
||||
_window_size(std::min(window_size, MAX_SEQS_OUT)),
|
||||
_seq_out(0),
|
||||
_seq_ack(0),
|
||||
_prev_recv_seq(0),
|
||||
_total_recv_packets(0),
|
||||
_start_of_burst(false),
|
||||
_skip_late(false),
|
||||
_use_time(false),
|
||||
_tick_rate(1.0),
|
||||
_timeout(ACK_TIMEOUT)
|
||||
{
|
||||
UHD_MSG(status) << "fifo_ctrl.window_size = " << _window_size << std::endl;
|
||||
@@ -155,6 +166,7 @@ public:
|
||||
_time = time;
|
||||
_use_time = _time != uhd::time_spec_t(0.0);
|
||||
if (_use_time) _timeout = MASSIVE_TIMEOUT; //permanently sets larger timeout
|
||||
_start_of_burst = true;
|
||||
}
|
||||
|
||||
void set_tick_rate(const double rate){
|
||||
@@ -162,6 +174,11 @@ public:
|
||||
_tick_rate = rate;
|
||||
}
|
||||
|
||||
void set_late_policy(const bool skip_late)
|
||||
{
|
||||
_skip_late = skip_late;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/*******************************************************************
|
||||
@@ -184,7 +201,8 @@ private:
|
||||
packet_info.packet_count = _seq_out;
|
||||
packet_info.sid = _sid;
|
||||
packet_info.tsf = _time.to_ticks(_tick_rate);
|
||||
packet_info.sob = false;
|
||||
packet_info.sob = _start_of_burst;
|
||||
_start_of_burst = false; //only set once by set time, then cleared
|
||||
packet_info.eob = false;
|
||||
packet_info.has_sid = true;
|
||||
packet_info.has_cid = false;
|
||||
@@ -195,6 +213,10 @@ private:
|
||||
//load header
|
||||
vrt::if_hdr_pack_be(pkt, packet_info);
|
||||
|
||||
//time command flags
|
||||
if (_skip_late) cmd |= SKIP_LATE_CMD;
|
||||
if (_use_time) cmd |= TIME_WAIT_CMD;
|
||||
|
||||
//load payload
|
||||
const boost::uint32_t ctrl_word = (addr & 0xff) | cmd | (_seq_out << 16);
|
||||
pkt[packet_info.num_header_words32+0] = htonl(ctrl_word);
|
||||
@@ -221,10 +243,50 @@ private:
|
||||
vrt::if_packet_info_t packet_info;
|
||||
packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
|
||||
vrt::if_hdr_unpack_be(pkt, packet_info);
|
||||
_seq_ack = ntohl(pkt[packet_info.num_header_words32+0]) >> 16;
|
||||
if (_seq_ack == seq_to_ack){
|
||||
return ntohl(pkt[packet_info.num_header_words32+1]);
|
||||
|
||||
//extract the payloads
|
||||
const boost::int32_t header = ntohl(pkt[packet_info.num_header_words32+0]);
|
||||
const boost::int32_t rb_data = ntohl(pkt[packet_info.num_header_words32+1]);
|
||||
const boost::int32_t last_header = ntohl(pkt[packet_info.num_header_words32+2]);
|
||||
const boost::int32_t fifo_occupied = ntohl(pkt[packet_info.num_header_words32+3]);
|
||||
const boost::uint16_t this_seq = header >> 16;
|
||||
const boost::uint16_t last_seq = last_header >> 16;
|
||||
const boost::uint16_t result_fifo_occupied = fifo_occupied >> 16;
|
||||
const boost::uint16_t command_fifo_occupied = fifo_occupied & 0xffff;
|
||||
|
||||
//check if we lost packets from device -> host
|
||||
const boost::uint16_t next_recv_seq = _prev_recv_seq+1;
|
||||
if (next_recv_seq != this_seq)
|
||||
{
|
||||
UHD_MSG(error) << boost::format(
|
||||
"Detected packet loss from device to host:\n"
|
||||
"Host expected sequence 0x%x, but got 0x%x"
|
||||
) % next_recv_seq % this_seq << std::endl;
|
||||
}
|
||||
|
||||
//check if we lost packets from host -> device
|
||||
if (_total_recv_packets != 0 and _prev_recv_seq != last_seq)
|
||||
{
|
||||
UHD_MSG(error) << boost::format(
|
||||
"Detected packet loss from host to device:\n"
|
||||
"Device expected last sequence 0x%x, but saw 0x%x"
|
||||
) % _prev_recv_seq % last_seq << std::endl;
|
||||
}
|
||||
|
||||
if (result_fifo_occupied > FIFO_DEPTH/2 or command_fifo_occupied > FIFO_DEPTH/2)
|
||||
{
|
||||
UHD_MSG(warning) << boost::format(
|
||||
"FIFOs are past half capacity!\n"
|
||||
"Command FIFO occupancy: %d/%d\n"
|
||||
"Result FIFO occupancy: %d/%d"
|
||||
) % command_fifo_occupied % FIFO_DEPTH % result_fifo_occupied % FIFO_DEPTH << std::endl;
|
||||
}
|
||||
|
||||
//store state for next recv iteration
|
||||
_total_recv_packets++;
|
||||
_prev_recv_seq = this_seq;
|
||||
_seq_ack = this_seq;
|
||||
if (_seq_ack == seq_to_ack) return rb_data;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -236,7 +298,12 @@ private:
|
||||
boost::mutex _mutex;
|
||||
boost::uint16_t _seq_out;
|
||||
boost::uint16_t _seq_ack;
|
||||
boost::uint16_t _prev_recv_seq;
|
||||
boost::uint16_t _next_recv_seq;
|
||||
boost::uint64_t _total_recv_packets;
|
||||
uhd::time_spec_t _time;
|
||||
bool _start_of_burst;
|
||||
bool _skip_late;
|
||||
bool _use_time;
|
||||
double _tick_rate;
|
||||
double _timeout;
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user