From 71a0f2ffabb3721e5b987598a09a4b12893030a1 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 25 Sep 2026 16:01:29 -0700 Subject: [PATCH] Make every normative tag a normative rule; drop rule definitions and params tools create_normative_rules.py now reads only the tag files: each norm: tag is one normative rule named by the tag without the norm: prefix, and its chapter comes from the tag file's section tree (tags.rb now records each section's level). The rule-definition YAML (-d), its schema, the many:1/1:many mapping, context tags, implementation-defined behavior metadata and tables, and the params tools that depended on them (create_params.py, create_param_tables.py, export_params_to_udb.py and their schemas and tests) are removed. Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: David Harris --- .pre-commit-config.yaml | 1 - Makefile | 217 +- converters/tags.rb | 2 + normative-rules.md | 9 +- schemas/common-schema.json | 115 - schemas/csr-table-schema.json | 46 - schemas/defs-schema.json | 183 -- schemas/norm-rules-schema.json | 142 +- schemas/param-common-schema.json | 152 -- schemas/param-defs-schema.json | 229 -- schemas/param-table-schema.json | 46 - schemas/params-schema.json | 208 -- schemas/udb-json-schema-draft-07.json | 242 -- schemas/udb_param_schema.json | 48 - schemas/udb_schema_defs.json | 875 ------- .../expected/test-ch1-norm-tags.json | 10 + .../expected/test-ch2-norm-tags.json | 4 + tests/norm-rule/expected/test-norm-rules.html | 1819 ++------------ tests/norm-rule/expected/test-norm-rules.json | 2149 +++++------------ tests/norm-rule/missing_tag_refs.yaml | 72 - tests/norm-rule/test-ch1.adoc | 2 +- tests/norm-rule/test-ch1.yaml | 264 -- tests/norm-rule/test-ch2.adoc | 2 +- tests/norm-rule/test-ch2.yaml | 95 - .../all_csrs_a_to_z.adoc | 13 - .../all_csrs_by_chapter.adoc | 33 - .../test-ch1/all_csrs.adoc | 1 - .../test-ch1/satp.MODE.adoc | 6 - .../test-ch1/warl_csrs.adoc | 1 - .../test-ch2/all_csrs.adoc | 4 - .../test-ch2/foo.ABC.adoc | 6 - .../test-ch2/foo.GHI.adoc | 5 - .../test-ch2/qux.QQQ.adoc | 6 - .../test-ch2/warl_csrs.adoc | 2 - .../test-ch2/wlrl_csrs.adoc | 2 - .../test-ch2/zort.XYZ.adoc | 5 - tests/params/expected/test-csr-appendix.adoc | 3 - .../all_params_a_to_z.adoc | 13 - .../all_params_by_chapter.adoc | 23 - .../test-ch1/all_params.adoc | 9 - .../test-ch1/csrs/all_csrs.adoc | 1 - .../test-ch1/csrs/satp.MODE.adoc | 6 - .../test-ch2/all_params.adoc | 12 - .../test-ch2/csrs/all_csrs.adoc | 4 - .../test-ch2/csrs/foo.ABC.adoc | 6 - .../test-ch2/csrs/foo.GHI.adoc | 5 - .../test-ch2/csrs/qux.QQQ.adoc | 6 - .../test-ch2/csrs/zort.XYZ.adoc | 5 - .../all_params_a_to_z.adoc | 13 - .../all_params_by_chapter.adoc | 23 - .../test-ch1/all_params.adoc | 9 - .../test-ch1/csrs/all_csrs.adoc | 1 - .../test-ch1/csrs/satp.MODE.adoc | 4 - .../test-ch2/all_params.adoc | 12 - .../test-ch2/csrs/all_csrs.adoc | 4 - .../test-ch2/csrs/foo.ABC.adoc | 3 - .../test-ch2/csrs/foo.GHI.adoc | 3 - .../test-ch2/csrs/qux.QQQ.adoc | 3 - .../test-ch2/csrs/zort.XYZ.adoc | 3 - .../all_params_a_to_z.adoc | 13 - .../all_params_by_chapter.adoc | 23 - .../test-ch1/all_params.adoc | 9 - .../test-ch1/csrs/all_csrs.adoc | 1 - .../test-ch1/csrs/satp.MODE.adoc | 6 - .../test-ch2/all_params.adoc | 12 - .../test-ch2/csrs/all_csrs.adoc | 4 - .../test-ch2/csrs/foo.ABC.adoc | 6 - .../test-ch2/csrs/foo.GHI.adoc | 5 - .../test-ch2/csrs/qux.QQQ.adoc | 6 - .../test-ch2/csrs/zort.XYZ.adoc | 5 - .../test-export-params-to-udb/ALL_BASES.yaml | 14 - .../ARRAY_OF_BIT.yaml | 18 - .../ARRAY_OF_BOOLEAN.yaml | 16 - .../ARRAY_OF_BYTE.yaml | 18 - .../ARRAY_OF_DWORD.yaml | 18 - .../ARRAY_OF_HWORD.yaml | 18 - .../ARRAY_OF_INT32.yaml | 18 - .../ARRAY_OF_LIST_INT.yaml | 20 - .../ARRAY_OF_LIST_STR.yaml | 20 - .../ARRAY_OF_NEG10TO20.yaml | 18 - .../ARRAY_OF_UINT5.yaml | 18 - .../ARRAY_OF_UINT64.yaml | 18 - .../ARRAY_OF_WORD.yaml | 18 - .../test-export-params-to-udb/ASIDLEN.yaml | 14 - .../test-export-params-to-udb/ASIDLEN1.yaml | 14 - .../test-export-params-to-udb/ASIDLEN2.yaml | 14 - .../test-export-params-to-udb/BASE_RV32I.yaml | 12 - .../BASE_RV32I_RV64I.yaml | 12 - .../test-export-params-to-udb/BIT.yaml | 14 - .../test-export-params-to-udb/BOOLEAN.yaml | 12 - .../test-export-params-to-udb/BYTE.yaml | 17 - .../test-export-params-to-udb/DWORD.yaml | 14 - .../test-export-params-to-udb/FOOBAR.yaml | 14 - .../test-export-params-to-udb/HWORD.yaml | 14 - .../test-export-params-to-udb/INT2.yaml | 14 - .../test-export-params-to-udb/INT64.yaml | 14 - .../test-export-params-to-udb/INT_MXLEN.yaml | 12 - .../test-export-params-to-udb/LIST_INT.yaml | 18 - .../test-export-params-to-udb/LIST_STR.yaml | 16 - .../MOCK_CSR_FIELD_Y.yaml | 12 - .../test-export-params-to-udb/MOCK_CSR_X.yaml | 12 - .../MOCK_EXT_DEP_A_ON_B.yaml | 12 - .../MOCK_INST_X.yaml | 12 - .../test-export-params-to-udb/MXLEN.yaml | 18 - .../NO_IMPL_DEF.yaml | 17 - .../ROSE_COLORS.yaml | 19 - .../test-export-params-to-udb/UINT32.yaml | 14 - .../test-export-params-to-udb/UINT6.yaml | 14 - .../UINT_1TO100.yaml | 14 - .../test-export-params-to-udb/UINT_4TO8.yaml | 14 - .../test-export-params-to-udb/UINT_MXLEN.yaml | 13 - .../test-export-params-to-udb/WORD.yaml | 14 - .../test-export-params-to-udb/XLEN.yaml | 17 - .../all_csrs_a_to_z.adoc | 13 - .../all_csrs_by_chapter.adoc | 33 - .../all_params_a_to_z.adoc | 51 - .../all_params_by_chapter.adoc | 23 - .../test-ch1/ALL_BASES.adoc | 9 - .../test-ch1/ARRAY_OF_BIT.adoc | 9 - .../test-ch1/ARRAY_OF_BOOLEAN.adoc | 9 - .../test-ch1/ARRAY_OF_BYTE.adoc | 9 - .../test-ch1/ARRAY_OF_DWORD.adoc | 9 - .../test-ch1/ARRAY_OF_HWORD.adoc | 9 - .../test-ch1/ARRAY_OF_INT32.adoc | 9 - .../test-ch1/ARRAY_OF_LIST_INT.adoc | 9 - .../test-ch1/ARRAY_OF_LIST_STR.adoc | 9 - .../test-ch1/ARRAY_OF_NEG10TO20.adoc | 9 - .../test-ch1/ARRAY_OF_UINT5.adoc | 9 - .../test-ch1/ARRAY_OF_UINT64.adoc | 9 - .../test-ch1/ARRAY_OF_WORD.adoc | 9 - .../test-ch1/BIT.adoc | 9 - .../test-ch1/BOOLEAN.adoc | 9 - .../test-ch1/BYTE.adoc | 9 - .../test-ch1/DWORD.adoc | 9 - .../test-ch1/HWORD.adoc | 9 - .../test-ch1/INT2.adoc | 9 - .../test-ch1/INT64.adoc | 9 - .../test-ch1/INT_MXLEN.adoc | 9 - .../test-ch1/LIST_INT.adoc | 9 - .../test-ch1/LIST_STR.adoc | 9 - .../test-ch1/MXLEN.adoc | 9 - .../test-ch1/UINT32.adoc | 9 - .../test-ch1/UINT6.adoc | 9 - .../test-ch1/UINT_1TO100.adoc | 9 - .../test-ch1/UINT_4TO8.adoc | 9 - .../test-ch1/UINT_MXLEN.adoc | 9 - .../test-ch1/WORD.adoc | 9 - .../test-ch1/all_csrs.adoc | 1 - .../test-ch1/all_params.adoc | 30 - .../test-ch1/satp.MODE.adoc | 6 - .../test-ch1/warl_csrs.adoc | 1 - .../test-ch2/ASIDLEN.adoc | 9 - .../test-ch2/ASIDLEN1.adoc | 9 - .../test-ch2/ASIDLEN2.adoc | 9 - .../test-ch2/BASE_RV32I.adoc | 9 - .../test-ch2/BASE_RV32I_RV64I.adoc | 9 - .../test-ch2/FOOBAR.adoc | 10 - .../test-ch2/MOCK_CSR_FIELD_Y.adoc | 9 - .../test-ch2/MOCK_CSR_X.adoc | 9 - .../test-ch2/MOCK_EXT_DEP_A_ON_B.adoc | 9 - .../test-ch2/MOCK_INST_X.adoc | 9 - .../test-ch2/NO_IMPL_DEF.adoc | 11 - .../test-ch2/ROSE_COLORS.adoc | 11 - .../test-ch2/XLEN.adoc | 10 - .../test-ch2/all_csrs.adoc | 4 - .../test-ch2/all_params.adoc | 13 - .../test-ch2/foo.ABC.adoc | 6 - .../test-ch2/foo.GHI.adoc | 5 - .../test-ch2/qux.QQQ.adoc | 6 - .../test-ch2/warl_csrs.adoc | 2 - .../test-ch2/wlrl_csrs.adoc | 2 - .../test-ch2/zort.XYZ.adoc | 5 - .../all_params_a_to_z.adoc | 51 - .../all_params_by_chapter.adoc | 23 - .../test-ch1/all_params.adoc | 38 - .../test-ch1/params/ALL_BASES.adoc | 9 - .../test-ch1/params/ARRAY_OF_BIT.adoc | 9 - .../test-ch1/params/ARRAY_OF_BOOLEAN.adoc | 9 - .../test-ch1/params/ARRAY_OF_BYTE.adoc | 9 - .../test-ch1/params/ARRAY_OF_DWORD.adoc | 9 - .../test-ch1/params/ARRAY_OF_HWORD.adoc | 9 - .../test-ch1/params/ARRAY_OF_INT32.adoc | 9 - .../test-ch1/params/ARRAY_OF_LIST_INT.adoc | 9 - .../test-ch1/params/ARRAY_OF_LIST_STR.adoc | 9 - .../test-ch1/params/ARRAY_OF_NEG10TO20.adoc | 9 - .../test-ch1/params/ARRAY_OF_UINT5.adoc | 9 - .../test-ch1/params/ARRAY_OF_UINT64.adoc | 9 - .../test-ch1/params/ARRAY_OF_WORD.adoc | 9 - .../test-ch1/params/BIT.adoc | 9 - .../test-ch1/params/BOOLEAN.adoc | 9 - .../test-ch1/params/BYTE.adoc | 9 - .../test-ch1/params/DWORD.adoc | 9 - .../test-ch1/params/HWORD.adoc | 9 - .../test-ch1/params/INT2.adoc | 9 - .../test-ch1/params/INT64.adoc | 9 - .../test-ch1/params/INT_MXLEN.adoc | 9 - .../test-ch1/params/LIST_INT.adoc | 9 - .../test-ch1/params/LIST_STR.adoc | 9 - .../test-ch1/params/MXLEN.adoc | 9 - .../test-ch1/params/UINT32.adoc | 9 - .../test-ch1/params/UINT6.adoc | 9 - .../test-ch1/params/UINT_1TO100.adoc | 9 - .../test-ch1/params/UINT_4TO8.adoc | 9 - .../test-ch1/params/UINT_MXLEN.adoc | 9 - .../test-ch1/params/WORD.adoc | 9 - .../test-ch1/params/all_params.adoc | 30 - .../test-ch2/all_params.adoc | 21 - .../test-ch2/params/ASIDLEN.adoc | 9 - .../test-ch2/params/ASIDLEN1.adoc | 9 - .../test-ch2/params/ASIDLEN2.adoc | 9 - .../test-ch2/params/BASE_RV32I.adoc | 9 - .../test-ch2/params/BASE_RV32I_RV64I.adoc | 9 - .../test-ch2/params/FOOBAR.adoc | 10 - .../test-ch2/params/MOCK_CSR_FIELD_Y.adoc | 9 - .../test-ch2/params/MOCK_CSR_X.adoc | 9 - .../test-ch2/params/MOCK_EXT_DEP_A_ON_B.adoc | 9 - .../test-ch2/params/MOCK_INST_X.adoc | 9 - .../test-ch2/params/NO_IMPL_DEF.adoc | 11 - .../test-ch2/params/ROSE_COLORS.adoc | 11 - .../test-ch2/params/XLEN.adoc | 10 - .../test-ch2/params/all_params.adoc | 13 - .../all_params_a_to_z.adoc | 51 - .../all_params_by_chapter.adoc | 23 - .../test-ch1/all_params.adoc | 38 - .../test-ch1/params/ALL_BASES.adoc | 7 - .../test-ch1/params/ARRAY_OF_BIT.adoc | 7 - .../test-ch1/params/ARRAY_OF_BOOLEAN.adoc | 7 - .../test-ch1/params/ARRAY_OF_BYTE.adoc | 7 - .../test-ch1/params/ARRAY_OF_DWORD.adoc | 7 - .../test-ch1/params/ARRAY_OF_HWORD.adoc | 7 - .../test-ch1/params/ARRAY_OF_INT32.adoc | 7 - .../test-ch1/params/ARRAY_OF_LIST_INT.adoc | 7 - .../test-ch1/params/ARRAY_OF_LIST_STR.adoc | 7 - .../test-ch1/params/ARRAY_OF_NEG10TO20.adoc | 7 - .../test-ch1/params/ARRAY_OF_UINT5.adoc | 7 - .../test-ch1/params/ARRAY_OF_UINT64.adoc | 7 - .../test-ch1/params/ARRAY_OF_WORD.adoc | 7 - .../test-ch1/params/BIT.adoc | 7 - .../test-ch1/params/BOOLEAN.adoc | 7 - .../test-ch1/params/BYTE.adoc | 7 - .../test-ch1/params/DWORD.adoc | 7 - .../test-ch1/params/HWORD.adoc | 7 - .../test-ch1/params/INT2.adoc | 7 - .../test-ch1/params/INT64.adoc | 7 - .../test-ch1/params/INT_MXLEN.adoc | 7 - .../test-ch1/params/LIST_INT.adoc | 7 - .../test-ch1/params/LIST_STR.adoc | 7 - .../test-ch1/params/MXLEN.adoc | 7 - .../test-ch1/params/UINT32.adoc | 7 - .../test-ch1/params/UINT6.adoc | 7 - .../test-ch1/params/UINT_1TO100.adoc | 7 - .../test-ch1/params/UINT_4TO8.adoc | 7 - .../test-ch1/params/UINT_MXLEN.adoc | 7 - .../test-ch1/params/WORD.adoc | 7 - .../test-ch1/params/all_params.adoc | 30 - .../test-ch2/all_params.adoc | 21 - .../test-ch2/params/ASIDLEN.adoc | 7 - .../test-ch2/params/ASIDLEN1.adoc | 7 - .../test-ch2/params/ASIDLEN2.adoc | 7 - .../test-ch2/params/BASE_RV32I.adoc | 7 - .../test-ch2/params/BASE_RV32I_RV64I.adoc | 7 - .../test-ch2/params/FOOBAR.adoc | 8 - .../test-ch2/params/MOCK_CSR_FIELD_Y.adoc | 7 - .../test-ch2/params/MOCK_CSR_X.adoc | 7 - .../test-ch2/params/MOCK_EXT_DEP_A_ON_B.adoc | 7 - .../test-ch2/params/MOCK_INST_X.adoc | 7 - .../test-ch2/params/NO_IMPL_DEF.adoc | 9 - .../test-ch2/params/ROSE_COLORS.adoc | 9 - .../test-ch2/params/XLEN.adoc | 8 - .../test-ch2/params/all_params.adoc | 13 - .../all_params_a_to_z.adoc | 51 - .../all_params_by_chapter.adoc | 23 - .../test-ch1/all_params.adoc | 38 - .../test-ch1/params/ALL_BASES.adoc | 9 - .../test-ch1/params/ARRAY_OF_BIT.adoc | 9 - .../test-ch1/params/ARRAY_OF_BOOLEAN.adoc | 9 - .../test-ch1/params/ARRAY_OF_BYTE.adoc | 9 - .../test-ch1/params/ARRAY_OF_DWORD.adoc | 9 - .../test-ch1/params/ARRAY_OF_HWORD.adoc | 9 - .../test-ch1/params/ARRAY_OF_INT32.adoc | 9 - .../test-ch1/params/ARRAY_OF_LIST_INT.adoc | 9 - .../test-ch1/params/ARRAY_OF_LIST_STR.adoc | 9 - .../test-ch1/params/ARRAY_OF_NEG10TO20.adoc | 9 - .../test-ch1/params/ARRAY_OF_UINT5.adoc | 9 - .../test-ch1/params/ARRAY_OF_UINT64.adoc | 9 - .../test-ch1/params/ARRAY_OF_WORD.adoc | 9 - .../test-ch1/params/BIT.adoc | 9 - .../test-ch1/params/BOOLEAN.adoc | 9 - .../test-ch1/params/BYTE.adoc | 9 - .../test-ch1/params/DWORD.adoc | 9 - .../test-ch1/params/HWORD.adoc | 9 - .../test-ch1/params/INT2.adoc | 9 - .../test-ch1/params/INT64.adoc | 9 - .../test-ch1/params/INT_MXLEN.adoc | 9 - .../test-ch1/params/LIST_INT.adoc | 9 - .../test-ch1/params/LIST_STR.adoc | 9 - .../test-ch1/params/MXLEN.adoc | 9 - .../test-ch1/params/UINT32.adoc | 9 - .../test-ch1/params/UINT6.adoc | 9 - .../test-ch1/params/UINT_1TO100.adoc | 9 - .../test-ch1/params/UINT_4TO8.adoc | 9 - .../test-ch1/params/UINT_MXLEN.adoc | 9 - .../test-ch1/params/WORD.adoc | 9 - .../test-ch1/params/all_params.adoc | 30 - .../test-ch2/all_params.adoc | 21 - .../test-ch2/params/ASIDLEN.adoc | 9 - .../test-ch2/params/ASIDLEN1.adoc | 9 - .../test-ch2/params/ASIDLEN2.adoc | 9 - .../test-ch2/params/BASE_RV32I.adoc | 9 - .../test-ch2/params/BASE_RV32I_RV64I.adoc | 9 - .../test-ch2/params/FOOBAR.adoc | 10 - .../test-ch2/params/MOCK_CSR_FIELD_Y.adoc | 9 - .../test-ch2/params/MOCK_CSR_X.adoc | 9 - .../test-ch2/params/MOCK_EXT_DEP_A_ON_B.adoc | 9 - .../test-ch2/params/MOCK_INST_X.adoc | 9 - .../test-ch2/params/NO_IMPL_DEF.adoc | 11 - .../test-ch2/params/ROSE_COLORS.adoc | 11 - .../test-ch2/params/XLEN.adoc | 10 - .../test-ch2/params/all_params.adoc | 13 - tests/params/expected/test-param-tables.adoc | 3 - .../test-param-tables/all_params_a_to_z.adoc | 65 - .../all_params_by_chapter.adoc | 43 - .../test-ch1/all_params.adoc | 48 - .../test-ch1/csrs/all_csrs.adoc | 1 - .../test-ch1/csrs/satp.MODE.adoc | 6 - .../test-ch1/params/ALL_BASES.adoc | 9 - .../test-ch1/params/ARRAY_OF_BIT.adoc | 9 - .../test-ch1/params/ARRAY_OF_BOOLEAN.adoc | 9 - .../test-ch1/params/ARRAY_OF_BYTE.adoc | 9 - .../test-ch1/params/ARRAY_OF_DWORD.adoc | 9 - .../test-ch1/params/ARRAY_OF_HWORD.adoc | 9 - .../test-ch1/params/ARRAY_OF_INT32.adoc | 9 - .../test-ch1/params/ARRAY_OF_LIST_INT.adoc | 9 - .../test-ch1/params/ARRAY_OF_LIST_STR.adoc | 9 - .../test-ch1/params/ARRAY_OF_NEG10TO20.adoc | 9 - .../test-ch1/params/ARRAY_OF_UINT5.adoc | 9 - .../test-ch1/params/ARRAY_OF_UINT64.adoc | 9 - .../test-ch1/params/ARRAY_OF_WORD.adoc | 9 - .../test-ch1/params/BIT.adoc | 9 - .../test-ch1/params/BOOLEAN.adoc | 9 - .../test-ch1/params/BYTE.adoc | 9 - .../test-ch1/params/DWORD.adoc | 9 - .../test-ch1/params/HWORD.adoc | 9 - .../test-ch1/params/INT2.adoc | 9 - .../test-ch1/params/INT64.adoc | 9 - .../test-ch1/params/INT_MXLEN.adoc | 9 - .../test-ch1/params/LIST_INT.adoc | 9 - .../test-ch1/params/LIST_STR.adoc | 9 - .../test-ch1/params/MXLEN.adoc | 9 - .../test-ch1/params/UINT32.adoc | 9 - .../test-ch1/params/UINT6.adoc | 9 - .../test-ch1/params/UINT_1TO100.adoc | 9 - .../test-ch1/params/UINT_4TO8.adoc | 9 - .../test-ch1/params/UINT_MXLEN.adoc | 9 - .../test-ch1/params/WORD.adoc | 9 - .../test-ch1/params/all_params.adoc | 30 - .../test-ch2/all_params.adoc | 34 - .../test-ch2/csrs/all_csrs.adoc | 4 - .../test-ch2/csrs/foo.ABC.adoc | 6 - .../test-ch2/csrs/foo.GHI.adoc | 5 - .../test-ch2/csrs/qux.QQQ.adoc | 6 - .../test-ch2/csrs/zort.XYZ.adoc | 5 - .../test-ch2/params/ASIDLEN.adoc | 9 - .../test-ch2/params/ASIDLEN1.adoc | 9 - .../test-ch2/params/ASIDLEN2.adoc | 9 - .../test-ch2/params/BASE_RV32I.adoc | 9 - .../test-ch2/params/BASE_RV32I_RV64I.adoc | 9 - .../test-ch2/params/FOOBAR.adoc | 10 - .../test-ch2/params/MOCK_CSR_FIELD_Y.adoc | 9 - .../test-ch2/params/MOCK_CSR_X.adoc | 9 - .../test-ch2/params/MOCK_EXT_DEP_A_ON_B.adoc | 9 - .../test-ch2/params/MOCK_INST_X.adoc | 9 - .../test-ch2/params/NO_IMPL_DEF.adoc | 11 - .../test-ch2/params/ROSE_COLORS.adoc | 11 - .../test-ch2/params/XLEN.adoc | 10 - .../test-ch2/params/all_params.adoc | 13 - tests/params/expected/test-params.html | 492 ---- tests/params/expected/test-params.json | 1729 ------------- tests/params/test-ch1.yaml | 161 -- tests/params/test-ch2.yaml | 92 - tests/params/test-csr-table-full-default.yaml | 15 - tests/params/test-csr-table-minimal.yaml | 9 - tests/params/test-csr-table-reordered.yaml | 15 - .../params/test-param-table-full-default.yaml | 15 - tests/params/test-param-table-minimal.yaml | 9 - tests/params/test-param-table-reordered.yaml | 15 - tests/params/test-param-tables.adoc | 3 - tests/shared_utils/test_shared_utils.py | 262 -- .../test_tag_text_to_html_unit.py | 9 +- tools/README.md | 229 +- tools/appendix_shared_utils.py | 38 - tools/create_normative_rules.py | 1034 ++------ tools/create_param_tables.py | 510 ---- tools/create_params.py | 1409 ----------- tools/default_csr_table.yaml | 15 - tools/default_param_table.yaml | 15 - tools/export_params_to_udb.py | 117 - tools/params_json_to_udb_yaml.py | 0 tools/shared_utils.py | 326 +-- tools/tag_text_to_html.py | 4 - 400 files changed, 999 insertions(+), 16337 deletions(-) delete mode 100644 schemas/common-schema.json delete mode 100644 schemas/csr-table-schema.json delete mode 100644 schemas/defs-schema.json delete mode 100644 schemas/param-common-schema.json delete mode 100644 schemas/param-defs-schema.json delete mode 100644 schemas/param-table-schema.json delete mode 100644 schemas/params-schema.json delete mode 100644 schemas/udb-json-schema-draft-07.json delete mode 100644 schemas/udb_param_schema.json delete mode 100644 schemas/udb_schema_defs.json delete mode 100644 tests/norm-rule/missing_tag_refs.yaml delete mode 100644 tests/norm-rule/test-ch1.yaml delete mode 100644 tests/norm-rule/test-ch2.yaml delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/all_csrs_a_to_z.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/all_csrs_by_chapter.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch1/all_csrs.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch1/satp.MODE.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch1/warl_csrs.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch2/all_csrs.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch2/foo.ABC.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch2/foo.GHI.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch2/qux.QQQ.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch2/warl_csrs.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch2/wlrl_csrs.adoc delete mode 100644 tests/params/expected/test-csr-appendix-adoc-includes/test-ch2/zort.XYZ.adoc delete mode 100644 tests/params/expected/test-csr-appendix.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/all_params_a_to_z.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/all_params_by_chapter.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/test-ch1/all_params.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/test-ch1/csrs/all_csrs.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/test-ch1/csrs/satp.MODE.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/test-ch2/all_params.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/test-ch2/csrs/all_csrs.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/test-ch2/csrs/foo.ABC.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/test-ch2/csrs/foo.GHI.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/test-ch2/csrs/qux.QQQ.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-full-default/test-ch2/csrs/zort.XYZ.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/all_params_a_to_z.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/all_params_by_chapter.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/test-ch1/all_params.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/test-ch1/csrs/all_csrs.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/test-ch1/csrs/satp.MODE.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/test-ch2/all_params.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/test-ch2/csrs/all_csrs.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/test-ch2/csrs/foo.ABC.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/test-ch2/csrs/foo.GHI.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/test-ch2/csrs/qux.QQQ.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-minimal/test-ch2/csrs/zort.XYZ.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/all_params_a_to_z.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/all_params_by_chapter.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/test-ch1/all_params.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/test-ch1/csrs/all_csrs.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/test-ch1/csrs/satp.MODE.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/test-ch2/all_params.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/test-ch2/csrs/all_csrs.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/test-ch2/csrs/foo.ABC.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/test-ch2/csrs/foo.GHI.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/test-ch2/csrs/qux.QQQ.adoc delete mode 100644 tests/params/expected/test-csr-table-variants/test-csr-table-reordered/test-ch2/csrs/zort.XYZ.adoc delete mode 100644 tests/params/expected/test-export-params-to-udb/ALL_BASES.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_BIT.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_BOOLEAN.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_BYTE.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_DWORD.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_HWORD.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_INT32.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_LIST_INT.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_LIST_STR.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_NEG10TO20.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_UINT5.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_UINT64.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ARRAY_OF_WORD.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ASIDLEN.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ASIDLEN1.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ASIDLEN2.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/BASE_RV32I.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/BASE_RV32I_RV64I.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/BIT.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/BOOLEAN.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/BYTE.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/DWORD.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/FOOBAR.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/HWORD.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/INT2.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/INT64.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/INT_MXLEN.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/LIST_INT.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/LIST_STR.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/MOCK_CSR_FIELD_Y.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/MOCK_CSR_X.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/MOCK_EXT_DEP_A_ON_B.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/MOCK_INST_X.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/MXLEN.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/NO_IMPL_DEF.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/ROSE_COLORS.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/UINT32.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/UINT6.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/UINT_1TO100.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/UINT_4TO8.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/UINT_MXLEN.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/WORD.yaml delete mode 100644 tests/params/expected/test-export-params-to-udb/XLEN.yaml delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/all_csrs_a_to_z.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/all_csrs_by_chapter.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/all_params_a_to_z.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/all_params_by_chapter.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ALL_BASES.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_BIT.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_BYTE.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_DWORD.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_HWORD.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_INT32.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_NEG10TO20.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_UINT5.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_UINT64.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/ARRAY_OF_WORD.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/BIT.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/BYTE.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/DWORD.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/HWORD.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/INT2.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/INT64.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/INT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/MXLEN.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/UINT32.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/UINT6.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/UINT_1TO100.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/UINT_4TO8.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/UINT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/WORD.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/all_csrs.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/all_params.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/satp.MODE.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch1/warl_csrs.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/ASIDLEN.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/ASIDLEN1.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/ASIDLEN2.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/BASE_RV32I.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/BASE_RV32I_RV64I.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/FOOBAR.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/MOCK_CSR_FIELD_Y.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/MOCK_CSR_X.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/MOCK_EXT_DEP_A_ON_B.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/MOCK_INST_X.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/NO_IMPL_DEF.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/ROSE_COLORS.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/XLEN.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/all_csrs.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/all_params.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/foo.ABC.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/foo.GHI.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/qux.QQQ.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/warl_csrs.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/wlrl_csrs.adoc delete mode 100644 tests/params/expected/test-param-appendix-adoc-includes/test-ch2/zort.XYZ.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/all_params_a_to_z.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/all_params_by_chapter.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ALL_BASES.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_BIT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_BYTE.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_DWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_HWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_INT32.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_NEG10TO20.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_UINT5.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_UINT64.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/ARRAY_OF_WORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/BIT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/BYTE.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/DWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/HWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/INT2.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/INT64.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/INT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/MXLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/UINT32.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/UINT6.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/UINT_1TO100.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/UINT_4TO8.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/UINT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/WORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch1/params/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/ASIDLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/ASIDLEN1.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/ASIDLEN2.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/BASE_RV32I.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/BASE_RV32I_RV64I.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/FOOBAR.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/MOCK_CSR_FIELD_Y.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/MOCK_CSR_X.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/MOCK_EXT_DEP_A_ON_B.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/MOCK_INST_X.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/NO_IMPL_DEF.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/ROSE_COLORS.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/XLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-full-default/test-ch2/params/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/all_params_a_to_z.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/all_params_by_chapter.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ALL_BASES.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_BIT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_BYTE.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_DWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_HWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_INT32.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_NEG10TO20.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_UINT5.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_UINT64.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/ARRAY_OF_WORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/BIT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/BYTE.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/DWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/HWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/INT2.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/INT64.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/INT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/MXLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/UINT32.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/UINT6.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/UINT_1TO100.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/UINT_4TO8.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/UINT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/WORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch1/params/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/ASIDLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/ASIDLEN1.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/ASIDLEN2.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/BASE_RV32I.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/BASE_RV32I_RV64I.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/FOOBAR.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/MOCK_CSR_FIELD_Y.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/MOCK_CSR_X.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/MOCK_EXT_DEP_A_ON_B.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/MOCK_INST_X.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/NO_IMPL_DEF.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/ROSE_COLORS.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/XLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-minimal/test-ch2/params/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/all_params_a_to_z.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/all_params_by_chapter.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ALL_BASES.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_BIT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_BYTE.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_DWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_HWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_INT32.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_NEG10TO20.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_UINT5.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_UINT64.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/ARRAY_OF_WORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/BIT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/BYTE.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/DWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/HWORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/INT2.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/INT64.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/INT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/MXLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/UINT32.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/UINT6.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/UINT_1TO100.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/UINT_4TO8.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/UINT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/WORD.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch1/params/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/all_params.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/ASIDLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/ASIDLEN1.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/ASIDLEN2.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/BASE_RV32I.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/BASE_RV32I_RV64I.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/FOOBAR.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/MOCK_CSR_FIELD_Y.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/MOCK_CSR_X.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/MOCK_EXT_DEP_A_ON_B.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/MOCK_INST_X.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/NO_IMPL_DEF.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/ROSE_COLORS.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/XLEN.adoc delete mode 100644 tests/params/expected/test-param-table-variants/test-param-table-reordered/test-ch2/params/all_params.adoc delete mode 100644 tests/params/expected/test-param-tables.adoc delete mode 100644 tests/params/expected/test-param-tables/all_params_a_to_z.adoc delete mode 100644 tests/params/expected/test-param-tables/all_params_by_chapter.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/all_params.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/csrs/all_csrs.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/csrs/satp.MODE.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ALL_BASES.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_BIT.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_BYTE.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_DWORD.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_HWORD.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_INT32.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_NEG10TO20.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_UINT5.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_UINT64.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/ARRAY_OF_WORD.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/BIT.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/BOOLEAN.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/BYTE.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/DWORD.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/HWORD.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/INT2.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/INT64.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/INT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/LIST_INT.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/LIST_STR.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/MXLEN.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/UINT32.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/UINT6.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/UINT_1TO100.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/UINT_4TO8.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/UINT_MXLEN.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/WORD.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch1/params/all_params.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/all_params.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/csrs/all_csrs.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/csrs/foo.ABC.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/csrs/foo.GHI.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/csrs/qux.QQQ.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/csrs/zort.XYZ.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/ASIDLEN.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/ASIDLEN1.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/ASIDLEN2.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/BASE_RV32I.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/BASE_RV32I_RV64I.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/FOOBAR.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/MOCK_CSR_FIELD_Y.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/MOCK_CSR_X.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/MOCK_EXT_DEP_A_ON_B.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/MOCK_INST_X.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/NO_IMPL_DEF.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/ROSE_COLORS.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/XLEN.adoc delete mode 100644 tests/params/expected/test-param-tables/test-ch2/params/all_params.adoc delete mode 100644 tests/params/expected/test-params.html delete mode 100644 tests/params/expected/test-params.json delete mode 100644 tests/params/test-ch1.yaml delete mode 100644 tests/params/test-ch2.yaml delete mode 100644 tests/params/test-csr-table-full-default.yaml delete mode 100644 tests/params/test-csr-table-minimal.yaml delete mode 100644 tests/params/test-csr-table-reordered.yaml delete mode 100644 tests/params/test-param-table-full-default.yaml delete mode 100644 tests/params/test-param-table-minimal.yaml delete mode 100644 tests/params/test-param-table-reordered.yaml delete mode 100644 tests/params/test-param-tables.adoc delete mode 100644 tools/appendix_shared_utils.py delete mode 100644 tools/create_param_tables.py delete mode 100644 tools/create_params.py delete mode 100644 tools/default_csr_table.yaml delete mode 100644 tools/default_param_table.yaml delete mode 100644 tools/export_params_to_udb.py delete mode 100644 tools/params_json_to_udb_yaml.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 701c800..593c1d1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,4 +16,3 @@ repos: hooks: - id: yamlfmt args: [--mapping, '2', --sequence, '4', --offset, '2', --preserve-quotes] - exclude: ^tests/params/expected/ diff --git a/Makefile b/Makefile index 268d222..e534a31 100644 --- a/Makefile +++ b/Makefile @@ -19,37 +19,16 @@ TOOLS_DIR := tools BUILD_DIR := build TESTS_DIR := tests NORM_RULE_TESTS_DIR := $(TESTS_DIR)/norm-rule -PARAMS_TESTS_DIR := $(TESTS_DIR)/params TAGS_TESTS_DIR := $(TESTS_DIR)/tags ADOC2HTML_TESTS_DIR := $(TESTS_DIR)/adoc2html SHARED_UTILS_TESTS_DIR := $(TESTS_DIR)/shared_utils TEXT_TO_HTML_TESTS_DIR := $(TESTS_DIR)/text_to_html -NORM_RULE_DEF_DIR := $(NORM_RULE_TESTS_DIR) NORM_RULE_EXPECTED_DIR := $(NORM_RULE_TESTS_DIR)/expected -PARAMS_DEF_DIR := $(PARAMS_TESTS_DIR) -PARAMS_EXPECTED_DIR := $(PARAMS_TESTS_DIR)/expected # Scripts being tested. TAGS_BACKEND := tags.rb CREATE_NORM_RULE_TOOL := $(TOOLS_DIR)/create_normative_rules.py CREATE_NORM_RULE_PYTHON := python3 $(CREATE_NORM_RULE_TOOL) -CREATE_PARAMS_TOOL := $(TOOLS_DIR)/create_params.py -CREATE_PARAMS_PYTHON := python3 $(CREATE_PARAMS_TOOL) -CREATE_PARAM_TABLES_TOOL := $(TOOLS_DIR)/create_param_tables.py -CREATE_PARAM_TABLES_PYTHON := python3 $(CREATE_PARAM_TABLES_TOOL) -PARAMS_ADOC_SOURCE := $(PARAMS_TESTS_DIR)/test-param-tables.adoc -PARAM_TABLE_SCHEMA_INPUT := $(TOOLS_DIR)/default_param_table.yaml -CSR_TABLE_SCHEMA_INPUT := $(TOOLS_DIR)/default_csr_table.yaml -PARAM_TABLE_VARIANT_FILES := \ - $(PARAMS_TESTS_DIR)/test-param-table-full-default.yaml \ - $(PARAMS_TESTS_DIR)/test-param-table-reordered.yaml \ - $(PARAMS_TESTS_DIR)/test-param-table-minimal.yaml -CSR_TABLE_VARIANT_FILES := \ - $(PARAMS_TESTS_DIR)/test-csr-table-full-default.yaml \ - $(PARAMS_TESTS_DIR)/test-csr-table-reordered.yaml \ - $(PARAMS_TESTS_DIR)/test-csr-table-minimal.yaml -EXPORT_PARAMS_TO_UDB_TOOL := $(TOOLS_DIR)/export_params_to_udb.py -EXPORT_PARAMS_TO_UDB_PYTHON := python3 $(EXPORT_PARAMS_TO_UDB_TOOL) # Stuff for building test standards document in HTML to have links into it. DOCS = test-ch1 test-ch2 @@ -67,9 +46,6 @@ TEST_CH1_NORM_TAGS_OUTPUT_FNAME := test-ch1$(DOC_NORM_TAG_SUFFIX) TEST_CH2_NORM_TAGS_OUTPUT_FNAME := test-ch2$(DOC_NORM_TAG_SUFFIX) NORM_RULE_JSON_OUTPUT_FNAME := test-norm-rules.json NORM_RULE_HTML_OUTPUT_FNAME := test-norm-rules.html -NORM_RULE_TAGS_NO_RULES_OUTPUT_FNAME := test-norm-rules_tags_no_rules.json -PARAMS_JSON_OUTPUT_FNAME := test-params.json -PARAMS_HTML_OUTPUT_FNAME := test-params.html # Tag extraction test files DUPLICATE_TEST_ADOC_INPUT_FNAME := duplicate.adoc @@ -83,18 +59,6 @@ BUILT_TEST_CH2_NORM_TAGS_FNAME := $(BUILD_DIR)/$(TEST_CH2_NORM_TAGS_OUTPUT_FNAME BUILT_DUPLICATE_NORM_TAGS_FNAME := $(BUILD_DIR)/$(DUPLICATE_NORM_TAGS_OUTPUT_FNAME) BUILT_NORM_RULES_JSON := $(BUILD_DIR)/$(NORM_RULE_JSON_OUTPUT_FNAME) BUILT_NORM_RULES_HTML := $(BUILD_DIR)/$(NORM_RULE_HTML_OUTPUT_FNAME) -BUILT_NORM_RULES_TAGS_NO_RULES := $(BUILD_DIR)/$(NORM_RULE_TAGS_NO_RULES_OUTPUT_FNAME) -BUILT_PARAMS_JSON := $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) -BUILT_PARAMS_HTML := $(BUILD_DIR)/$(PARAMS_HTML_OUTPUT_FNAME) -BUILT_PARAM_ADOC_DIR := $(BUILD_DIR)/test-param-tables -BUILT_PARAM_ADOC_STAMP := $(BUILD_DIR)/test-param-adoc.done -BUILT_PARAMS_ADOC := $(BUILD_DIR)/test-param-tables.adoc -BUILT_PARAM_TABLE_VARIANTS_DIR := $(BUILD_DIR)/test-param-table-variants -BUILT_PARAM_TABLE_VARIANTS_STAMP := $(BUILD_DIR)/test-param-table-variants.done -BUILT_CSR_TABLE_VARIANTS_DIR := $(BUILD_DIR)/test-csr-table-variants -BUILT_CSR_TABLE_VARIANTS_STAMP := $(BUILD_DIR)/test-csr-table-variants.done -BUILT_EXPORT_PARAMS_TO_UDB_DIR := $(BUILD_DIR)/test-export-params-to-udb -BUILT_EXPORT_PARAMS_TO_UDB_STAMP := $(BUILD_DIR)/test-export-params-to-udb.done # Combine separate fnames into lists. BUILT_TEST_HTML_FNAMES := $(BUILT_TEST_CH1_HTML_FNAME) $(BUILT_TEST_CH2_HTML_FNAME) @@ -106,18 +70,8 @@ EXPECTED_CH1_NORM_TAGS := $(NORM_RULE_EXPECTED_DIR)/$(TEST_CH1_NORM_TAGS_OUTPUT_ EXPECTED_CH2_NORM_TAGS := $(NORM_RULE_EXPECTED_DIR)/$(TEST_CH2_NORM_TAGS_OUTPUT_FNAME) EXPECTED_NORM_RULES_JSON := $(NORM_RULE_EXPECTED_DIR)/$(NORM_RULE_JSON_OUTPUT_FNAME) EXPECTED_NORM_RULES_HTML := $(NORM_RULE_EXPECTED_DIR)/$(NORM_RULE_HTML_OUTPUT_FNAME) -EXPECTED_PARAMS_JSON := $(PARAMS_EXPECTED_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) -EXPECTED_PARAMS_HTML := $(PARAMS_EXPECTED_DIR)/$(PARAMS_HTML_OUTPUT_FNAME) -EXPECTED_PARAMS_ADOC := $(PARAMS_EXPECTED_DIR)/test-param-tables.adoc -EXPECTED_PARAM_ADOC_DIR := $(PARAMS_EXPECTED_DIR)/test-param-tables -EXPECTED_PARAM_TABLE_VARIANTS_DIR := $(PARAMS_EXPECTED_DIR)/test-param-table-variants -EXPECTED_CSR_TABLE_VARIANTS_DIR := $(PARAMS_EXPECTED_DIR)/test-csr-table-variants -EXPECTED_EXPORT_PARAMS_TO_UDB_DIR := $(PARAMS_EXPECTED_DIR)/test-export-params-to-udb - -# Normative rule definition input YAML files. -GOOD_NORM_RULE_DEF_FILES := $(NORM_RULE_DEF_DIR)/test-ch1.yaml $(NORM_RULE_DEF_DIR)/test-ch2.yaml -BAD_NORM_RULE_DEF_FILES := $(NORM_RULE_DEF_DIR)/missing_tag_refs.yaml -PARAM_DEF_TEST_FILES := $(PARAMS_TESTS_DIR)/test-ch1.yaml $(PARAMS_TESTS_DIR)/test-ch2.yaml + +# Unit test scripts. ADOC2HTML_TEST_SCRIPT := $(ADOC2HTML_TESTS_DIR)/test_adoc_to_html.py SHARED_UTILS_TEST_SCRIPT := $(SHARED_UTILS_TESTS_DIR)/test_shared_utils.py ADOC_TO_HTML_UNIT_TEST_SCRIPT := $(TEXT_TO_HTML_TESTS_DIR)/test_adoc_to_html_unit.py @@ -127,13 +81,6 @@ TAG_TEXT_TO_HTML_UNIT_TEST_SCRIPT := $(TEXT_TO_HTML_TESTS_DIR)/test_tag_text_to_ # Add -t to each normative tag input filename and add prefix of "/" to make into absolute pathname. NORM_TAG_FILE_ARGS := $(foreach relative_pname,$(BUILT_TEST_NORM_TAGS_FNAMES),-t /$(relative_pname)) -# Add -d to each normative rule definition filename -GOOD_NORM_RULE_DEF_ARGS := $(foreach relative_pname,$(GOOD_NORM_RULE_DEF_FILES),-d $(relative_pname)) -BAD_NORM_RULE_DEF_ARGS := $(foreach relative_pname,$(BAD_NORM_RULE_DEF_FILES),-d $(relative_pname)) - -# Add --param-def to each parameter definition filename -PARAM_DEF_TEST_ARGS := $(foreach relative_pname,$(PARAM_DEF_TEST_FILES),--param-def $(relative_pname)) - # Provide mapping from a stds doc norm tags JSON file to a URL that one can link to. Used to create links into stds doc. NORM_RULE_DOC2URL_ARGS := $(foreach doc_name,$(DOCS),-tag2url /$(BUILD_DIR)/$(doc_name)$(DOC_NORM_TAG_SUFFIX) $(doc_name).html) @@ -193,44 +140,24 @@ OPTIONS := --trace \ -D build \ --failure-level=WARN - - # Default target .PHONY: all all: test - - # Build tests and compare against expected .PHONY: test test: build-tests compare-tests test-adoc2html test-shared-utils test-text-to-html # Build tests .PHONY: build-tests build-test-tags build-test-norm-rules-json build-test-norm-rules-html -.PHONY: build-test-tags-without-rules build-test-params-json build-test-params-html -.PHONY: build-test-param-adoc build-test-param-table-variants -.PHONY: build-test-csr-table-variants build-test-export-params-to-udb -build-tests: build-test-tags build-test-norm-rules-json build-test-norm-rules-html \ -build-test-tags-without-rules build-test-params-json build-test-params-html build-test-param-adoc \ -build-test-param-table-variants build-test-csr-table-variants \ -build-test-export-params-to-udb +build-tests: build-test-tags build-test-norm-rules-json build-test-norm-rules-html build-test-tags: $(BUILT_TEST_NORM_TAGS_FNAMES) $(BUILT_DUPLICATE_NORM_TAGS_FNAME) build-test-norm-rules-json: $(BUILT_NORM_RULES_JSON) build-test-norm-rules-html: $(BUILT_NORM_RULES_HTML) -build-test-tags-without-rules: $(BUILT_NORM_RULES_TAGS_NO_RULES) -build-test-params-json: $(BUILT_PARAMS_JSON) -build-test-params-html: $(BUILT_PARAMS_HTML) -build-test-param-adoc: $(BUILT_PARAM_ADOC_STAMP) -build-test-param-table-variants: $(BUILT_PARAM_TABLE_VARIANTS_STAMP) -build-test-csr-table-variants: $(BUILT_CSR_TABLE_VARIANTS_STAMP) -build-test-export-params-to-udb: $(BUILT_EXPORT_PARAMS_TO_UDB_STAMP) # Compare tests against expected .PHONY: compare-tests -compare-tests: compare-test-tags compare-test-norm-rules-json compare-test-norm-rules-html \ -compare-test-params-json compare-test-params-html compare-test-params-adoc \ -compare-test-param-adoc-files \ -compare-test-param-table-variants compare-test-csr-table-variants compare-test-export-params-to-udb +compare-tests: compare-test-tags compare-test-norm-rules-json compare-test-norm-rules-html .PHONY: compare-test-tags compare-test-tags: compare-test-ch1-tags compare-test-ch2-tags @@ -255,41 +182,6 @@ compare-test-norm-rules-html: $(EXPECTED_NORM_RULES_HTML) $(BUILT_NORM_RULES_HTM @echo "CHECKING HTML BUILT NORM RULES AGAINST EXPECTED NORM RULES" diff $(EXPECTED_NORM_RULES_HTML) $(BUILT_NORM_RULES_HTML) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) -.PHONY: compare-test-params-json -compare-test-params-json: $(EXPECTED_PARAMS_JSON) $(BUILT_PARAMS_JSON) - @echo "CHECKING JSON BUILT PARAMS AGAINST EXPECTED PARAMS" - diff $(EXPECTED_PARAMS_JSON) $(BUILT_PARAMS_JSON) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) - -.PHONY: compare-test-params-html -compare-test-params-html: $(EXPECTED_PARAMS_HTML) $(BUILT_PARAMS_HTML) - @echo "CHECKING HTML BUILT PARAMS AGAINST EXPECTED PARAMS" - diff $(EXPECTED_PARAMS_HTML) $(BUILT_PARAMS_HTML) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) - -.PHONY: compare-test-params-adoc -compare-test-params-adoc: $(EXPECTED_PARAMS_ADOC) $(BUILT_PARAMS_ADOC) - @echo "CHECKING PARAMS ADOC AGAINST EXPECTED" - diff $(EXPECTED_PARAMS_ADOC) $(BUILT_PARAMS_ADOC) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) - -.PHONY: compare-test-param-adoc-files -compare-test-param-adoc-files: $(EXPECTED_PARAM_ADOC_DIR) $(BUILT_PARAM_ADOC_DIR) - @echo "CHECKING GENERATED PARAM ADOC FILES AGAINST EXPECTED" - diff -r $(EXPECTED_PARAM_ADOC_DIR) $(BUILT_PARAM_ADOC_DIR) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) - -.PHONY: compare-test-param-table-variants -compare-test-param-table-variants: $(EXPECTED_PARAM_TABLE_VARIANTS_DIR) $(BUILT_PARAM_TABLE_VARIANTS_DIR) - @echo "CHECKING PARAM TABLE VARIANT OUTPUTS AGAINST EXPECTED" - diff -r $(EXPECTED_PARAM_TABLE_VARIANTS_DIR) $(BUILT_PARAM_TABLE_VARIANTS_DIR) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) - -.PHONY: compare-test-csr-table-variants -compare-test-csr-table-variants: $(EXPECTED_CSR_TABLE_VARIANTS_DIR) $(BUILT_CSR_TABLE_VARIANTS_DIR) - @echo "CHECKING CSR TABLE VARIANT OUTPUTS AGAINST EXPECTED" - diff -r $(EXPECTED_CSR_TABLE_VARIANTS_DIR) $(BUILT_CSR_TABLE_VARIANTS_DIR) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) - -.PHONY: compare-test-export-params-to-udb -compare-test-export-params-to-udb: $(EXPECTED_EXPORT_PARAMS_TO_UDB_DIR) $(BUILT_EXPORT_PARAMS_TO_UDB_DIR) - @echo "CHECKING GENERATED EXPORT PARAMS TO UDB FILES AGAINST EXPECTED" - diff -r $(EXPECTED_EXPORT_PARAMS_TO_UDB_DIR) $(BUILT_EXPORT_PARAMS_TO_UDB_DIR) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) - # Test Adoc2HTML converter behavior in isolation. .PHONY: test-adoc2html test-adoc2html: $(ADOC2HTML_TEST_SCRIPT) $(TOOLS_DIR)/adoc_to_html.py @@ -326,12 +218,7 @@ test-tag-text-to-html-unit: $(TAG_TEXT_TO_HTML_UNIT_TEST_SCRIPT) $(TOOLS_DIR)/ta # .PHONY: update-expected -update-expected: update-test-tags update-test-norm-rules-json update-test-norm-rules-html update-test-params-json update-test-params-html update-test-params-adoc update-test-param-adoc-files update-test-param-table-variants update-test-csr-table-variants update-test-export-params-to-udb -# Update expected UDB YAMLs from built UDB YAMLs -.PHONY: update-test-export-params-to-udb -update-test-export-params-to-udb: build-test-export-params-to-udb - rm -rf $(PARAMS_EXPECTED_DIR)/test-export-params-to-udb - cp -r $(BUILD_DIR)/test-export-params-to-udb $(PARAMS_EXPECTED_DIR)/test-export-params-to-udb +update-expected: update-test-tags update-test-norm-rules-json update-test-norm-rules-html .PHONY: update-test-tags update-test-tags: update-test-ch1-tags update-test-ch2-tags @@ -352,36 +239,6 @@ update-test-norm-rules-json: $(BUILT_NORM_RULES_JSON) update-test-norm-rules-html: $(BUILT_NORM_RULES_HTML) cp -f $(BUILT_NORM_RULES_HTML) $(EXPECTED_NORM_RULES_HTML) -.PHONY: update-test-params-json -update-test-params-json: $(BUILT_PARAMS_JSON) - mkdir -p $(PARAMS_EXPECTED_DIR) - cp -f $(BUILT_PARAMS_JSON) $(EXPECTED_PARAMS_JSON) - -.PHONY: update-test-params-html -update-test-params-html: $(BUILT_PARAMS_HTML) - mkdir -p $(PARAMS_EXPECTED_DIR) - cp -f $(BUILT_PARAMS_HTML) $(EXPECTED_PARAMS_HTML) - -.PHONY: update-test-params-adoc -update-test-params-adoc: $(BUILT_PARAMS_ADOC) - mkdir -p $(PARAMS_EXPECTED_DIR) - cp -f $(BUILT_PARAMS_ADOC) $(EXPECTED_PARAMS_ADOC) - -.PHONY: update-test-param-adoc-files -update-test-param-adoc-files: $(BUILT_PARAM_ADOC_DIR) - rm -rf $(EXPECTED_PARAM_ADOC_DIR) - cp -r $(BUILT_PARAM_ADOC_DIR) $(EXPECTED_PARAM_ADOC_DIR) - -.PHONY: update-test-param-table-variants -update-test-param-table-variants: $(BUILT_PARAM_TABLE_VARIANTS_DIR) - rm -rf $(EXPECTED_PARAM_TABLE_VARIANTS_DIR) - cp -r $(BUILT_PARAM_TABLE_VARIANTS_DIR) $(EXPECTED_PARAM_TABLE_VARIANTS_DIR) - -.PHONY: update-test-csr-table-variants -update-test-csr-table-variants: $(BUILT_CSR_TABLE_VARIANTS_DIR) - rm -rf $(EXPECTED_CSR_TABLE_VARIANTS_DIR) - cp -r $(BUILT_CSR_TABLE_VARIANTS_DIR) $(EXPECTED_CSR_TABLE_VARIANTS_DIR) - # Build normative tags with ch1 adoc input $(BUILT_TEST_CH1_NORM_TAGS_FNAME): $(NORM_RULE_TESTS_DIR)/$(TEST_CH1_INPUT_ADOC_FNAME) $(CONVERTERS_DIR)/$(TAGS_BACKEND) $(WORKDIR_SETUP) @@ -402,58 +259,17 @@ $(BUILT_DUPLICATE_NORM_TAGS_FNAME): $(TAGS_TESTS_DIR)/$(DUPLICATE_TEST_ADOC_INPU $(WORKDIR_TEARDOWN) # Build normative rules with JSON output format -$(BUILT_NORM_RULES_JSON): $(BUILT_TEST_NORM_TAGS_FNAMES) $(GOOD_NORM_RULE_DEF_FILES) +$(BUILT_NORM_RULES_JSON): $(BUILT_TEST_NORM_TAGS_FNAMES) $(CREATE_NORM_RULE_TOOL) $(WORKDIR_SETUP) cp -f $(BUILT_TEST_NORM_TAGS_FNAMES) $@.workdir - $(DOCKER_CMD) $(DOCKER_QUOTE) $(CREATE_NORM_RULE_TOOL) -j $(NORM_TAG_FILE_ARGS) $(GOOD_NORM_RULE_DEF_ARGS) $(NORM_RULE_DOC2URL_ARGS) $@ $(DOCKER_QUOTE) - $(WORKDIR_TEARDOWN) - -# Build params JSON output from generated normative rules JSON and parameter definitions. -$(BUILT_PARAMS_JSON): $(BUILT_NORM_RULES_JSON) $(PARAM_DEF_TEST_FILES) $(CREATE_PARAMS_TOOL) - $(WORKDIR_SETUP) - cp -f $(BUILT_NORM_RULES_JSON) $@.workdir/$(BUILD_DIR) - $(DOCKER_CMD) $(DOCKER_QUOTE) $(CREATE_PARAMS_PYTHON) --norm-rules $(BUILT_NORM_RULES_JSON) $(PARAM_DEF_TEST_ARGS) --output $(BUILT_PARAMS_JSON) $(DOCKER_QUOTE) - $(WORKDIR_TEARDOWN) - -# Build params HTML output from generated normative rules JSON and parameter definitions. -$(BUILT_PARAMS_HTML): $(BUILT_NORM_RULES_JSON) $(PARAM_DEF_TEST_FILES) $(CREATE_PARAMS_TOOL) - $(WORKDIR_SETUP) - cp -f $(BUILT_NORM_RULES_JSON) $@.workdir/$(BUILD_DIR) - $(DOCKER_CMD) $(DOCKER_QUOTE) $(CREATE_PARAMS_PYTHON) --html --norm-rules $(BUILT_NORM_RULES_JSON) $(PARAM_DEF_TEST_ARGS) --output $(BUILT_PARAMS_HTML) $(DOCKER_QUOTE) - $(WORKDIR_TEARDOWN) - -# Build parameter AsciiDoc row fragments from generated params JSON. -$(BUILT_PARAM_ADOC_STAMP): $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) $(CREATE_PARAM_TABLES_TOOL) $(PARAMS_ADOC_SOURCE) $(PARAM_TABLE_SCHEMA_INPUT) $(CSR_TABLE_SCHEMA_INPUT) - $(WORKDIR_SETUP) - cp -f $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) $@.workdir/$(BUILD_DIR) - cp -f $(PARAMS_ADOC_SOURCE) $@.workdir/$(BUILT_PARAMS_ADOC) - $(DOCKER_CMD) $(DOCKER_QUOTE) $(CREATE_PARAM_TABLES_PYTHON) --input $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) --param-table $(PARAM_TABLE_SCHEMA_INPUT) --csr-table $(CSR_TABLE_SCHEMA_INPUT) --output-dir $(BUILT_PARAM_ADOC_DIR) && touch $(BUILT_PARAM_ADOC_STAMP) $(DOCKER_QUOTE) - rm -rf $(BUILT_PARAM_ADOC_DIR) - mv $@.workdir/$(BUILT_PARAM_ADOC_DIR) $(BUILT_PARAM_ADOC_DIR) - mv $@.workdir/$(BUILT_PARAMS_ADOC) $(BUILT_PARAMS_ADOC) - $(WORKDIR_TEARDOWN) - -$(BUILT_PARAM_TABLE_VARIANTS_STAMP): $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) $(CREATE_PARAM_TABLES_TOOL) $(PARAM_TABLE_VARIANT_FILES) - $(WORKDIR_SETUP) - cp -f $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) $@.workdir/$(BUILD_DIR) - $(DOCKER_CMD) $(DOCKER_QUOTE) set -e; rm -rf $(BUILT_PARAM_TABLE_VARIANTS_DIR); mkdir -p $(BUILT_PARAM_TABLE_VARIANTS_DIR); $(foreach f,$(PARAM_TABLE_VARIANT_FILES),python3 $(CREATE_PARAM_TABLES_TOOL) --input $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) --param-table $(f) --output-dir $(BUILT_PARAM_TABLE_VARIANTS_DIR)/$(basename $(notdir $(f))); ) touch $(BUILT_PARAM_TABLE_VARIANTS_STAMP) $(DOCKER_QUOTE) - rm -rf $(BUILT_PARAM_TABLE_VARIANTS_DIR) - mv $@.workdir/$(BUILT_PARAM_TABLE_VARIANTS_DIR) $(BUILT_PARAM_TABLE_VARIANTS_DIR) - $(WORKDIR_TEARDOWN) - -$(BUILT_CSR_TABLE_VARIANTS_STAMP): $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) $(CREATE_PARAM_TABLES_TOOL) $(CSR_TABLE_VARIANT_FILES) - $(WORKDIR_SETUP) - cp -f $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) $@.workdir/$(BUILD_DIR) - $(DOCKER_CMD) $(DOCKER_QUOTE) set -e; rm -rf $(BUILT_CSR_TABLE_VARIANTS_DIR); mkdir -p $(BUILT_CSR_TABLE_VARIANTS_DIR); $(foreach f,$(CSR_TABLE_VARIANT_FILES),python3 $(CREATE_PARAM_TABLES_TOOL) --input $(BUILD_DIR)/$(PARAMS_JSON_OUTPUT_FNAME) --csr-table $(f) --output-dir $(BUILT_CSR_TABLE_VARIANTS_DIR)/$(basename $(notdir $(f))); ) touch $(BUILT_CSR_TABLE_VARIANTS_STAMP) $(DOCKER_QUOTE) - rm -rf $(BUILT_CSR_TABLE_VARIANTS_DIR) - mv $@.workdir/$(BUILT_CSR_TABLE_VARIANTS_DIR) $(BUILT_CSR_TABLE_VARIANTS_DIR) + $(DOCKER_CMD) $(DOCKER_QUOTE) $(CREATE_NORM_RULE_TOOL) -j $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DOC2URL_ARGS) $@ $(DOCKER_QUOTE) $(WORKDIR_TEARDOWN) # Build normative rules with HTML output format -$(BUILT_NORM_RULES_HTML): $(BUILT_TEST_NORM_TAGS_FNAMES) $(GOOD_NORM_RULE_DEF_FILES) $(BUILT_TEST_HTML_FNAMES) +$(BUILT_NORM_RULES_HTML): $(BUILT_TEST_NORM_TAGS_FNAMES) $(CREATE_NORM_RULE_TOOL) $(BUILT_TEST_HTML_FNAMES) $(WORKDIR_SETUP) cp -f $(BUILT_TEST_NORM_TAGS_FNAMES) $@.workdir - $(DOCKER_CMD) $(DOCKER_QUOTE) $(CREATE_NORM_RULE_TOOL) --html $(NORM_TAG_FILE_ARGS) $(GOOD_NORM_RULE_DEF_ARGS) $(NORM_RULE_DOC2URL_ARGS) $@ $(DOCKER_QUOTE) + $(DOCKER_CMD) $(DOCKER_QUOTE) $(CREATE_NORM_RULE_TOOL) --html $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DOC2URL_ARGS) $@ $(DOCKER_QUOTE) $(WORKDIR_TEARDOWN) # This is the HTML file that represents the standards doc. THe norm rule HTML links into this HTML. @@ -468,21 +284,6 @@ $(BUILT_TEST_CH2_HTML_FNAME) : $(NORM_RULE_TESTS_DIR)/$(TEST_CH2_INPUT_ADOC_FNAM $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_HTML) -o $@ $< $(DOCKER_QUOTE) $(WORKDIR_TEARDOWN) -# Build normative rules with different YAML that should create an error due to tags without norm rules referencing them. -# Should exit with a non-zero status and then we just "touch" the output file so it exists and make is happy. -$(BUILT_NORM_RULES_TAGS_NO_RULES): $(BUILT_TEST_CH1_NORM_TAGS_FNAME) $(BAD_NORM_RULE_DEF_FILES) - $(WORKDIR_SETUP) - cp -f $(BUILT_TEST_CH1_NORM_TAGS_FNAME) $@.workdir - $(DOCKER_CMD) $(DOCKER_QUOTE) $(CREATE_NORM_RULE_TOOL) $(NORM_TAG_FILE_ARGS) $(BAD_NORM_RULE_DEF_ARGS) $(NORM_RULE_DOC2URL_ARGS) $(BUILD_DIR)/bogus || touch $(BUILT_NORM_RULES_TAGS_NO_RULES) $(DOCKER_QUOTE) - $(WORKDIR_TEARDOWN) - -$(BUILT_EXPORT_PARAMS_TO_UDB_STAMP): $(BUILT_PARAMS_JSON) $(EXPORT_PARAMS_TO_UDB_TOOL) - $(WORKDIR_SETUP) - cp -f $(BUILT_PARAMS_JSON) $@.workdir/$(BUILD_DIR) - $(DOCKER_CMD) $(DOCKER_QUOTE) $(EXPORT_PARAMS_TO_UDB_PYTHON) --input $(BUILT_PARAMS_JSON) --output-dir $(BUILT_EXPORT_PARAMS_TO_UDB_DIR) && touch $(BUILT_EXPORT_PARAMS_TO_UDB_STAMP) $(DOCKER_QUOTE) - mv $@.workdir/$(BUILT_EXPORT_PARAMS_TO_UDB_DIR) $(BUILT_EXPORT_PARAMS_TO_UDB_DIR) - $(WORKDIR_TEARDOWN) - # Update docker image to latest docker-pull-latest: ${DOCKER_BIN} pull ${DOCKER_IMG} diff --git a/converters/tags.rb b/converters/tags.rb index 9f8b4b3..664c1cb 100644 --- a/converters/tags.rb +++ b/converters/tags.rb @@ -13,6 +13,7 @@ class TagsConverter # # * title: String - Section title. # * id: String - Generated ID for the title which can be used for HTML links. + # * level: Integer - Section level (0 for a part of a book, 1 for a chapter, ...). # * children: Array
- Child sections. # * tags: Array - List of tags in this section directly (not in children). # @@ -71,6 +72,7 @@ def convert(node, transform = node.node_name, opts = nil) section = { "title" => node.title, "id" => node.id, + "level" => node.level, "children" => [], "tags" => [], } diff --git a/normative-rules.md b/normative-rules.md index 7cdf2a5..4db3d15 100644 --- a/normative-rules.md +++ b/normative-rules.md @@ -24,17 +24,14 @@ Normative rules specify the behaviors an implementation must meet in order to be RISC-V International standards are written in an open-source markup language known as [AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest). If normative rules are not explicitly listed in the visible content of a standard (usually in tables with a unique ID for each normative rule), the AsciiDoc anchor facility is used to "tag" normative text. This latter case is the focus of the remainder of this document. -When normative rules aren't explicitly listed by a standard, it is likely the standard was written without easy identification of normative rules in mind. This can lead to multiple normative rules being located in one tag (tag = anchored section of normative text) known as a "many:1" mapping (many normative rules mapped to one tag) or a normative rule needing to reference multiple tags known as a "1:many" mapping (one normative rule mapped to multiple tags). Here's examples of these cases: -* "many:1" (normative rules for ANDI, ORI, and XORI instructions mapped to one tag)
+Each tag (tag = anchored section of normative text) is one normative rule, and the rule's name is the tag's anchor name without the `norm:` prefix. There is no separate definition of normative rules and no mapping between normative rules and tags, so one normative rule never spans several tags and one tag never holds several normative rules. When a sentence states several behaviors at once, tag it once and name the tag for all of them. For example, one tag named `norm:andi_ori_xori_op` covers:
`ANDI, ORI, XORI are logical operations that perform bitwise AND, OR, and XOR on register rs1 and the sign-extended 12-bit immediate and place the result in rd.` -* "1:many"
-TBD: waiting for ideal example -Quite often there is a "1:1" mapping between normative rules and tags, but not always! Because of this "not always" reality, standards provide YAML files that provide the mapping between normative rules and tags. This repository contains a simple Ruby script that uses these YAML files to create the canonical list of normative rules for its associated standard. This script can output these normative rules in formats suitable for both human-friendly and machine-readable formats. +This repository contains a Python script (`tools/create_normative_rules.py`) that reads the tags extracted from a standard and creates the canonical list of normative rules for that standard. This script can output these normative rules in formats suitable for both human-friendly and machine-readable formats. ## AsciiDoc Anchor Background -AsciiDoc provides facilities to create invisible anchors associated with an entire paragraph or portions of a paragraph. These anchors are only visible in raw AsciiDoc files and are invisible in the PDF and GitHub AsciiDoc previewer. Each "tag" added to an AsciiDoc file to identify normative text (remember, not always a 1:1 mapping from normative rules to tags) has an associated anchor name. These anchor names must be unique across all the AsciiDoc files used by a particular standard but aren't required to be unique across standards. Each RISC-V standard defines the naming convention of these anchor names but the anchor names must start with the prefix of "norm:" so they can be readily located by tools. +AsciiDoc provides facilities to create invisible anchors associated with an entire paragraph or portions of a paragraph. These anchors are only visible in raw AsciiDoc files and are invisible in the PDF and GitHub AsciiDoc previewer. Each "tag" added to an AsciiDoc file to identify normative text is one normative rule and has an associated anchor name. These anchor names must be unique across all the AsciiDoc files used by a particular standard but aren't required to be unique across standards. Each RISC-V standard defines the naming convention of these anchor names but the anchor names must start with the prefix of "norm:" so they can be readily located by tools. AsciiDoc supports several styles of anchors: * _inline anchor_ such as:
diff --git a/schemas/common-schema.json b/schemas/common-schema.json deleted file mode 100644 index 2bd8255..0000000 --- a/schemas/common-schema.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - - "title": "Common content used by multiple schemas (reduces copy & paste)", - - "summaryDesc": { - "description": "Short summary of the normative rule (just a few words)" - }, - "clarificationTextDesc": { - "description": "Provides text to supplement information available in the standards documentation.\nOnly use this until clarifying text is in the standards documentation or its authors have decided against adding it." - }, - "clarificationLinkDesc": { - "description": "Provides link to clarification GitHub issue in the standards documentation repository" - }, - "noteDesc": { - "description": "A non-normative note about the normative rule" - }, - "descriptionDesc": { - "description": "Comprehensive description of the normative rule (sentence, paragraph, or longer)" - }, - "kindRuleDesc": { - "description": "The kind of standards object associated with this normative rule\nChoices are extension, extension_dependency, instruction, csr, or csr_field." - }, - "instanceRuleDesc": { - "description": "The name of a standards object of the specified kind associated with this normative rule" - }, - "instancesRuleDesc": { - "description": "The names of standards objects of the specified kind associated with this normative rule" - }, - "implDefBehaviorDesc": { - "description": "A normative rule that allows an implementation choices in how to meet the rule" - }, - "implDefCategoryTypeDesc": { - "description": "Category of implementation-defined behavior (if any)" - }, - "stringArray": { - "type": "array", - "items": { "type": "string" }, - "minItems": 1 - }, - "ruleNamePattern" : { - "pattern": "^[a-zA-z][a-zA-z0-9_-]+$" - }, - "implDefNamePattern" : { - "pattern": "^[A-Z][A-Z0-9_]+$" - }, - "tagNamePattern" : { - "pattern": "^[a-zA-z][:a-zA-z0-9_-]+$" - }, - "stdsObjectKind": { - "type": "string", - "enum": ["base", "extension", "extension_dependency", "instruction", "csr", "csr_field"] - }, - "bases": { - "type": "string", - "enum": ["Any", "RV32I", "RV32E", "RV64I", "RV64E"] - }, - "implDefBehavior": { - "type": "boolean" - }, - "implDefCategoryType": { - "type": "string", - "enum": ["WARL", "WLRL"] - }, - "ruleName": { - "type": "string", - "$ref": "#/ruleNamePattern" - }, - "ruleNameArray": { - "type": "array", - "items": { - "type": "string", - "$ref": "#/ruleNamePattern" - }, - "minItems": 1 - }, - "implDefName": { - "type": "string", - "$ref": "#/implDefNamePattern" - }, - "implDefNameArray": { - "type": "array", - "items": { - "type": "string", - "$ref": "#/implDefNamePattern" - }, - "minItems": 1 - }, - "tagName": { - "type": "string", - "$ref": "#/tagNamePattern" - }, - "tagObject": { - "type": "object", - "properties": { - "name": { "$ref": "#/tagName" }, - "context": { - "type": "boolean", - "description": "Indicates tag provided for context to provide clarity for the non-context tag(s)" - } - }, - "required": ["name"], - "additionalProperties": false - }, - "tagNameArray": { - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/tagName" }, - { "$ref": "#/tagObject" } - ] - }, - "minItems": 1 - } -} diff --git a/schemas/csr-table-schema.json b/schemas/csr-table-schema.json deleted file mode 100644 index 2c98e30..0000000 --- a/schemas/csr-table-schema.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Schema for CSR table layout files", - "type": "object", - "properties": { - "$schema": { - "type": "string", - "description": "Optional path/URI to this schema" - }, - "columns": { - "type": "array", - "description": "Ordered list of CSR columns from left to right", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1, - "description": "Display name of the column" - }, - "column": { - "type": "string", - "description": "Canonical column identifier", - "enum": [ - "NAME", - "TYPE", - "FEATURES", - "IMPLEMENTATION_DEFINED_BEHAVIORS" - ] - }, - "width_pct": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 100, - "description": "Percentage of total table width allocated to this column" - } - }, - "required": ["name", "column", "width_pct"], - "additionalProperties": false - } - } - }, - "required": ["columns"], - "additionalProperties": false -} diff --git a/schemas/defs-schema.json b/schemas/defs-schema.json deleted file mode 100644 index 8b03102..0000000 --- a/schemas/defs-schema.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Schema for normative rule definitions input files", - "type": "object", - - "properties": { - "$schema": { - "type": "string" - }, - "chapter_name": { - "type": "string", - "description": "Name of chapter (keep it short) in standards document associated with normative rules definitions" - }, - "normative_rule_definitions": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "name": { - "$ref": "common-schema.json#/ruleName", - "description": "Single normative rule name" - }, - "names": { - "$ref": "common-schema.json#/ruleNameArray", - "description": "Multiple normative rule names" - }, - "summary": { - "type": "string", - "$ref": "common-schema.json#/summaryDesc" - }, - "note": { - "type": "string", - "$ref": "common-schema.json#/noteDesc" - }, - "clarification-text": { - "type": "string", - "$ref": "common-schema.json#/clarificationTextDesc" - }, - "clarification-link": { - "type": "string", - "format": "uri", - "pattern": "^https://(www.)?github.com/riscv/.+/issues/[0-9]+$", - "$ref": "common-schema.json#/clarificationLinkDesc" - }, - "description": { - "type": "string", - "$ref": "common-schema.json#/descriptionDesc" - }, - "kind": { - "allOf": [ - { "$ref": "common-schema.json#/stdsObjectKind" }, - { "$ref": "common-schema.json#/kindRuleDesc" } - ] - }, - "instance": { - "type": "string", - "$ref": "common-schema.json#/instanceRuleDesc" - }, - "instances": { - "allOf": [ - { "$ref": "common-schema.json#/stringArray" }, - { "$ref": "common-schema.json#/instancesRuleDesc" } - ] - }, - "impl-def-behavior": { - "allOf": [ - { "$ref": "common-schema.json#/implDefBehavior" }, - { "$ref": "common-schema.json#/implDefBehaviorDesc" } - ] - }, - "impl-def-category": { - "allOf": [ - { "$ref": "common-schema.json#/implDefCategoryType" }, - { "$ref": "common-schema.json#/implDefCategoryTypeDesc" } - ] - }, - "tag": { - "$ref": "common-schema.json#/tagName", - "description": "Name of tag containing normative text" - }, - "tags": { - "$ref": "common-schema.json#/tagNameArray", - "description": "List of tag names containing normative text" - } - }, - "allOf": [ - { - "oneOf": [ - { "required": ["name"] }, - { "required": ["names"] } - ] - }, - { - "not": { - "required": ["tag", "tags"] - } - }, - { - "not": { - "required": ["instance", "instances"] - } - }, - { - "if": { - "properties": { - "impl-def-behavior": { "const": true } - }, - "required": ["impl-def-behavior"] - }, - "then": { - "properties": { - "name": { "$ref": "common-schema.json#/implDefName" } - } - }, - "else": { - "properties": { - "name": { "$ref": "common-schema.json#/ruleName" } - } - } - }, - { - "if": { - "properties": { - "impl-def-behavior": { "const": true } - }, - "required": ["impl-def-behavior"] - }, - "then": { - "properties": { - "names": { "$ref": "common-schema.json#/implDefNameArray" } - } - }, - "else": { - "properties": { - "names": { "$ref": "common-schema.json#/ruleNameArray" } - } - } - }, - { - "if": { - "properties": { - "kind": { "const": "base" } - }, - "required": ["kind"] - }, - "then": { - "properties": { - "instance": { - "$ref": "common-schema.json#/bases" - }, - "instances": { - "type": "array", - "items": { - "$ref": "common-schema.json#/bases" - }, - "minItems": 1 - } - } - } - }, - { - "if": { - "required": ["impl-def-category"] - }, - "then": { - "required": ["impl-def-behavior"], - "properties": { - "impl-def-behavior": { "const": true } - } - } - } - ], - "dependencies": { - "clarification-text": ["clarification-link"] - }, - "additionalProperties": false - } - } - }, - "required": ["$schema", "chapter_name", "normative_rule_definitions"], - "additionalProperties": false -} diff --git a/schemas/norm-rules-schema.json b/schemas/norm-rules-schema.json index c4084ec..74b021d 100644 --- a/schemas/norm-rules-schema.json +++ b/schemas/norm-rules-schema.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Schema for norm-rules.json", + "description": "Each normative tag in a standards document is one normative rule. The rule name is the tag name without the \"norm:\" prefix.", "type": "object", "definitions": { @@ -8,149 +9,27 @@ "type": "object", "properties": { "name": { - "type": "string", - "description": "Normative rule name" - }, - "def_filename": { "type": "string", - "description": "Normative rule definition file that defines this rule" + "description": "Normative rule name (the tag name without the \"norm:\" prefix)" }, "chapter_name": { "type": "string", - "description": "Normative rules for specified chapter in standards document" - }, - "summary": { - "type": "string", - "$ref": "common-schema.json#/summaryDesc" + "description": "Title of the chapter in the standards document that contains the tag" }, - "note": { + "text": { "type": "string", - "$ref": "common-schema.json#/noteDesc" + "description": "Text of the tag in the standards document" }, - "clarification-text": { + "tag_filename": { "type": "string", - "$ref": "common-schema.json#/clarificationTextDesc" + "description": "Name of the tag file that contains the tag" }, - "clarification-link": { + "stds_doc_url": { "type": "string", - "format": "uri", - "pattern": "^https://(www.)?github.com/riscv/.+/issues/[0-9]+$", - "$ref": "common-schema.json#/clarificationLinkDesc" - }, - "description": { - "type": "string", - "$ref": "common-schema.json#/descriptionDesc" - }, - "kind": { - "allOf": [ - { "$ref": "common-schema.json#/stdsObjectKind" }, - { "$ref": "common-schema.json#/kindRuleDesc" } - ] - }, - "instances": { - "allOf": [ - { "$ref": "common-schema.json#/stringArray" }, - { "$ref": "common-schema.json#/instancesRuleDesc" } - ] - }, - "impl-def-behavior": { - "allOf": [ - { "$ref": "common-schema.json#/implDefBehavior" }, - { "$ref": "common-schema.json#/implDefBehaviorDesc" } - ] - }, - "impl-def-category": { - "allOf": [ - { "$ref": "common-schema.json#/implDefCategoryType" }, - { "$ref": "common-schema.json#/implDefCategoryTypeDesc" } - ] - }, - "tags": { - "type": "array", - "description": "List of normative rule tags", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "name": { - "$ref": "common-schema.json#/tagName", - "description": "Name of the tag (an anchor in the standard's adoc files)" - }, - "context": { - "type": "boolean", - "description": "Indicates tag provided for context to provide clarity for the non-context tag(s)" - }, - "text": { - "type": "string", - "description": "The text from the standard associated with this tag" - }, - "tag_filename": { - "type": "string", - "description": "Tag file that maps tag names to tag text" - }, - "stds_doc_url": { - "type": "string", - "description": "URL to standards doc associated with tag_filename" - } - }, - "required": ["name", "context"] - } + "description": "URL of the standards document that contains the tag" } }, - "required": ["name", "def_filename", "chapter_name"], - "dependencies": { - "tag_filename": ["stds_doc_url"] - }, - "allOf": [ - { - "if": { - "properties": { - "impl-def-behavior": { "const": true } - }, - "required": ["impl-def-behavior"] - }, - "then": { - "properties": { - "name": { "$ref": "common-schema.json#/implDefName" } - } - }, - "else": { - "properties": { - "name": { "$ref": "common-schema.json#/ruleName" } - } - } - }, - { - "if": { - "properties": { - "kind": { "const": "base" } - }, - "required": ["kind"] - }, - "then": { - "properties": { - "instances": { - "type": "array", - "items": { - "$ref": "common-schema.json#/bases" - }, - "minItems": 1 - } - } - } - }, - { - "if": { - "required": ["impl-def-category"] - }, - "then": { - "required": ["impl-def-behavior"], - "properties": { - "impl-def-behavior": { "const": true } - } - } - } - ], + "required": ["name", "chapter_name", "text", "tag_filename", "stds_doc_url"], "additionalProperties": false } }, @@ -158,7 +37,6 @@ "properties": { "normative_rules": { "type": "array", - "minItems": 1, "items": { "$ref": "#/definitions/normativeRuleEntry" } diff --git a/schemas/param-common-schema.json b/schemas/param-common-schema.json deleted file mode 100644 index 7ef5cd4..0000000 --- a/schemas/param-common-schema.json +++ /dev/null @@ -1,152 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - - "title": "Common content used by multiple parameter schemas (reduces copy & paste)", - - "noteDesc": { - "description": "A non-normative note about the normative rule" - }, - "descriptionDesc": { - "description": "Comprehensive description of the normative rule (sentence, paragraph, or longer)" - }, - "implDefBehaviorDesc": { - "description": "A normative rule that allows an implementation choices in how to meet the rule" - }, - "paramBehaviorDesc": { - "description": "A parameter that maps to one or more implementation-defined behaviors in the standards documentation" - }, - "paramTypeDesc": { - "description": "Can be boolean, bit, byte, hword, word, dword, int, uint, array of strings, or array of integers. Use \"range\" for min/max ranges. Specify width property for int/uint" - }, - "paramRangeDesc": { - "description": "Array of 2 integers specifying lower and upper bound (in that order)" - }, - "paramWidthDesc": { - "description": "Either an integer bit width between 2 and 64 (inclusive) or the name of another parameter that provides the bit width. Used only with type \"int\" or \"uint\"" - }, - "csrWidthParameterDesc": { - "description": "Name of the parameter referenced by a CSR entry. Required only when type is \"VarWidth\"." - }, - "csrTypeDesc": { - "description": "CSR encoding type discriminator. Legal values are \"LegalEnum\", \"VarWidth\", \"ConstMask\", and \"Other\"." - }, - "paramType": { - "oneOf": [ - { - "type": "string", - "pattern": "^(boolean|bit|byte|hword|word|dword|int|uint)$" - }, - { - "type": "array", - "items": { "type": "string" }, - "minItems": 1 - }, - { - "type": "array", - "items": { "type": "integer" }, - "minItems": 1 - } - ] - }, - "paramRange": { - "type": "array", - "description": "Inclusive range [lo, hi] as two integers", - "items": { - "type": "integer" - }, - "minItems": 2, - "maxItems": 2 - }, - "paramArray": { - "type": "array", - "description": "Inclusive index bounds [lo, hi] as two non-negative integers", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "paramWidth": { - "oneOf": [ - { - "type": "integer", - "minimum": 2, - "maximum": 64 - }, - { - "$ref": "#/paramName" - } - ] - }, - "csrCategory": { - "type": "string", - "enum": ["WARL", "WLRL"] - }, - "csrType": { - "type": "string", - "enum": ["LegalEnum", "VarWidth", "ConstMask", "Other"] - }, - "stringArray": { - "type": "array", - "items": { "type": "string" }, - "minItems": 1 - }, - "implDefNamePattern" : { - "pattern": "^[A-Z][A-Z0-9_]+$" - }, - "paramNamePattern" : { - "$ref": "#/implDefNamePattern" - }, - "csrNamePattern" : { - "pattern": "^[a-zA-Z][a-zA-Z0-9_]+$" - }, - "implDefName": { - "type": "string", - "$ref": "#/implDefNamePattern" - }, - "implDefNameArray": { - "type": "array", - "items": { - "type": "string", - "$ref": "#/implDefNamePattern" - }, - "minItems": 1 - }, - "paramName": { - "type": "string", - "$ref": "#/paramNamePattern" - }, - "paramNameArray": { - "type": "array", - "items": { - "type": "string", - "$ref": "#/paramNamePattern" - }, - "minItems": 1 - }, - "csrName": { - "type": "string", - "$ref": "#/csrNamePattern" - }, - "csrNameArray": { - "type": "array", - "items": { - "type": "string", - "$ref": "#/csrNamePattern" - }, - "minItems": 1 - }, - "funcOfRegName": { - "allOf": [ - { "$ref": "#/csrName" }, - { "description": "CSR name associated with function-of relationship" } - ] - }, - "funcOfFieldName": { - "allOf": [ - { "$ref": "#/csrName" }, - { "description": "CSR field name associated with function-of relationship" } - ] - } -} diff --git a/schemas/param-defs-schema.json b/schemas/param-defs-schema.json deleted file mode 100644 index 9c02b78..0000000 --- a/schemas/param-defs-schema.json +++ /dev/null @@ -1,229 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Schema for parameter definition input files", - "type": "object", - - "properties": { - "$schema": { - "type": "string" - }, - "chapter_name": { - "type": "string", - "description": "Name of chapter (keep it short) in standards document associated with parameter definitions" - }, - "parameter_definitions": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "name": { - "$ref": "param-common-schema.json#/paramName", - "description": "Single parameter name" - }, - "names": { - "$ref": "param-common-schema.json#/paramNameArray", - "description": "Multiple parameter names" - }, - "long-name": { - "type": "string", - "description": "Long name of the parameter (a few words)" - }, - "note": { - "type": "string", - "$ref": "param-common-schema.json#/noteDesc" - }, - "description": { - "type": "string", - "$ref": "param-common-schema.json#/descriptionDesc" - }, - "impl-def": { - "$ref": "param-common-schema.json#/implDefName", - "description": "Name of implementation-defined behavior" - }, - "impl-defs": { - "$ref": "param-common-schema.json#/implDefNameArray", - "description": "List of implementation-defined behaviors" - }, - "type": { - "$ref": "param-common-schema.json#/paramType" - }, - "range": { - "$ref": "param-common-schema.json#/paramRange" - }, - "array": { - "$ref": "param-common-schema.json#/paramArray" - }, - "width": { - "allOf": [ - { "$ref": "param-common-schema.json#/paramWidth" }, - { "$ref": "param-common-schema.json#/paramWidthDesc" } - ] - } - }, - "allOf": [ - { - "oneOf": [ - { "required": ["type"] }, - { "required": ["range"] } - ] - }, - { - "if": { - "required": ["width"] - }, - "then": { - "properties": { - "type": { - "enum": ["int", "uint"] - } - }, - "required": ["type"] - } - }, - { - "if": { - "properties": { - "type": { - "enum": ["int", "uint"] - } - }, - "required": ["type"] - }, - "then": { - "required": ["width"] - } - }, - { - "oneOf": [ - { "required": ["name"] }, - { "required": ["names"] } - ] - }, - { - "not": { - "required": ["impl-def", "impl-defs"] - } - }, - { - "if": { - "not": { - "anyOf": [ - { "required": ["impl-def"] }, - { "required": ["impl-defs"] } - ] - } - }, - "then": { - "required": ["description"] - } - } - ], - "additionalProperties": false - } - }, - "csr_definitions": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "reg-name": { - "$ref": "param-common-schema.json#/csrName", - "description": "Single CSR name" - }, - "reg-names": { - "$ref": "param-common-schema.json#/csrNameArray", - "description": "Multiple CSR names" - }, - "note": { - "type": "string", - "$ref": "param-common-schema.json#/noteDesc" - }, - "description": { - "type": "string", - "$ref": "param-common-schema.json#/descriptionDesc" - }, - "field-name": { - "$ref": "param-common-schema.json#/csrName", - "description": "Single CSR field name" - }, - "func-of-reg-name": { - "$ref": "param-common-schema.json#/funcOfRegName" - }, - "func-of-field-name": { - "$ref": "param-common-schema.json#/funcOfFieldName" - }, - "field-names": { - "$ref": "param-common-schema.json#/csrNameArray", - "description": "Multiple CSR field names" - }, - "type": { - "allOf": [ - { "$ref": "param-common-schema.json#/csrType" }, - { "$ref": "param-common-schema.json#/csrTypeDesc" } - ] - }, - "width-parameter": { - "allOf": [ - { "$ref": "param-common-schema.json#/paramName" }, - { "$ref": "param-common-schema.json#/csrWidthParameterDesc" } - ] - }, - "impl-def": { - "$ref": "param-common-schema.json#/implDefName", - "description": "Name of implementation-defined behavior" - }, - "impl-defs": { - "$ref": "param-common-schema.json#/implDefNameArray", - "description": "List of implementation-defined behaviors" - } - }, - "allOf": [ - { - "oneOf": [ - { "required": ["reg-name"] }, - { "required": ["reg-names"] } - ] - }, - { - "not": { - "required": ["field-name", "field-names"] - } - }, - { - "required": ["type"] - }, - { - "if": { - "properties": { - "type": { "const": "VarWidth" } - }, - "required": ["type"] - }, - "then": { - "required": ["width-parameter"] - }, - "else": { - "not": { - "required": ["width-parameter"] - } - } - }, - { - "not": { - "required": ["impl-def", "impl-defs"] - } - } - ], - "additionalProperties": false - } - } - }, - "required": ["$schema", "chapter_name"], - "anyOf": [ - { "required": ["parameter_definitions"] }, - { "required": ["csr_definitions"] } - ], - "additionalProperties": false -} diff --git a/schemas/param-table-schema.json b/schemas/param-table-schema.json deleted file mode 100644 index 765ad1a..0000000 --- a/schemas/param-table-schema.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Schema for parameter table layout files", - "type": "object", - "properties": { - "$schema": { - "type": "string", - "description": "Optional path/URI to this schema" - }, - "columns": { - "type": "array", - "description": "Ordered list of parameter columns from left to right", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1, - "description": "Display name of the column" - }, - "column": { - "type": "string", - "description": "Canonical column identifier", - "enum": [ - "PARAM_NAME_AND_NORM_RULE_MAPPING", - "TYPE", - "FEATURES", - "DEFINITION" - ] - }, - "width_pct": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 100, - "description": "Percentage of total table width allocated to this column" - } - }, - "required": ["name", "column", "width_pct"], - "additionalProperties": false - } - } - }, - "required": ["columns"], - "additionalProperties": false -} diff --git a/schemas/params-schema.json b/schemas/params-schema.json deleted file mode 100644 index 67175c7..0000000 --- a/schemas/params-schema.json +++ /dev/null @@ -1,208 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Schema for params.json", - "type": "object", - - "properties": { - "parameters": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "name": { - "$ref": "param-common-schema.json#/paramName", - "description": "Parameter name (all uppercase with underscores for separators)" - }, - "long-name": { - "type": "string", - "description": "Long name of the parameter (a few words)" - }, - "def_filename": { - "type": "string", - "description": "Parameter definition file that defines this parameter" - }, - "chapter_name": { - "type": "string", - "description": "Parameters for specified chapter in standards document" - }, - "note": { - "type": "string", - "$ref": "param-common-schema.json#/noteDesc" - }, - "description": { - "type": "string", - "$ref": "param-common-schema.json#/descriptionDesc" - }, - "type": { - "$ref": "param-common-schema.json#/paramType" - }, - "range": { - "$ref": "param-common-schema.json#/paramRange" - }, - "array": { - "$ref": "param-common-schema.json#/paramArray" - }, - "width": { - "allOf": [ - { "$ref": "param-common-schema.json#/paramWidth" }, - { "$ref": "param-common-schema.json#/paramWidthDesc" } - ] - }, - "json-schema": { - "type": "object", - "description": "JSON Schema equivalent of the type or range property" - }, - "impl-defs": { - "allOf": [ - { - "type": "array", - "items": { - "$ref": "norm-rules-schema.json#/definitions/normativeRuleEntry" - }, - "minItems": 1 - }, - { "$ref": "param-common-schema.json#/implDefBehaviorDesc" } - ] - } - }, - "required": ["name", "long-name", "def_filename", "chapter_name", "json-schema"], - "allOf": [ - { - "oneOf": [ - { "required": ["type"] }, - { "required": ["range"] } - ] - }, - { - "if": { - "required": ["width"] - }, - "then": { - "properties": { - "type": { - "enum": ["int", "uint"] - } - }, - "required": ["type"] - } - }, - { - "if": { - "properties": { - "type": { - "enum": ["int", "uint"] - } - }, - "required": ["type"] - }, - "then": { - "required": ["width"] - } - } - ], - "additionalProperties": false - } - }, - "csrs": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "reg-name": { - "type": "string", - "description": "CSR name" - }, - "field-name": { - "type": "string", - "description": "CSR field name" - }, - "func-of-reg-name": { - "$ref": "param-common-schema.json#/funcOfRegName" - }, - "func-of-field-name": { - "$ref": "param-common-schema.json#/funcOfFieldName" - }, - "def_filename": { - "type": "string", - "description": "Parameter definition file that defines this CSR" - }, - "chapter_name": { - "type": "string", - "description": "CSRs for specified chapter in standards document" - }, - "note": { - "type": "string", - "$ref": "param-common-schema.json#/noteDesc" - }, - "description": { - "type": "string", - "$ref": "param-common-schema.json#/descriptionDesc" - }, - "category": { - "$ref": "param-common-schema.json#/csrCategory", - "description": "CSR category" - }, - "type": { - "allOf": [ - { "$ref": "param-common-schema.json#/csrType" }, - { "$ref": "param-common-schema.json#/csrTypeDesc" } - ] - }, - "width-parameter": { - "allOf": [ - { "$ref": "param-common-schema.json#/paramName" }, - { "$ref": "param-common-schema.json#/csrWidthParameterDesc" } - ] - }, - "impl-defs": { - "allOf": [ - { - "type": "array", - "items": { - "$ref": "norm-rules-schema.json#/definitions/normativeRuleEntry" - }, - "minItems": 1 - }, - { "$ref": "param-common-schema.json#/implDefBehaviorDesc" } - ] - } - }, - "required": ["reg-name", "long-name", "def_filename", "chapter_name", "category", "type"], - "allOf": [ - { - "if": { - "properties": { - "type": { "const": "VarWidth" } - }, - "required": ["type"] - }, - "then": { - "required": ["width-parameter"] - }, - "else": { - "not": { - "required": ["width-parameter"] - } - } - }, - { - "if": { - "required": ["func-of-field-name"] - }, - "then": { - "required": ["func-of-reg-name"] - } - } - ], - "additionalProperties": false - } - } - }, - "anyOf": [ - { "required": ["parameters"] }, - { "required": ["csrs"] } - ], - "additionalProperties": false -} diff --git a/schemas/udb-json-schema-draft-07.json b/schemas/udb-json-schema-draft-07.json deleted file mode 100644 index 252199e..0000000 --- a/schemas/udb-json-schema-draft-07.json +++ /dev/null @@ -1,242 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://json-schema.org/draft-07/schema#", - "title": "Core schema meta-schema", - "definitions": { - "schemaArray": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#" - } - }, - "nonNegativeInteger": { - "type": "integer", - "minimum": 0 - }, - "nonNegativeIntegerDefault0": { - "allOf": [ - { - "$ref": "#/definitions/nonNegativeInteger" - }, - { - "default": 0 - } - ] - }, - "simpleTypes": { - "enum": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ] - }, - "stringArray": { - "type": "array", - "items": { - "type": "string" - }, - "uniqueItems": true, - "default": [] - } - }, - "type": ["object", "boolean"], - "properties": { - "$id": { - "type": "string", - "format": "uri-reference" - }, - "$schema": { - "type": "string", - "format": "uri" - }, - "$ref": { - "type": "string", - "format": "uri-reference" - }, - "$comment": { - "type": "string" - }, - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "default": true, - "readOnly": { - "type": "boolean", - "default": false - }, - "writeOnly": { - "type": "boolean", - "default": false - }, - "examples": { - "type": "array", - "items": true - }, - "multipleOf": { - "type": "number", - "exclusiveMinimum": 0 - }, - "maximum": { - "type": "number" - }, - "exclusiveMaximum": { - "type": "number" - }, - "minimum": { - "type": "number" - }, - "exclusiveMinimum": { - "type": "number" - }, - "maxLength": { - "$ref": "#/definitions/nonNegativeInteger" - }, - "minLength": { - "$ref": "#/definitions/nonNegativeIntegerDefault0" - }, - "pattern": { - "type": "string", - "format": "regex" - }, - "additionalItems": { - "$ref": "#" - }, - "items": { - "anyOf": [ - { - "$ref": "#" - }, - { - "$ref": "#/definitions/schemaArray" - } - ], - "default": true - }, - "maxItems": { - "$ref": "#/definitions/nonNegativeInteger" - }, - "minItems": { - "$ref": "#/definitions/nonNegativeIntegerDefault0" - }, - "uniqueItems": { - "type": "boolean", - "default": false - }, - "contains": { - "$ref": "#" - }, - "maxProperties": { - "$ref": "#/definitions/nonNegativeInteger" - }, - "minProperties": { - "$ref": "#/definitions/nonNegativeIntegerDefault0" - }, - "required": { - "$ref": "#/definitions/stringArray" - }, - "additionalProperties": { - "$ref": "#" - }, - "definitions": { - "type": "object", - "additionalProperties": { - "$ref": "#" - }, - "default": {} - }, - "properties": { - "type": "object", - "additionalProperties": { - "$ref": "#" - }, - "default": {} - }, - "patternProperties": { - "type": "object", - "additionalProperties": { - "$ref": "#" - }, - "propertyNames": { - "format": "regex" - }, - "default": {} - }, - "dependencies": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "$ref": "#" - }, - { - "$ref": "#/definitions/stringArray" - } - ] - } - }, - "propertyNames": { - "$ref": "#" - }, - "const": true, - "enum": { - "type": "array", - "items": true, - "minItems": 1, - "uniqueItems": true - }, - "type": { - "anyOf": [ - { - "$ref": "#/definitions/simpleTypes" - }, - { - "type": "array", - "items": { - "$ref": "#/definitions/simpleTypes" - }, - "minItems": 1, - "uniqueItems": true - } - ] - }, - "format": { - "type": "string" - }, - "contentMediaType": { - "type": "string" - }, - "contentEncoding": { - "type": "string" - }, - "if": { - "$ref": "#" - }, - "then": { - "$ref": "#" - }, - "else": { - "$ref": "#" - }, - "allOf": { - "$ref": "#/definitions/schemaArray" - }, - "anyOf": { - "$ref": "#/definitions/schemaArray" - }, - "oneOf": { - "$ref": "#/definitions/schemaArray" - }, - "not": { - "$ref": "#" - } - }, - "default": true -} diff --git a/schemas/udb_param_schema.json b/schemas/udb_param_schema.json deleted file mode 100644 index 5b54c75..0000000 --- a/schemas/udb_param_schema.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - - "required": [ - "$schema", - "kind", - "description", - "long_name", - "definedBy", - "schema" - ], - "properties": { - "$schema": { - "const": "udb_param_schema.json#" - }, - "kind": { - "const": "parameter" - }, - "name": { - "$ref": "udb_schema_defs.json#/$defs/param_name" - }, - "long_name": { - "description": "Short description of the parameter", - "type": "string" - }, - "description": { - "$ref": "udb_schema_defs.json#/$defs/spec_text", - "description": "Parameter description, including list of valid values" - }, - "definedBy": { - "description": "Extension requirement condition that must be met for parameter to exist. The condition that the defining extension is implemented is implicit, and does not need to be explicitly listed", - "$ref": "udb_schema_defs.json#/$defs/condition" - }, - "schema": { - "$ref": "udb-json-schema-draft-07.json#", - "additionalProperties": false - }, - "requirements": { - "$ref": "udb_schema_defs.json#/$defs/condition" - }, - "$source": { - "type": "string", - "description": "Source file where this parameter was defined" - } - }, - "additionalProperties": false -} diff --git a/schemas/udb_schema_defs.json b/schemas/udb_schema_defs.json deleted file mode 100644 index e77b027..0000000 --- a/schemas/udb_schema_defs.json +++ /dev/null @@ -1,875 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - - "title": "Common patterns used by all schemas", - - "$defs": { - "$source": { - "type": "string", - "format": "uri-reference", - "description": "Path to the source file containing this object" - }, - "semantic_version": { - "type": "string", - "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" - }, - "rvi_version": { - "type": "string", - "pattern": "^[0-9]+(\\.[0-9]+(\\.[0-9]+(-pre)?)?)?$" - }, - "csr_name": { - "type": "string", - "pattern": "^[a-z][a-z0-9_.]+$", - "description": "CSR name" - }, - "csr_field": { - "type": "string", - "pattern": "^[a-z][a-z0-9_.]+\\.[A-Z0-9]+$", - "description": "CSR field" - }, - "csr_field_bits": { - "type": "string", - "pattern": "^[a-z][a-z0-9_.]+\\.[A-Z0-9]+\\[[0-9]+(:[0-9]+)?\\]$", - "description": "CSR field" - }, - "field_location": { - "oneOf": [ - { "type": "integer", "description": "Location of a single bit" }, - { - "type": "string", - "pattern": "^[0-9]+-[0-9]+$", - "description": "Location range of a multi-bit field" - } - ], - "description": "Location of a field in a register" - }, - "bit_length_value": { - "description": "Bit width value for a register or field", - "oneOf": [ - { - "type": "integer", - "minimum": 1 - }, - { - "type": "string", - "minLength": 1, - "enum": ["MXLEN", "FLEN", "VLEN"] - } - ] - }, - "register_name": { - "type": "string", - "pattern": "^[A-Za-z][A-Za-z0-9_.-]*$", - "description": "Register name" - }, - "register_file_name": { - "type": "string", - "pattern": "^[A-Z]$", - "description": "Register file name" - }, - "register_alias": { - "type": "string", - "pattern": "^[A-Za-z][A-Za-z0-9_.-]*$", - "description": "Register alias or ABI mnemonic" - }, - "possibly_split_field_location": { - "description": "Location specifier for a field", - "oneOf": [ - { - "description": "bit range location, possibly split", - "type": "string", - "pattern": "^(([0-9]+)|([0-9]+-[0-9]+))(\\|(([0-9]+)|([0-9]+-[0-9]+)))*$" - }, - { - "description": "Single bit location", - "type": "integer", - "minimum": 0, - "maximum": 31 - } - ] - }, - "revision_history_entry": { - "type": "object", - "properties": { - "revision": { - "$ref": "#/$defs/semantic_version", - "description": "Revision number" - }, - "date": { - "type": "string", - "format": "date", - "description": "The date of the change" - }, - "changes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "List of changes" - } - }, - "required": ["date", "revision", "changes"], - "additionalProperties": false - }, - "spec_state": { - "type": "string", - "enum": [ - "development", - "frozen", - "public-review", - "ratification-ready", - "ratified", - "nonstandard-released" - ] - }, - "spec_text": { - "oneOf": [ - { - "type": "string", - "description": "Asciidoctor source" - }, - { - "type": "array", - "items": { - "$ref": "#/$defs/conditional_text" - } - } - ] - }, - "conditional_text": { - "type": "object", - "required": ["text"], - "properties": { - "text": { - "type": "string", - "description": "Asciidoctor source" - }, - "when()": { - "type": "string", - "description": "IDL boolean expression. When true, the text applies" - }, - "when_ast": { "type": "object" } - }, - "additionalProperties": false - }, - "license": { - "description": "License that applies to the textual documentation for this extension", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "License name" - }, - "id": { - "type": "string", - "description": "License identifier" - }, - "url": { - "type": "string", - "format": "uri", - "description": "Link to license text" - }, - "text_url": { - "type": "string", - "format": "uri", - "description": "Link to license text" - } - }, - "additionalProperties": false - }, - "company": { - "description": "A company", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name of the company. Should be \"RISC-V International\" for standard extensions" - }, - "url": { - "type": "string", - "format": "uri", - "description": "Website of the company. Should be \"https://riscv.org\" for standard extensions" - } - } - }, - "extension_presence": { - "oneOf": [ - { - "type": "string", - "enum": ["mandatory", "optional", "prohibited"] - }, - { - "type": "object", - "required": ["optional"], - "properties": { - "optional": { - "type": "string", - "enum": ["localized", "development", "expansion", "transitory"] - } - }, - "additionalProperties": false - } - ] - }, - "date": { - "type": "string", - "format": "date", - "description": "A specific day in YYYY-MM-DD format", - "examples": ["2018-11-13", "2024-12-31"] - }, - "extension_name": { - "type": "string", - "pattern": "^(([A-WY])|([SXZ][a-z0-9]+))$" - }, - "extension_version": { - "$ref": "#/$defs/rvi_version" - }, - "requirement_string": { - "type": "string", - "pattern": "^((>=)|(>)|(~>)|(<)|(<=)|(=))?\\s*[0-9]+(\\.[0-9]+(\\.[0-9]+(-[a-fA-F0-9]+)?)?)?$" - }, - "version_requirements": { - "description": "A (set of) version requirements", - "oneOf": [ - { - "$ref": "#/$defs/requirement_string" - }, - { - "type": "array", - "items": { - "$ref": "#/$defs/requirement_string" - } - } - ] - }, - "extension_requirement": { - "description": "A requirement on an extension. Can either specify just an extension name, in which case version '>= 0' is implied, or both a name and a requirement", - "type": "object", - "properties": { - "name": { - "$ref": "#/$defs/extension_name" - }, - "version": { - "$ref": "#/$defs/version_requirements" - } - }, - "required": ["name"], - "additionalProperties": false - }, - "param_name": { - "type": "string", - "pattern": "^[A-Z][A-Z_0-9]*$" - }, - "param_requirement": { - "type": "object", - "required": ["name", "schema"], - "properties": { - "name": { - "$ref": "#/$defs/param_name" - }, - "schema": { - "$ref": "json-schema-draft-07.json#" - } - }, - "additionalProperties": false - }, - "requires_entry": { - "oneOf": [ - { "$ref": "#/$defs/extension_requirement" }, - { - "type": "object", - "properties": { - "anyOf": { - "type": "array", - "items": { - "$ref": "#/$defs/requires_entry" - } - }, - "allOf": { - "type": "array", - "items": { - "$ref": "#/$defs/requires_entry" - } - }, - "oneOf": { - "type": "array", - "items": { - "$ref": "#/$defs/requires_entry" - } - }, - "not": { - "type": "object", - "$ref": "#/$defs/requires_entry" - } - }, - "additionalProperties": false - } - ] - }, - "extension_with_version": { - "type": "object", - "required": ["name", "version"], - "properties": { - "name": { - "$ref": "#/$defs/extension_name" - }, - "version": { - "$ref": "#/$defs/extension_version" - } - } - }, - "author": { - "type": "object", - "required": ["name"], - "properties": { - "name": { - "type": "string", - "description": "Author's full name" - }, - "email": { - "type": "string", - "format": "email", - "description": "Author's email address" - }, - "organization": { - "$ref": "#/$defs/organization", - "description": "Author's organization, which should be an RVI member (or individual)" - } - }, - "additionalProperties": false - }, - "organization": { - "type": "object", - "required": ["name"], - "properties": { - "name": { - "type": "string", - "description": "Organization name" - }, - "url": { - "type": "string", - "format": "uri", - "description": "Organization URL" - } - }, - "additionalProperties": false - }, - "when_condition": { - "type": "object", - "properties": { - "version": { - "$ref": "#/$defs/version_requirements" - } - }, - "additionalProperties": false - }, - "parameter_constraint": { - "type": "object", - "properties": { - "schema": { - "$ref": "json-schema-draft-07.json#" - }, - "when": { - "$ref": "#/$defs/when_condition" - } - } - }, - "cert_normative_rules": { - "description": "Architecturally visible behaviors requiring validation by certification tests", - "type": "array", - "required": ["id", "name", "doc_links", "description"], - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "doc_links": { - "description": "Link to UDB documentation, ISA manual, Sail code, or IDL code", - "type": "array", - "items": { - "type": "string" - } - }, - "description": { - "type": "string" - } - }, - "additionalProperties": false - }, - "encoding_match": { - "oneOf": [ - { - "type": "string", - "pattern": "^[01-]{43}11111$", - "description": "48-bit encoding" - }, - { - "type": "string", - "pattern": "^[01-]{30}11$", - "description": "32-bit encoding" - }, - { - "type": "string", - "pattern": "^[01-]{14}((00)|(01)|(10))$", - "description": "16-bit encoding" - } - ] - }, - "inst_type_name": { - "type": "string", - "pattern": "[A-Z][A-Za-z0-9\\-]*" - }, - "inst_subtype_name": { - "type": "string", - "pattern": "[A-Z][A-Za-z0-9\\-]*-[A-Za-z0-9\\-]*" - }, - "reference": { - "type": "string", - "pattern": "^.+\\.yaml#(/.*)?$", - "description": "refrence to another database object, as a JSON Reference" - }, - "integer": { - "description": "An integer, either native to JSON or a number-like string", - "oneOf": [ - { - "type": "integer" - }, - { - "type": "string", - "pattern": "^0b[01]+$" - }, - { - "type": "string", - "pattern": "^0x[a-fA-F0-9]+$" - } - ] - }, - "ref_url": { - "type": "string", - "pattern": "^.*/.*\\.yaml#.*$" - }, - "ref_url_list": { - "oneOf": [ - { - "$ref": "#/$defs/ref_url" - }, - { - "type": "array", - "items": { - "$ref": "#/$defs/ref_url" - } - } - ] - }, - "extension_condition": { - "description": "A logic condition specifying certain extension version requirements", - "type": "object", - "required": ["extension"], - "properties": { - "extension": { - "oneOf": [ - { - "$ref": "#/$defs/extension_requirement" - }, - { - "type": "object", - "additionalProperties": false, - "properties": { - "allOf": { - "type": "array", - "items": { - "$ref": "schema_defs.json#/$defs/extension_condition/properties/extension" - }, - "minItems": 2 - }, - "anyOf": { - "type": "array", - "items": { - "$ref": "schema_defs.json#/$defs/extension_condition/properties/extension" - }, - "minItems": 2 - }, - "oneOf": { - "type": "array", - "items": { - "$ref": "schema_defs.json#/$defs/extension_condition/properties/extension" - }, - "minItems": 2 - }, - "noneOf": { - "type": "array", - "items": { - "$ref": "schema_defs.json#/$defs/extension_condition/properties/extension" - }, - "minItems": 2 - }, - "not": { - "$ref": "schema_defs.json#/$defs/extension_condition/properties/extension" - } - }, - "minProperties": 1, - "maxProperties": 1 - }, - { - "type": "object", - "required": ["if", "then"], - "properties": { - "if": { - "$ref": "schema_defs.json#/$defs/condition" - }, - "then": { - "$ref": "schema_defs.json#/$defs/extension_condition/properties/extension" - } - }, - "additionalProperties": false - } - ] - } - }, - "additionalProperties": false - }, - "param_condition": { - "type": "object", - "required": ["param"], - "properties": { - "param": { - "oneOf": [ - { - "type": "object", - "additionalProperties": false, - "required": ["name"], - "properties": { - "name": { - "$ref": "#/$defs/param_name" - }, - "index": { - "type": "integer" - }, - "size": { - "type": "boolean" - }, - "equal": { - "oneOf": [ - { - "type": "integer" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ] - }, - "oneOf": { - "type": "array", - "minItems": 2, - "oneOf": [ - { - "items": { - "type": "integer" - } - }, - { - "items": { - "type": "string" - } - }, - { - "items": { - "type": "array", - "items": { - "type": "integer" - }, - "minItems": 1 - } - }, - { - "items": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - } - } - ] - }, - "notEqual": { - "oneOf": [ - { - "type": "integer" - }, - { - "type": "string" - }, - { - "type": "boolean" - } - ] - }, - "greaterThan": { - "type": "integer" - }, - "lessThan": { - "type": "integer" - }, - "greaterThanOrEqual": { - "type": "integer" - }, - "lessThanOrEqual": { - "type": "integer" - }, - "includes": { - "oneOf": [ - { - "type": "integer" - }, - { - "type": "string" - } - ] - }, - "reason": { - "description": "Why the param condition exists", - "type": "string" - } - }, - "$comment": "Mandating 2-3 properties, depending on if reason is given", - "minProperties": 2, - "maxProperties": 3 - }, - { - "type": "object", - "additionalProperties": false, - "properties": { - "allOf": { - "type": "array", - "items": { - "$ref": "schema_defs.json#/$defs/param_condition/properties/param" - }, - "minItems": 2 - }, - "anyOf": { - "type": "array", - "items": { - "$ref": "schema_defs.json#/$defs/param_condition/properties/param" - }, - "minItems": 2 - }, - "oneOf": { - "type": "array", - "items": { - "$ref": "schema_defs.json#/$defs/param_condition/properties/param" - }, - "minItems": 2 - }, - "noneOf": { - "type": "array", - "items": { - "$ref": "schema_defs.json#/$defs/param_condition/properties/param" - }, - "minItems": 2 - }, - "not": { - "$ref": "schema_defs.json#/$defs/param_condition/properties/param" - } - }, - "minProperties": 1, - "maxProperties": 1 - } - ] - } - }, - "additionalProperties": false - }, - - "idl": { - "description": "IDL code", - "type": "string" - }, - - "idl_condition": { - "description": "A condition expressed with IDL", - "type": "object", - "required": ["idl()"], - "properties": { - "idl()": { - "description": "IDL function containing one or more implications (e.g., A -> B).", - "$ref": "#/$defs/idl" - }, - "idl_ast": { - "type": "object" - }, - "reason": { - "description": "Why the constraint exists", - "type": "string" - } - }, - "additionalProperties": false - }, - - "yaml_condition": { - "oneOf": [ - { - "type": "object", - "properties": { - "allOf": { - "type": "array", - "items": { - "$ref": "#/$defs/yaml_condition" - }, - "minItems": 2 - }, - "anyOf": { - "type": "array", - "items": { - "$ref": "#/$defs/yaml_condition" - }, - "minItems": 2 - }, - "oneOf": { - "type": "array", - "items": { - "$ref": "#/$defs/yaml_condition" - }, - "minItems": 2 - }, - "noneOf": { - "type": "array", - "items": { - "$ref": "#/$defs/yaml_condition" - }, - "minItems": 2 - }, - "not": { - "$ref": "#/$defs/yaml_condition" - } - }, - "minProperties": 1, - "maxProperties": 1, - "additionalProperties": false - }, - { - "$ref": "#/$defs/extension_condition" - }, - { - "$ref": "#/$defs/param_condition" - }, - { - "$ref": "#/$defs/xlen_condition" - } - ] - }, - - "xlen_condition": { - "type": "object", - "required": ["xlen"], - "properties": { - "xlen": { - "enum": [32, 64] - } - }, - "additionalProperties": false - }, - - "condition": { - "oneOf": [ - { - "$ref": "#/$defs/yaml_condition" - }, - { - "$ref": "#/$defs/idl_condition" - } - ] - }, - - "extension_requirement_list_item": { - "description": "A list of extension requirements, possibly with a condition", - "oneOf": [ - { - "$ref": "#/$defs/extension_requirement" - }, - { - "description": "A conditional extension requirement", - "type": "object", - "properties": { - "name": { - "$ref": "#/$defs/extension_name" - }, - "version": { - "$ref": "#/$defs/version_requirements" - }, - "when": { - "$comment": "Using 'when' instead of 'if' to distinguish it from 'if' in a condition", - "$ref": "#/$defs/condition" - } - }, - "required": ["name", "when"], - "additionalProperties": false - } - ] - }, - "extension_requirement_list": { - "oneOf": [ - { - "type": "object", - "properties": { - "allOf": { - "type": "array", - "items": { - "$ref": "#/$defs/extension_requirement_list_item" - }, - "minItems": 1 - } - }, - "additionalProperties": false - }, - { - "$ref": "#/$defs/extension_requirement_list_item" - } - ] - }, - - "uint32": { - "type": "integer", - "minimum": 0, - "maximum": 4294967295 - }, - "uint64": { - "type": "integer", - "minimum": 0, - "maximum": 18446744073709551615 - }, - "32bit_unsigned_pow2": { - "description": "An unsigned power of 2 that fits in 32 bits", - "type": "integer", - "enum": [ - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4095, 8192, 16384, - 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, - 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, - 1073741824, 2147483648 - ] - }, - "64bit_unsigned_pow2": { - "description": "An unsigned power of 2 that fits in 64 bits", - "type": "integer", - "enum": [ - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4095, 8192, 16384, - 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, - 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, - 1073741824, 2147483648, 4294967296, 8589934592, 17179869184, - 34359738368, 68719476736, 137438953472, 274877906944, 549755813888, - 1099511627776, 2199023255552, 4398046511104, 8796093022208, - 17592186044416, 35184372088832, 70368744177664, 140737488355328, - 281474976710656, 562949953421312, 1125899906842624, 2251799813685248, - 4503599627370496, 9007199254740992, 18014398509481984, - 36028797018963968, 72057594037927936, 144115188075855872, - 288230376151711744, 576460752303423488, 1152921504606846976, - 2305843009213693952, 4611686018427387904, 9223372036854775808 - ] - } - } -} diff --git a/tests/norm-rule/expected/test-ch1-norm-tags.json b/tests/norm-rule/expected/test-ch1-norm-tags.json index 969a5ef..a1cb38b 100644 --- a/tests/norm-rule/expected/test-ch1-norm-tags.json +++ b/tests/norm-rule/expected/test-ch1-norm-tags.json @@ -81,10 +81,12 @@ { "title": "Chapter 1", "id": "_chapter_1", + "level": 1, "children": [ { "title": "Chapter 1.1 - Inline Tagging", "id": "_chapter_1_1_inline_tagging", + "level": 2, "children": [], "tags": [ "norm:inline", @@ -100,6 +102,7 @@ { "title": "Chapter 1.2 - Paragraph Tagging", "id": "_chapter_1_2_paragraph_tagging", + "level": 2, "children": [], "tags": [ "norm:paragraph:no-inline-anchors", @@ -113,6 +116,7 @@ { "title": "Chapter 1.3 - AsciiDoc Formatting", "id": "_chapter_1_3_asciidoc_formatting", + "level": 2, "children": [], "tags": [ "norm:bold", @@ -141,6 +145,7 @@ { "title": "Chapter 1.4 - Table Tagging", "id": "_chapter_1_4_table_tagging", + "level": 2, "children": [], "tags": [ "norm:table:no-anchors-in-cells:entire-table", @@ -155,6 +160,7 @@ { "title": "Chapter 1.5 - Tagging Unordered Lists", "id": "_chapter_1_5_tagging_unordered_lists", + "level": 2, "children": [], "tags": [ "norm:unordered-list:no-anchors-in-items:entire-list", @@ -167,6 +173,7 @@ { "title": "Chapter 1.6 - Tagging Ordered Lists", "id": "_chapter_1_6_tagging_ordered_lists", + "level": 2, "children": [], "tags": [ "norm:ordered-list:no-anchors-in-items:entire-list", @@ -178,6 +185,7 @@ { "title": "Chapter 1.7 - Tagging Description Lists", "id": "_chapter_1_7_tagging_description_lists", + "level": 2, "children": [], "tags": [ "norm:description-list:no-anchors-in-items:entire-list", @@ -192,10 +200,12 @@ { "title": "Chapter 2 - Implementation-Defined Behaviors", "id": "_chapter_2_implementation_defined_behaviors", + "level": 1, "children": [ { "title": "Chapter 2.1 - WARL", "id": "_chapter_2_1_warl", + "level": 2, "children": [], "tags": [ "norm:satp_asid_warl_asidlen" diff --git a/tests/norm-rule/expected/test-ch2-norm-tags.json b/tests/norm-rule/expected/test-ch2-norm-tags.json index 5d92e97..9d8ebb1 100644 --- a/tests/norm-rule/expected/test-ch2-norm-tags.json +++ b/tests/norm-rule/expected/test-ch2-norm-tags.json @@ -29,10 +29,12 @@ { "title": "Chapter 2", "id": "_chapter_2", + "level": 1, "children": [ { "title": "Chapter 2.1 - Tagging Admonitions", "id": "_chapter_2_1_tagging_admonitions", + "level": 2, "children": [], "tags": [ "norm:admonition:single-paragraph-note", @@ -47,6 +49,7 @@ { "title": "Chapter 2.2 - Implementation-Defined Behaviors", "id": "_chapter_2_2_implementation_defined_behaviors", + "level": 2, "children": [], "tags": [ "norm:ROSE_COLORS", @@ -64,6 +67,7 @@ { "title": "Chapter 2.3 - CSR Field Types", "id": "_chapter_2_3_csr_field_types", + "level": 2, "children": [], "tags": [ "norm:foo_abc_warl_enum", diff --git a/tests/norm-rule/expected/test-norm-rules.html b/tests/norm-rule/expected/test-norm-rules.html index 005734f..47456a1 100644 --- a/tests/norm-rule/expected/test-norm-rules.html +++ b/tests/norm-rule/expected/test-norm-rules.html @@ -121,11 +121,7 @@ /* Chapter tables use all available width and divvied up using the percentages above */ #table-norm-rules-ch-1 > table { table-layout: fixed; width: 100% } #table-norm-rules-ch-2 > table { table-layout: fixed; width: 100% } - #table-impldefs-no-cat > table { table-layout: fixed; width: 100% } - #table-impldefs-impl-cat-WARL > table { table-layout: fixed; width: 100% } - #table-impldefs-impl-cat-WLRL > table { table-layout: fixed; width: 100% } - #table-impldefs-ch-1 > table { table-layout: fixed; width: 100% } - #table-impldefs-ch-2 > table { table-layout: fixed; width: 100% } + #table-norm-rules-ch-3 > table { table-layout: fixed; width: 100% } /* Responsive */ @media (max-width:820px){ @@ -141,1931 +137,532 @@
-

98 Normative Rules: Includes 32 Implementation-Defined Behaviors (27 No Category, 3 WARL, 2 WLRL)

+

94 Normative Rules

- + - + - - - - - - - + + + - - + + + - - + + + - - - + + + - - + + + - - + + + - - - + + + - - - + + + - - + + + - - - + + + - - + + + - - - + + + - - + + + - - + + + - - - + + + - - + + + - - - + + + - - + + + - - - + + + - - + + + - - - + + + + +
Chapter One: 78 Normative Rules: Includes 17 Implementation-Defined Behaviors (16 No Category, 1 WARL)Chapter Chapter 2: 21 Normative Rules
NameInformationInformation Source
NameTextLocation
inlineA few wordsSummary
extensionKindadmonition:single-paragraph-noteSingle paragraph note
that spans lines.
norm:admonition:single-paragraph-note
[Zicsr, ABC]Instancesadmonition:no-anchors-in-notes:entire-noteParagraph A

Paragraph B

Paragraph C
norm:admonition:no-anchors-in-notes:entire-note
inside inlinenorm:inlineadmonition:anchors-in-notes:note1Paragraph 0norm:admonition:anchors-in-notes:note1
no_tagNormative rule without tag/tags and nested bold cases.Summaryadmonition:anchors-in-notes:note3Paragraph 2norm:admonition:anchors-in-notes:note3
This normative rule has no references to the standard. This should only be used in extraordinary circumstances.
It does include a link to table1 (another normative rule).
Has basic adoc formatting such as bold, italics, monospace, 2superscript, subscript, underline,
and ≤ (Unicode text for less-than-equals-to) and ≠ (Unicode decimal value for not-equal-to).
Noteadmonition:anchors-in-notes:entire-noteParagraph 0

Paragraph 1

Paragraph 2
norm:admonition:anchors-in-notes:entire-note
Let's try a nested bold italics case or all 3 bold italic monospace too.Descriptionadmonition:only-anchors-in-notes:note1Paragraph Xnorm:admonition:only-anchors-in-notes:note1
inline-with-hashincludes a hash # symbol.norm:inline-with-hashadmonition:only-anchors-in-notes:note3Paragraph Znorm:admonition:only-anchors-in-notes:note3
extension-dependencyextension_dependencyKindROSE_COLORSYou can use red or yellow roses. The tags backend removes some adoc formating so I don't see bold text but I can see superscript as long as I use the inline anchor and not the paragraph anchor.norm:ROSE_COLORS
The F extensions depends on the Zicsr extension.norm:extension-dependencyXLENWe use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.norm:XLEN
one_basebaseKindASIDLENThe number of ASID bits is UNSPECIFIED and may be zero. The number of implemented ASID bits, termed ASIDLEN, may be determined by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one.norm:ASIDLEN
RV32IInstancefoobar-ch2This is the Ch2 part of the foobar normative rule.norm:foobar-ch2
ALL_BASESbaseKindmock-inst-xHere’s a normative rule for mock instruction "X".norm:mock-inst-x
AnyInstancebase-rv32iHere’s a normative rule for the RV32I base ISA.norm:base-rv32i
Everyone loves RISC-V!norm:all-basesbase-rv32i-rv64iHere’s a normative rule for the RV32I or RV64I base ISA.norm:base-rv32i-rv64i
clarification-without-textisn't clear enough.norm:clarification-without-textmock-csr-xHere’s a normative rule for mock CSR "X".norm:mock-csr-x
[CLARIFICATION] (No clarification text available)GitHub Issuemock-csr-field-yHere’s a normative rule for mock CSR field "Y".norm:mock-csr-field-y
clarification-with-textalso isn't clear enough.norm:clarification-with-textmock-ext-dep-A-on-BHere’s a normative rule for mock extension dependency of extension A on extension B.norm:mock-ext-dep-A-on-B
[CLARIFICATION] This is the optional clarifying text.GitHub Issuefoo_abc_warl_enumAn implementation may support any or all of the following values for the 4-bit foo.ABC field: When foo.GHI is 0, legal values are 0, 4, 15. When foo.GHI is non-zero, legal values are 1, 2, 3.norm:foo_abc_warl_enum
clarification-with-tablealso isn't clear enough.norm:clarification-with-textfoo_ghi_warl_var_widthThe foo.GHI CSR field width ranges from 4 to 8 bits as specified by the UINT_4TO8 parameter value.norm:foo_ghi_warl_var_width
[CLARIFICATION]
Header1Header2
R1C1R1C2
R2C1R2C2

GitHub Issuezort_xyz_wlrl_ro_maskAn implementation may treat each bit of the zort.XYZ
CSR as read-only or read-write
norm:zort_xyz_wlrl_ro_mask
cat-colorsCats come in many colors.norm:cat-colorsqux_qqq_wlrl_otherThe qux.QQQ CSR field has implementation-defined behavior
that doesn't match any of the defined WARL/WLRL types.
norm:qux_qqq_wlrl_other
+
+ +
+ + + + + + + + + + + - - - + + + - - + + + - - - + + + - - + + + - - - + + + - - + + + - - + + + - - - - - + - - - - - - + - - - + + + - + - + - + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - + - + - + + + + + + - + - + - + - + - - - - - - + - + - + + + + + + - + - - - - - - + - + - + + + + + + - + - - - - - - - - - - + + + +
Chapter Chapter 1: 55 Normative Rules
NameTextLocation
cat-claws-one-line-1This kind of animal has claws.norm:cat-clawsinlineinside inlinenorm:inline
[CONTEXT] Cats come in many colors.norm:cat-colorsinline-with-hashincludes a hash # symbol.norm:inline-with-hash
cat-claws-multi-lines-1[CONTEXT] Cats come in many colors.norm:cat-colorsextension-dependencyThe F extensions depends on the Zicsr extension.norm:extension-dependency
This kind of animal has claws.norm:cat-clawsall-basesEveryone loves RISC-V!norm:all-bases
cat-claws-multi-lines-2This kind of animal has claws.norm:cat-clawsclarification-without-textisn't clear enough.norm:clarification-without-text
[CONTEXT] Cats come in many colors.norm:cat-colorsclarification-with-textalso isn't clear enough.norm:clarification-with-text
cat-claws-multi-lines-3[CONTEXT] Cats come in many colors.cat-colorsCats come in many colors. norm:cat-colors
cat-claws This kind of animal has claws. norm:cat-claws
paragraph-with-a-really-wide-rule-nameHere's a description.
It's got 2 lines.
Description
paragraph:no-inline-anchors Paragraph without inline anchors norm:paragraph:no-inline-anchors
inline-anchors-in-paragraph-entireParagraph with inline anchor and something.norm:paragraph:inline-anchors:entire
inline-anchors-in-paragraph-inline-anchorparagraph:inline-anchors:inline-anchor inline anchor norm:paragraph:inline-anchors:inline-anchor
formulaeThis paragraph looks like a formulae to Excel because it has this < sign in it. Make sure this gets written as a string, not a formulae in the XLSX or else it will create an error in Excel.norm:formulaeparagraph:inline-anchors:entireParagraph with inline anchor and something.norm:paragraph:inline-anchors:entire
rule_with_newlinesparagraph:tag_with_newlines Here’s the first line. Here’s the second line. norm:paragraph:tag_with_newlines
double_tagsdef This paragraph has two tags but we only ever get a tag for norm:def. norm:def
boldformulaeThis paragraph looks like a formulae to Excel because it has this < sign in it. Make sure this gets written as a string, not a formulae in the XLSX or else it will create an error in Excel.norm:formulae
bold ABC is a network - Bold is removed by tags backend so I don't see it norm:bold
italicsitalics Let's have fun today - Italics is removed by tags backend so I don't see it norm:italics
superscriptsuperscript both 232 and 32 work norm:superscript
subscriptsubscript both log and log2 work norm:subscript
inline-underlineinline-underline ABC inside tag GHI norm:inline-underline
paragraph-underlineparagraph-underline Paragraph underlined outside. norm:paragraph-underline
standalone_ampersandstandalone_ampersand ABC & DEF norm:standalone_ampersand
unicode_nameunicode_name DEF ≥ GHI norm:unicode_name
unicode_decimal_valueunicode_decimal_value GHI ≥ JKL norm:unicode_decimal_value
unicode_hexadecimal_valueunicode_hexadecimal_value JKL ≥ MNO norm:unicode_hexadecimal_value
unicode_charunicode_char MNO ≥ PQR norm:unicode_char
macro_callmacro_call 200 ≥ 100 norm:macro_call
attribute_in_formattingattribute_in_formatting ≥ and ≥ norm:attribute_in_formatting
It isn't 100, it's ≥ norm:superscript norm:attribute_with_hyperlink
attribute_undefinedattribute_undefined 200 {no-such-attribute} 100 norm:attribute_undefined
hyperlink1hyperlink1 ABC norm:superscript DEF norm:hyperlink1
hyperlink2hyperlink2 DEF custom text GHI norm:hyperlink2
hyperlink3hyperlink3 ABC non-norm-anchor DEF norm:hyperlink3
hyperlink4hyperlink4 DEF custom text GHI norm:hyperlink4
hyperlink5hyperlink5 GHI norm:superscript and norm:subscript JKL norm:hyperlink5
hyperlink6hyperlink6 JKL hello and goodbye MNO norm:hyperlink6
table1
WITH anchor
WITHOUT anchor
norm:table:anchors-in-cells:entire-table
table2table:no-anchors-in-cells:entire-table
Header 1Header 2
Cell in column 1, row 1Cell in column 2, row 1
Cell in column 1, row 2Cell in column 2, row 2
norm:table:no-anchors-in-cells:entire-table
table3table:anchors-in-cells:entire-table-tagged:cell WITH anchor norm:table:anchors-in-cells:entire-table-tagged:cell
table4table:anchors-in-cells:entire-table
WITH anchor
WITHOUT anchor
norm:table:anchors-in-cells:entire-table
table:anchors-in-cells:entire-table-not-tagged:cell ABC DEF norm:table:anchors-in-cells:entire-table-not-tagged:cell
table5table:many-rows
NameColor
RosesRed
VioletsBlue
Name1Color1
Name2Color2
Name3Color3
Name4Color4
Name5Color5
Name6Color6
Name7Color7
Name8Color8
Name9Color9
Name10Color10
......
norm:table:many-rows
table6table:single-char-cells
X1X2
AB
CD
norm:table:single-char-cells
table7table:column-first-order
ColAColB
0
1
Off
On
norm:table:column-first-order
unordered1unordered-list:no-anchors-in-items:entire-list Item A
Item B
Item C
norm:unordered-list:no-anchors-in-items:entire-list
unordered2Item 1
Item 2
Item 3
norm:unordered-list:anchors-in-items:entire-list
unordered3unordered-list:anchors-in-items:item1 Item 1 norm:unordered-list:anchors-in-items:item1
unordered4unordered-list:anchors-in-items:item2 Item 2 norm:unordered-list:anchors-in-items:item2
unordered5unordered-list:anchors-in-items:entire-listItem 1
Item 2
Item 3
norm:unordered-list:anchors-in-items:entire-list
unordered-list:multiple-levels Zca and not F
Zca, Zcf and F (but not D) is specified (RV32 only)
Zca, Zcf and Zcd if D is specified (RV32 only)

this configuration excludes Zcmp, Zcmt
Zca, Zcd if D is specified (RV64 only)

this configuration excludes Zcmp, Zcmt
norm:unordered-list:multiple-levels
ordered1ordered-list:no-anchors-in-items:entire-list Item A
Item B
Item C
norm:ordered-list:no-anchors-in-items:entire-list
ordered2Item 1
Item 2
Item 3
norm:ordered-list:anchors-in-items:entire-list
ordered3ordered-list:anchors-in-items:item1 Item 1 norm:ordered-list:anchors-in-items:item1
ordered4ordered-list:anchors-in-items:item2 Item 2 norm:ordered-list:anchors-in-items:item2
desc1ordered-list:anchors-in-items:entire-listItem 1
Item 2
Item 3
norm:ordered-list:anchors-in-items:entire-list
description-list:no-anchors-in-items:entire-list Description-A
Item A
Description-B
Item B
Description-C
Item C
norm:description-list:no-anchors-in-items:entire-list
desc2description-list:anchors-in-items:entire-list Description-1 norm:description-list:anchors-in-items:entire-list
desc3Item 1norm:description-list:anchors-in-items:item1
Item 3norm:description-list:anchors-in-items:item3
desc4description-list:anchors-in-items:item1 Item 1 norm:description-list:anchors-in-items:item1
description-list:anchors-in-items:item3 Item 3 norm:description-list:anchors-in-items:item3
+
+ +
+ + + + + + + + + + + - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - + + + + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - -
Chapter Chapter 2 - Implementation-Defined Behaviors: 18 Normative Rules
NameTextLocation
BOOLEANextensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behavior
boolean This is a boolean. norm:boolean
[CONTEXT] Here’s some context for the boolean.norm:boolean-context
BITextensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behavior
bit This is a bit. norm:bit
BYTEextensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behavior
byte This is a byte. norm:byte
HWORDextensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behavior
hword This is a half-word (16 bits). norm:hword
WORDextensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behavior
word This is a word (32 bits). norm:word
DWORDextensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behavior
dword This is a double-word (64 bits). norm:dword
UINT6extensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behaviorboolean-contextHere’s some context for the boolean.norm:boolean-context
uint6 This is a 6-bit unsigned integer. norm:uint6
UINT32extensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behavior
uint32 This is a 32-bit unsigned integer. Should be 0 to < 232-1. Need to use inline anchor to see superscript. norm:uint32
INT64extensionKind
MockExtYInstance
Implementation-defined behaviorImplementation-defined behavior
int64 This is a 64-bit signed integer. norm:int64
INT2extensionKind
MockExtYInstance
Implementation-defined behaviorImplementation-defined behavior
int2 This is a 2-bit signed integer. norm:int2
UINT_1TO100extensionKind
MockExtYInstance
Implementation-defined behaviorImplementation-defined behavior
uint-1to100 This is an unsigned integer in the range of 1 to 100. norm:uint-1to100
UINT_4TO8extensionKind
MockExtYInstance
Implementation-defined behaviorImplementation-defined behavior
uint-4to8 This is an unsigned integer in the range of 4 to 8. norm:uint-4to8
LIST_STRextensionKind
MockExtYInstance
Implementation-defined behaviorImplementation-defined behavior
list-str
NameDescription
ABCLetters "ABC"
DEFLetters "DEF"
GHILetters "GHI"
norm:list-str
LIST_INTextensionKind
[MockExtX, MockExtY]Instances
Implementation-defined behaviorImplementation-defined behavior
list-int This is a list with values 1, 2 and 4. norm:list-int
FOOBAR_CH1_EXT_XextensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behavior
foobar-ch1 This is the Ch1 part of the foobar normative rule. norm:foobar-ch1
ARRAYextensionKind
MockExtXInstance
Implementation-defined behaviorImplementation-defined behavior
array Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation. norm:array
SATP_ASID_WARL_ASIDLENcsr_fieldKind
satp.ASIDInstance
Implementation-defined behaviorImplementation-defined behavior
WARLImplementation-defined behavior category
The satp.ASID CSR field width is specified by the ASIDLEN parameter value.norm:satp_asid_warl_asidlen
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Chapter Two: 20 Normative Rules: Includes 15 Implementation-Defined Behaviors (11 No Category, 2 WARL, 2 WLRL)
NameInformationInformation Source
admon1Single paragraph note
that spans lines.
norm:admonition:single-paragraph-note
admon2Paragraph A

Paragraph B

Paragraph C
norm:admonition:no-anchors-in-notes:entire-note
admon3Paragraph 0

Paragraph 1

Paragraph 2
norm:admonition:anchors-in-notes:entire-note
admon4Paragraph Xnorm:admonition:only-anchors-in-notes:note1
Paragraph Znorm:admonition:only-anchors-in-notes:note3
admon5One line descriptionDescription
Paragraph 0norm:admonition:anchors-in-notes:note1
Paragraph 2norm:admonition:anchors-in-notes:note3
ROSE_COLORSImplementation-defined behaviorImplementation-defined behavior
You can use red or yellow roses. The tags backend removes some adoc formating so I don't see bold text but I can see superscript as long as I use the inline anchor and not the paragraph anchor.norm:ROSE_COLORS
XLEN1extensionKind
MockExtZInstance
Implementation-defined behaviorImplementation-defined behavior
We use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.norm:XLEN
XLEN2extensionKind
MockExtZInstance
Implementation-defined behaviorImplementation-defined behavior
We use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.norm:XLEN
ASIDLENextensionKind
MockExtZInstance
Implementation-defined behaviorImplementation-defined behavior
The number of ASID bits is UNSPECIFIED and may be zero. The number of implemented ASID bits, termed ASIDLEN, may be determined by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one.norm:ASIDLEN
FOOBAR_CH2_EXT_ZextensionKind
MockExtZInstance
Implementation-defined behaviorImplementation-defined behavior
This is the Ch2 part of the foobar normative rule.norm:foobar-ch2
MOCK_INST_XinstructionKind
MockInstXInstance
Implementation-defined behaviorImplementation-defined behavior
Here’s a normative rule for mock instruction "X".norm:mock-inst-x
BASE_RV32IbaseKind
RV32IInstance
Implementation-defined behaviorImplementation-defined behavior
Here’s a normative rule for the RV32I base ISA.norm:base-rv32i
BASE_RV32I_RV64IbaseKind
[RV32I, RV64I]Instances
Implementation-defined behaviorImplementation-defined behavior
Here’s a normative rule for the RV32I or RV64I base ISA.norm:base-rv32i-rv64i
MOCK_CSR_XcsrKind
MockCsrXInstance
Implementation-defined behaviorImplementation-defined behavior
Here’s a normative rule for mock CSR "X".norm:mock-csr-x
MOCK_CSR_FIELD_Ycsr_fieldKind
MockCsrFieldYInstance
Implementation-defined behaviorImplementation-defined behavior
Here’s a normative rule for mock CSR field "Y".norm:mock-csr-field-y
MOCK_EXT_DEP_A_ON_Bextension_dependencyKind
MockExtDepAOnBInstance
Implementation-defined behaviorImplementation-defined behavior
Here’s a normative rule for mock extension dependency of extension A on extension B.norm:mock-ext-dep-A-on-B
FOO_ABC_WARL_ENUMcsr_fieldKind
foo.ABCInstance
Implementation-defined behaviorImplementation-defined behavior
WARLImplementation-defined behavior category
An implementation may support any or all of the following values for the 4-bit foo.ABC field: When foo.GHI is 0, legal values are 0, 4, 15. When foo.GHI is non-zero, legal values are 1, 2, 3.norm:foo_abc_warl_enum
FOO_GHI_WARL_VAR_WIDTHImplementation-defined behaviorImplementation-defined behavior
WARLImplementation-defined behavior category
The foo.GHI CSR field width ranges from 4 to 8 bits as specified by the UINT_4TO8 parameter value.norm:foo_ghi_warl_var_width
ZORT_XYZ_WLRL_RO_MASKcsr_fieldKind
zort.XYZInstance
Implementation-defined behaviorImplementation-defined behavior
WLRLImplementation-defined behavior category
An implementation may treat each bit of the zort.XYZ
CSR as read-only or read-write
norm:zort_xyz_wlrl_ro_mask
QUX_QQQ_WLRL_OTHERcsr_fieldKind
qux.QQQInstance
Implementation-defined behaviorImplementation-defined behavior
WLRLImplementation-defined behavior category
The qux.QQQ CSR field has implementation-defined behavior
that doesn't match any of the defined WARL/WLRL types.
norm:qux_qqq_wlrl_other
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
No Category (A-Z): All 27 Implementation-Defined Behaviors
NameInformationInformation Source
ARRAYextensionKind
MockExtXInstance
Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.norm:array
ASIDLENextensionKind
MockExtZInstance
The number of ASID bits is UNSPECIFIED and may be zero. The number of implemented ASID bits, termed ASIDLEN, may be determined by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one.norm:ASIDLEN
BASE_RV32IbaseKind
RV32IInstance
Here’s a normative rule for the RV32I base ISA.norm:base-rv32i
BASE_RV32I_RV64IbaseKind
[RV32I, RV64I]Instances
Here’s a normative rule for the RV32I or RV64I base ISA.norm:base-rv32i-rv64i
BITextensionKind
MockExtXInstance
This is a bit.norm:bit
BOOLEANextensionKind
MockExtXInstance
This is a boolean.norm:boolean
[CONTEXT] Here’s some context for the boolean.norm:boolean-context
BYTEextensionKind
MockExtXInstance
This is a byte.norm:byte
DWORDextensionKind
MockExtXInstance
This is a double-word (64 bits).norm:dword
FOOBAR_CH1_EXT_XextensionKind
MockExtXInstance
This is the Ch1 part of the foobar normative rule.norm:foobar-ch1
FOOBAR_CH2_EXT_ZextensionKind
MockExtZInstance
This is the Ch2 part of the foobar normative rule.norm:foobar-ch2
HWORDextensionKind
MockExtXInstance
This is a half-word (16 bits).norm:hword
INT2extensionKind
MockExtYInstance
This is a 2-bit signed integer.norm:int2
INT64extensionKind
MockExtYInstance
This is a 64-bit signed integer.norm:int64
LIST_INTextensionKind
[MockExtX, MockExtY]Instances
This is a list with values 1, 2 and 4.norm:list-int
LIST_STRextensionKind
MockExtYInstance
NameDescription
ABCLetters "ABC"
DEFLetters "DEF"
GHILetters "GHI"
norm:list-str
MOCK_CSR_FIELD_Ycsr_fieldKind
MockCsrFieldYInstance
Here’s a normative rule for mock CSR field "Y".norm:mock-csr-field-y
MOCK_CSR_XcsrKind
MockCsrXInstance
Here’s a normative rule for mock CSR "X".norm:mock-csr-x
MOCK_EXT_DEP_A_ON_Bextension_dependencyKind
MockExtDepAOnBInstance
Here’s a normative rule for mock extension dependency of extension A on extension B.norm:mock-ext-dep-A-on-B
MOCK_INST_XinstructionKind
MockInstXInstance
Here’s a normative rule for mock instruction "X".norm:mock-inst-x
ROSE_COLORSYou can use red or yellow roses. The tags backend removes some adoc formating so I don't see bold text but I can see superscript as long as I use the inline anchor and not the paragraph anchor.norm:ROSE_COLORS
UINT32extensionKind
MockExtXInstance
This is a 32-bit unsigned integer. Should be 0 to < 232-1. Need to use inline anchor to see superscript.norm:uint32
UINT6extensionKind
MockExtXInstance
This is a 6-bit unsigned integer.norm:uint6
UINT_1TO100extensionKind
MockExtYInstance
This is an unsigned integer in the range of 1 to 100.norm:uint-1to100
UINT_4TO8extensionKind
MockExtYInstance
This is an unsigned integer in the range of 4 to 8.norm:uint-4to8
WORDextensionKind
MockExtXInstance
This is a word (32 bits).norm:word
XLEN1extensionKind
MockExtZInstance
We use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.norm:XLEN
XLEN2extensionKind
MockExtZInstance
We use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.norm:XLEN
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WARL Category (A-Z): All 3 Implementation-Defined Behaviors
NameInformationInformation Source
FOO_ABC_WARL_ENUMcsr_fieldKind
foo.ABCInstance
An implementation may support any or all of the following values for the 4-bit foo.ABC field: When foo.GHI is 0, legal values are 0, 4, 15. When foo.GHI is non-zero, legal values are 1, 2, 3.norm:foo_abc_warl_enum
FOO_GHI_WARL_VAR_WIDTHThe foo.GHI CSR field width ranges from 4 to 8 bits as specified by the UINT_4TO8 parameter value.norm:foo_ghi_warl_var_width
SATP_ASID_WARL_ASIDLENcsr_fieldKind
satp.ASIDInstance
The satp.ASID CSR field width is specified by the ASIDLEN parameter value.norm:satp_asid_warl_asidlen
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WLRL Category (A-Z): All 2 Implementation-Defined Behaviors
NameInformationInformation Source
QUX_QQQ_WLRL_OTHERcsr_fieldKind
qux.QQQInstance
The qux.QQQ CSR field has implementation-defined behavior
that doesn't match any of the defined WARL/WLRL types.
norm:qux_qqq_wlrl_other
ZORT_XYZ_WLRL_RO_MASKcsr_fieldKind
zort.XYZInstance
An implementation may treat each bit of the zort.XYZ
CSR as read-only or read-write
norm:zort_xyz_wlrl_ro_mask
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
Chapter One: All 17 Implementation-Defined Behaviors
NameInformationInformation Source
BOOLEANextensionKind
MockExtXInstance
This is a boolean.norm:boolean
[CONTEXT] Here’s some context for the boolean.norm:boolean-context
BITextensionKind
MockExtXInstance
This is a bit.norm:bit
BYTEextensionKind
MockExtXInstance
This is a byte.norm:byte
HWORDextensionKind
MockExtXInstance
This is a half-word (16 bits).norm:hword
WORDextensionKind
MockExtXInstance
This is a word (32 bits).norm:word
DWORDextensionKind
MockExtXInstance
This is a double-word (64 bits).norm:dword
UINT6extensionKind
MockExtXInstance
This is a 6-bit unsigned integer.norm:uint6
UINT32extensionKind
MockExtXInstance
This is a 32-bit unsigned integer. Should be 0 to < 232-1. Need to use inline anchor to see superscript.norm:uint32
INT64extensionKind
MockExtYInstance
This is a 64-bit signed integer.norm:int64
INT2extensionKind
MockExtYInstance
This is a 2-bit signed integer.norm:int2
UINT_1TO100extensionKind
MockExtYInstance
This is an unsigned integer in the range of 1 to 100.norm:uint-1to100
UINT_4TO8extensionKind
MockExtYInstance
This is an unsigned integer in the range of 4 to 8.norm:uint-4to8
LIST_STRextensionKind
MockExtYInstance
NameDescription
ABCLetters "ABC"
DEFLetters "DEF"
GHILetters "GHI"
norm:list-str
LIST_INTextensionKind
[MockExtX, MockExtY]Instances
This is a list with values 1, 2 and 4.norm:list-int
FOOBAR_CH1_EXT_XextensionKind
MockExtXInstance
This is the Ch1 part of the foobar normative rule.norm:foobar-ch1
ARRAYextensionKind
MockExtXInstance
Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.norm:array
SATP_ASID_WARL_ASIDLENcsr_fieldKind
satp.ASIDInstance
WARLImplementation-defined behavior category
satp_asid_warl_asidlen The satp.ASID CSR field width is specified by the ASIDLEN parameter value. norm:satp_asid_warl_asidlen
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Chapter Two: All 15 Implementation-Defined Behaviors
NameInformationInformation Source
ROSE_COLORSYou can use red or yellow roses. The tags backend removes some adoc formating so I don't see bold text but I can see superscript as long as I use the inline anchor and not the paragraph anchor.norm:ROSE_COLORS
XLEN1extensionKind
MockExtZInstance
We use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.norm:XLEN
XLEN2extensionKind
MockExtZInstance
We use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.norm:XLEN
ASIDLENextensionKind
MockExtZInstance
The number of ASID bits is UNSPECIFIED and may be zero. The number of implemented ASID bits, termed ASIDLEN, may be determined by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one.norm:ASIDLEN
FOOBAR_CH2_EXT_ZextensionKind
MockExtZInstance
This is the Ch2 part of the foobar normative rule.norm:foobar-ch2
MOCK_INST_XinstructionKind
MockInstXInstance
Here’s a normative rule for mock instruction "X".norm:mock-inst-x
BASE_RV32IbaseKind
RV32IInstance
Here’s a normative rule for the RV32I base ISA.norm:base-rv32i
BASE_RV32I_RV64IbaseKind
[RV32I, RV64I]Instances
Here’s a normative rule for the RV32I or RV64I base ISA.norm:base-rv32i-rv64i
MOCK_CSR_XcsrKind
MockCsrXInstance
Here’s a normative rule for mock CSR "X".norm:mock-csr-x
MOCK_CSR_FIELD_Ycsr_fieldKind
MockCsrFieldYInstance
Here’s a normative rule for mock CSR field "Y".norm:mock-csr-field-y
MOCK_EXT_DEP_A_ON_Bextension_dependencyKind
MockExtDepAOnBInstance
Here’s a normative rule for mock extension dependency of extension A on extension B.norm:mock-ext-dep-A-on-B
FOO_ABC_WARL_ENUMcsr_fieldKind
foo.ABCInstance
WARLImplementation-defined behavior category
An implementation may support any or all of the following values for the 4-bit foo.ABC field: When foo.GHI is 0, legal values are 0, 4, 15. When foo.GHI is non-zero, legal values are 1, 2, 3.norm:foo_abc_warl_enum
FOO_GHI_WARL_VAR_WIDTHWARLImplementation-defined behavior category
The foo.GHI CSR field width ranges from 4 to 8 bits as specified by the UINT_4TO8 parameter value.norm:foo_ghi_warl_var_width
ZORT_XYZ_WLRL_RO_MASKcsr_fieldKind
zort.XYZInstance
WLRLImplementation-defined behavior category
An implementation may treat each bit of the zort.XYZ
CSR as read-only or read-write
norm:zort_xyz_wlrl_ro_mask
QUX_QQQ_WLRL_OTHERcsr_fieldKind
qux.QQQInstance
WLRLImplementation-defined behavior category
The qux.QQQ CSR field has implementation-defined behavior
that doesn't match any of the defined WARL/WLRL types.
norm:qux_qqq_wlrl_other
-
- - diff --git a/tests/params/expected/test-params.json b/tests/params/expected/test-params.json deleted file mode 100644 index 0a96cee..0000000 --- a/tests/params/expected/test-params.json +++ /dev/null @@ -1,1729 +0,0 @@ -{ - "parameters": [ - { - "name": "BOOLEAN", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "BOOLEAN parameter", - "type": "boolean", - "json-schema": { - "type": "boolean" - }, - "impl-defs": [ - { - "name": "BOOLEAN", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:boolean", - "context": false, - "text": "This is a boolean.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - }, - { - "name": "norm:boolean-context", - "context": true, - "text": "Here’s some context for the boolean.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "BIT", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "BIT", - "type": "bit", - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 1 - }, - "impl-defs": [ - { - "name": "BIT", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:bit", - "context": false, - "text": "This is a bit.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "BYTE", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "8-bit unsigned integer", - "type": "byte", - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "description": "Here's a longer description for the BYTE parameter. It is an 8-bit unsigned integer.\n", - "impl-defs": [ - { - "name": "BYTE", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:byte", - "context": false, - "text": "This is a byte.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "HWORD", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "HWORD parameter", - "type": "hword", - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 65535 - }, - "impl-defs": [ - { - "name": "HWORD", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:hword", - "context": false, - "text": "This is a half-word (16 bits).", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "WORD", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "HWORD parameter", - "type": "word", - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 4294967295 - }, - "impl-defs": [ - { - "name": "WORD", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:word", - "context": false, - "text": "This is a word (32 bits).", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "DWORD", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "DWORD parameter", - "type": "dword", - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 18446744073709551615 - }, - "impl-defs": [ - { - "name": "DWORD", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:dword", - "context": false, - "text": "This is a double-word (64 bits).", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "UINT6", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "UINT6 parameter", - "type": "uint", - "width": 6, - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 63 - }, - "impl-defs": [ - { - "name": "UINT6", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:uint6", - "context": false, - "text": "This is a 6-bit unsigned integer.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "UINT32", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "UINT32 parameter", - "type": "uint", - "width": 32, - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 4294967295 - }, - "impl-defs": [ - { - "name": "UINT32", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:uint32", - "context": false, - "text": "This is a 32-bit unsigned integer. Should be 0 to &lt; 2^32^-1. Need to use inline anchor to see superscript.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "INT64", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "INT64 parameter", - "type": "int", - "width": 64, - "json-schema": { - "type": "integer", - "minimum": -9223372036854775808, - "maximum": 9223372036854775807 - }, - "impl-defs": [ - { - "name": "INT64", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtY" - ], - "tags": [ - { - "name": "norm:int64", - "context": false, - "text": "This is a 64-bit signed integer.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "INT2", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "Signed 2-bit integer", - "type": "int", - "width": 2, - "json-schema": { - "type": "integer", - "minimum": -2, - "maximum": 1 - }, - "impl-defs": [ - { - "name": "INT2", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtY" - ], - "tags": [ - { - "name": "norm:int2", - "context": false, - "text": "This is a 2-bit signed integer.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "MXLEN", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "MXLEN parameter", - "type": [ - 32, - 64 - ], - "json-schema": { - "type": "integer", - "enum": [ - 32, - 64 - ] - }, - "description": "Supported machine register widths. Doesn't have an impl-def just for testing purposes.\n" - }, - { - "name": "UINT_MXLEN", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "UINT_MXLEN parameter", - "type": "uint", - "width": "MXLEN", - "json-schema": { - "type": "integer", - "minimum": 0 - }, - "description": "Unsigned integer whose width is MXLEN." - }, - { - "name": "INT_MXLEN", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "INT_MXLEN parameter", - "type": "int", - "width": "MXLEN", - "json-schema": { - "type": "integer" - }, - "description": "Signed integer whose width is MXLEN." - }, - { - "name": "UINT_1TO100", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "UINT_1TO100 parameter", - "range": [ - 1, - 100 - ], - "json-schema": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "impl-defs": [ - { - "name": "UINT_1TO100", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtY" - ], - "tags": [ - { - "name": "norm:uint-1to100", - "context": false, - "text": "This is an unsigned integer in the range of 1 to 100.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "UINT_4TO8", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "UINT_4TO8 parameter", - "range": [ - 4, - 8 - ], - "json-schema": { - "type": "integer", - "minimum": 4, - "maximum": 8 - }, - "impl-defs": [ - { - "name": "UINT_4TO8", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtY" - ], - "tags": [ - { - "name": "norm:uint-4to8", - "context": false, - "text": "This is an unsigned integer in the range of 4 to 8.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "LIST_STR", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "LIST_STR parameter", - "type": [ - "ABC", - "DEF", - "GHI" - ], - "json-schema": { - "type": "string", - "enum": [ - "ABC", - "DEF", - "GHI" - ] - }, - "impl-defs": [ - { - "name": "LIST_STR", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtY" - ], - "tags": [ - { - "name": "norm:list-str", - "context": false, - "text": "Name|Description\n===\nABC|Letters \"ABC\"¶DEF|Letters \"DEF\"¶GHI|Letters \"GHI\"\n===", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "LIST_INT", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "LIST_INT parameter", - "type": [ - 1, - 2, - 4 - ], - "json-schema": { - "type": "integer", - "enum": [ - 1, - 2, - 4 - ] - }, - "impl-defs": [ - { - "name": "LIST_INT", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX", - "MockExtY" - ], - "tags": [ - { - "name": "norm:list-int", - "context": false, - "text": "This is a list with values 1, 2 and 4.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ALL_BASES", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ALL_BASES parameter", - "type": "int", - "width": 2, - "json-schema": { - "type": "integer", - "minimum": -2, - "maximum": 1 - }, - "impl-defs": [ - { - "name": "ALL_BASES", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "base", - "impl-def-behavior": false, - "instances": [ - "Any" - ], - "tags": [ - { - "name": "norm:all-bases", - "context": false, - "text": "Everyone loves RISC-V!", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_LIST_STR", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_LIST_STR parameter", - "type": [ - "A", - "B", - "C" - ], - "array": [ - 3, - 31 - ], - "json-schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "A", - "B", - "C" - ] - }, - "minItems": 29, - "maxItems": 29 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_LIST_INT", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_LIST_INT parameter", - "type": [ - 1, - 2, - 4 - ], - "array": [ - 0, - 15 - ], - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "enum": [ - 1, - 2, - 4 - ] - }, - "minItems": 16, - "maxItems": 16 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_BOOLEAN", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_BOOLEAN parameter", - "type": "boolean", - "array": [ - 1, - 10 - ], - "json-schema": { - "type": "array", - "items": { - "type": "boolean" - }, - "minItems": 10, - "maxItems": 10 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_BIT", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_BIT parameter", - "type": "bit", - "array": [ - 0, - 15 - ], - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0, - "maximum": 1 - }, - "minItems": 16, - "maxItems": 16 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_BYTE", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_BYTE parameter", - "type": "byte", - "array": [ - 0, - 3 - ], - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "minItems": 4, - "maxItems": 4 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_HWORD", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_HWORD parameter", - "type": "hword", - "array": [ - 0, - 3 - ], - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0, - "maximum": 65535 - }, - "minItems": 4, - "maxItems": 4 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_WORD", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_WORD parameter", - "type": "word", - "array": [ - 0, - 31 - ], - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0, - "maximum": 4294967295 - }, - "minItems": 32, - "maxItems": 32 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_DWORD", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_DWORD parameter", - "type": "dword", - "array": [ - 0, - 31 - ], - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0, - "maximum": 18446744073709551615 - }, - "minItems": 32, - "maxItems": 32 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_UINT5", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_UINT5 parameter", - "type": "uint", - "array": [ - 0, - 3 - ], - "width": 5, - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0, - "maximum": 31 - }, - "minItems": 4, - "maxItems": 4 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_INT32", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_INT32 parameter", - "type": "int", - "array": [ - 0, - 3 - ], - "width": 32, - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "minimum": -2147483648, - "maximum": 2147483647 - }, - "minItems": 4, - "maxItems": 4 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_UINT64", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_UINT64 parameter", - "type": "uint", - "array": [ - 0, - 3 - ], - "width": 64, - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0, - "maximum": 18446744073709551615 - }, - "minItems": 4, - "maxItems": 4 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ARRAY_OF_NEG10TO20", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "long-name": "ARRAY_OF_NEG10TO20 parameter", - "range": [ - -10, - 20 - ], - "array": [ - 0, - 3 - ], - "json-schema": { - "type": "array", - "items": { - "type": "integer", - "minimum": -10, - "maximum": 20 - }, - "minItems": 4, - "maxItems": 4 - }, - "impl-defs": [ - { - "name": "ARRAY", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:array", - "context": false, - "text": "Can have up to 29 performance counters. Reading an unimplemented performance counter either returns a value or raises an illegal instruction exception, depending on the implementation.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - } - ] - }, - { - "name": "ROSE_COLORS", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "ROSE_COLORS parameter", - "type": [ - "RED", - "PINK", - "WHITE" - ], - "json-schema": { - "type": "string", - "enum": [ - "RED", - "PINK", - "WHITE" - ] - }, - "note": "This is a note about the ROSE_COLORS parameter.", - "description": "This is a description about the ROSE_COLORS parameter. Here's some *bold text*.", - "impl-defs": [ - { - "name": "ROSE_COLORS", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "impl-def-behavior": true, - "tags": [ - { - "name": "norm:ROSE_COLORS", - "context": false, - "text": "You can use red or yellow roses. The tags backend removes some adoc formating so I don't see bold text but I can see ^superscript^ as long as I use the inline anchor and not the paragraph anchor.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "XLEN", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "XLEN parameter", - "type": [ - 32, - 64 - ], - "json-schema": { - "type": "integer", - "enum": [ - 32, - 64 - ] - }, - "impl-defs": [ - { - "name": "XLEN1", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtZ" - ], - "tags": [ - { - "name": "norm:XLEN", - "context": false, - "text": "We use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - }, - { - "name": "XLEN2", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtZ" - ], - "tags": [ - { - "name": "norm:XLEN", - "context": false, - "text": "We use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "FOOBAR", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "FOOBAR parameter", - "type": "boolean", - "json-schema": { - "type": "boolean" - }, - "impl-defs": [ - { - "name": "FOOBAR_CH1_EXT_X", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtX" - ], - "tags": [ - { - "name": "norm:foobar-ch1", - "context": false, - "text": "This is the Ch1 part of the foobar normative rule.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - }, - { - "name": "FOOBAR_CH2_EXT_Z", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtZ" - ], - "tags": [ - { - "name": "norm:foobar-ch2", - "context": false, - "text": "This is the Ch2 part of the foobar normative rule.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "ASIDLEN", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "ASIDLEN parameter", - "range": [ - 0, - 16 - ], - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 16 - }, - "impl-defs": [ - { - "name": "ASIDLEN", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtZ" - ], - "tags": [ - { - "name": "norm:ASIDLEN", - "context": false, - "text": "The number of ASID bits is UNSPECIFIED and may be zero. The number of implemented ASID bits, termed ASIDLEN, may be determined by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "ASIDLEN1", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "ASIDLEN parameter", - "range": [ - 0, - 16 - ], - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 16 - }, - "impl-defs": [ - { - "name": "ASIDLEN", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtZ" - ], - "tags": [ - { - "name": "norm:ASIDLEN", - "context": false, - "text": "The number of ASID bits is UNSPECIFIED and may be zero. The number of implemented ASID bits, termed ASIDLEN, may be determined by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "ASIDLEN2", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "ASIDLEN parameter", - "range": [ - 0, - 16 - ], - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 16 - }, - "impl-defs": [ - { - "name": "ASIDLEN", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtZ" - ], - "tags": [ - { - "name": "norm:ASIDLEN", - "context": false, - "text": "The number of ASID bits is UNSPECIFIED and may be zero. The number of implemented ASID bits, termed ASIDLEN, may be determined by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "NO_IMPL_DEF", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "NO_IMPL_DEF parameter", - "type": "bit", - "json-schema": { - "type": "integer", - "minimum": 0, - "maximum": 1 - }, - "note": "This is a note for a parameter without any implementation-defined behavior. Here's an 2^32^ exponent.", - "description": "Parameter intentionally defined without implementation-defined behavior." - }, - { - "name": "MOCK_INST_X", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "MOCK_INST_X parameter", - "type": "boolean", - "json-schema": { - "type": "boolean" - }, - "note": "This is a Mock \"X\" instruction parameter.", - "impl-defs": [ - { - "name": "MOCK_INST_X", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "instruction", - "impl-def-behavior": true, - "instances": [ - "MockInstX" - ], - "tags": [ - { - "name": "norm:mock-inst-x", - "context": false, - "text": "Here’s a normative rule for mock instruction \"X\".", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "BASE_RV32I", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "BASE_RV32I parameter", - "type": "boolean", - "json-schema": { - "type": "boolean" - }, - "note": "This is a base RV32I parameter.", - "impl-defs": [ - { - "name": "BASE_RV32I", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "base", - "impl-def-behavior": true, - "instances": [ - "RV32I" - ], - "tags": [ - { - "name": "norm:base-rv32i", - "context": false, - "text": "Here’s a normative rule for the RV32I base ISA.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "BASE_RV32I_RV64I", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "BASE_RV32I_RV64I parameter", - "type": "boolean", - "json-schema": { - "type": "boolean" - }, - "note": "This is a base RV32I or RV64I parameter.", - "impl-defs": [ - { - "name": "BASE_RV32I_RV64I", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "base", - "impl-def-behavior": true, - "instances": [ - "RV32I", - "RV64I" - ], - "tags": [ - { - "name": "norm:base-rv32i-rv64i", - "context": false, - "text": "Here’s a normative rule for the RV32I or RV64I base ISA.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "MOCK_CSR_X", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "MOCK_CSR_X parameter", - "type": "boolean", - "json-schema": { - "type": "boolean" - }, - "note": "This is a Mock \"X\" CSR parameter.", - "impl-defs": [ - { - "name": "MOCK_CSR_X", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "csr", - "impl-def-behavior": true, - "instances": [ - "MockCsrX" - ], - "tags": [ - { - "name": "norm:mock-csr-x", - "context": false, - "text": "Here’s a normative rule for mock CSR \"X\".", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "MOCK_CSR_FIELD_Y", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "MOCK_CSR_FIELD_Y parameter", - "type": "boolean", - "json-schema": { - "type": "boolean" - }, - "note": "This is a Mock \"Y\" CSR field parameter.", - "impl-defs": [ - { - "name": "MOCK_CSR_FIELD_Y", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "csr_field", - "impl-def-behavior": true, - "instances": [ - "MockCsrFieldY" - ], - "tags": [ - { - "name": "norm:mock-csr-field-y", - "context": false, - "text": "Here’s a normative rule for mock CSR field \"Y\".", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "name": "MOCK_EXT_DEP_A_ON_B", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "long-name": "MOCK_EXT_DEP_A_ON_B parameter", - "type": "boolean", - "json-schema": { - "type": "boolean" - }, - "note": "This is a Mock extension dependency parameter (A depends B).", - "impl-defs": [ - { - "name": "MOCK_EXT_DEP_A_ON_B", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "extension_dependency", - "impl-def-behavior": true, - "instances": [ - "MockExtDepAOnB" - ], - "tags": [ - { - "name": "norm:mock-ext-dep-A-on-B", - "context": false, - "text": "Here’s a normative rule for mock extension dependency of extension A on extension B.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - } - ], - "csrs": [ - { - "reg-name": "satp", - "field-name": "MODE", - "def_filename": "test-ch1.yaml", - "chapter_name": "One", - "category": "WARL", - "type": "VarWidth", - "width-parameter": "ASIDLEN", - "impl-defs": [ - { - "name": "SATP_ASID_WARL_ASIDLEN", - "def_filename": "tests/norm-rule/test-ch1.yaml", - "chapter_name": "One", - "kind": "csr_field", - "impl-def-behavior": true, - "instances": [ - "satp.ASID" - ], - "impl-def-category": "WARL", - "tags": [ - { - "name": "norm:satp_asid_warl_asidlen", - "context": false, - "text": "The satp.ASID CSR field width is specified by the ASIDLEN parameter value.", - "tag_filename": "/build/test-ch1-norm-tags.json", - "stds_doc_url": "test-ch1.html" - } - ] - }, - { - "name": "ASIDLEN", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "extension", - "impl-def-behavior": true, - "instances": [ - "MockExtZ" - ], - "tags": [ - { - "name": "norm:ASIDLEN", - "context": false, - "text": "The number of ASID bits is UNSPECIFIED and may be zero. The number of implemented ASID bits, termed ASIDLEN, may be determined by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "reg-name": "foo", - "field-name": "ABC", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "category": "WARL", - "type": "LegalEnum", - "func-of-reg-name": "foo", - "func-of-field-name": "GHI", - "impl-defs": [ - { - "name": "FOO_ABC_WARL_ENUM", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "csr_field", - "impl-def-behavior": true, - "instances": [ - "foo.ABC" - ], - "impl-def-category": "WARL", - "tags": [ - { - "name": "norm:foo_abc_warl_enum", - "context": false, - "text": "An implementation may support any or all of the following values for the 4-bit foo.ABC field: When foo.GHI is 0, legal values are 0, 4, 15. When foo.GHI is non-zero, legal values are 1, 2, 3.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "reg-name": "foo", - "field-name": "GHI", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "category": "WARL", - "type": "VarWidth", - "width-parameter": "UINT_4TO8", - "impl-defs": [ - { - "name": "FOO_GHI_WARL_VAR_WIDTH", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "impl-def-behavior": true, - "impl-def-category": "WARL", - "tags": [ - { - "name": "norm:foo_ghi_warl_var_width", - "context": false, - "text": "The foo.GHI CSR field width ranges from 4 to 8 bits as specified by the UINT_4TO8 parameter value.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "reg-name": "zort", - "field-name": "XYZ", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "category": "WLRL", - "type": "ConstMask", - "impl-defs": [ - { - "name": "ZORT_XYZ_WLRL_RO_MASK", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "csr_field", - "impl-def-behavior": true, - "instances": [ - "zort.XYZ" - ], - "impl-def-category": "WLRL", - "tags": [ - { - "name": "norm:zort_xyz_wlrl_ro_mask", - "context": false, - "text": "An implementation may treat each bit of the zort.XYZ\nCSR as read-only or read-write", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - }, - { - "reg-name": "qux", - "field-name": "QQQ", - "def_filename": "test-ch2.yaml", - "chapter_name": "Two", - "category": "WLRL", - "type": "Other", - "func-of-reg-name": "foo", - "func-of-field-name": "GHI", - "impl-defs": [ - { - "name": "QUX_QQQ_WLRL_OTHER", - "def_filename": "tests/norm-rule/test-ch2.yaml", - "chapter_name": "Two", - "kind": "csr_field", - "impl-def-behavior": true, - "instances": [ - "qux.QQQ" - ], - "impl-def-category": "WLRL", - "tags": [ - { - "name": "norm:qux_qqq_wlrl_other", - "context": false, - "text": "The qux.QQQ CSR field has implementation-defined behavior\nthat doesn't match any of the defined WARL/WLRL types.", - "tag_filename": "/build/test-ch2-norm-tags.json", - "stds_doc_url": "test-ch2.html" - } - ] - } - ] - } - ] -} diff --git a/tests/params/test-ch1.yaml b/tests/params/test-ch1.yaml deleted file mode 100644 index c9a34e2..0000000 --- a/tests/params/test-ch1.yaml +++ /dev/null @@ -1,161 +0,0 @@ ---- -# yaml-language-server: $schema=../../schemas/param-defs-schema.json - -$schema: "../../schemas/param-defs-schema.json#" - -chapter_name: One - -parameter_definitions: - - - name: BOOLEAN - long-name: BOOLEAN parameter - impl-def: BOOLEAN - type: boolean - - name: BIT - long-name: BIT - impl-def: BIT - type: bit - - name: BYTE - long-name: 8-bit unsigned integer - impl-def: BYTE - type: byte - description: | - Here's a longer description for the BYTE parameter. It is an 8-bit unsigned integer. - - name: HWORD - long-name: HWORD parameter - impl-def: HWORD - type: hword - - name: WORD - long-name: HWORD parameter - impl-def: WORD - type: word - - name: DWORD - long-name: DWORD parameter - impl-def: DWORD - type: dword - - name: UINT6 - long-name: UINT6 parameter - impl-def: UINT6 - type: uint - width: 6 - - name: UINT32 - long-name: UINT32 parameter - impl-def: UINT32 - type: uint - width: 32 - - name: INT64 - long-name: INT64 parameter - impl-def: INT64 - type: int - width: 64 - - name: INT2 - long-name: Signed 2-bit integer - impl-def: INT2 - type: int - width: 2 - - name: MXLEN - long-name: MXLEN parameter - type: [32, 64] - description: | - Supported machine register widths. Doesn't have an impl-def just for testing purposes. - - name: UINT_MXLEN - long-name: UINT_MXLEN parameter - type: uint - width: MXLEN - description: Unsigned integer whose width is MXLEN. - - name: INT_MXLEN - long-name: INT_MXLEN parameter - type: int - width: MXLEN - description: Signed integer whose width is MXLEN. - - name: UINT_1TO100 - long-name: UINT_1TO100 parameter - impl-def: UINT_1TO100 - range: [1, 100] - - name: UINT_4TO8 - long-name: UINT_4TO8 parameter - impl-def: UINT_4TO8 - range: [4, 8] - - name: LIST_STR - long-name: LIST_STR parameter - impl-def: LIST_STR - type: [ABC, DEF, GHI] - - name: LIST_INT - long-name: LIST_INT parameter - impl-def: LIST_INT - type: [1, 2, 4] - - name: ALL_BASES - long-name: ALL_BASES parameter - impl-def: ALL_BASES - type: int - width: 2 - - name: ARRAY_OF_LIST_STR - long-name: ARRAY_OF_LIST_STR parameter - impl-def: ARRAY - type: [A, B, C] - array: [3, 31] - - name: ARRAY_OF_LIST_INT - long-name: ARRAY_OF_LIST_INT parameter - impl-def: ARRAY - type: [1, 2, 4] - array: [0, 15] - - name: ARRAY_OF_BOOLEAN - long-name: ARRAY_OF_BOOLEAN parameter - impl-def: ARRAY - type: boolean - array: [1, 10] - - name: ARRAY_OF_BIT - long-name: ARRAY_OF_BIT parameter - impl-def: ARRAY - type: bit - array: [0, 15] - - name: ARRAY_OF_BYTE - long-name: ARRAY_OF_BYTE parameter - impl-def: ARRAY - type: byte - array: [0, 3] - - name: ARRAY_OF_HWORD - long-name: ARRAY_OF_HWORD parameter - impl-def: ARRAY - type: hword - array: [0, 3] - - name: ARRAY_OF_WORD - long-name: ARRAY_OF_WORD parameter - impl-def: ARRAY - type: word - array: [0, 31] - - name: ARRAY_OF_DWORD - long-name: ARRAY_OF_DWORD parameter - impl-def: ARRAY - type: dword - array: [0, 31] - - name: ARRAY_OF_UINT5 - long-name: ARRAY_OF_UINT5 parameter - impl-def: ARRAY - type: uint - width: 5 - array: [0, 3] - - name: ARRAY_OF_INT32 - long-name: ARRAY_OF_INT32 parameter - impl-def: ARRAY - type: int - width: 32 - array: [0, 3] - - name: ARRAY_OF_UINT64 - long-name: ARRAY_OF_UINT64 parameter - impl-def: ARRAY - type: uint - width: 64 - array: [0, 3] - - name: ARRAY_OF_NEG10TO20 - long-name: ARRAY_OF_NEG10TO20 parameter - impl-def: ARRAY - range: [-10, 20] - array: [0, 3] - -csr_definitions: - - reg-name: satp - field-name: MODE - type: VarWidth - width-parameter: ASIDLEN - impl-defs: [SATP_ASID_WARL_ASIDLEN, ASIDLEN] diff --git a/tests/params/test-ch2.yaml b/tests/params/test-ch2.yaml deleted file mode 100644 index 6b79d97..0000000 --- a/tests/params/test-ch2.yaml +++ /dev/null @@ -1,92 +0,0 @@ ---- -# yaml-language-server: $schema=../../schemas/param-defs-schema.json - -$schema: "../../schemas/param-defs-schema.json#" - -chapter_name: Two - -parameter_definitions: - - - name: ROSE_COLORS - long-name: ROSE_COLORS parameter - impl-def: ROSE_COLORS - note: This is a note about the ROSE_COLORS parameter. - description: This is a description about the ROSE_COLORS parameter. Here's some *bold text*. - type: [RED, PINK, WHITE] - - name: XLEN - long-name: XLEN parameter - impl-defs: [XLEN1, XLEN2] - type: [32, 64] - - name: FOOBAR - long-name: FOOBAR parameter - impl-defs: [FOOBAR_CH1_EXT_X, FOOBAR_CH2_EXT_Z] - type: boolean - - names: [ASIDLEN, ASIDLEN1, ASIDLEN2] - long-name: ASIDLEN parameter - impl-def: ASIDLEN - range: [0, 16] - - name: NO_IMPL_DEF - long-name: NO_IMPL_DEF parameter - note: This is a note for a parameter without any implementation-defined behavior. Here's an 2^32^ exponent. - type: bit - description: Parameter intentionally defined without implementation-defined behavior. - - name: MOCK_INST_X - long-name: MOCK_INST_X parameter - impl-def: MOCK_INST_X - type: boolean - note: This is a Mock "X" instruction parameter. - - name: BASE_RV32I - long-name: BASE_RV32I parameter - impl-def: BASE_RV32I - type: boolean - note: This is a base RV32I parameter. - - name: BASE_RV32I_RV64I - long-name: BASE_RV32I_RV64I parameter - impl-def: BASE_RV32I_RV64I - type: boolean - note: This is a base RV32I or RV64I parameter. - - name: MOCK_CSR_X - long-name: MOCK_CSR_X parameter - impl-def: MOCK_CSR_X - type: boolean - note: This is a Mock "X" CSR parameter. - - name: MOCK_CSR_FIELD_Y - long-name: MOCK_CSR_FIELD_Y parameter - impl-def: MOCK_CSR_FIELD_Y - type: boolean - note: This is a Mock "Y" CSR field parameter. - - name: MOCK_EXT_DEP_A_ON_B - long-name: MOCK_EXT_DEP_A_ON_B parameter - impl-def: MOCK_EXT_DEP_A_ON_B - type: boolean - note: This is a Mock extension dependency parameter (A depends B). - -csr_definitions: - # Case 1a: Enum - - reg-name: foo - field-name: ABC - type: LegalEnum - func-of-field-name: GHI - impl-def: FOO_ABC_WARL_ENUM - - # Case 2: CSR field with width specified by a named parameter's value. - - reg-name: foo - field-name: GHI - type: VarWidth - width-parameter: UINT_4TO8 - impl-def: FOO_GHI_WARL_VAR_WIDTH - - # Case 3: CSR field with some bits that are read-only and some bits that are read-write. - - reg-name: zort - field-name: XYZ - type: ConstMask - impl-def: ZORT_XYZ_WLRL_RO_MASK - - # Case 4: CSR field that doesn't match any of the above cases. - # Also test func-of relationship to a field in a different register. - - reg-name: qux - field-name: QQQ - func-of-reg-name: foo - func-of-field-name: GHI - type: Other - impl-def: QUX_QQQ_WLRL_OTHER diff --git a/tests/params/test-csr-table-full-default.yaml b/tests/params/test-csr-table-full-default.yaml deleted file mode 100644 index 49c88c2..0000000 --- a/tests/params/test-csr-table-full-default.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -$schema: schemas/csr-table-schema.json -columns: - - name: Name - column: NAME - width_pct: 20 - - name: Type - column: TYPE - width_pct: 20 - - name: Feature(s) - column: FEATURES - width_pct: 15 - - name: Implementation-defined Behavior(s) - column: IMPLEMENTATION_DEFINED_BEHAVIORS - width_pct: 45 diff --git a/tests/params/test-csr-table-minimal.yaml b/tests/params/test-csr-table-minimal.yaml deleted file mode 100644 index 91187cf..0000000 --- a/tests/params/test-csr-table-minimal.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -$schema: schemas/csr-table-schema.json -columns: - - name: Name - column: NAME - width_pct: 40 - - name: Implementation-defined Behavior(s) - column: IMPLEMENTATION_DEFINED_BEHAVIORS - width_pct: 60 diff --git a/tests/params/test-csr-table-reordered.yaml b/tests/params/test-csr-table-reordered.yaml deleted file mode 100644 index 57c6303..0000000 --- a/tests/params/test-csr-table-reordered.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -$schema: schemas/csr-table-schema.json -columns: - - name: Type - column: TYPE - width_pct: 20 - - name: Feature(s) - column: FEATURES - width_pct: 15 - - name: Name - column: NAME - width_pct: 20 - - name: Implementation-defined Behavior(s) - column: IMPLEMENTATION_DEFINED_BEHAVIORS - width_pct: 45 diff --git a/tests/params/test-param-table-full-default.yaml b/tests/params/test-param-table-full-default.yaml deleted file mode 100644 index 3785225..0000000 --- a/tests/params/test-param-table-full-default.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -$schema: schemas/param-table-schema.json -columns: - - name: Parameter and Mapping to Normative Rules - column: PARAM_NAME_AND_NORM_RULE_MAPPING - width_pct: 30 - - name: Type - column: TYPE - width_pct: 10 - - name: Feature(s) - column: FEATURES - width_pct: 10 - - name: Definition - column: DEFINITION - width_pct: 50 diff --git a/tests/params/test-param-table-minimal.yaml b/tests/params/test-param-table-minimal.yaml deleted file mode 100644 index 2ba4119..0000000 --- a/tests/params/test-param-table-minimal.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -$schema: schemas/param-table-schema.json -columns: - - name: Parameter and Mapping to Normative Rules - column: PARAM_NAME_AND_NORM_RULE_MAPPING - width_pct: 40 - - name: Definition - column: DEFINITION - width_pct: 60 diff --git a/tests/params/test-param-table-reordered.yaml b/tests/params/test-param-table-reordered.yaml deleted file mode 100644 index 3d1eacd..0000000 --- a/tests/params/test-param-table-reordered.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -$schema: schemas/param-table-schema.json -columns: - - name: Type - column: TYPE - width_pct: 10 - - name: Feature(s) - column: FEATURES - width_pct: 10 - - name: Parameter and Mapping to Normative Rules - column: PARAM_NAME_AND_NORM_RULE_MAPPING - width_pct: 30 - - name: Definition - column: DEFINITION - width_pct: 50 diff --git a/tests/params/test-param-tables.adoc b/tests/params/test-param-tables.adoc deleted file mode 100644 index b76be6d..0000000 --- a/tests/params/test-param-tables.adoc +++ /dev/null @@ -1,3 +0,0 @@ -// Just used to include all generated adoc parameter and WARL/WLRL CSR tables into a single file. -include::test-param-tables/all_params_a_to_z.adoc[] -include::test-param-tables/all_params_by_chapter.adoc[] diff --git a/tests/shared_utils/test_shared_utils.py b/tests/shared_utils/test_shared_utils.py index 481f94f..adee12e 100644 --- a/tests/shared_utils/test_shared_utils.py +++ b/tests/shared_utils/test_shared_utils.py @@ -7,10 +7,8 @@ import json import sys import tempfile -from importlib import util from contextlib import redirect_stderr, redirect_stdout from pathlib import Path -from typing import Dict, Optional # Ensure tools/ is importable when running from repository root. REPO_ROOT = Path(__file__).resolve().parents[2] @@ -25,26 +23,6 @@ class FatalRaised(Exception): """Raised by test fatal callback to capture fatal messages.""" -def expect_fatal(callable_obj, *args, **kwargs): - """Call helper and return fatal message if fatal callback is invoked.""" - captured: Dict[str, Optional[str]] = {"message": None} - - def fatal_callback(message: str): - captured["message"] = message - raise FatalRaised(message) - - kwargs["fatal"] = fatal_callback - try: - callable_obj(*args, **kwargs) - except FatalRaised: - pass - else: - raise AssertionError("Expected fatal callback to be invoked") - - assert isinstance(captured["message"], str) - return captured["message"] - - def test_error_prints_expected_prefix(): err = io.StringIO() with redirect_stderr(err): @@ -110,251 +88,11 @@ def fatal_cb(msg: str): assert fatal_messages[-1] == f"Expected top-level JSON object in {bad}" -def test_load_yaml_object_success(): - if util.find_spec("yaml") is None: - # The Makefile test path runs in a container with dependencies; skip locally. - return - - with tempfile.TemporaryDirectory() as tmp: - yaml_path = Path(tmp) / "good.yaml" - yaml_path.write_text("chapter_name: CH1\n", encoding="utf-8") - - def fatal_cb(msg: str): - raise FatalRaised(msg) - - loaded = shared_utils.load_yaml_object(str(yaml_path), fatal_cb) - assert loaded == {"chapter_name": "CH1"} - - -def test_format_param_feature_impldefs_and_fallbacks(): - param = { - "impl-defs": [ - {"kind": "base", "instances": ["RV64I", "RV64I"]}, - {"kind": "extension", "instances": ["Zicsr"]}, - {"kind": "mystery", "instances": ["Xfoo"]}, - ] - } - err = io.StringIO() - with redirect_stderr(err): - assert shared_utils.format_param_feature(param) == "BASE:RV64I, EXT:Zicsr, Xfoo" - assert "Unknown standards object kind 'mystery'" in err.getvalue() - - assert shared_utils.format_param_feature({"chapter_name": "CH2"}) == "CHAP:CH2" - assert shared_utils.format_param_feature({}) == "(unspecified)" - - -def test_infer_param_type_string_success_cases(): - # Core scalar keyword types. - assert ( - shared_utils.infer_param_type_string( - {"name": "P_BOOL", "type": "boolean"}, - lambda msg: (_ for _ in ()).throw(AssertionError(msg)), - ) - == "boolean" - ) - assert ( - shared_utils.infer_param_type_string( - {"name": "P_INT", "type": "int", "width": 32}, - lambda msg: (_ for _ in ()).throw(AssertionError(msg)), - ) - == "32-bit signed integer" - ) - assert ( - shared_utils.infer_param_type_string( - {"name": "P_UINT", "type": "uint", "width": "MXLEN"}, - lambda msg: (_ for _ in ()).throw(AssertionError(msg)), - ) - == "MXLEN-bit unsigned integer" - ) - - # Unknown string types are preserved (used by CSR paths such as WARL/WLRL). - assert ( - shared_utils.infer_param_type_string( - {"name": "P_CSR", "type": "WARL"}, - lambda msg: (_ for _ in ()).throw(AssertionError(msg)), - ) - == "WARL" - ) - - # Enumerations. - assert ( - shared_utils.infer_param_type_string( - {"name": "P_ENUM_S", "type": ["A", "B"]}, - lambda msg: (_ for _ in ()).throw(AssertionError(msg)), - ) - == "[A, B]" - ) - assert ( - shared_utils.infer_param_type_string( - {"name": "P_ENUM_I", "type": [1, 2, 3]}, - lambda msg: (_ for _ in ()).throw(AssertionError(msg)), - ) - == "[1, 2, 3]" - ) - assert ( - shared_utils.infer_param_type_string( - { - "reg-name": "foo", - "field-name": "ABC", - "enum": { - "legal": [0, 3, 10], - "illegal-write-return": 0, - }, - }, - lambda msg: (_ for _ in ()).throw(AssertionError(msg)), - ) - == "[0, 3, 10]" - ) - - # Range and array wrapping. - assert ( - shared_utils.infer_param_type_string( - {"name": "P_RANGE", "range": [0, 16]}, - lambda msg: (_ for _ in ()).throw(AssertionError(msg)), - ) - == "range 0 to 16" - ) - assert ( - shared_utils.infer_param_type_string( - {"name": "P_ARRAY", "type": "uint", "width": 8, "array": [0, 3]}, - lambda msg: (_ for _ in ()).throw(AssertionError(msg)), - ) - == "array[0..3] of 8-bit unsigned integer" - ) - - -def test_infer_param_type_string_all_fatal_cases(): - cases = [ - ( - {"type": "boolean"}, - "Expected parameter name or CSR reg-name to be a non-empty string", - ), - ( - {"name": "P", "type": []}, - "has an empty type array", - ), - ( - {"name": "P", "type": ["A", 1]}, - "has invalid type array; expected all strings or all integers", - ), - ( - {"name": "P", "type": [True, False]}, - "has invalid type array; expected all strings or all integers", - ), - ( - {"name": "P", "type": "int"}, - "has type 'int' but no valid width", - ), - ( - {"name": "P", "type": "uint", "width": True}, - "has type 'uint' but no valid width", - ), - ( - {"name": "P", "type": ""}, - "has invalid type of ''", - ), - ( - {"name": "P", "range": [0]}, - "has invalid range array; expected exactly 2 values", - ), - ( - {"name": "P", "range": [3, 1]}, - "has min range value 3 greater than max range value 1", - ), - ( - {"name": "P", "range": ["0", 1]}, - "has non-integer min range value of '0'", - ), - ( - {"name": "P", "range": [0, "1"]}, - "has non-integer max range value of '1'", - ), - ( - {"name": "P", "range": [True, 1]}, - "has non-integer min range value of True", - ), - ( - {"name": "P", "range": [0, True]}, - "has non-integer max range value of True", - ), - ( - {"name": "P"}, - "has neither a valid type, enum, nor a valid range", - ), - ( - {"name": "P", "type": "boolean", "array": [0]}, - "has invalid array bounds; expected exactly 2 values", - ), - ( - {"name": "P", "type": "boolean", "array": ["0", 1]}, - "has non-integer min array value of '0'", - ), - ( - {"name": "P", "type": "boolean", "array": [True, 1]}, - "has non-integer min array value of True", - ), - ( - {"name": "P", "type": "boolean", "array": [0, "1"]}, - "has non-integer max array value of '1'", - ), - ( - {"name": "P", "type": "boolean", "array": [True, 1]}, - "has non-integer min array value of True", - ), - ( - {"name": "P", "type": "boolean", "array": [0, True]}, - "has non-integer max array value of True", - ), - ( - {"name": "P", "type": "boolean", "array": [0, False]}, - "has non-integer max array value of False", - ), - ( - {"name": "P", "type": "boolean", "array": [-1, 2]}, - "has invalid array bounds; values must be non-negative", - ), - ( - {"name": "P", "type": "boolean", "array": [4, 2]}, - "has min array value 4 greater than max array value 2", - ), - ] - - for param, expected_substring in cases: - message = expect_fatal(shared_utils.infer_param_type_string, param) - assert expected_substring in message - - -def test_check_kind_validation(): - # Known kind should not invoke fatal. - shared_utils.check_kind("base", "NR-1", None, lambda msg: (_ for _ in ()).throw(AssertionError(msg)), "x.py") - - message = expect_fatal(shared_utils.check_kind, "unknown", "NR-2", "tag-a", program_name="x.py") - assert "Don't recognize kind 'unknown'" in message - assert "tag tag-a in normative rule NR-2" in message - assert "x.py: Allowed kinds are:" in message - - -def test_check_impldef_cat_validation(): - # Known category should not invoke fatal. - shared_utils.check_impldef_cat("WARL", "NR-1", None, lambda msg: (_ for _ in ()).throw(AssertionError(msg)), "x.py") - - message = expect_fatal(shared_utils.check_impldef_cat, "BAD", "NR-2", "tag-b", program_name="x.py") - assert "Don't recognize impl-def-category 'BAD'" in message - assert "tag tag-b in normative rule NR-2" in message - assert "x.py: Allowed impl-def-categories are:" in message - - def main() -> int: test_error_prints_expected_prefix() test_make_log_helpers_info_and_error_output() test_make_log_helpers_fatal_exits() test_load_json_object_success_and_top_level_validation() - test_load_yaml_object_success() - test_format_param_feature_impldefs_and_fallbacks() - test_infer_param_type_string_success_cases() - test_infer_param_type_string_all_fatal_cases() - test_check_kind_validation() - test_check_impldef_cat_validation() print("test_shared_utils.py: all tests passed") return 0 diff --git a/tests/text_to_html/test_tag_text_to_html_unit.py b/tests/text_to_html/test_tag_text_to_html_unit.py index 520b169..d57df24 100644 --- a/tests/text_to_html/test_tag_text_to_html_unit.py +++ b/tests/text_to_html/test_tag_text_to_html_unit.py @@ -19,19 +19,14 @@ def test_empty_tag_text_returns_placeholder(): assert convert_tag_text_to_html(" ") == "(No text available)" -def test_context_prefix_is_added(): - assert convert_tag_text_to_html("Some text", is_context=True) == "[CONTEXT] Some text" - - def test_tag_text_conversion_with_link_target(): text = "See <>" - expected = '[CONTEXT] See norm:r2' - assert convert_tag_text_to_html(text, target_html_fname="rules.html", is_context=True) == expected + expected = 'See norm:r2' + assert convert_tag_text_to_html(text, target_html_fname="rules.html") == expected def main() -> int: test_empty_tag_text_returns_placeholder() - test_context_prefix_is_added() test_tag_text_conversion_with_link_target() print("test_tag_text_to_html_unit.py: all tests passed") return 0 diff --git a/tools/README.md b/tools/README.md index 9749687..9613d4a 100644 --- a/tools/README.md +++ b/tools/README.md @@ -9,11 +9,8 @@ This directory contains command-line generators and shared Python helper modules | adoc_to_html.py | Helper module | Converts inline AsciiDoc formatting and entities to HTML. | | def_text_to_html.py | Helper module | Converts definition text to HTML, including table and anchor-link handling. | | tag_text_to_html.py | Helper module | Converts tag text to HTML and applies tag-specific display behavior. | -| shared_utils.py | Helper module | Shared constants, logging helpers, YAML/JSON loaders, and common validators/formatters. | -| create_normative_rules.py | CLI tool | Builds normative-rules JSON or HTML from rule-definition YAML and tag JSON files. | -| create_params.py | CLI tool | Builds params JSON or HTML from normative-rules JSON and parameter-definition YAML files. | -| create_param_tables.py | CLI tool | Generates parameter and/or CSR AsciiDoc fragments and include files from params JSON and table-layout YAML files. | -| export_params_to_udb.py | CLI tool | Converts a params.json file (conforming to schemas/params-schema.json) into individual YAML files for each parameter (conforming to schemas/udb_param_schema.json). | +| shared_utils.py | Helper module | Shared logging helpers and JSON loader. | +| create_normative_rules.py | CLI tool | Builds normative-rules JSON or HTML from tag JSON files. | ## Script Details @@ -43,7 +40,7 @@ Key capabilities: - Newline conversion and link helper utilities. Usage: -- Imported by create_normative_rules.py, create_params.py, and tag_text_to_html.py. +- Imported by create_normative_rules.py and tag_text_to_html.py. ### tag_text_to_html.py @@ -53,232 +50,40 @@ Purpose: Key capabilities: - Pipeline conversion via convert_tag_text_to_html. - Returns a "(No text available)" placeholder for empty tag text. -- Prefixes context-only tag text with "[CONTEXT]". Usage: -- Imported by create_normative_rules.py and create_params.py. +- Imported by create_normative_rules.py. ### shared_utils.py Purpose: -- Provides shared constants, logging helpers, file loaders, and common validators/formatters used across tools scripts. +- Provides shared logging helpers and a JSON file loader used across tools scripts. Key capabilities: - make_log_helpers: creates script-scoped error/info/fatal callable helpers. -- load_json_object / load_yaml_object: safe JSON and YAML file loaders with error reporting. -- infer_param_type_string: renders human-readable parameter type strings for table output. -- format_param_feature: renders a parameter feature string from chapter name and impl-defs. -- Constants for standards object kinds, impl-def categories, and CSR category mappings. +- load_json_object: safe JSON file loader with error reporting. Usage: -- Imported by create_normative_rules.py, create_params.py, and create_param_appendix.py. +- Imported by create_normative_rules.py. -### create_params.py +### create_normative_rules.py Purpose: -- Creates params JSON/HTML outputs from normative-rules JSON plus parameter-definition YAML files. +- Creates the normative-rules JSON/HTML outputs for a standard from the tag JSON files that the tags.rb Asciidoctor backend extracts. +- Every tag is one normative rule. The rule name is the tag name without the "norm:" prefix; there is no separate rule definition and no mapping between rules and tags. -Inputs: -- Normative-rules JSON file (-n / --norm-rules) -- Parameter definition files (-d / --param-def) - -Outputs: -- JSON (default) or HTML file. -```bash -python3 tools/create_params.py \ - --norm-rules build/test-norm-rules.json \ - --param-def tests/params/test-ch1.yaml \ - --param-def tests/params/test-ch2.yaml \ - --output build/test-params.json -``` - -```bash -python3 tools/create_params.py --html \ - --norm-rules build/test-norm-rules.json \ - --param-def tests/params/test-ch1.yaml \ - --param-def tests/params/test-ch2.yaml \ - --output build/test-params.html -``` - -Parameter Type Encoding: -- Each parameter definition must include exactly one of `type` or `range`. -- `type` may be one of: - - Unsigned integers: `boolean`, `bit`, `byte`, `hword`, `word`, `dword`, `uint` - - Signed integers: `int` - - Enum composed of strings (e.g. `[ABC, DEF]`) or integers (e.g., `[32, 64]`) -- `width` (in bits) is required when `type` is `int` or `uint`. - - Integer width: `2..64` (inclusive, use `bit` for 1-bit integers) - - Or the name of another parameter that supplies the bit width -- `array` is optional and, when present, wraps the base integer/range/list as a fixed-length array. - - Format: `[lo, hi]` where `lo >= 0` and `lo <= hi` -- `range` is an inclusive integer range of two integers. - - Format: `[lo, hi]` where `lo < hi` (negative values are allowed) - -Examples: -```yaml -# Scalar fixed-width integer -- name: UINT_OF_WIDTH_32 - impl-def: UINT32 - type: uint - width: 32 - -# Scalar width derived from another parameter -- name: MXLEN - type: [32, 64] - description: Supported machine register widths. -- name: INT_MXLEN - type: int - width: MXLEN - description: Signed integer whose width is MXLEN. - -# Lists (AKA enums) values -- name: MODE - impl-def: MODE - type: [A, B, C] -- name: XLEN - impl-defs: [XLEN1, XLEN2] - type: [32, 64] - -# Range form (inclusive) -- name: PRIORITY - impl-def: PRIORITY - range: [-10, 20] - -# Array of uint values with fixed element count -- name: ARRAY_OF_UINT5 - impl-def: ARRAY - type: uint - width: 5 - array: [0, 3] - -# Array of ranged integers -- name: ARRAY_OF_NEG10TO20 - impl-def: ARRAY - range: [-10, 20] - array: [0, 3] -``` - -CSR Definition Encoding: -- Use `csr_definitions` entries for CSRs, with `reg-name` (single CSR) or `reg-names` (multiple CSRs). -- Every CSR/field entry must include `type` with one of: - - `LegalEnum` - Standard defines legal values and implementation supports a subset that doesn't use all possible bit encodings (e.g., 10 values in a 4-bit field). Implementation's config file provides: - - A list of supported legal write values. An empty list indicates the CSR/field is treated as read-only zero. - - An indication of whether illegal write values are ignored or how they map to legal values - - `VarWidth` - CSR/field is variable width and the `width-parameter` property provides the name of the parameter that provides its value. - - `ConstMask` - CSR/field allows implementation to treat some bits as constant values. Writes are ignored and reads return the constant value. Implementation's config file provides: - - mask: A bit mask (1 = constant, 0 = variable) of constant bits - - value: The value of those constant bits. If they are all zero the value can be omitted. - - `Other` - CSR/field doesn't match any of the other `type` choices -- Every CSR entry must include `impl-def` or `impl-defs`. - - At least one referenced normative rule must provide `impl-def-category`. - - Any provided `impl-def-category` values across referenced impl-defs must agree. - - The category is mapped into CSR category (`WARL`/`WLRL`) for output grouping. -- If CSR/field type values are a function of another CSR/field: - - `func-of-reg-name`: Name of other CSR register (can be omitted if same CSR as this one) - - `func-of-field-name`: Name of other CSR field (can be omitted if entire CSR value) -- In HTML and AsciiDoc output, the `Type` column adds `func-of: [.]` on a new line when either of these properties is present. - -Examples: -```yaml -# Implementation supports a list of legal values (specified in config file) -- reg-name: mtvec - field-name: MODE - impl-def: MTVEC_MODE_WARL - type: LegalEnum - -# Implementation has field legal values a function of another field (specified in config file) -- reg-name: mtvec - field-name: BASE - impl-def: MTVEC_BASE_WARL - type: LegalEnum - func-of-reg-name: mtvec - func-of-field-name: MODE - -# Width-based CSR field (VarWidth parameter name provided by `width-parameter` property) -- reg-name: satp - field-name: ASID - impl-def: SATP_ASID_WARL - type: VarWidth - width-parameter: ASIDLEN - -# Implementation's config file provides bit mask of constant bits and their value (if not all 0). -- reg-name: zort - impl-def: ZORT_IMPL - type: ConstMask - -# Explicitly "Other" (doesn't match other `type` values) -- reg-name: mstatus - field-name: MPP - impl-def: MSTATUS_MPP_WLRL - type: Other -``` - - -### create_param_tables.py - -Purpose: -- Generates AsciiDoc table-row fragment files and include files for parameters and/or CSRs from a params JSON file. - -Inputs: -- Params JSON file (`-i` / `--input`). -- Parameter table-layout YAML file (`--param-table`), conforming to `schemas/param-table-schema.json` (optional). -- CSR table-layout YAML file (`--csr-table`), conforming to `schemas/csr-table-schema.json` (optional). -- At least one of `--param-table` or `--csr-table` must be provided. - -Outputs: -- Output directory containing: - - Per-chapter subdirectories (for example, `/`). - - Per-parameter and/or per-CSR row fragments grouped by AsciiDoc filename under chapter-local `params/` and `csrs/` subdirectories. - - Per-adoc include files (`/params/all_params.adoc`, `/csrs/all_csrs.adoc`) in input JSON order. - - Per-chapter combined include file (`/all_params.adoc`) containing all parameter and CSR row includes for that chapter. - - Top-level include files: - - `all_params_a_to_z.adoc` (two global tables across all chapters: one for parameters and one for CSRs, each sorted A-Z). - - `all_params_by_chapter.adoc` (chapter-organized, with separate parameter and CSR tables per chapter in input order). - -Behavior: -- If `--param-table` is given, generates parameter appendix files (like the old create_param_appendix.py) -- If `--csr-table` is given, generates CSR appendix files (like the old create_csr_appendix.py) -- If both are given, generates both under chapter-local `params/` and `csrs/` subdirectories and writes unified top-level `all_params*.adoc` files - -Typical commands: -```bash -# Generate parameter appendix only -python3 tools/create_param_tables.py \ - --input build/test-params.json \ - --param-table tools/default_param_table.yaml \ - --output-dir build/test-param-tables - -# Generate CSR appendix only -python3 tools/create_param_tables.py \ - --input build/test-params.json \ - --csr-table tools/default_csr_table.yaml \ - --output-dir build/test-csr-appendix-adoc-includes - -# Generate both in the same directory -python3 tools/create_param_tables.py \ - --input build/test-params.json \ - --param-table tools/default_param_table.yaml \ - --csr-table tools/default_csr_table.yaml \ - --output-dir build/merged-appendix-adoc-includes -``` - -### export_params_to_udb.py - -Purpose: -- Converts a params.json file (conforming to schemas/params-schema.json) into individual YAML files for each parameter (conforming to schemas/udb_param_schema.json). - -Arguments: -- `-i`, `--input` (required): Path to params.json input file -- `-o`, `--output-dir` (required): Directory to write YAML files -- `-h`, `--help`: Show help message and exit +Key capabilities: +- Uses each tag file's section tree to give every rule the title of the chapter (level-1 section) containing its tag. +- JSON output conforms to schemas/norm-rules-schema.json (name, chapter_name, text, tag_filename, and stds_doc_url for each rule). +- HTML output has one table per chapter in document order, with an anchor per rule name and a link from each rule to its tag in the standard. +- Fails on duplicate tag names and on tag names without the "norm:" prefix. Usage: ```bash -python3 tools/export_params_to_udb.py -i build/test-params.json -o build/test-export-params-to-udb +python3 tools/create_normative_rules.py -j -t build/test-ch1-norm-tags.json -tag2url build/test-ch1-norm-tags.json test-ch1.html build/test-norm-rules.json +python3 tools/create_normative_rules.py --html -t build/test-ch1-norm-tags.json -tag2url build/test-ch1-norm-tags.json test-ch1.html build/test-norm-rules.html ``` -Each output YAML file will be named `.yaml` (upper-case) and placed in the specified output directory. - ## Notes - These scripts are exercised by targets in the repository Makefile. diff --git a/tools/appendix_shared_utils.py b/tools/appendix_shared_utils.py deleted file mode 100644 index ec8d4da..0000000 --- a/tools/appendix_shared_utils.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -"""Shared helpers for appendix generators.""" - -import re -from typing import Any, Dict, List - - -def safe_filename(name: str) -> str: - """Map a display name to a safe output filename stem.""" - return re.sub(r"[^A-Za-z0-9_.-]", "_", name) - - -def infer_normative_rules(item: Dict[str, Any]) -> List[str]: - """Return unique normative rule names referenced by impl-defs.""" - impl_defs = item.get("impl-defs") - if not isinstance(impl_defs, list): - return [] - - names: List[str] = [] - seen = set() - for impl_def in impl_defs: - if not isinstance(impl_def, dict): - continue - name = impl_def.get("name") - if isinstance(name, str) and name not in seen: - seen.add(name) - names.append(name) - return names - - -def render_table_cols_spec(columns: List[Dict[str, Any]]) -> str: - """Render AsciiDoc cols specification from column widths.""" - return ",".join(f"{col['width_pct']}%" for col in columns) - - -def render_table_header_row(columns: List[Dict[str, Any]]) -> str: - """Render AsciiDoc header row from configured display names.""" - return "| " + " | ".join(str(col["name"]) for col in columns) diff --git a/tools/create_normative_rules.py b/tools/create_normative_rules.py index 3565469..4f068d3 100755 --- a/tools/create_normative_rules.py +++ b/tools/create_normative_rules.py @@ -1,22 +1,18 @@ #!/usr/bin/env python3 -"""Create normative rules from tag and definition files.""" +"""Create normative rules from tag files. + +Every normative tag (an AsciiDoc anchor whose name starts with "norm:") is one normative rule. +The rule's name is the tag's name without the "norm:" prefix. There is no separate definition +of normative rules and no mapping between rules and tags. +""" import json import sys -import re import argparse -from pathlib import Path from typing import Dict, List, Optional, Any, Tuple -from def_text_to_html import ( - convert_def_text_to_html, - tag2html_link, -) +from def_text_to_html import tag2html_link from shared_utils import ( - IMPLDEF_CATEGORIES, - check_impldef_cat, - check_kind, load_json_object, - load_yaml_object, make_log_helpers, ) from tag_text_to_html import convert_tag_text_to_html @@ -27,268 +23,42 @@ # Names/prefixes for tables in HTML output. NORM_RULES_CH_TABLE_NAME_PREFIX = "table-norm-rules-ch-" -IMPLDEFS_NO_CAT_TABLE_NAME_PREFIX = "table-impldefs-no-cat" -IMPLDEFS_CAT_TABLE_NAME_PREFIX = "table-impldefs-impl-cat-" -IMPLDEFS_CH_TABLE_NAME_PREFIX = "table-impldefs-ch-" -# Norm rule name checking -NORM_RULE_NAME_PATTERN = r"^[a-zA-Z][a-zA-Z0-9_-]+$" -IMPLDEF_NAME_PATTERN = r"^[A-Z][A-Z0-9_]+$" +# AsciiDoc section level of a chapter. Level 0 sections are parts (e.g., the volumes of a book). +CHAPTER_LEVEL = 1 error, info, fatal = make_log_helpers(PN) -################################### -# Classes for Normative Rule Tags # -################################### - +class NormativeRule: + """Holds all information for one normative rule (i.e., one normative tag).""" -class NormativeTag: - """Holds all information for one tag.""" - - def __init__(self, name: str, tag_filename: str, text: str): - if not isinstance(name, str): - fatal(f"Need String for name but passed a {type(name).__name__}") + def __init__(self, tag_name: str, tag_filename: str, text: str, chapter_name: str, chapter_key: str): + if not isinstance(tag_name, str): + fatal(f"Need String for tag_name but passed a {type(tag_name).__name__}") if not isinstance(tag_filename, str): fatal(f"Need String for tag_filename but passed a {type(tag_filename).__name__}") if not isinstance(text, str): fatal(f"Need String for text but passed a {type(text).__name__}") + if not isinstance(chapter_name, str): + fatal(f"Need String for chapter_name but passed a {type(chapter_name).__name__}") + if not isinstance(chapter_key, str): + fatal(f"Need String for chapter_key but passed a {type(chapter_key).__name__}") - self.name = name + self.tag_name = tag_name + self.name = tag_name[len(NORM_PREFIX):] self.tag_filename = tag_filename self.text = text - - -class NormativeTags: - """Holds all the normative rule tags for a RISC-V standard.""" - - def __init__(self): - # Contains tag entries as a flat hash for the entire standard (across multiple tag files). - # The hash key is the tag name and the hash value is a NormativeTag object - # The tag names must be unique across the standard. - self.tag_map: Dict[str, NormativeTag] = {} - - def add_tags(self, tag_filename: str, tags: Dict[str, str]): - """Add tags for specified standards document. - - Args: - tag_filename: Name of the tag file - tags: Hash key is tag name (AKA anchor name) and value is tag text. - """ - if not isinstance(tag_filename, str): - fatal(f"Need String for tag_filename but was passed a {type(tag_filename).__name__}") - if not isinstance(tags, dict): - fatal(f"Need Dict for tags but was passed a {type(tags).__name__}") - - for name, text in tags.items(): - if not isinstance(name, str): - fatal(f"Tag name {name} in file {tag_filename} is a {type(name).__name__} instead of a String") - - if not isinstance(text, str): - fatal(f"Tag name {name} in file {tag_filename} is a {type(text).__name__} instead of a String\n" - f"{PN}: If the AsciiDoc anchor for {name} is before an AsciiDoc 'Description List' term, " - f"move to after term on its own line.") - - if name in self.tag_map: - fatal(f"Tag name {name} in file {tag_filename} already defined in file {self.tag_map[name].tag_filename}") - - self.tag_map[name] = NormativeTag(name, tag_filename, text) - - def get_tag(self, name: str) -> Optional[NormativeTag]: - """Get normative tag object corresponding to tag name. Returns None if not found.""" - return self.tag_map.get(name) - - def get_tags(self) -> List[NormativeTag]: - """Return all normative tags for the standard.""" - return list(self.tag_map.values()) - - -########################################## -# Classes for Normative Rule Definitions # -########################################## - - -class TagRef: - """Holds reference to one tag in a normative rule definition.""" - - def __init__(self, name: str, context: bool = False): - if not isinstance(name, str): - fatal(f"Need String for name but was passed a {type(name).__name__}") - if not isinstance(context, bool): - fatal(f"Need Boolean for context but was passed a {type(context).__name__}") - - self.name = name - self._context = context - - def is_context(self) -> bool: - return self._context - - -class NormativeRuleDef: - """Holds one normative rule definition.""" - - def __init__(self, name: str, def_filename: str, chapter_name: str, data: Dict[str, Any]): - if not isinstance(name, str): - fatal(f"Need String for name but was passed a {type(name).__name__}") - if not isinstance(def_filename, str): - fatal(f"Need String for def_filename but was passed a {type(def_filename).__name__}") - if not isinstance(chapter_name, str): - fatal(f"Need String for chapter_name but was passed a {type(chapter_name).__name__}") - if not isinstance(data, dict): - fatal(f"Need Dict for data but was passed a {type(data).__name__}") - - self.name = name - self.def_filename = def_filename self.chapter_name = chapter_name - - self.summary = data.get("summary") - if self.summary is not None and not isinstance(self.summary, str): - fatal(f"Provided {type(self.summary).__name__} class for summary in normative rule {name} but need a String") - - self.note = data.get("note") - if self.note is not None and not isinstance(self.note, str): - fatal(f"Provided {type(self.note).__name__} class for note in normative rule {name} but need a String") - - self.clarification_link = data.get("clarification-link") - if self.clarification_link is not None and not isinstance(self.clarification_link, str): - fatal(f"Provided {type(self.clarification_link).__name__} class for clarification_link in normative rule {name} but need a String") - - self.clarification_text = data.get("clarification-text") - if self.clarification_text is not None and not isinstance(self.clarification_text, str): - fatal(f"Provided {type(self.clarification_text).__name__} class for clarification_text in normative rule {name} but need a String") - - self.description = data.get("description") - if self.description is not None and not isinstance(self.description, str): - fatal(f"Provided {type(self.description).__name__} class for description in normative rule {name} but need a String") - - self.kind = data.get("kind") - if self.kind is not None: - if not isinstance(self.kind, str): - fatal(f"Provided {type(self.kind).__name__} class for kind in normative rule {name} but need a String") - check_kind(self.kind, self.name, None, fatal, PN) - - self.impldef = data.get("impl-def-behavior", False) - if not isinstance(self.impldef, bool): - fatal(f"Provided {type(self.impldef).__name__} class for impl-def-behavior in normative rule {name} but need a Boolean") - - self.impldef_cat = data.get("impl-def-category") - if self.impldef_cat is not None: - if not isinstance(self.impldef_cat, str): - fatal(f"Provided {type(self.impldef_cat).__name__} class for impldef_cat in normative rule {name} but need a String") - check_impldef_cat(self.impldef_cat, self.name, None, fatal, PN) - - if not self.impldef: - fatal(f"Normative rule {name} has impl-def-category property but impl-def-behavior isn't true") - - self.instances: List[str] = [] - if "instance" in data and data["instance"] is not None: - self.instances.append(data["instance"]) - if "instances" in data and data["instances"] is not None: - instances = data["instances"] - if not isinstance(instances, list): - fatal(f"Normative rule {name} has non-list instances. Use \"instance\" instead.") - if not instances: - fatal(f"Normative rule {name} has empty instances") - self.instances.extend(instances) - - if self.kind is None: - # Not allowed to have instances without a kind. - if self.instances: - fatal(f"Normative rule {name} defines instances but no kind") - else: - if not isinstance(self.instances, list): - fatal(f"Provided {type(self.instances).__name__} class for instances in normative rule {name} but need a List") - - self.tag_refs: List[TagRef] = [] - if "tag" in data and data["tag"] is not None: - self.tag_refs.append(TagRef(data["tag"])) - if "tags" in data and data["tags"] is not None: - tags_data = data["tags"] - if not isinstance(tags_data, list): - fatal(f"Normative rule {name} has non-list tags. Use \"tag\" instead.") - if not tags_data: - fatal(f"Normative rule {name} has empty tags") - for tag_data in tags_data: - if isinstance(tag_data, str): - self.tag_refs.append(TagRef(tag_data)) - elif isinstance(tag_data, dict): - tag_name = tag_data.get("name") - if tag_name is None: - fatal(f"Normative rule {name} tag reference {tag_data} missing name") - if not isinstance(tag_name, str): - fatal(f"Normative rule {name} tag reference {tag_data} has non-string name") - - context = tag_data.get("context", False) - self.tag_refs.append(TagRef(tag_name, context)) - else: - fatal(f"Normative rule {name} has tag reference that's a {type(tag_data).__name__} instead of a String or Dict: {tag_data}") - - # Validate name (function of impldef). - pattern = IMPLDEF_NAME_PATTERN if self.impldef else NORM_RULE_NAME_PATTERN - if not re.match(pattern, self.name): - fatal(f"Normative rule '{name}' doesn't match regex pattern '{pattern}'") - - -class NormativeRuleDefs: - """Holds all the information for all normative rule definition files.""" - - def __init__(self): - self.norm_rule_defs: List[NormativeRuleDef] = [] - self._defs_by_name: Dict[str, NormativeRuleDef] = {} - - def add_file_contents(self, def_filename: str, chapter_name: str, array_data: List[Any]): - if not isinstance(def_filename, str): - fatal(f"Need String for def_filename but passed a {type(def_filename).__name__}") - if not isinstance(chapter_name, str): - fatal(f"Need String for chapter_name but passed a {type(chapter_name).__name__}") - if not isinstance(array_data, list): - fatal(f"Need List for array_data but passed a {type(array_data).__name__}") - if not array_data: - fatal(f"Need non-empty List for array_data in {def_filename}") - - for data in array_data: - if not isinstance(data, dict): - fatal(f"File {def_filename} entry isn't a dict: {data}") - - if "name" in data and data["name"] is not None: - # Add one definition object - self._add_def(data["name"], def_filename, chapter_name, data) - elif "names" in data and data["names"] is not None: - # Add one definition object for each name in array - names = data["names"] - if not isinstance(names, list): - fatal(f"File {def_filename} has non-list names in normative rule definition entry: {data} (Use \"name\" instead.)") - if not names: - fatal(f"File {def_filename} has empty names in normative rule definition entry: {data}") - for name in names: - self._add_def(name, def_filename, chapter_name, data) - else: - fatal(f"File {def_filename} missing name/names in normative rule definition entry: {data}") - - def _add_def(self, name: str, def_filename: str, chapter_name: str, data: Dict[str, Any]): - if not isinstance(name, str): - fatal(f"Need String for name but passed a {type(name).__name__}") - if not isinstance(def_filename, str): - fatal(f"Need String for def_filename but passed a {type(def_filename).__name__}") - if not isinstance(chapter_name, str): - fatal(f"Need String for chapter_name but passed a {type(chapter_name).__name__}") - if not isinstance(data, dict): - fatal(f"Need Dict for data but passed a {type(data).__name__}") - - if name in self._defs_by_name: - fatal(f"Normative rule definition {name} in file {def_filename} already defined in file {self._defs_by_name[name].def_filename}") - - # Create definition object and store reference to it in array (to maintain order) and defs_by_name (for convenient lookup by name). - norm_rule_def = NormativeRuleDef(name, def_filename, chapter_name, data) - self.norm_rule_defs.append(norm_rule_def) - self._defs_by_name[name] = norm_rule_def + # Unique key for the chapter (chapter titles such as "Introduction" can repeat). + self.chapter_key = chapter_key -def parse_argv() -> Tuple[List[str], List[str], Dict[str, str], str, str, bool]: +def parse_argv() -> Tuple[List[str], Dict[str, str], str, str]: """Parse command line arguments. Returns: - Tuple of (def_fnames, tag_fnames, tag_fname2url, output_fname, output_format, warn_if_tags_no_rules) + Tuple of (tag_fnames, tag_fname2url, output_fname, output_format) """ parser = argparse.ArgumentParser( description='Creates list of normative rules and stores them in (JSON format).', @@ -298,10 +68,6 @@ def parse_argv() -> Tuple[List[str], List[str], Dict[str, str], str, str, bool]: default='json', help='Set output format to JSON (default)') parser.add_argument('--html', action='store_const', const='html', dest='output_format', help='Set output format to HTML') - parser.add_argument('-w', action='store_true', dest='warn_if_tags_no_rules', - help='Warning instead of error if tags found without rules (Only use for debugging!)') - parser.add_argument('-d', action='append', dest='def_fnames', metavar='fname', - help='Normative rule definition filename (YAML format)') parser.add_argument('-t', action='append', dest='tag_fnames', metavar='fname', help='Normative tag filename (JSON format)') parser.add_argument('-tag2url', action='append', nargs=2, dest='tag2url_list', @@ -312,11 +78,6 @@ def parse_argv() -> Tuple[List[str], List[str], Dict[str, str], str, str, bool]: args = parser.parse_args() # Validate required arguments - if not args.def_fnames: - info("Missing normative rule definition filename(s)") - parser.print_help() - sys.exit(1) - if not args.tag_fnames: info("Missing normative tag filename(s)") parser.print_help() @@ -328,25 +89,64 @@ def parse_argv() -> Tuple[List[str], List[str], Dict[str, str], str, str, bool]: for tag_fname, url in args.tag2url_list: tag_fname2url[tag_fname] = url - if (args.output_format in ['json', 'html']) and not tag_fname2url: + if not tag_fname2url: info("Missing -tag2url command line options") parser.print_help() sys.exit(1) - return (args.def_fnames, args.tag_fnames, tag_fname2url, - args.output_fname, args.output_format, args.warn_if_tags_no_rules) + return (args.tag_fnames, tag_fname2url, args.output_fname, args.output_format) + +def find_tag_chapters(tag_fname: str, sections: Dict[str, Any]) -> Dict[str, Tuple[str, str]]: + """Return a Dict from tag name to (chapter name, chapter key) using the section tree in a tag file. + + A tag's chapter is its nearest enclosing section of level CHAPTER_LEVEL. A tag outside any + chapter (e.g., directly in a part or in the preamble) uses its nearest enclosing section instead. + """ + if not isinstance(sections, dict): + fatal(f"'sections' must be an object in {tag_fname}") + + tag2chapter: Dict[str, Tuple[str, str]] = {} + + def walk(node: Dict[str, Any], chapter: Optional[Dict[str, Any]], nearest: Optional[Dict[str, Any]]): + for key in ("children", "tags"): + if not isinstance(node.get(key), list): + fatal(f"Section {node.get('title')!r} in {tag_fname} has no '{key}' list") + + if node is not sections: + nearest = node + level = node.get("level") + if not isinstance(level, int): + fatal(f"Section {node.get('title')!r} in {tag_fname} has no integer 'level'. " + f"Rebuild the tag file with the current tags.rb backend.") + if level == CHAPTER_LEVEL: + chapter = node + + owner = chapter if chapter is not None else nearest + for tag_name in node["tags"]: + if owner is None: + tag2chapter[tag_name] = ("", f"{tag_fname}#") + else: + tag2chapter[tag_name] = (owner.get("title") or "", f"{tag_fname}#{owner.get('id')}") + + for child in node["children"]: + walk(child, chapter, nearest) + + walk(sections, None, None) + return tag2chapter -def load_tags(tag_fnames: List[str]) -> NormativeTags: - """Load the contents of all normative rule tag files in JSON format. + +def load_rules(tag_fnames: List[str]) -> List[NormativeRule]: + """Load the contents of all normative tag files in JSON format. Returns: - NormativeTags class with all the contents. + List of NormativeRule objects in tag file order and document order within each tag file. """ if not isinstance(tag_fnames, list): fatal(f"Need List[String] for tag_fnames but passed a {type(tag_fnames).__name__}") - tags = NormativeTags() + rules: List[NormativeRule] = [] + tag_name2fname: Dict[str, str] = {} for tag_fname in tag_fnames: info(f"Loading tag file {tag_fname}") @@ -359,188 +159,67 @@ def load_tags(tag_fnames: List[str]) -> NormativeTags: fatal(f"'tags' must be an object in {tag_fname}") assert isinstance(tags_data, dict) - # Add tags from JSON file to Python class. - tags.add_tags(tag_fname, tags_data) - - return tags - - -def load_definitions(def_fnames: List[str]) -> NormativeRuleDefs: - """Load the contents of all normative rule definition files in YAML format. + sections = file_data.get("sections") + if sections is None: + fatal(f"Missing 'sections' key in {tag_fname}") + tag2chapter = find_tag_chapters(tag_fname, sections) - Returns: - NormativeRuleDefs class with all the contents. - """ - if not isinstance(def_fnames, list): - fatal(f"Need List[String] for def_fnames but passed a {type(def_fnames).__name__}") + for tag_name, text in tags_data.items(): + if not isinstance(tag_name, str): + fatal(f"Tag name {tag_name} in file {tag_fname} is a {type(tag_name).__name__} instead of a String") - defs = NormativeRuleDefs() + if not isinstance(text, str): + fatal(f"Tag name {tag_name} in file {tag_fname} is a {type(text).__name__} instead of a String\n" + f"{PN}: If the AsciiDoc anchor for {tag_name} is before an AsciiDoc 'Description List' term, " + f"move to after term on its own line.") - for def_fname in def_fnames: - info(f"Loading definition file {def_fname}") - yaml_hash = load_yaml_object(def_fname, fatal) + if not tag_name.startswith(NORM_PREFIX): + fatal(f"Tag name {tag_name} in file {tag_fname} doesn't start with \"{NORM_PREFIX}\"") - chapter_name = yaml_hash.get("chapter_name") - if chapter_name is None: - fatal(f"Missing 'chapter_name' key in {def_fname}") - if not isinstance(chapter_name, str): - fatal(f"'chapter_name' isn't a string in {def_fname}") - assert isinstance(chapter_name, str) + if tag_name in tag_name2fname: + fatal(f"Tag name {tag_name} in file {tag_fname} already defined in file {tag_name2fname[tag_name]}") + tag_name2fname[tag_name] = tag_fname - array_data = yaml_hash.get("normative_rule_definitions") - if array_data is None: - fatal(f"Missing 'normative_rule_definitions' key in {def_fname}") - if not isinstance(array_data, list) or not array_data: - fatal(f"'normative_rule_definitions' isn't a non-empty list in {def_fname}") - assert isinstance(array_data, list) + if tag_name not in tag2chapter: + fatal(f"Tag name {tag_name} in file {tag_fname} isn't in the file's section tree") + chapter_name, chapter_key = tag2chapter[tag_name] - defs.add_file_contents(def_fname, chapter_name, array_data) + rules.append(NormativeRule(tag_name, tag_fname, text, chapter_name, chapter_key)) - return defs + return rules -def create_normative_rules_hash(defs: NormativeRuleDefs, tags: NormativeTags, - tag_fname2url: Dict[str, str]) -> Dict[str, List[Dict[str, Any]]]: +def create_normative_rules_hash(rules: List[NormativeRule], + tag_fname2url: Dict[str, str]) -> Dict[str, List[Dict[str, Any]]]: """Returns a Dict with just one entry called "normative_rules" that contains a List of Dicts of all normative rules. Dict is suitable for JSON/YAML serialization. """ - if not isinstance(defs, NormativeRuleDefs): - fatal(f"Need NormativeRuleDefs for defs but was passed a {type(defs).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but was passed a {type(tags).__name__}") + if not isinstance(rules, list): + fatal(f"Need List[NormativeRule] for rules but was passed a {type(rules).__name__}") if not isinstance(tag_fname2url, dict): fatal(f"Need Dict for tag_fname2url but passed a {type(tag_fname2url).__name__}") - info("Creating normative rules from definition files") + info("Creating normative rules from tag files") ret: Dict[str, List[Dict[str, Any]]] = {"normative_rules": []} - for d in defs.norm_rule_defs: - # Create dict with mandatory definition file arguments. - hash_entry: Dict[str, Any] = { - "name": d.name, - "def_filename": d.def_filename, - "chapter_name": d.chapter_name - } + for nr in rules: + url = tag_fname2url.get(nr.tag_filename) + if url is None: + fatal(f"No fname tag to URL mapping (-tag2url cmd line arg) for tag fname {nr.tag_filename} for tag name {nr.tag_name}") - # Now add optional arguments. - if d.kind is not None: - hash_entry["kind"] = d.kind - hash_entry["impl-def-behavior"] = d.impldef - if d.instances: - hash_entry["instances"] = d.instances - if d.impldef_cat is not None: - hash_entry["impl-def-category"] = d.impldef_cat - if d.summary is not None: - hash_entry["summary"] = d.summary - if d.note is not None: - hash_entry["note"] = d.note - if d.clarification_text is not None: - hash_entry["clarification-text"] = d.clarification_text - if d.clarification_link is not None: - hash_entry["clarification-link"] = d.clarification_link - if d.description is not None: - hash_entry["description"] = d.description - - # Add tag entries - resolved_tags: List[Dict[str, Any]] = [] - for tag_ref in d.tag_refs: - # Lookup tag - tag = tags.get_tag(tag_ref.name) - if tag is None: - fatal(f"Normative rule {d.name} defined in file {d.def_filename} references non-existent tag {tag_ref.name}") - assert tag is not None - - url = tag_fname2url.get(tag.tag_filename) - if url is None: - fatal(f"No fname tag to URL mapping (-tag2url cmd line arg) for tag fname {tag.tag_filename} for tag name {tag.name}") - - resolved_tag = { - "name": tag.name, - "context": tag_ref.is_context(), - "text": tag.text, - "tag_filename": tag.tag_filename, - "stds_doc_url": url - } - - resolved_tags.append(resolved_tag) - if resolved_tags: - hash_entry["tags"] = resolved_tags - - ret["normative_rules"].append(hash_entry) + ret["normative_rules"].append({ + "name": nr.name, + "chapter_name": nr.chapter_name, + "text": nr.text, + "tag_filename": nr.tag_filename, + "stds_doc_url": url + }) return ret -def validate_defs_and_tags(defs: NormativeRuleDefs, tags: NormativeTags, warn_if_tags_no_rules: bool): - """Fatal error if any normative rule references a non-existent tag. - - Fatal error or warning (controlled by cmd line switch) if there are tags that no rule references. - """ - if not isinstance(defs, NormativeRuleDefs): - fatal(f"Need NormativeRuleDefs for defs but passed a {type(defs).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but was passed a {type(tags).__name__}") - - missing_tag_cnt = 0 - bad_norm_rule_name_cnt = 0 - unref_cnt = 0 - referenced_tags = {} # Key is tag name and value is any non-None value - - # Go through each normative rule definition. Look for: - # - References to non-existent tags - # - Normative rule names starting with NORM_PREFIX (should only be for tags) - for d in defs.norm_rule_defs: - for tag_ref in d.tag_refs: - # Lookup tag by its name - tag = tags.get_tag(tag_ref.name) - - if tag is None: - missing_tag_cnt += 1 - error(f"Normative rule {d.name} references non-existent tag {tag_ref.name} in file {d.def_filename}") - else: - referenced_tags[tag.name] = 1 # Any non-None value - - if d.name.startswith(NORM_PREFIX): - bad_norm_rule_name_cnt += 1 - error(f"Normative rule {d.name} starts with \"{NORM_PREFIX}\" prefix. This prefix is only for tag names, not rule names.") - - if d.clarification_text is not None: - if d.clarification_link is None: - error(f"Normative rule {d.name} has clarification-text but no clarification-link") - - if d.clarification_link is not None: - if not re.match(r'^https://(www\.)?github\.com/riscv/.+/issues/[0-9]+$', d.clarification_link): - error(f"Normative rule {d.name} clarification-link of '{d.clarification_link}' doesn't look like a RISC-V GitHub issue link") - - # Look for any unreferenced tags. - for tag in tags.get_tags(): - if tag.name not in referenced_tags: - msg = f"Tag {tag.name} not referenced by any normative rule. Did you forget to define a normative rule?" - if warn_if_tags_no_rules: - info(msg) - else: - error(msg) - unref_cnt += 1 - - if missing_tag_cnt > 0: - error(f"{missing_tag_cnt} reference{'s' if missing_tag_cnt != 1 else ''} to non-existing tags") - - if bad_norm_rule_name_cnt > 0: - error(f"{bad_norm_rule_name_cnt} illegal normative rule name{'s' if bad_norm_rule_name_cnt != 1 else ''}") - - if unref_cnt > 0: - msg = f"{unref_cnt} tag{'s' if unref_cnt != 1 else ''} have no normative rules referencing them" - if warn_if_tags_no_rules: - info(msg) - else: - error(msg) - - if (missing_tag_cnt > 0) or (bad_norm_rule_name_cnt > 0) or ((unref_cnt > 0) and not warn_if_tags_no_rules): - fatal("Exiting due to errors") - - def output_json(filename: str, normative_rules_hash: Dict[str, List[Dict[str, Any]]]): """Store normative rules in JSON output file.""" if not isinstance(filename, str): @@ -559,80 +238,28 @@ def output_json(filename: str, normative_rules_hash: Dict[str, List[Dict[str, An fatal(f"Error writing to {filename}: {e}") -def output_html(filename: str, defs: NormativeRuleDefs, tags: NormativeTags, - tag_fname2url: Dict[str, str]): +def output_html(filename: str, rules: List[NormativeRule], tag_fname2url: Dict[str, str]): """Store normative rules in HTML output file.""" if not isinstance(filename, str): fatal(f"Need String for filename but passed a {type(filename).__name__}") - if not isinstance(defs, NormativeRuleDefs): - fatal(f"Need NormativeRuleDefs for defs but passed a {type(defs).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but passed a {type(tags).__name__}") + if not isinstance(rules, list): + fatal(f"Need List[NormativeRule] for rules but passed a {type(rules).__name__}") if not isinstance(tag_fname2url, dict): fatal(f"Need Dict for tag_fname2url but passed a {type(tag_fname2url).__name__}") - # Array of all chapter names - chapter_names = [] - - # Organize rules. Each dict key is chapter name. Each dict entry is a List[NormativeRuleDef]. - norm_rules_by_chapter_name = {} - impldefs_by_chapter_name = {} - - # Are there any impldef normative rules? - any_impldefs = False - - # Create list of all impldef normative rules that don't have a category. - impldefs_no_cat = [] - - # Organize rules by implementation-defined category. - impldefs_by_cat = {cat: [] for cat in IMPLDEF_CATEGORIES} - - # Go through all normative rule definitions and put into appropriate data structures. - for d in defs.norm_rule_defs: - if d.chapter_name not in chapter_names: - chapter_names.append(d.chapter_name) - - if d.chapter_name not in norm_rules_by_chapter_name: - norm_rules_by_chapter_name[d.chapter_name] = [] - norm_rules_by_chapter_name[d.chapter_name].append(d) - - if d.impldef: - any_impldefs = True - - if d.impldef_cat is None: - impldefs_no_cat.append(d) - else: - impldefs_by_cat[d.impldef_cat].append(d) - - if d.chapter_name not in impldefs_by_chapter_name: - impldefs_by_chapter_name[d.chapter_name] = [] - impldefs_by_chapter_name[d.chapter_name].append(d) - - # Sort alphabetically for consistent output. - chapter_names.sort() - impldefs_no_cat.sort(key=lambda p: p.name) - for cat in IMPLDEF_CATEGORIES: - impldefs_by_cat[cat].sort(key=lambda p: p.name) + # Organize rules by chapter, keeping document order. Each dict key is a chapter key. + chapter_keys: List[str] = [] + chapter_names: Dict[str, str] = {} + rules_by_chapter: Dict[str, List[NormativeRule]] = {} + for nr in rules: + if nr.chapter_key not in rules_by_chapter: + chapter_keys.append(nr.chapter_key) + chapter_names[nr.chapter_key] = nr.chapter_name + rules_by_chapter[nr.chapter_key] = [] + rules_by_chapter[nr.chapter_key].append(nr) # Create list of all table names in order. - table_names = [] - table_num = 1 - for _ in chapter_names: - table_names.append(f"{NORM_RULES_CH_TABLE_NAME_PREFIX}{table_num}") - table_num += 1 - - if len(impldefs_no_cat) > 0: - table_names.append(IMPLDEFS_NO_CAT_TABLE_NAME_PREFIX) - - for cat in IMPLDEF_CATEGORIES: - if len(impldefs_by_cat[cat]) > 0: - table_names.append(f"{IMPLDEFS_CAT_TABLE_NAME_PREFIX}{cat}") - - table_num = 1 - for chapter_name in chapter_names: - if chapter_name in impldefs_by_chapter_name: - table_names.append(f"{IMPLDEFS_CH_TABLE_NAME_PREFIX}{table_num}") - table_num += 1 + table_names = [f"{NORM_RULES_CH_TABLE_NAME_PREFIX}{table_num}" for table_num in range(1, len(chapter_keys) + 1)] try: with open(filename, 'w', encoding='utf-8') as f: @@ -640,39 +267,14 @@ def output_html(filename: str, defs: NormativeRuleDefs, tags: NormativeTags, f.write('\n') f.write('
\n') - html_sidebar(f, chapter_names, defs.norm_rule_defs, any_impldefs, - impldefs_no_cat, impldefs_by_cat, impldefs_by_chapter_name) + html_sidebar(f, [chapter_names[key] for key in chapter_keys]) f.write('
\n') f.write(' \n') + f.write(f'

{get_counts_str(rules)}

\n') - counts_str = get_impldefs_counts_str(defs.norm_rule_defs) - f.write(f'

{counts_str}

\n') - - table_num = 1 - for chapter_name in chapter_names: - nr_defs = norm_rules_by_chapter_name[chapter_name] + for table_num, key in enumerate(chapter_keys, start=1): html_norm_rule_table(f, f"{NORM_RULES_CH_TABLE_NAME_PREFIX}{table_num}", - chapter_name, nr_defs, tags, tag_fname2url) - table_num += 1 - - if any_impldefs: - if len(impldefs_no_cat) > 0: - html_impldef_table(f, IMPLDEFS_NO_CAT_TABLE_NAME_PREFIX, - "No Category (A-Z)", impldefs_no_cat, tags, tag_fname2url) - - for cat in IMPLDEF_CATEGORIES: - nr_defs = impldefs_by_cat[cat] - if len(nr_defs) > 0: - html_impldef_cat_table(f, f"{IMPLDEFS_CAT_TABLE_NAME_PREFIX}{cat}", - f"{cat} Category (A-Z)", nr_defs, tags, tag_fname2url) - - table_num = 1 - for chapter_name in chapter_names: - if chapter_name in impldefs_by_chapter_name: - nr_defs = impldefs_by_chapter_name[chapter_name] - html_impldef_table(f, f"{IMPLDEFS_CH_TABLE_NAME_PREFIX}{table_num}", - f"Chapter {chapter_name}", nr_defs, tags, tag_fname2url) - table_num += 1 + chapter_names[key], rules_by_chapter[key], tag_fname2url) f.write('
\n') f.write('
\n') @@ -830,120 +432,39 @@ def html_head(f, table_names: List[str]): ''') -def html_sidebar(f, chapter_names: List[str], nrs: List[NormativeRuleDef], - any_impldefs: bool, impldefs_no_cat: List[NormativeRuleDef], - impldefs_by_cat: Dict[str, List[NormativeRuleDef]], - impldefs_by_chapter_name: Dict[str, List[NormativeRuleDef]]): + +def html_sidebar(f, chapter_names: List[str]): """Write HTML sidebar section.""" if not isinstance(chapter_names, list): fatal(f"Need List for chapter_names but passed a {type(chapter_names).__name__}") - if not isinstance(nrs, list): - fatal(f"Need List[NormativeRuleDef] for nrs but passed a {type(nrs).__name__}") - if not isinstance(any_impldefs, bool): - fatal(f"Need Boolean for any_impldefs but passed a {type(any_impldefs).__name__}") - if not isinstance(impldefs_no_cat, list): - fatal(f"Need List[NormativeRuleDef] for impldefs_no_cat but passed a {type(impldefs_no_cat).__name__}") - if not isinstance(impldefs_by_cat, dict): - fatal(f"Need Dict for impldefs_by_cat but passed a {type(impldefs_by_cat).__name__}") - if not isinstance(impldefs_by_chapter_name, dict): - fatal(f"Need Dict for impldefs_by_chapter_name but passed a {type(impldefs_by_chapter_name).__name__}") f.write('\n') f.write(' \n') def html_norm_rule_table(f, table_name: str, chapter_name: str, - nr_defs: List[NormativeRuleDef], tags: NormativeTags, - tag_fname2url: Dict[str, str]): + rules: List[NormativeRule], tag_fname2url: Dict[str, str]): """Write HTML table for normative rules.""" if not isinstance(table_name, str): fatal(f"Need String for table_name but passed a {type(table_name).__name__}") if not isinstance(chapter_name, str): fatal(f"Need String for chapter_name but passed a {type(chapter_name).__name__}") - if not isinstance(nr_defs, list): - fatal(f"Need List for nr_defs but passed a {type(nr_defs).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but passed a {type(tags).__name__}") - if not isinstance(tag_fname2url, dict): - fatal(f"Need Dict for tag_fname2url but passed a {type(tag_fname2url).__name__}") - - counts_str = get_impldefs_counts_str(nr_defs) - - html_table_header(f, table_name, f"Chapter {chapter_name}: {counts_str}") - for nr in nr_defs: - html_norm_rule_table_row(f, nr, tags, tag_fname2url) - html_table_footer(f) - - -def html_impldef_table(f, table_name: str, caption_prefix: str, - nr_defs: List[NormativeRuleDef], tags: NormativeTags, - tag_fname2url: Dict[str, str]): - """Write HTML table for implementation-defined behaviors.""" - if not isinstance(table_name, str): - fatal(f"Need String for table_name but passed a {type(table_name).__name__}") - if not isinstance(caption_prefix, str): - fatal(f"Need String for caption_prefix but passed a {type(caption_prefix).__name__}") - if not isinstance(nr_defs, list): - fatal(f"Need List for nr_defs but passed a {type(nr_defs).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but passed a {type(tags).__name__}") - if not isinstance(tag_fname2url, dict): - fatal(f"Need Dict for tag_fname2url but passed a {type(tag_fname2url).__name__}") - - html_table_header(f, table_name, f"{caption_prefix}: All {len(nr_defs)} Implementation-Defined Behaviors") - for nr in nr_defs: - html_impldef_table_row(f, nr, tags, tag_fname2url) - html_table_footer(f) - - -def html_impldef_cat_table(f, table_name: str, caption_prefix: str, - nr_defs: List[NormativeRuleDef], tags: NormativeTags, - tag_fname2url: Dict[str, str]): - """Write HTML table for implementation-defined behaviors by category.""" - if not isinstance(table_name, str): - fatal(f"Need String for table_name but passed a {type(table_name).__name__}") - if not isinstance(caption_prefix, str): - fatal(f"Need String for caption_prefix but passed a {type(caption_prefix).__name__}") - if not isinstance(nr_defs, list): - fatal(f"Need List for nr_defs but passed a {type(nr_defs).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but passed a {type(tags).__name__}") + if not isinstance(rules, list): + fatal(f"Need List for rules but passed a {type(rules).__name__}") if not isinstance(tag_fname2url, dict): fatal(f"Need Dict for tag_fname2url but passed a {type(tag_fname2url).__name__}") - html_table_header(f, table_name, f"{caption_prefix}: All {len(nr_defs)} Implementation-Defined Behaviors") - for nr in nr_defs: - html_impldef_cat_table_row(f, nr, tags, tag_fname2url) + html_table_header(f, table_name, f"Chapter {chapter_name}: {get_counts_str(rules)}") + for nr in rules: + html_norm_rule_table_row(f, nr, tag_fname2url) html_table_footer(f) @@ -964,206 +485,30 @@ def html_table_header(f, table_name: str, table_caption: str): f.write(' \n') f.write(' \n') f.write(' \n') - f.write(' NameInformationInformation Source\n') + f.write(' NameTextLocation\n') f.write(' \n') f.write(' \n') -def html_norm_rule_table_row(f, nr: NormativeRuleDef, tags: NormativeTags, - tag_fname2url: Dict[str, str]): +def html_norm_rule_table_row(f, nr: NormativeRule, tag_fname2url: Dict[str, str]): """Write HTML table row for normative rule.""" - if not isinstance(nr, NormativeRuleDef): - fatal(f"Need NormativeRuleDef for nr but passed a {type(nr).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but passed a {type(tags).__name__}") + if not isinstance(nr, NormativeRule): + fatal(f"Need NormativeRule for nr but passed a {type(nr).__name__}") if not isinstance(tag_fname2url, dict): fatal(f"Need Dict for tag_fname2url but passed a {type(tag_fname2url).__name__}") - name_is_anchor = True # Rule name is an anchor link in chapter tables - omit = {} # Don't omit anything + target_html_fname = tag_fname2url.get(nr.tag_filename) + if target_html_fname is None: + fatal(f"No fname tag to HTML mapping (-tag2url cmd line arg) for tag fname {nr.tag_filename} for tag name {nr.tag_name}") - html_table_row(f, nr, name_is_anchor, omit, tags, tag_fname2url) + tag_text = convert_tag_text_to_html(nr.text, target_html_fname) + tag_link = tag2html_link(nr.tag_name, nr.tag_name, target_html_fname) - -def html_impldef_table_row(f, nr: NormativeRuleDef, tags: NormativeTags, - tag_fname2url: Dict[str, str]): - """Write HTML table row for implementation-defined behavior.""" - if not isinstance(nr, NormativeRuleDef): - fatal(f"Need NormativeRuleDef for nr but passed a {type(nr).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but passed a {type(tags).__name__}") - if not isinstance(tag_fname2url, dict): - fatal(f"Need Dict for tag_fname2url but passed a {type(tag_fname2url).__name__}") - - name_is_anchor = False - omit = {"impldef": True} # Redundant - - html_table_row(f, nr, name_is_anchor, omit, tags, tag_fname2url) - - -def html_impldef_cat_table_row(f, nr: NormativeRuleDef, tags: NormativeTags, - tag_fname2url: Dict[str, str]): - """Write HTML table row for implementation-defined behavior by category.""" - if not isinstance(nr, NormativeRuleDef): - fatal(f"Need NormativeRuleDef for nr but passed a {type(nr).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but passed a {type(tags).__name__}") - if not isinstance(tag_fname2url, dict): - fatal(f"Need Dict for tag_fname2url but passed a {type(tag_fname2url).__name__}") - - name_is_anchor = False - omit = { - "impldef": True, # Redundant - "impldef_cat": True # Redundant - } - - html_table_row(f, nr, name_is_anchor, omit, tags, tag_fname2url) - - -def html_table_row(f, nr: NormativeRuleDef, name_is_anchor: bool, omit: Dict[str, bool], - tags: NormativeTags, tag_fname2url: Dict[str, str]): - """Write HTML table row.""" - if not isinstance(nr, NormativeRuleDef): - fatal(f"Need NormativeRuleDef for nr but passed a {type(nr).__name__}") - if not isinstance(name_is_anchor, bool): - fatal(f"Need Boolean for name_is_anchor but passed a {type(name_is_anchor).__name__}") - if not isinstance(omit, dict): - fatal(f"Need Dict for omit but passed a {type(omit).__name__}") - if not isinstance(tags, NormativeTags): - fatal(f"Need NormativeTags for tags but passed a {type(tags).__name__}") - if not isinstance(tag_fname2url, dict): - fatal(f"Need Dict for tag_fname2url but passed a {type(tag_fname2url).__name__}") - - omit_impldef = omit.get("impldef", False) - omit_impldef_cat = omit.get("impldef_cat", False) - - name_row_span = ( - (0 if nr.summary is None else 1) + - (0 if nr.note is None else 1) + - (0 if nr.clarification_link is None else 1) + - (0 if nr.description is None else 1) + - (0 if nr.kind is None else 1) + - (0 if not nr.instances else 1) + - (0 if omit_impldef or not nr.impldef else 1) + - (0 if omit_impldef_cat or nr.impldef_cat is None else 1) + - len(nr.tag_refs) - ) - - # Tracks if this is the first row for the normative rule. - first_row = True - - # Output the normative rule name cell with rowspan. f.write(' \n') - if name_is_anchor: - f.write(f' {nr.name}\n') - else: - f.write(f' {nr.name}\n') - - if nr.summary is not None: - text = convert_def_text_to_html(nr.summary) - - if not first_row: - f.write(' \n') - f.write(f' {text}\n') - f.write(' Summary\n') - f.write(' \n') - first_row = False - - if nr.note is not None: - text = convert_def_text_to_html(nr.note) - - if not first_row: - f.write(' \n') - f.write(f' {text}\n') - f.write(' Note\n') - f.write(' \n') - first_row = False - - if nr.description is not None: - text = convert_def_text_to_html(nr.description) - - if not first_row: - f.write(' \n') - f.write(f' {text}\n') - f.write(' Description\n') - f.write(' \n') - first_row = False - - if nr.kind is not None: - if not first_row: - f.write(' \n') - f.write(f' {nr.kind}\n') - f.write(' Kind\n') - f.write(' \n') - first_row = False - - if nr.instances: - if len(nr.instances) == 1: - instances_str = nr.instances[0] - rule_name = "Instance" - else: - instances_str = "[" + ', '.join(nr.instances) + "]" - rule_name = "Instances" - - if not first_row: - f.write(' \n') - f.write(f' {instances_str}\n') - f.write(f' {rule_name}\n') - f.write(' \n') - first_row = False - - if not omit_impldef and nr.impldef: - if not first_row: - f.write(' \n') - f.write(' Implementation-defined behavior\n') - f.write(' Implementation-defined behavior\n') - f.write(' \n') - first_row = False - - if not omit_impldef_cat and nr.impldef_cat is not None: - if not first_row: - f.write(' \n') - f.write(f' {nr.impldef_cat}\n') - f.write(' Implementation-defined behavior category\n') - f.write(' \n') - first_row = False - - for tag_ref in nr.tag_refs: - tag = tags.get_tag(tag_ref.name) - if tag is None: - fatal(f"Normative rule {nr.name} defined in file {nr.def_filename} references non-existent tag {tag_ref.name}") - assert tag is not None - - target_html_fname = tag_fname2url.get(tag.tag_filename) - if target_html_fname is None: - fatal(f"No fname tag to HTML mapping (-tag2url cmd line arg) for tag fname {tag.tag_filename} for tag name {tag.name}") - - tag_text = convert_tag_text_to_html(tag.text, target_html_fname, tag_ref.is_context()) - - tag_link = tag2html_link(tag_ref.name, tag_ref.name, target_html_fname) - - if not first_row: - f.write(' \n') - f.write(f' {tag_text}\n') - f.write(f' {tag_link}\n') - f.write(' \n') - first_row = False - - if nr.clarification_link is not None: - # The clarification text can only exist if the clarification link also exists. - if nr.clarification_text is None: - text = "(No clarification text available)" - else: - text = convert_def_text_to_html(nr.clarification_text) - - link = f'GitHub Issue' - - if not first_row: - f.write(' \n') - f.write(f' [CLARIFICATION] {text}\n') - f.write(f' {link}\n') - f.write(' \n') - first_row = False + f.write(f' {nr.name}\n') + f.write(f' {tag_text}\n') + f.write(f' {tag_link}\n') + f.write(' \n') def html_table_footer(f): @@ -1206,98 +551,37 @@ def html_script(f): f.write(script) -def get_impldefs_counts_str(nr_defs: List[NormativeRuleDef]) -> str: - """Get string describing implementation-defined counts.""" - if not isinstance(nr_defs, list): - fatal(f"Need List for nr_defs but passed a {type(nr_defs).__name__}") - - num_rules = len(nr_defs) - counts_str = f"{num_rules} Normative Rule{'s' if num_rules != 1 else ''}" - - num_impldefs = count_impldefs(nr_defs) - if num_impldefs > 0: - counts_str += f": Includes {num_impldefs} Implementation-Defined Behavior{'s' if num_impldefs != 1 else ''}" - - num_impldefs_no_cat = num_impldefs # Start with total and subtract out categorized counts - - any_impldef_cats = False - num_impldef_cats = {} - for cat in IMPLDEF_CATEGORIES: - num_impldef_cats[cat] = count_impldef_cats(nr_defs, cat) - if num_impldef_cats[cat] > 0: - any_impldef_cats = True - num_impldefs_no_cat -= num_impldef_cats[cat] - - if any_impldef_cats: - counts_str += " (" - - cats_str = [f"{num_impldefs_no_cat} No Category"] - for cat in IMPLDEF_CATEGORIES: - if num_impldef_cats[cat] > 0: - cats_str.append(f"{num_impldef_cats[cat]} {cat}") - - counts_str += ", ".join(cats_str) - counts_str += ")" - - return counts_str - - -def count_impldefs(nrs: List[NormativeRuleDef]) -> int: - """Count implementation-defined behaviors.""" - if not isinstance(nrs, list): - raise TypeError(f"Need List[NormativeRuleDef] for nrs but passed a {type(nrs).__name__}") - - count = 0 - for nr in nrs: - if nr.impldef: - count += 1 - - return count - - -def count_impldef_cats(nrs: List[NormativeRuleDef], impldef_cat: str) -> int: - """Count implementation-defined behaviors by category.""" - if not isinstance(nrs, list): - raise TypeError(f"Need List[NormativeRuleDef] for nrs but passed a {type(nrs).__name__}") - if not isinstance(impldef_cat, str): - raise TypeError(f"Need String for impldef_cat but passed a {type(impldef_cat).__name__}") - count = 0 - for nr in nrs: - if nr.impldef_cat == impldef_cat: - count += 1 +def get_counts_str(rules: List[NormativeRule]) -> str: + """Get string describing the number of normative rules.""" + if not isinstance(rules, list): + fatal(f"Need List for rules but passed a {type(rules).__name__}") - return count + num_rules = len(rules) + return f"{num_rules} Normative Rule{'s' if num_rules != 1 else ''}" def main(): """Main function.""" info(f"Passed command-line: {' '.join(sys.argv[1:])}") - def_fnames, tag_fnames, tag_fname2url, output_fname, output_format, warn_if_tags_no_rules = parse_argv() + tag_fnames, tag_fname2url, output_fname, output_format = parse_argv() - info(f"Normative rule definition filenames = {def_fnames}") info(f"Normative tag filenames = {tag_fnames}") for tag_fname, url in tag_fname2url.items(): info(f"Normative tag file {tag_fname} links to URL {url}") info(f"Output filename = {output_fname}") info(f"Output format = {output_format}") - defs = load_definitions(def_fnames) - tags = load_tags(tag_fnames) - validate_defs_and_tags(defs, tags, warn_if_tags_no_rules) + rules = load_rules(tag_fnames) - info(f"Storing {len(defs.norm_rule_defs)} normative rules into file {output_fname}") - info(f"Includes {count_impldefs(defs.norm_rule_defs)} implementation-defined behavior normative rules") - for cat in IMPLDEF_CATEGORIES: - count = count_impldef_cats(defs.norm_rule_defs, cat) - info(f"Includes {count} {cat} normative rule{'s' if count != 1 else ''}") + info(f"Storing {len(rules)} normative rules into file {output_fname}") if output_format == "json": - normative_rules_hash = create_normative_rules_hash(defs, tags, tag_fname2url) + normative_rules_hash = create_normative_rules_hash(rules, tag_fname2url) output_json(output_fname, normative_rules_hash) elif output_format == "html": - output_html(output_fname, defs, tags, tag_fname2url) + output_html(output_fname, rules, tag_fname2url) else: raise ValueError(f"Unknown output_format of {output_format}") diff --git a/tools/create_param_tables.py b/tools/create_param_tables.py deleted file mode 100644 index bbc8745..0000000 --- a/tools/create_param_tables.py +++ /dev/null @@ -1,510 +0,0 @@ -#!/usr/bin/env python3 -""" -create_param_tables.py - -Generates AsciiDoc table-row fragment files and include files for parameters and/or CSRs from a params JSON file. - -Usage: - python3 tools/create_param_tables.py --input [--param-table ] [--csr-table ] --output-dir - -- If --param-table is given, generates parameter appendix files (like create_param_appendix.py) -- If --csr-table is given, generates CSR appendix files (like create_csr_appendix.py) -- If both are given, generates both under separate subdirectories in the output directory - -Input JSON must conform to schemas/params-schema.json. -""" - -import argparse -import sys -from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple - -from appendix_shared_utils import ( - infer_normative_rules, - render_table_cols_spec, - render_table_header_row, - safe_filename, -) -from shared_utils import ( - IMPLDEF_CATEGORIES, - NORM_RULES_BASE_URL, - check_impldef_cat, - check_kind, - format_param_feature, - infer_param_type_string, - load_json_object, - load_yaml_object, - make_log_helpers, -) - -PN = "create_param_tables.py" - -PARAM_ALLOWED_TABLE_COLUMNS = { - "PARAM_NAME_AND_NORM_RULE_MAPPING", - "TYPE", - "FEATURES", - "DEFINITION", -} -CSR_ALLOWED_TABLE_COLUMNS = { - "NAME", - "TYPE", - "FEATURES", - "IMPLEMENTATION_DEFINED_BEHAVIORS", -} - -error, info, fatal = make_log_helpers(PN) - -def parse_args(): - parser = argparse.ArgumentParser( - description="Generate AsciiDoc appendix files for parameters and/or CSRs from params JSON." - ) - parser.add_argument("-i", "--input", required=True, metavar="FILE", help="Input params JSON file (conforms to schemas/params-schema.json)") - parser.add_argument("-o", "--output-dir", required=True, metavar="DIR", help="Directory where .adoc files will be written") - parser.add_argument("--param-table", metavar="FILE", help="Input YAML parameter table layout file (schemas/param-table-schema.json)") - parser.add_argument("--csr-table", metavar="FILE", help="Input YAML CSR table layout file (schemas/csr-table-schema.json)") - return parser.parse_args() - -def load_params_json(pathname: str) -> Dict[str, Any]: - data = load_json_object(pathname, fatal) - return data - -def load_param_table_yaml(pathname: str) -> List[Dict[str, Any]]: - data = load_yaml_object(pathname, fatal) - columns_obj = data.get("columns") - if not isinstance(columns_obj, list) or not columns_obj: - fatal(f"Expected non-empty columns array in {pathname}") - for idx, col in enumerate(columns_obj): - column = col.get("column") - if column not in PARAM_ALLOWED_TABLE_COLUMNS: - allowed = ", ".join(sorted(PARAM_ALLOWED_TABLE_COLUMNS)) - fatal(f"Don't recognize columns[{idx}].column {column!r}; allowed values are: {allowed}") - return columns_obj - -def load_csr_table_yaml(pathname: str) -> List[Dict[str, Any]]: - data = load_yaml_object(pathname, fatal) - columns_obj = data.get("columns") - if not isinstance(columns_obj, list) or not columns_obj: - fatal(f"Expected non-empty columns array in {pathname}") - for idx, col in enumerate(columns_obj): - column = col.get("column") - if column not in CSR_ALLOWED_TABLE_COLUMNS: - allowed = ", ".join(sorted(CSR_ALLOWED_TABLE_COLUMNS)) - fatal(f"Don't recognize columns[{idx}].column {column!r}; allowed values are: {allowed}") - return columns_obj - -def has_block_content(text: str) -> bool: - if "!===" in text: - return True - return "\n\n" in text - -def normalize_inline_text(text: str) -> str: - import re - return re.sub(r"\s+", " ", text.strip()) - -def render_definition_cell(param: Dict[str, Any]) -> str: - note = param.get("note") - description = param.get("description") - parts = [] - if isinstance(note, str) and note.strip(): - parts.append(f"NOTE: {note.strip()}") - if isinstance(description, str) and description.strip(): - parts.append(description.strip()) - if not parts: - return "| See normative rule" - text = "\n\n".join(parts) - if has_block_content(text): - return "a| " + text - return "| " + normalize_inline_text(text) - -def render_param_name_and_norm_rule_mapping_cell(name: str, norm_rules: List[str]) -> str: - lines = ["a|", f"[#param:{name}]#{name}#", "", "Normative Rule(s):", ""] - if norm_rules: - for rule_name in norm_rules: - lines.append(f"* {NORM_RULES_BASE_URL}#{rule_name}[{rule_name}]") - else: - lines.append("* (none)") - return "\n".join(lines) - -def format_param_count_label(count: int) -> str: - noun = "Parameter" if count == 1 else "Parameters" - return f"{count} {noun}" - -def render_parameter_row_fragment(param: Dict[str, Any], columns: List[Dict[str, Any]]) -> str: - name = param["name"] - type_str = infer_param_type_string(param, fatal) - feature = format_param_feature(param) - norm_rules = infer_normative_rules(param) - lines = [] - for col in columns: - col_id = col["column"] - if col_id == "PARAM_NAME_AND_NORM_RULE_MAPPING": - lines.append(render_param_name_and_norm_rule_mapping_cell(name, norm_rules)) - elif col_id == "TYPE": - lines.append(f"| {type_str}") - elif col_id == "FEATURES": - lines.append(f"| {feature}") - elif col_id == "DEFINITION": - lines.append(render_definition_cell(param)) - else: - fatal(f"Internal error: unsupported column identifier {col_id!r}") - return "\n".join(lines) + "\n" - -def write_param_output_files(params: List[Dict[str, Any]], output_dir: Path, columns: List[Dict[str, Any]]): - output_dir.mkdir(parents=True, exist_ok=True) - table_cols = render_table_cols_spec(columns) - table_header = render_table_header_row(columns) - chapter_files = {} - chapter_names = {} - seen_names = set() - for param in params: - name = param["name"] - file_stem = safe_filename(name) - if file_stem in seen_names: - fatal(f"Duplicate output filename stem {file_stem!r}; parameter names must be unique after filename sanitization") - seen_names.add(file_stem) - def_filename = param.get("def_filename", "") - if not isinstance(def_filename, str) or not def_filename: - fatal(f"Expected non-empty def_filename for parameter {name!r}") - def_dir_name = Path(def_filename).stem - if not def_dir_name: - fatal(f"def_filename {def_filename!r} for parameter {name!r} has no usable stem for a chapter subdirectory name") - chapter_dir = output_dir / def_dir_name - param_dir = chapter_dir / "params" - param_dir.mkdir(parents=True, exist_ok=True) - chapter_name = param.get("chapter_name") - if not isinstance(chapter_name, str) or not chapter_name.strip(): - fatal(f"Expected non-empty chapter_name for parameter {name!r}") - if chapter_dir in chapter_names and chapter_names[chapter_dir] != chapter_name: - fatal(f"Conflicting chapter_name values for def_filename {def_filename!r}: {chapter_names[chapter_dir]!r} vs {chapter_name!r}") - chapter_names[chapter_dir] = chapter_name - out_path = param_dir / f"{file_stem}.adoc" - content = render_parameter_row_fragment(param, columns) - with open(out_path, "w", encoding="utf-8") as f: - f.write(content) - chapter_files.setdefault(chapter_dir, []).append(f"{file_stem}.adoc") - for chapter_dir, filenames in chapter_files.items(): - include_lines = "\n".join(f"include::{fname}[]" for fname in filenames) - chapter_include_path = chapter_dir / "params" / "all_params.adoc" - with open(chapter_include_path, "w", encoding="utf-8") as f: - f.write(include_lines + "\n") - all_param_entries = [ - (file_stem, chapter_dir) - for chapter_dir, filenames in chapter_files.items() - for file_stem in (Path(f).stem for f in filenames) - ] - return { - "table_cols": table_cols, - "table_header": table_header, - "chapter_files": chapter_files, - "chapter_names": chapter_names, - "chapter_order": list(chapter_files.keys()), - "all_entries": all_param_entries, - } - -def csr_display_name(csr: Dict[str, Any]) -> str: - reg_name = csr["reg-name"] - field_name = csr.get("field-name") - if isinstance(field_name, str) and field_name: - return f"{reg_name}.{field_name}" - return reg_name - -def format_csr_count_label(count: int) -> str: - noun = "CSR" if count == 1 else "CSRs" - return f"{count} {noun}" - -def render_name_cell(csr: Dict[str, Any]) -> str: - return f"| {csr_display_name(csr)}" - -def render_type_cell(csr: Dict[str, Any]) -> str: - csr_type = csr.get("type") - type_display = csr_type if isinstance(csr_type, str) and csr_type else "Other" - if type_display == "VarWidth": - width_parameter = csr.get("width-parameter") - if isinstance(width_parameter, str) and width_parameter: - type_display = f"VarWidth = {width_parameter}" - func_of_reg_name = csr.get("func-of-reg-name") - func_of_field_name = csr.get("func-of-field-name") - if (isinstance(func_of_reg_name, str) and func_of_reg_name) or (isinstance(func_of_field_name, str) and func_of_field_name): - base_reg_name = "" - if isinstance(func_of_reg_name, str) and func_of_reg_name: - base_reg_name = func_of_reg_name - elif isinstance(func_of_field_name, str) and func_of_field_name: - reg_name = csr.get("reg-name") - if isinstance(reg_name, str) and reg_name: - base_reg_name = reg_name - func_of_target = base_reg_name - if isinstance(func_of_field_name, str) and func_of_field_name: - if func_of_target: - func_of_target = f"{func_of_target}.{func_of_field_name}" - else: - func_of_target = func_of_field_name - return f"a| {type_display} +\nfunc-of: {func_of_target}" - return f"| {type_display}" - -def render_features_cell(csr: Dict[str, Any]) -> str: - return f"| {format_param_feature(csr)}" - -def render_impl_defined_behavior_cell(csr: Dict[str, Any]) -> str: - lines = ["a|"] - norm_rules = infer_normative_rules(csr) - if norm_rules: - for rule_name in norm_rules: - lines.append(f"* {NORM_RULES_BASE_URL}#{rule_name}[{rule_name}]") - else: - lines.append("* (none)") - note = csr.get("note") - if isinstance(note, str) and note.strip(): - lines.append("") - lines.append(f"NOTE: {note.strip()}") - description = csr.get("description") - if isinstance(description, str) and description.strip(): - lines.append("") - lines.append(description.strip()) - return "\n".join(lines) - -def render_csr_row_fragment(csr: Dict[str, Any], columns: List[Dict[str, Any]]) -> str: - lines = [] - for col in columns: - col_id = col["column"] - if col_id == "NAME": - lines.append(render_name_cell(csr)) - elif col_id == "TYPE": - lines.append(render_type_cell(csr)) - elif col_id == "FEATURES": - lines.append(render_features_cell(csr)) - elif col_id == "IMPLEMENTATION_DEFINED_BEHAVIORS": - lines.append(render_impl_defined_behavior_cell(csr)) - else: - fatal(f"Internal error: unsupported column identifier {col_id!r}") - return "\n".join(lines) + "\n" - -def write_csr_output_files(csrs: List[Dict[str, Any]], output_dir: Path, columns: List[Dict[str, Any]]): - output_dir.mkdir(parents=True, exist_ok=True) - table_cols = render_table_cols_spec(columns) - table_header = render_table_header_row(columns) - chapter_files = {} - chapter_names = {} - seen_names = set() - for csr in csrs: - name = csr_display_name(csr) - file_stem = safe_filename(name) - if file_stem in seen_names: - fatal(f"Duplicate output filename stem {file_stem!r}; CSR names must be unique after filename sanitization") - seen_names.add(file_stem) - def_filename = csr.get("def_filename", "") - if not isinstance(def_filename, str) or not def_filename: - fatal(f"Expected non-empty def_filename for CSR {name!r}") - def_dir_name = Path(def_filename).stem - if not def_dir_name: - fatal(f"def_filename {def_filename!r} for CSR {name!r} has no usable stem for a chapter subdirectory name") - chapter_dir = output_dir / def_dir_name - csr_dir = chapter_dir / "csrs" - csr_dir.mkdir(parents=True, exist_ok=True) - chapter_name_value = csr.get("chapter_name") - if not isinstance(chapter_name_value, str) or not chapter_name_value.strip(): - fatal(f"Expected non-empty chapter_name for CSR {name!r}") - chapter_name = str(chapter_name_value) - if chapter_dir in chapter_names and chapter_names[chapter_dir] != chapter_name: - fatal(f"Conflicting chapter_name values for def_filename {def_filename!r}: {chapter_names[chapter_dir]!r} vs {chapter_name!r}") - chapter_names[chapter_dir] = chapter_name - out_path = csr_dir / f"{file_stem}.adoc" - content = render_csr_row_fragment(csr, columns) - with open(out_path, "w", encoding="utf-8") as f: - f.write(content) - chapter_files.setdefault(chapter_dir, []).append(f"{file_stem}.adoc") - category_value = csr.get("category") - if not isinstance(category_value, str) or not category_value: - fatal(f"Expected non-empty category for CSR {name!r}") - category = category_value - if category not in IMPLDEF_CATEGORIES: - allowed_str = ", ".join(IMPLDEF_CATEGORIES) - fatal(f"Unrecognized category {category!r} for CSR {name!r}; allowed values are: {allowed_str}") - # Keep category validation for input quality checks, but top-level outputs list all CSRs. - for chapter_dir, filenames in chapter_files.items(): - include_lines = "\n".join(f"include::{fname}[]" for fname in filenames) - chapter_include_path = chapter_dir / "csrs" / "all_csrs.adoc" - with open(chapter_include_path, "w", encoding="utf-8") as f: - f.write(include_lines + "\n") - all_csr_entries = [ - (file_stem, chapter_dir) - for chapter_dir, filenames in chapter_files.items() - for file_stem in (Path(f).stem for f in filenames) - ] - return { - "table_cols": table_cols, - "table_header": table_header, - "chapter_files": chapter_files, - "chapter_names": chapter_names, - "chapter_order": list(chapter_files.keys()), - "all_entries": all_csr_entries, - } - -def write_combined_top_level_files( - output_dir: Path, - param_summary: Optional[Dict[str, Any]], - csr_summary: Optional[Dict[str, Any]], -): - output_dir.mkdir(parents=True, exist_ok=True) - - chapter_order: List[Path] = [] - if param_summary is not None: - chapter_order.extend(param_summary["chapter_order"]) - if csr_summary is not None: - for chapter_dir in csr_summary["chapter_order"]: - if chapter_dir not in chapter_order: - chapter_order.append(chapter_dir) - - # Write per-chapter combined files as standalone tables for params then csrs. - for chapter_dir in chapter_order: - combined_lines: List[str] = [] - if param_summary is not None: - param_stems = sorted(Path(fname).stem for fname in param_summary["chapter_files"].get(chapter_dir, [])) - if param_stems: - combined_lines.append(f".Parameter Definitions (A-Z): {format_param_count_label(len(param_stems))}") - combined_lines.append(f"[cols=\"{param_summary['table_cols']}\"]") - combined_lines.append("|===") - combined_lines.append("") - combined_lines.append(param_summary["table_header"]) - combined_lines.append("") - for stem in param_stems: - combined_lines.append(f"include::params/{stem}.adoc[]") - combined_lines.append("") - combined_lines.append("|===") - combined_lines.append("") - if csr_summary is not None: - csr_stems = sorted(Path(fname).stem for fname in csr_summary["chapter_files"].get(chapter_dir, [])) - if csr_stems: - combined_lines.append(f".WARL/WLRL CSR Definitions (A-Z): {format_csr_count_label(len(csr_stems))}") - combined_lines.append(f"[cols=\"{csr_summary['table_cols']}\"]") - combined_lines.append("|===") - combined_lines.append("") - combined_lines.append(csr_summary["table_header"]) - combined_lines.append("") - for stem in csr_stems: - combined_lines.append(f"include::csrs/{stem}.adoc[]") - combined_lines.append("") - combined_lines.append("|===") - combined_lines.append("") - combined_path = chapter_dir / "all_params.adoc" - with open(combined_path, "w", encoding="utf-8") as f: - if combined_lines: - f.write("\n".join(combined_lines).rstrip() + "\n") - else: - f.write("") - - a_to_z_lines: List[str] = [] - if param_summary is not None: - all_param_entries = [ - (Path(fname).stem, chapter_dir) - for chapter_dir in chapter_order - for fname in param_summary["chapter_files"].get(chapter_dir, []) - ] - a_to_z_lines.append(f".Parameter Definitions (A-Z): {format_param_count_label(len(all_param_entries))}") - a_to_z_lines.append(f"[cols=\"{param_summary['table_cols']}\"]") - a_to_z_lines.append("|===") - a_to_z_lines.append("") - a_to_z_lines.append(param_summary["table_header"]) - a_to_z_lines.append("") - for stem, chapter_dir in sorted(all_param_entries, key=lambda e: e[0]): - a_to_z_lines.append(f"include::{chapter_dir.name}/params/{stem}.adoc[]") - a_to_z_lines.append("") - a_to_z_lines.append("|===") - a_to_z_lines.append("") - - if csr_summary is not None: - all_csr_entries = [ - (Path(fname).stem, chapter_dir) - for chapter_dir in chapter_order - for fname in csr_summary["chapter_files"].get(chapter_dir, []) - ] - a_to_z_lines.append(f".WARL/WLRL CSR Definitions (A-Z): {format_csr_count_label(len(all_csr_entries))}") - a_to_z_lines.append(f"[cols=\"{csr_summary['table_cols']}\"]") - a_to_z_lines.append("|===") - a_to_z_lines.append("") - a_to_z_lines.append(csr_summary["table_header"]) - a_to_z_lines.append("") - for stem, chapter_dir in sorted(all_csr_entries, key=lambda e: e[0]): - a_to_z_lines.append(f"include::{chapter_dir.name}/csrs/{stem}.adoc[]") - a_to_z_lines.append("") - a_to_z_lines.append("|===") - a_to_z_lines.append("") - a_to_z_path = output_dir / "all_params_a_to_z.adoc" - with open(a_to_z_path, "w", encoding="utf-8") as f: - f.write("\n".join(a_to_z_lines).rstrip() + "\n") - - chapter_lines: List[str] = [] - for chapter_dir in chapter_order: - chapter_name = None - if param_summary is not None: - chapter_name = param_summary["chapter_names"].get(chapter_dir) - if chapter_name is None and csr_summary is not None: - chapter_name = csr_summary["chapter_names"].get(chapter_dir) - if chapter_name is None: - continue - chapter_lines.append(f"=== {chapter_name}") - chapter_lines.append("") - - if param_summary is not None: - param_filenames = param_summary["chapter_files"].get(chapter_dir, []) - if param_filenames: - chapter_count = len(param_filenames) - chapter_lines.append(f".Chapter {chapter_name} Parameter Definitions: {format_param_count_label(chapter_count)}") - chapter_lines.append(f"[cols=\"{param_summary['table_cols']}\"]") - chapter_lines.append("|===") - chapter_lines.append("") - chapter_lines.append(param_summary["table_header"]) - chapter_lines.append("") - chapter_lines.append(f"include::{chapter_dir.name}/params/all_params.adoc[]") - chapter_lines.append("") - chapter_lines.append("|===") - chapter_lines.append("") - - if csr_summary is not None: - csr_filenames = csr_summary["chapter_files"].get(chapter_dir, []) - if csr_filenames: - csr_count = len(csr_filenames) - chapter_lines.append(f".Chapter {chapter_name} WARL/WLRL CSR Definitions: {format_csr_count_label(csr_count)}") - chapter_lines.append(f"[cols=\"{csr_summary['table_cols']}\"]") - chapter_lines.append("|===") - chapter_lines.append("") - chapter_lines.append(csr_summary["table_header"]) - chapter_lines.append("") - chapter_lines.append(f"include::{chapter_dir.name}/csrs/all_csrs.adoc[]") - chapter_lines.append("") - chapter_lines.append("|===") - chapter_lines.append("") - - by_chapter_path = output_dir / "all_params_by_chapter.adoc" - with open(by_chapter_path, "w", encoding="utf-8") as f: - f.write("\n".join(chapter_lines).rstrip() + "\n") - -def main() -> int: - args = parse_args() - data = load_params_json(args.input) - out_dir = Path(args.output_dir) - did_any = False - param_summary: Optional[Dict[str, Any]] = None - csr_summary: Optional[Dict[str, Any]] = None - if args.param_table: - if "parameters" not in data or not isinstance(data["parameters"], list): - fatal("Input JSON does not contain a 'parameters' array.") - columns = load_param_table_yaml(args.param_table) - params = data["parameters"] - info(f"Writing {len(params)} parameter AsciiDoc files under chapter params/ subdirectories in {out_dir}") - param_summary = write_param_output_files(params, out_dir, columns) - did_any = True - if args.csr_table: - if "csrs" not in data or not isinstance(data["csrs"], list): - fatal("Input JSON does not contain a 'csrs' array.") - columns = load_csr_table_yaml(args.csr_table) - csrs = data["csrs"] - info(f"Writing {len(csrs)} CSR AsciiDoc files under chapter csrs/ subdirectories in {out_dir}") - csr_summary = write_csr_output_files(csrs, out_dir, columns) - did_any = True - if not did_any: - fatal("Must specify at least one of --param-table or --csr-table.") - write_combined_top_level_files(out_dir, param_summary, csr_summary) - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/create_params.py b/tools/create_params.py deleted file mode 100644 index c8c3071..0000000 --- a/tools/create_params.py +++ /dev/null @@ -1,1409 +0,0 @@ -#!/usr/bin/env python3 -"""Create params JSON from normative rules JSON and parameter definition YAML files.""" - -import argparse -import json -import re -import sys -from pathlib import Path -from typing import Any, Dict, List, Optional, Set, Tuple - -from def_text_to_html import ( - convert_def_text_to_html, - tag2html_link, -) -from shared_utils import ( - IMPLDEF_CATEGORIES, - STDS_OBJECT_KINDS, - check_impldef_cat, - check_kind, - format_param_feature, - impldef_category_to_csr_category, - infer_param_type_string, - load_json_object, - load_yaml_object, - make_log_helpers, -) -from tag_text_to_html import convert_tag_text_to_html - -PN = "create_params.py" -PARAMS_CH_TABLE_NAME_PREFIX = "table-params-ch-" -PARAMS_NO_CH_TABLE_NAME = "table-params-no-ch" -CSRS_CH_TABLE_NAME_PREFIX = "table-csrs-ch-" -CSRS_NO_CH_TABLE_NAME = "table-csrs-no-ch" -CSR_TYPES: Set[str] = {"LegalEnum", "VarWidth", "ConstMask", "Other"} - -error, info, fatal = make_log_helpers(PN) - - -def csr_table_name_for_chapter_category(table_num: int, category: str) -> str: - """Build CSR table id for one chapter/category bucket.""" - return f"{CSRS_CH_TABLE_NAME_PREFIX}{table_num}-{category.lower()}" - - -def csr_table_name_for_no_chapter_category(category: str) -> str: - """Build CSR table id for no-chapter/category bucket.""" - return f"{CSRS_NO_CH_TABLE_NAME}-{category.lower()}" - - -def count_label(count: int, singular: str, plural: str) -> str: - """Return a correctly pluralized count label.""" - return f"{count} {singular if count == 1 else plural}" - - -def parse_args() -> argparse.Namespace: - """Parse command-line arguments.""" - parser = argparse.ArgumentParser( - description=( - "Create params output from one normative rules JSON file and one or more " - "parameter definition YAML files." - ) - ) - parser.add_argument( - "-j", - action="store_const", - const="json", - dest="output_format", - default="json", - help="Set output format to JSON (default)", - ) - parser.add_argument( - "--html", - action="store_const", - const="html", - dest="output_format", - help="Set output format to HTML", - ) - parser.add_argument( - "-n", - "--norm-rules", - required=True, - metavar="FILE", - help="Normative rules JSON filename (conforms to schemas/norm-rules-schema.json)", - ) - parser.add_argument( - "-d", - "--param-def", - action="append", - required=True, - metavar="FILE", - help="Parameter definition YAML filename (conforms to schemas/param-defs-schema.json). " - "Specify one or more times.", - ) - parser.add_argument( - "-o", - "--output", - required=True, - metavar="FILE", - help="Output filename (JSON conforms to schemas/params-schema.json)", - ) - return parser.parse_args() - - -def load_json_file(pathname: str) -> Dict[str, Any]: - """Load a JSON file as a dict.""" - return load_json_object(pathname, fatal) - - -def load_yaml_file(pathname: str) -> Dict[str, Any]: - """Load a YAML file as a dict.""" - return load_yaml_object(pathname, fatal) - - - - - -def normalize_impldef_refs( - entry: Dict[str, Any], - src_filename: str, - item_name: str, - item_kind: str, -) -> List[str]: - """Return impl-def references from one definition entry as a normalized array.""" - has_impldef = "impl-def" in entry - has_impldefs = "impl-defs" in entry - - if has_impldef and has_impldefs: - fatal(f"{item_kind} {item_name} in {src_filename} cannot define both impl-def and impl-defs") - - refs: List[str] = [] - if has_impldef: - impl_def: Any = entry.get("impl-def") - if not isinstance(impl_def, str): - fatal(f"{item_kind} {item_name} in {src_filename} has non-string impl-def") - refs = [impl_def] - elif has_impldefs: - impl_defs: Any = entry.get("impl-defs") - if not isinstance(impl_defs, list): - fatal(f"{item_kind} {item_name} in {src_filename} has non-list impl-defs. Use \"impl-def\" instead.") - if not impl_defs: - fatal(f"{item_kind} {item_name} in {src_filename} has empty impl-defs") - for impl_def in impl_defs: - if not isinstance(impl_def, str): - fatal(f"{item_kind} {item_name} in {src_filename} has non-string value in impl-defs") - refs = list(impl_defs) - - return refs - - -def rules_by_name(norm_rules_data: Dict[str, Any], src_filename: str) -> Dict[str, Dict[str, Any]]: - """Create lookup map from normative rule name to its JSON object.""" - rules_obj: Any = norm_rules_data.get("normative_rules") - if not isinstance(rules_obj, list) or not rules_obj: - fatal(f"Missing, invalid, or empty normative_rules array in {src_filename}") - rules: List[Any] = rules_obj - - by_name: Dict[str, Dict[str, Any]] = {} - for rule in rules: - if not isinstance(rule, dict): - fatal(f"Found non-object entry in normative_rules array in {src_filename}") - - name: Any = rule.get("name") - if not isinstance(name, str): - fatal(f"Found normative rule without string name in {src_filename}") - - if name in by_name: - fatal(f"Duplicate normative rule name {name} in {src_filename}") - - by_name[name] = rule - - return by_name - - -def resolve_impldef_entries( - impl_defs: List[str], - norm_rules_by_name: Dict[str, Dict[str, Any]], - norm_rules_filename: str, - src_filename: str, - item_name: str, - item_kind: str, -) -> List[Dict[str, Any]]: - """Resolve impl-def names to normativeRuleEntry objects.""" - resolved: List[Dict[str, Any]] = [] - for impl_def in impl_defs: - norm_rule_opt = norm_rules_by_name.get(impl_def) - if norm_rule_opt is None: - fatal( - f"{item_kind} {item_name} in {src_filename} references impl-def {impl_def} " - f"which is not present in normative rules {norm_rules_filename}" - ) - assert norm_rule_opt is not None - resolved_entry = dict(norm_rule_opt) - - kind = resolved_entry.get("kind") - if kind is not None: - if not isinstance(kind, str): - fatal( - f"{item_kind} {item_name} in {src_filename} references impl-def {impl_def} " - f"with non-string kind ({type(kind).__name__}) " - f"in normative rules {norm_rules_filename}" - ) - if kind not in STDS_OBJECT_KINDS: - allowed_kinds = ",".join(STDS_OBJECT_KINDS) - fatal( - f"{item_kind} {item_name} in {src_filename} references impl-def {impl_def} " - f"with invalid kind {kind!r} in normative rules {norm_rules_filename}. " - f"Allowed kinds are: {allowed_kinds}" - ) - check_kind(kind, impl_def, None, fatal, PN) - - impldef_cat = resolved_entry.get("impl-def-category") - if impldef_cat is not None: - if not isinstance(impldef_cat, str): - fatal( - f"{item_kind} {item_name} in {src_filename} references impl-def {impl_def} " - f"with non-string impl-def-category ({type(impldef_cat).__name__}) " - f"in normative rules {norm_rules_filename}" - ) - if impldef_cat not in IMPLDEF_CATEGORIES: - allowed_cats = ",".join(IMPLDEF_CATEGORIES) - fatal( - f"{item_kind} {item_name} in {src_filename} references impl-def {impl_def} " - f"with invalid impl-def-category {impldef_cat!r} in normative rules " - f"{norm_rules_filename}. Allowed impl-def-categories are: {allowed_cats}" - ) - check_impldef_cat(impldef_cat, impl_def, None, fatal, PN) - - resolved.append(resolved_entry) - return resolved - - -def param_type_to_json_schema( - param_type: Any, - param_range: Any, - param_array: Any, - param_width: Any, - def_filename: str, - name: str, -) -> Dict[str, Any]: - """Convert a type/range plus optional array bounds to a JSON Schema object.""" - item_schema: Dict[str, Any] = {} - if param_range is not None: - item_schema = {"type": "integer", "minimum": param_range[0], "maximum": param_range[1]} - elif isinstance(param_type, list): - all_int = all(isinstance(v, int) for v in param_type) - all_str = all(isinstance(v, str) for v in param_type) - if all_int: - item_schema = {"type": "integer", "enum": list(param_type)} - elif all_str: - item_schema = {"type": "string", "enum": list(param_type)} - else: - item_schema = {"enum": list(param_type)} - else: - # Type matching is case-sensitive; only canonical lowercase tokens are accepted. - if param_type == "boolean": - item_schema = {"type": "boolean"} - elif param_type == "bit": - item_schema = {"type": "integer", "minimum": 0, "maximum": 1} - elif param_type == "byte": - item_schema = {"type": "integer", "minimum": 0, "maximum": 255} - elif param_type == "hword": - item_schema = {"type": "integer", "minimum": 0, "maximum": 65535} - elif param_type == "word": - item_schema = {"type": "integer", "minimum": 0, "maximum": 4294967295} - elif param_type == "dword": - item_schema = {"type": "integer", "minimum": 0, "maximum": 18446744073709551615} - elif param_type in {"int", "uint"}: - if isinstance(param_width, int) and not isinstance(param_width, bool): - n = param_width - if n < 2 or n > 64: - signedness = "signed" if param_type == "int" else "unsigned" - fatal( - f"Parameter {name} in {def_filename} has invalid {signedness} width {n} " - f"for type {param_type!r} (expected 2–64 bits)" - ) - if param_type == "uint": - item_schema = {"type": "integer", "minimum": 0, "maximum": (1 << n) - 1} - else: - item_schema = { - "type": "integer", - "minimum": -(1 << (n - 1)), - "maximum": (1 << (n - 1)) - 1, - } - elif isinstance(param_width, str): - if param_type == "uint": - item_schema = {"type": "integer", "minimum": 0} - else: - item_schema = {"type": "integer"} - else: - fatal( - f"Parameter {name} in {def_filename} has type {param_type!r} " - "but no usable width" - ) - else: - fatal(f"Parameter {name} in {def_filename} has unrecognized type {param_type!r}") - return {} # unreachable - - if param_array is None: - return item_schema - - array_len = param_array[1] - param_array[0] + 1 - return { - "type": "array", - "items": item_schema, - "minItems": array_len, - "maxItems": array_len, - } - - -def add_parameter_entries( - parameters: List[Dict[str, Any]], - entry: Dict[str, Any], - def_filename: str, - chapter_name: str, - norm_rules_by_name: Dict[str, Dict[str, Any]], - norm_rules_filename: str, -): - """Expand one parameter definition entry into one or more output parameter objects.""" - names: List[str] = [] - - if "name" in entry: - name: Any = entry.get("name") - if not isinstance(name, str): - fatal(f"Found parameter entry with non-string name in {def_filename}") - names = [name] - elif "names" in entry: - names_value: Any = entry.get("names") - if not isinstance(names_value, list): - fatal(f"Found parameter entry with non-list names in {def_filename} (Use \"name\" instead.)") - if not names_value: - fatal(f"Found parameter entry with empty names in {def_filename}") - for name in names_value: - if not isinstance(name, str): - fatal(f"Found non-string value in names array in {def_filename}") - names = list(names_value) - else: - fatal( - f"Parameter definition in {def_filename} must define either 'name' or 'names'" - ) - - if len(names) == 1: - param_ref = f"Parameter {names[0]}" - else: - joined_names = ", ".join(names) - param_ref = f"Parameter entry with names [{joined_names}]" - - has_type = "type" in entry - has_range = "range" in entry - has_array = "array" in entry - if has_type == has_range: - fatal(f"{param_ref} in {def_filename} must define exactly one of type or range") - - param_type: Any = entry.get("type") - param_range: Any = entry.get("range") - param_array: Any = entry.get("array") - param_width: Any = entry.get("width") - if has_type: - if isinstance(param_type, str): - pass - elif isinstance(param_type, list): - if not param_type: - fatal(f"{param_ref} in {def_filename} has empty type array") - for value in param_type: - if not isinstance(value, (str, int)): - fatal( - f"{param_ref} in {def_filename} has invalid type array value " - f"{value!r}; expected string or integer" - ) - else: - fatal(f"{param_ref} in {def_filename} has invalid type; expected string or array") - - if has_range: - if not isinstance(param_range, list) or len(param_range) != 2: - fatal(f"{param_ref} in {def_filename} has invalid range; expected array of 2 integers") - if not isinstance(param_range[0], int) or not isinstance(param_range[1], int): - fatal(f"{param_ref} in {def_filename} has invalid range; values must be integers") - if param_range[0] >= param_range[1]: - fatal(f"{param_ref} in {def_filename} has invalid range; first value must be less than second") - - if has_array: - if not isinstance(param_array, list) or len(param_array) != 2: - fatal(f"{param_ref} in {def_filename} has invalid array; expected array of 2 integers") - if not isinstance(param_array[0], int) or not isinstance(param_array[1], int): - fatal(f"{param_ref} in {def_filename} has invalid array; values must be integers") - if param_array[0] < 0 or param_array[1] < 0: - fatal(f"{param_ref} in {def_filename} has invalid array; values must be non-negative") - if param_array[0] > param_array[1]: - fatal(f"{param_ref} in {def_filename} has invalid array; first value must be less than or equal to second") - - if param_width is not None: - if isinstance(param_width, int): - if param_width < 2 or param_width > 64: - fatal( - f"{param_ref} in {def_filename} has invalid width; " - "integer values must be in [2, 64]" - ) - elif not isinstance(param_width, str): - fatal( - f"{param_ref} in {def_filename} has invalid width; " - "expected integer in [2, 64] or parameter name" - ) - - if has_type and isinstance(param_type, str): - if param_type in {"int", "uint"}: - if param_width is None: - fatal( - f"{param_ref} in {def_filename} with type {param_type!r} " - "must define width" - ) - elif param_width is not None: - fatal( - f"{param_ref} in {def_filename} has width but type {param_type!r}; " - "width is allowed only with type 'int' or 'uint'" - ) - elif param_width is not None: - fatal( - f"{param_ref} in {def_filename} has width but no type 'int' or 'uint'; " - "width is allowed only with type 'int' or 'uint'" - ) - - has_impldef = "impl-def" in entry - has_impldefs = "impl-defs" in entry - if not has_impldef and not has_impldefs and "description" not in entry: - fatal( - f"{param_ref} in {def_filename} without impl-def/impl-defs " - "must define description" - ) - - - for name in names: - impl_defs = normalize_impldef_refs(entry, def_filename, name, "Parameter") - - # Enforce long-name is present and is a string - if "long-name" not in entry: - fatal(f"Parameter {name} in {def_filename} is missing required 'long-name' property") - long_name_val = entry["long-name"] - if not isinstance(long_name_val, str): - fatal(f"Parameter {name} in {def_filename} has non-string long-name") - - # Enforce chapter_name is present and is a string - if not isinstance(chapter_name, str) or not chapter_name: - fatal(f"Parameter {name} in {def_filename} is missing or has invalid 'chapter_name' property") - - - out_entry: Dict[str, Any] = { - "name": name, - "def_filename": Path(def_filename).name, - "chapter_name": chapter_name, - "long-name": long_name_val, - } - - if has_type: - out_entry["type"] = param_type - if has_range: - out_entry["range"] = list(param_range) - if has_array: - out_entry["array"] = list(param_array) - if param_width is not None: - out_entry["width"] = param_width - - out_entry["json-schema"] = param_type_to_json_schema( - param_type, param_range, param_array, param_width, def_filename, name - ) - - note = entry.get("note") - if note is not None: - if not isinstance(note, str): - fatal(f"Parameter {name} in {def_filename} has non-string note") - out_entry["note"] = note - - description = entry.get("description") - if description is not None: - if not isinstance(description, str): - fatal(f"Parameter {name} in {def_filename} has non-string description") - out_entry["description"] = description - - if impl_defs: - out_entry["impl-defs"] = resolve_impldef_entries( - impl_defs, - norm_rules_by_name, - norm_rules_filename, - def_filename, - name, - "Parameter", - ) - - parameters.append(out_entry) - - -def add_csr_entries( - csrs: List[Dict[str, Any]], - entry: Dict[str, Any], - def_filename: str, - chapter_name: str, - norm_rules_by_name: Dict[str, Dict[str, Any]], - norm_rules_filename: str, -): - """Expand one CSR definition entry into one or more output CSR objects.""" - raw_csr_type = entry.get("type") - raw_parameter_name = entry.get("width-parameter") - raw_func_of_reg_name = entry.get("func-of-reg-name") - raw_func_of_field_name = entry.get("func-of-field-name") - - if not isinstance(raw_csr_type, str): - fatal(f"Found CSR entry with missing or non-string type in {def_filename}") - if raw_csr_type not in CSR_TYPES: - allowed_types = ", ".join(sorted(CSR_TYPES)) - fatal( - f"Found CSR entry with invalid type {raw_csr_type!r} in {def_filename}. " - f"Allowed types are: {allowed_types}" - ) - csr_type = raw_csr_type - - parameter_name: Optional[str] = None - if raw_parameter_name is not None: - if not isinstance(raw_parameter_name, str): - fatal(f"Found CSR entry with non-string width-parameter in {def_filename}") - parameter_name = raw_parameter_name - - func_of_reg_name: Optional[str] = None - if raw_func_of_reg_name is not None: - if not isinstance(raw_func_of_reg_name, str): - fatal(f"Found CSR entry with non-string func-of-reg-name in {def_filename}") - func_of_reg_name = raw_func_of_reg_name - - func_of_field_name: Optional[str] = None - if raw_func_of_field_name is not None: - if not isinstance(raw_func_of_field_name, str): - fatal(f"Found CSR entry with non-string func-of-field-name in {def_filename}") - func_of_field_name = raw_func_of_field_name - - if csr_type == "VarWidth": - if parameter_name is None: - fatal( - f"Found CSR entry in {def_filename} with type 'VarWidth' but no width-parameter property" - ) - elif parameter_name is not None: - fatal( - f"Found CSR entry in {def_filename} with type {csr_type!r} that also defines 'width-parameter'" - ) - - names: List[str] = [] - if "reg-name" in entry: - name: Any = entry.get("reg-name") - if not isinstance(name, str): - fatal(f"Found CSR entry with non-string reg-name in {def_filename}") - names = [name] - elif "reg-names" in entry: - names_value: Any = entry.get("reg-names") - if not isinstance(names_value, list): - if isinstance(names_value, str): - fatal( - f"Found CSR entry with non-list reg-names in {def_filename}; " - f"received single name {names_value!r}. Use reg-name: {names_value!r} instead" - ) - fatal(f"Found CSR entry with non-list reg-names in {def_filename}") - if not names_value: - fatal(f"Found CSR entry with empty reg-names in {def_filename}") - for name in names_value: - if not isinstance(name, str): - fatal(f"Found non-string value in CSR reg-names array in {def_filename}") - names = list(names_value) - else: - fatal(f"Found CSR entry without reg-name/reg-names in {def_filename}") - - representative_name = names[0] - - # Resolve impl-defs at entry level (shared across all names in this entry). - impl_def_refs = normalize_impldef_refs(entry, def_filename, representative_name, "CSR") - if not impl_def_refs: - fatal( - f"CSR {representative_name} in {def_filename} has no impl-def(s)" - ) - resolved_impl_defs = resolve_impldef_entries( - impl_def_refs, - norm_rules_by_name, - norm_rules_filename, - def_filename, - representative_name, - "CSR", - ) - - # Derive CSR category from impl-def-category. - # At least one referenced impl-def must provide a category, and all provided - # categories must agree. - impldef_categories: List[str] = [] - for resolved in resolved_impl_defs: - cat = resolved.get("impl-def-category") - if cat is None: - continue - if not isinstance(cat, str): - fatal( - f"CSR {representative_name} in {def_filename} references impl-def " - f"'{resolved.get('name')}' with non-string impl-def-category " - f"({type(cat).__name__}) in normative rules {norm_rules_filename}" - ) - impldef_categories.append(cat) - - if not impldef_categories: - impldef_names = ", ".join(f"'{r.get('name')}'" for r in resolved_impl_defs) - fatal( - f"CSR {representative_name} in {def_filename} has impl-defs with no " - f"impl-def-category in normative rules {norm_rules_filename}: {impldef_names}" - ) - - if len(set(impldef_categories)) > 1: - details = ", ".join( - f"'{r.get('name')}': {r.get('impl-def-category')!r}" - for r in resolved_impl_defs - if r.get("impl-def-category") is not None - ) - fatal( - f"CSR {representative_name} in {def_filename} has impl-defs with " - f"conflicting impl-def-category values in normative rules {norm_rules_filename}: " - f"{details}" - ) - - csr_category: str = impldef_category_to_csr_category(impldef_categories[0], fatal) - - # Parse field-names list up front so it can be included in any error messages below. - if "field-name" in entry: - field_name_val: Any = entry.get("field-name") - if not isinstance(field_name_val, str): - fatal(f"CSR {representative_name} in {def_filename} has non-string field-name") - field_names_list: List[str] = [field_name_val] - elif "field-names" in entry: - field_names_val: Any = entry.get("field-names") - if not isinstance(field_names_val, list) or not field_names_val: - fatal(f"CSR {representative_name} in {def_filename} has invalid or empty field-names") - for fn in field_names_val: - if not isinstance(fn, str): - fatal(f"Found non-string value in CSR field-names array in {def_filename}") - field_names_list = list(field_names_val) - else: - field_names_list = [] - - for name in names: - def csr_id(field_name: Optional[str] = None) -> str: - if field_name is not None: - return f"CSR {name} field {field_name}" - return f"CSR {name}" - - out_entry: Dict[str, Any] = { - "reg-name": name, - "def_filename": Path(def_filename).name, - "chapter_name": chapter_name, - "category": csr_category, - "type": csr_type, - } - - if parameter_name is not None: - out_entry["width-parameter"] = parameter_name - effective_func_of_reg_name = func_of_reg_name - if effective_func_of_reg_name is None and func_of_field_name is not None: - effective_func_of_reg_name = name - if effective_func_of_reg_name is not None: - out_entry["func-of-reg-name"] = effective_func_of_reg_name - if func_of_field_name is not None: - out_entry["func-of-field-name"] = func_of_field_name - - note = entry.get("note") - if note is not None: - if not isinstance(note, str): - field_ctx = field_names_list[0] if len(field_names_list) == 1 else None - fatal(f"{csr_id(field_ctx)} in {def_filename} has non-string note") - out_entry["note"] = note - - description = entry.get("description") - if description is not None: - if not isinstance(description, str): - field_ctx = field_names_list[0] if len(field_names_list) == 1 else None - fatal(f"{csr_id(field_ctx)} in {def_filename} has non-string description") - out_entry["description"] = description - - if field_names_list: - for field_name in field_names_list: - # Build field_entry with field-name immediately after reg-name. - field_entry: Dict[str, Any] = {"reg-name": out_entry["reg-name"], "field-name": field_name} - for k, v in out_entry.items(): - if k != "reg-name": - field_entry[k] = v - field_entry["impl-defs"] = resolved_impl_defs - csrs.append(field_entry) - else: - out_entry["impl-defs"] = resolved_impl_defs - csrs.append(out_entry) - - -def create_params_hash(norm_rules_json: str, param_def_yaml_files: List[str]) -> Dict[str, List[Dict[str, Any]]]: - """Build params object that conforms to schemas/params-schema.json.""" - info(f"Loading normative rules JSON {norm_rules_json}") - norm_rules_data = load_json_file(norm_rules_json) - norm_rules_map = rules_by_name(norm_rules_data, norm_rules_json) - - parameters: List[Dict[str, Any]] = [] - csrs: List[Dict[str, Any]] = [] - saw_parameter_definitions = False - saw_csr_definitions = False - - for def_file in param_def_yaml_files: - info(f"Loading parameter definition file {def_file}") - yaml_data = load_yaml_file(def_file) - chapter_name_obj: Any = yaml_data.get("chapter_name") - if not isinstance(chapter_name_obj, str): - fatal(f"Missing or invalid chapter_name in {def_file}") - chapter_name = chapter_name_obj - - parameter_definitions_obj: Any = yaml_data.get("parameter_definitions") - if parameter_definitions_obj is not None: - if not isinstance(parameter_definitions_obj, list) or not parameter_definitions_obj: - fatal(f"Invalid or empty parameter_definitions array in {def_file}") - saw_parameter_definitions = True - parameter_definitions: List[Any] = parameter_definitions_obj - for entry in parameter_definitions: - if not isinstance(entry, dict): - fatal(f"Found non-object entry in parameter_definitions in {def_file}") - add_parameter_entries( - parameters, - entry, - def_file, - chapter_name, - norm_rules_map, - norm_rules_json, - ) - - csr_definitions_obj: Any = yaml_data.get("csr_definitions") - if csr_definitions_obj is not None: - if not isinstance(csr_definitions_obj, list) or not csr_definitions_obj: - fatal(f"Invalid or empty csr_definitions array in {def_file}") - saw_csr_definitions = True - csr_definitions: List[Any] = csr_definitions_obj - for idx, entry in enumerate(csr_definitions): - if not isinstance(entry, dict): - fatal(f"Found non-object entry in csr_definitions in {def_file}") - add_csr_entries( - csrs, - entry, - def_file, - chapter_name, - norm_rules_map, - norm_rules_json, - ) - - if parameter_definitions_obj is None and csr_definitions_obj is None: - fatal(f"Missing parameter_definitions and csr_definitions arrays in {def_file}") - - # Validate that string-valued width fields reference an existing parameter name. - param_name_set = {p["name"] for p in parameters if isinstance(p.get("name"), str)} - for p in parameters: - width = p.get("width") - if isinstance(width, str) and width not in param_name_set: - fatal( - f"Parameter {p['name']} in {p['def_filename']} has string width {width!r} " - "which is not the name of a known parameter" - ) - - for c in csrs: - parameter_name = c.get("width-parameter") - if isinstance(parameter_name, str) and parameter_name not in param_name_set: - csr_name = c.get("reg-name", "") - field_name = c.get("field-name") - if isinstance(field_name, str) and field_name: - csr_name = f"{csr_name}.{field_name}" - fatal( - f"CSR {csr_name} in {c['def_filename']} has width-parameter {parameter_name!r} " - "which is not the name of a known parameter" - ) - - output: Dict[str, List[Dict[str, Any]]] = {} - if parameters: - output["parameters"] = parameters - if csrs: - output["csrs"] = csrs - return output - - -def write_json_file(pathname: str, data: Dict[str, Any]): - """Write output dict to JSON file.""" - try: - with open(pathname, "w", encoding="utf-8") as f: - json.dump(data, f, indent=2, ensure_ascii=False) - f.write("\n") - except Exception as e: - fatal(f"Error writing output file {pathname}: {e}") - - -def strip_internal_fields(obj: Any) -> Any: - """Recursively remove internal keys (prefixed with underscore).""" - if isinstance(obj, dict): - out: Dict[str, Any] = {} - for key, value in obj.items(): - if isinstance(key, str) and key.startswith("_"): - continue - out[key] = strip_internal_fields(value) - return out - if isinstance(obj, list): - return [strip_internal_fields(x) for x in obj] - return obj - - -def output_json(filename: str, params_hash: Dict[str, List[Dict[str, Any]]]): - """Store parameters in JSON output file.""" - if not isinstance(filename, str): - fatal(f"Need String for filename but passed a {type(filename).__name__}") - if not isinstance(params_hash, dict): - fatal(f"Need Dict for params_hash but passed a {type(params_hash).__name__}") - - clean_hash = strip_internal_fields(params_hash) - if not isinstance(clean_hash, dict): - fatal(f"Need Dict for clean_hash but got {type(clean_hash).__name__}") - write_json_file(filename, clean_hash) - - -def output_html(filename: str, params_hash: Dict[str, List[Dict[str, Any]]]): - """Store parameters in HTML output file.""" - if not isinstance(filename, str): - fatal(f"Need String for filename but passed a {type(filename).__name__}") - if not isinstance(params_hash, dict): - fatal(f"Need Dict for params_hash but passed a {type(params_hash).__name__}") - - params_obj: Any = params_hash.get("parameters") - if params_obj is not None and not isinstance(params_obj, list): - fatal("Invalid parameters array") - params: List[Dict[str, Any]] = params_obj if isinstance(params_obj, list) else [] - - csrs_obj: Any = params_hash.get("csrs") - if csrs_obj is not None and not isinstance(csrs_obj, list): - fatal("Invalid csrs array") - csrs: List[Dict[str, Any]] = csrs_obj if isinstance(csrs_obj, list) else [] - - if not params and not csrs: - fatal("Missing parameters/csrs arrays") - - chapter_names, params_by_chapter, params_no_chapter = params_by_chapter_name(params) - csr_chapter_names, csrs_by_chapter, csrs_no_chapter = params_by_chapter_name(csrs) - - table_names: List[str] = [] - table_num = 1 - for _ in chapter_names: - table_names.append(f"{PARAMS_CH_TABLE_NAME_PREFIX}{table_num}") - table_num += 1 - if params_no_chapter: - table_names.append(PARAMS_NO_CH_TABLE_NAME) - - csr_table_num = 1 - for chapter_name in csr_chapter_names: - chapter_csrs = csrs_by_chapter[chapter_name] - for category in IMPLDEF_CATEGORIES: - category_csrs = [c for c in chapter_csrs if c.get("category") == category] - if category_csrs: - table_names.append(csr_table_name_for_chapter_category(csr_table_num, category)) - csr_table_num += 1 - if csrs_no_chapter: - for category in IMPLDEF_CATEGORIES: - category_csrs = [c for c in csrs_no_chapter if c.get("category") == category] - if category_csrs: - table_names.append(csr_table_name_for_no_chapter_category(category)) - - try: - with open(filename, "w", encoding="utf-8") as f: - html_head(f) - f.write('\n') - f.write('
\n') - - if params: - html_sidebar(f, chapter_names, params_by_chapter, params_no_chapter) - if csrs: - html_sidebar_csrs(f, csr_chapter_names, csrs_by_chapter, csrs_no_chapter) - else: - f.write(' \n') - else: - f.write('
\n') - html_script(f) - f.write('\n') - f.write('\n') - except Exception as e: - fatal(f"Error writing HTML to {filename}: {e}") - - - -def html_head(f): - """Write HTML head section.""" - - css = ''' - - - - - Parameters - - -''' - f.write(css) - - -def html_sidebar( - f, - chapter_names: List[str], - params_by_chapter: Dict[str, List[Dict[str, Any]]], - params_no_chapter: List[Dict[str, Any]], -): - """Write sidebar section.""" - if not isinstance(chapter_names, list): - fatal(f"Need List for chapter_names but passed a {type(chapter_names).__name__}") - if not isinstance(params_by_chapter, dict): - fatal(f"Need Dict for params_by_chapter but passed a {type(params_by_chapter).__name__}") - if not isinstance(params_no_chapter, list): - fatal(f"Need List for params_no_chapter but passed a {type(params_no_chapter).__name__}") - - f.write(' \n') - - -def html_params_table( - f, - table_name: str, - caption_prefix: str, - params: List[Dict[str, Any]], - chapter_name: Optional[str], -): - """Write full parameters table.""" - html_table_header( - f, - table_name, - f"{caption_prefix}: {count_label(len(params), 'Parameter', 'Parameters')}", - ) - for param in params: - html_param_table_row(f, param, chapter_name) - html_table_footer(f) - - -def html_csrs_table( - f, - table_name: str, - caption_prefix: str, - csrs: List[Dict[str, Any]], - chapter_name: Optional[str], -): - """Write full CSR table.""" - html_table_header( - f, - table_name, - f"{caption_prefix}: {count_label(len(csrs), 'CSR', 'CSRs')}", - "CSR Name", - ) - for csr in csrs: - html_param_table_row(f, csr, chapter_name) - html_table_footer(f) - - -def html_table_header(f, table_name: str, table_caption: str, name_header: str = "Parameter Name"): - """Write HTML table header.""" - f.write('\n') - f.write(f'
\n') - f.write(' \n') - f.write(f' \n') - f.write(' \n') - f.write(' \n') - f.write(' \n') - f.write(' \n') - f.write(' \n') - f.write(' \n') - f.write(' \n') - f.write( - f' ' - '\n' - ) - f.write(' \n') - f.write(' \n') - - -def html_build_descriptions(entry: Dict[str, Any], impl_defs: List[Any]) -> List[str]: - """Build note/description/tag text blocks for one table row.""" - descriptions: List[str] = [] - note = entry.get("note") - description = entry.get("description") - - if isinstance(note, str): - descriptions.append("NOTE: " + convert_def_text_to_html(note)) - if isinstance(description, str): - descriptions.append("DESC: " + convert_def_text_to_html(description)) - - for impl_def in impl_defs: - if not isinstance(impl_def, dict): - continue - tags = impl_def.get("tags") - if not isinstance(tags, list): - continue - for tag in tags: - if not isinstance(tag, dict): - continue - tag_text = tag.get("text") - tag_name = tag.get("name") - target_html_fname = tag.get("stds_doc_url") - is_context = bool(tag.get("context", False)) - if not isinstance(tag_text, str): - continue - if not isinstance(tag_name, str): - fatal( - f"Invalid or missing tag name in normative rules JSON: {tag!r}" - ) - assert isinstance(tag_name, str) - html = convert_tag_text_to_html(tag_text, target_html_fname, is_context) - if re.search(r"\n') - f.write(f' \n') - f.write(f' \n') - f.write(f' \n') - f.write(f' \n') - f.write(' \n') - - for desc in descriptions[1:]: - f.write(' \n') - f.write(f' \n') - f.write(' \n') - - -def html_parameter_table_row(f, param: Dict[str, Any], chapter_name: Optional[str]): - """Write one row for an entry conforming to parameter_definitions.""" - name_obj = param.get("name") - name = name_obj if isinstance(name_obj, str) else "" - - impl_defs_all = param.get("impl-defs") - impl_defs = filter_impldefs_for_chapter(impl_defs_all, chapter_name) - - type_display = infer_param_type_string( - param, - fatal, - ) - - feature_param = dict(param) - if isinstance(impl_defs_all, list): - feature_param["impl-defs"] = impl_defs - if chapter_name is not None: - feature_param["chapter_name"] = chapter_name - feature_str = format_param_feature(feature_param) - - descriptions = html_build_descriptions(param, impl_defs) - html_write_table_row(f, name, type_display, feature_str, descriptions) - - -def html_csr_table_row(f, csr: Dict[str, Any], chapter_name: Optional[str]): - """Write one row for an entry conforming to csr_definitions.""" - reg_name = csr.get("reg-name") - field_name = csr.get("field-name") - if isinstance(reg_name, str) and reg_name: - if isinstance(field_name, str) and field_name: - name = f"{reg_name}.{field_name}" - else: - name = reg_name - else: - fatal("CSR entry missing reg-name") - return - - impl_defs_all = csr.get("impl-defs") - impl_defs = filter_impldefs_for_chapter(impl_defs_all, chapter_name) - - csr_type = csr.get("type") - type_display = csr_type if isinstance(csr_type, str) and csr_type else "Other" - - # For VarWidth types, append the width-parameter value - if type_display == "VarWidth": - width_param = csr.get("width-parameter") - if isinstance(width_param, str) and width_param: - type_display = f"VarWidth = {width_param}" - - func_of_reg_name = csr.get("func-of-reg-name") - func_of_field_name = csr.get("func-of-field-name") - if ( - isinstance(func_of_reg_name, str) - and func_of_reg_name - ) or ( - isinstance(func_of_field_name, str) - and func_of_field_name - ): - base_reg_name: str = "" - if isinstance(func_of_reg_name, str) and func_of_reg_name: - base_reg_name = func_of_reg_name - elif isinstance(func_of_field_name, str) and func_of_field_name: - if isinstance(reg_name, str) and reg_name: - base_reg_name = reg_name - - func_of_target = base_reg_name - if isinstance(func_of_field_name, str) and func_of_field_name: - if func_of_target: - func_of_target = f"{func_of_target}.{func_of_field_name}" - else: - func_of_target = func_of_field_name - type_display = f"{type_display}
func-of: {func_of_target}" - - feature_csr = dict(csr) - if isinstance(impl_defs_all, list): - feature_csr["impl-defs"] = impl_defs - if chapter_name is not None: - feature_csr["chapter_name"] = chapter_name - feature_str = format_param_feature(feature_csr) - - descriptions = html_build_descriptions(csr, impl_defs) - html_write_table_row(f, name, type_display, feature_str, descriptions) - - -def html_param_table_row(f, param: Dict[str, Any], chapter_name: Optional[str]): - """Write one table row, dispatching to parameter or CSR renderer.""" - reg_name = param.get("reg-name") - if isinstance(reg_name, str) and reg_name: - html_csr_table_row(f, param, chapter_name) - else: - html_parameter_table_row(f, param, chapter_name) - - -def html_table_footer(f): - """Write HTML table footer.""" - f.write(' \n') - f.write('
{table_caption}
{name_header}TypeFeature(s)Information (mostly Normative Rules)
{name}{type_display}{feature_str}{descriptions[0]}
{desc}
\n') - f.write('
\n') - - -def param_chapter_names(param: Dict[str, Any]) -> List[str]: - """Return sorted unique chapter names referenced by a parameter's impl-defs.""" - chapter_name = param.get("chapter_name") - if isinstance(chapter_name, str): - return [chapter_name] - - impl_defs = param.get("impl-defs") - if not isinstance(impl_defs, list): - return [] - - names: List[str] = [] - seen = set() - for impl_def in impl_defs: - if not isinstance(impl_def, dict): - continue - name = impl_def.get("chapter_name") - if isinstance(name, str) and name not in seen: - seen.add(name) - names.append(name) - names.sort() - return names - - -def params_by_chapter_name( - params: List[Dict[str, Any]], -) -> Tuple[List[str], Dict[str, List[Dict[str, Any]]], List[Dict[str, Any]]]: - """Group parameters by chapter_name values.""" - by_chapter: Dict[str, List[Dict[str, Any]]] = {} - without_chapter: List[Dict[str, Any]] = [] - - for param in params: - chapters = param_chapter_names(param) - if not chapters: - without_chapter.append(param) - continue - for chapter in chapters: - if chapter not in by_chapter: - by_chapter[chapter] = [] - by_chapter[chapter].append(param) - - chapter_names = sorted(by_chapter.keys()) - return chapter_names, by_chapter, without_chapter - - -def filter_impldefs_for_chapter(impl_defs: Any, chapter_name: Optional[str]) -> List[Any]: - """Filter impl-def objects for the specified chapter, preserving input order.""" - if not isinstance(impl_defs, list): - return [] - if chapter_name is None: - return list(impl_defs) - - filtered: List[Any] = [] - for impl_def in impl_defs: - if not isinstance(impl_def, dict): - continue - impl_chapter = impl_def.get("chapter_name") - if impl_chapter == chapter_name: - filtered.append(impl_def) - return filtered - - -def html_script(f): - """Write HTML script section.""" - script = ''' -''' - f.write(script) - - -def get_params_counts_str(params: List[Dict[str, Any]], csrs: List[Dict[str, Any]]) -> str: - """Build heading summary string for params output.""" - parts: List[str] = [] - if params: - total_params = len(params) - parts.append(count_label(total_params, "Parameter", "Parameters")) - if csrs: - total_csrs = len(csrs) - parts.append(count_label(total_csrs, "WARL/WLRL CSR", "WARL/WLRL CSRs")) - if not parts: - return count_label(0, "Entry", "Entries") - return ", ".join(parts) - - -def main() -> int: - """Program entry point.""" - args = parse_args() - params = create_params_hash(args.norm_rules, args.param_def) - info(f"Writing output file {args.output}") - if args.output_format == "json": - output_json(args.output, params) - elif args.output_format == "html": - output_html(args.output, params) - else: - fatal(f"Unknown output format {args.output_format}") - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/default_csr_table.yaml b/tools/default_csr_table.yaml deleted file mode 100644 index 49c88c2..0000000 --- a/tools/default_csr_table.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -$schema: schemas/csr-table-schema.json -columns: - - name: Name - column: NAME - width_pct: 20 - - name: Type - column: TYPE - width_pct: 20 - - name: Feature(s) - column: FEATURES - width_pct: 15 - - name: Implementation-defined Behavior(s) - column: IMPLEMENTATION_DEFINED_BEHAVIORS - width_pct: 45 diff --git a/tools/default_param_table.yaml b/tools/default_param_table.yaml deleted file mode 100644 index 3785225..0000000 --- a/tools/default_param_table.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -$schema: schemas/param-table-schema.json -columns: - - name: Parameter and Mapping to Normative Rules - column: PARAM_NAME_AND_NORM_RULE_MAPPING - width_pct: 30 - - name: Type - column: TYPE - width_pct: 10 - - name: Feature(s) - column: FEATURES - width_pct: 10 - - name: Definition - column: DEFINITION - width_pct: 50 diff --git a/tools/export_params_to_udb.py b/tools/export_params_to_udb.py deleted file mode 100644 index dd36e91..0000000 --- a/tools/export_params_to_udb.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python3 -""" -Script to convert a params.json file (conforming to schemas/params-schema.json) -into individual YAML files for each parameter (conforming to schemas/udb_param_schema.json). - -Usage: - python tools/export_params_to_udb.py -i params.json -o outdir - python tools/export_params_to_udb.py --input params.json --output-dir outdir - -Arguments: - -i, --input Path to params.json input file (required) - -o, --output-dir Directory to write YAML files (required) - -h, --help Show this help message and exit - -Each output YAML file will be named .yaml (upper-case). -""" -import argparse -import os -from pathlib import Path -import sys -import yaml - -# Allow import from parent directory if run as a script or from test -try: - from tools.shared_utils import make_log_helpers, load_json_object -except ModuleNotFoundError: - sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '.'))) - from shared_utils import make_log_helpers, load_json_object - -def main(): - parser = argparse.ArgumentParser( - description="Convert params.json to UDB YAML files. Each output YAML file will be named .yaml (upper-case)." - ) - parser.add_argument('-i', '--input', required=True, metavar='FILE', help='Path to params.json input file') - parser.add_argument('-o', '--output-dir', required=True, metavar='DIR', help='Directory to write YAML files') - args = parser.parse_args() - - error, info, fatal = make_log_helpers("export_params_to_udb.py") - - # Load input JSON - params_data = load_json_object(args.input, fatal) - parameters = params_data.get('parameters') - if not isinstance(parameters, list): - fatal("Input JSON does not contain a 'parameters' array.") - - # Prepare output directory - outdir = Path(args.output_dir) - outdir.mkdir(parents=True, exist_ok=True) - - for param in parameters: - name = param.get('name') - if not name: - fatal("Parameter missing 'name'") - if 'long-name' not in param: - fatal(f"Parameter '{name}' missing 'long-name'") - out_name = f"{name.upper()}.yaml" - out_path = outdir / out_name - - # Compose description: combine description and note if both exist - desc = param.get('description', '') - note = param.get('note', '') - if desc and note: - description = f"{desc}\nNOTE: {note}" - elif desc: - description = desc - elif note: - description = f"NOTE: {note}" - else: - description = '' - - # Build definedBy property from extension impl-defs and their instances - defined_by = None - impl_defs = param.get('impl-defs', []) - extension_names = [] - for impldef in impl_defs: - kind = impldef.get('kind') - if kind == 'extension': - instances = impldef.get('instances') - if isinstance(instances, list): - for ext_name in instances: - if isinstance(ext_name, str): - extension_names.append(ext_name) - elif kind == 'base': - # Treat 'base' as an extension named 'I' - extension_names.append('I') - if not extension_names: - extension_names = ['I'] - if len(extension_names) == 1: - defined_by = {"extension": {"name": extension_names[0]}} - else: - defined_by = {"extension": {"anyOf": [{"name": n} for n in extension_names]}} - - # Map input to output schema - out_obj = { - "$schema": "param_schema.json#", - "kind": "parameter", - "name": name, - "long_name": param['long-name'], - "description": description, - "schema": param.get('json-schema', {}), - } - if defined_by is not None: - out_obj["definedBy"] = defined_by - # Optionally add $source if available - if 'def_filename' in param: - out_obj["$source"] = param['def_filename'] - # Optionally add requirements if present - if 'requirements' in param: - out_obj['requirements'] = param['requirements'] - - with open(out_path, 'w', encoding='utf-8') as f: - f.write('---\n') - yaml.safe_dump(out_obj, f, sort_keys=False, allow_unicode=True) - info(f"Wrote {out_path}") - -if __name__ == "__main__": - main() diff --git a/tools/params_json_to_udb_yaml.py b/tools/params_json_to_udb_yaml.py deleted file mode 100644 index e69de29..0000000 diff --git a/tools/shared_utils.py b/tools/shared_utils.py index 664bf3e..f267043 100644 --- a/tools/shared_utils.py +++ b/tools/shared_utils.py @@ -1,73 +1,17 @@ -"""Shared tables and helpers for tools scripts. +"""Shared helpers for tools scripts. -This module contains reusable constants and routines consumed by +This module contains reusable routines consumed by multiple Python scripts in the tools directory. """ import sys import traceback -from importlib import import_module from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple +from typing import Any, Callable, Dict, Tuple import json -STDS_OBJECT_KINDS: List[str] = [ - "base", - "extension", - "extension_dependency", - "instruction", - "csr", - "csr_field", -] - - -IMPLDEF_CATEGORIES: List[str] = ["WARL", "WLRL"] - -# Explicit mapping from impl-def-category values (implDefCategoryType in common-schema.json) -# to output CSR category values (csrCategory in param-common-schema.json). -# These use separate schema definitions so they cannot be assumed identical. -IMPLDEF_CATEGORY_TO_CSR_CATEGORY: Dict[str, str] = { - "WARL": "WARL", - "WLRL": "WLRL", -} - - -def impldef_category_to_csr_category( - impldef_cat: str, - fatal: Callable[[str], None], -) -> str: - """Convert an impl-def-category value to its output CSR category. - - Uses an explicit mapping so that changes to either schema are caught - at the mapping site rather than silently passed through. - """ - result = IMPLDEF_CATEGORY_TO_CSR_CATEGORY.get(impldef_cat) - if result is None: - allowed_str = ",".join(IMPLDEF_CATEGORY_TO_CSR_CATEGORY) - fatal( - f"No CSR category mapping for impl-def-category {impldef_cat!r}. " - f"Allowed impl-def-categories are: {allowed_str}" - ) - return "" # unreachable; fatal() does not return - return result - - -STDS_OBJECT_KIND_TO_FEATURE: Dict[str, str] = { - "base": "BASE", - "extension": "EXT", - "csr": "CSR", - "csr_field": "FLD", - "extension_dependency": "EXT_DEP", - "instruction": "INST", -} - - -NORM_RULES_BASE_URL = ( - "https://riscv.github.io/riscv-isa-manual/snapshot/norm-rules/norm-rules.html" -) - PN = "shared_utils.py" @@ -115,267 +59,3 @@ def load_json_object(pathname: str, fatal: Callable[[str], None]) -> Dict[str, A fatal(f"Expected top-level JSON object in {pathname}") return data - - -def load_yaml_object(pathname: str, fatal: Callable[[str], None]) -> Dict[str, Any]: - """Load and validate a top-level YAML object from a file.""" - yaml_module: Any = None - try: - yaml_module = import_module("yaml") - except ImportError: - fatal("PyYAML is required but not installed. Run: pip install PyYAML") - - path = Path(pathname) - data: Any = None - try: - with open(path, "r", encoding="utf-8") as f: - data = yaml_module.safe_load(f) - except FileNotFoundError as e: - fatal(str(e)) - except yaml_module.YAMLError as e: - fatal(f"YAML parse error in {pathname}: {e}") - except Exception as e: - fatal(f"Error reading YAML file {pathname}: {e}") - - if not isinstance(data, dict): - fatal(f"Expected top-level YAML object in {pathname}") - - return data - - -def format_param_feature( - param: Dict[str, Any], -) -> str: - """Render a parameter feature string from chapter name and impl-defs.""" - impl_defs = param.get("impl-defs") - if not isinstance(impl_defs, list): - chapter_name = param.get("chapter_name") - if isinstance(chapter_name, str) and chapter_name: - return f"CHAP:{chapter_name}" - return "(unspecified)" - - features: List[str] = [] - seen = set() - warned_unknown_kinds = set() - for impl_def in impl_defs: - if not isinstance(impl_def, dict): - continue - kind = impl_def.get("kind") - prefix = None - if isinstance(kind, str): - prefix = STDS_OBJECT_KIND_TO_FEATURE.get(kind) - if prefix is None and kind not in warned_unknown_kinds: - warned_unknown_kinds.add(kind) - error( - "Unknown standards object kind " - f"{kind!r}; expected one of {', '.join(STDS_OBJECT_KINDS)}" - ) - elif kind is not None: - kind_type = type(kind).__name__ - marker = f"type:{kind_type}" - if marker not in warned_unknown_kinds: - warned_unknown_kinds.add(marker) - error( - "Unknown standards object kind type " - f"{kind_type!r}; expected string kind values" - ) - instances = impl_def.get("instances") - if not isinstance(instances, list): - continue - for instance in instances: - if not isinstance(instance, str): - continue - rendered = f"{prefix}:{instance}" if prefix else instance - if rendered not in seen: - seen.add(rendered) - features.append(rendered) - - if not features: - chapter_name = param.get("chapter_name") - if isinstance(chapter_name, str) and chapter_name: - return f"CHAP:{chapter_name}" - return "(unspecified)" - - return ", ".join(features) - - -def infer_param_type_string( - param: Dict[str, Any], - fatal: Callable[[str], None], -) -> str: - """Render a parameter type string for table output. - - The input shape mirrors entries in params JSON output, including support for - scalar type/range forms and optional array bounds. - """ - param_type = param.get("type") - param_enum = param.get("enum") - param_range = param.get("range") - param_array = param.get("array") - param_width = param.get("width") - - param_name = "" - param_name_obj = param.get("name") - if isinstance(param_name_obj, str) and param_name_obj: - param_name = param_name_obj - else: - reg_name_obj = param.get("reg-name") - field_name_obj = param.get("field-name") - if isinstance(reg_name_obj, str) and reg_name_obj: - if isinstance(field_name_obj, str) and field_name_obj: - param_name = f"{reg_name_obj}.{field_name_obj}" - else: - param_name = reg_name_obj - else: - fatal("Expected parameter name or CSR reg-name to be a non-empty string") - - scalar_type = "" - - if isinstance(param_type, list): - if not param_type: - fatal(f"Parameter {param_name!r} has an empty type array") - if all(isinstance(v, str) for v in param_type): - enum_values = ", ".join(param_type) - scalar_type = f"[{enum_values}]" - elif all(isinstance(v, int) and not isinstance(v, bool) for v in param_type): - enum_values = ", ".join(map(str, param_type)) - scalar_type = f"[{enum_values}]" - else: - fatal( - f"Parameter {param_name!r} has invalid type array; expected all strings " - "or all integers" - ) - - elif isinstance(param_enum, dict): - enum_legal = param_enum.get("legal") - if not isinstance(enum_legal, list) or not enum_legal: - fatal( - f"Parameter {param_name!r} has invalid enum object; expected non-empty legal list" - ) - if not all(isinstance(v, int) and not isinstance(v, bool) for v in enum_legal): - fatal( - f"Parameter {param_name!r} has invalid enum.legal array; expected all integers" - ) - enum_values = ", ".join(map(str, enum_legal)) - scalar_type = f"[{enum_values}]" - - elif isinstance(param_type, str): - if param_type in {"boolean", "bit", "byte", "hword", "word", "dword"}: - scalar_type = param_type - - if param_type in {"int", "uint"}: - if isinstance(param_width, int) and not isinstance(param_width, bool): - signedness = "signed" if param_type == "int" else "unsigned" - scalar_type = f"{param_width}-bit {signedness} integer" - elif isinstance(param_width, str): - signedness = "signed" if param_type == "int" else "unsigned" - scalar_type = f"{param_width}-bit {signedness} integer" - else: - fatal( - f"Parameter {param_name!r} has type {param_type!r} but no valid width" - ) - - if not scalar_type: - # Keep unknown string types representable for callers that include - # non-parameter objects (e.g. CSR categories like WARL/WLRL). - scalar_type = param_type - - if not scalar_type: - fatal(f"Parameter {param_name!r} has invalid type of {param_type!r}") - - elif isinstance(param_range, list): - if len(param_range) != 2: - fatal( - f"Parameter {param_name!r} has invalid range array; expected exactly 2 values" - ) - - lo, hi = param_range - - if isinstance(lo, int) and not isinstance(lo, bool) and isinstance(hi, int) and not isinstance(hi, bool): - if lo > hi: - fatal( - f"Parameter {param_name!r} has min range value {lo!r} greater than max range value {hi!r}" - ) - scalar_type = f"range {lo} to {hi}" - - if not isinstance(lo, int) or isinstance(lo, bool): - fatal( - f"Parameter {param_name!r} has non-integer min range value of {lo!r}" - ) - - if not isinstance(hi, int) or isinstance(hi, bool): - fatal( - f"Parameter {param_name!r} has non-integer max range value of {hi!r}" - ) - - else: - fatal( - f"Parameter {param_name!r} has neither a valid type, enum, nor a valid range" - ) - - if isinstance(param_array, list): - if len(param_array) != 2: - fatal( - f"Parameter {param_name!r} has invalid array bounds; expected exactly 2 values" - ) - - lo, hi = param_array - if not isinstance(lo, int) or isinstance(lo, bool): - fatal( - f"Parameter {param_name!r} has non-integer min array value of {lo!r}" - ) - if not isinstance(hi, int) or isinstance(hi, bool): - fatal( - f"Parameter {param_name!r} has non-integer max array value of {hi!r}" - ) - if lo < 0 or hi < 0: - fatal( - f"Parameter {param_name!r} has invalid array bounds; values must be non-negative" - ) - if lo > hi: - fatal( - f"Parameter {param_name!r} has min array value {lo!r} greater than max array value {hi!r}" - ) - return f"array[{lo}..{hi}] of {scalar_type}" - - return scalar_type - - -def check_kind( - kind: str, - nr_name: str, - name: Optional[str], - fatal: Callable[[str], None], - program_name: str = "create_normative_rules.py", -): - """Fatal if kind is not recognized. - - The name is None if this is called in the normative rule definition. - """ - if kind not in STDS_OBJECT_KINDS: - tag_str = "" if name is None else f"tag {name} in " - allowed_str = ",".join(STDS_OBJECT_KINDS) - fatal( - f"Don't recognize kind '{kind}' for {tag_str}normative rule {nr_name}\n" - f"{program_name}: Allowed kinds are: {allowed_str}" - ) - - -def check_impldef_cat( - impldef_cat: str, - nr_name: str, - name: Optional[str], - fatal: Callable[[str], None], - program_name: str = "create_normative_rules.py", -): - """Fatal if impl-def-category is not recognized. - - The name is None if this is called in the normative rule definition. - """ - if impldef_cat not in IMPLDEF_CATEGORIES: - tag_str = "" if name is None else f"tag {name} in " - allowed_str = ",".join(IMPLDEF_CATEGORIES) - fatal( - f"Don't recognize impl-def-category '{impldef_cat}' for {tag_str}normative rule {nr_name}\n" - f"{program_name}: Allowed impl-def-categories are: {allowed_str}" - ) diff --git a/tools/tag_text_to_html.py b/tools/tag_text_to_html.py index 248a1d0..27cef99 100644 --- a/tools/tag_text_to_html.py +++ b/tools/tag_text_to_html.py @@ -9,7 +9,6 @@ def convert_tag_text_to_html( tag_text: str, target_html_fname: Optional[str] = None, - is_context: bool = False, ) -> str: """Convert tag text to HTML and apply tag-specific display behavior.""" text = convert_def_text_to_html(tag_text, target_html_fname) @@ -17,7 +16,4 @@ def convert_tag_text_to_html( if text.strip() == "": text = "(No text available)" - if is_context: - text = "[CONTEXT] " + text - return text