Skip to content

TTL_74646

Source: Verilog/Shared/support/TTL_74646.v

Where it sits (Simulation): ND120_TOP > ND120_CORE > ND3202D > BIF_5 > BIF_DPATH_9 > BIF_DPATH_CDLBD_11 > TTL_74646 - instance path: CORE.CPU_BOARD.BIF.DPATH.CDLBD.CHIP_7B

Used in: BIF_DPATH_CDLBD_11 (all tops)

Contains: no other modules.

Module hierarchy - All modules

TTL_74646 symbol

Schematic

Drawn from the Verilog: the yosys netlist of the Simulation (Verilator) build, instance CORE.CPU_BOARD.BIF.DPATH.CDLBD.CHIP_7B. Sub-modules are boxes (click the picture to open it full size; there every sub-module box links to its page, and every wire shows its Verilog name).

TTL_74646 schematic

Description

Component : TTL_74646 OCTAL BUS TRANSCEIVERS AND REGISTERS WITH 3-STATE OUTPUTS (None inverting) DOC: https://www.ti.com/lit/ds/symlink/sn54as646.pdf Last reviewed: 14-DEC-2024 Ronny Hansen

Ports

Direction Width Name Description
input 1 sysclk FPGA system clock (used only when USE_SYSCLK_AB/BA=2)
input [7:0] A_IN
input [7:0] B_IN
input 1 CLKAB
input 1 CLKBA
input 1 DIR Direction (1=A to B, 0=B to A)
input 1 OE_n (active low) Output Enable Negated
input 1 SAB Select-Control AB - multiplex stored and real-time (transparent mode) registeres
input 1 SBA Select-Control BA - multiplex stored and real-time (transparent mode) registeres. 0=REAL-TIME
output [7:0] A_OUT
output [7:0] B_OUT

Verilog source

Verilog/Shared/support/TTL_74646.v on GitHub.

Show the Verilog of TTL_74646 (166 lines)
/******************************************************************************
 **                                                                          **
 ** Component : TTL_74646                                                    **
 **                                                                          **
 ** OCTAL BUS TRANSCEIVERS AND REGISTERS WITH 3-STATE OUTPUTS                **
 ** (None inverting)                                                         **
 **                                                                          **
 ** DOC: https://www.ti.com/lit/ds/symlink/sn54as646.pdf                     **
**                                                                           **
 ** Last reviewed: 14-DEC-2024                                               **
 ** Ronny Hansen                                                             **
 *****************************************************************************/

