|
| 1 | +<<< |
| 2 | +[appendix] |
| 3 | +== CSR Details |
| 4 | + |
| 5 | +<% design.in_scope_csrs.sort_by(&:name).each do |csr| -%> |
| 6 | +<<< |
| 7 | +[[csr-<%= csr.name %>-def]] |
| 8 | +=== <%= csr.name %> |
| 9 | + |
| 10 | +*<%= csr.long_name %>* |
| 11 | + |
| 12 | +<% unless csr.base.nil? -%> |
| 13 | +[NOTE] |
| 14 | +-- |
| 15 | +`<%= csr.name %>` is only defined in RV<%= csr.base %>. |
| 16 | +-- |
| 17 | +<% end -%> |
| 18 | + |
| 19 | +<%= csr.description %> |
| 20 | + |
| 21 | +==== Attributes |
| 22 | +[%autowidth] |
| 23 | +|=== |
| 24 | +h| CSR Address | <%= "0x#{csr.address.to_s(16)}" %> |
| 25 | +<% if csr.priv_mode == 'VS' -%> |
| 26 | +h| Virtual CSR Address | <%= "0x#{csr.virtual_address.to_s(16)}" %> |
| 27 | +<% end -%> |
| 28 | +h| Defining extension a| <%= csr.defined_by_condition.to_asciidoc %> |
| 29 | +<% if csr.dynamic_length?(design) -%> |
| 30 | +h| Length | <%= csr.length_pretty(design) %> |
| 31 | +<% else -%> |
| 32 | +h| Length | <%= csr.length_pretty(design) %> |
| 33 | +<% end -%> |
| 34 | +h| Privilege Mode | <%= csr.priv_mode %> |
| 35 | +|=== |
| 36 | + |
| 37 | + |
| 38 | +==== Format |
| 39 | +<% unless csr.dynamic_length?(design) || csr.implemented_fields(design).any? { |f| f.dynamic_location?(design) } -%> |
| 40 | +<%# CSR has a known static length, so there is only one format to display -%> |
| 41 | +.<%= csr.name %> format |
| 42 | +[wavedrom, ,svg,subs='attributes',width="100%"] |
| 43 | +.... |
| 44 | +<%= JSON.dump csr.wavedrom_desc(design, csr.base.nil? ? 32 : csr.base, optional_type: 2) %> |
| 45 | +.... |
| 46 | +<% else -%> |
| 47 | +<%# CSR has a dynamic length, or a field has a dynamic location, |
| 48 | + so there is more than one format to display -%> |
| 49 | +This CSR format changes dynamically with XLEN. |
| 50 | + |
| 51 | +.<%= csr.name %> Format when <%= csr.length_cond32 %> |
| 52 | +[wavedrom, ,svg,subs='attributes',width="100%"] |
| 53 | +.... |
| 54 | +<%= JSON.dump csr.wavedrom_desc(design, 32, optional_type: 2) %> |
| 55 | +.... |
| 56 | + |
| 57 | +.<%= csr.name %> Format when <%= csr.length_cond64 %> |
| 58 | +[wavedrom, ,svg,subs='attributes',width="100%"] |
| 59 | +.... |
| 60 | +<%= JSON.dump csr.wavedrom_desc(design, 64, optional_type: 2) %> |
| 61 | +.... |
| 62 | + |
| 63 | + |
| 64 | +<% end # unless dynamic length -%> |
| 65 | +
|
| 66 | +==== Field Summary |
| 67 | +
|
| 68 | +// use @ as a separator since IDL code can contain | |
| 69 | +[%autowidth,separator=@,float="center",align="center",cols="^,<,<,<",options="header",role="stretch"] |
| 70 | +|=== |
| 71 | +@ Name @ Location @ Type @ Reset Value |
| 72 | +
|
| 73 | +<%- csr.implemented_fields(design).each do |field| -%> |
| 74 | +@ xref:<%=csr.name%>-<%=field.name%>-def[`<%= field.name %>`] |
| 75 | +a@ |
| 76 | +<%- if field.dynamic_location?(design) -%> |
| 77 | +
|
| 78 | +[when,"<%= field.location_cond32 %>"] |
| 79 | +-- |
| 80 | +<%= field.location_pretty(design, 32) %> |
| 81 | +-- |
| 82 | +
|
| 83 | +[when,"<%= field.location_cond64 %>"] |
| 84 | +-- |
| 85 | +<%= field.location_pretty(design, 64) %> |
| 86 | +-- |
| 87 | +
|
| 88 | +<%- else -%> |
| 89 | +<%= field.location_pretty(design) %> |
| 90 | +<%- end -%> |
| 91 | +a@ |
| 92 | +
|
| 93 | +-- |
| 94 | +<%= field.type_pretty(design.symtab) %> |
| 95 | +-- |
| 96 | +
|
| 97 | +a@ |
| 98 | +
|
| 99 | +-- |
| 100 | +<%= field.reset_value_pretty(design) %> |
| 101 | +-- |
| 102 | +
|
| 103 | +<%- end -%> |
| 104 | +|=== |
| 105 | +
|
| 106 | +==== Fields |
| 107 | +
|
| 108 | +<%- if csr.implemented_fields(design).empty? -%> |
| 109 | +This CSR has no fields. However, it must still exist (not cause an `Illegal Instruction` trap) and always return zero on a read. |
| 110 | +<%- else -%> |
| 111 | +
|
| 112 | +<%- csr.implemented_fields(design).each do |field| -%> |
| 113 | +[[<%=csr.name%>-<%=field.name%>-def]] |
| 114 | +===== `<%= field.name %>` |
| 115 | +
|
| 116 | +<%- if !field.defined_in_all_bases? -%> |
| 117 | +IMPORTANT: <%= field.name %> is only defined in <%= field.base32_only? ? "RV32" : "RV64" %> (`<%= field.base32_only? ? field.location_cond32 : field.location_cond64 %>`) |
| 118 | +<%- end -%> |
| 119 | +
|
| 120 | +**** |
| 121 | +Location:: |
| 122 | +<%= field.location_pretty(design) %> |
| 123 | +
|
| 124 | +Description:: |
| 125 | +<%= field.description.gsub("\n", " +\n") %> |
| 126 | +
|
| 127 | +Type:: |
| 128 | +<%= field.type_pretty(design.symtab) %> |
| 129 | +
|
| 130 | +Reset value:: |
| 131 | +<%= field.reset_value_pretty(design) %> |
| 132 | +
|
| 133 | +**** |
| 134 | +
|
| 135 | +<%- end -%> |
| 136 | +<%- end -%> |
| 137 | +
|
| 138 | +<%- if csr.implemented_fields(design).map(&:has_custom_sw_write?).any? -%> |
| 139 | +==== Software write |
| 140 | +
|
| 141 | +This CSR may store a value that is different from what software attempts to write. |
| 142 | +
|
| 143 | +When a software write occurs (_e.g._, through `csrrw`), the following determines the |
| 144 | +written value: |
| 145 | +
|
| 146 | +[idl] |
| 147 | +---- |
| 148 | +<%- csr.implemented_fields(design).each do |field| -%> |
| 149 | +<%- if field.has_custom_sw_write? -%> |
| 150 | +<%= field.name %> = <%= field["sw_write(csr_value)"] %> |
| 151 | +<%- else -%> |
| 152 | +<%= field.name %> = csr_value.<%= field.name %> |
| 153 | +<%- end -%> |
| 154 | +<%- end -%> |
| 155 | +---- |
| 156 | +<%- end -%> |
| 157 | +
|
| 158 | +<%- if csr.has_custom_sw_read? -%> |
| 159 | +==== Software read |
| 160 | +
|
| 161 | +This CSR may return a value that is different from what is stored in hardware. |
| 162 | +
|
| 163 | +[source,idl,subs="specialchars,macros"] |
| 164 | +---- |
| 165 | +<%= csr.sw_read_ast(design.symtab).gen_adoc %> |
| 166 | +---- |
| 167 | +<%- end -%> |
| 168 | +
|
| 169 | +<% end # do in_scope_csrs -%> |
0 commit comments