FrontPanel SDK Examples

These pages include a number of resources to help make you more productive with our products. Please refer to the following resources if you need a hand.

Setting and Getting Multiple Registers

Setting and getting multiple registers at once is possible with the WriteRegisters() and ReadRegisters() methods. Rather than passing in a single okTRegisterEntry object, a set of okTRegisterEntry objects is passed to WriteRegisters() or ReadRegisters() in the form of a vector of okTRegisterEntry objects (C++) or wrapped in an object of class okTRegisterEntries (C#,Python, and Java). These are initialized in different ways, but are used by ReadRegisters() and WriteRegisters() in the same way. Note that when using ReadRegisters(), the set of okTRegisterEntry objects that is passed to the method must have valid addresses already set. Note also that in Java, the address and data members of the okTRegisterEntry class are accessed using their own setter and getter methods, not by dot and bracket notation.

The okRegisterBridge module is unique among the FrontPanel endpoints in that it does not have an endpoint address. Instead, registers are read and written by referencing a data address, which is the same for both read and write operations. Also unlike other single FrontPanel endpoints, okRegisterBridge interacts with both incoming and outgoing data from the FrontPanel Host interface.

This module can be tested with the “Accessing BRAM” example code. For specific information about each of these methods, consult the FrontPanel User’s Manual, the FrontPanel API guide, and the samples and README files provided with the FrontPanel download.

Note: This section contains both software and HDL portions. The software and HDL must work in tandem if FrontPanel is to be used on the PC end to perform tasks on the FPGA. The HDL in this section is designed to be set within the FrontPanel Framework HDL, available on the HDL Framework page for USB 2.0 and USB 3.0. For specific information about the FrontPanel methods or modules, consult the FrontPanel User’s Manual, the FrontPanel API guide, and the samples and README files provided with the FrontPanel download.

okCFrontPanel dev;
okCFrontPanel::ErrorCode error;
std::vector regs(3);
std::vector inreg(3);
UINT32 i;

// Initialize outgoing addresses and data, incoming addresses
for (i = 0; i < 3; i++){
     regs[i].address = i;
     regs[i].data = i;
     inreg[i].address = i;
}

dev.OpenBySerial();
error = dev.ConfigureFPGA("example.rbf");
// It’s a good idea to check for errors here!

error = dev.WriteRegisters(regs);
error = dev.ReadRegisters(regs);
// Checking that the methods returned NoError is not sufficient for design verification!!
okCFrontPanel dev = new okCFrontPanel();
okCFrontPanel.ErrorCode error;
okTRegisterEntries regs = new okTRegisterEntries(3);
okTRegisterEntries inreg = new okTRegisterEntries(3);
okTRegisterEntry newreg = new okTRegisterEntry();
int i;
UInt32 n = 0;

// Initialize outgoing addresses and data, incoming addresses
 for (i = 0; i < 3; i++)
 {
     newreg.address = n;
     regs.Add(newreg);
     newreg.data = 0;
     inreg.Add(newreg);
     n++;
}

error = dev.OpenBySerial("");
error = dev.ConfigureFPGA("example.rbf");

error = dev.WriteRegisters(regs);
error = dev.ReadRegisters(inreg);
// Checking that the methods returned NoError is not sufficient for design verification!!
dev = ok.okCFrontPanel()
reg = ok.okTRegisterEntry()
regs = ok.okTRegisterEntries(3)
inreg = ok.okTRegisterEntries(3)

# Initialize outgoing addresses and data, incoming addresses
for i in range(3):
     inreg[i].address = i
     regs[i].address = i
     regs[i].data = i

dev.OpenBySerial("")
error = dev.ConfigureFPGA("example.rbf")
# It’s a good idea to check for errors here!!

error = dev.WriteRegisters(regs)
error = dev.ReadRegisters(inreg)
# Checking that the methods returned NoError is not sufficient for design verification!!
public class example{
     okCFrontPanel dev;
     okCFrontPanel.ErrorCode error;
     okTRegisterEntries regs = new okTRegisterEntries(3);
     okTRegisterEntries inreg = new okTRegisterEntries(3);
     int i;

     public void ReadWrite(){
          dev = new okCFrontPanel();
          dev.OpenBySerial("");
          error = dev.ConfigureFPGA("example.rbf");
          //It’s a good idea to check for errors here!!
	
          // Initialize outgoing addresses and data, incoming addresses
          for(i = 0; i < 3; i++){
               regs.get(i).setAddress(i);
               inreg.get(i).setAddress(i);
               regs.get(i).setData(i);
          }

          error = dev.WriteRegisters(regs);
          error = dev.ReadRegisters(inreg);
          // Checking that the methods returned NoError is not sufficient for design verification!!
     }
}
//Configured for XEM6310-LX45

// Wire declarations
wire [31:0] regAddress;
wire [31:0] regDataOut;
reg [31:0] regStore[31:0];
wire [31:0] regDataIn;
wire regRead;
wire regWrite;
reg [3:0] WriteEnByte;
	
// Circuit behavior
always @ (*) begin
     if(regWrite) WriteEnByte = 4'b1111;
     else WriteEnByte = 4'b0000;
end
	
Xilinx_BRAM_Simple_Dual_Port (
     .DO(regDataIn),
     .DI(regDataOut),
     .RDADDR(regAddress[8:0]),
     .RDCLK(okClk),
     .RDEN(regRead),
     .RST(reset),      
     .WE(WriteEnByte),
     .WRADDR(regAddress[8:0]),
     .WRCLK(okClk),
     .WREN(regWrite)
);
	
// FrontPanel endpoint instantiation
okRegisterBridge regBridge (
     .okHE(okHE),
     .okEH(okEHx[0*65 +: 65]),
     .ep_write(regWrite),
     .ep_read(regRead),
     .ep_address(regAddress),
     .ep_dataout(regDataOut),
     .ep_datain(regDataIn)
);

// ******BRAM module source******//
// Include outside of top module

//XILINX BRAM MACRO
//Generated by Xilinx ISE
module Xilinx_BRAM_Simple_Dual_Port(
     input [31:0] DI,
     output [31:0] DO,
     input [8:0] WRADDR,
     input [8:0] RDADDR,
     input [3:0] WE,
     input WREN,
     input RDEN,
     input RST,
     input SSR,
     input WRCLK,
     input RDCLK
);

// BRAM_SDP_MACRO: Simple Dual Port RAM
// Spartan-6
// Xilinx HDL Language Template, version 14.7

BRAM_SDP_MACRO #(
     .BRAM_SIZE("18Kb"), 
     .DEVICE("SPARTAN6"),
     .WRITE_WIDTH(32),
     .READ_WIDTH(32),
     .DO_REG(0),
     .INIT_FILE ("NONE"),
     .SIM_COLLISION_CHECK ("ALL"), 
     .SRVAL(72'h000000000000000000),
     .INIT(72'h000000000000000000),
) BRAM_SDP_MACRO_inst (
     .DO(DO),
     .DI(DI),
     .RDADDR(RDADDR),
     .RDCLK(RDCLK),
     .RDEN(RDEN),
     .REGCE(REGCE),
     .RST(RST),      
     .WE(WE),
     .WRADDR(WRADDR),
     .WRCLK(WRCLK),
     .WREN(WREN)
);

// End of BRAM_SDP_MACRO_inst instantiation
							
endmodule
--Signal declarations
signal regAddress : STD_LOGIC_VECTOR(31 downto 0) := x"00000000";
signal regDataOut : STD_LOGIC_VECTOR(31 downto 0);
signal regDataIn : STD_LOGIC_VECTOR(31 downto 0) := x"00000000";
signal regRead : STD_LOGIC;
signal regWrite : STD_LOGIC;
signal writeEn : STD_LOGIC_VECTOR(3 downto 0);

--Component declaration goes in architecture portion of VHDL body
COMPONENT BRAM_Macro
     PORT (
          clka : IN STD_LOGIC;
          wea : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
          addra : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
          dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
          douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
          );
END COMPONENT;

--Circuit behavior

process (regWrite) begin
	if(regWrite = '1') then
		writeEn <= "1111";
	else
		writeEn <= "0000";
	end if;
end process;

--Instantiate Block RAM Xilinx Core IP
BRAM_inst : BRAM_Macro port map(
     wea => writeEn,
     addra => regAddress,
     dina => regDataOut,
     douta => regDataIn,
     clka => okClk
     );

--FrontPanel endpoint instantiation
regBridge : okRegisterBridge port map(
     okHE=>okHE,
     okEH=>okEHx(1*65-1 downto 0*65),
     ep_write=>regWrite,
     ep_read=>regRead,
     ep_address=>regAddress, 
     ep_dataout=>regDataOut,
     ep_datain=>regDataIn
     );