diff --git a/CURRICULUM.md b/CURRICULUM.md index 66cf8e6..f72a3fd 100644 --- a/CURRICULUM.md +++ b/CURRICULUM.md @@ -68,20 +68,11 @@ Flag numbers identify the weak dimension(s): 1=Concept Focus, 2=Starter Calibrat > Ref: `DataTypes/DataTypes.sv`, `Arrays/PackedArrays.sv`, > `Arrays/Packed_UnpackedArrays.sv` -### Chapter: Interfaces & Procedures -| Slug | Title | Status | Score | Prereqs | Teaches | -|---|---|---|---|---|---| -| `sv/interfaces` | Interfaces | ✅ | 25/27 ⚠️2,9 | `sv/modules-and-ports`, `sv/parameters` | `interface`, signal bundling, interface functions (`sprint()`), dot-notation access | -| `sv/modports` | Modports | ✅ | 25/27 ⚠️2,9 | `sv/interfaces` | `modport` (initiator/target), direction enforcement, `virtual interface` for UVM | -| `sv/tasks-functions` | Tasks | ✅ | 24/27 ⚠️1,9 | `sv/interfaces`, `sv/parameters` | `task` (automatic, timing-aware), `function` (pure), driving DUT via virtual interface | -| `sv/clocking-blocks` | Clocking Blocks | 💡 | — | `sv/interfaces` | `clocking` block, input/output skew, synchronous testbench sampling | - ### Chapter: State Machines | Slug | Title | Status | Score | Prereqs | Teaches | |---|---|---|---|---|---| | `sv/enums` | typedef enum | ✅ | 24/27 ⚠️2,9 | `sv/always-ff`, `sv/always-comb` | `typedef enum`, named constants, enum-typed ports, enum in `case` | -| `sv/fsm` | Two-Always Moore FSM | ✅ | 27/27 | `sv/enums`, `sv/always-ff`, `sv/always-comb` | two-always Moore pattern (FF state + comb output), FSM-gated SRAM write/read | -| `sv/mealy-fsm` | Mealy FSM | 📝 | — | `sv/fsm` | Mealy output depends on current input, single-always style | +| `sv/mealy-fsm` | Mealy FSM | 📝 | — | `sv/enums` | Mealy output depends on current input, single-always style | > Moore-only leaves students unable to recognise the more common Mealy > pattern in real codebases. @@ -96,9 +87,9 @@ Flag numbers identify the weak dimension(s): 1=Concept Focus, 2=Starter Calibrat ### Chapter: Testbench Essentials | Slug | Title | Status | Score | Prereqs | Teaches | |---|---|---|---|---|---| -| `sv/classes` | Classes and Objects | ✅ | 27/27 | `sv/tasks-functions` | `class`/`endclass`, fields, `function new()`, `this.`, handle semantics, `convert2string` | +| `sv/classes` | Classes and Objects | ✅ | 27/27 | `sv/data-types` | `class`/`endclass`, fields, `function new()`, `this.`, handle semantics, `convert2string` | | `sv/queues-arrays` | Dynamic Arrays and Queues | ✅ | 27/27 | `sv/classes` | `type name[]`, `new[n]`, `.size()`, `type name[$]`, `push_back`, `pop_front` | -| `sv/fork-join` | Concurrent Processes: fork...join | ✅ | 27/27 | `sv/tasks-functions` | `fork...join`, `fork...join_any`, `fork...join_none`, `automatic` tasks | +| `sv/fork-join` | Concurrent Processes: fork...join | ✅ | 27/27 | `sv/events` | `fork...join`, `fork...join_any`, `fork...join_none`, `automatic` tasks | | `sv/randomization` | Constrained Randomization | ✅ | 27/27 | `sv/classes` | `rand`, `randomize()`, `constraint`, `inside`, inline `with {}`, `constraint_mode(0)` | --- @@ -197,59 +188,6 @@ Flag numbers identify the weak dimension(s): 1=Concept Focus, 2=Starter Calibrat --- -## Part 3 — Universal Verification Methodology - -### Chapter: UVM Foundations -| Slug | Title | Status | Score | Prereqs | Teaches | -|---|---|---|---|---|---| -| `uvm/reporting` | The First UVM Test | ✅ | 24/27 ⚠️4,9 | `sv/modules-and-ports`, `sv/interfaces` | `uvm_component`, `uvm_test`, `` `uvm_info/warning/error ``, severity levels, `build_phase`/`run_phase`, objections | -| `uvm/seq-item` | Sequence Items | ✅ | 24/27 ⚠️4,5,9 | `uvm/reporting`, `sv/packed-structs` | `uvm_sequence_item`, `` `uvm_object_utils ``, `rand` fields, constraints, `convert2string` | - -### Chapter: Stimulus -| Slug | Title | Status | Score | Prereqs | Teaches | -|---|---|---|---|---|---| -| `uvm/sequence` | Sequences | ✅ | 25/27 ⚠️9 | `uvm/seq-item` | `uvm_sequence`, `body()`, `start_item`/`randomize`/`finish_item` loop | -| `uvm/driver` | The Driver | ✅ | 24/27 ⚠️2,8,9 | `uvm/sequence`, `sv/interfaces`, `sv/always-ff` | `uvm_driver`, `get_next_item`/`item_done`, virtual interface driving, 1-cycle latency capture | -| `uvm/constrained-random` | Constrained-Random Scenarios | ✅ | 25/27 ⚠️5,9 | `uvm/seq-item` | `dist`, inline `randomize() with {}`, `constraint_mode()` | - -### Chapter: Checking -| Slug | Title | Status | Score | Prereqs | Teaches | -|---|---|---|---|---|---| -| `uvm/monitor` | Monitor and Scoreboard | ✅ | 25/27 ⚠️5,9 | `uvm/driver`, `uvm/seq-item` | `uvm_monitor`, `uvm_analysis_port`, `write()`, `uvm_scoreboard`, shadow memory | -| `uvm/env` | Environment and Test | ✅ | 23/27 ⚠️5,8,9 | `uvm/monitor` | `uvm_env`, `uvm_agent`, analysis port → scoreboard wiring | - -### Chapter: Functional Coverage -| Slug | Title | Status | Score | Prereqs | Teaches | -|---|---|---|---|---|---| -| `uvm/covergroup` | Functional Coverage | ✅ | 25/27 ⚠️5,9 | `uvm/monitor`, `sv/covergroup-basics` | functional coverage in UVM, `uvm_subscriber`, sampling transactions | -| `uvm/cross-coverage` | Cross Coverage | ✅ | 24/27 ⚠️5,9 | `uvm/covergroup`, `sv/cross-coverage` | cross in UVM context, `addr × we` 2D coverage | -| `uvm/coverage-driven` | Coverage-Driven Verification | ✅ | 25/27 ⚠️6,9 | `uvm/cross-coverage` | coverage-driven loop, `get_coverage()` exit condition | - -### Chapter: Advanced UVM -| Slug | Title | Status | Score | Prereqs | Teaches | -|---|---|---|---|---|---| -| `uvm/factory-override` | Factory Overrides | ✅ | 25/27 ⚠️5,9 | `uvm/seq-item` | `uvm_factory`, `type_id::set_type_override`, corner-case testing via type substitution | -| `uvm/virtual-seq` | Virtual Sequences | 💡 | — | `uvm/env` | `uvm_virtual_sequencer`, coordinating stimulus across multiple agents | -| `uvm/ral` | Register Abstraction Layer (RAL) | 💡 | — | `uvm/driver` | `uvm_reg_block`, `uvm_reg`, frontdoor/backdoor register access | - ---- - -## Part 4 — cocotb - -### Chapter: cocotb Basics -| Slug | Title | Status | Score | Prereqs | Teaches | -|---|---|---|---|---|---| -| `cocotb/first-test` | Your First cocotb Test | ✅ | 22/27 ⚠️2,4,9 | `sv/always-ff` (Python basics assumed) | `@cocotb.test()`, `dut.signal.value`, `await Timer()`, VCD generation | -| `cocotb/clock-and-timing` | Clock and Timing | ✅ | 24/27 ⚠️4,9 | `cocotb/first-test` | `Clock()`, `start_soon()`, `await ClockCycles()`, sim time queries | - -### Chapter: Triggers & Clocks -| Slug | Title | Status | Score | Prereqs | Teaches | -|---|---|---|---|---|---| -| `cocotb/edge-triggers` | Edge Triggers | ✅ | 24/27 ⚠️4,9 | `cocotb/clock-and-timing` | `RisingEdge`, `FallingEdge`, awaiting edge trigger objects | -| `cocotb/clockcycles-patterns` | Clock Cycles & Patterns | ✅ | 25/27 ⚠️9 | `cocotb/edge-triggers` | multi-cycle sequences, burst patterns, structured test routines | - ---- - ## Diagram opportunities (from MIT 6.111 research) Reference PDFs in `reference/mit-6111/` (CC BY-NC-SA 4.0, Chandrakasan, Spring 2006). @@ -260,13 +198,10 @@ Listed by lesson, in priority order: | `sv/always-ff` | D latch vs. D register schematics — "level-sensitive vs. edge-triggered" side-by-side | L5 p2 | | `sv/always-ff` | Pipeline timing: one stage with Tcq, Tlogic, Tsu labeled; formula T > Tcq+Tlogic+Tsu | L5 p3-5 | | `sv/always-ff` | Synchronous vs. async reset waveform comparison | L5 | -| `sv/fsm` | ✅ Moore block diagram SVG added (Comb. Logic ↔ State Reg, inputs/outputs) | L6 p6 | -| `sv/fsm` | Level-to-pulse edge-detector as a 2-state worked example before the SRAM controller | L6 p7 | | `sv/welcome` | HDL design flow: Problem → Behavioral → HDL → Synthesis → Implementation | L1 p12 | | `sv/data-types` | Two's complement circular number line (overflow wraparound visualised) | L8-9 p3 | | `sv/modules-and-ports` | Common logic gates table: NAND/AND/NOR/OR with symbol + truth table + Boolean expression | L2 p9 | | `sv/always-comb` | Gate-level mux diagram (AND/OR/NOT tree) matching the case statement | L3 | -| `sv/interfaces` | Two module boxes wired through a named interface bundle | — | --- diff --git a/src/lessons/compiler-quarantine.test.js b/src/lessons/compiler-quarantine.test.js new file mode 100644 index 0000000..37190e2 --- /dev/null +++ b/src/lessons/compiler-quarantine.test.js @@ -0,0 +1,32 @@ +import { describe, expect, it } from 'vitest'; +import { lessons } from './index.js'; + +const browserBlocked = [ + 'sv/interfaces', + 'sv/modports', + 'sv/tasks-functions', + 'sv/fsm', + 'uvm/reporting', + 'uvm/seq-item', + 'uvm/sequence', + 'uvm/driver', + 'uvm/constrained-random', + 'uvm/monitor', + 'uvm/env', + 'uvm/covergroup', + 'uvm/cross-coverage', + 'uvm/coverage-driven', + 'uvm/factory-override', + 'uvm/ral', + 'cocotb/first-test', + 'cocotb/clock-and-timing', + 'cocotb/edge-triggers', + 'cocotb/clockcycles-patterns' +]; + +describe('compiler-blocked lessons', () => { + it('does not publish lessons whose browser compiler path is not qualified', () => { + const published = new Set(lessons.map(({ slug }) => slug)); + expect(browserBlocked.filter((slug) => published.has(slug))).toEqual([]); + }); +}); diff --git a/src/lessons/index.js b/src/lessons/index.js index b11cbba..65f1261 100644 --- a/src/lessons/index.js +++ b/src/lessons/index.js @@ -79,8 +79,7 @@ export const parts = [ { title: 'Introduction', lessons: [L('sv/welcome'), L('sv/modules-and-ports'), L('sv/data-types'), L('sv/always-comb')] }, { title: 'Sequential Logic', lessons: [L('sv/events'), L('sv/always-ff'), L('sv/counter')] }, { title: 'Data Types', lessons: [L('sv/parameters'), L('sv/packed-structs')] }, - { title: 'Interfaces & Procedures', lessons: [L('sv/interfaces'), L('sv/modports'), L('sv/tasks-functions')] }, - { title: 'State Machines', lessons: [L('sv/enums'), L('sv/fsm')] }, + { title: 'State Machines', lessons: [L('sv/enums')] }, { title: 'Covergroups', lessons: [L('sv/covergroup-basics'), L('sv/coverpoint-bins'), L('sv/cross-coverage')] }, { title: 'Testbench Essentials', lessons: [L('sv/classes'), L('sv/queues-arrays'), L('sv/fork-join'), L('sv/randomization')] }, ], @@ -100,32 +99,12 @@ export const parts = [ { title: 'Formal Verification', lessons: [L('sva/formal-assume'), L('sva/always-eventually'), L('sva/until'), L('sva/lec')] }, ], }, - { - title: 'Universal Verification Methodology', - chapters: [ - { title: 'UVM Foundations', lessons: [L('uvm/reporting'), L('uvm/seq-item')] }, - { title: 'Stimulus', lessons: [L('uvm/sequence'), L('uvm/driver'), L('uvm/constrained-random')] }, - { title: 'Checking', lessons: [L('uvm/monitor'), L('uvm/env')] }, - { - title: 'Functional Coverage', - lessons: [L('uvm/covergroup'), L('uvm/cross-coverage'), L('uvm/coverage-driven')], - }, - { title: 'Advanced UVM', lessons: [L('uvm/factory-override'), L('uvm/ral')] }, - ], - }, { title: 'RTL Design Patterns', chapters: [ { title: 'Synthesis', lessons: [L('rtl/rtl-to-gates'), L('rtl/synthesis-gotchas')] }, ], }, - { - title: 'cocotb', - chapters: [ - { title: 'cocotb Basics', lessons: [L('cocotb/first-test'), L('cocotb/clock-and-timing')] }, - { title: 'Triggers & Clocks', lessons: [L('cocotb/edge-triggers'), L('cocotb/clockcycles-patterns')] }, - ], - }, { title: 'MLIR & MOX', chapters: [