// ============================================================================ // f545.v — 54F/74F545 Octal Bidirectional Transceiver (3-State Inputs/Outputs) // // Fairchild FAST (Advanced Schottky TTL) // Source: docs/devices/54F74F545.txt (1985 Fairchild FAST Data Book, // pages 4-416 ... 4-418; the 1980 data book carries the 'F545 in its // Section 3 selection guide only, page 3-29. 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. // // 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. // // Functionally identical to 'F245: a single T//R select bit means exactly one // direction (or neither, under /OE HIGH) can ever be active, so there is no // independent-enable hazard here. See src/f245.v's header comment (and, for // the full backstory on why the T//R-style transceivers are structurally // immune to the both-directions-enabled contention 'F242/'F243 carry, // src/f242.v's and src/f243.v's). // // 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: // // tPLH/tPHL (An to Bn or Bn to An) 2.5 / 7.0 ns / 2.5 / 7.0 ns // tPZH (Output Enable Time) 3.0 / 8.0 ns // tPZL (Output Enable Time) 3.5 / 9.0 ns // tPHZ (Output Disable Time) 3.0 / 7.5 ns // tPLZ (Output Disable Time) 2.0 / 7.5 ns // // A single Prop Delay row in the data sheet covers both directions (An to Bn // and Bn to An share the same figures) — the buffers are symmetric. These // figures are numerically identical to 'F245's AC table. // // DC CHARACTERISTICS gives ICCH/ICCL/ICCZ power-supply-current figures only; // this project's models don't simulate 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. // // Pinout (20-pin DIP) differs from 'F245's physical arrangement (A0..A7 on // pins 1-8, /OE on 9, GND on 10, T//R on 11, B7..B0 descending on 12-19, // Vcc on 20) even though the port list below is unaffected, since this // project's ports are named/scalar rather than positional and Icarus does // not model physical pin numbers. // ============================================================================ `timescale 1ns/100ps module f545 ( input wire oe_n, // pin 9: output enable (active LOW) input wire tr, // pin 11: direction select: H = A->B (Transmit), L = B->A (Receive) inout wire a0, a1, a2, a3, a4, a5, a6, a7, // pins 1-8: bus A (bidirectional) inout wire b0, b1, b2, b3, b4, b5, b6, b7 // pins 19-12: bus B (bidirectional) ); // 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 An to Bn or Bn to An (data sheet: tPLH 2.5/4.2/6.0, // tPHL 2.5/4.6/6.0) — one row covers both directions. specparam tlh = 2.5:4.2:6.0; specparam thl = 2.5:4.6:6.0; // Output Enable Time (data sheet: tPZH 3.0/5.3/7.0, tPZL 3.5/6.0/8.0) specparam tzh = 3.0:5.3:7.0; specparam tzl = 3.5:6.0:8.0; // Output Disable Time (data sheet: tPHZ 3.0/5.0/6.5, tPLZ 2.0/5.0/6.5) specparam thz = 3.0:5.0:6.5; specparam tlz = 2.0:5.0:6.5; // 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