Skip to content

Instantly share code, notes, and snippets.

@NSG650
Created July 16, 2025 14:32
Show Gist options
  • Save NSG650/7ce8f256510ef8cb9a3acd3f961f8d0f to your computer and use it in GitHub Desktop.
Save NSG650/7ce8f256510ef8cb9a3acd3f961f8d0f to your computer and use it in GitHub Desktop.
Brainfuck implementation in Verilog
module bf;
reg [7:0] mem [0:255];
reg [7:0] mp = 0;
reg [2:0] code [0:255];
reg [7:0] ip = 0;
reg [7:0] stack [0:255];
reg [7:0] sp = 0;
reg [2:0] state = 0;
reg clk = 0;
reg [7:0] next = 0;
reg [2:0] opcode = 0;
integer STDOUT = 32'h8000_0001;
always @(posedge clk) begin
case (state)
0: begin // fetch
opcode = code[ip];
state <= 1;
end
1: begin // decode + execute
if (next) begin
if (opcode == 3'b110) next++; // [
if (opcode == 3'b111) next--; // ]
end
else case(opcode)
3'b010: $fwrite(STDOUT, "%c", mem[mp]); // .
3'b100: mp++; // >
3'b101: mp--; // <
3'b110: begin // [
if (mem[mp] == 0) begin
next = 1;
end else begin
stack[sp] = ip;
sp++;
end
end
3'b111: begin // ]
if (mem[mp] != 0) begin
ip = stack[sp - 1];
end else begin
sp--;
end
end
endcase
state <= 2;
end
2: begin // write back
case (opcode)
3'b000: mem[mp]++; // +
3'b001: mem[mp]--; // -
3'b011: mem[mp] = 0; // , (I don't know how to get input from stdin in verilog lol)
endcase
state <= 3;
end
3: begin
ip++;
state <= 0;
if (ip == 0) $finish;
end
endcase
end
integer i;
initial begin
for (i = 0; i < 255; i++) mem[i] = 0;
for (i = 0; i < 255; i++) code[i] = 0;
for (i = 0; i < 255; i++) stack[i] = 0;
$readmemh("program.hex", code);
end
always #1 clk = ~clk;
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment