├── example └── reject_syntax.txt ├── .gitignore ├── config.ini ├── LICENSE ├── xilinx_coe_generator.py └── README.md /example/reject_syntax.txt: -------------------------------------------------------------------------------- 1 | 0x0=42815555 * 10 lalala 2 | 0x10 = 30222211 3 | 20213211 * 20 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-project 2 | *.sublime-workspace 3 | *_test.* 4 | *.bak 5 | *.html 6 | *.htm -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | ; value in USER section overwrite the default config value 2 | [USER] 3 | 4 | 5 | ; The value in DEFAULT section shall be left untouched 6 | [DEFAULT] 7 | ; The input file name written with defined syntax 8 | INPUT_FILE = example/normal.txt 9 | ; The file name for output coe file 10 | OUTPUT_FILE = output/output.coe 11 | 12 | ; the maximum range for each bit, 16 for hex 13 | ACCEPT_RADIX = 16 14 | ; maximum size of the targetted RAM 15 | MAX_SIZE = 150000 16 | ; default data for the remaining data of RAM 17 | DEFAULT_DATA = 0 18 | ; number of datas in each line of coe output, wont affect Xilinx RAM but affect our readability 19 | NUM_DATA_EACH = 10 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Xilinx COE Generator Contributor 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /xilinx_coe_generator.py: -------------------------------------------------------------------------------- 1 | import re 2 | from shutil import copyfile 3 | import configparser 4 | 5 | # Loading available config 6 | config = configparser.ConfigParser() 7 | config.read('config.ini') 8 | 9 | if 'USER' in config: 10 | allSetting = config['USER'] 11 | INPUT_FILE = allSetting.get('INPUT_FILE') 12 | OUTPUT_FILE = allSetting.get('OUTPUT_FILE') 13 | ACCEPT_RADIX = allSetting.get('ACCEPT_RADIX') 14 | MAX_SIZE = allSetting.getint('MAX_SIZE') 15 | DEFAULT_DATA = allSetting.get('DEFAULT_DATA') 16 | NUM_VALUE_EACH = allSetting.getint('NUM_VALUE_EACH') 17 | else: 18 | print('Error: Please make sure that config.ini is accessible and both [USER] and [DEFAULT] sections exist in it.. Exiting..') 19 | exit() 20 | 21 | ## end of setting 22 | 23 | try: 24 | with open(INPUT_FILE) as fp: 25 | lines = fp.read().split("\n") 26 | except IOError: 27 | print("Error: The INPUT_FILE does not exist.. exiting..") 28 | exit() 29 | 30 | try: 31 | with open(OUTPUT_FILE) as fp: 32 | pass 33 | copyfile(OUTPUT_FILE, '{}.bak'.format(OUTPUT_FILE)) 34 | except: 35 | pass 36 | 37 | try: 38 | fp = open(OUTPUT_FILE, 'w') 39 | except IOError: 40 | print("Error: Cannot open the OUTPUT_FILE for write.. exiting..") 41 | exit() 42 | 43 | numLines = 1 44 | addr = 0 45 | wordArray = [DEFAULT_DATA]*(MAX_SIZE-1) 46 | 47 | for line in lines: 48 | line = line.strip() 49 | reObj = re.search('^0x([0-9a-fA-F]+) *?= *?([0-9a-fA-F]+) *?\* *?([0-9]+)$', line) 50 | if reObj: 51 | if addr != 0: 52 | print('stop at 0x{:02X}'.format(addr-1)) #because add 1 after saving ram 53 | addr = int(reObj.group(1), 16) 54 | print('Start at 0x{}, '.format(reObj.group(1)), end='') 55 | # seeking to there. 56 | numEnd = int(reObj.group(3)) 57 | for i in range(0, numEnd): 58 | wordArray[addr] = reObj.group(2) 59 | addr+=1 60 | i+=1 61 | else: 62 | reObj = re.search('^0x([0-9a-fA-F]+) *?= *?([0-9a-fA-F]+)$', line) 63 | if reObj: 64 | if addr != 0: 65 | print('stop at 0x{:02X}'.format(addr-1)) 66 | addr = int(reObj.group(1), 16) 67 | print('Start at 0x{}, '.format(reObj.group(1)), end='') 68 | # seeking to there. 69 | wordArray[addr] = reObj.group(2) 70 | addr+=1 71 | else: 72 | reObj = re.search('^([0-9a-fA-F]+) *?\* *?([0-9]+)$', line) 73 | if reObj: 74 | numEnd = int(reObj.group(2)) 75 | for i in range(0, numEnd): 76 | wordArray[addr] = reObj.group(1) 77 | addr+=1 78 | else: 79 | reObj = re.search('^([0-9a-fA-F]+)$', line) 80 | if reObj: 81 | wordArray[addr] = reObj.group(1) 82 | addr+=1 83 | else: 84 | print('Warning: The syntax \"{}\" at line {} is not accepted'.format(line, numLines)) 85 | numLines+=1 86 | print('stop at 0x{:02X}'.format(addr-1)) 87 | 88 | fp.write( 89 | """; This coe file is generated using third party script 90 | ; maintained at the github repository 91 | ; By using this script, you are considered 92 | ; as accepted the disclaimer and MIT license specified on 93 | ; https://github.com/kooltzh/xilinx-coe-generator 94 | 95 | """) 96 | fp.write('memory_initialization_radix={};\n'.format(ACCEPT_RADIX)) 97 | fp.write('memory_initialization_vector=') 98 | 99 | current = 0 100 | for word in wordArray: 101 | if current == 9: 102 | fp.write("{}\n".format(word)) 103 | current = 0 104 | else: 105 | fp.write("{} ".format(word)) 106 | current = current + 1 107 | 108 | fp.write(";") 109 | fp.close() 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Xilinx RAM COE Generator 2 | ## Overview 3 | This third party python script with no dependency other than native python package is used to generate Xilinx *.coe files for RAM data initializing 4 | 5 | Xilinx RAM COE files aka coefficient files is used to initiate the data associated with their addresses inside Block RAM or other types of RAM. 6 | 7 | The reference for Xilinx *.coe files can be found here at [COE File Syntax](https://www.xilinx.com/support/documentation/sw_manuals/xilinx11/cgn_r_coe_file_syntax.htm) on Xilinx support website. 8 | 9 | ## Motivation 10 | Although it is possible to use one RAM controller for each data with large FPGA setup, saving multiple data on single RAM usually costs us less resource requirement and provides routing simplicity thus decreasing development time. However, this usually comes with the expenses of doing [Memory Mapping](https://en.wikipedia.org/wiki/Memory_map) on available variables. 11 | 12 | The *coe files is read and write in linear fashion, ie. it will start from address 0x0 all the ways until 0x100000 (your end). Therefore, saving a series of data starting from arbitary addresses (eg. 0x1A32) usually is a hard task as we might need to count the data manually. 13 | 14 | Besides, data collision in same address is also possible as chucks of data might overlap with each other 15 | 16 | This python script is use to translate addresses and data specified by the input file, then arrange them to generate *.coe files 17 | 18 | ## Using it 19 | * Clone or download the repository 20 | * Update the config.ini files 21 | * Write your own input file using the syntax specified at the following section 22 | * run `python xilinx-coe-generator.py` 23 | 24 | ## Available setting in config.ini 25 | 26 | Default setting values is defined in the `[default]` section, user can overwrite the setting in `[user]` section 27 | ```ini 28 | ; value in USER section overwrite the default config value 29 | [USER] 30 | INPUT_FILE = example/my_new_file.txt 31 | 32 | ; The value in DEFAULT section shall be left untouched 33 | [DEFAULT] 34 | ; The input file name written with defined syntax 35 | INPUT_FILE = example/normal.txt 36 | ; The file name for output coe file 37 | OUTPUT_FILE = output.coe 38 | 39 | ; the maximum range for each bit, 16 for hex 40 | ACCEPT_RADIX = 16 41 | ; maximum size of the targetted RAM 42 | MAX_SIZE = 150000 43 | ; default data for the remaining data of RAM 44 | DEFAULT_DATA = 0 45 | ; number of datas in each line of coe output, wont affect Xilinx RAM but affect our readability 46 | NUM_DATA_EACH = 10 47 | ``` 48 | 49 | This will cause the script to take "example/my_new_file.txt" as input, then follow default value for other variables. 50 | 51 | ## Documentation 52 | This python script is developed on python 3.7.1 on Ubuntu 18.04 LTS 53 | 54 | ### Accepted syntaxes for input files 55 | Here are 4 of the syntaxes acceptable for this script 56 | The spaces in between ` = ` or ` * ` is optional. 57 | ``` 58 | 0x[address] = [data] * [number of repeat] 59 | 0x[address] = [data] 60 | [data] * [number of repeat] 61 | [data] 62 | ``` 63 | In the following sections, please note that we will be using w/ "0x" for address, w/o "0x" for data. Both are in hexadecimal. 64 | 65 | 66 | Syntax: 67 | ``` 68 | 0x[address] = [data] 69 | ``` 70 | 71 | Eg. Saving data `0xAB3432` into address `0x123AB` shall be 72 | ``` 73 | 0x123AB = AB3432 74 | ``` 75 | 76 | ### Saving chucks of data 77 | To save this chuck of data one after another 78 | 79 | |Address|Data| 80 | |---|---| 81 | |0x10|0x20| 82 | |0x11|0x21| 83 | |...|...| 84 | |0x1F|0x2F| 85 | 86 | Shall be written like this in input file 87 | ``` 88 | 0x10 = 20 89 | 21 90 | 22 91 | ... 92 | 2F 93 | ``` 94 | 95 | ### Saving repetitive data 96 | One can use " * " as indicator for repetitive data. Notes that \[ number of repeat \] is in decimal of base 10 97 | 98 | Syntax: 99 | ``` 100 | 0x[address] = [data] * [number of repeat] 101 | ``` 102 | 103 | Eg. saving 12 data with value of `0xABC` in address range of `0x110 to 0x11C` 104 | ``` 105 | 0x110 = ABC * 12 106 | ``` 107 | 108 | |Address|Data| 109 | |---|---| 110 | |0x110|0xABC| 111 | |0x111|0xABC| 112 | |...|...| 113 | |0x11B|0xABC| 114 | 115 | ### Using two types of syntax together 116 | It is also possible to generate repeative values after assigning address on previous line. 117 | ``` 118 | 0x100 = 1102321C 119 | 20932123 120 | 32212CDA * 3 121 | BC312212 122 | ``` 123 | 124 | Will result in 125 | 126 | |Address|Data| 127 | |---|---| 128 | |0x100|0x1102321C| 129 | |0x101|0x20932123| 130 | |0x102|0x32212CDA| 131 | |0x103|0x32212CDA| 132 | |0x104|0x32212CDA| 133 | |0x105|0xBC312212| 134 | 135 | 136 | ## Using examples 137 | 138 | Will be added in the future 139 | 140 | ## To do list 141 | * [ ] Accepting comment in input file 142 | * [ ] Adding more example 143 | * [ ] Adding command line interface (CLI) support 144 | * [ ] Adding Collision alert. ie. warning for saving multiple data on same address 145 | * [ ] Reading files directly as binary 146 | 147 | ## Disclaimer 148 | Although the contributor of this project had made every attempt to ensure the best possible accuracy of this script. However, this python script is provided "as is" without warranty of any kind. The contributor does not take any responsibility or liability for the damage of lost caused by the usage of this script. 149 | 150 | By using this script, you are hereby agree to the condition stated in the disclaimer section of this project. 151 | 152 | ## Wrapping up! 153 | This project is maintained as side project of an undergraduate. So updates might come a bit occasionally 154 | 155 | For any issues, please submit an [issues](https://github.com/kooltzh/xilinx-coe-generator/issues) or contact the author at kooltzh@gmail.com 156 | 157 | ## Contributing 158 | Have all the fun forking the repository, check out, then submit your new feature as pull request, 159 | I will be more than happy to accept it :D --------------------------------------------------------------------------------