From 7bcde5405026a3b6e38178c44d1fb1b0c7e56457 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 5 Jul 2016 12:33:15 -0700 Subject: [PATCH] Tool for generating CPLD bitstreams in C++ arrays, from SVF file. --- firmware/tools/extract_cpld_data.py | 124 ++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100755 firmware/tools/extract_cpld_data.py diff --git a/firmware/tools/extract_cpld_data.py b/firmware/tools/extract_cpld_data.py new file mode 100755 index 000000000..c44058548 --- /dev/null +++ b/firmware/tools/extract_cpld_data.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python + +# +# Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. +# +# This file is part of PortaPack. +# +# This program 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 2, or (at your option) +# any later version. +# +# This program 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 this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +# Very fragile code to extract data from Altera MAX V CPLD SVF + +import sys + +if len(sys.argv) != 2: + print('Usage: ') + sys.exit(-1) + +f = open(sys.argv[1], 'r') + +calculate_crc = False + +# !PROGRAM +# SIR 10 TDI (203); +# RUNTEST 93 TCK; +# SDR 13 TDI (0000); +# SIR 10 TDI (2F4); +# RUNTEST 93 TCK; +# while: + # SDR 16 TDI (7FFF); + # RUNTEST 1800 TCK; +# SIR 10 TDI (203); +# RUNTEST 93 TCK; +# SDR 13 TDI (0001); +# SIR 10 TDI (2F4); +# RUNTEST 93 TCK; + +phase = None + +block_0 = [] +block_1 = [] +current_block = None + +for line in f: + line = line.strip().upper() + + if line == '!PROGRAM': + phase = 'block_0' + current_block = block_0 + elif line == '!VERIFY': + phase = 'verify' + current_block = None + + if phase == 'block_0': + if line == 'SDR 13 TDI (0001);': + phase = 'block_1' + current_block = block_1 + + if phase == 'block_0' or phase == 'block_1': + if line.startswith('SDR 16 TDI ('): + sdr_value = int(line.split('(', 1)[1][:4], 16) + #print('0x%04x,' % sdr_value) + current_block.append(sdr_value) + +def print_block(block): + for n in range(0, len(block), 8): + chunk = block[n:n+8] + line = ['0x%04x,' % v for v in chunk] + print('\t%s' % ' '.join(line)) + +def crc32(blocks): + import zlib + + crc_bytes = [] + for block in blocks: + for word in block: + crc_bytes.append((word >> 0) & 0xff) + crc_bytes.append((word >> 8) & 0xff) + return zlib.crc32(bytearray(crc_bytes)) & 0xffffffff + +print("""#include "portapack_cpld_data.hpp" + +#include +#include + +namespace portapack { +namespace cpld { +""") + +print('const std::array block_0 { {' % len(block_0)) +print_block(block_0) + +print("""} }; +""") + +print('const std::array block_1 { {' % len(block_1)) +print_block(block_1) + +print("""} }; + +} /* namespace cpld */ +} /* namespace portapack */ +""") + +if calculate_crc: + # Apply post-programming modification to make post-programming CRC correct: + programmed_block_0 = block_0[:] + programmed_block_0[0] &= 0xfbff + + crc = crc32((programmed_block_0, block_1)) + print('%08x' % crc)