Now that we’ve talked about what NCL is, it’s time to actually make something with it.
For complete project files, see my GitHub
I will be using Modelsim as my IDE (with a little Notepad++) and VHDL. I’ll be starting with simulation, but eventually I want to load something on an FPGA, so I’ll be keeping an eye for synthesis where I can.
Setup
The first thing to do is make a package with some useful types and functions. I’ll call it work.NCL
:
library ieee; use ieee.std_logic_1164.all; package ncl is type ncl_pair is record data0 : std_logic; data1 : std_logic; end record ncl_pair; type ncl_pair_vector is array (integer range <>) of ncl_pair; component THmn is generic(M : integer := 1; N : integer := 1; Delay : time := 1 ns); port(inputs : in std_logic_vector(0 to N-1); output : out std_logic); end component THmn; end ncl;
I’ve decided to make each NCL line be std_logic
to allow the synthesizer to use standard logic functions.
The gates themselves operate on single lines, but components take in pairs, though it could be expanded to triples or higher if needed later. Before, we can do anything else we need to build the NCL Threshold gate.
Implementation
I tried to implement the threshold gate structurally with the generic parameter, but I was unable to make it work, I’ll look into making a structural version someday.
For synthesis, I may need to make parameter-specific components. The generic component could maybe act as an automatic selector, instantiating the correct implementations.
The most basic description of a threshold gate is that it sets when enough inputs are set, when no inputs are set, the output clears, otherwise no action is taken. For now, I have decided to implement the threshold gate without weights, and instead to use repeated inputs (handled by the calling entity) if I need weights. A TH23W2 would be instantiated as a TH24, and the first input would be given twice.
Here goes:
library ieee; use ieee.std_logic_1164.all; use work.ncl.all; entity THmn is generic(M : integer := 1; N : integer := 1; Delay : time := 1 ns); port(inputs : in std_logic_vector(0 to N-1); output : out std_logic := '0'); end THmn; architecture simple of THmn is begin ThresholdGate: process(inputs) variable num_1 : integer; begin num_1 := 0; for i in 0 to N-1 loop if inputs(i) = '1' then num_1 := num_1 + 1; end if; end loop; if num_1 >= M then output <= '1' after Delay; elsif num_1 = 0 then output <= '0' after Delay; end if; end process; end simple;
Essentially, it counts the number of 1’s, and checks for the set and clear conditions.
Testing
I made a test script to help make sure the generics work correctly (and get practice for testing later modules). Part of a test for TH22 is below:
See scripts/tests/test_threshold_gate.tcl on GitHub for my tests.
I have tested it for up to TH77, beyond that it takes too long to run (runtime is 2n). My test file is designed to test every possible transition of input values, in both the output set and clear states.
Thanks for reading. If you have any thoughts on how to improve the design, let me know by message or in the comments.
Commit: 5b852e5