Context
Embedded Digital Systems mini-project in the first year of the MESI master's (Faculty of Physics & Engineering, University of Strasbourg, supervised by Mr F. Dadouche). The goal was to practise co-design, designing the hardware and the software together, of a system-on-programmable-chip (SoPC) on FPGA. The target was a DE10-Lite board (Intel MAX 10 FPGA) turned into a complete electronic alarm clock.
Approach / Solution
On the hardware side (Quartus Prime and Platform Designer/Qsys), I assembled a system-on-chip around a 50 MHz Nios II processor, with on-chip memory, PIOs and two timers. Each DE10-Lite peripheral connects to the processor through a bit-sized PIO (six 7-segment displays, ten switches, two buttons, LEDs, speaker). A co-design subtlety, an inverter placed in the BDF schematic makes the buttons active-high, so the PIOs are configured for rising-edge interrupt detection. On the software side (C, Nios II SBT), a main loop reads the inputs and refreshes the display while two interrupt routines handle real time. The SYS_CLK_TIMER (1 ms) is the time base, the TONE_TIMER generates the square-wave sound by toggling an output. To share variables between the ISRs and the loop, I protected the accesses with critical sections (temporarily disabling interrupts). Beyond the spec, I added a 12h/24h toggle, 8 switch-selectable melodies (instead of a plain 500 Hz beep), two setting modes (single press or continuous, 0.5 s step), a display lock, and automatic initialisation to the compile time via the __TIME__ macro.
Results
A fully working alarm clock on FPGA, with every required function plus several improvements, validated feature by feature on the board. Two lessons stood out. • The real constraints of embedded systems. To initialise the clock I first tried sscanf, impossible here, because the BSP is configured with the Small C Library (-msmallc) to shrink the binary, and sscanf (stdio.h) is excluded. So I wrote a manual ASCII decode of __TIME__ (a few subtractions and multiplications), lighter, faster, dependency-free. In embedded, every byte counts. • Method. I first wrote the alarm in one big block, leaning too much on examples and AI, which produced many bugs that were hard to isolate. On my supervisor's advice I switched to incremental development, design the logic on paper, then code and test each sub-function in isolation before integrating. That is the most important takeaway of the project. Future work, an external RTC (keep time through a power loss), a Snooze function, an LCD/OLED display, a DAC for richer sound, and a full-hardware VHDL port to compare with the SoPC approach.