From 8a82ddf6e12fb501aa7ef100aec5b9fa2cac3df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Gourichon?= Date: Thu, 10 Dec 2020 11:32:21 +0100 Subject: [PATCH] CSR fields: generate convenience functions (#725) Generate convenience methods to extract/replace bits in CSR fields, only generate replace if CSR register is writable. --- litex/soc/integration/export.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/litex/soc/integration/export.py b/litex/soc/integration/export.py index f7a83a12e..e13d66229 100644 --- a/litex/soc/integration/export.py +++ b/litex/soc/integration/export.py @@ -223,8 +223,29 @@ def get_csr_header(regions, constants, csr_base=None, with_access_functions=True origin += alignment//8*nr if hasattr(csr, "fields"): for field in csr.fields.fields: - r += "#define CSR_"+name.upper()+"_"+csr.name.upper()+"_"+field.name.upper()+"_OFFSET "+str(field.offset)+"\n" - r += "#define CSR_"+name.upper()+"_"+csr.name.upper()+"_"+field.name.upper()+"_SIZE "+str(field.size)+"\n" + offset = str(field.offset) + size = str(field.size) + r += "#define CSR_"+name.upper()+"_"+csr.name.upper()+"_"+field.name.upper()+"_OFFSET "+offset+"\n" + r += "#define CSR_"+name.upper()+"_"+csr.name.upper()+"_"+field.name.upper()+"_SIZE "+size+"\n" + if with_access_functions: + reg_name = name + "_" + csr.name.lower() + field_name = reg_name + "_" + field.name.lower() + r += "static inline uint32_t " + field_name + "_extract(uint32_t oldword) {\n" + r += "\tuint32_t mask = ((1 << " + size + ")-1);\n" + r += "\treturn ( (oldword >> " + offset + ") & mask );\n}\n" + r += "static inline uint32_t " + field_name + "_read(void) {\n" + r += "\tuint32_t word = " + reg_name + "_read();\n" + r += "\treturn " + field_name + "_extract(word);\n" + r += "}\n" + if (reg_name + "_write") in r: + r += "static inline uint32_t " + field_name + "_replace(uint32_t oldword, uint32_t plain_value) {\n" + r += "\tuint32_t mask = ((1 << " + size + ")-1);\n" + r += "\treturn (oldword & (~(mask << " + offset + "))) | (mask & plain_value)<< " + offset + " ;\n}\n" + r += "static inline void " + field_name + "_write(uint32_t plain_value) {\n" + r += "\tuint32_t oldword = " + reg_name + "_read();\n" + r += "\tuint32_t newword = " + field_name + "_replace(oldword, plain_value);\n" + r += "\t" + reg_name + "_write(newword);\n" + r += "}\n" r += "\n#endif\n" return r