An FPGA-Based Mechanical Keyboard

You can buy all kinds of keyboards these days, from basic big-brand stuff to obscure mechanical delicacies from small-time builders. Or, you can go the maker route, and build your own. That’s precisely what [Lambert Sartory] did with their Clavier build.

This build goes a bit of a different route to many other DIY keyboards out there, in that [Lambert] was keen to build it around an FPGA instead of an off-the-shelf microcontroller. To that end, the entire USB HID stack was implemented in VHDL on a Lattice ECP5 chip. It was a heavy-duty way to go, but it makes the keyboard quite unique compared to those that just rely on existing HID libraries to do the job. This onboard hardware also allowed [Lambert] to include JTAG, SPI, I2C, and UART interfaces right on the keyboard, as well as a USB hub for good measure.

As for the mechanical design, it’s a full-size 105-key ISO keyboard with one bonus key for good measure. That’s the coffee key, which either locks the attached computer when you’re going for a break, or resets the FPGA with a long press just in case it’s necessary. It’s built with Cherry MX compatible switches, has N-key rollover capability, and a mighty 1000 Hz polling rate. If you can exceed that by hand, you’re some sort of superhuman.

The great thing about building your own keyboard is you can put in whatever features you desire. If you’re whipping up your own neat interface devices, don’t hesitate to let us know!

15 thoughts on “An FPGA-Based Mechanical Keyboard

    1. That doesn’t seem quite fair. You can certainly find ways to spend significant money on mechanical keyboards; and they are more or less inherently more expensive than membrane ones; but the basic models with no-name switches land at $30-50; which is pretty reasonable given that moving parts haven’t come down in price as fast as transistors and that you can easily spend that much on a membrane unit with a name brand or some dubiously useful media keys.

        1. Do you only ever buy the cheapest version of something that exists?

          If it’s something you spend significant time using then it can make sense to buy a decent version.

          You could apply your argument to pretty much anything and it doesn’t become any more valid. You could use a fold out plastic table or you could use a desk, you could use folding plastic chairs or you could buy a decently comfortable computer chair. In most cases the experience and comfort of using the cheapest you can get vs mid range will be pretty significant.

          I’m sure there will be things in your life that you have paid more than absolutely necessary for to get a better product.

    2. Sure, it’s not the cheapest way, but the ECP5 here can be bought for about $7. Compared to the price of the mechanical switches, it’s not that crazy.

      The point of the project was mostly to learn how USB works at the protocol level, and an FPGA was the best way to achieve that.

    3. Well the goal here was not mass production, rather learning how USB works at the protocol level. And for that, there’s no better platform than an FPGA.

      As a side note, the ECP5 on this board can be had for about $7, which is not that crazy compared to the price of the mechanical switches…

  1. That’s a damn clean repository for quite a fine project!
    And everything is free open source, from the projects to the tools, that’s really impressive and shows what can be done.
    Lastly, the custom “Coffee key” is a nice touch, the cherry on top of this very well made project.
    Congratulations, and thanks for the open source project!

  2. It’s somewhat crazy to debounce the keys with counters clocked by 48MHz. Each counter therefore needs 18 bits for counting to 240000, equivalent to 5ms debouncing time. This sums up to 1908 flip-flops for 106 keys! However, the LFE5U25F6BG256C contains 24,000 logic elements, meaning that the counters only use 8% of the flip-flops.

    1. Perhaps one can use a separate function triggered by a much slower timer, to count for the debouncing. Then use a variable (VHDL variable) shared between the debouncing function and the main one for a simple yes/no.

      That should reduce the counter to a more manageable size.

    2. Well spotted!
      I left it like that because I wanted to check with an oscilloscope first how the switches behave, to fine tune the debouncing duration, but I didn’t have time to do it yet.
      It’s indeed not an issue since the FPGA is largely oversized for the task, but it was the cheapest.
      To optimize this would be quite easy, the LED modulator does something similar already with the ClockScaler block.

Leave a Reply to BastetCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.