| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| // UVM Registers auto-generated by `reggen` containing data structure |
| // Do Not Edit directly |
| <% from reggen import (gen_dv) |
| %>\ |
| <%def name="construct_classes(block)">\ |
| % for b in block.blocks: |
| ${construct_classes(b)} |
| % endfor |
| <% |
| regs_flat = block.get_regs_flat() |
| %>\ |
| |
| // Block: ${block.name} |
| `ifndef ${block.name.upper()}_REG_BLOCK__SV |
| `define ${block.name.upper()}_REG_BLOCK__SV |
| |
| // Forward declare all register/memory/block classes |
| % for r in regs_flat: |
| typedef class ${gen_dv.rcname(block, r)}; |
| % endfor |
| % for w in block.wins: |
| typedef class ${gen_dv.mcname(block, w)}; |
| % endfor |
| typedef class ${gen_dv.bcname(block)}; |
| |
| % for r in regs_flat: |
| <% |
| reg_width = block.width |
| %>\ |
| // Class: ${gen_dv.rcname(block, r)} |
| class ${gen_dv.rcname(block, r)} extends dv_base_reg; |
| // fields |
| % for f in r.fields: |
| rand dv_base_reg_field ${f.name}; |
| % endfor |
| |
| `uvm_object_utils(${gen_dv.rcname(block, r)}) |
| |
| function new(string name = "${gen_dv.rcname(block, r)}", |
| int unsigned n_bits = ${reg_width}, |
| int has_coverage = UVM_NO_COVERAGE); |
| super.new(name, n_bits, has_coverage); |
| endfunction : new |
| |
| virtual function void build(); |
| // create fields |
| % for f in r.fields: |
| <% |
| field_size = f.msb - f.lsb + 1 |
| if f.swaccess.name == "R0W1C": |
| field_access = "W1C" |
| else: |
| field_access = f.swaccess.name |
| |
| if f.hwaccess == HwAccess.HRO: |
| field_volatile = 0 |
| else: |
| field_volatile = 1 |
| %>\ |
| ${f.name} = dv_base_reg_field::type_id::create("${f.name}"); |
| ${f.name}.configure( |
| .parent(this), |
| .size(${field_size}), |
| .lsb_pos(${f.lsb}), |
| .access("${field_access}"), |
| .volatile(${field_volatile}), |
| .reset(${reg_width}'h${format(f.resval, 'x')}), |
| .has_reset(1), |
| .is_rand(1), |
| .individually_accessible(1)); |
| % endfor |
| endfunction : build |
| |
| endclass : ${gen_dv.rcname(block, r)} |
| |
| % endfor |
| % for w in block.wins: |
| <% |
| mem_name = w.name.lower() |
| mem_right = w.dvrights.upper() |
| mem_n_bits = w.n_bits |
| mem_size = int((w.limit_addr - w.base_addr) / (mem_n_bits / 8)) |
| %>\ |
| // Class: ${gen_dv.mcname(block, w)} |
| class ${gen_dv.mcname(block, w)} extends dv_base_mem; |
| |
| `uvm_object_utils(${gen_dv.mcname(block, w)}) |
| |
| function new(string name = "${gen_dv.mcname(block, w)}", |
| longint unsigned size = ${mem_size}, |
| int unsigned n_bits = ${mem_n_bits}, |
| string access = "RW"/* TODO:"${mem_right}"*/, |
| int has_coverage = UVM_NO_COVERAGE); |
| super.new(name, size, n_bits, access, has_coverage); |
| endfunction : new |
| |
| endclass : ${gen_dv.mcname(block, w)} |
| |
| % endfor |
| // Class: ${gen_dv.bcname(block)} |
| class ${gen_dv.bcname(block)} extends dv_base_reg_block; |
| % if block.blocks: |
| // sub blocks |
| % endif |
| % for b in block.blocks: |
| rand ${gen_dv.bcname(b)} ${b.name}; |
| % endfor |
| % if regs_flat: |
| // registers |
| % endif |
| % for r in regs_flat: |
| rand ${gen_dv.rcname(block, r)} ${r.name}; |
| % endfor |
| % if block.wins: |
| // memories |
| % endif |
| % for w in block.wins: |
| rand ${gen_dv.mcname(block, w)} ${gen_dv.miname(w)}; |
| % endfor |
| |
| `uvm_object_utils(${gen_dv.bcname(block)}) |
| |
| function new(string name = "${gen_dv.bcname(block)}", |
| int has_coverage = UVM_NO_COVERAGE); |
| super.new(name, has_coverage); |
| endfunction : new |
| |
| virtual function void build(uvm_reg_addr_t base_addr); |
| // create default map |
| this.default_map = create_map(.name("default_map"), |
| .base_addr(base_addr), |
| .n_bytes(${block.width//8}), |
| .endian(UVM_LITTLE_ENDIAN)); |
| % if block.blocks: |
| |
| // create sub blocks and add their maps |
| % endif |
| % for b in block.blocks: |
| ${b.name} = ${gen_dv.bcname(b)}::type_id::create("${b.name}"); |
| ${b.name}.configure(.parent(this)); |
| ${b.name}.build(.base_addr(base_addr + ${gen_dv.sv_base_addr(b)})); |
| default_map.add_submap(.child_map(${b.name}.default_map), |
| .offset(base_addr + ${gen_dv.sv_base_addr(b)})); |
| % endfor |
| % if regs_flat: |
| |
| // create registers |
| % endif |
| % for r in regs_flat: |
| <% |
| reg_name = r.name |
| reg_right = r.dvrights |
| reg_width = block.width |
| reg_offset = str(reg_width) + "'h" + "%x" % r.offset |
| %>\ |
| ${reg_name} = ${gen_dv.rcname(block, r)}::type_id::create("${reg_name}"); |
| ${reg_name}.configure(.blk_parent(this)); |
| ${reg_name}.build(); |
| default_map.add_reg(.rg(${reg_name}), |
| .offset(${reg_offset}), |
| .rights("${reg_right}")); |
| % endfor |
| % if block.wins: |
| |
| // create memories |
| % endif |
| % for w in block.wins: |
| <% |
| mem_name = w.name.lower() |
| mem_right = w.dvrights.upper() |
| mem_offset = str(block.width) + "'h" + "%x" % w.base_addr |
| mem_n_bits = w.n_bits |
| mem_size = int((w.limit_addr - w.base_addr) / (mem_n_bits / 8)) |
| %>\ |
| ${mem_name} = ${gen_dv.mcname(block, w)}::type_id::create("${mem_name}"); |
| ${mem_name}.configure(.parent(this)); |
| default_map.add_mem(.mem(${mem_name}), |
| .offset(${mem_offset}), |
| .rights("${mem_right}")); |
| % endfor |
| endfunction : build |
| |
| endclass : ${gen_dv.bcname(block)} |
| |
| `endif\ |
| </%def>\ |
| ${construct_classes(block)} |