Lattice Certus-NX FPGA Versa

Table of contents

RoadTest: Summer of FPGAs -- Lattice Certus-NX Versa Eval Bd

Author: dimiterk

Creation date:

Evaluation Type: Development Boards & Tools

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?: Any FPGA board with 40K LUTs and above.

What were the biggest problems encountered?: Camera modules were not included , PCIe reference design is not ready for use on Ubuntu 20.02, JTAG is not always reliable , requires reboot, Very few IP cores (ex SPI master missing)

Detailed Review:

This roadtest will take a look at the Lattice Certus-NX FPGA Versa evaluation board. Many thank to Element14 and @rscansy for proving the Certus-NX hardware for this review.  The plan is to test the Radiant and Lattice Propel SOC IDEs as well as test the PCIe interface of this board.

  1. Unboxing Certus-NX Versa

The Versa evaluation board comes with a 2 lane PCIE edge connector, a multi-adapter power supply and a USB mini cable.

The board sports two connectors for a parallel and a MIPI camera however no cameras come with the development board and most importantly no specific camera modules are specified in the documentation. As an aside I tried to use an OV5640 camera with an SMD connector for the parallel camera interface however the kit uses a different pitch SMD connector so it was not possible to mount the camera.

  1. Hardware peripherals

The kit comes with :

  1. a) 3 PMOD connectors
  2. b) 2 camera connectors (1 MIPI) 1 parallel
  3. c) 5 buttons
  4. d) 4 slide switches
  5. e) 1 seven segment display
  6. f) 2 Ethernet PHY (SGMII and RGMI)
  7. g) Embedded FTDI serial and JTAG programmer

  1. Development environment

The Lattice Radiant version 3.0 , Lattice Propel and Lattice Propel builder were installed for this review. Both Radiant and Lattice Propel require a license tied to the MAC address.

Once you provide the MAC , Lattice will email you a license file. Add the License Path to the environmental variables as below and you can get started with the EVB.

  1. FPGA RTL flow

Lattice Radiant is used for the RTL flow. Creating a project requires selecting the proper device which in this case is the LFD2NX family, LFD2NX-40 device in a 256 CSB package. The first project will be the obligatory blinking LED project using the 8 onboard LEDs.

RTL project with Lattice radiant

{gallery}Lattice Radiant

Fig 2. Project name

Fig 3. Adding HDL sources

Fig 3. Selecting the FPGA chip

Fig 4. Select the synthesis tool

Fig 5. Finalize the project flow

Fig 6. Configure PLL

All the unused LED has to be set HIGH otherwise they will dimly light up souring current. The code below takes the 12MHz input clock from pin G13 and scales it to light up two LED’s at different frequencies.

 

module LEDblink(CLK_12, o_led);
input CLK_12;     // clock typically from 10MHz to 50MHz

output o_led[7:0];

// create a binary counter
reg [31:0] cnt;
always @(posedge CLK_12)
	begin
		cnt <= cnt+1;
	end
		
		
assign o_led[0] = cnt[22];    // blink the LED at a few Hz (using the 23th bit of the counter, use a different bit to modify the blinking rate)
assign o_led[1] = 1;    
assign o_led[2] = 1;    
assign o_led[3] = 1;    
assign o_led[4] = 1;    
assign o_led[5] = 1;    
assign o_led[6] = 1;    
assign o_led[7] = cnt[20];    

endmodule

The synthesis constraints are specified on the pre-synthesis constraint files .sdc file.

create_clock -name {clk_12Mhz} -period 83 -waveform {0 4} [get_ports CLK_12]
ldc_set_port -iobuf {IO_TYPE=LVCMOS18} [get_ports CLK_12]
ldc_set_location -site {G13} [get_ports CLK_12]


