dEEP FPGA -kurssia Helsinki Hacklabillä

Suovulan muistipointteja kirjasta Real World FPGA Design with Verilog:


Latches vs. Flipflops
Synchronization
                                                                                                      
                                                                                                      

CPLD-ohjelmointi JTAGWhisperer-ohjelmalla

Esimerkit Windowsiin, mutta kaikki ohjelmat ovat saatavilla myös muihin käyttöjärjestelmiin.

1. JTAGWhisperer-ohjelma Arduinoon

      
2. Python-ympäristön asennus

        http://www.python.org/download/ (python-2.7.2.msi)
        
         http://sourceforge.net/projects/pyserial/ (pyserial-2.5.win32.exe)
        

3. Python-skriptin ja Arduinon yhteistyön testaus

         C:\Users\Jari\Documents\Arduino\libraries\JTAGWhisperer
    
        c:\python27\python send_xsvf -p COM8 xsvf\XC9572XL\DeviceID.xsvf
    
        Ready to send file of size 90 bytes.
        Device is ready.
        Sent:       64 bytes,       26 remaining
        IMPORTANT: SDR check failed.
        IMPORTANT: Failure at instruction #7
        IMPORTANT: Processed 7 instructions.
        IMPORTANT: Checksum 6c2/21.
        Received device quit: Exiting!
        Expected checksum: 10c1/5a.
        Elapsed time: 0.04 seconds.

4. CPLD:n kytkeminen Arduinoon

        Arduino pin  8 = TMS
        Arduino pin  9 = TDI
        Arduino pin 10 = TDO
        Arduino pin 11 = TCK

    
   
5. CPLD:n ohjelmointi

        Ready to send file of size 103964 bytes.
        Device is ready.
        Sent:   103964 bytes,        0 remaining
        IMPORTANT: XCOMPLETE
        IMPORTANT: Processed 11582 instructions.
        IMPORTANT: Checksum 6e06ac/1961c.
        Received device quit: Exiting!
        Expected checksum: 6e06ac/1961c.
        Elapsed time: 43.77 seconds.

--------8<----------------8<----------------8<----------------8<----------------8<--------


enum { BufferSize = 1*1024 };
uint8_t    buffer[BufferSize];

enum {
  SERIAL_DATA       = 3,
  SERIAL_CLK        = 4,
  SERIAL_ENABLE     = 12,
  SERIAL_DELAY      = 10,
};

const uint8_t IntelHEXStartCode = ':';

void HALT(uint8_t) {
   // Kääk -> HALT
   while (true) {
     digitalWrite(13, LOW);
     delay(500);
     digitalWrite(13, HIGH);
     delay(500);
   }  
}


void setup() {                
  
  pinMode(13, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(SERIAL_DATA, OUTPUT);
  pinMode(SERIAL_CLK, OUTPUT);
  pinMode(SERIAL_ENABLE, OUTPUT);

  
  digitalWrite(13, LOW);
  
  // Test static allocation
  for (size_t i = 0; i < BufferSize; ++i) {
    buffer[i] = 0;
  }

  
  
  Serial.begin(9600);
  Serial.flush();      // ??
  while (Serial.available()) Serial.read();   // Clear input
  
  // All Ok
  Serial.print("OK");  
  Serial.println();  
  digitalWrite(13, HIGH);
  
  
  digitalWrite(11, LOW);
  delayMicroseconds(1);
  digitalWrite(11, HIGH);
  
  

}

size_t     bytesReceived = 0;

uint32_t   lastPrintTime = 0;
bool       dirty = false;


uint8_t readHex8() {
  while (Serial.available() < 2) { }; 
  int h1 = Serial.read();
  int h2 = Serial.read();

  uint8_t val = 0;
  if (h1 >= '0' && h1 <= '9') val |= (h1 - '0') << 4;
  if (h1 >= 'a' && h1 <= 'f') val |= (h1 - 'a' + 10) << 4;
  if (h1 >= 'A' && h1 <= 'F') val |= (h1 - 'A' + 10) << 4;
  if (h2 >= '0' && h2 <= '9') val |= (h2 - '0') << 0;
  if (h2 >= 'a' && h2 <= 'f') val |= (h2 - 'a' + 10) << 0;
  if (h2 >= 'A' && h2 <= 'F') val |= (h2 - 'A' + 10) << 0;
  
  return val;
}

uint16_t readHex16BE() {
  uint16_t  b1 = readHex8();
  uint16_t  b2 = readHex8();

  return (b1 << 8) + b2;
}

uint32_t readHex32BE() {
  uint32_t  b1 = readHex8();
  uint32_t  b2 = readHex8();
  uint32_t  b3 = readHex8();
  uint32_t  b4 = readHex8();

  return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
}




uint8_t send_serial_out(uint32_t val, size_t bits) {
  uint8_t even_parity = 0;
  
  digitalWrite(SERIAL_CLK, LOW);
  digitalWrite(SERIAL_ENABLE, HIGH);
  
  for(size_t i = 0; i < bits; i++) { 
    bool bit = (val >> (bits - i - 1)) & 0x1;
    digitalWrite(SERIAL_DATA, bit);  // siirretään taulukko vasemmalta oikealle 
    digitalWrite(SERIAL_CLK, HIGH);
    //delay(SERIAL_DELAY); 
    digitalWrite(SERIAL_CLK, LOW);
    //delay(SERIAL_DELAY); 
    
    even_parity = (even_parity ^ bit) & 0x01;
  }
  digitalWrite(SERIAL_ENABLE, LOW);
  digitalWrite(SERIAL_CLK, LOW);
  
  return even_parity;
}


        // uint8_t send_serial_out(uint8_t table[], size_t tablesize) {



void loop() {
  
  int c = 0;
  
  if (Serial.available()) {
    c = Serial.read();
    if (c == IntelHEXStartCode) {
      uint8_t     byteCount = readHex8();
      uint16_t    address = readHex16BE();
      uint8_t     recordType = readHex8();

       
      if (recordType == 00) {
        
        Serial.print("byteCount = ");  
        Serial.print(byteCount);  
        Serial.print(" address = ");  
        Serial.print(address);  
        Serial.print(" recordType = ");  
        Serial.print(recordType);  
        
        // Data
        for (size_t i = 0; i < byteCount; ++i) {
          buffer[i] = readHex8();
        }

        // Tässä näin..
        for (size_t i = 0; i < byteCount; ++i) {
          send_serial_out((uint32_t(address + i) << 8) | buffer[i], 15+8);
        }
       
        Serial.print(" <> ");  
        
        
        bytesReceived += byteCount;
        
      } else if (recordType == 01) {
        // End Of File
        Serial.println("<EOF>");  
        for (size_t i = 0; i < byteCount; ++i) readHex8();
        
        dirty = true;
      } else {
        //Serial.print("Unknown record");  
        for (size_t i = 0; i < byteCount; ++i) readHex8();
      }

      uint8_t    checksum = readHex8();

      /*
      Serial.print(" checksum = ");  
      Serial.print(int(checksum));  
      Serial.println();  
      */
    } else {
      // Skip  
      //Serial.print("unknown char = ");  
      //Serial.print(int(c));  
      //Serial.println();  
    }
  }
  
  if (dirty && (millis() - lastPrintTime) > 5000) {
    Serial.print("OK ");  
    Serial.print(bytesReceived);  
    Serial.print(" bytes received");  
    Serial.println();  
    
    lastPrintTime = millis();
    dirty = false;
    
  }
 
  
  
}