Two traffic-light lessons, compared
You gave Codex and me the same brief: 20261019_exercise.md, byte-for-byte identical in both
directories. It asks for a breadboard/ site whose first lesson is the 4017 + OR-gate traffic light, in
15 sections, in English and Russian. This page reviews everything in
lssk_codex/breadboard and compares it with my
breadboard/m11_traffic_light.
- I ran Codex's own scripts myself, on copies: Icarus 12, Icarus 14, Verilator 5.053, licensed Questa 2025.2 and Yosys 0.69.
- I put the same 12 bugs into both designs.
- I list my own weak points next to Codex's.
Codex was still editing while I worked. Its README, pages and Questa notes changed at 13:21–13:22; its HDL has not
changed since 07:30. This review is of a snapshot taken at 13:27 PDT on 21 October. I changed nothing in
lssk_codex.
The rules were not the same for both of us. Codex got yuri_rules_3.txt, with eight rules. I got
yuri_rules_4.txt, which has two of them plus "Asynchronous reset is also OK". The style
section checks both sites against all of the rules.
timeunit in every RTL file: Yosys 0.69 read_verilog -sv fails on line 15. Mine synthesizes.# 1, 2 × negedgeIn Codex's benches. Mine has neither: only the clock generator has a delay.Verdict
- Both sites are complete and work. Each has all 15 sections, English and Russian, three schematics, two equivalent designs, chip models, scripts for three simulators, and BGM and Tiny Tapeout wrappers. Codex's site is polished, carefully cross-checked and honest about what it did not test.
- Codex's verification is broader, and that is the main thing to take from it. It has a unit test for the chip models (all 256 input patterns of the OR chips, plus the 4017's CARRY and CLOCK INHIBIT) and a bench that simulates all three wrappers with both designs. Those benches catch three bugs that mine misses.
- The biggest technical problem is
timeunit 1ns; timeprecision 1ps;in every synthesizable file. Yosys's standard reader rejects them in the newest version here (0.69), not only in the "older 0.43" that Codex blames. BGM's Yosys flow and a Tiny Tapeout build would fail unless switched to Slang. BGM itself usestimeunitonly in testbenches (16 files, all of themtb.sv). - The testbenches keep the letter of rules_3 but not the BGM examples. They sample at the edge plus
# 1and drive inputs with blocking assignments in the middle of the cycle. That pattern then needs 19# 1delays and two negedge waits.- The negedge waits are not needed. Without them, Codex's main bench stops catching a design that counts on the falling edge, but a BGM-style rising-edge checker catches it with no negedge.
- Codex wrote that no deviation was required and did not write
need_to_deviate_from_style.html.
- Schematic 1 does not show what the brief asked for. The brief asked for flip-flops and gates; Codex draws the state register as a black box.
- Process notes leak into the student pages. Examples: the typo in "the prompt", the license failure inside Codex's sandbox, a page fetch that timed out. The pages also over-credit Timofei, and the footers say "Traffic-light idea: Timofei Nikiforov".
- My own gaps, all things Codex has:
- no unit test for the chip models;
- wrappers never simulated;
- no synthesis script;
- no time unit in
tb.sv; - bare
wiredeclarations; - no CSV or ZIP downloads.
What the tools say
| Check | Codex | Mine |
|---|---|---|
| Icarus 12.0 | PASS: all three benches, 285 checks in the main one | PASS: 82 checks |
| Icarus 14.0 devel | PASS: all three | PASS |
| Verilator 5.053, as each script runs it | PASS: all three, with --timing and without -Wall; the script turns off PINCONNECTEMPTY and DECLFILENAME | PASS with -Wall |
Verilator -Wall lint |
|
0 warnings. My unused outputs get named wires, and two lint_off lines carry a comment. |
| Questa 2025.2 with the license | PASS: all three benches, 0 errors and 0 warnings.
I ran Codex's 13:21 run_questa.sh from my shell. The page still tells students the simulation "is blocked". |
PASS: 0 errors, 0 warnings |
Yosys 0.69 read_verilog -sv, which BGM's Yosys flow uses | Parse error:
rtl/traffic_light.sv:15: ERROR: syntax error, unexpected TOK_TIME_SCALE. Yosys 0.43 gives the same error. |
OK:
|
| Yosys 0.69 + Slang | OK: both cores; the TT top is 81 cells | Not needed |
| Wiring check | Static checks:
|
Static checks:
RRRRYYGGGG. |
| Link check | 178 local links checked by its validate.py; I found no broken ones | Link and anchor checks clean |
Errors and wrong claims in Codex's site
Ranked by how much they would hurt a student or a teacher. "Evidence" is what I ran or read today.
| # | Severity | What | Evidence | Fix |
|---|---|---|---|---|
| 1 | high | timeunit/timeprecision in all 11 HDL files, synthesizable ones included. The TT
project.v, both cores, the chip models and both BGM wrappers fail to parse with Yosys's standard reader.
Codex says "the older local Yosys 0.43 built-in reader cannot parse"; the newest Yosys here fails the same way. |
|
Keep timeunit in testbenches only, as BGM does. The rule's own example was a testbench. |
| 2 | medium | Schematic 1 has no flip-flops and no gates for the state. It shows a "10-state cyclic FSM" box feeding three ORs. The brief asks for "gates, flip-flop and other elements in generic fashion". The generic RTL is a ring of ten flip-flops, and no drawing shows that ring. | images/logic_en.svg, whose caption says "the block defines behavior, not a storage encoding" |
Draw the register. Either draw ten flip-flops in a ring, or, like mine, the 4017's own 5-bit Johnson counter with a 10-gate decoder. |
| 3 | medium | The two negedge waits are called "necessary", and they are not. The style guide says "a posedge-only reset
check would not establish this behavior".
need_to_deviate_from_style.html was written. validation.json says
"style_deviation_required": false. |
Bug hunt: with the negedge block deleted, Codex's main bench misses "counts on the falling edge". My rising-edge checker catches it. | Use a BGM-style checker in always @ (posedge clk). It samples the values of the cycle that just ended. |
| 4 | medium | Timofei is credited too often, and as the originator.
|
Visible text: title, h1, table of contents, section 1 heading, section 1 text, footer. The index page has 2 more. | Drop the footer credit and the name in module names and paths. Keep one factual mention of where the circuit was described. |
| 5 | low–medium | The Questa status on the page is wrong for this machine. Section 11 says: "Runtime blocked here: FlexNet sees an empty host ID and Questa reports Invalid host." That is true inside Codex's sandbox only. The README says the same. | Codex's own updated run_questa.sh, run from a normal shell, passes all three benches |
Report the real result, or leave sandbox details out of student pages. |
| 6 | low–medium | The lesson disagrees with Codex's own exercise list and kits. exercises.html calls the exercise
P11 and uses the 5 V traffic-light module (LSSK row 64). The lesson is BB-FSM-01 and uses three separate
5 V LEDs (rows 46–48). The sheet itself notes that those three LEDs are "not really needed". |
lssk_codex/exercises.html, P11 entry |
Use the list's ID and its traffic-light module. One module GND lead replaces the three LED cathode jumpers. |
| 7 | low | The power module is drawn off the board, with "two supply leads" to LP01 and LM01. The part in row 56 is a breadboard power module that plugs straight into the rails. So two wires are extra, and the picture differs from the getting-started guide. | Codex's parts table, the text under schematic 3, and row 56 of its saved sheet rows | Plug the module into the rails at the end of the board. |
| 8 | low | Rail coordinates such as LP25 and RM08 are invented. Real boards print no hole numbers on the rails. The split between holes 25 and 26 is an assumption; the text admits it. | Section 7 and jumpers.csv |
Refer to rails by the printed column numbers, the way my checklist does: "top + rail, column 12". |
| 9 | low | A wrong reason for leaving out `default_nettype none. The guide says "Questa rejects their implicit
net types". Every tool must reject ports without a net type; that is what the directive is for.
project.v also drops the TT template's `default_nettype none and its
input wire header, which the brief quoted. |
Style guide §16 and integration/tinytapeout/project.v |
Keep the TT template header as given. |
| 10 | low | The Verilator check is weaker than it looks. The script runs without -Wall and turns off two
warnings, while the page says only "All three testbenches pass". |
See "What the tools say" above | Use named unused wires and -Wall. |
Questionable design choices
- The generic design is a one-hot ring of ten flip-flops. The ring is a valid RTL idiom. But the 4017 has five flip-flops inside, a Johnson counter, so the lesson misses the chance to show what is in the chip. The ring also has no self-correction. Codex's 4017 model is a binary counter, so the three encodings in the lesson are all different (one-hot RTL, binary model, Johnson chip).
- Benches stop at the first mismatch with
$fatal, print no per-cycle trace and have nofinalsummary. A student sees either one PASS line or one error message. The BGM examples count errors and summarize them infinal; mine also prints a table, one line per cycle. - Lots of disclaimers in student text. Examples: "No physical circuit has been tested", "not the HDL simulator or an electrical model", "Parts descriptions alone do not establish module electrical specifications". They are honest, but they belong in the README, not in a lesson for 15-year-olds.
- The ZIP (2.2 MB) ships
research/: 33 logs, JSON records and a copy of your rules file. - The TT outputs are gated with
ena. This is harmless but unnecessary: Tiny Tapeout's docs sayenacan be ignored. - Two wrapper parameters,
CHIP_MODELandUSE_CHIP_MODEL, each select the design with agenerate if. This is fine, but the two wrappers name the parameter differently.
Testbench and HDL style against your rules
Rules marked rules_3 only were given to Codex and not to me. I check my code against them as well, because you may want them applied to both sites.
| Rule | Codex | Mine |
|---|---|---|
No # delay unless necessary both |
19 sites of # 1: 9 in tb_cmos, 6 in tb_integrations, 4 in
tb_traffic_light. Some sit in tasks that run hundreds of times. |
Only # 5 in the clock generator |
| No negedge unless you have to both | 2 sites, both avoidable (finding 3) | None |
| Follow the BGM examples both | No always @ (posedge clk) checker, no was_reset, no final.
Stimulus uses blocking assignments in the middle of the cycle, with no <= anywhere. |
Checker at the rising edge, was_reset, summary in final. Stimulus uses
<= after @ (posedge clk). |
Report deviations in need_to_deviate_from_style.html both |
Not written. The exceptions are explained in the style guide instead. | No deviations |
New SystemVerilog time syntax, not `timescale rules_3 only |
Done, but in every file, which breaks synthesis (finding 1) | No time unit at all, so units depend on the simulator: Verilator reports
$finish at 445ps, while Icarus uses its own default. Adding timeunit to tb.sv only would fix it. |
wire only for wire a = …; rules_3 only |
Followed | Three places don't follow it:
|
Align = rules_3 only | Mostly | Yes |
Clock in its own always # (period / 2) rules_3 only |
Yes. Verilator -Wall flags it as PROCASSINIT. |
The clock has its own initial … forever block, as in the BGM examples, but not this exact form. |
Tasks without Verilog-95 begin/end rules_3 only | Yes | No tasks |
| Timeouts in clock cycles rules_3 only | 500, 500 and 200 cycles | No watchdog. The run has a fixed length, so it cannot hang, but a cycle watchdog costs three lines. |
Codex's style guide (22 rules, English and Russian, Markdown copies)
is a good idea, and it records the upstream commits it cites. Three of its rules contradict the evidence above:
§17 puts timeunit everywhere, §16 gives the wrong reason for default_nettype, and the section
"Why specific # 1 and negedge uses remain" says the negedge waits are necessary.
Bug hunt: the same 12 bugs in both designs
Each bug was put into a fresh copy and run with Icarus 12. "Caught" means the bench printed no PASS.
For Codex, "main without negedge" is tb_traffic_light.sv with its low-clock block deleted.
| Bug | Codex tb_cmos | Codex main | Codex integrations | Codex main without negedge | Mine |
|---|---|---|---|---|---|
| No bug (sanity) | pass | pass | pass | pass | pass |
| Generic design counts on the falling clock edge | missed | caught | missed | missed | caught |
| Generic design: synchronous reset | missed | caught | caught | caught | caught |
| Generic design: reset goes to state 1 | missed | caught | caught | caught | caught |
| Generic design: green misses state 6 | missed | caught | caught | caught | caught |
| Chips: a red OR input on Q4 instead of Q3 | missed | caught | caught | caught | caught |
| Chips: a green OR input left at GND | missed | caught | caught | caught | caught |
| 4017 model: synchronous reset | caught | caught | caught | caught | caught |
| 4017 model counts on the falling edge | caught | caught | missed | missed | caught |
| 4017 model ignores CLOCK INHIBIT | caught | missed | missed | missed | missed |
| 4017 model: CARRY high in counts 0–5 | caught | missed | missed | missed | missed |
| 4071 gate J is AND (Codex's yellow gate; unused in mine) | caught | caught | caught | caught | missed |
| 4071 gate K is AND (my yellow gate; unused in Codex's) | caught | missed | missed | missed | caught |
- Codex: 12 of 12 over three benches with 514 lines. Mine: 9 of 12 with one bench of 198 lines. The three I miss are in parts of the chips that my circuit does not use. Only a unit test of each chip model can catch those, and Codex has one.
- The negedge question. With the negedge block removed, Codex's main bench misses "counts on the falling edge",
in both the generic design and the 4017 model. My bench uses no negedge and no
# 1, and catches both. It samples at the rising edge, so it sees the cycle that just ended, as a flip-flop would.
Presentation and wording
What works well in Codex's site
- Clean layout: a dark header with three numbers (4/2/4, 3 chips, 10 states), a sticky table of contents, and each section in its own card. A print stylesheet is included.
- Every figure is an SVG file with SVG and PNG download links and alt text.
- Both pages set
langandhreflang, and the two languages link to each other. - Seven clean drawings. The state graph has the Moore outputs inside the nodes, and a second graph shows the one-hot codes. The pinouts are clear.
- The parts table links each part to its exact sheet row, for example
range=LSSK!A37:Q37, and comes with CSV files for parts and jumpers. - A small JavaScript stepper (Run 1 Hz, Step, Reset) shows the ten states and the lamps. It works offline.
- A troubleshooting table and "try next" tasks. One useful note: the source's "outputs 1–4, 5–6, 7–10" counts from one, while the datasheet says Q0–Q9.
What doesn't
- Notes meant for you appear on student pages:
- "the prompt's 'hackaton_top' omits an h", which also appears as a comment inside
hackathon_top.sv; - "The live Google sheet was unavailable during this update";
- "Icarus 13 … is not installed here";
- the FlexNet host-ID story;
- "fetch timed out; no technical claims rely on it";
- "the quotation in the assignment and archived text were used".
- "the prompt's 'hackaton_top' omits an h", which also appears as a comment inside
- The breadboard drawing is hard to follow. Ten signal wires leave the board and loop around its left side. Labels cover row numbers and pin numbers, and the clock and reset modules are not drawn. A student needs the hole-by-hole table to build it, and that table is collapsed.
- The timing diagram is drawn by hand, not taken from the simulation. It has no reset trace. The clock starts high at t = 0, so the first counting edge is ambiguous.
- Code has no syntax highlighting and is collapsed. There is no dark mode.
- Calling the Habr article "Yuri Panchul's course" and listing it under "Course and the traffic-light exercise" is vague. The lesson number, 1.7, would help readers find it.
Russian page
The translation is complete and matches the English section by section. The problems are terminology and a few calques:
- «микросхемы CMOS» throughout; the page never uses «КМОП».
- «Сброс асинхронный, активный высокий» is a calque of "active high". A few lines later the page says «активен единицей», so the wording is also inconsistent.
- «Двухвходовый ИЛИ даёт 1» is missing a noun: «двухвходовый элемент ИЛИ».
- «даташит» is jargon in a school text. Use «техническое описание (datasheet)».
- «Сброс выбирает S0» is a calque. Use «сброс переводит автомат в S0».
- «выемкой вверх» is understandable, but «ключом вверх» is the usual term for the notch on a DIP package.
Ideas to adopt
From Codex into my lesson
I have not changed anything yet. Tell me which of these to do.
- A unit-test bench for the chip models, in the posedge style: every OR input pattern on every pin, plus the 4017's CARRY and CLOCK INHIBIT. CLOCK INHIBIT can be tested by driving CLOCK as data from the bench's clock. This closes the three bugs I miss.
- A simulation of the wrappers (
lab_top,hackathon_top,project.v) with both designs. I have never simulated mine. - A synthesis check script: Yosys
read_verilog -sv; synth; check -assert, run on the stock reader. - Parts linked to their sheet rows, while keeping my prices.
- CSV downloads for parts and wires, and a ZIP of the exercise without build logs.
- The note about counting from one ("outputs 1–4" are Q0–Q3).
- A troubleshooting table that maps each symptom to what to check.
- rules_3 items, if you want them in my code too:
timeunit 1ns; timeprecision 1ps;intb.svonly;logicfor DUT outputs and unused nets;- a watchdog counted in clock cycles.
- Optional: the small state stepper widget.
From my lesson into Codex's
- Schematic 1 with real flip-flops and gates. The Johnson counter and decoder are what is inside the 4017.
- A breadboard drawing that looks like the board, with the modules on it, plus a checklist with tick boxes.
- A waveform made from the simulation's VCD, so the picture and the testbench cannot disagree.
- A rising-edge checker with
was_resetandfinal, which removes all# 1delays and negedge waits. - RTL that the stock Yosys reader accepts, so BGM's Yosys flow and Tiny Tapeout work without Slang.
- The kit's traffic-light module and prices from the sheet.
- A clean
-Wallrun, syntax highlighting, copy buttons and dark mode.
The brief, item by item
| Brief item | Codex | Mine |
|---|---|---|
| 1 · ID, name, why it matters | BB-FSM-01, a new ID that is not the P11 in its own list. Good motivation and prerequisites. | M11, the ID from exercises.html |
| 2 · Key element, symbols, truth table, waveform | FSM graph, OR truth tables, hand-drawn timing, stepper widget | The 4017 explained, with a waveform from the simulation |
| 3 · Parts | Rows of the sheet with deep links and a CSV; no prices; three separate LEDs; 37 + 2 + 6 wires | Prices and suppliers; the traffic-light module; 24 + 10 wires; no CSV |
| 4 · Chips, pins, polarity | Three pin tables and a pinout drawing. The CLOCK INHIBIT detail cites Nexperia. | A pinout and table for each chip |
| 5 · Schematic 1: flip-flops and gates | A black box and three ORs | 5 flip-flops, 10 ANDs and 3 ORs |
| 6 · Schematic 2: chip connections | Clean pin-level block diagram | Chip-level schematic |
| 7 · Schematic 3: breadboard | Hole map with all 37 jumpers; dense and abstract; the CSV and table are exact | Picture of the board with the modules, build steps and a checklist with tick boxes |
| 8 · Generic SystemVerilog | A one-hot ring of ten flip-flops | A Johnson counter and decoder, matching schematic 1 and the 4017 |
| 9 · Chip models | Ports named after pins (p14_clock); marked synthesizable | Datasheet names, with the pin number in a comment; marked synthesizable |
| 10 · Chip-level SystemVerilog | Generated from the pin and net database | Generated from the checked wire list |
| 11 · Testbench for Icarus, Questa and Verilator | Three benches; scripts that accept tool paths from environment variables. The page says Questa cannot run, but it can. | One bench, three scripts and a clean script; all three simulators run |
12 · BGM lab_top | Full interface, LEDs and LCD colour, reset on key[0], a staging script | LEDs show a running state, the 7-segment display shows the light |
13 · BGM hackathon_top | Fills the LCD with the current colour | Draws a traffic light on the LCD |
14 · Tiny Tapeout project.v | Uses clock_hz: 1 with no divider. A DIP switch selects bars or the state digit, and the lamps also go to uio. Needs Slang to synthesize. | Uses clock_hz: 1 with no divider. Bars on the display; stock Yosys works; a comment says to rename the module. |
| 15 · Other | Bring-up steps, a troubleshooting table, "try next" tasks and sources | Tasks including a clock enable, and related designs |
| Site: list page, English and Russian, linked | Yes, plus a style guide | Yes |
How this was checked
- Snapshot.
lssk_codex/breadboardwas copied at 13:27 PDT. I diffed the HDL against the copy I ran earlier, and all nine files were unchanged. Every run used copies in my scratch directory; nothing was written tolssk_codex. - Simulation. I ran Codex's
scripts/run.sh:- with Icarus 12.0 from
/usr/bin, and Icarus 14.0 devel and Verilator 5.053 from~/oss-cad-suite; - with Questa Altera Starter FPGA Edition 2025.2, using
SALT_LICENSE_SERVER=~/flexlm/license.dat; - and Codex's 13:21
run_questa.shon its own.
verilator --lint-only -Wallon the same file sets. - with Icarus 12.0 from
- Synthesis. Yosys 0.69+24 with
read_verilog -sv … ; synth -top … -flatten; check -assert; stat, then the same with-m slangandread_slang. I also tried Yosys 0.43 from/usr/bin. - Bugs. A script put each of the 12 bugs above into fresh copies of both projects and ran every bench with Icarus 12. For the "without negedge" column, the low-clock block was removed from Codex's main bench with a regular expression.
- BGM facts come from the local clone at commit
3b18fdba:- all 63
slow_clk_geninstances useslow_clk_hz (1); timeunitappears only in testbenches;- the Yosys flow uses
read_verilog -sv; - the pow_5 bench and the FIFO's
fifo_monitor.svusewas_reset; - the pow_5 bench and the microarchitecture-challenge
testbench.svend withfinal.
- all 63
- Text, wiring and counts. I read both of Codex's lesson pages, both list pages, the style guide, the README, the
tools and the
research/records. I checked every pin of the three pin tables and all 37 jumpers against the CD4017B, CD4071B and CD4072B pinouts. The Timofei counts come from the HTML, with text and<pre>blocks counted separately.