I have wasted far too much time on this.
So here goes. Started off coding up a basic SPI slave device, to work with a Raspberry Pi as SPI master. Using a Xilinx XC6SLX16 as the slave. Using a logic analyzer in parallel with the FPGA and the RPi. Garbage read back to the RPi. So I have whittled the code down to simply triggering on the SPI clock positive edge, incrementing a 3-bit counter to then write out the counter bits on three general purpose I/O lines for the logic analyzer to display. I have reduced the RPi SPI clock to 25khz (SPI divider of 10,000).
module laser1(
input sclk,
output miso,
output [2:0] out
);
reg miso_r;
reg [2:0] count;
reg [7:0] data1;
initial begin
data1 = 8'b11000101;
count = 3'b000;
end
assign miso = miso_r;
assign out = count;
always @(posedge sclk) begin
case (count)
0: miso_r <= data1[0];
1: miso_r <= data1[1];
2: miso_r <= data1[2];
3: miso_r <= data1[3];
4: miso_r <= data1[4];
5: miso_r <= data1[5];
6: miso_r <= data1[6];
7: miso_r <= data1[7];
endcase
count <= count + 1'b1;
if (count == 3'b111)
count <= 3'b000;
end
endmodule
I have ended up using a case statement but it still acts idiotic. I used to have:
miso_r <= data1[count];
On the logic analyzer, the 3 bits of 'count' are channels 4,5,6:
With each triggering from the SPI clock, we see 'count' take on these values:
0,1,2,3,5,6,7,0,1,3,5,6,7,0,1,3
If I change the index into data1 to be a constant, 'count' increments normally. The very act of using it as a bit-select totally wrecks its value.
This is beyond weird. Any insights are appreciated...
This is the contents of the constraints file, showing the label for each pin out of the package file:
NET miso LOC="F9"; // IO_L40P_0
NET sclk LOC="A9"; // IO_L34N_GCLK18_0
NET out<2> LOC="F7"; // IO_L5P_0
NET out<1> LOC="D6"; // IO_L7P_0
NET out<0> LOC="P9"; // IO_L14N_D12_2