alexforencich / cocotbext-axi

AXI interface modules for Cocotb
MIT License
209 stars 68 forks source link

AxiStreamSink not reading signed_int from dut #74

Open thenameisT opened 11 months ago

thenameisT commented 11 months ago

While I am using AxiStreamSink to collect dut out, I have noticed that the signed integer is not being collected. When I collect directly from dut out (without using AxiStreamSink) I am able to collect signed integer.


`TX frame: AxiStreamFrame(tdata=[33, -11, 15, -68, 40, -24, -57, 87, 49, 93, -21, 73, 124, 41, 97, 181, 73, 80, 64, 45, 57, 78, -25,................31]

` RX frame: AxiStreamFrame(tdata=[3264, 3263, 1279, 768, 447, 2304, 0, 256, 3216, 1696, 1056, 4000, 704, 1792, 1824, 1216, ......345]`

The input stimulus is a sine wave, signed integer. There are around 80,000 samples, I have just mentioned few above

Is it because of this like in AxiStreamSink code in axis file?

# for offset in range(self.byte_lanes):
                    frame.tdata.append((self.bus.tdata.value.integer >> (offset * self.byte_size)) & self.byte_mask)
#

Should it be self.bus.tdata.value.signed_integer ? Please let me know

alexforencich commented 11 months ago

Not sure what the best solution would be here. I don't think using signed_integer is a good idea though - first, it isn't going to work as expected if byte_lanes isn't 1 (and I think the bit masking is going to remove the sign information anyway even if you swap integer for signed_integer). Second, bytes doesn't accept signed integers, you get an exception if there is anything outside of 0-255, at least when byte_size is 8.

I'm thinking maybe the "right" solution would be to add a config option somewhere (probably to the constructor) to control sign bit handling in the RX direction. This would also force anything with 8 bit bytes to use list instead of bytes so the sign information is preserved.

thenameisT commented 11 months ago

Thank you for the quick reply. I am using byte_size=12 Could you please let me know how exactly to do it?

thenameisT commented 11 months ago

And another issue, the input sample is around 80,000 and the output samples I receive using axistreamsink is 160,000(almost double ). Any idea where I might be wrong ? But its right when i just use AXIStremSource to drive samples to dut and collect it using my own logic.(without sink)

alexforencich commented 11 months ago

Wrong number of outputs makes me thing you're not implementing the AXI stream handshake correctly somehow. If your logic works when it's talking to another piece of your own logic, my guess is you may have misunderstood some aspect of the AXI stream spec. I would have to see a waveform dump to get to the bottom of whatever is going on.

Also, I suppose it might make sense to add some additional assertions, for example if tvalid is high but tready is low, no signals are allowed to change until tready goes high. This would probably help catch a few bugs.

alexforencich commented 11 months ago

Also, to manually recreate the sign bit, I think the simplest thing to do is something like this, assuming your data bus is 16 bits wide (so the sign bit is bit 15):

data = [(x ^ 2**15) - 2**15 for x in data]