DE0-Nano to Python via TCL
How to communicate between a PC and a design running on the DE0-Nano using the Virtual JTAG Megafunction, a Tcl TCP/IP Server running in quartus_stp with virtually any programming language.

*07/05/14 – Reader Paul Green has extended this post’s idea and built a virtual com port for talking to the DE0-Nano. Check out his very well written vj-uart project on GitHub. Here is my tutorial on how to use vj-uart.

*04/18/14 – See the comments below for the new open_sld project from Vern Muhr which allows direct access to the Virtual JTAG interface (using Python) without the TCP/IP TCL pipe described in this article.

The first thing I wondered when I got my hands on the DE0-Nano was how best to communicate with a design inside the FPGA. Initially, I assumed that with the USB connection onboard there would be some form of UART connected to a few of the FGPA Pins. Unfortunately, this was not the case.

I sent an email to the creators of the DE0-Nano, terasIC asking how best to go about communicating with a design and their application engineer recommended adding a second USB connection with something like the FTDI 232RL USB to UART Bridge.

I was still convinced there had to be a more elegant way. Fortunately, I came across this post on the Altera forums talking about the Virtual JTAG interface. Thanks to those pointers from the ever helpful Dave, the seed was planted for the solution presented below.

[separator top=”20″ bottom=”20″ style=”single”]

Virtual JTAG Example – Blinky Lights

To demonstrate this functionality I put together a project that uses the DE0-Nano LEDs to count from 0 to 128 in binary, all at the command of a Python script. Nothing better than some flashing lights to demonstrate a new technique.

Download the Project Files

Here I’m attaching the project files, then below I’ll discuss how everything works. I’ve uploaded the files as an Archived Quartus Project (inside a ZIP file since WordPress doesn’t like .qar file types), this contains all of the Quartus Design Files (in Verilog), the Tcl Server Script and the Python File. Let me know in the comments if you would prefer the raw files outside a QAR file instead. (Or both?)

