The code waits for the FIFO to not be empty, reads eight nybbles which it then constructs into a 32 bit word. When I do that it works reliably, reading all data correctly.
If I change the code so that instead of waiting it selects on a 'not empty' case, then the data is not read in correctly. Data are misaligned into the nybble array.
I have no idea why. Can anyone enlighten me as to why this code should run any differently based on the value of USE_SELECT.
Code: Select all
#include <platform.h>
#include <string.h>
#include <stdio.h>
#include "max10_data.h"
#include "defs.h"
#define BUFFER_LEN (32)
#define USE_SELECT (0)
void fifo_task(in port port_data_hi, in port port_data_lo, out port port_clk, out port port_read_req, in port port_empty, clock clk, server max10_data_if i_data)
{
configure_clock_rate(clk, 100, 4); // 100/4 = 25MHz
configure_port_clock_output(port_clk, clk);
configure_in_port(port_data_hi, clk);
configure_in_port(port_data_lo, clk);
start_clock(clk);
int D[8];
int data;
int prev;
int count = 0;
while(TRUE)
{
#if USE_SELECT
select
{
case port_empty when pinseq(0) :> void:
#else
port_empty when pinseq(0) :> void; // Wait for FIFO not empty
#endif
clearbuf(port_data_hi);
clearbuf(port_data_lo);
port_read_req <: 1;
for(int i=0; i<4; i++)
{
port_data_hi :> D[i*2+1];
port_data_lo :> D[i*2];
}
port_read_req <: 0;
// Build data into 32 bit value
data = D[7] << 28 |
D[6] << 24 |
D[5] << 20 |
D[4] << 16 |
D[3] << 12 |
D[2] << 8 |
D[1] << 4 |
D[0];
// Incoming data counts in lower two bytes.
if (((((prev & 0xFFFF0000) | ((prev+1) & 0xFFFF)) != data) // Data is incorrect
&& count > 10000) // Ignore errors after soon after printf. The printf throws things out of sync.
|| (count == 5000000)) // All data correct for 5million readings.
{
printf("#%10d\t%08X\t%08X\n", count, prev, data);
count = 0;
}
prev = data;
count++;
#if USE_SELECT
break;
}
#endif
}
}