NCL Decoder Implementation

Design Recap

The circuit diagram of the decoder:

DMUX2

This decoder will be generic, and be implemented much like the MUX.

Implementation

Each row will be generated based on it’s index. For each input:

  • If it is set:
    • Use DATA0 for the DATA0 of that case’s output
    • Use DATA1 for the DATA1 of that case’s output
  • If it is clear:
    • Use DATA1 for the DATA0 of that case’s output
    • Use DATA0 for the DATA1 of that case’s output

The DATA0 output sets are combined with a THN1, and the DATA1 outputs are combined with a THNN:

Rows: for i in 0 to NumOutputs - 1 generate
  cntlBits: for iBit in 0 to NumInputs - 1 generate
    Cntl0Selection: if (to_signed(2**iBit, NumInputs+1) and to_signed(i, NumInputs+1)) = 0 generate
      Gate0Inputs(i)(iBit) <= inputs(iBit).DATA1;
      Gate1Inputs(i)(iBit) <= inputs(iBit).DATA0;
    end generate;

    Cntl1Selection: if (to_signed(2**iBit, NumInputs+1) and to_signed(i, NumInputs+1)) > 0 generate
      Gate0Inputs(i)(iBit) <= inputs(iBit).DATA0;
      Gate1Inputs(i)(iBit) <= inputs(iBit).DATA1;
    end generate;
  end generate;

  Gate0: THmn
    generic map(N => NumInputs, M => 1)
    port map(inputs => Gate0Inputs(i),
             output => outputs(i).DATA0);
  Gate1: THmn
    generic map(N => NumInputs, M => NumInputs)
    port map(inputs => Gate1Inputs(i),
             output => outputs(i).DATA1);
end generate;

This assigns input cases to the gates. If any non-selected values are asserted, then the DATA0 line of that case is asserted.

Adding the declarations around it:

library ieee;
use ieee.std_logic_1164.all;
use work.ncl.all;
use ieee.numeric_std.all;

entity Decoder is
  generic(NumInputs : integer := 2);
  port(inputs  : in  ncl_pair_vector(0 to NumInputs-1);
       outputs : out ncl_pair_vector(0 to (2**NumInputs)-1));
end entity Decoder;

architecture structural of Decoder is
  constant NumOutputs : integer := 2 ** NumInputs;

  type GateInputs is array (integer range <>) of std_logic_vector(0 to NumInputs - 1);
  signal Gate0Inputs : GateInputs(0 to NumOutputs-1);
  signal Gate1Inputs : GateInputs(0 to NumOutputs-1);
begin
  Rows: for i in 0 to NumOutputs - 1 generate
    cntlBits: for iBit in 0 to NumInputs - 1 generate
      Cntl0Selection: if (to_signed(2**iBit, NumInputs+1) and to_signed(i, NumInputs+1)) = 0 generate
        Gate0Inputs(i)(iBit) <= inputs(iBit).DATA1;
        Gate1Inputs(i)(iBit) <= inputs(iBit).DATA0;
      end generate;

      Cntl1Selection: if (to_signed(2**iBit, NumInputs+1) and to_signed(i, NumInputs+1)) > 0 generate
        Gate0Inputs(i)(iBit) <= inputs(iBit).DATA0;
        Gate1Inputs(i)(iBit) <= inputs(iBit).DATA1;
      end generate;
    end generate;

    Gate0: THmn
             generic map(N => NumInputs, M => 1)
             port map(inputs => Gate0Inputs(i),
                      output => outputs(i).DATA0);
    Gate1: THmn
             generic map(N => NumInputs, M => NumInputs)
             port map(inputs => Gate1Inputs(i),
                      output => outputs(i).DATA1);
  end generate;
end structural;

Testing

I tested it for 2 inputs, to make sure the generics build correctly. The outputs do not go through all combinations, since only one is allowed to be DATA1 at a time. Here’s the test script

Capture

Commit: a58ee22

Leave a Reply