// ============================================================================ // f588.v — 54F/74F588 Octal Bidirectional Transceiver (3-State Inputs/Outputs, // with IEEE-488 Termination Resistors) // // Fairchild FAST (Advanced Schottky TTL) // Source: docs/devices/54F74F588.txt (1985 Fairchild FAST Data Book, // pages 4-474 ... 4-476; the 1980 data book carries the 'F588 in its // Section 3 selection guide only, page 3-30. Released data sheet.) // // Eight channels, each a back-to-back pair of non-inverting 3-state buffers // between the bidirectional bus pins A0..A7 and B0..B7. A single T//R input // selects which buffer of the pair is active (HIGH = Transmit = A -> B, // LOW = Receive = B -> A); /OE gates both directions, HIGH disabling every // buffer to High-Z regardless of T//R. Identical architecture and truth // table to 'F245. // // Truth table (per channel): // OE_n=L, TR=L -> B drives A (A = B); // OE_n=L, TR=H -> A drives B (B = A); // OE_n=H -> both sides High-Z. // // As with 'F245, there is no independent-enable hazard here: T//R is a // single select bit, so exactly one direction (or neither, under /OE HIGH) // can ever be active. See src/f245.v's header comment (and, further back, // src/f242.v's/src/f243.v's) for the full backstory on why the T//R-style // transceivers are structurally immune to the both-directions-enabled // contention 'F242/'F243 carry. // // IEEE-488 termination resistors: the B ports carry a built-in resistive // termination network per the IEEE-488 instrumentation bus standard (data // sheet input-loading table lists B0-B7 as "T* = Resistive Termination per // IEEE-488 Standard" in place of an ordinary HIGH unit load, and the DC // table's VNL "No-load Voltage" row gives the network's idle level on B, // 2.5 V min / 3.7 V typ with T//R LOW and IOUT = 0). This is a physical/ // analog characteristic of the B-pin network, not a digital function — it // does not change the truth table above or invent a new logic state. It is // documented here, not modeled: this project's models are purely digital/ // timing gate-level (DC current/voltage tables are documentation-only // throughout, e.g. 'F245's ICCH/ICCL/ICCZ), and no device in this codebase // gives an undriven 3-state pin anything other than plain 1'bz — including // 'F289's open-collector outputs, whose external pull-up is likewise noted // in comments and left for the testbench/external circuit to resolve rather // than modeled with a Verilog `tri1`/pullup construct. B here follows the // same precedent: an undriven B pin reads 1'bz in this model, same as A. // // Timing values from the data sheet AC Characteristics table, T_A = +25 C, // V_CC = +5.0 V, C_L = 50 pF column, min:typ:max ns. The sheet's second // column, 74F over the commercial T_A/V_CC range, gives min/max only. Both // enable/disable rows are explicitly specified as "T//R or /OE to A or B" — // a T//R change while /OE stays enabled (switching which side drives) and // an /OE change both contribute to the same figures, so (like 'F245) each // path below is conditioned on both tr and oe_n together: // // tPLH (A to B or B to A) 2.5 / 7.0 ns // tPHL (A to B or B to A) 2.5 / 7.5 ns // tPZH (Output Enable Time) 2.5 / 8.0 ns // tPZL (Output Enable Time) 2.5 / 10.0 ns // tPHZ (Output Disable Time) 2.5 / 8.0 ns // tPLZ (Output Disable Time) 2.5 / 8.0 ns // // A single Prop Delay row in the data sheet covers both directions (A to B // and B to A share the same figures) — the buffers are symmetric. // // DC CHARACTERISTICS gives a much larger table than 'F245's (VOH, VOL, VNL, // VCD, IIH, IIL, IIH+IOZH, ICCH/ICCL/ICCZ); this project's models don't // simulate analog/DC characteristics or current draw. // // Ports are scalar and named after the data sheet pin names: Icarus Verilog // does not fully support multi-bit (parallel) specify path connections, so // vector ports would get incorrect per-bit delays. Each bus pin is a path // DESTINATION in one direction and a SOURCE in the other, so the specify // block carries one statement per scalar pin per direction. // ============================================================================ `timescale 1ns/100ps module f588 ( input wire oe_n, // output enable (active LOW) input wire tr, // direction select: H = A->B (Transmit), L = B->A (Receive) inout wire a0, a1, a2, a3, a4, a5, a6, a7, // bus A (bidirectional) inout wire b0, b1, b2, b3, b4, b5, b6, b7 // bus B (bidirectional), IEEE-488 termination resistors (not modeled, see header) ); // A -> B (Transmit, non-inverting), active when OE_n LOW and TR HIGH wire drive_ab = ~oe_n & tr; // B -> A (Receive, non-inverting), active when OE_n LOW and TR LOW wire drive_ba = ~oe_n & ~tr; assign b0 = drive_ab ? a0 : 1'bz; assign b1 = drive_ab ? a1 : 1'bz; assign b2 = drive_ab ? a2 : 1'bz; assign b3 = drive_ab ? a3 : 1'bz; assign b4 = drive_ab ? a4 : 1'bz; assign b5 = drive_ab ? a5 : 1'bz; assign b6 = drive_ab ? a6 : 1'bz; assign b7 = drive_ab ? a7 : 1'bz; assign a0 = drive_ba ? b0 : 1'bz; assign a1 = drive_ba ? b1 : 1'bz; assign a2 = drive_ba ? b2 : 1'bz; assign a3 = drive_ba ? b3 : 1'bz; assign a4 = drive_ba ? b4 : 1'bz; assign a5 = drive_ba ? b5 : 1'bz; assign a6 = drive_ba ? b6 : 1'bz; assign a7 = drive_ba ? b7 : 1'bz; specify // T_A = +25 C, V_CC = +5.0 V, C_L = 50 pF, min:typ:max ns. // Prop Delay A to B or B to A (data sheet: tPLH 2.5/4.5/6.0, // tPHL 2.5/5.0/6.5) — one row covers both directions. specparam tlh = 2.5:4.5:6.0; specparam thl = 2.5:5.0:6.5; // Output Enable Time, T//R or /OE to A or B (data sheet: // tPZH 2.5/5.0/7.0, tPZL 2.5/7.0/9.0) specparam tzh = 2.5:5.0:7.0; specparam tzl = 2.5:7.0:9.0; // Output Disable Time, T//R or /OE to A or B (data sheet: // tPHZ 2.5/5.5/7.0, tPLZ 2.5/5.5/7.0) specparam thz = 2.5:5.5:7.0; specparam tlz = 2.5:5.5:7.0; // A -> B direction: bus B pins are the path destinations (a0, tr, oe_n => b0) = (tlh, thl, tlz, tzh, thz, tzl); (a1, tr, oe_n => b1) = (tlh, thl, tlz, tzh, thz, tzl); (a2, tr, oe_n => b2) = (tlh, thl, tlz, tzh, thz, tzl); (a3, tr, oe_n => b3) = (tlh, thl, tlz, tzh, thz, tzl); (a4, tr, oe_n => b4) = (tlh, thl, tlz, tzh, thz, tzl); (a5, tr, oe_n => b5) = (tlh, thl, tlz, tzh, thz, tzl); (a6, tr, oe_n => b6) = (tlh, thl, tlz, tzh, thz, tzl); (a7, tr, oe_n => b7) = (tlh, thl, tlz, tzh, thz, tzl); // B -> A direction: the same physical pins, opposite roles — // bus A pins are the path destinations (b0, tr, oe_n => a0) = (tlh, thl, tlz, tzh, thz, tzl); (b1, tr, oe_n => a1) = (tlh, thl, tlz, tzh, thz, tzl); (b2, tr, oe_n => a2) = (tlh, thl, tlz, tzh, thz, tzl); (b3, tr, oe_n => a3) = (tlh, thl, tlz, tzh, thz, tzl); (b4, tr, oe_n => a4) = (tlh, thl, tlz, tzh, thz, tzl); (b5, tr, oe_n => a5) = (tlh, thl, tlz, tzh, thz, tzl); (b6, tr, oe_n => a6) = (tlh, thl, tlz, tzh, thz, tzl); (b7, tr, oe_n => a7) = (tlh, thl, tlz, tzh, thz, tzl); endspecify endmodule