```{_ex3_submission} ``` # Ex. 3: Software development and system simulation Group: **rvlab01** ## 1. Questions ### 1. to 4: What is the highest speed of the running light your software can handle? Our software can prevent the pattern from reaching the most and least significan bits of the pattern as long as the number of cycles between each animation step is above 55. ### 2. to 4: How many clock cycles does your application require for a complete pass of its main loop? To determine the number of clock cycles for a `main` loop cycle, the jump address of the beginning of the `main` loop was determined by looking at jumps in the dissassembly of the software binary. Markers for that PC address can be seen in the follwing image: ![Ex4_Q2](res/Ex4_Q2.png) By determining times between the cycles where the code is only checking the pattern and not writing anything, and then dividing by the period of a `sys_clk` cycle, resulted in an average number of 27 cylcles per loop. A `main` loop cycle including the writes required for a direction reversal takes approx. 70 `sys_clk` cycles. ### 3. to 4: How many clock cycles after the 1st instruction in ctrt0.S is the stack pointer of the IRQ initialized? The `csrrw zero, mscratch, sp` command was determined to be the end of the stack pointer of the IRQ initialization. In the wave viewer it can be oberserved that starting at address zero results in a jump to the `_start` symbol. From there, we can observe the process of setting all 32 internal registers to zero. The address of the `_irq_stack_top` symbol is then loaded in the CS register. Measuring the time after the reset is released until `lui sp, %hi(_main_stack_top)`, the instruction after the stack pointer of the IRQ initialization, was reached, resulted in 36 `sys_clk`s for 34 instructions. This shows that only the first two jump instructions need more than one cycle. ## 2. Deliverables of task 4 ### 1. Register definitions ```{reggen} student_rlight ``` #### Register usage All writable registers may be changed at any time. On a `mode` register change, the `pattern` will be applied. The `speed` register value will be applied immediately. When the `mode` is changed to `stop`, the system does not reset the current LEDs (`status`) and instead stays at the last displayed pattern. On the next `mode` change, it will reset. ### 2. source texts of the .c and .h files you created or modified (driver and mini application) yourself (not the generated source files) These sources can be found in the appendix. ### 3. a wave view from the system simulation which shows the lightening up of an outermost “grey” LED and the following write access of the software to the mode register To prevent the LED pattern from reaching the most and least significant bits, the `main` loop keeps reading the current pattern (`status`) from the hardware. If a bit in the outermost "grey" positions is detected, the current pattern (`status`) is written back to the `pattern` register, to be reapplied once the animation `mode` is changed. The reversal of the animation direction is completed by writing the inverse rotation mode to the `mode` register. The following wave view shows this behavior. The rightmost "gray" LED-bit is highlighted in pink. Directly before the orange cursor, the `main` loop has detected a necessity to change the direction `mode` to `left`. The caused write flag in the `mode` register is highlighted in blue. ![Ex3_Task_4_3 Wave view](res/Ex3_Task_4_3.png) After reducing the number of clocks between each animation step to 55 in the `speed` register, the software is no longer able to prevent the animation from reaching the most and least significant bits of the pattern. ## Appendix: - [`main.c`](#mini-application) - [`running_light_ctrl.c`](#rlight-api-source) - [`running_light_control.h`](#rlight-api-header) - [`rvlab.h`](#rvlab-header) - [`tinyprintf.c`](#tinyprintfc) ### tinyprintf.c Added support for binary output format: ```C case 'b': p.base = 2; #ifdef PRINTF_LONG_SUPPORT if (lng) li2a(va_arg(va, unsigned long int), &p); else #endif i2a(va_arg(va, int), &p); written += putchw(putp, &p); break; ```