??? 10/24/07 03:12 Read: times Msg Score: +1 +1 Informative |
#146108 - OP Update 9 of ? Responding to: ???'s previous message |
Well, today was a good day. I finished the last of the modules for the Morse code decoder, wired them all together in a top level module, loaded them into the Xilinx evaluation board, and it kinda, sorta, almost actually worked. Imagine that. Of course I had debugged the individual modules one by one in the simulator beforehand. And Andy and Jez and Richard saved me from falling more than a few times ... many thanks for that.
I'll explain later what "kinda, sorta, almost" means. But first I want to show what I did and ask the experts out there for a critique. In particular, I'm wondering about questions like these:
Here's a top-level block diagram of the Morse code decoder: and here is the code that implements it: I made most of the diagrams here before I did very much of the implementation. As a result, they may not match the Verilog code exactly. But they are close. For the record, I've been using the word mark to mean either a dit or a dah, and space to mean the silent periods between the dits and the dahs. For lack of a better word, I've been using event to mean either a mark or a space. The topmost block in the diagram above watches the input line for transitions in either direction. For each one, it spits out the duration of the mark or space just ending (this is just the time since the previous transition), along with a single bit to indicate whether it was a mark or a space. Here are links to details for this block: The FIFO in the middle of the diagram buffers the raw event information for use later by the decoder below it. Here are links to details for this block: There's a little state machine inside the decoder that grabs events one by one from the bottom of the FIFO and assembles them into Morse code characters. The decoder then uses a simple table lookup scheme to translate sequences of dits and dahs into the corresponding ASCII codes. The state machine is in one module and the character translation table in another. Here are the details: Decoder state machine: Character translation table: Finally, the block at the bottom serializes the ASCII codes into an RS232 bitstream that something like Hyperterminal can display. Here are the details: But wait! How does the decoder know the difference between the dits and the dahs? Well, everyone knows that dahs are longer than dits, but the decoder needs an actual threshold between the two to sort out the raw event information from the FIFO. The block on the left side of the picture watches the marks as they occur, discriminates the long ones from the short ones, and generates the threshold that the decoder needs. The threshold detector block contains four modules. Two of them are identical averagers that keep a running average of the lengths of the dits and dahs. As it turns out, they use the very same filtering mechanism discussed here: The third module within the threshold detector works at startup to put short marks into the "dit" averager and long marks into the "dah" averager in order to get things started. Once the running averages have been established, then this tentative approach is abandoned and the output of the threshold detector is used to discriminate the incoming dits and dahs. Here are the details for this module: The last module in the threshold detector is one that simply ties the other three together: The Result As I mentioned, the decoder as presented "kinda, sorta, almost" works. There are two problems at this point. One is a simple matter of key bounce. I need to work out some sort of filtering scheme that eliminates spurious transitions on the input signal without wiping out legitimate dits if somebody is sending really fast. A simple RC filter might be just the thing. Or maybe another averager in the FPGA. A worse problem is that I didn't design in any way to handle the long spaces between words, or the very long space when the input simply ends. As a result, THEWORDSRUNTOGETHERANDTHELASTCHARACTERNEVERGETSTRANSMITTE This is something I definitely should have thought about earlier. It remains to be seen if the fix turns out to be really ugly or just the regular kind. -- Russ |