/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: HP80000.java * Written by David Hopkins, Sun Microsystems. * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */ package com.sun.electric.tool.simulation.test; public class HP80000 extends Equipment { public static int SYSTEM=0, SYSTEMCLOCK=1, DATAGEN1GHZ=2, DG1GHZ128K=3; private int selectedInst; /** * Creates a new instance of HP80000 * @param name */ public HP80000(String name) { super(name); selectInstrument(HP80000.SYSTEM); } public void reset() { write("*CLS"); write("*RST"); try { Thread.sleep(300); } catch (InterruptedException _) { } } public void start() { write(":INST:SEL SYSTEMCLOCK"); write(":TRIG:STAR"); try { Thread.sleep(100); } catch (InterruptedException _) { } } public void stop() { write(":INST:SEL SYSTEMCLOCK"); write(":TRIG:STOP"); try { Thread.sleep(100); } catch (InterruptedException _) { } } public void pause() { write(":INST:SEL SYSTEMCLOCK"); write(":TRIG:PAUS"); try { Thread.sleep(100); } catch (InterruptedException _) { } } public void cont() { write(":INST:SEL SYSTEMCLOCK"); write(":TRIG:CONT"); try { Thread.sleep(100); } catch (InterruptedException _) { } } /** * Select an instrument. Most commands must be run after selecting * the proper instrument. * @param inst the instrument */ public void selectInstrument(int inst) { write(":INST:SEL "+instToString(inst)); selectedInst = inst; } private String instToString(int inst) { switch(inst) { case 0: return "System"; case 1: return "SystemClock"; case 2: return "DATAGEN1GHZ"; case 3: return "DG1GHZ128K"; } return "Unknown"; } // ------------------------- System Clock ------------------------- /** * Set the clock source to internal or external. * @param internal true for internal, false for external */ public void setClockSource(boolean internal) { if (!isSelectedInstSystemClock()) return; if (internal) write(":CLOC:SOUR INT"); else write(":CLOC:SOUR EXT"); } /** * Set the internal system clock frequency. Default value is 1GHz. * The frequency will be set to the nearest available frequency setting. * The available range is 7.8125 MHz to 1 GHz. * @param freq the frequency * @param units the units: "M" or "KHz" or "MHz". */ public void setClockFrequency(double freq, String units) { if (!isSelectedInstSystemClock()) return; if (!units.toLowerCase().endsWith("hz")) units = units + "HZ"; write(":CLOC:INT:FREQ "+freq+" "+units); } // ----------------------- Managing Groups -------------------------- public void printGroups() { if (!isSelectedInstDataGen()) return; write(":DIG:GRO:CAT?"); String s = read(200); System.out.println("Groups: "+s); } /** * Define a group and assign channels to the group. The instrument must * be a DATAGEN1GHZ or DG1GHZ128K; the group name is whatever you choose, * and the slotsAndChannels argument sets which channels on which slots (modules) * are assigned to this group. * <P> * For example, the following strings all assign channels 0 to 3 on slot 0 * and slot 2 to this group: * <pre> * Individual Logical Channels: * 0,1,2,3,8,9,10,11 * Logical Channel Ranges: * 0:3,8:11 * Module slot and channel: * 0(0:3),2(0:3) * </pre> * * @param groupName a new group name * @param slotsAndChannels the slots and channels */ public void defineGroup(String groupName, String slotsAndChannels) { if (!isSelectedInstDataGen()) return; write(":DIG:GRO:DEF "+groupName+",(@"+slotsAndChannels+")"); } /** * Delete the group on the instrument. Note that the group "ALL" will delete all groups * @param groupName which group to delete */ public void deleteGroup(String groupName) { if (!isSelectedInstDataGen()) return; if (groupName.equals("ALL")) write(":DIG:GRO:DEL:ALL"); else write(":DIG:GRO:DEL "+groupName); } /** * Select given group for currently selected instrument * (currently selected instrument must be DATAGEN1GHZ or DG1GHZ128K) * Note that the group "ALL" will select ALL groups. Also, * the group "NONE" will select no groups, and all subsequent group-oriented * commands will be disabled. * @param groupName which group */ public void selectGroup(String groupName) { if (!isSelectedInstDataGen()) return; write(":DIG:GRO:SEL "+groupName); } // ------------------- Group Level Commands for Data Gen ---------------- /** * Set the pattern cycling for the currently selected group. Note that * this does not set the actual pattern itself, only the number of bits * and cycling of the pattern. Note that start+length must be les than 16384. * @param startLength number of start bits at start, generated once, must be 0 or 4 or more * @param cycleLength number of repeated bits, must be 0 or multiple of 8 * @param cycleTimes number of times to loop, 0 to 255, or -1 for infinite looping */ public void setGroupPatternCycle(int startLength, int cycleLength, int cycleTimes) { if (!isSelectedInstDataGen()) return; String l = cycleTimes < 0 ? "INF" : String.valueOf(cycleTimes); if (startLength < 4 && startLength != 0) { System.out.println("Error: pattern cycle start value must be 0, or 4 or more"); return; } if (cycleLength % 8 != 0) { System.out.println("Error: pattern cycle length value must be 0 or multiple of 8"); return; } if (cycleTimes > 255) { System.out.println("Warning: pattern cycle loop value maximum is 255, dropping "+cycleTimes+" to 255"); cycleTimes = 255; } write(":PATT:CYCL "+startLength+","+cycleLength+","+l); try { Thread.sleep(100); } catch (InterruptedException _) { } } /** * Set the data for the current group. The array size must equal the number of * channels in the group. The length of the binData Strings must equal the number * of bits in the sequence. The string format is binary, for example, "010010110". * @param binData the binary data sequences for each channel. */ public void setGroupData(String [] binData) { if (!isSelectedInstDataGen()) return; if (binData.length == 0) return; int numChannels = binData.length; int datalen = binData[0].length(); for (int i=0; i<binData.length; i++) { if (binData[i].length() != datalen) { System.out.println("Error: in setData, all arrays must be the same length"); return; } } for (int i=0; i<datalen; i++) { StringBuffer cmd = new StringBuffer(); cmd.append(":PATT:MOD "); cmd.append(i); cmd.append(",#B"); for (int j=numChannels-1; j >= 0; j--) { cmd.append(binData[j].charAt(i)); } write(cmd.toString()); try { Thread.sleep(100); } catch (InterruptedException _) { } //System.out.println("wrote: "+cmd.toString()); } write(":PATT:UPD"); try { Thread.sleep(100); } catch (InterruptedException _) { } } /** * Print data for signal in a group. Unfortunately this only seems to * work if there is only one signal in a group * @param start * @param end * @param numSignals */ public void printGroupData(int start, int end, int numSignals) { if (!isSelectedInstDataGen()) return; write(":FORM ASC,"+numSignals); write(":PATT:MOD? "+start+","+end); String s = read(400); System.out.println(s); /* String vectors [] = s.split(","); for (int i=0; i<numSignals; i++) { System.out.print("Signal"+i+": "); int mask = 1 << i; for (int j=0; j<vectors.length; j++) { if ((Integer.valueOf(vectors[j]) & mask) == 0) System.out.print("0"); else System.out.print("1"); } System.out.println(); } */ } /** * Set the data for the given channel * @param signal which signal in the group * @param dataPat string of 1's and 0's of length "length" specified by setPatternCycle * @deprecated can't get it to work */ private void setPatternData(int signal, String dataPat) { if (!isSelectedInstDataGen()) return; write(":FORM PACK,1"); write(":PATT:DATA"+signal+" "+dataPat); write(":PATT:UPD"); } /** * Print the data for the given channel * @param signal which signal in the group * @param start start * @param end end * @deprecated useless */ private void printPatternData(int signal, int start, int end) { if (!isSelectedInstDataGen()) return; write(":FORM HEX,8"); //write(":PATT:DATA"+signal+"?"); //write(":PATT:DATA?"); write(":PATT:DATA"+signal+"? "+start+","+end); try { Thread.sleep(2000); } catch (InterruptedException _) { } String s = read(600); System.out.println("Data for signal "+signal+" is: (len="+s.length()+")"); System.out.println(s); } /** * Set the signal format for the currently selected Group * Note that there is only one signal polarity setting for a module, so other * groups on the same module will also be affected. * @param NonReturntoZero true to set to non-return-to-zero, false to set return-to-zero */ public void setSignalFormat(boolean NonReturntoZero) { if (!isSelectedInstDataGen()) return; if (NonReturntoZero) write(":SIGN:FORM NRZ"); else write(":SIGN:FORM RZ"); } /** * Set the signal polarity (normal or inverted) for all signals * in the currently selected Group. * @param normal true for normal, false for inverted */ public void setGroupSignalPolarity(boolean normal) { setGroupSignalPolarity(-1, normal); } /** * Set the signal polarity (normal or inverted) for a signal * in the currently selected Group. * @param signal which signal in the group, or -1 for all signals * @param normal true for normal, false for inverted */ public void setGroupSignalPolarity(int signal, boolean normal) { if (!isSelectedInstDataGen()) return; String s = signal < 0 ? "" : String.valueOf(signal); if (normal) write(":SIGN:POL"+s+" NORM"); else write(":SIGN:POL"+s+" INV"); } /** * Turn on or off the output state * (whether output is enabled) for all signals in the currently selected Group. * @param on true to enable, false to disable */ public void setOutputState(boolean on) { setOutputState(-1, on); } /** * Turn on or off the output state * (whether output is enabled) for the signal in the currently selected Group. * Or, set signal to -1 to set the state for all signals in the group. * @param signal -1 for all signals, or which signal in the currently selected group. * @param on true to enable, false to disable */ public void setOutputState(int signal, boolean on) { if (!isSelectedInstDataGen()) return; String s = signal < 0 ? "" : String.valueOf(signal); if (on) write(":OUTP"+s+" ON"); else write(":OUTP"+s+" OFF"); } /** * Set the output termination for all signals in the currently selected group * The state can be one of the following: * <pre> * 0: 50 ohms terminated to ground (GROUND) * 1: 50 ohms terminated to -2V (ECL) * 2: 50 ohms terminated to +3V (PECL) * 3: open circuit (OPEN) * </pre> * Note that the output state must be switched off to change this setting * @param state which termination to set */ public void setOutputTermination(int state) { setOutputTermination(-1, state); } /** * Set the output termination for the signal in the currently selected group, * or all signals in the group if signal is -1. * The state can be one of the following: * <pre> * 0: 50 ohms terminated to ground (GROUND) * 1: 50 ohms terminated to -2V (ECL) * 2: 50 ohms terminated to +3V (PECL) * 3: open circuit (OPEN) * </pre> * Note that the output state must be switched off to change this setting * @param signal which signal in the group, or -1 for all signals in the group * @param state which termination to set */ public void setOutputTermination(int signal, int state) { if (!isSelectedInstDataGen()) return; String s = signal < 0 ? "" : String.valueOf(signal); switch (state) { case 0: write(":OUTP"+s+":TERM GRO"); break; case 1: write(":OUTP"+s+":TERM ECL"); break; case 2: write(":OUTP"+s+":TERM PECL"); break; case 3: write(":OUTP"+s+":TERM OPEN"); break; default: System.out.println("State "+state+" is not a valid output termination state"); } } /** * Set the delay of a signal in the currently selected group. * The valid range is -2000 to +2000 ps * @param ps how many picoseconds to delay the data relative to the clock */ public void setGroupDelay(int ps) { setGroupDelay(-1, ps); } /** * Set the delay of a signal in the currently selected group. * The valid range is -2000 to +2000 ps. Reset value is 0. * @param signal which signal in the currently selected group, -1 for all signals * @param ps how many picoseconds to delay the data relative to the clock */ public void setGroupDelay(int signal, int ps) { if (!isSelectedInstDataGen()) return; String s = signal < 0 ? "" : String.valueOf(signal); if (ps < -2000 || ps > 2000) { System.out.println("Valid range for group delay is -2000ps to 2000ps: not "+ps); return; } write(":SOUR:PULS:DEL"+s+" "+ps+" PS"); } /** * Set the high voltage level for all signals in the currently selected group * Reset value is +1V. Range depends on termination and Low value setting. * The difference between high and low is constrained such that: * <pre> * Term Min and Max Magnitude of Voltage Swing * Ground 0.5V <= (High - Low) <= 2.5V * ECL 0.5V <= (High - Low) <= 2.5V * PECL 0.5V <= (High - Low) <= 2.5V * OPEN 1.0V <= (High - Low) <= 5.0V * </pre> * Absolute limits are: * <pre> * Term Limits * Ground -1.5V to 3.0V * ECL -1.5V to 1.0V * PECL 0V to 4.5V * OPEN -2.5V to 4.5V * </pre> * Note that the output state must be switched off to change this setting * @param voltage the voltage for a high value */ public void setGroupHighVoltageLevel(double voltage) { setGroupHighVoltageLevel(-1, voltage); } /** * Set the high voltage level for a signal in the currently selected group * Reset value is +1V. Range depends on termination and Low value setting. * The difference between high and low is constrained such that: * <pre> * Term Min and Max Magnitude of Voltage Swing * Ground 0.5V <= (High - Low) <= 2.5V * ECL 0.5V <= (High - Low) <= 2.5V * PECL 0.5V <= (High - Low) <= 2.5V * OPEN 1.0V <= (High - Low) <= 5.0V * </pre> * Absolute limits are: * <pre> * Term Limits * Ground -1.5V to 3.0V * ECL -1.5V to 1.0V * PECL 0V to 4.5V * OPEN -2.5V to 4.5V * </pre> * Note that the output state must be switched off to change this setting * @param signal which signal in the currently selected group, -1 for all signals * @param voltage the voltage for a high value */ public void setGroupHighVoltageLevel(int signal, double voltage) { if (!isSelectedInstDataGen()) return; String s = signal < 0 ? "" : String.valueOf(signal); write(":SOUR:VOLT:LEV:IMM:HIGH"+s+" "+voltage+" V"); } /** * Set the low voltage level for all signals in the currently selected group * Reset value is -1V. Range depends on termination and High value setting. * The difference between high and low is constrained such that: * <pre> * Term Min and Max Magnitude of Voltage Swing * Ground 0.5V <= (High - Low) <= 2.5V * ECL 0.5V <= (High - Low) <= 2.5V * PECL 0.5V <= (High - Low) <= 2.5V * OPEN 1.0V <= (High - Low) <= 5.0V * </pre> * Absolute limits are: * <pre> * Term Limits * Ground -1.5V to 3.0V * ECL -1.5V to 1.0V * PECL 0V to 4.5V * OPEN -2.5V to 4.5V * </pre> * Note that the output state must be switched off to change this setting * @param voltage the voltage for a high value */ public void setGroupLowVoltageLevel(double voltage) { setGroupLowVoltageLevel(-1, voltage); } /** * Set the low voltage level for a signal in the currently selected group * Reset value is -1V. Range depends on termination and High value setting. * The difference between high and low is constrained such that: * <pre> * Term Min and Max Magnitude of Voltage Swing * Ground 0.5V <= (High - Low) <= 2.5V * ECL 0.5V <= (High - Low) <= 2.5V * PECL 0.5V <= (High - Low) <= 2.5V * OPEN 1.0V <= (High - Low) <= 5.0V * </pre> * Absolute limits are: * <pre> * Term Limits * Ground -1.5V to 3.0V * ECL -1.5V to 1.0V * PECL 0V to 4.5V * OPEN -2.5V to 4.5V * </pre> * Note that the output state must be switched off to change this setting * @param signal which signal in the currently selected group, -1 for all signals * @param voltage the voltage for a high value */ public void setGroupLowVoltageLevel(int signal, double voltage) { if (!isSelectedInstDataGen()) return; String s = signal < 0 ? "" : String.valueOf(signal); write(":SOUR:VOLT:LEV:IMM:LOW"+s+" "+voltage+" V"); } //------------------------------------------------------------------------------ private void printResponse() { String s = read(200); System.out.println(s); } private boolean isSelectedInstSystem() { if (selectedInst != HP80000.SYSTEM) { System.out.println("Error, issuing SYSTEM related command when currently " + "selected instrument is not SYSTEM"); return false; } return true; } private boolean isSelectedInstSystemClock() { if (selectedInst != HP80000.SYSTEMCLOCK) { System.out.println("Error, issuing SYSTEMCLOCK related command when currently " + "selected instrument is not SYSTEMCLOCK"); return false; } return true; } private boolean isSelectedInstDataGen() { if (selectedInst != HP80000.DATAGEN1GHZ && selectedInst != HP80000.DG1GHZ128K) { System.out.println("Error, issuing DATAGEN1GHZ/DG1GHZ128K related command when currently " + "selected instrument is not DATAGEN1GHZ/DG1GHZ128K"); return false; } return true; } private void printErrorQueue() { write(":SYST:ERR?"); String s = read(200); System.out.println(s); } // ------------------------------- Main --------------------------------- public static void main(String args[]) { // which gpib controller (ethernet-to-gpib box) the HP80000 is connected to Infrastructure.gpibControllers = new int[]{2}; // create instrument based on assigned name in ibconf program on electron HP80000 datagen = new HP80000("HP80000"); datagen.reset(); datagen.selectInstrument(HP80000.DG1GHZ128K); datagen.deleteGroup("ALL"); datagen.defineGroup("foo", "0(2:3)"); datagen.printGroups(); datagen.selectGroup("foo"); datagen.setGroupPatternCycle(4, 8, 1); String [] data = new String [] { "000100110111", "100011001000" }; datagen.printGroupData(0, 12, 2); datagen.setGroupData(data); datagen.deleteGroup("ALL"); datagen.defineGroup("clk", "0(2)"); datagen.printGroups(); datagen.selectGroup("clk"); datagen.setGroupPatternCycle(0, 16, -1); datagen.setGroupData(new String [] { "0000111111110000" }); datagen.printGroupData(0, 15, 1); System.out.println("done"); } }