Closed ginty closed 4 years ago
@ginty Have you hooked up regs, memory maps and address blocks so this iteration pattern can be used in Python?
for reg in origen.dut.regs:
@info-rchitect, it will definitely work like that eventually, but not sure if it does currently or not
@coreyeng, I haven't made any changes per #71 yet and I'm currently in two minds about whether I should or not. I think for non-model related things (e.g. pattern, flow AST) should not pile in under the existing DUT, but its actually working pretty well for me now as far as model-data and state are concerned.
The RwLock provides (threadsafe) interior mutability to the Bit objects which have a state field which is wrapped by it. So as far as regs go, everything else is essentially immutable, i.e. you declare memory maps, regs, etc. and then these are fixed. The only thing that needs to change during pattern generation is the data stored by the regs and that boils down to the individual bit's state fields.
The way I'm writing it now is that every PyApi entry method grabs an immutable reference to the DUT, and then this is passed down to core functions that require it. Pure Rust entry points (i.e. from the CLI) in future should do the same. Interior functions should be banned from ever grabbing a DUT lock directly (as that can deadlock easily) and instead must look to their caller to provide it.
That has given me pretty minimal bother from the borrow-checker and I think this is following how data is intended to be shared between functions in Rust. The interior mutability aspect of the bits means that I hardly ever need a mutable DUT reference and that certainly helps with borrowing.
An advantage I'm seeing from having everything under DUT now is that it is just one reference I need to pass around. Even though moving to separate REGS, BITS, statics does give finer-grained locking, it would then mean that I would have to deal with passing lots of these references around instead of just one.
@ginty, sounds good! I think I've been doing something similar with timing so it should follow your rules above.
There's still a lot to do on regs, but thought I would open a PR to merge the current state into master to allow others access to it. Work will continue to add more functionality on this branch afterwards - I've copied over the reg_spec from O1 and my plan is to now work through that to add whatever is missing.
This PR adds the following:
Here is the latest register definition API:
Note that enumerated values as discussed in #31 are partially implemented - any enums defined as above do end up in the database but there is no API to consume them yet (will likely be
my_reg.set_data("val1")
).@info-rchitect I commented out your translator tests due to API changes, please feel free to re-instate with the latest API or wait for things to settle down as you see fit. Hopefully the above reg API is stable now though.
In the console, you should soon be able to just do
dut.regs
to see the list of regs that have been defined as they would have been in O1 without a memory map or address block parent. However, for now you need to dodut.default.default.regs
(reflecting that such regs are now physically instantiated in a default (auto-generated) memory map and address block), and you will see something like this:And register displays now work,
areg0
can be looked up a number of ways:And you get the same reg view from O1:
The data can be get/set on the whole register and individual bit fields: