Skip to content

Commit c1993ea

Browse files
committed
feat: Initial version
0 parents  commit c1993ea

File tree

14 files changed

+628
-0
lines changed

14 files changed

+628
-0
lines changed

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.log
2+
.git
3+
.gitignore
4+
README.md

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Server port
2+
PORT=8080

.github/workflows/test.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Build and Test
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v4
16+
17+
- name: Build Docker container
18+
run: make docker-build
19+
20+
- name: Start container in background
21+
run: docker run -d -p 8080:8080 --name fpga-compiler fpga-compiler:latest
22+
23+
- name: Wait for service to be ready
24+
run: |
25+
timeout 30 bash -c 'until curl -f http://localhost:8080/health; do sleep 1; done'
26+
27+
- name: Run API test
28+
run: make test-api
29+
30+
- name: Show container logs
31+
if: always()
32+
run: docker logs fpga-compiler
33+
34+
- name: Stop container
35+
if: always()
36+
run: docker stop fpga-compiler && docker rm fpga-compiler

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.env

Dockerfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
FROM golang:1.25-alpine AS builder
2+
3+
WORKDIR /app
4+
5+
# Install build dependencies
6+
RUN apk add --no-cache git
7+
8+
# Copy go mod files
9+
COPY go.mod go.sum* ./
10+
RUN go mod download
11+
12+
# Copy source code
13+
COPY *.go ./
14+
15+
# Build the application
16+
RUN CGO_ENABLED=0 GOOS=linux go build -o /fpga-compiler .
17+
18+
# Final stage
19+
FROM alpine:3.23
20+
21+
# Install FPGA toolchain from edge repository
22+
RUN apk add --no-cache \
23+
--repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing \
24+
yosys \
25+
nextpnr-ice40 \
26+
icestorm
27+
28+
# Copy the binary from builder
29+
COPY --from=builder /fpga-compiler /usr/local/bin/fpga-compiler
30+
31+
# Create app directory for verilog files
32+
RUN mkdir -p /app/verilog
33+
WORKDIR /app
34+
35+
# Copy verilog files (these will be copied from the host)
36+
COPY verilog/ /app/verilog/
37+
38+
# Expose port
39+
EXPOSE 8080
40+
41+
# Run the application
42+
CMD ["fpga-compiler"]

LICENSE

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Copyright 2024 Tiny Tapeout LTD
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
15+
Note: the files under the [src/sim/spice](src/sim/spice/) directory are licensed under the MIT License.

Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.PHONY: build run docker-build docker-run docker-push clean test-api
2+
3+
build:
4+
go build -o fpga-compiler .
5+
6+
run:
7+
go run main.go
8+
9+
docker-build:
10+
docker build -t fpga-compiler:latest .
11+
12+
docker-run:
13+
docker run -p 8080:8080 --rm fpga-compiler:latest
14+
15+
docker-compose-up:
16+
docker-compose up --build
17+
18+
docker-compose-down:
19+
docker-compose down
20+
21+
clean:
22+
rm -f fpga-compiler
23+
docker-compose down -v
24+
25+
test-api:
26+
@echo "Testing API endpoint..."
27+
@curl -X POST http://localhost:8080/api/compile \
28+
-H "Content-Type: application/json" \
29+
-d '{"sources":{"project.v":"module tt_um_test(input clk, output led); reg r; always @(posedge clk) r <= ~r; assign led = r; endmodule"},"topModule":"tt_um_test"}'

README.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Tiny Tapeout FPGA Compilation Server
2+
3+
A lightweight Go server that compiles Verilog projects using Yosys and nextpnr-ice40, streaming output in real-time.
4+
5+
## Features
6+
7+
- Receives Verilog source files via HTTP POST
8+
- Compiles using Yosys + nextpnr-ice40 + icepack
9+
- Streams compilation output in real-time using Server-Sent Events (SSE)
10+
- Returns the compiled bitstream (.bin file) on success
11+
12+
## Quick Start
13+
14+
**Start the server:**
15+
```bash
16+
docker-compose up --build
17+
```
18+
19+
**Check health:**
20+
```bash
21+
curl http://localhost:8080/health
22+
```
23+
24+
**Test the API:**
25+
```bash
26+
make test-api
27+
```
28+
29+
You should see streaming output from yosys, nextpnr, and icepack!
30+
31+
**Stop the server:**
32+
```bash
33+
docker-compose down
34+
```
35+
36+
## Building
37+
38+
```bash
39+
docker build -t fpga-compiler .
40+
```
41+
42+
Or using docker-compose:
43+
44+
```bash
45+
docker-compose build
46+
```
47+
48+
## Running
49+
50+
```bash
51+
docker run -p 8080:8080 fpga-compiler
52+
```
53+
54+
Or using docker-compose:
55+
56+
```bash
57+
docker-compose up
58+
```
59+
60+
## API
61+
62+
### POST /api/compile
63+
64+
Compiles Verilog files and returns the bitstream.
65+
66+
**Request Body:**
67+
68+
```json
69+
{
70+
"sources": {
71+
"project.v": "module project_top(...); ... endmodule",
72+
"other.v": "module other(...); ... endmodule"
73+
},
74+
"topModule": "tt_um_project_name"
75+
}
76+
```
77+
78+
**Response:**
79+
80+
Server-Sent Events stream with JSON messages:
81+
82+
```json
83+
{"type": "command", "command": "yosys", "args": ["..."]}
84+
{"type": "stdout", "data": "Output text..."}
85+
{"type": "stderr", "data": "Error text..."}
86+
{"type": "success", "data": "base64:...bitstream data..."}
87+
{"type": "error", "message": "Error message"}
88+
```
89+
90+
### GET /health
91+
92+
Health check endpoint.
93+
94+
## Environment Variables
95+
96+
- `PORT` - Server port (default: 8080)
97+
98+
## Development
99+
100+
```bash
101+
# Install dependencies
102+
go mod download
103+
104+
# Run locally (requires yosys, nextpnr-ice40, icepack installed)
105+
go run main.go
106+
```

docker-compose.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
services:
2+
fpga-compiler:
3+
build:
4+
context: .
5+
dockerfile: Dockerfile
6+
ports:
7+
- "8080:8080"
8+
environment:
9+
- PORT=8080
10+
restart: unless-stopped
11+
healthcheck:
12+
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/health"]
13+
interval: 30s
14+
timeout: 10s
15+
retries: 3
16+
start_period: 40s

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/TinyTapeout/vga-playground/server
2+
3+
go 1.21
4+
5+
require github.com/google/uuid v1.6.0

0 commit comments

Comments
 (0)