module TTL_74646(
   input sysclk, // FPGA system clock (used only when USE_SYSCLK_AB/BA=2)
   input[7:0] A_IN,
   input[7:0] B_IN,
   input CLKAB,
   input CLKBA,
   input DIR,   // Direction (1=A to B, 0=B to A)
   input OE_n,  // Output Enable Negated
   input SAB,   // Select-Control AB - multiplex stored and real-time (transparent mode) registeres
   input SBA,   // Select-Control BA - multiplex stored and real-time (transparent mode) registeres. 0=REAL-TIME

   output[7:0] A_OUT,
   output[7:0] B_OUT
);

   // USE_SYSCLK_AB / USE_SYSCLK_BA select how the two internal registers
   // capture (independently, one per clock pin):
   //   0 (default): original posedge CLKAB / CLKBA - matches the real chip.
   //   2: sysclk-sampled RISING-EDGE capture (AM29C821 USE_SYSCLK=2
   //      pattern) - the FPGA-safe mode when the clock pin is driven by a
   //      control strobe (ECREQ, BGNT_n ...), not a clock. One capture per
   //      detected rise, no fabric-routed clock net. NOTE: the capture
   //      lands one sysclk AFTER the rise - only safe when the data is
   //      still valid then (start-of-window strobes like ECREQ).
   //   3: sysclk WINDOWED capture - follow the data on every posedge
   //      sysclk while the strobe pin is LOW, hold from the rise on. Ends
   //      holding the value present AT the strobe rise, with no one-cycle
   //      lag - the FPGA-safe mode for END-of-window strobes (DSTB_n,
   //      which marks the end of the memory data window; mode 2 sampled
   //      one cycle late, after the memory stopped driving). Only valid
   //      when the register is not observed during the low window (CDLBD:
   //      SAB=DSTB_n selects real-time data while the strobe is low, so
   //      regA is only read after the rise).
   parameter USE_SYSCLK_AB = 0;
   parameter USE_SYSCLK_BA = 0;



   /*******************************************************************************
   ** The wires are defined here                                                 **
   *******************************************************************************/
   wire s_sab;
   wire s_clkab;
   wire s_sba;
   wire s_clkba;
   wire s_dir;
   wire s_oe_n;


   /*******************************************************************************
   ** The module functionality is described here                                 **
   *******************************************************************************/

   /*******************************************************************************
   ** Here all input connections are defined                                     **
   *******************************************************************************/
   assign s_sab   = SAB;
   assign s_clkab = CLKAB;
   assign s_sba   = SBA;
   assign s_clkba = CLKBA;
   assign s_dir   = DIR;
   assign s_oe_n  = OE_n;



   /*******************************************************************************
   ** Here all in-lined components are defined                                   **
   *******************************************************************************/

   reg [7:0] regA;
   reg [7:0] regB;

   reg [7:0] regA_Delayed;
   reg [7:0] regB_Delayed;


   always@(A_IN)
   begin
      regA_Delayed <= A_IN;
   end

   always@(B_IN, SBA)
   begin
      regB_Delayed <= B_IN;
   end

   generate
      if (USE_SYSCLK_AB == 2) begin : gen_ab_edge
         reg clkab_d = 1'b0;
         always @(posedge sysclk) begin
            clkab_d <= s_clkab;
            if (s_clkab && !clkab_d) regA <= regA_Delayed;
         end
      end else if (USE_SYSCLK_AB == 3) begin : gen_ab_window
         always @(posedge sysclk) begin
            if (!s_clkab) regA <= regA_Delayed;
         end
      end else begin : gen_ab_posedge
         always @(posedge s_clkab )
         begin
            //regA <= A_IN; //Capture directly input signal
            regA <= regA_Delayed; //Capture delayed input signal
         end
      end

      if (USE_SYSCLK_BA == 2) begin : gen_ba_edge
         reg clkba_d = 1'b0;
         always @(posedge sysclk) begin
            clkba_d <= s_clkba;
            if (s_clkba && !clkba_d) regB <= regB_Delayed;
         end
      end else begin : gen_ba_posedge
         always @(posedge s_clkba )
         begin
            //regB <= B_IN;  //Capture directly input signal
            regB <= regB_Delayed; //Capture delayed input signal
         end
      end
   endgenerate


/*
A_OUT:
   If OE_n is not active (low), the output is 0.

   If DIR is 0 (B to A direction):
      If SBA is 0, A_OUT gets real-time data from B_IN.
      If SBA is 1, A_OUT gets stored data from regB.

*/
   // sdir = 0 => B => A

   // s_sba = 0 => Real Time B to A
   // s_sba = 1 => Register  B to A
   assign A_OUT = s_oe_n ? 8'b0 : !s_dir ?  ((!s_sba) ? B_IN : regB) : 8'b0;


/*
B_OUT:
      If OE_n is not active (low), the output is 0.

      If DIR is 1 (A to B direction):
         If SAB is 0, B_OUT gets real-time data from A_IN.
         If SAB is 1, B_OUT gets stored data from regA.
*/

   // sdir = 1 => A => B

   // s_sab = 0 => Real Time A to B
   // s_sab = 1 => Register  A to B
   assign B_OUT = s_oe_n ? 8'b0 : s_dir ?  ((!s_sab) ? A_IN : regA) : 8'b0;

endmodule