Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

HDL Copilot

A retrieval-augmented debugging assistant for FPGA/Verilog coursework — ask it about a symptom ("my grappler FSM never reaches GRAB", "TimeQuest reports failing paths I don't understand"), and it retrieves the relevant pattern from a curated knowledge base and grounds an LLM's answer in it, citing exactly which chunks it used.

It's built around a real case: a three-FSM robotic-arm controller (XY motion, extender, grappler) on a MAX10-class board, which is exactly the kind of design where state-encoding bugs, blocking/non-blocking races, and multi-module handshake mismatches actually show up.

Why this project

It's a small, complete slice of what a GenAI-adjacent engineering role actually looks like day to day:

  • Python + TypeScript/React — FastAPI backend, typed React frontend
  • LLM concepts — prompting (a grounding-constrained system prompt), RAG (retrieve → construct context → generate), and a documented vector-DB abstraction
  • Databases — SQL (SQLite) for relational entities, NoSQL (TinyDB) for irregularly-shaped chat logs — used deliberately for what each is good at, not just for résumé coverage
  • Modern dev workflow — Git, .env config, pytest, typed API client
  • GenAI tooling curiosity — built iteratively the way you'd actually use Cursor/Copilot-style tools: small modules, docstring-first, one concern per file

Architecture

┌─────────────┐      HTTP       ┌──────────────────┐
│ React + TS  │ ──────────────▶ │     FastAPI       │
│  (Vite)     │ ◀────────────── │                    │
└─────────────┘      JSON       │  ┌──────────────┐  │
                                 │  │ RAG pipeline │  │
                                 │  └──────┬───────┘  │
                                 │         │          │
                     ┌───────────┼─────────┼──────────┼───────────┐
                     ▼           ▼         ▼          ▼           │
              ┌───────────┐ ┌─────────┐ ┌────────┐ ┌───────────┐  │
              │  SQLite   │ │ TinyDB  │ │ TF-IDF │ │ Anthropic │  │
              │ sessions, │ │  chat   │ │ vector │ │  API /    │  │
              │ bug repts │ │ messages│ │ store  │ │  mock     │  │
              └───────────┘ └─────────┘ └────────┘ └───────────┘  │
                                                                    │
                     kb/*.md ──(ingest.py)──────────────────────────┘

Why TF-IDF instead of a hosted embedding model? The vector store (backend/app/vector_store.py) exposes the same add_documents() / query() interface a real client (Chroma, pgvector, Pinecone) would. TF-IDF

  • cosine similarity is a fully local, dependency-light substitute that lets the whole pipeline run offline with zero API keys — swapping in real embeddings later only touches that one file.

Why the LLM call has a mock fallback: backend/app/llm_client.py checks for ANTHROPIC_API_KEY. Without one, it falls back to a deterministic responder that still surfaces the retrieved KB chunk, so a reviewer cloning this repo sees the real retrieval quality without needing credentials.

Project structure

backend/
  app/
    main.py          FastAPI routes
    rag.py            retrieval + prompt construction
    vector_store.py    TF-IDF vector store (swappable interface)
    llm_client.py      Anthropic API wrapper + offline mock
    db.py              SQLite: sessions, bug_reports
    nosql_store.py      TinyDB: chat messages
    ingest.py          chunks kb/*.md into the vector index
  kb/                  knowledge base (Verilog/FPGA bug patterns)
  tests/               pytest suite
frontend/
  src/
    api/client.ts       typed fetch wrapper
    components/         Sidebar, ChatPanel, MessageBubble, SourcesPanel
    App.tsx

Running it

Backend

cd backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt --break-system-packages   # or without the flag in a venv
python -m app.ingest                # build the vector index from kb/
uvicorn app.main:app --reload --port 8000

Optionally copy .env.example to .env and set ANTHROPIC_API_KEY for live model responses instead of the offline mock.

Frontend

cd frontend
npm install
npm run dev

Visit the printed localhost URL. The frontend expects the API at http://localhost:8000 by default (override via VITE_API_URL).

Tests

cd backend
pytest tests/ -v

Design notes

The UI leans into the subject matter rather than a generic chat-app look — a dark PCB-substrate palette, copper/signal-cyan accents, and a literal digital-signal-trace divider used as both a section break and the "thinking" indicator while a query is in flight.

What I'd build next

  • Swap the TF-IDF store for real embeddings + pgvector once this needs to scale past a single course's worth of documents
  • Let students upload their own .v/.sdc files to grow the knowledge base per-course

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages