Hi and welcome👋.

I’m Phong.

On this blog, I write about topics related to my work.Why writing? Because writing helps me think - there is no better tool for organizing a long line of thought.

System C TLM 2.0

Transaction-Level Modeling 2.0 (TLM-2.0) is a modeling methodology defined in IEEE 1666-2023. Instead of communicating through individual signals at every clock cycle, modules exchange complete transactions (read/write requests) using C++ function calls. This raises the abstraction level, dramatically increasing simulation speed and enabling early software development before RTL is available. 1. Introduce TLM-2.0 replaces pin-level signal connections with high-level function calls carrying a tlm_generic_payload transaction object. An initiator (e.g., a CPU model) calls transport functions on a target (e.g., a memory) through typed sockets and a bus/router. ...

March 29, 2026 · 10 min · Phong Nguyen

System C

1. Introduce SystemC is a C++ class library, that provides a mechanism for managing complex systems involving large numbers of components. SystemC is capable of modeling hardware and software together at multiple level of abstraction (Algorithm / Functional level, Transaction-Level Modeling, Register Transfer Level) Modeling is the process of creating a simplified version of a real system. Simulation is the process of executing the model over time to see how it behaves. ...

March 23, 2026 · 21 min · Phong Nguyen

Embedded C

Embedded C . 1. C Language 1.1. Introduction Programming language is a set of instructions that used to communicate with a computer and control its behavior. C is a general-purpose procedural programming language. 1.2. Expression An expression is a combination of operators, constants and variables that evaluate to a value. There are several types of expressions, including: constant expr: 5, 10+3 integral expr: x*y floating expr: x + 10.75 relational expr: x <=y logical expr: x > y && z == 6 pointer expr: &x bitwise: x<<3 1.3. Variables & Data Types A variable is a named location in memory that stores data. Every variable must be declared to specify its type. e.g. int a; Common Data Types in C: Data Type Size (Typical) Range char 1 byte -128 to 127 unsigned char 1 byte 0 to 255 short 2 bytes -32,768 to 32,767 int (16-bit) 2 bytes -32,768 to 32,767 int (32-bit) 4 bytes -32,768 to 32,767 unsigned int 2 bytes 0 to 65,535 (16-bit) long 4 bytes -2,147,483,648 to 2,147,483,647 float 4 bytes ±3.4e±38 (~6–7 digits precision) double 8 bytes On a 32-bit machine, short is not efficient because the CPU is designed to process 32-bit data in one step. ...

March 21, 2026 · 5 min · Phong Nguyen

CMake Guide

1. Introduction It’s a meta-build system generator. How it works: We write high-level instructions in a CMakeLists.txt file (platform-agnostic).Then CMake generates build system files for the platform we choose: On Linux/Unix: generates Makefile (for make) or build.ninja (for ninja). On Windows: generates Visual Studio solutions (.sln). On macOS: can generate Xcode projects. CMake Generators: CMake support multiple build systems output a.k.a generators. Which generator is used can be controlled via CMAKE_GENERATOR or cmake -G option ...

August 21, 2025 · 14 min · Phong Nguyen

Cpp

