// ============================================================================ // f373.v — 54F/74F373 Octal Transparent Latch (With 3-State Outputs) // // Fairchild FAST (Advanced Schottky TTL) // Source: docs/devices/54F74F373.txt (1980 Fairchild FAST Data Book, // pages 4-100 ... 4-102) // // Eight D-type latches with 3-state outputs. While Latch Enable (LE) is // HIGH the latches are transparent: O_n follows D_n. When LE is LOW the // latches hold the data present a setup time before the HIGH-to-LOW LE // transition. Output Enable (OE_n) LOW drives the outputs; OE_n HIGH forces // the high-impedance state without disturbing the latches. // // Timing values from the data sheet AC Characteristics table, // 54F/74F column (T_A = +25 C, V_CC = +5.0 V, C_L = 15 pF), min:typ:max ns. // // 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. // ============================================================================ `timescale 1ns/100ps module f373 ( input wire oe_n, // output enable (active LOW) input wire le, // latch enable (active HIGH) input wire d0, d1, d2, d3, // data inputs 0-3 input wire d4, d5, d6, d7, // data inputs 4-7 output wire o0, o1, o2, o3, // 3-state latch outputs 0-3 output wire o4, o5, o6, o7 // 3-state latch outputs 4-7 ); // Transparent latch bank: Q follows D while LE is HIGH, holds while LOW. reg [7:0] q_int; always @(*) begin if (le) q_int <= {d7, d6, d5, d4, d3, d2, d1, d0}; end // 3-state output buffers (OE_n HIGH -> high impedance) assign o0 = oe_n ? 1'bz : q_int[0]; assign o1 = oe_n ? 1'bz : q_int[1]; assign o2 = oe_n ? 1'bz : q_int[2]; assign o3 = oe_n ? 1'bz : q_int[3]; assign o4 = oe_n ? 1'bz : q_int[4]; assign o5 = oe_n ? 1'bz : q_int[5]; assign o6 = oe_n ? 1'bz : q_int[6]; assign o7 = oe_n ? 1'bz : q_int[7]; specify // Propagation delay D_n to O_n (data sheet: tPLH 2.0/4.3/6.5, // tPHL 1.0/2.7/4.5 ns) specparam tlh_d_o = 2.0:4.3:6.5; specparam thl_d_o = 1.0:2.7:4.5; // Propagation delay LE to O_n (data sheet: tPLH 4.0/9.2/13, // tPHL 2.0/4.2/6.5 ns) specparam tlh_le_o = 4.0:9.2:13; specparam thl_le_o = 2.0:4.2:6.5; // Output enable/disable time OE_n to O_n (data sheet: // tPZH 3.0/6.8/11, tPZL 3.0/6.0/10, tPHZ 3.0/5.7/9.0, // tPLZ 3.0/6.2/9.0 ns; disable times measured with C_L = 5 pF) specparam tzh_oe_o = 3.0:6.8:11; specparam tzl_oe_o = 3.0:6.0:10; specparam thz_oe_o = 3.0:5.7:9.0; specparam tlz_oe_o = 3.0:6.2:9.0; // 6-delay form, IEEE order (0->1, 1->0, 0->Z, Z->1, 1->Z, Z->0): // D_n causes only 0->1/1->0 transitions, OE_n only Z transitions. (oe_n, d0 => o0) = (tlh_d_o, thl_d_o, tlz_oe_o, tzh_oe_o, thz_oe_o, tzl_oe_o); (oe_n, d1 => o1) = (tlh_d_o, thl_d_o, tlz_oe_o, tzh_oe_o, thz_oe_o, tzl_oe_o); (oe_n, d2 => o2) = (tlh_d_o, thl_d_o, tlz_oe_o, tzh_oe_o, thz_oe_o, tzl_oe_o); (oe_n, d3 => o3) = (tlh_d_o, thl_d_o, tlz_oe_o, tzh_oe_o, thz_oe_o, tzl_oe_o); (oe_n, d4 => o4) = (tlh_d_o, thl_d_o, tlz_oe_o, tzh_oe_o, thz_oe_o, tzl_oe_o); (oe_n, d5 => o5) = (tlh_d_o, thl_d_o, tlz_oe_o, tzh_oe_o, thz_oe_o, tzl_oe_o); (oe_n, d6 => o6) = (tlh_d_o, thl_d_o, tlz_oe_o, tzh_oe_o, thz_oe_o, tzl_oe_o); (oe_n, d7 => o7) = (tlh_d_o, thl_d_o, tlz_oe_o, tzh_oe_o, thz_oe_o, tzl_oe_o); (le => o0) = (tlh_le_o, thl_le_o); (le => o1) = (tlh_le_o, thl_le_o); (le => o2) = (tlh_le_o, thl_le_o); (le => o3) = (tlh_le_o, thl_le_o); (le => o4) = (tlh_le_o, thl_le_o); (le => o5) = (tlh_le_o, thl_le_o); (le => o6) = (tlh_le_o, thl_le_o); (le => o7) = (tlh_le_o, thl_le_o); // AC operating requirements (data sheet, +25 C 5.0 V minima): // ts(H) 2.0, ts(L) 2.0, th(H) 3.0, th(L) 3.0, tw(H) LE 6.0 ns. // Setup/hold are relative to the HIGH-to-LOW LE edge that closes // the latch. Icarus Verilog does not support timing checks; kept // (guarded) for simulators that do. `ifndef __ICARUS__ specparam ts_h = 2.0; specparam ts_l = 2.0; specparam th_h = 3.0; specparam th_l = 3.0; specparam tw_le_h = 6.0; $setup(d0, negedge le, ts_h); $setup(d1, negedge le, ts_h); $setup(d2, negedge le, ts_h); $setup(d3, negedge le, ts_h); $setup(d4, negedge le, ts_h); $setup(d5, negedge le, ts_h); $setup(d6, negedge le, ts_h); $setup(d7, negedge le, ts_h); $hold(negedge le, d0, th_h); $hold(negedge le, d1, th_h); $hold(negedge le, d2, th_h); $hold(negedge le, d3, th_h); $hold(negedge le, d4, th_h); $hold(negedge le, d5, th_h); $hold(negedge le, d6, th_h); $hold(negedge le, d7, th_h); $width(posedge le, tw_le_h); `endif endspecify endmodule