silica-eda 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. silica_eda-0.1.0/.claude/settings.local.json +23 -0
  2. silica_eda-0.1.0/.gitignore +45 -0
  3. silica_eda-0.1.0/PKG-INFO +237 -0
  4. silica_eda-0.1.0/README.md +216 -0
  5. silica_eda-0.1.0/examples/uart/uart_tx.sv +97 -0
  6. silica_eda-0.1.0/examples/uart/uart_tx_tb.sv +165 -0
  7. silica_eda-0.1.0/pyproject.toml +45 -0
  8. silica_eda-0.1.0/silica/__init__.py +1 -0
  9. silica_eda-0.1.0/silica/adapters/__init__.py +0 -0
  10. silica_eda-0.1.0/silica/adapters/_hints.py +62 -0
  11. silica_eda-0.1.0/silica/adapters/icarus.py +140 -0
  12. silica_eda-0.1.0/silica/adapters/sby.py +193 -0
  13. silica_eda-0.1.0/silica/adapters/verible.py +69 -0
  14. silica_eda-0.1.0/silica/adapters/verilator.py +177 -0
  15. silica_eda-0.1.0/silica/adapters/yosys.py +146 -0
  16. silica_eda-0.1.0/silica/cli.py +19 -0
  17. silica_eda-0.1.0/silica/clients_registry.py +105 -0
  18. silica_eda-0.1.0/silica/config.py +40 -0
  19. silica_eda-0.1.0/silica/server.py +53 -0
  20. silica_eda-0.1.0/silica/setup.py +529 -0
  21. silica_eda-0.1.0/silica/skills/README.md +34 -0
  22. silica_eda-0.1.0/silica/skills/base/rtl_assistant.md +76 -0
  23. silica_eda-0.1.0/silica/skills/workflows/debug_simulation_failure.md +193 -0
  24. silica_eda-0.1.0/silica/terminal.py +30 -0
  25. silica_eda-0.1.0/silica/tools/__init__.py +0 -0
  26. silica_eda-0.1.0/silica/tools/_config_dispatch.py +67 -0
  27. silica_eda-0.1.0/silica/tools/formal.py +81 -0
  28. silica_eda-0.1.0/silica/tools/lint.py +68 -0
  29. silica_eda-0.1.0/silica/tools/project.py +205 -0
  30. silica_eda-0.1.0/silica/tools/simulation.py +81 -0
  31. silica_eda-0.1.0/silica/tools/synthesis.py +55 -0
  32. silica_eda-0.1.0/silica/tools/waveform.py +59 -0
  33. silica_eda-0.1.0/silica/tools_registry.py +173 -0
  34. silica_eda-0.1.0/uv.lock +833 -0