See plus plus :) . Refer 0. Notes printf/snprintf Cheat Sheet {C / C++} Integer Data type Specifier Notes int8_t / signed char %hhd signed 8-bit uint8_t / unsigned char %hhu unsigned 8-bit int16_t / short %hd signed 16-bit uint16_t / unsigned short %hu unsigned 16-bit int32_t / long %ld signed 32-bit uint32_t / unsigned long %lu unsigned 32-bit int64_t / long long %lld signed 64-bit uint64_t / unsigned long long %llu unsigned 64-bit Floating point Data type Specifier Notes float %f 4-byte float double %f Arduino AVR: double = float long double %Lf depends on platform %e → scientific notation %g → auto select %f or %e Char / String Data type Specifier Notes char %c single character char* / String %s null-terminated string Pointer / Address Data type Specifier Notes void* %p memory address, hex Hex / Octal / Binary Data type Specifier Notes unsigned int %x / %X hexadecimal unsigned int %o octal Arduino only %b binary Flags, Width, Precision %-10d → left-justify, width 10 %010d → pad with zeros, width 10 %.2f → 2 decimal digits %*d → dynamic width Specific Notes uint32_t → %lu int32_t → %ld uint16_t → %u int16_t → %d or %hd uint8_t → %u or %hhu int8_t → %d or %hhd float → %f Use snprintf() with correctly sized buffer to avoid overflow Code Timming C++11 comes with some functionality in the chrono library to time our code to see how long it takes to run. e.g. #include <array> #include <chrono> // for std::chrono functions #include <cstddef> // for std::size_t #include <iostream> #include <numeric> // for std::iota const int g_arrayElements { 10000 }; class Timer { private: // Type aliases to make accessing nested type easier using Clock = std::chrono::steady_clock; using Second = std::chrono::duration<double, std::ratio<1> >; std::chrono::time_point<Clock> m_beg{ Clock::now() }; public: void reset() { m_beg = Clock::now(); } double elapsed() const { return std::chrono::duration_cast<Second>(Clock::now() - m_beg).count(); } }; void sortArray(std::array<int, g_arrayElements>& array) { // Step through each element of the array // (except the last one, which will already be sorted by the time we get there) for (std::size_t startIndex{ 0 }; startIndex < (g_arrayElements - 1); ++startIndex) { // smallestIndex is the index of the smallest element we’ve encountered this iteration // Start by assuming the smallest element is the first element of this iteration std::size_t smallestIndex{ startIndex }; // Then look for a smaller element in the rest of the array for (std::size_t currentIndex{ startIndex + 1 }; currentIndex < g_arrayElements; ++currentIndex) { // If we've found an element that is smaller than our previously found smallest if (array[currentIndex] < array[smallestIndex]) { // then keep track of it smallestIndex = currentIndex; } } // smallestIndex is now the smallest element in the remaining array // swap our start element with our smallest element (this sorts it into the correct place) std::swap(array[startIndex], array[smallestIndex]); } } int main() { std::array<int, g_arrayElements> array; std::iota(array.rbegin(), array.rend(), 1); // fill the array with values 10000 to 1 Timer t; sortArray(array); std::cout << "Time taken: " << t.elapsed() << " seconds\n"; return 0; } Command line Command line arguments are optional string arguments that are passed by the operating system to the program when it launch. Passing command line arguments: we simply list the command line arguments right after the executeable name. Using command line arguments: by using different form of main(): main(int argc, char* argv[]) / main(int argc, char** argv) argc: argument count, always be at least 1, because the first argument is always the name of the program itself. argv: is where the actual argument values are stored (think: argv = argument values) e.g. #include <iostream> #include <sstream> // for std::stringstream #include <string> int main(int argc, char* argv[]) { if (argc <= 1) { // On some operating systems, argv[0] can end up as an empty string instead of the program's name. // We'll conditionalize our response on whether argv[0] is empty or not. if (argv[0]) std::cout << "Usage: " << argv[0] << " <number>" << '\n'; else std::cout << "Usage: <program name> <number>" << '\n'; return 1; } std::stringstream convert{ argv[1] }; // set up a stringstream variable named convert, initialized with the input from argv[1] int myint{}; if (!(convert >> myint)) // do the conversion myint = 0; // if conversion fails, set myint to a default value std::cout << "Got integer: " << myint << '\n'; return 0; } Things that can impact the performance of the program: TBD Measuring performance: gather at least 3 results. the program runs in 10 seconds etc 1. Introduction C++ was developed as an extension to C. It adds man few features to the C language, and tis perhaps best through of as a superset of C. Step 1: Define the problem that you would like to solve ...

February 9, 2025 · 111 min · Phong Nguyen

Makefile Guide

Introduction It’s a build tool (specifically, make is a build automation utility). How it works: Reads a file called Makefile that describes rules for how to build source files into targets (executables, libraries, etc.). GNU Make is a tool which controls the generation of executables and other non-source files of a program from the program’s source files. Make get its knowledge of how to build your program from a file called the makefile, which lists each of the non-source files and how to compute it from the other files. When you write a program, you should write a makefile for it, so that it is possible to use Make to build and install the program. ...

August 9, 2024 · 11 min · Phong Nguyen

C/C++ Tools

1. Doxygen Code documentation can be achieved with the Doxygen framework which is one of the most standard one for many languages. 1.1. Getting Started Install: $ sudo apt install doxygen Create a config and update: $ mkdir docs && cd docs $ doxygen -g Doxyfile $ vi Doxyfile Running doxygen: $ cd docs && doxygen <config-file> & htlm/index.htlm Install the VSCode Extension: Doxygen Documentation Generator 1.2. Doxygen with CMake Create a Doxygen file template for CMake: ...

March 30, 2026 · 4 min · Phong Nguyen

CI/CD Guide

1. Introduce 2. Docker: Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code, you can significantly reduce the delay between writing code and running it in production. ...

March 12, 2026 · 3 min · Phong Nguyen

Vim Syntax

1. Modes Key Mode Description ESC Normal Mode Default mode. Used for navigation and simple editing. i Insert Mode Insert and edit text. : Command Mode Run commands like save, quit, search, etc. 2. Basic Commands Open File vi <file> Quit :q! Insert Text i Save File :w Save and Quit :wq 3. Navigation Enable Line Numbers :set number Jump to Line :<line_number> Example: ...

March 8, 2026 · 2 min · Phong Nguyen

Complexity

References: How to Find the Complexity of an Algorithm 1. Introduction Algorithmic complexity is a measure of the resources and algorithm requires about its input size. The two main types are: Time complexity: number of operations performed by an algorithm Space complexity: the amount of memory consumed 2. Time Complexity The time complexity of an algorithm quantifies the amount of time (operations) taken by an algorithm to run as a function of the length of the input It’s commonly expressed by Big-O notation Hierarchy of Time Complexities (Fastest to Slowest): (O(1)) - Constant: Fastest; performance is independent of input size. (O(\log n)) - Logarithmic: Very fast, typical for binary searches. (O(n)) - Linear: Efficient, grows proportionally to input. (O(n\log n)) - Linearithmic: Common for efficient sorting, like QuickSort. (O(n^{2})) - Quadratic: Acceptable for small input, common in nested loops. (O(2^{n})) or (O(n!)) - Exponential/Factorial: Generally only acceptable for very small inputs. 2.1. Constant Time - (O(1)) It takes the same amount of time regardless[rɪˈɡɑːrd.ləs] of input size. 2.2 Linear Time - (O(n)) [ˈlɪn.i.ɚ] ...

January 27, 2026 · 3 min · Phong Nguyen