import com.xilinx.util.JBitsCommandLineApp;

import com.xilinx.JBits.CoreTemplate.*;

import com.xilinx.JBits.Virtex.RTPCore.SizeException;

import com.xilinx.JBits.Virtex.Devices;
import com.xilinx.JBits.Virtex.JBits;

import com.xilinx.JRoute.Virtex.Router.JRoute;

import com.xilinx.Netlist.SYM.*;

import com.xilinx.JBits.Virtex.RTPCore.Basic.Clock;

public class TestCore extends JBitsCommandLineApp  
{
 
    /* Define this for debug purposes only */
    boolean debug = true;
    
    /** This method creates and places the RTPCores */
    public void
        run() {
       

        try
            {

                JRoute jroute;
                 

                int ROW = 8;
                int COL = 2;
                int WORD_WIDTH = 8;
                int NO_TAPS = 4;

                int [] constants;
                constants = new int[NO_TAPS];
                constants[0]= 1;
                constants[1]= 1;
                constants[2]= 1;
                constants[3]= 1;
         

                Offset shiftOffset;
                Offset dalutOffset;
                Offset counterOffset;
                

                if(debug)
                    // verbose mode routing
                    jroute = new JRoute(jbits,System.out); 
                else
                    jroute = new JRoute(jbits);

                Bitstream.setVirtex(jbits, jroute);
                CoreOutput.generateBitstream(true);
                CoreOutput.generateEDIF(false);
                CoreOutput.generateSYM(true);

                /* Create Top level net and bus */
                Net clk = new Net("clk",null);
                Net load = new Net("load",null);
                Bus Din = new Bus("DataIN",null,WORD_WIDTH);
                Bus Dout = new Bus("DataOUT",null,NO_TAPS);
                Bus DALUTout = new Bus("DALUTout",null,WORD_WIDTH);
                /* Create Clock Core */
                Clock clock = new Clock("clock", clk);

                /* Create  cores */
                Shift2D shifter;
                Dalut dalut;
                JCounter counter;
                
         
             
                shifter = new Shift2D("Shifter",clk,Dout,Din,load);
                dalut = new Dalut("DALUT",constants,clk,DALUTout,Dout);
                counter = new  JCounter("Counter", 4, clk, load);/* Must be changed to a generic no of bits */
                
       
         
                if(debug)
                    dalut.test_parm();
         
                /* Place the core on row and col position*/
                shiftOffset = shifter.getRelativeOffset();
                shiftOffset.setVerOffset(Gran.CLB,ROW);
                shiftOffset.setHorOffset(Gran.CLB,COL);

                dalutOffset = dalut.getRelativeOffset();
                dalutOffset.setVerOffset(Gran.CLB,ROW);
                dalutOffset.setHorOffset(Gran.CLB,COL+(WORD_WIDTH/2));

                counterOffset = counter.getRelativeOffset();
                counterOffset.setVerOffset(Gran.CLB,ROW+1);
                counterOffset.setVerOffset(Gran.SLICE,0);
                counterOffset.setHorOffset(Gran.CLB,COL);


                /* Implement RTPCores */
                clock.implement(0); // Use GCLK0
                shifter.implement();
                dalut.implement();
                counter.implement();
                
         
         
                /* Connect Top level nets */
                try {
                 
                    Bitstream.connect(Dout);
                    Bitstream.connect(load);
                    if(debug)
                        System.out.println("Connecting Clock");
                    
                    Bitstream.connect(clk);

                                  
         
                } catch ( ConnectionException e) {
                    e.printStackTrace();
                    System.exit(-1);
                }




                /* 
                 * Define SYM pins.
                 */
                try {
                                SYM.add(clk);
                    //            SYM.add(load);
                    //           SYM.add(Din);
                    SYM.add(Dout);
                    SYM.add(DALUTout);
                    SYM.add(load);
                    
           

                } catch (SYMexception se) {
                    System.out.println(se);
                }

                CoreOutput.writeSymFile("Shifter2D.sym");


            }
        catch(Exception e)
            {

                System.out.println(e);
                System.exit(-1);
            }

        //         catch (SizeException se) {
        //             se.printStackTrace();
        //             System.exit(-1);
        //         }

    }
    

    /* main program */
    public static void 
        main(String args[]) {
        TestCore app = new TestCore();
        app.appName="Test DA core";
        app.parseCommandLine(args);
        app.makeJBits();
        System.out.println("running...");
        app.run();
        app.writeBitstream();

    } /* end main() */
    
}
    
