1For general information about these models refer to [README.md](README.md)
2
3You will only need to continue reading if you are curious about how these
4models are built, or if you want to use them for some other purpose than
5with the nrf52_bsim.
6
7## Requirements
8
9The purpose of these models is to provide a good enoug HW model for BLE
10protocol simulations, which will focus on the SW, to be able to debug it,
11and run long simulations fast.<br>
12We are not interested in modelling the particularities of the HW when
13they are not relevant for the SW execution.
14Therefore many details can be simplified or omited all together.
15
16The focus of these models is on the Zephyr BLE stack, and therefore
17only the peripherals which are necessary for its proper function have
18been modelled so far.
19
20Regarding the time accuracy, these models will focus mostly on the radio
21activity accuracy. With other peripherals being overall more rough. Note that
22as all models are based on public specifications, all peripherals timings
23could, anyhow, not be better than what is described in those.<br>
24Overall these models have a time granularity of 1us.
25
26## Implementation specification
27
28Overall these models are "event driven". There is several ways
29of building these kind of models, but for simplicity, speed, and to not need to
30rely on any kind of library or 3rd party engine, these models are built with a
31very nimble engine provided partly by the models themselves, and partly by the
32nrf52_bsim "time machine".<br>
33The reason for this division is due to the nrf52_bsim being
34the overall scheduler, which initializes both models and "CPU", and is in
35charge of when each should run.<br>
36
37### About the event scheduling
38
39In reality any action performed by a HW peripheral will take some amount of
40time.<br>
41For our purposes any HW process which takes too short for the SW to
42realize, will be modelled as being instantaneous in simulation time.
43Such processes will just be implemented as a C function (or a set of them),
44which will change the models status as needed.
45
46Other processes do take a considerable amount of time, like for example sending
47a radio packet, or generating a random number.<br>
48Such processes will be modelled in a bit more complex way:
49
50  * The process model may use one or several "events"/timers.
51  * When needed these timers will be set at a point in the future where some
52    action needs to be performed.
53  * Whenever that time is reached, an scheduler will call a function in that
54    model tasked with continuing executing that task/process.
55
56In this model, all of these events|timers types and their callbacks are known
57in design/compile time.
58Meaning, there is no dynamic registration of events types.<br>
59Normally each peripheral model will have 1 of such event timers, and it will
60be up to the peripheral model to schedule several subevents using only that
61one timer and callback if needed.
62
63The HW models top level, `NRF_HW_model_top`, collects all these events and
64exposes only 1 timer (with 1 callback) to the overall scheduler provided by
65the nrf52_bsim.
66
67Whenever a HW model updates its timer, it will call a function in the top level
68to update that top level timer if needed.
69
70The overall scheduler provided by the nrf52_bsim, will advance simulated time
71when needed, and call into the top level HW models "event|task runner"
72(`nrf_hw_some_timer_reached()`) whenever its timer time is reached.
73This will in turn call whichever HW submodule task function was scheduled for
74this moment.
75
76Note that several HW submodules may be scheduled to run in the same µs.
77In this case, they will be handled in different "delta cycles" in that same µs.
78, that is, in different consecutive calls to `nrf_hw_some_timer_reached()`.
79Each timer|event has a given priority, and therefore will always be called
80in the same order relative to other HW events which may be schedule in the
81same µs.<br>
82Note also, that any HW submodule may schedule a new event to be called in the
83same µs in which it is running. This can be done for any purpose,
84like for example to deffer a sideeffect of writing to a register from a SW
85thread into the HW models thread.
86
87### The SW registers IF
88
89Each peripheral model which has HW registers accessible by SW, presents
90a structure which matches those registers' layout.
91This structure will be allocated somewhere in the process memory, but certainly
92not in the same address as in the real HW.
93Therefore any access to the real registers must be, in someway, corrected
94to access this structure instead.
95In Zephyr's nrf52_bsim case, this is achieved by providing a version of the
96macros which, in real point to the peripherals base addresses, which points
97to these structures.
98
99Writing to this structure in itself will only cause that memory location to be
100changed. For many registers this is perfectly fine, as that is just the same
101that happens in the real HW (a register is changed, which later may be
102read by the actual HW).<br>
103But for some registers, accesing them (writing and/or reading them) causes some
104sideeffect, that is, something else to happen in the HW.
105For example, in real HW, writting a `1` to
106`NRF_RNG->TASKS_START` will start the random number generation.
107
108For these type of registers with sideeffects, the HW models must be triggered,
109this is achieved by calling `nrf_<periperal>_regw_sideeffects_<register name>()`
110after the write itself.
111In the nrf52_bsim case, this is done in the replacement nRFx HAL function.
112
113### HW interrupts
114
115For a HW model to raise an interrupt all it will need to do is call into the
116interrupt controller model function `hw_irq_ctrl_set_irq(<irq_nbr>)`.
117
118The interrupt controller will update its status, and if the interrupt was not
119masked, one delta cycle later, awake the CPU by calling
120`posix_interrupt_raised()`.
121
122In the nrf52_bsim `posix_interrupt_raised()` is provided by the Zephyr
123POSIX arch `inf_clock`.
124
125### Structure of the HW models:
126
127The actual HW models of the SOC peripherals are split in one file per peripheral.
128The files are named `NRF_<PERIPHERAL>.{c|h}`.
129
130Mostly all these models have the following functions:
131
132#### Interface:
133```
134nrf_<periperal>_init()            : Initialize the model
135nrf_<periperal>_cleanup()         : Free any memory used by the model
136nrf_<periperal>_<TASK name>()     : Perform the actions triggered by <TASK>
137nrf_<periperal>_regw_sideeffects_<register name>()
138                                  : Trigger any possible sideeffect from writing
139                                    to that regiter
140Timer_<peripheral> &
141nrf_<periperal>_timer_triggered() : Models which take time to perform their work
142                                    Use a registered timer. When that timer is
143                                    reached, this function is called to perform
144                                    any neccessary step, including update that
145                                    timer.
146```
147#### Internal/static:
148```
149signal_<event register name>() : Signal that <event> has just happened
150
151```
152The tasks, registers and event names should match the register interface
153specified in the linked documentation.
154
155
156## Integrating these models in another system
157
158This subsection provides information you would need if you try to use
159these models without the nrf52_bsim wrapping logic.
160
161### Models interface towards a simulation scheduler
162
163As described before, overall the models are "event driven":
164They rely on an overall scheduler triggering (calling) them in
165the appropriate times.
166
167In the case of Zephyr's nrf52_bsim, this overall scheduler is provided by
168the nrf52_bsim "time machine". The interface the models expect from this
169is described in [`time_machine_if.h`](../src/HW_models/time_machine_if.h)
170
171The top level [`NRF_HW_model_top.c`](../src/HW_models/NRF_HW_model_top.c)
172exposes one event timer: `nrf_hw_next_timer_to_trigger`.
173This timer represents, in microseconds, when the models need to perform
174the next action.
175
176It is the responsability of that overall scheduler to ensure the HW models
177top level scheduling function (`nrf_hw_some_timer_reached()`) is called
178whenever that time is reached.
179
180This timer may be changed after each execution of the models, or whenever
181a HW register is written.
182When the models change this timer, they will call
183`tm_find_next_timer_to_trigger()` to notify that overall scheduler of the
184change.
185
186The models are initalized by calling first `nrf_hw_pre_init()`.
187Later `nrf_hw_initialize()` shall be called with the command line selected
188options.<br>
189No other HW model function can be called before these two.<br>
190`nrf_hw_models_free_all()` shall be called to clean up after the simulation
191is done: to deallocate and close any resource the models may be using.
192
193### Models interface towards a CPU model:
194
195For details about the SW register IF please see check the
196"The SW registers IF" section above.
197For details about how interrupts are raised see "HW interrupts" above.
198
199### Thread safety
200
201This HW models API is NOT thread safe: This means a call to one of the
202HW models functions cannot be done if another thread of the same process
203is currently also calling another of these functions.
204Meaning, only one function may be called at a time.<br>
205This is not going to be a problem if only one thread calls into the HW models.
206It won't be a problem either if by any other synchronization mechanism it is
207ensured only one thread calls into these HW models at a time.
208(this second case is how it is done in the nrf52_bsim)
209
210### Command line intercace arguments
211
212These models command line arguments/options are described in
213[`NRF_hw_args.h`](../src/HW_models/NRF_hw_args.h)
214
215The way to describe the command line arguments follows Babblesim's
216`libUtilv1` command line parsing convention.
217
218You can check the nrf52_bsim wrapping code for an insight on how
219you can set them.
220
221