ldc_set_location -site {B3} [get_ports {o_led[0]}]
ldc_set_location -site {A2} [get_ports {o_led[1]}]
ldc_set_location -site {H16} [get_ports {o_led[2]}]
ldc_set_location -site {B2} [get_ports {o_led[3]}]
ldc_set_location -site {H15} [get_ports {o_led[4]}]
ldc_set_location -site {H14} [get_ports {o_led[5]}]
ldc_set_location -site {H12} [get_ports {o_led[6]}]
ldc_set_location -site {J15} [get_ports {o_led[7]}]


ldc_set_location -site {E16} [get_ports {i_dipsw[1]}]
ldc_set_location -site {L10} [get_ports {i_dipsw[0]}]
ldc_set_location -site {L11} [get_ports {i_dipsw[2]}]
ldc_set_location -site {R3} [get_ports {i_dipsw[3]}]

ldc_set_port -iobuf {PULLMODE=UP IO_TYPE=LVCMOS15} [get_ports {switch}]
ldc_set_port -iobuf {PULLMODE=UP IO_TYPE=LVCMOS18} [get_ports {i_dipsw[1]}]
ldc_set_port -iobuf {PULLMODE=UP IO_TYPE=LVCMOS15} [get_ports {i_dipsw[2]}]
ldc_set_port -iobuf {PULLMODE=UP IO_TYPE=LVCMOS15} [get_ports {i_dipsw[3]}]

Next example will instantiate a PLL clocking IP that uses the 25MHz clock on pin F16 to generate the same 12 MHz clock as input to the blinking LED module.

The code below shows how to generate the PLL using the 25MHz clock. The fractional divider needs to be enabled to allow the PPL to generate lower clock frequencies from the 25MHz clock that meet the output tolerance.

module LEDblink(CLK_25, o_led);
input CLK_25;     // clock typically from 10MHz to 50MHz
output o_led[7:0];


// Inputs
    reg clki_i;
    //reg rstn_i;
    reg refdetreset;


// Outputs
    wire clkop_o;
    wire lock_o;
    wire refdetlos;


// Bidirs


// Instantiate the UUT
// Please check and add your parameters manually
    Clock25MHz VGAclk (
        .clki_i(CLK_25), 
        .rstn_i(1), 
        .refdetreset(refdetreset), 
        .clkop_o(clkop_o), 
        .lock_o(lock_o), 
        .refdetlos(refdetlos)
        );
		
		
		
// create a binary counter
reg [31:0] cnt;
always @(posedge clkop_o)
	begin
		cnt <= cnt+1;
	end
		
		
assign o_led[0] = cnt[22];    // blink the LED at a few Hz (using the 23th bit of the counter, use a different bit to modify the blinking rate)
assign o_led[1] = 1;    
assign o_led[2] = 1;    
assign o_led[3] = 1;    
assign o_led[4] = 1;    
assign o_led[5] = 1;    
assign o_led[6] = 1;    
assign o_led[7] = cnt[20];    

endmodule




		
	

One issue that was encountered consistently with radiant is that you may have to power cycle the board to get the FTDI JTAG programmed to succeed.

Also, FTUSB1 should be used for programming as channel 0 is used for the UART pins.

Lattice radiant also uses Lattice Reveal as an internal Logic analyzer core. I encountered timing issue during placement even for simple designs hence one needs to constrain the clocks before each synthesis run.

The board does not have any VGA connector so a VGA PMOD was added using the following constraint file on PMOD connectors J8 and J5.

create_clock -name {clk_25Mhz} -period 40 [get_ports CLK_25]
ldc_set_port -iobuf {IO_TYPE=LVCMOS33} [get_ports CLK_25]
ldc_set_location -site {F16} [get_ports CLK_25]

ldc_set_location -site {H1} [get_ports {vga_b[0]}]
ldc_set_location -site {H2} [get_ports {vga_b[1]}]
ldc_set_location -site {N1} [get_ports {vga_b[2]}]
ldc_set_location -site {K5} [get_ports {vga_b[3]}]
ldc_set_location -site {N2} [get_ports {vga_r[0]}]
ldc_set_location -site {L3} [get_ports {vga_r[1]}]
ldc_set_location -site {M3} [get_ports {vga_r[2]}]
ldc_set_location -site {L5} [get_ports {vga_r[3]}]


