// SPDX-License-Identifier: Apache-2.0 ; specs/course/buses-and-peripherals.t27 -- the t27 course on buses and peripherals ; Source of truth for apps/website/scripts/course-from-spec.mjs (gHashTag/trinity), which reads ; it the way it reads specs/course/course.t27: the constant schema, every test block below, every ; widget in specs/widgets/gallery.t27, every lesson spec compiled clean, the Russian bundle named ; by specs/course/buses-and-peripherals-ru.t27. It writes this course into src/lib/course.generated.ts ; (the page at #/buses-and-peripherals) and a byte-identical copy of this file at ; public/learn/buses-and-peripherals.t27. ASCII only (L3), English only (LANG-EN). ; WHAT THE COURSE IS: course 7 of specs/course/courses.t27, 27 lessons in 9 modules of 3. It ; stands on its own: why a bus exists at all, UART frame by frame, SPI mode by mode, the APB ; handshake, the five AXI4 channels, memory maps, bridges, Ethernet frames and RGMII timing, ; and the bench IO discipline that guards the real hardware. Every lesson opens one widget ; and one spec. ; WHAT THE COURSE DOES NOT DO: it says no number of its own. Every number in a lesson comes ; from the spec it opens, from the recording it plays, or from the page of the widget it shows, ; and each of those names its own source. Two specs were written for this course (specs/fpga/rgmii.t27 ; and specs/fpga/eth_crc.t27, landed through gHashTag/t27); their teaching assumptions are ; labelled in the specs themselves. Where the native runner is blocked on a spec the recording ; shows what does run and says so, the way the clocks course does. ; WHY 27: 3 cubed lessons, the size of a TRI-27 word. Changing the shape changes the tests. ; phi^2 + 1/phi^2 = 3 | TRINITY module buses_and_peripherals; pub const KIND : str = "course"; pub const ID : str = "buses-and-peripherals"; pub const SCHEMA_VERSION : u8 = 1; ; The derived files the generator rewrites (relative to apps/website). pub const GENERATED : [2]str = ["src/lib/course.generated.ts", "public/learn/buses-and-peripherals.t27"]; pub const ROUTE : str = "buses-and-peripherals"; ; Share pages: learn/ for course 1, learn// for the next (specs/course/courses.t27). pub const SHARE_PATH : str = "learn/buses-and-peripherals/"; ; The same paid FPGA training cohort the clocks course feeds (specs/course/clocks-and-cdc.t27). pub const COHORT_ROUTE : str = "fpga-training"; pub const GALLERY : str = "specs/widgets/gallery.t27"; pub const LOCALES : [2]str = ["en", "ru"]; pub const RU_CONTRACT : str = "specs/course/buses-and-peripherals-ru.t27"; ; Lesson marks the reader sets are kept in this browser only, under this key, one key for ; every course. pub const PROGRESS_KEY : str = "t27-course-done"; pub const SENDS_NOTHING : bool = true; ; A lesson's widget is the page's main stage, so it is drawn taller than a ; gallery card (specs/widgets/gallery.t27 EMBED_* heights are for embeds in posts). pub const TOOL_FRAME_HEIGHT : u16 = 640; pub const PLAYER_FRAME_HEIGHT : u16 = 480; ; --- Words on the page --------------------------------------------------------------------- pub const TITLE : str = "Buses and peripherals with t27: UART, SPI, APB, AXI4, Ethernet"; pub const DESCRIPTION : str = "Course 7, 27 lessons, one widget and one t27 spec each: why a bus exists, the UART frame, SPI modes, the APB handshake, the five AXI4 channels, memory maps, bridges, Ethernet frames and RGMII timing, and the bench IO discipline. Every number comes from a spec or a recorded run."; pub const SAY_KICKER : str = "Course"; pub const SAY_LEAD : str = "It picks up where the clocks course ends. Every lesson opens a real tool or a recording of t27c on a real machine, next to a spec you can run in your browser."; pub const SAY_SHAPE : str = "9 modules of 3 lessons, 27 cells. A filled cell is a lesson you marked done."; pub const SAY_START : str = "Start lesson 1"; pub const SAY_CONTINUE : str = "Continue"; pub const SAY_MODULE : str = "Module {0}"; pub const SAY_LESSON : str = "Lesson {0} of {1}"; pub const SAY_GOAL : str = "You will learn"; pub const SAY_TRY : str = "Try it"; pub const SAY_ALSO : str = "Also try"; pub const SAY_ALSO_HINT : str = "Each one swaps the widget above."; pub const SAY_BACK_TO_MAIN : str = "Back to this lesson's widget"; pub const SAY_SPEC : str = "Open the lesson's spec in the player"; pub const SAY_OPEN_PAGE : str = "Open the widget on its own page"; pub const SAY_WIDGET_LANG : str = "Widgets keep their own English words: each one lives in its own t27 spec."; pub const SAY_PREV : str = "Previous"; pub const SAY_NEXT : str = "Next"; pub const SAY_ALL : str = "All lessons"; pub const SAY_MARK : str = "Mark as done"; pub const SAY_MARKED : str = "Done"; pub const SAY_PROGRESS : str = "{0} of {1} done"; pub const SAY_PRIVATE : str = "Progress stays in this browser; nothing is sent."; pub const SAY_SOURCE : str = "This course is itself a t27 spec: read it"; pub const SAY_COHORT : str = "Looking for the paid FPGA training? It moved to its own page."; pub const SAY_NOT_FOUND : str = "No lesson has this address."; pub const SAY_OPEN_LESSON : str = "Open the interactive lesson"; pub const SAY_OPEN_COURSE : str = "Open the interactive course"; pub const SAY_SEO_TITLE : str = "{0}: buses and peripherals course, lesson {1} of {2}"; pub const SAY_SHARE : str = "Link to share, with a preview card"; pub const SAY_NEXT_COURSE : str = "Next course"; pub const SAY_PREV_COURSE : str = "Previous course"; ; --- Modules ------------------------------------------------------------------------------- pub const LESSONS_PER_MODULE : u8 = 3; pub const MODULE_COUNT : u8 = 9; pub const MODULE_IDS : [9]str = ["what-a-bus-is", "uart", "spi", "apb", "axi4", "memory", "bridges", "ethernet", "the-bench"]; pub const MODULE_TITLES : [9]str = [ "What a bus is", "UART", "SPI", "APB", "AXI4", "Memory", "Bridges", "Ethernet", "The bench" ]; pub const MODULE_LINES : [9]str = [ "Why a bus exists at all: a conversation on wires, framed and addressed, and who is allowed to talk.", "The two-wire bus with no clock: the frame, the divisor that sets the rate, and the status a driver polls.", "The clocked conversation: four modes, a prescaler ladder, and a chip select per servant.", "The register bus: PSEL and PENABLE, strobes and wait states, and how many address bits a peripheral count costs.", "The five channels: address, data and response in both directions, lite or full, bursts and IDs.", "What sits on the far side of every bus: memory maps, port kinds, and latency that a wait state must cover.", "Why designs grow more than one bus, and the packet bridge that moves work between them.", "Frames, the frame check sequence, RGMII timing, and the pre-registered steps of a real bring-up.", "The discipline that guards real hardware: who holds the IO, taking and giving the lock, and what runs next." ]; ; --- Lessons ------------------------------------------------------------------------------- ; LESSON_WIDGETS names the widget the lesson opens; every one is a gallery id, and no two ; lessons of any course open the same one. LESSON_ALSO lists more gallery ids, comma ; separated, shown as chips that swap the widget. LESSON_SPECS is the spec under ; public/t27/files/ the lesson opens in the player; every lesson names one. pub const LESSON_COUNT : u8 = 27; pub const LESSON_IDS : [27]str = [ "wires-that-talk", "framing-a-conversation", "master-and-servant", "the-frame", "baud-and-the-divisor", "status-and-fifos", "modes-cpol-cpha", "the-prescaler-ladder", "chip-select-and-widths", "psel-and-penable", "strobes-and-waits", "address-decode", "five-channels", "lite-or-full", "bursts-and-ids", "memory-maps", "ports-and-kinds", "latency", "why-bridges", "the-packet-bridge", "everything-in-one-bench", "frames-and-the-fcs", "rgmii-timing", "bring-up-on-the-bench", "who-holds-the-io", "claim-and-release", "capstone-what-runs-next" ]; pub const LESSON_MODULES : [27]str = [ "what-a-bus-is", "what-a-bus-is", "what-a-bus-is", "uart", "uart", "uart", "spi", "spi", "spi", "apb", "apb", "apb", "axi4", "axi4", "axi4", "memory", "memory", "memory", "bridges", "bridges", "bridges", "ethernet", "ethernet", "ethernet", "the-bench", "the-bench", "the-bench" ]; pub const LESSON_WIDGETS : [27]str = [ "t27c-check-uart", "t27c-check-spi", "t27c-check-apb", "t27c-verilog-uart", "t27c-hir-uart", "t27c-verilog-uart-tb", "t27c-verilog-spi", "t27c-spi-tb", "t27c-verilog-spi-tb", "t27c-verilog-apb", "t27c-hir-apb", "t27c-verilog-apb-tb", "t27c-verilog-axi4", "t27c-check-axi4", "t27c-verilog-axi-tb", "t27c-memory", "t27c-check-memory", "t27c-verilog-mem-tb", "t27c-check-bridge", "t27c-verilog-bridge", "t27c-verilog-integration-tb", "t27c-eth-crc", "t27c-rgmii", "tri-fpga-steps", "tri-fpga-ioclients", "tri-fpga-claim", "tri-fpga-next" ]; pub const LESSON_ALSO : [27]str = [ "uart-bucket", "", "", "t27c-check-uart", "t27c-verilog-uart", "", "t27c-check-spi", "t27c-verilog-spi", "", "t27c-check-apb", "t27c-verilog-apb", "", "t27c-check-axi4,t27c-hir-axi4", "t27c-verilog-axi4", "", "t27c-check-memory", "", "", "t27c-verilog-bridge", "", "", "tri-fpga-rgmii", "tri-fpga-txhold", "tri-fpga-wire", "", "tri-fpga-release", "t27c-verilog-top,t27c-verilog-top-tb" ]; pub const LESSON_SPECS : [27]str = [ "specs/fpga/uart.t27", "specs/fpga/spi.t27", "specs/fpga/apb_bridge.t27", "specs/fpga/uart.t27", "specs/fpga/uart.t27", "specs/fpga/testbench/uart_tb.t27", "specs/fpga/spi.t27", "specs/fpga/testbench/spi_tb.t27", "specs/fpga/testbench/spi_tb.t27", "specs/fpga/apb_bridge.t27", "specs/fpga/apb_bridge.t27", "specs/fpga/testbench/apb_bridge_tb.t27", "specs/fpga/axi4.t27", "specs/fpga/axi4.t27", "specs/fpga/testbench/axi4_tb.t27", "specs/fpga/memory.t27", "specs/fpga/memory.t27", "specs/fpga/testbench/memory_tb.t27", "specs/fpga/bridge.t27", "specs/fpga/bridge.t27", "specs/fpga/testbench/integration_tb.t27", "specs/fpga/eth_crc.t27", "specs/fpga/rgmii.t27", "specs/tools/trios/tri/fpga-steps.t27", "specs/tools/trios/tri/fpga-ioclients.t27", "specs/tools/trios/tri/fpga-claim.t27", "specs/fpga/top_level.t27" ]; pub const LESSON_TITLES : [27]str = [ "Wires that talk", "Framing a conversation", "Master and servant", "The frame: start, data, stop", "Baud and the divisor", "Status and FIFOs", "Modes: CPOL and CPHA", "The prescaler ladder", "Chip select and widths", "PSEL and PENABLE", "Strobes and waits", "Address decode", "Five channels", "Lite or full", "Bursts and IDs", "Memory maps", "Ports and kinds", "Latency", "Why bridges", "The packet bridge", "Everything in one bench", "Frames and the FCS", "RGMII timing", "Bring-up on the bench", "Who holds the IO", "Claim and release", "Capstone: what runs next" ]; pub const LESSON_GOALS : [27]str = [ "What a bus is for, what the two-wire conversation of a UART costs, and what the course's opening spec checks.", "What a clocked conversation changes, and how the SPI spec states its modes and rates.", "What a register bus is, who drives and who answers, and how APB names the roles.", "How a UART frame is built bit by bit, and what the compiler emits for it.", "How one divisor turns a clock into a bit rate, and what changing it breaks.", "What a driver polls, when a send is refused, and what the testbench of the UART checks.", "What CPOL and CPHA mean, why there are four modes, and which one the spec configures.", "How the prescaler ladder turns one clock into a family of SCK rates, and which steps are valid.", "How a chip select picks the listener, and how wide a transfer may be.", "How the APB two-phase handshake works, and what the compiler emits for the bridge.", "What the strobe bytes mean, when a servant holds the bus, and how the IR sees it.", "How many address bits a peripheral count costs, and what the bench of the bridge checks.", "What the five AXI4 channels carry, and what the compiler emits for them.", "What AXI4 Lite keeps and drops, and what validation demands of a bus.", "How a burst is described, what an ID is for, and what the AXI4 bench checks.", "How a memory map is declared, what BRAM and ROM mean as kinds, and what 15 native tests check.", "What a port is on a memory, how many a memory may have, and who may write.", "What latency a memory answers in, and what the memory bench checks of reads and writes.", "Why a design grows more than one bus, and what the bridge spec checks of its own state.", "How the packet bridge moves work between buses, and what its buffers cost.", "What an integration bench checks when every bus of the design is driven at once.", "How an Ethernet frame ends in a CRC-32, and what the check computes.", "What RGMII timing demands of a double-data-rate nibble, and what the spec asserts of it.", "What a pre-registered bring-up looks like on the real bench, step by step.", "Who holds the bench IO right now, and what the registered clients declare.", "How a claim is taken and given back, and why the discipline matters.", "How the pieces of this course meet in one design, and what runs next on the bench." ]; pub const LESSON_TEXTS : [27]str = [ "A bus exists because pins are dear: two chips that must talk share wires, and the wires carry a conversation both sides agreed to. The simplest one is the UART of this lesson's spec, ZeroDSP_UART: two wires, no clock, both sides agreeing on a rate -- the spec carries UART_CLOCK_HZ at 100,000,000 and UART_BAUD_RATE at 115,200. The recording runs t27c check on the spec: 0 errors, 0 warnings, the entry bar every lesson's spec clears. The player compiles it in your browser.", "A conversation needs rules about when a word starts and ends, or the far side samples noise. The clocked answer is SPI, and the spec of this lesson, SPI_Master, states its ground: CLK_FREQ at 50,000,000, SPI_CPOL and SPI_CPHA at 0, a maximum data width of 32 bits. The recording runs t27c check on it: 0 errors, 0 warnings. The three buses this module opens -- UART, SPI, APB -- are the three answers the course takes apart, one per module.", "A register bus gives the conversation roles: one master drives addresses, each servant answers when named. APB is that bus at its plainest, and the spec of this lesson is its bridge: ApbBridge, with APB_ADDR_WIDTH 32, APB_DATA_WIDTH 32 and APB_STRB_WIDTH 4. The recording runs t27c check: 0 errors, 0 warnings. The module after next takes its handshake apart phase by phase.", "A UART frame is the atoms of the bus: the line idles high, a start bit pulls it low, eight data bits follow, and a stop bit returns it high. The testbench spec of the last lesson of this module checks the idle itself -- uart_tb_tx_idle_high and uart_tb_rx_idle_high are two of its seven tests. The recording shows the compiler lowering the spec to synthesizable Verilog: the module ZeroDSP_UART, its clk, rst_n, en, data and ready ports, the datapath as wires.", "The rate is a divisor: the clock divided by the baud gives the bit period, and the spec states it as a constant expression -- UART_BIT_PERIOD is UART_CLOCK_HZ / UART_BAUD_RATE, 100,000,000 over 115,200. The test uart_configure_changes_baud_divisor checks that configuring the driver moves the divisor. The recording shows the spec lowered to hardware IR: the compiler's own view of the wires and state before Verilog exists.", "A driver needs to know the hardware's mood: the spec carries STATUS_IDLE as 0, STATUS_TX_BUSY as 1, STATUS_RX_BUSY as 2, and a 16-deep FIFO each way. The test uart_tx_send_returns_false_when_busy is the rule a driver lives by -- you do not push a busy transmitter. The recording lowers the UART testbench spec to Verilog: what a bench looks like when the compiler emits it.", "CPOL picks the clock's idle level, CPHA picks which edge samples: four combinations, four modes, and devices that only speak one. The spec configures mode 0 -- SPI_CPOL 0, SPI_CPHA 0 -- and spi_mode_0_configuration is the test that pins it. The recording lowers the SPI spec to synthesizable Verilog.", "One clock becomes a family of rates through the prescaler ladder: PRESCALER_2 is 0, PRESCALER_4 is 1, and the ladder climbs while the clock holds. spi_prescaler_16_default checks the default, spi_set_prescaler_valid and spi_set_prescaler_invalid check the bounds, spi_sck_freq_at_50 checks the arithmetic. The recording is a native run: the SPI testbench spec through the real t27c, 7 tests pass.", "The chip select is the addressing of SPI: pull one CS low and that servant listens, hold the others high and they stay silent. The spec gives the select its timing -- CS_ASSERT_DELAY and CS_DEASSERT_DELAY at 100 ns each -- and the width its bounds: spi_set_data_width_8 and spi_set_data_width_32 bracket a MAX_DATA_WIDTH of 32. The recording lowers the SPI testbench spec to Verilog.", "APB moves a transfer in two phases: setup, where PSEL names the servant and the address settles, and access, where PENABLE rises and the transfer completes. The spec's ApbTransfer enum carries the kinds, and the bench of the twelfth lesson drives write and read through them. The recording lowers the APB bridge spec to synthesizable Verilog: the port list, the wiring, the decode.", "The strobe bytes say which lanes of the word carry data: strb_width_32bit and strb_width_16bit are two of the spec's eighteen tests, one word served whole and one half-word served. A slow servant holds the bus with a wait state instead of guessing. The recording shows the APB bridge as hardware IR: PSEL, PENABLE and the decode as the compiler structures them.", "Addressing on APB is a question of bits: how many servants sit behind the bridge decides how many address bits the decode spends. The spec answers by count -- addr_bits_for_1_peripheral, addr_bits_for_4_peripherals, addr_bits_for_8_peripherals -- and its testbench drives the result: test_reset_state, test_apb_write, test_apb_read, test_write_read_roundtrip, test_multiple_apb_writes, eight tests. The recording lowers the APB bridge testbench spec to Verilog.", "AXI4 carries five independent channels: write address, write data, write response, read address, read data. The spec states the widths -- AXI_ADDR_WIDTH 32, AXI_DATA_WIDTH 32, AXI_STRB_WIDTH 4, AXI_ID_WIDTH 4, AXI_LEN_WIDTH 8, AXI_SIZE_WIDTH 3 -- under a MAX_BUS_PORTS of 32. The recording lowers the AXI4 spec to synthesizable Verilog: the channels' wiring and handshakes as generated wires.", "Lite is the same handshake with the burst machinery lifted out: no LEN, no size ladder, one transfer at a time. The spec's AxiKind enum carries lite and full, and its tests name the difference -- axi4_lite_is_lite, axi4_full_is_full -- and the validation rules: validate_lite_ok, validate_full_ok, validate_empty_name, validate_zero_addr. The recording runs t27c check on the spec: 0 errors, 0 warnings.", "A burst is one address and a count: AXI_LEN_WIDTH 8 means up to 256 beats under one address, and the ID lets a master's transactions interleave and still land in order. The bench drives it: test_reset_state, test_single_write, test_single_read, test_write_read_roundtrip, test_multiple_writes, eight tests. The recording lowers the AXI4 testbench spec to Verilog.", "A memory map is who lives at which address: the spec's MemKind enum carries the kinds, and make_bram_has_depth, make_bram_small and make_bram_single are three of its fifteen tests. The recording is a native run: the memory spec through the real t27c, 15 tests pass and 6 invariants are proved comptime -- the one spec of the bus family the native runner takes whole.", "A port is a lane into the memory: read, write or both, and MAX_MEM_PORTS 8 bounds them. add_read_port_increments, add_write_port_increments and add_rw_port check the counting, is_rom checks that a read-only kind refuses a write port. The recording runs t27c check on the spec: 0 errors, 0 warnings.", "Every answer costs cycles, and the spec's MemLatency enum carries the kinds a wait state must cover. The bench checks the behaviour: test_reset_clears, test_write_read_single, test_write_read_multiple, test_overwrite, test_all_zero_bits, nine tests. The recording lowers the memory testbench spec to Verilog.", "A design grows more than one bus because peripherals andcompute differ: a slow register bus for the knobs, a wide one for the data. The bridge spec, FPGA_Bridge, is the crossing of this design, and bridge_initially_idle and bridge_rx_buffers_empty are two of its twenty-one tests. The recording runs t27c check: 0 errors, 0 warnings.", "The packet bridge moves work between buses as packets: RX and TX buffers of 256 bytes each, an SPI buffer of 64, MAX_PACKET_SIZE 128, PACKET_TIMEOUT 10,000 cycles, and opcodes OP_MAC_MUL, OP_MAC_MAC and OP_MAC_MACC for the work it carries. bridge_buffer_count_wrap and bridge_buffer_count_wrap2 check the arithmetic at the seam. The recording lowers the bridge spec to synthesizable Verilog.", "An integration bench drives every bus at once and asks the design to hold together: test_reset_all_modules, test_module_count, test_mac_uart_pipeline, test_spi_memory_pipeline, test_full_pipeline, seven tests. The recording lowers the integration testbench spec to Verilog: every bus of the design in one bench.", "An Ethernet frame ends in a frame check sequence: a CRC-32 over the bytes, computed by the sender and recomputed by the receiver. The spec of this lesson, written for this course, carries the polynomial and the arithmetic, and its header labels what the check does and does not claim. The recording runs t27c on it.", "RGMII moves a nibble per clock edge, both edges: double data rate at 125 MHz for gigabit, and a single-data-rate downshift for 10 and 100. The spec of this lesson, written for this course, carries the timing arithmetic and its assumptions in the header. The recording runs t27c on it.", "A bring-up is not improvisation: the steps are pre-registered, each command is logged, and what did not run is as recorded as what did. The widget is the Ethernet bring-up plan on this bench, tri fpga-steps, and the spec is its tool card. The next module shows the discipline that guards the hardware the plan touches.", "Real hardware shared is hardware borrowed: the bench registers its IO clients, and the recording reads them live -- names, claims and what each declares it owns. The spec is the tool card of tri fpga-ioclients. The lesson closes the loop the course opened: a bus, its spec, its bench, and now the hands on it.", "A claim is a promise: one client holds the lock, works, and gives it back. The recording takes the claim with tri fpga-claim and the chip that follows it gives it back with tri fpga-release -- take and return recorded back to back, the bench reporting who holds it and then itself free. The spec is the tool card of tri fpga-claim.", "Close the course where it started, at the whole design: top_level.t27 carries CLK_FREQ_HZ 100,000,000, SYSTICK_HZ 1000, NUM_MAC_UNITS 8, DATA_WIDTH 32, and the opcodes CMD_NOP, CMD_MAC_MULT, CMD_MAC_DOT and CMD_UART_SEND -- nineteen tests of the design that holds every bus this course took apart. The recording reads what the bench runs next; the also-chips lower the whole design to Verilog, and its top bench with it." ]; pub const LESSON_TASKS : [27]str = [ "In the recording, find the error and warning counts; then in the spec frame find UART_CLOCK_HZ and UART_BAUD_RATE and divide them for the bit period.", "In the recording, find the error and warning counts; then in the spec frame find CLK_FREQ, CPOL and CPHA, and say which mode the spec configures.", "In the recording, find the error and warning counts; then in the spec frame find the three APB widths and say what the strobe width of 4 covers.", "In the recording, find the module name and its ports; then in the spec frame find the width and depth constants of the frame and the FIFO.", "In the recording, watch the IR view of the divisor; then in the spec frame find UART_BIT_PERIOD and the test that moves it.", "In the recording, find what the bench prints of the idle lines; then in the spec frame find the three status codes and the test that refuses a busy send.", "In the recording, find the module ports the Verilog gives the SPI master; then in the spec frame find the mode-0 test and name what CPOL and CPHA each pick.", "In the recording, count the passing tests; then in the spec frame list the prescaler constants and find the test that checks the default.", "In the recording, find the bench's Verilog; then in the spec frame find both CS delays and the two width tests that bracket the maximum.", "In the recording, find the bridge's port list; then in the spec frame find the ApbTransfer kinds and say which phase PENABLE names.", "In the recording, find PSEL and PENABLE in the IR; then in the spec frame find the two strobe-width tests and say what a half-word transfer strobes.", "In the recording, find the bench tests; then in the spec frame compute the address bits the spec spends for 8 peripherals.", "In the recording, find the channels in the emitted wires; then in the spec frame list the six AXI widths and say what the 8-bit LEN covers.", "In the recording, find the error and warning counts; then in the spec frame find the AxiKind values and the four validation tests.", "In the recording, find the bench tests; then in the spec frame compute the burst ceiling the LEN width allows and say what an ID buys.", "In the recording, count the passing tests and proved invariants; then in the spec frame find the MemKind values and the three make_bram tests.", "In the recording, find the error and warning counts; then in the spec frame find MAX_MEM_PORTS and the test that refuses a write port on ROM.", "In the recording, find the bench tests; then in the spec frame find the MemLatency kinds and say what a wait state must cover.", "In the recording, find the error and warning counts; then in the spec frame find the two idle tests and count the spec's tests.", "In the recording, find the module ports of the bridge; then in the spec frame find the four buffer constants and the timeout, and the three opcodes.", "In the recording, find the five pipeline tests; then in the spec frame say which two buses the integration bench joins.", "In the recording, watch the run; then in the spec frame find the polynomial the CRC-32 uses and what the header labels as an assumption.", "In the recording, watch the run; then in the spec frame find the DDR rate and what the spec says of the 10 and 100 downshift.", "In the recording, count the steps and find one that did not run; then in the spec frame read what the tool card declares it records.", "In the recording, list the clients the bench reports; then in the spec frame find what a client must declare to register.", "In the recording, watch the claim land and the release land; then in the spec frame find what tri fpga-claim refuses when the lock is held.", "In the recording, read what runs next; then in the spec frame find the four opcodes and count the design's tests." ]; ; --- Claims -------------------------------------------------------------------------------- test the_course_is_three_cubed { assert LESSONS_PER_MODULE == 3; assert MODULE_COUNT == 9; assert LESSON_COUNT == 27; assert MODULE_COUNT * LESSONS_PER_MODULE == LESSON_COUNT; assert LESSON_COUNT == 3 * 3 * 3; } test it_starts_with_wires_and_ends_with_the_bench { assert MODULE_IDS[0] == "what-a-bus-is"; assert LESSON_MODULES[0] == "what-a-bus-is"; assert LESSON_WIDGETS[0] == "t27c-check-uart"; assert LESSON_SPECS[0] == "specs/fpga/uart.t27"; assert MODULE_IDS[8] == "the-bench"; assert LESSON_MODULES[26] == "the-bench"; assert LESSON_WIDGETS[26] == "tri-fpga-next"; assert LESSON_SPECS[26] == "specs/fpga/top_level.t27"; } test the_uart_module_opens_the_uart_family { assert MODULE_IDS[1] == "uart"; assert LESSON_SPECS[3] == "specs/fpga/uart.t27"; assert LESSON_SPECS[4] == "specs/fpga/uart.t27"; assert LESSON_SPECS[5] == "specs/fpga/testbench/uart_tb.t27"; assert LESSON_WIDGETS[3] == "t27c-verilog-uart"; assert LESSON_WIDGETS[4] == "t27c-hir-uart"; } test the_spi_module_carries_a_native_run { assert MODULE_IDS[2] == "spi"; assert LESSON_SPECS[7] == "specs/fpga/testbench/spi_tb.t27"; assert LESSON_WIDGETS[7] == "t27c-spi-tb"; } test apb_and_axi_each_get_three_lessons { assert MODULE_IDS[3] == "apb"; assert LESSON_WIDGETS[9] == "t27c-verilog-apb"; assert LESSON_WIDGETS[11] == "t27c-verilog-apb-tb"; assert MODULE_IDS[4] == "axi4"; assert LESSON_WIDGETS[12] == "t27c-verilog-axi4"; assert LESSON_WIDGETS[14] == "t27c-verilog-axi-tb"; } test the_memory_module_holds_the_native_run { assert MODULE_IDS[5] == "memory"; assert LESSON_WIDGETS[15] == "t27c-memory"; assert LESSON_SPECS[15] == "specs/fpga/memory.t27"; } test the_bridge_module_ends_in_the_integration_bench { assert MODULE_IDS[6] == "bridges"; assert LESSON_WIDGETS[20] == "t27c-verilog-integration-tb"; assert LESSON_SPECS[20] == "specs/fpga/testbench/integration_tb.t27"; } test the_ethernet_module_carries_the_new_specs { assert MODULE_IDS[7] == "ethernet"; assert LESSON_SPECS[21] == "specs/fpga/eth_crc.t27"; assert LESSON_SPECS[22] == "specs/fpga/rgmii.t27"; assert LESSON_WIDGETS[21] == "t27c-eth-crc"; assert LESSON_WIDGETS[22] == "t27c-rgmii"; assert LESSON_WIDGETS[23] == "tri-fpga-steps"; } test the_bench_module_reads_live_tools { assert MODULE_IDS[8] == "the-bench"; assert LESSON_WIDGETS[24] == "tri-fpga-ioclients"; assert LESSON_WIDGETS[25] == "tri-fpga-claim"; assert LESSON_SPECS[25] == "specs/tools/trios/tri/fpga-claim.t27"; } test the_course_sends_nothing { assert SENDS_NOTHING == true; assert LOCALES[0] == "en"; assert LOCALES[1] == "ru"; }