I like tinkering with schematic based logic design, but I can easily find myself distracted away from the technical problem at hand by trying to make my schematic nice and neat. Using code instead of a schematic will let me abstract away this problem while also providing means of making my designs more scalable and easier to understand.
In this post I'll export a schematic based design from Digital to run on a real FPGA and I'll also look at how custom blocks in Verilog can be added into a schematic design in Digital.
Digital Goes IRL
So far in this series all of the circuit tinkery has been virtual, but the HDL exporting features in Digital will let us bring these designs to life.
I'll first come up with a rough plan. The Arty-A7 board I will use has enough lights, buttons and switches for me to play around with, so that is not a big concern.
The schematic has one big issue though: the telnet block is actually powered my magic (or simulator software) so it can't be exported to HDL. That's not a dealbreaker for today's goal though, I'll just... simulate the emulated hardware with actual hardware, obviously!
Since the telnet block is going away, so does the communication protocol from before and so I'll simplify the schematic a bit before getting deeper into this.
That cleans up a good bit of clutter. The register now has floating inputs so I'll need to route some new signals to it. This is also a good time to replace the switches and LEDs in the design as those physical devices are also not part of the HDL model of the digital world. Everything will get simplified down to inputs an outputs at the top level.
I'm not sure if
Clk needs to be changed, I guess we'll find out when I try to export it!
Clk wasn't a problem, but all of my other pins being unlabeled was. After slapping some names on them, Digital is ready to export it to Verilog for me.
Let's see what it generated...
/* * Generated by Digital. Don't modify this file! * Any changes will be lost if this file is regenerated. */ module DIG_Register_BUS #( parameter Bits = 1 ) ( input C, input en, input [(Bits - 1):0]D, output [(Bits - 1):0]Q ); reg [(Bits - 1):0] state = 'h0; assign Q = state; always @ (posedge C) begin if (en) state <= D; end endmodule module top ( input Clk, input r1, input r2, input t, input s1, input s2, output l1, output l2 ); wire [1:0] s0; wire [1:0] s3; assign s0 = r1; assign s0 = r2; DIG_Register_BUS #( .Bits(2) ) DIG_Register_BUS_i0 ( .D( s0 ), .C( Clk ), .en( t ), .Q( s3 ) ); assign l1 = (s1 ^ s3); assign l2 = (s2 ^ s3); endmodule
It's interesting to see what kind of HDL it generated for me. There's a module digital made to represent it's version of a register and the
top module which is my design. I named the file
top.v so that the module would be named
top and that is conventionally the name for the top level module in an FPGA project.
Some FPGA Wizardry
One of my side projects, which will hopefully be receiving some more love in the near future, is a tool to aide in this kind of digital tinkery called Wiz. My aim for this tool is to make playing with FPGAs a lot easier and more fun, especially for curious software developers.
As of this writing the tool is very young and in rough shape, but it's made for this exact type of exploratory usage so here we go!
I'll start by creating a new folder, and within that folder I'll make a
wiz.toml file, this is a manifest file used by Wiz that tells it how I want to build and program my logic design project.
package_name = 'irl' builder = 'vivado' programmer = 'vivado' target_part = 'xc7a35ticsg324-1L' target_device = 'xc7a35t_0' source_files = ['top.v'] bitstream_path = 'irl.bit' [pins]
This file format is very likely to change, but the important parts are that
vivado is what I'll be using for building and programming the device and it also specifies some details about my target Artix-A35T FPGA part/device.
I'll also need to add more detail to the
[pins] section to map out the FPGA pins to the inputs and outputs of my
top module. This is mostly going to be a matter of referring to the board reference material and selecting from that.
In this case, I'll use the Arty's
LD6 LEDs as LED1 (
l1) and LED2 (
l2), which are mapped to pins
T9 respectively. For the physical switch inputs (
s2), I'll use the left two dip switches (
SW2) and for the register inputs (
r2) I'll use the right two (
t, my trigger input to save the new register state, I'll use the
BTN0 button. That just leaves
Clk, which I'll hook up to the 100mhz clock on FPGA pin
[pins] Clk = 'E3' r1 = 'C11' r2 = 'A8' t = 'D9' s1 = 'A10' s2 = 'C10' l1 = 'T10' l2 = 'T9'
Picking and mapping the pins can be a little tedious, but professional FPGA tools often make it much more work than this!
Next I'll build the project with
It takes a good bit to get through all its steps, but at the end I have my bitfile ready to flash. I'll plug in my Arty board and load it up with
Huzzah, my design is now implemented and working in real hardware!
The design itself isn't very interesting, but I'm pretty happy with the flow my Wiz tool is starting to enable.
Returning to Schematics
Now what I'll do is a little bit of the opposite direction, just to prove that these tools can be mixed and matched. I'll make a new schematic and include a new Verilog block that includes the design. This is the exported Verilog from earlier, but this time imported into Digital as a module.
Everything needs to match up, including the one
Clk signal I capitalized for no reason and the
top module name for the block. I now have a pretty decent grip on a flow for how to mix and match HDL and schematics for logic design. That'll be all for this post!