ldc_set_location -site {J11} [get_ports {vga_hsync}]
ldc_set_location -site {J12} [get_ports {vga_vsync}]
ldc_set_location -site {C8} [get_ports {vga_g[0]}]
ldc_set_location -site {C7} [get_ports {vga_g[1]}]
ldc_set_location -site {B7} [get_ports {vga_g[2]}]
ldc_set_location -site {A7} [get_ports {vga_g[3]}]

#ldc_set_location -site {K11} [get_ports {io_mtr_pmod0[6]}]
#ldc_set_location -site {K12} [get_ports {io_mtr_pmod0[7]}]



#UART
ldc_set_port -iobuf {IO_TYPE=LVCMOS33} [get_ports txd_o]
ldc_set_port -iobuf {IO_TYPE=LVCMOS33} [get_ports rxd_i]
ldc_set_location -site {E13} [get_ports txd_o]
ldc_set_location -site {F10} [get_ports rxd_i]
#GSRN
ldc_set_location -site {G4} [get_ports rstn_i]
#ldc_set_port -iobuf {PULLMODE=UP} [get_ports rstn_i]
ldc_set_port -iobuf {PULLMODE=UP IO_TYPE=LVCMOS18} [get_ports rstn_i]

This is still in progress as there are some timing issues that need to be resolved with the core.

  1. Lattice Propel SOC Flow

The Lattice Propel builder was used to build a RISC-V System On Chip (SOC) on the FPGA. Lattice shows two examples of this.

The first is a VexRiscv SOC with a custom CNN that makes use of TensorFlow Lite CNN accelerator to predict motor failures. The second example is a node system that also shows how to use the VexRISCV core as an MCU with custom IP cores.

One can either design a SOC using the Block based Lattice Propel Builder and then design the firmware  by importing the sbx file or simply start from the Lattice Proper Eclipse environment and create the complete system from there.

Lattice Propel

One issue that was encountered with these examples is that they use old IP cores of the RiscV MCU. Updating them also introduces incompatibilities.

RISCV Peripheral cores

The last testing module was to build a custom APB3 IP using the Lattice provided IP builder.

Even here the flow seems straightforward but there are enough bumps that make deployment of a simple APB3 IP like an SPI master harder than it should be.  Compared with Intel IP designder or  Xilinx IP integrator the IP design GUI lacks the polish and gives cryptic errors.

  1. PCIE reference design testing

The Versa board can be installed on a motherboard PCIe x2 slot.

Before that one has to install the PCIe kernel driver and compile the GUI. The aim is to control the 7- segment display from the desktop GUI using the PCIE as an endpoint.

To test the PCIe package run the Linux install script. The package states that the kernel module is compatible with Kernel 5.x. However upon installing this as you can see below there are compilation errors that preclude the installation of the kernel module.

{gallery}PCIE test

PCIE kernel driver installation issue

Kernel compilation issue

GUI

GUI

GUI

GUI

To test the PCIE the bitstream has to be programmed first. After installing one can query the board using lspci command.

However not much can be done without a working kernel module.

The PCIe package was released in November and as of December 27 it has been removed from the Certus-NX Versa evaluation board page again so it may be updated in the near future again.

Verdict

The Good

1. 40K LUT FPGA with PCIE connector and 1G Ethernet

2. Radiant supports scripted tcl flow

The Bad

1. PCIE kernel module cannot compile on Ubuntu 20.02

2. No camera modules or references for specified connectors

3. Lattice Propel Vexrisc core has a very limited number of IP cores (no SPI master)

4. MIPI DPHY core not available for free

5. GUI English translation (specifically errors) are lacking so Lattice Radiant may require some further polishing

Anonymous