chiselrocket-chip

Accessing regmap RegFields


I am trying to find a clean way to access the regmap that is used with *RegisterNode for creating documentation and testing files. The TLRegisterNode has methods for generating the json through some Annotations. These are done in the regmap method by adding them to the ElaborationArtefacts object. Other protocols don't seem to have these annotations.

Is there anyway to iterate over the "regmap" Register Fields post elaboration or during?

I cannot just access the regmap as it's not really a val/var since it's a method. I can't quite figure out where this information is being stored. I don't really believe it's actually "storing" any information as much as it is simply creating the hardware to attach the specified logic to the RegisterNode based logic.

The JSON output is actually fine for me as I could just write a post processing script to convert JSON to my required formats, but I'm wondering if I can access this information OR if I could add a custom function call at the end. I cannot extend the case class *RegisterNode, but I'm not sure if it's possible to add custom functions to run at the end of the regmap method.

Here is something I threw together quickly:

//in *RegisterRouter.scala

def customregmap(customFunc: (RegField.Map*) => Unit, mapping: RegField.Map*) = {
  regmap(mapping:_*)
  customFunc(mapping:_*)
}

def regmap(mapping: RegField.Map*) = {
  //normal stuff
}

A user could then create a custom function to run and pass it to the regmap or to the RegisterRouter

def myFunc(mapping: RegField.Map*): Unit = {
  println("I'm doing my custom function for regmap!")
}

// ...

node.customregmap(myFunc, 
    0x0 -> coreControlRegFields,
    0x4 -> fdControlRegFields,
    0x8 -> fdControl2RegFields,    
  )

This is just a quick example I have. I believe what would be better, if something like this was possible, would be to have a Seq of functions that could be added to the RegisterNode that are ran at the end of the regmap method, similar to how TLRegisterNode currently works. So a user could add an arbitrary number and you still use the regmap call.

Background (not directly part of question):

I have a unified register script that I have built over the years in which I describe the registers for a particular IP. It works very similar to the RegField/node.regmap, except it obviously doesn't know about diplomacy and the like. It will generate the Verilog, but also a variety of files for DV (basic `defines for simple verilog simulations and more complex uvm_reg_block defines also with the ability to describe multiple of the IPs for a subsystem all the way up to an SoC level). It will also print out C Header files for SW and Sphinx reStructuredText for documentation.

Diplomacy actually solves one of the main issues I've been dealing with so I'm obviously trying to push most of my newer designs to Chisel/Diplo.


Solution

  • I ended up solving this by creating my own RegisterNode which is the same as the rocketchip RegisterNodes except that I use a different Elaboration Artifact to grab the info and store it for later.