30 May 2021

News: May 2021

As well as the occasional big blog post, I make many smaller FPGA discoveries and Project F updates each month. I thought it would be interesting to share a few of these in a monthly news post. What do you think? Let me know via @WillFlux or open an issue on GitHub.


In May, I added two blog posts: Hello Arty Part 3 and FPGA Sine Lookup Table.

Hello Arty is my introductory series for the Digilent Arty board. In Hello Arty Part 3, we design a countdown timer and a traffic light control system using finite state machines. We also cover enums, case statements, button debouncing, and shift registers. I think this part is overly long, and I still haven’t covered test benches, so I am considering a fourth part for this series.

Sine Lookup Table is a new entry in the cookbook. We pre-calculate sine values with a Python script and then load them into a ROM with a simple Verilog module. For many applications, pre-calculated sine values are more than good enough. I’ve been using the lookup table for simple 3D graphics, which I’ll write about soon.

Sine & Cosine

Graph image by Geek3 in the public domain.


I dipped my toes in the waters of YouTube with a little demo reel: FPGA Graphics Demo 1.

All the graphics in this demo reel are generated by an Artix-7 FPGA using designs from FPGA Graphics. I sped up some of the sequences during video editing, and I’m using pre-recorded music, but otherwise, what you see is exactly as it came from the FPGA.

Stay tuned for more videos over the summer.

FPGA Graphics

The FPGA Graphics tutorial series has been my main focus for the past year. This month I made a few useful improvements to existing designs from this series.

Draw Line Performance

Many graphics routines depend on line drawing. This month, I improved the performance of the Bresenham’s line module: draw_line.sv. The cube and triangle demos from Lines and Triangles now comfortably meet timing on iCEBreaker, allowing me to close issue #37.

Ad Astra on iCEBreaker

The Ad Astra blog post includes a greetings demo using sprites to draw text characters. This design was one of the earliest created for my FPGA Graphics series, and its performance has never been great on iCEBreaker.

I recently learnt about Yosys support for ABC logic library v9 from a conversation on 1BitSquared Discord. I tried ABC v9 on several designs with variable results: logic usage was down significantly on all designs, but some designs suffered performance regressions. Happily, Ad Astra on iCEBreaker was one of the designs that showed a significant improvement in timing, allowing me to close issue #32.

If you want to try ABC v9 with your iCEBreaker designs use: synth_ice40 -abc9 -device u, and you can see a complete example in the Ad Astra Makefile.

FPGA Ad Astra

The Sky is Falling

The hedgehog sprite from Hardware Sprites walks under a cloudless sky.

Hedgehog walking under the sky

My original sky design used combinational logic (nextpnr timings are shown below the design):

    logic [11:0] bg_colr;
    always_comb begin
        bg_colr = 12'h260;  // default
        if (sy < 80)       bg_colr = 12'h239;
        else if (sy < 140) bg_colr = 12'h24A;
        else if (sy < 190) bg_colr = 12'h25B;
        else if (sy < 230) bg_colr = 12'h26C;
        else if (sy < 265) bg_colr = 12'h27D;
        else if (sy < 295) bg_colr = 12'h29E;
        else if (sy < 320) bg_colr = 12'h2BF;

// Info: 13.7 ns logic, 23.9 ns routing
// Info: Max frequency for clock 'clk_pix': 26.63 MHz (PASS at 25.14 MHz)

I recently switched to a new registered version that cut routing time in half!

    logic [11:0] bg_colr;
    always_ff @(posedge clk_pix) begin
        if (line) begin
            if      (sy == 0)   bg_colr <= 12'h239;
            else if (sy == 80)  bg_colr <= 12'h24A;
            else if (sy == 140) bg_colr <= 12'h25B;
            else if (sy == 190) bg_colr <= 12'h26C;
            else if (sy == 230) bg_colr <= 12'h27D;
            else if (sy == 265) bg_colr <= 12'h29E;
            else if (sy == 295) bg_colr <= 12'h2BF;
            else if (sy == 320) bg_colr <= 12'h260;

// Info: 11.9 ns logic, 11.8 ns routing
// Info: Max frequency for clock 'clk_pix': 42.14 MHz (PASS at 25.14 MHz)

The maximum frequency of the complete hedgehog design increased from a marginal 26.63 MHz to a comfortable 42.14 MHz. The moral of this story: beware of seemingly simple combinational logic tanking your timing.

For the complete designs, see the Hardware Sprite design files (GitHub).

Bits & Tips

nextpnr Clock Constraint

You can set a nextpnr clock constraint in your PCF file using set_frequency.

For iCEBreaker, I use:

## Board Clock: 12 MHz
set_frequency  clk_12m      12
set_io -nowarn clk_12m      35

FPGA and RISC-V links that caught my eye:

And Finally…

I’m a sucker for Amiga documentaries, and Kim Justice’s The Story and Games of the Bitmap Brothers is one of the best.

©2021 Will Green, Project F