ICE Cores

From ICE Enterprises
(Redirected from Category:ICE Cores)
Jump to navigation Jump to search
ICE's framework for developing Code Once, Run Everywhere library functions.

The ICE-CORE library is a collection of signal processing functions designed to run on multiple software/hardware implementations including ICE-FPGA cards. A common public interface is used to simplify development, testing, validation, and performance comparisons between the supported architectures. The HALO or Hardware Abstraction Layer Object is a C/Java callable format definition supporting run-time selection of the underlying hardware implementation. Wrappers are auto-generated for code sharing between various Midas and non-Midas frameworks.

Overview

The HALO currently supports the following architectures:

 JDK - the java reference implementation 
 CPU - the native C implementation
 GPU - the GPU implementation
 VHS - the verilator HDL simulator implementation
 MLS - the MatLab Simulink implementation
 ICE - the ICE FPGA implementation

The development methodology for ICE FPGA functions is as follows:

  1. Code a simple reference algorithm for the function in Java (with primitive and test suite)
  2. Code an optimized version in C (and validate)
  3. Convert to Verilog using the Verilator HDL simulator (and validate)
  4. Compile for FPGA and run on an ICE card (and validate)

The Core Library class can be found in nxm.ice.lib.Core.java.

This paradigm supports the development of software systems that can take advantage of special-purpose hardware, such as GPU's and ICE FPGA's, either as needed or as available.

Naming Conventions

  • Library names should adhere to the following naming conventions:
  • Foo.java - the java implementation of the function Foo Foo.c - the C implementation of Foo (conditionally compiled for CPU, GPU, VHS, or ICE)
  • The Java reference implementation should put readability above performance.
  • The native and hardware implementations should stress performance.
  • The NeXtMidas wrappers to the Native functions are inner classes of Foo.java, creating Foo$CPU.class, Foo$ICE.class, etc.

Function

The Core class in nxm.ice.lib provides the standard framework for developing a Java callable Core. The wrappers for each hardware implementation are auto-generated by the inner class definitions in the Java reference class. This allows the /CORE=x switch to select the desired implementation of the library function without altering the primitive.

There is an example for each library language on their respective pages: CORE JDK, CORE CPU, CORE GPU, CORE VHS, CORE ICE

Primitive

It is recommended that you write a primitive that uses this class. The syntax to initialize a Core object from NeXtMidas is as follows:

Core foo = Core.forName("Foo",MA);

The /CORE=x switch is parsed in the forName() method to select the implementation. The switch argument must match the first letters of one of the implementations or an exception will be thrown.

Here is an example NeXtMidas primitive icenoop.java:

 /**
   Implements a NOOP function with reformat and decimation
 */
 public class icenoop extends Primitive implements Chainable {
 
   private int dec,tl=4096;
   private DataFile hi,ho;
   private Data dbi,dbo;
   private Core core;
 
   public int open() {
 
     dec = MA.getL("DEC",1);
 
     hi = MA.getDataFile ("IN","1000","S#,C#",0);
     hi.open();
 
     ho = MA.getDataFile ("OUT",hi,0);
     ho.setXDelta(hi.getXDelta()*dec);
     ho.open();
 
     core = Core.forName("Noop",MA);
     core.setFormats(hi.getFormat(),ho.getFormat());
     core.set("DECIMATION",dec);
     core.open();
 
     tl = MA.getL("/TL", tl);
     dbi = hi.getDataBuffer(tl);
     dbo = ho.getDataBuffer(tl);
 
     return (NORMAL);
   }
 
   public int process() {
     int n = hi.read(dbi);
     if (n<0) return (FINISH);
     n = core.process (dbi,n, dbo,tl);
     if (n>0) ho.write(dbo,n);
     return (NORMAL);
   }
 
   public int close() {
     core.close();
     hi.close();
     ho.close();
     return (NORMAL);
   }
 
   public Object getNextLink() { return core; }
   public Object getPrevLink() { return null; }
 
 }

Example Calls

Some sample calls for the foo primitive would look as follows:

JDK

nM> fooprim/core=java <arg> <arg> <arg>

CPU

nM> fooprim/core=cpu <arg> <arg> <arg>
nM> fooprim/core=c <arg> <arg> <arg>

ICE

nM> fooprim/core=ice <arg> <arg> <arg>
nM> fooprim/core=ice/coredev=pic1:12 <arg> <arg> <arg>

Core Library