For my TinyTapeout 4 personal project, I designed an ASIC Tamagotchi that lives on the chip. Given the limited space available, this Tamagotchi is simple but functional. It is also an excellent starting point for learning ASIC design and explores interesting concepts such as implementing UART serial communication and generating pseudo-random numbers, which I mentioned in a previous post.

About the Tamagotchi

The Tamagotchi design is very simple. It consists of a small memory that stores ASCII characters so the Tamagotchi can be rendered graphically in the serial console. It also includes state-machine-based control logic to show different animations that represent the Tamagotchi’s states. In addition, it has a sort of “needs bar” that shows hunger, sleep, and boredom. These needs increase over time and can be reduced by entering keyboard commands corresponding to each need. If any of these needs are not properly satisfied, the Tamagotchi will die and the chip will need to be reset before playing again, just like a real Tamagotchi.

Design

The heart of the Tamagotchi is largely the pseudo-random number generator. This is because it controls how and which of the Tamagotchi’s stats will increase in what appears to be a “random” way.

Despite its simplicity, this design covers a number of interesting concepts and functions that make the project valuable both educationally and functionally. In addition, the ASIC Tamagotchi on-chip is a creative and entertaining project that makes it possible to explore building an embedded system in a resource-constrained environment.

Pseudo-Random Number Generator

The pseudo-random number generator is an 8-bit Linear Feedback Shift Register (LFSR). An LFSR is a sequential circuit that generates a bit sequence that repeats after a certain number of clock cycles. The sequence produced by an LFSR looks random, but it is actually deterministic and periodic. The period length (the number of clock cycles before the sequence repeats) depends on how the LFSR is configured, specifically which bits are used for feedback.

module random(
    input wire clk,           // Clock input
    input wire rst,           // Reset input
    input wire [7:0] seed,    // 8-bit seed input
    output wire [7:0] rand_out // 8-bit pseudo-random number output
);

reg [7:0] lfsr_reg;          // 8-bit register to hold the LFSR state

always @(posedge clk or posedge rst) begin
    if (rst) begin
        lfsr_reg <= seed; // Initialize the LFSR with the seed
    end else begin
        // XOR feedback taps for an 8-bit LFSR: 8, 6, 5, 4
        lfsr_reg <= {lfsr_reg[6:0], lfsr_reg[7] ^ lfsr_reg[4] ^ lfsr_reg[5] ^ lfsr_reg[3]};
    end
end

assign rand_out = lfsr_reg;

endmodule

Character Memory

The character memory is an 8-bit ROM that stores ASCII characters so the Tamagotchi can be rendered graphically in the serial console. Since it is read-only, the characters are loaded into memory during synthesis. The character memory is implemented as an 8-bit read-only memory with 256 words, where each word is an 8-bit ASCII character. It is populated with the ASCII characters that represent the different Tamagotchi animations.

UART Serial Communication

UART serial communication is implemented through a finite state machine (FSM) that controls data transmission and reception. It uses as a base the transmission I implemented in a previous post.

Control Logic

The control logic is quite simple in concept: for each need, there is a register that decrements over time, and when the register reaches zero, the Tamagotchi dies. To prevent the register from reaching zero, you can enter a command from the keyboard that increases the register.