[tagline_box backgroundcolor=”#f6f6f6″ shadow=”yes” border=”1px” bordercolor=”#f6f6f6″ highlightposition=”left” link=”http://idle-logic.com/wp-content/uploads/2012/04/vJTAG_DE0-Nano_Example.zip” linktarget=”” button=”Download” title=”Download the Project File” description=”vJTAG_DE0-Nano_Example.zip”][/tagline_box]

[separator top=”0″ bottom=”20″ style=”single”]

Digital Design Files (Quartus Project)

I’m just going to provide a quick overview of the design and not go into a step by step guide for how to recreate the project from scratch. Have a look at the two examples in the DE0-Nano User Manual for very good instructions on how to create a project from start to finish.

Top Level

My preference is to use schematic entry for the top level design, I think this makes it easier to understand the overall functionality:

Top Level Schematic

Top Level Schematic

vJTAG

vJTAG Block

The first block is the vJTAG, which is a sld_virtual_jtag instance generated by the Altera Megafunction Wizard.

The Megafunction User Guide has a great description for what this block is all about:

The virtual JTAG megafunction IP gives you direct access to the JTAG control signals routed to the FPGA core logic, which gives you a fine granularity of control over the JTAG resource. This opens up the JTAG resource as a general-purpose serial communication interface. A complete Tcl API is available for sending and receiving transactions into your device during runtime. Because the JTAG pins are readily accessible during runtime, this megafunction can be an easy way to customize a JTAG scan chain internal to the device, which can be used to create debugging applications.

vJTAG_interface

vJTAG_interface

This is the block with all the brains for capturing and sending data through the vJTAG. There are two main pieces of information that come from the PC to the Virtual JTAG, an instruction register and a data register. Essentially, we are required to capture bit shifted data from the tdi pin while shifting out data back to the interface through the tdo pin. The ir_in output tells us what specific instruction is being requested.

In this case we configured the vJTAG to have a 1 bit wide instruction register (0 = Bypass, 1 = Capture New LED Output Settings).

Here is the verilog code for this block:

module vJTAG_interface (
	input tck, tdi, aclr, ir_in,v_sdr, udr,

	output reg [6:0] LEDs,
	output reg tdo

);

reg DR0_bypass_reg; // Safeguard in case bad IR is sent through JTAG
reg [6:0] DR1; // Date, time and revision DR.  We could make separate Data Registers for each one, but

wire select_DR0 = !ir_in; // Default to 0, which is the bypass register
wire select_DR1 = ir_in; //Data Register 1 will collect the new LED Settings

always @ (posedge tck or posedge aclr)
begin
	if (aclr)
	begin
		DR0_bypass_reg <= 1'b0;
		DR1 <= 7'b000000;
	end
	else
	begin
		DR0_bypass_reg <= tdi; //Update the Bypass Register Just in case the incoming data is not sent to DR1

		if ( v_sdr )  // VJI is in Shift DR state
			if (select_DR1) //ir_in has been set to choose DR1
					DR1 <= {tdi, DR1[6:1]}; // Shifting in (and out) the data

	end
end

//Maintain the TDO Continuity
always @ (*)
begin
	if (select_DR1)
		tdo <= DR1[0];
    else
		tdo <= DR0_bypass_reg;
end

//The udr signal will assert when the data has been transmitted and it's time to Update the DR
//  so copy it to the Output LED register.
//  Note that connecting the LED's to the DR1 register will cause an unwanted behavior as data is shifted through it
always @(udr)
begin
	LEDs <= DR1;
end

endmodule

This code was developed and derived with the help of some examples from the Altera Wiki

Clock Blinker

clk_blinker

This is just a small block to generate a slow blinking indicator to tell us the design has downloaded to the FPGA and has started running.

module clk_blinker (
	input clk,
	output blink
);
reg [25:0] count;
always @(posedge clk)
	count <= count + 1'b1;
assign blink = count[25];
endmodule

LED Connector

LED Connector

This block just rips the LED_Output bus down into the individual pin connections. I think there is an easier way to do this schematically, but this works for now.

module LED_Connector(
	input [6:0]LEDs,
	output wire LED_6,
	output wire LED_5,
	output wire LED_4,
	output wire LED_3,
	output wire LED_2,
	output wire LED_1,
	output wire LED_0

);

assign LED_6 = LEDs[6];
assign LED_5 = LEDs[5];
assign LED_4 = LEDs[4];
assign LED_3 = LEDs[3];
assign LED_2 = LEDs[2];
assign LED_1 = LEDs[1];
assign LED_0 = LEDs[0];
endmodule

[separator top=”20″ bottom=”20″ style=”single”]

TCL TCP/IP Server

The functions that we use to communicate to the Virtual JTAG instance inside our design are exposed inside the quartus_stp.exe application. Presented below is a small Tcl script which runs in the quartus_stp.exe that starts a TCP/IP server and pipes data to the DE0-Nano, thus giving access to the DE0-Nano design with virtually any programming language.


##############################################################################################
############################# Basic vJTAG Interface ##########################################
##############################################################################################

#This portion of the script is derived from some of the examples from Altera

global usbblaster_name
global test_device
# List all available programming hardwares, and select the USBBlaster.
# (Note: this example assumes only one USBBlaster connected.)
# Programming Hardwares:
foreach hardware_name [get_hardware_names] {
#	puts $hardware_name
	if { [string match "USB-Blaster*" $hardware_name] } {
		set usbblaster_name $hardware_name
	}
}

puts "\nSelect JTAG chain connected to $usbblaster_name.\n";

# List all devices on the chain, and select the first device on the chain.
#Devices on the JTAG chain:

foreach device_name [get_device_names -hardware_name $usbblaster_name] {
#	puts $device_name
	if { [string match "@1*" $device_name] } {
		set test_device $device_name
	}
}
puts "\nSelect device: $test_device.\n";

# Open device
proc openport {} {
	global usbblaster_name
        global test_device
	open_device -hardware_name $usbblaster_name -device_name $test_device
}

# Close device.  Just used if communication error occurs
proc closeport { } {
	catch {device_unlock}
	catch {close_device}
}

proc set_LEDs {send_data} {
	openport
	device_lock -timeout 10000
	# Shift through DR.  Note that -dr_value is unimportant since we're not actually capturing the value inside the part, just seeing what shifts out
	puts "Writing - $send_data"
	device_virtual_ir_shift -instance_index 0 -ir_value 1 -no_captured_ir_value
	#set tdi [device_virtual_dr_shift -dr_value $send_data -instance_index 0  -length 7] #Use this if you want to read back the tdi while you shift in the new value
	device_virtual_dr_shift -dr_value $send_data -instance_index 0  -length 7 -no_captured_dr_value

	# Set IR back to 0, which is bypass mode
	device_virtual_ir_shift -instance_index 0 -ir_value 0 -no_captured_ir_value

	closeport

	#return $tdi
}

##############################################################################################

##############################################################################################
################################# TCP/IP Server ##############################################
##############################################################################################

#Code Dervied from Tcl Developer Exchange - http://www.tcl.tk/about/netserver.html

proc Start_Server {port} {
	set s [socket -server ConnAccept $port]
	puts "Started Socket Server on port - $port"
	vwait forever
}

proc ConnAccept {sock addr port} {
    global conn

    # Record the client's information

    puts "Accept $sock from $addr port $port"
    set conn(addr,$sock) [list $addr $port]

    # Ensure that each "puts" by the server
    # results in a network transmission

    fconfigure $sock -buffering line

    # Set up a callback for when the client sends data

    fileevent $sock readable [list IncomingData $sock]
}

proc IncomingData {sock} {
    global conn

    # Check end of file or abnormal connection drop,
    # then write the data to the vJTAG

    if {[eof $sock] || [catch {gets $sock line}]} {
	close $sock
	puts "Close $conn(addr,$sock)"
	unset conn(addr,$sock)
    } else {
	#Before the connection is closed we get an emtpy data transmission. Let's check for it and trap it
	set data_len [string length $line]
	if {$data_len != "0"} then {
		#Extract the First Bit
		set line [string range $line 0 6]
		#Send the vJTAG Commands to Update the LED
		set_LEDs $line
	}
    }
}

#Start thet Server at Port 2540
Start_Server 2540

##############################################################################################

In order to run this server, I recommend you create a shortcut to the quartus_stp.exe application, then modify the shortcut to execute this script like I’ve shown here:

Shortcut Example to Run Tcl TCP/IP Server

When you run this shortcut the device should be detected automatically, and the server will start and begin listening for connections. It should look like this:

TCL Server

[separator top=”20″ bottom=”20″ style=”single”]

Python LED Counting Script

Here is the small script used to make a socket connection to the Tcl server, and send the binary string data to exercise the LEDs.

import socket

host = 'localhost'
port = 2540
size = 1024

def Open(host, port):
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect(( host,port))
	return s

def Write_LED(conn,intValue):
    size = 7
    bStr_LEDValue = bin(intValue).split('0b')[1].zfill(size) #Convert from int to binary string
    conn.send(bStr_LEDValue + '\n') #Newline is required to flush the buffer on the Tcl server

conn = Open(host, port)

for val in range(0, 2**7):
    Write_LED(conn, val)

conn.close()

[separator top=”20″ bottom=”20″ style=”single”]

Summary

This tutorial demonstrates a proof of concept for creating a communication path between almost any programming language running on your PC and your digital design running on the DE0-Nano. In this example I’ve sacrificed detail for brevity, I think you’ll find that the Virtual JTAG User Manual explains very well the operation of that block. Feel free to leave a question in the comments section below if you are looking for more detail on any portion of this posting.

In the next blog post I’ll show how to simulate this design in ModelSim, I think this is an excellent way to understand how the digital design works.

In addition, just after I finished putting this post together I stumbled across a very rigorous, and more complex example of using this Virtual JTAG, and Tcl Server. In this tutorial the author shows how to connect the Virtual JTAG to an Avalon-MM master, find it here: Using the USB-Blaster as an SOPC/Qsys Avalon-MM master Tutorial.