145 lines
3.8 KiB
Python
145 lines
3.8 KiB
Python
#!/usr/bin/python3
|
|
import json
|
|
import sys
|
|
|
|
"""
|
|
This file uses csr.json and csr_bitwidth.json and writes functions
|
|
that handle reads and writes to MMIO.
|
|
"""
|
|
|
|
class CSRGenerator:
|
|
def __init__(self, csrjson, bitwidthjson, registers, outf, dacmax, adcmax):
|
|
self.registers = registers
|
|
self.csrs = json.load(open(csrjson))
|
|
self.bws = json.load(open(bitwidthjson))
|
|
self.file = outf
|
|
self.dacmax = dacmax
|
|
self.adcmax = adcmax
|
|
|
|
def get_reg(self, name, num):
|
|
if num is None:
|
|
regname = f"base_{name}"
|
|
else:
|
|
regname = f"base_{name}_{num}"
|
|
return self.csrs["csr_registers"][regname]["addr"]
|
|
|
|
def get_bitwidth_type(self, name):
|
|
b = self.bws[name]
|
|
if b <= 8:
|
|
return 8
|
|
elif b <= 16:
|
|
return 16
|
|
elif b <= 32:
|
|
return 32
|
|
elif b <= 64:
|
|
return 64
|
|
else:
|
|
raise Exception('unsupported width', b)
|
|
|
|
def print(self, *args):
|
|
print(*args, end='', file=self.file)
|
|
|
|
def print_write_fun(self, name, regnum):
|
|
typ = self.get_bitwidth_type(name)
|
|
self.print('static inline void\n')
|
|
self.print(f'write_{name}(uint{typ}_t v')
|
|
|
|
if regnum != 1:
|
|
self.print(f', int num')
|
|
self.print(')\n{\n')
|
|
|
|
if regnum != 1:
|
|
self.print('\t', f'static const uintptr_t loc[{regnum}]', '= {\n')
|
|
self.print('\t\t', self.get_reg(name,0), '\n')
|
|
for i in range(1,regnum):
|
|
self.print('\t\t,', self.get_reg(name, i), '\n')
|
|
self.print('\t};\n')
|
|
self.print('''
|
|
if (num < 0 || num >= ARRAY_SIZE(loc)) {
|
|
LOG_ERR("invalid location %d", num);
|
|
k_fatal_halt(K_ERR_KERNEL_OOPS);
|
|
}
|
|
''')
|
|
self.print('\t', f'litex_write{typ}(v, {"loc[num]" if regnum != 1 else self.get_reg(name, None)});', '\n}\n\n')
|
|
|
|
def print_read_fun(self, name, regnum):
|
|
typ = self.get_bitwidth_type(name)
|
|
self.print(f'static inline uint{typ}_t\nread_{name}')
|
|
|
|
if regnum != 1:
|
|
self.print(f'(int num)', '\n{\n')
|
|
else:
|
|
self.print('(void)\n{\n')
|
|
|
|
if regnum != 1:
|
|
self.print('\t', f'static const uintptr_t loc[{regnum}]', '= {\n')
|
|
self.print('\t\t', self.get_reg(name,0), '\n')
|
|
for i in range(1,regnum):
|
|
self.print('\t\t,', self.get_reg(name, i), '\n')
|
|
self.print('\t};\n')
|
|
self.print('''
|
|
if (num < 0 || num >= ARRAY_SIZE(loc)) {
|
|
LOG_ERR("invalid location %d", num);
|
|
k_fatal_halt(K_ERR_KERNEL_OOPS);
|
|
}
|
|
''')
|
|
self.print('\t', f'return litex_read{typ}({"loc[num]" if regnum != 1 else self.get_reg(name, None)}', ');\n}\n\n')
|
|
|
|
def print_file(self):
|
|
self.print('''
|
|
#pragma once
|
|
|
|
static inline void litex_write64(uint64_t value, unsigned long addr)
|
|
{
|
|
#if CONFIG_LITEX_CSR_DATA_WIDTH >= 32
|
|
sys_write32(value >> 32, addr);
|
|
sys_write32(value, addr + 0x4);
|
|
#else
|
|
# error Unsupported CSR data width
|
|
#endif
|
|
}
|
|
|
|
''')
|
|
self.print('#define DAC_MAX', self.dacmax, '\n')
|
|
self.print('#define ADC_MAX', self.adcmax, '\n')
|
|
for reg in self.registers:
|
|
self.print_read_fun(reg[1],reg[2])
|
|
if not reg[0]: #read only
|
|
self.print_write_fun(reg[1],reg[2])
|
|
|
|
if __name__ == "__main__":
|
|
dac_num = 8
|
|
adc_num = 8
|
|
|
|
registers = [
|
|
# Read-only, name, number
|
|
(False, "dac_sel", dac_num),
|
|
(True, "dac_finished", dac_num),
|
|
(False, "dac_arm", dac_num),
|
|
(True, "from_dac", dac_num),
|
|
(False, "to_dac", dac_num),
|
|
# (False, "wf_arm", dac_num),
|
|
# (False, "wf_halt_on_finish", dac_num),
|
|
# (True, "wf_finished", dac_num),
|
|
# (True, "wf_running", dac_num),
|
|
# (False, "wf_time_to_wait", dac_num),
|
|
# (False, "wf_refresh_start", dac_num),
|
|
# (True, "wf_refresh_finished", dac_num),
|
|
# (False, "wf_start_addr", dac_num),
|
|
|
|
(True, "adc_finished", adc_num),
|
|
(False, "adc_arm", adc_num),
|
|
(True, "from_adc", adc_num),
|
|
|
|
(False, "adc_sel", adc_num),
|
|
(True, "cl_in_loop", 1),
|
|
(False, "cl_cmd", 1),
|
|
(False, "cl_word_in", 1),
|
|
(False, "cl_word_out", 1),
|
|
(False, "cl_start_cmd", 1),
|
|
(True, "cl_finish_cmd", 1),
|
|
]
|
|
|
|
CSRGenerator("csr.json", "csr_bitwidth.json", registers, sys.stdout, dac_num, adc_num).print_file()
|
|
|