mirror of
https://github.com/fairwaves/UHD-Fairwaves.git
synced 2025-11-04 14:03:19 +00:00
Compare commits
3 Commits
fpga_wip
...
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 XPORT_HDR = 1, //extra transport hdr line
|
||||||
parameter PROT_DEST = 0, //protocol framer destination
|
parameter PROT_DEST = 0, //protocol framer destination
|
||||||
parameter PROT_HDR = 1, //needs a protocol header?
|
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
|
//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 [63:0] in_command_ticks, out_command_ticks;
|
||||||
wire [31:0] in_command_hdr, out_command_hdr;
|
wire [31:0] in_command_hdr, out_command_hdr;
|
||||||
wire [31:0] in_command_data, out_command_data;
|
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_full, command_fifo_empty;
|
||||||
wire command_fifo_read, command_fifo_write;
|
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),
|
.clk(clock), .rst(reset), .clear(clear),
|
||||||
.datain({in_command_ticks, in_command_hdr, in_command_data, in_command_has_time}),
|
.datain({in_command_ticks, in_command_hdr, in_command_data}),
|
||||||
.dataout({out_command_ticks, out_command_hdr, out_command_data, out_command_has_time}),
|
.dataout({out_command_ticks, out_command_hdr, out_command_data}),
|
||||||
.write(command_fifo_write), .full(command_fifo_full), //input interface
|
.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 [31:0] in_result_data, out_result_data;
|
||||||
wire result_fifo_full, result_fifo_empty;
|
wire result_fifo_full, result_fifo_empty;
|
||||||
wire result_fifo_read, result_fifo_write;
|
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),
|
.clk(clock), .rst(reset), .clear(clear),
|
||||||
.datain({in_result_hdr, in_result_data}),
|
.datain({in_result_hdr, in_result_data}),
|
||||||
.dataout({out_result_hdr, out_result_data}),
|
.dataout({out_result_hdr, out_result_data}),
|
||||||
.write(result_fifo_write), .full(result_fifo_full), //input interface
|
.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_ticks = in_ticks_reg;
|
||||||
assign in_command_data = in_data_reg;
|
assign in_command_data = in_data_reg;
|
||||||
assign in_command_hdr = in_hdr_reg;
|
assign in_command_hdr = in_hdr_reg;
|
||||||
assign in_command_has_time = has_tsf_reg;
|
|
||||||
|
|
||||||
always @(posedge clock) begin
|
always @(posedge clock) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
@@ -244,18 +247,24 @@ module settings_fifo_ctrl
|
|||||||
always @(posedge clock)
|
always @(posedge clock)
|
||||||
vita_time_reg <= vita_time;
|
vita_time_reg <= vita_time;
|
||||||
|
|
||||||
wire late;
|
wire late, now;
|
||||||
`ifndef FIFO_CTRL_NO_TIME
|
`ifndef FIFO_CTRL_NO_TIME
|
||||||
time_compare time_compare(
|
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
|
`else
|
||||||
assign late = 1;
|
assign late = 1;
|
||||||
|
assign now = 1;
|
||||||
`endif
|
`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)
|
//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 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
|
//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;
|
wire action = (cmd_state == EVENT_CMD) && ~result_fifo_full && perfs_ready && time_ready;
|
||||||
|
|
||||||
assign command_fifo_read = action;
|
assign command_fifo_read = action;
|
||||||
@@ -275,6 +284,7 @@ module settings_fifo_ctrl
|
|||||||
command_ticks_reg <= out_command_ticks;
|
command_ticks_reg <= out_command_ticks;
|
||||||
command_hdr_reg <= out_command_hdr;
|
command_hdr_reg <= out_command_hdr;
|
||||||
command_data_reg <= out_command_data;
|
command_data_reg <= out_command_data;
|
||||||
|
cmd_was_late <= late; //TODO do something with
|
||||||
end
|
end
|
||||||
|
|
||||||
EVENT_CMD: begin // poking and peeking happens here!
|
EVENT_CMD: begin // poking and peeking happens here!
|
||||||
@@ -332,11 +342,14 @@ module settings_fifo_ctrl
|
|||||||
localparam WRITE_VRT_SID = 2;
|
localparam WRITE_VRT_SID = 2;
|
||||||
localparam WRITE_RB_HDR = 3;
|
localparam WRITE_RB_HDR = 3;
|
||||||
localparam WRITE_RB_DATA = 4;
|
localparam WRITE_RB_DATA = 4;
|
||||||
|
localparam WRITE_RB_DATA2 = 5;
|
||||||
|
localparam WRITE_RB_DATA3 = 6;
|
||||||
|
|
||||||
//the state for the start of packet condition
|
//the state for the start of packet condition
|
||||||
localparam WRITE_PKT_HDR = (PROT_HDR)? WRITE_PROT_HDR : WRITE_VRT_HDR;
|
localparam WRITE_PKT_HDR = (PROT_HDR)? WRITE_PROT_HDR : WRITE_VRT_HDR;
|
||||||
|
|
||||||
reg [2:0] out_state;
|
reg [2:0] out_state;
|
||||||
|
reg [31:0] last_result_hdr;
|
||||||
|
|
||||||
assign out_valid = ~result_fifo_empty;
|
assign out_valid = ~result_fifo_empty;
|
||||||
assign result_fifo_read = out_data[33] && writing;
|
assign result_fifo_read = out_data[33] && writing;
|
||||||
@@ -344,9 +357,11 @@ module settings_fifo_ctrl
|
|||||||
always @(posedge clock) begin
|
always @(posedge clock) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
out_state <= WRITE_PKT_HDR;
|
out_state <= WRITE_PKT_HDR;
|
||||||
|
last_result_hdr <= 32'b0;
|
||||||
end
|
end
|
||||||
else if (writing && out_data[33]) begin
|
else if (writing && out_data[33]) begin
|
||||||
out_state <= WRITE_PKT_HDR;
|
out_state <= WRITE_PKT_HDR;
|
||||||
|
last_result_hdr <= out_result_hdr;
|
||||||
end
|
end
|
||||||
else if (writing) begin
|
else if (writing) begin
|
||||||
out_state <= out_state + 1;
|
out_state <= out_state + 1;
|
||||||
@@ -357,7 +372,7 @@ module settings_fifo_ctrl
|
|||||||
//-- assign to output fifo interface
|
//-- assign to output fifo interface
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
wire [31:0] prot_hdr;
|
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[16] = 1; //yes frame
|
||||||
assign prot_hdr[18:17] = PROT_DEST;
|
assign prot_hdr[18:17] = PROT_DEST;
|
||||||
assign prot_hdr[31:19] = 0; //nothing
|
assign prot_hdr[31:19] = 0; //nothing
|
||||||
@@ -370,12 +385,14 @@ module settings_fifo_ctrl
|
|||||||
WRITE_VRT_SID: out_data_int <= ACK_SID;
|
WRITE_VRT_SID: out_data_int <= ACK_SID;
|
||||||
WRITE_RB_HDR: out_data_int <= out_result_hdr;
|
WRITE_RB_HDR: out_data_int <= out_result_hdr;
|
||||||
WRITE_RB_DATA: out_data_int <= out_result_data;
|
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;
|
default: out_data_int <= 0;
|
||||||
endcase //state
|
endcase //state
|
||||||
end
|
end
|
||||||
|
|
||||||
assign out_data[35:34] = 2'b0;
|
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[32] = (out_state == WRITE_PKT_HDR);
|
||||||
assign out_data[31:0] = out_data_int;
|
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_empty, command_fifo_full, //2
|
||||||
command_fifo_read, command_fifo_write, //2
|
command_fifo_read, command_fifo_write, //2
|
||||||
addr, //8
|
addr, //8
|
||||||
strobe_reg, strobe, poke, out_command_has_time //4
|
strobe_reg, strobe, poke, time_wait //4
|
||||||
};
|
};
|
||||||
|
|
||||||
endmodule //settings_fifo_ctrl
|
endmodule //settings_fifo_ctrl
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ module umtrx_core
|
|||||||
// Buffer Pool Status -- Slave #5
|
// Buffer Pool Status -- Slave #5
|
||||||
|
|
||||||
//compatibility number -> increment when the fpga has been sufficiently altered
|
//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};
|
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;
|
||||||
using namespace uhd::transport;
|
using namespace uhd::transport;
|
||||||
|
|
||||||
|
//command policy flags
|
||||||
static const size_t POKE32_CMD = (1 << 8);
|
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 ACK_TIMEOUT = 0.5;
|
||||||
static const double MASSIVE_TIMEOUT = 10.0; //for when we wait on a timed command
|
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_DIV SR_SPI_CORE + 0
|
||||||
#define SPI_CTRL SR_SPI_CORE + 1
|
#define SPI_CTRL SR_SPI_CORE + 1
|
||||||
@@ -50,6 +55,12 @@ public:
|
|||||||
_window_size(std::min(window_size, MAX_SEQS_OUT)),
|
_window_size(std::min(window_size, MAX_SEQS_OUT)),
|
||||||
_seq_out(0),
|
_seq_out(0),
|
||||||
_seq_ack(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)
|
_timeout(ACK_TIMEOUT)
|
||||||
{
|
{
|
||||||
UHD_MSG(status) << "fifo_ctrl.window_size = " << _window_size << std::endl;
|
UHD_MSG(status) << "fifo_ctrl.window_size = " << _window_size << std::endl;
|
||||||
@@ -155,6 +166,7 @@ public:
|
|||||||
_time = time;
|
_time = time;
|
||||||
_use_time = _time != uhd::time_spec_t(0.0);
|
_use_time = _time != uhd::time_spec_t(0.0);
|
||||||
if (_use_time) _timeout = MASSIVE_TIMEOUT; //permanently sets larger timeout
|
if (_use_time) _timeout = MASSIVE_TIMEOUT; //permanently sets larger timeout
|
||||||
|
_start_of_burst = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_tick_rate(const double rate){
|
void set_tick_rate(const double rate){
|
||||||
@@ -162,6 +174,11 @@ public:
|
|||||||
_tick_rate = rate;
|
_tick_rate = rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_late_policy(const bool skip_late)
|
||||||
|
{
|
||||||
|
_skip_late = skip_late;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
@@ -184,7 +201,8 @@ private:
|
|||||||
packet_info.packet_count = _seq_out;
|
packet_info.packet_count = _seq_out;
|
||||||
packet_info.sid = _sid;
|
packet_info.sid = _sid;
|
||||||
packet_info.tsf = _time.to_ticks(_tick_rate);
|
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.eob = false;
|
||||||
packet_info.has_sid = true;
|
packet_info.has_sid = true;
|
||||||
packet_info.has_cid = false;
|
packet_info.has_cid = false;
|
||||||
@@ -195,6 +213,10 @@ private:
|
|||||||
//load header
|
//load header
|
||||||
vrt::if_hdr_pack_be(pkt, packet_info);
|
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
|
//load payload
|
||||||
const boost::uint32_t ctrl_word = (addr & 0xff) | cmd | (_seq_out << 16);
|
const boost::uint32_t ctrl_word = (addr & 0xff) | cmd | (_seq_out << 16);
|
||||||
pkt[packet_info.num_header_words32+0] = htonl(ctrl_word);
|
pkt[packet_info.num_header_words32+0] = htonl(ctrl_word);
|
||||||
@@ -221,10 +243,50 @@ private:
|
|||||||
vrt::if_packet_info_t packet_info;
|
vrt::if_packet_info_t packet_info;
|
||||||
packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
|
packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
|
||||||
vrt::if_hdr_unpack_be(pkt, packet_info);
|
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){
|
//extract the payloads
|
||||||
return ntohl(pkt[packet_info.num_header_words32+1]);
|
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;
|
return 0;
|
||||||
@@ -236,7 +298,12 @@ private:
|
|||||||
boost::mutex _mutex;
|
boost::mutex _mutex;
|
||||||
boost::uint16_t _seq_out;
|
boost::uint16_t _seq_out;
|
||||||
boost::uint16_t _seq_ack;
|
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;
|
uhd::time_spec_t _time;
|
||||||
|
bool _start_of_burst;
|
||||||
|
bool _skip_late;
|
||||||
bool _use_time;
|
bool _use_time;
|
||||||
double _tick_rate;
|
double _tick_rate;
|
||||||
double _timeout;
|
double _timeout;
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user