Such Programming

Tinkerings and Ramblings

Mad Computer Science – Part 4 – Schematics to Verilog and Back(ish)

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.

About damn time

ad

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.

Arty A7

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!

So 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[0] = r1;
  assign s0[1] = r2;
  DIG_Register_BUS #(
    .Bits(2)
  )
  DIG_Register_BUS_i0 (
    .D( s0 ),
    .C( Clk ),
    .en( t ),
    .Q( s3 )
  );
  assign l1 = (s1 ^ s3[0]);
  assign l2 = (s2 ^ s3[1]);
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.

ad

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 LD7 and LD6 LEDs as LED1 (l1) and LED2 (l2), which are mapped to pins T10 and T9 respectively. For the physical switch inputs (s1 and s2), I'll use the left two dip switches (SW3 and SW2) and for the register inputs (r1 and r2) I'll use the right two (SW1 and SW0). For 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 E3.

[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 wiz build

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 wiz program.

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!

ad