// ============================================================================ // f500.v — 54F/74F500 6-Bit Analog-to-Digital Flash Converter // // Fairchild FAST (Advanced Schottky TTL) // Source: docs/devices/54F74F500.txt (1985 Fairchild FAST Data Book, // pages 4-365 ... 4-368) — PRELIMINARY data sheet. // // A 6-bit, fully parallel ("flash") ADC: 63 comparators spaced one quanta // apart on a resistor ladder between VRT (reference top, nominally 0 V) and // VRB (reference bottom, nominally -1.0 V), all comparing VIN against their // own tap point simultaneously. The most significant comparator that finds // VIN greater than its reference sets the encoded magnitude — a classic // thermometer code, so the COUNT of comparators reading VIN > threshold is // directly the 6-bit unsigned magnitude, 0 to 63. Two polarity control // inputs sit downstream of the conversion register (per the data sheet's // Block Diagram, PM/PL feed the OUTPUT BUFFERS stage, not the REGISTER MODE // SELECT stage that CVT/CP latches): PM complements the MSB (Q0) alone, PL // complements all five lesser bits (Q1-Q5) together — one PL bit, not five // independent controls. // // This model follows that same block-diagram structure — comparator ladder // -> AND-OR encoder -> latch -> output-buffer polarity XOR — rather than one // opaque closed-form formula: a `for` loop counts how many of the 63 // threshold comparisons are true (the AND-OR ENCODERS block, run at // simulation time against VIN since it is `real`-valued), the count latches // into a register on CVT the way the block diagram's REGISTER MODE SELECT // stage does, and a separate combinational XOR stage (OUTPUT BUFFERS) applies // PM/PL on top, so a PM/PL change does not need a new CVT edge to reach the // pins. // // SPECIFY PATHS MUST COVER EVERY INPUT THAT CAN CHANGE AN OUTPUT, not just // the ones with datasheet timing: an output net with a specify path declared // from one source (`cvt` here) but not from another (`pm`/`pl`, both of // which also drive Q0-Q5 through the polarity XOR below) gets Icarus's // distributed-delay mechanism applying the *declared* path's delay to every // transition of that net, PM/PL-caused ones included — confirmed directly // with a 2-bit toy circuit (a `posedge`-latched register XORed with a second // control input) both with and without an explicit path for the second // input: undeclared, a control-input-driven change measured the same 18 ns // as the clocked path; adding `(pm => q0) = (0, 0);` alongside the existing // `(cvt => q0)` path made it measure 0 ns instead, matching real LRM // path-delay semantics. So every path below is declared explicitly, // including PM/PL at 0 ns (the data sheet gives no PM/PL-to-Q timing to // transcribe, so 0 is "no delay claimed," not a transcribed figure). // // VIN is brought out on three physical pins (17, 19, 21) for current-sharing // and modeled here as a single logical `real` port; likewise AGnd (18, 20) // and Vee (1, 6) are not modeled at all, along with every other power/ground // pin, per this project's convention for all devices. // // Two assumptions not stated by the data sheet, both engineering judgment // calls rather than transcribed facts: // // - CVT edge: the data sheet does not say which edge of CVT (labeled CP // internally in the Block Diagram) samples/latches the result. This // model latches on the RISING edge (`posedge cvt`), matching every other // registered device in this project. // // - Ladder spacing: comparator i's threshold, for i = 1..63, is taken as // VRT - i/64.0*(VRT-VRB) — uniform spacing, no half-LSB offset. Real // flash ADCs often give the two end resistors (the Block Diagram labels // them RT/RB, distinct from the ladder's R) half the value of the // interior rungs for symmetric quantization error, but the data sheet's // Interface Specifications table gives only one R = 2.0 ohm "Reference // Resistor" figure — nothing that lets RT/RB be derived separately — so // asserting a specific split would invent a circuit detail the data // sheet doesn't support. Documented here as a stated simplification: a // judgment call, not a transcribed fact, the same distinction this // project draws whenever a preliminary or ambiguous data sheet leaves a // gap an engineer has to fill. // // Timing: the AC table's Propagation Delay row (tPLH) and its "Aperture // Delay" row (tPHL) — the table really does merge two different-sounding // names into what is structurally a tPLH/tPHL pair, a real quirk of this // preliminary sheet's layout, not a transcription error — both give 18.0 ns // TYP only (no Min/Max), so the specparams below are typ-only single values, // same convention as src/f240.v. tw(H)/tw(L) (Convert Pulse Width, 12.0 ns // Min each) and tA (Aperture Delay, 10.0 ns Typ) have no digital-simulation // equivalent modeled here: pulse-width minimums are timing-check territory // (Icarus doesn't support $width; see src/f74.v's `ifndef __ICARUS__` // pattern) and aperture delay/jitter describes analog sample-instant // uncertainty, not a propagation path — modeling it as extra timing // variation would invent behavior nothing else in this codebase does for // comparable specs. // // No AC Characteristics row exists for PM or PL to Q at all (only fmax, // tPLH, tPHL, tA, tw(H), tw(L) are listed), so the PM/PL paths below are // declared at 0 ns rather than left undeclared — see the note above on why // leaving them undeclared would silently borrow CVT's 18 ns instead of // reading as "no timing claimed." // // PERFORMANCE CHARACTERISTICS (Resolution, Input Range, Linearity Error, // Offset Error, Aperture Jitter, Bandwidth, Transient Response, SNR, Noise // Power Ratio) and the analog halves of INTERFACE SPECIFICATIONS (RIN, CIN, // IBIAS, IB, IRT, IRB, R, VRT/VRB/VRT-VRB ranges, ICC, IEE, VCC, VEE) are // analog/DC specs with no digital-simulation equivalent — not modeled, same // treatment every other analog/DC table gets in this project. // // Ports are scalar and named after the data sheet pin names, grouped by // function (control/strobe, analog, digital output) rather than strictly by // pin number, following src/f181.v's and src/f245.v's precedent for a // mixed-signal-adjacent port list. VIN, VRT and VRB are this project's first // `real`-typed ports: `real` input ports, `real`-valued comparisons in a // procedural loop, and specify-block path delays from a plain digital // signal (CVT) to scalar outputs all coexist without issue in this Icarus // setup. // ============================================================================ `timescale 1ns/100ps module f500 ( input wire pm, // Pin 4 — PM Polarity Control MSB (complements Q0) input wire pl, // Pin 5 — PL Polarity Control LSB (complements Q1-Q5, one control for all five) input wire cvt, // Pin 15 — CVT Convert strobe (Block Diagram's internal CP; latches the encoded result on its rising edge — assumption, see header) input real vrt, // Pin 22 — VRT Reference voltage, top (nominally 0 V) input real vin, // Pins 17, 19, 21 — VIN Analog input (three physical pins tied together, modeled as one) input real vrb, // Pin 16 — VRB Reference voltage, bottom (nominally -1.0 V) output wire q0, // Pin 14 — Q0 Digital output, MSB output wire q1, // Pin 13 — Q1 Digital output output wire q2, // Pin 12 — Q2 Digital output output wire q3, // Pin 11 — Q3 Digital output output wire q4, // Pin 10 — Q4 Digital output output wire q5 // Pin 9 — Q5 Digital output, LSB ); // ------------------------------------------------------------------ // Comparator ladder + AND-OR encoder + register (Block Diagram), // modeled as a threshold count rather than 63 discrete comparator // instances — see header. `code` is the raw thermometer-code // magnitude, pre-polarity, latched on the rising edge of CVT. // ------------------------------------------------------------------ reg [5:0] code; integer i, cnt; always @(posedge cvt) begin cnt = 0; for (i = 1; i <= 63; i = i + 1) if (vin > (vrt - (i / 64.0) * (vrt - vrb))) cnt = cnt + 1; code = cnt[5:0]; end // ------------------------------------------------------------------ // Output buffers: combinational polarity XOR stage, downstream of the // latch (see header) — a PM/PL change needs no new CVT edge to reach // Q0-Q5, and reaches them at 0 ns (see the explicit pm/pl specify paths // below, and the header note on why they're declared rather than left // implicit). // ------------------------------------------------------------------ assign q0 = code[5] ^ pm; assign q1 = code[4] ^ pl; assign q2 = code[3] ^ pl; assign q3 = code[2] ^ pl; assign q4 = code[1] ^ pl; assign q5 = code[0] ^ pl; specify // AC Characteristics, TA = +25 C, VCC = +5.0 V, VEE = -6.0 V, // CL = 50 pF: tPLH (Propagation Delay) and tPHL ("Aperture Delay", // the table's own quirky label for the same merged row) both give // 18.0 ns TYP only — no Min/Max on this preliminary sheet. specparam tlh_cvt_q = 18.0; specparam thl_cvt_q = 18.0; (cvt => q0) = (tlh_cvt_q, thl_cvt_q); (cvt => q1) = (tlh_cvt_q, thl_cvt_q); (cvt => q2) = (tlh_cvt_q, thl_cvt_q); (cvt => q3) = (tlh_cvt_q, thl_cvt_q); (cvt => q4) = (tlh_cvt_q, thl_cvt_q); (cvt => q5) = (tlh_cvt_q, thl_cvt_q); // PM/PL also drive Q0-Q5 (see the polarity XOR above) and must have // their own paths declared too, or Icarus's distributed-delay // mechanism applies CVT's 18 ns to PM/PL-caused transitions as well // — see the header note. No AC figure exists for either path, so // both are 0 ns: "no delay claimed," not a transcribed datasheet // value. (pm => q0) = (0, 0); (pl => q1) = (0, 0); (pl => q2) = (0, 0); (pl => q3) = (0, 0); (pl => q4) = (0, 0); (pl => q5) = (0, 0); endspecify endmodule