@@ -0,0 +1,23 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(/Users/simaanc/Developer/silica/.venv/bin/python --version)",
5
+ "Bash(/Users/simaanc/Developer/silica/.venv/bin/pip show *)",
6
+ "Bash(.venv/bin/pip install *)",
7
+ "Bash(uv add *)",
8
+ "Bash(uv sync *)",
9
+ "Bash(.venv/bin/silica config *)",
10
+ "Bash(.venv/bin/python *)",
11
+ "Bash(.venv/bin/silica unknown_cmd)",
12
+ "Bash(echo \"exit: $?\")",
13
+ "Bash(git add *)",
14
+ "Bash(git commit -m 'feat: add silica setup wizard and silica config status viewer *)",
15
+ "Bash(git commit *)",
16
+ "Bash(verilator *)",
17
+ "Bash(sby --help)",
18
+ "Bash(cat)",
19
+ "Bash(sby -f -t test.sby)",
20
+ "Bash(brew list *)"
21
+ ]
22
+ }
23
+ }
@@ -0,0 +1,45 @@
1
+ # Python bytecode
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyd
5
+ .Python
6
+
7
+ # Distribution / packaging
8
+ build/
9
+ dist/
10
+ *.egg-info/
11
+ *.egg
12
+ .eggs/
13
+ MANIFEST
14
+
15
+ # Virtual environments
16
+ .env
17
+ .venv
18
+ env/
19
+ venv/
20
+ ENV/
21
+
22
+ # Testing and analysis caches
23
+ .pytest_cache/
24
+ .mypy_cache/
25
+ .ruff_cache/
26
+ .coverage
27
+ coverage.xml
28
+ htmlcov/
29
+
30
+ # Type checkers
31
+ .dmypy.json
32
+ dmypy.json
33
+
34
+ # Editors and OS
35
+ .DS_Store
36
+ .idea/
37
+ .vscode/
38
+ *.swp
39
+ *.swo
40
+ *~
41
+
42
+ # Project-specific
43
+ *.vcd
44
+ obj_dir/
45
+ HANDOFF.md
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: silica-eda
3
+ Version: 0.1.0
4
+ Summary: AI-native EDA environment — MCP server for hardware design and verification
5
+ Author-email: Christopher Simaan <dev@getsilica.dev>
6
+ License: MIT
7
+ Keywords: ai,eda,fpga,hardware,mcp,rtl,systemverilog,verilog
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Requires-Python: >=3.11
14
+ Requires-Dist: mcp<2.0.0,>=1.9.0
15
+ Requires-Dist: tomli-w>=1.0.0
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
18
+ Requires-Dist: pytest>=8.0; extra == 'dev'
19
+ Requires-Dist: ruff>=0.4; extra == 'dev'
20
+ Description-Content-Type: text/markdown
21
+
22
+ # Silica
23
+
24
+ AI-native EDA environment — an MCP server that gives any LLM deep integration with the full EDA toolchain: simulation, synthesis, linting, formal verification, and autonomous debug loops.
25
+
26
+ ## What it does
27
+
28
+ Silica wraps open source EDA tools (Verilator, Yosys, Verible, Icarus) in a structured MCP interface. You describe what you want to the model; Silica gives it the tool access and reasoning skills to find and fix RTL bugs, synthesize designs, and run verification workflows autonomously.
29
+
30
+ The core value: **closed autonomous loops**. Run sim → parse failure → reason about RTL → propose fix → re-run — without human copy-paste.
31
+
32
+ ## Quick start
33
+
34
+ ### 1. Install Silica
35
+
36
+ ```bash
37
+ pip install silica-eda
38
+ ```
39
+
40
+ ### 2. Run the setup wizard
41
+
42
+ ```bash
43
+ silica setup
44
+ ```
45
+
46
+ The wizard detects which MCP clients and EDA tools you already have installed, lets you choose what to enable, and writes the MCP client config for you. It covers Claude Desktop, Claude Code, Cursor, Zed, Windsurf, OpenCode, and Gemini CLI.
47
+
48
+ When it's done, check your config anytime with:
49
+
50
+ ```bash
51
+ silica config
52
+ ```
53
+
54
+ ### 3. Install missing tools (if any)
55
+
56
+ The wizard prints install commands for any open source tools you selected but don't have yet. For example on macOS:
57
+
58
+ ```bash
59
+ brew install verilator yosys icarus-verilog verible
60
+ ```
61
+
62
+ **Ubuntu / Debian**
63
+ ```bash
64
+ sudo apt update && sudo apt install verilator yosys iverilog
65
+ # Verible: sudo apt install verible (Ubuntu 22.04+)
66
+ # or grab the release binary: https://github.com/chipsalliance/verible/releases
67
+ ```
68
+
69
+ **Fedora / RHEL**
70
+ ```bash
71
+ sudo dnf install verilator yosys iverilog
72
+ ```
73
+
74
+ **Arch**
75
+ ```bash
76
+ sudo pacman -S verilator yosys iverilog verible
77
+ ```
78
+
79
+ **Windows**
80
+ WSL2 is the recommended path:
81
+ ```powershell
82
+ wsl --install # installs Ubuntu by default
83
+ ```
84
+ Then follow the Ubuntu instructions above inside WSL. Claude Desktop and Cursor both support MCP servers running inside WSL via the `wsl -e silica serve` command pattern.
85
+
86
+ ### 4. Start the server
87
+
88
+ ```bash
89
+ silica serve
90
+ ```
91
+
92
+ Your MCP client will launch this automatically — you typically don't need to run it manually.
93
+
94
+ ### 5. Test the UART example
95
+
96
+ Ask Claude:
97
+
98
+ > Run the UART TX simulation in examples/uart/ and tell me if it passes.
99
+
100
+ Or introduce a bug and ask Claude to find and fix it autonomously:
101
+
102
+ > In examples/uart/uart_tx.sv, change line 54 to use `==` instead of `== CLKS_PER_BIT - 1` for the baud counter comparison. Then run the simulation, find the bug, and fix it.
103
+
104
+ ## Manual client setup
105
+
106
+ If you prefer to configure your MCP client by hand instead of using `silica setup`:
107
+
108
+ **Claude Desktop** — `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `~/.config/Claude/claude_desktop_config.json` (Linux):
109
+
110
+ ```json
111
+ {
112
+ "mcpServers": {
113
+ "silica": {
114
+ "command": "silica",
115
+ "args": ["serve"]
116
+ }
117
+ }
118
+ }
119
+ ```
120
+
121
+ **Claude Code**
122
+ ```bash
123
+ claude mcp add silica silica serve
124
+ ```
125
+
126
+ **Cursor** — `~/.cursor/mcp.json`:
127
+ ```json
128
+ {
129
+ "mcpServers": {
130
+ "silica": {
131
+ "command": "silica",
132
+ "args": ["serve"]
133
+ }
134
+ }
135
+ }
136
+ ```
137
+
138
+ **Windows (WSL2)**
139
+ ```json
140
+ {
141
+ "mcpServers": {
142
+ "silica": {
143
+ "command": "wsl",
144
+ "args": ["-e", "silica", "serve"]
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ ## CLI reference
151
+
152
+ | Command | Description |
153
+ |---|---|
154
+ | `silica serve` | Start the MCP server (stdio transport). Default if no subcommand given. |
155
+ | `silica setup` | Interactive first-run configuration wizard. |
156
+ | `silica config` | Show current configuration and live tool status. |
157
+
158
+ ## MCP Tools (v0.1)
159
+
160
+ | Tool | Description |
161
+ |---|---|
162
+ | `run_simulation` | Simulate RTL (Verilator / Icarus). Returns structured errors. |
163
+ | `synthesize` | Synthesize to gates (Yosys). Returns utilization. |
164
+ | `lint` | Static analysis (Verible / Verilator). Returns structured warnings. |
165
+ | `read_rtl` | Read source file with line numbers. |
166
+ | `write_rtl` | Propose RTL changes — always dry_run=True before writing. |
167
+ | `get_project_structure` | Scan for RTL and constraint files. |
168
+ | `search_rtl` | Grep across project RTL with context. |
169
+ | `get_constraints` | Read constraint files (.xdc, .sdc, .lpf). |
170
+
171
+ ## Workflow Skills
172
+
173
+ Silica ships reasoning scripts that teach the model how to interpret tool output and form hypotheses — not just how to call tools. Available as MCP prompts:
174
+
175
+ - `debug_simulation_failure` — step-by-step triage from error list to verified fix
176
+ - `write_testbench` — generate a complete testbench from a module interface
177
+ - `generate_assertions` — write SVA assertions from design intent
178
+ - `close_timing` — work through timing violations with synthesis feedback
179
+
180
+ ## Architecture
181
+
182
+ ```
183
+ silica/
184
+ ├── silica/
185
+ │ ├── server.py # FastMCP server; loads skills at boot
186
+ │ ├── cli.py # subcommand dispatch (serve / setup / config)
187
+ │ ├── tools_registry.py # canonical list of all supported EDA tools
188
+ │ ├── clients_registry.py # canonical list of all supported MCP clients
189
+ │ ├── terminal.py # OSC 8 hyperlink support
190
+ │ ├── config.py # ~/.silica/config.toml load/save
191
+ │ ├── setup.py # interactive setup wizard + config viewer
192
+ │ ├── tools/ # MCP tool definitions
193
+ │ │ ├── simulation.py # run_simulation()
194
+ │ │ ├── synthesis.py # synthesize()
195
+ │ │ ├── lint.py # lint()
196
+ │ │ └── project.py # read_rtl(), write_rtl(), get_project_structure(), ...
197
+ │ ├── adapters/ # per-tool CLI wrappers + output parsers
198
+ │ │ ├── verilator.py
199
+ │ │ ├── icarus.py
200
+ │ │ ├── yosys.py
201
+ │ │ └── verible.py
202
+ │ └── skills/
203
+ │ ├── base/rtl_assistant.md
204
+ │ └── workflows/
205
+ │ └── debug_simulation_failure.md
206
+ └── examples/
207
+ └── uart/ # reference design for end-to-end testing
208
+ ```
209
+
210
+ ## Toolchain coverage (v0.1)
211
+
212
+ | Category | Open source | Commercial (detected if on PATH) |
213
+ |---|---|---|
214
+ | Simulation | Verilator, Icarus Verilog | VCS (Synopsys), Questa (Siemens), Xcelium (Cadence) |
215
+ | Synthesis | Yosys | Vivado (AMD/Xilinx), Quartus (Intel), DC Shell (Synopsys) |
216
+ | Formal | SymbiYosys | JasperGold (Cadence), VC Formal (Synopsys) |
217
+ | Lint | Verible, svlint | SpyGlass (Synopsys) |
218
+ | Waveform | GTKWave, Surfer | Verdi (Synopsys) |
219
+
220
+ ## Development
221
+
222
+ ```bash
223
+ git clone https://github.com/getsilica/silica
224
+ cd silica
225
+ pip install -e ".[dev]"
226
+
227
+ # Run the server locally (for debugging)
228
+ silica serve
229
+
230
+ # Run the UART end-to-end test
231
+ iverilog -g2012 -o /tmp/uart_sim examples/uart/uart_tx_tb.sv examples/uart/uart_tx.sv
232
+ vvp /tmp/uart_sim
233
+ ```
234
+
235
+ ## License
236
+
237
+ MIT
@@ -0,0 +1,216 @@
1
+ # Silica
2
+
3
+ AI-native EDA environment — an MCP server that gives any LLM deep integration with the full EDA toolchain: simulation, synthesis, linting, formal verification, and autonomous debug loops.
4
+
5
+ ## What it does
6
+
7
+ Silica wraps open source EDA tools (Verilator, Yosys, Verible, Icarus) in a structured MCP interface. You describe what you want to the model; Silica gives it the tool access and reasoning skills to find and fix RTL bugs, synthesize designs, and run verification workflows autonomously.
8
+
9
+ The core value: **closed autonomous loops**. Run sim → parse failure → reason about RTL → propose fix → re-run — without human copy-paste.
10
+
11
+ ## Quick start
12
+
13
+ ### 1. Install Silica
14
+
15
+ ```bash
16
+ pip install silica-eda
17
+ ```
18
+
19
+ ### 2. Run the setup wizard
20
+
21
+ ```bash
22
+ silica setup
23
+ ```
24
+
25
+ The wizard detects which MCP clients and EDA tools you already have installed, lets you choose what to enable, and writes the MCP client config for you. It covers Claude Desktop, Claude Code, Cursor, Zed, Windsurf, OpenCode, and Gemini CLI.
26
+
27
+ When it's done, check your config anytime with:
28
+
29
+ ```bash
30
+ silica config
31
+ ```
32
+
33
+ ### 3. Install missing tools (if any)
34
+
35
+ The wizard prints install commands for any open source tools you selected but don't have yet. For example on macOS:
36
+
37
+ ```bash
38
+ brew install verilator yosys icarus-verilog verible
39
+ ```
40
+
41
+ **Ubuntu / Debian**
42
+ ```bash
43
+ sudo apt update && sudo apt install verilator yosys iverilog
44
+ # Verible: sudo apt install verible (Ubuntu 22.04+)
45
+ # or grab the release binary: https://github.com/chipsalliance/verible/releases
46
+ ```
47
+
48
+ **Fedora / RHEL**
49
+ ```bash
50
+ sudo dnf install verilator yosys iverilog
51
+ ```
52
+
53
+ **Arch**
54
+ ```bash
55
+ sudo pacman -S verilator yosys iverilog verible
56
+ ```
57
+
58
+ **Windows**
59
+ WSL2 is the recommended path:
60
+ ```powershell
61
+ wsl --install # installs Ubuntu by default
62
+ ```
63
+ Then follow the Ubuntu instructions above inside WSL. Claude Desktop and Cursor both support MCP servers running inside WSL via the `wsl -e silica serve` command pattern.
64
+
65
+ ### 4. Start the server
66
+
67
+ ```bash
68
+ silica serve
69
+ ```
70
+
71
+ Your MCP client will launch this automatically — you typically don't need to run it manually.
72
+
73
+ ### 5. Test the UART example
74
+
75
+ Ask Claude:
76
+
77
+ > Run the UART TX simulation in examples/uart/ and tell me if it passes.
78
+
79
+ Or introduce a bug and ask Claude to find and fix it autonomously:
80
+
81
+ > In examples/uart/uart_tx.sv, change line 54 to use `==` instead of `== CLKS_PER_BIT - 1` for the baud counter comparison. Then run the simulation, find the bug, and fix it.
82
+
83
+ ## Manual client setup
84
+
85
+ If you prefer to configure your MCP client by hand instead of using `silica setup`:
86
+
87
+ **Claude Desktop** — `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `~/.config/Claude/claude_desktop_config.json` (Linux):
88
+
89
+ ```json
90
+ {
91
+ "mcpServers": {
92
+ "silica": {
93
+ "command": "silica",
94
+ "args": ["serve"]
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ **Claude Code**
101
+ ```bash
102
+ claude mcp add silica silica serve
103
+ ```
104
+
105
+ **Cursor** — `~/.cursor/mcp.json`:
106
+ ```json
107
+ {
108
+ "mcpServers": {
109
+ "silica": {
110
+ "command": "silica",
111
+ "args": ["serve"]
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ **Windows (WSL2)**
118
+ ```json
119
+ {
120
+ "mcpServers": {
121
+ "silica": {
122
+ "command": "wsl",
123
+ "args": ["-e", "silica", "serve"]
124
+ }
125
+ }
126
+ }
127
+ ```
128
+
129
+ ## CLI reference
130
+
131
+ | Command | Description |
132
+ |---|---|
133
+ | `silica serve` | Start the MCP server (stdio transport). Default if no subcommand given. |
134
+ | `silica setup` | Interactive first-run configuration wizard. |
135
+ | `silica config` | Show current configuration and live tool status. |
136
+
137
+ ## MCP Tools (v0.1)
138
+
139
+ | Tool | Description |
140
+ |---|---|
141
+ | `run_simulation` | Simulate RTL (Verilator / Icarus). Returns structured errors. |
142
+ | `synthesize` | Synthesize to gates (Yosys). Returns utilization. |
143
+ | `lint` | Static analysis (Verible / Verilator). Returns structured warnings. |
144
+ | `read_rtl` | Read source file with line numbers. |
145
+ | `write_rtl` | Propose RTL changes — always dry_run=True before writing. |
146
+ | `get_project_structure` | Scan for RTL and constraint files. |
147
+ | `search_rtl` | Grep across project RTL with context. |
148
+ | `get_constraints` | Read constraint files (.xdc, .sdc, .lpf). |
149
+
150
+ ## Workflow Skills
151
+
152
+ Silica ships reasoning scripts that teach the model how to interpret tool output and form hypotheses — not just how to call tools. Available as MCP prompts:
153
+
154
+ - `debug_simulation_failure` — step-by-step triage from error list to verified fix
155
+ - `write_testbench` — generate a complete testbench from a module interface
156
+ - `generate_assertions` — write SVA assertions from design intent
157
+ - `close_timing` — work through timing violations with synthesis feedback
158
+
159
+ ## Architecture
160
+
161
+ ```
162
+ silica/
163
+ ├── silica/
164
+ │ ├── server.py # FastMCP server; loads skills at boot
165
+ │ ├── cli.py # subcommand dispatch (serve / setup / config)
166
+ │ ├── tools_registry.py # canonical list of all supported EDA tools
167
+ │ ├── clients_registry.py # canonical list of all supported MCP clients
168
+ │ ├── terminal.py # OSC 8 hyperlink support
169
+ │ ├── config.py # ~/.silica/config.toml load/save
170
+ │ ├── setup.py # interactive setup wizard + config viewer
171
+ │ ├── tools/ # MCP tool definitions
172
+ │ │ ├── simulation.py # run_simulation()
173
+ │ │ ├── synthesis.py # synthesize()
174
+ │ │ ├── lint.py # lint()
175
+ │ │ └── project.py # read_rtl(), write_rtl(), get_project_structure(), ...
176
+ │ ├── adapters/ # per-tool CLI wrappers + output parsers
177
+ │ │ ├── verilator.py
178
+ │ │ ├── icarus.py
179
+ │ │ ├── yosys.py
180
+ │ │ └── verible.py
181
+ │ └── skills/
182
+ │ ├── base/rtl_assistant.md
183
+ │ └── workflows/
184
+ │ └── debug_simulation_failure.md
185
+ └── examples/
186
+ └── uart/ # reference design for end-to-end testing
187
+ ```
188
+
189
+ ## Toolchain coverage (v0.1)
190
+
191
+ | Category | Open source | Commercial (detected if on PATH) |
192
+ |---|---|---|
193
+ | Simulation | Verilator, Icarus Verilog | VCS (Synopsys), Questa (Siemens), Xcelium (Cadence) |
194
+ | Synthesis | Yosys | Vivado (AMD/Xilinx), Quartus (Intel), DC Shell (Synopsys) |
195
+ | Formal | SymbiYosys | JasperGold (Cadence), VC Formal (Synopsys) |
196
+ | Lint | Verible, svlint | SpyGlass (Synopsys) |
197
+ | Waveform | GTKWave, Surfer | Verdi (Synopsys) |
198
+
199
+ ## Development
200
+
201
+ ```bash
202
+ git clone https://github.com/getsilica/silica
203
+ cd silica
204
+ pip install -e ".[dev]"
205
+
206
+ # Run the server locally (for debugging)
207
+ silica serve
208
+
209
+ # Run the UART end-to-end test
210
+ iverilog -g2012 -o /tmp/uart_sim examples/uart/uart_tx_tb.sv examples/uart/uart_tx.sv
211
+ vvp /tmp/uart_sim
212
+ ```
213
+
214
+ ## License
215
+
216
+ MIT
@@ -0,0 +1,97 @@
1
+ // uart_tx.sv — UART transmitter, 8N1, synchronous design
2
+ //
3
+ // Interface:
4
+ // valid/ready handshake — assert valid with data_in; ready pulses high when
5
+ // the transmitter accepts the byte and begins transmission.
6
+ // tx idles HIGH; start bit is LOW.
7
+
8
+ `timescale 1ns/1ps
9
+
10
+ module uart_tx #(
11
+ parameter int CLK_FREQ = 50_000_000, // Hz
12
+ parameter int BAUD_RATE = 115_200 // bps
13
+ ) (
14
+ input logic clk,
15
+ input logic rst_n, // active-low async reset
16
+ input logic [7:0] data_in,
17
+ input logic valid,
18
+ output logic ready,
19
+ output logic tx
20
+ );
21
+
22
+ localparam int CLKS_PER_BIT = CLK_FREQ / BAUD_RATE; // 434 @ 50 MHz / 115200
23
+
24
+ typedef enum logic [1:0] {
25
+ IDLE = 2'b00,
26
+ START = 2'b01,
27
+ DATA = 2'b10,
28
+ STOP = 2'b11
29
+ } state_t;
30
+
31
+ state_t state;
32
+ logic [15:0] baud_cnt;
33
+ logic [2:0] bit_idx;
34
+ logic [7:0] shift_reg;
35
+
36
+ assign ready = (state == IDLE);
37
+
38
+ always_ff @(posedge clk or negedge rst_n) begin
39
+ if (!rst_n) begin
40
+ state <= IDLE;
41
+ baud_cnt <= '0;
42
+ bit_idx <= '0;
43
+ shift_reg <= '0;
44
+ tx <= 1'b1;
45
+ end else begin
46
+ case (state)
47
+ IDLE: begin
48
+ tx <= 1'b1;
49
+ if (valid) begin
50
+ state <= START;
51
+ shift_reg <= data_in;
52
+ baud_cnt <= '0;
53
+ end
54
+ end
55
+
56
+ START: begin
57
+ tx <= 1'b0;
58
+ if (baud_cnt == 16'(CLKS_PER_BIT - 1)) begin
59
+ state <= DATA;
60
+ baud_cnt <= '0;
61
+ bit_idx <= '0;
62
+ end else begin
63
+ baud_cnt <= baud_cnt + 1;
64
+ end
65
+ end
66
+
67
+ DATA: begin
68
+ tx <= shift_reg[0];
69
+ if (baud_cnt == 16'(CLKS_PER_BIT - 1)) begin
70
+ baud_cnt <= '0;
71
+ shift_reg <= {1'b0, shift_reg[7:1]};
72
+ if (bit_idx == 3'd7) begin
73
+ state <= STOP;
74
+ end else begin
75
+ bit_idx <= bit_idx + 1;
76
+ end
77
+ end else begin
78
+ baud_cnt <= baud_cnt + 1;
79
+ end
80
+ end
81
+
82
+ STOP: begin
83
+ tx <= 1'b1;
84
+ if (baud_cnt == 16'(CLKS_PER_BIT - 1)) begin
85
+ state <= IDLE;
86
+ baud_cnt <= '0;
87
+ end else begin
88
+ baud_cnt <= baud_cnt + 1;
89
+ end
90
+ end
91
+
92
+ default: state <= IDLE;
93
+ endcase
94
+ end
95
+ end
96
+
97
+ endmodule