This week I mainly worked on the microphone boards and FPGA drivers. The microphone boards were finished early this week, and ordered on Wednesday. They were fabricated and shipped yesterday, and expected to arrive by next Friday (4/3).
As mentioned previously, this design uses a small number of large boards with 16 microphones each, connected directly to the FPGA board with ribbon cables. This should significantly reduce the amount of work required to fabricate the boards and assemble the final device, though at the expense of some configurability, if we have to change some parameter of the array later.
As the schematic shows, most of the parts on the board will not be populated, but were included as mitigations to possible issues. The microphone footprints were included in case we need to change microphones, and there are several different options for improving clock and data signal integrity (such as differential signaling and termination), if needed. Most parts, particularly the regulator, are relatively generic, and so can be acquired from multiple vendors, in case there is a problem with our digikey order (which was also placed this week).
While working on the FPGA ethernet driver, one problem that came up was with the UDP checksum. Unlike the ethernet frame CRC, which is in the footer of the packet, the UDP checksum is held in the packet header:
This means that the header depends on all of the data to be sent, which, means that the entire packet must be held in memory, then the checksum computed, then either the checksum modified in memory before transmission, or, during transmission the “source” of data has to be changed from memory to the register holding the checksum. I didn’t particularly like either of these solutions, and so, came up with another. I made the checksum an arbitrary constant, and added two bytes to the end of the UDP payload. Those two bytes, which I termed the “cross”, are computed based on all of the data, and the header, so that the checksum works out to that constant. The equation below isn’t exactly right, but gives the basic idea:
In this way, the packet can be sent out without knowing it’s entire contents ahead of time. In fact, if configured to do so, could actually take in new microphone data in the middle of the transmission of a packet, and include that in the packet. This greatly simplifies the rest of the ethernet interface controller, at the expense of a small amount of data overhead in every packet. Given the size of the packets though, this tradeoff is easily worth it.
This coming week, I mainly plan to work on getting the information flow, all the way from the FPGA PDM inputs to a logfile on a computer working. This was expected to be completed earlier, but the complexity of ethernet frames ended up being significantly greater than expected, and took several long days to get working. At this point all the components of the flow are working to some degree, but do not work together yet.