library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- DESCRIPTION: -- This package contains all the physical data related to the circuit, expressed as constants or -- parameters of the model. Procedures and functions definitions also belong to this file. -- The first part of this file is user-modifiable, where the second is not. -- If you modify the second part of this file, BE AWARE OF WHAT ARE YOU DOING. No guarantees -- are given if you modify the second part of this file. -- package NML_definitions is -----------------LIBRARY USER SETTINGS------------------ constant T : real := 300.0; --temperature [K] constant k : real := 1.3806488e-23; --Boltzmann constant [J/K] constant circuit_height : real := 1.0; --total height of the circuit in number of nanomagnets constant wire_Nlenght : integer := 4; --number of nanomagnets into a clock zone --base nanomagnet cell constant cell_height : real := 1.0e-7; --height of a nanomagnet [meters] constant cell_width : real := 5.0e-8; --width of nanomagnet [meters] constant cell_delay : time := 0 ns; --input-output delay constant cell_switchingEnergy : real := 30.0*k*T; --energy related to the switch of a magnet [J] constant DmW_switchingeEnergy : real := 30.0*k*T; --energy related to the switch of a domain wall [J] --clock pulse shape, two levels clock constant clock_T : real := 30.0e-9; --clock period [s] constant Ih: real := 2.0e-3; -- high level current [A] constant Il: real := 1.0e-3; -- low level current [A] constant t1: real := 1.0e-10; -- duration of transition 0 -> Ih [s] constant t2: real := 0.5e-10; -- start of transition Ih -> Il [s] constant t3: real := 1.0e-10; -- end of transition Ih -> Il [s] constant t4: real := 1.0e-10; -- start of transition Il -> 0 [s] --clock wire constants constant clock_wire_resistivity : real := 1.68e-8; --[Ohm*m] -- Copper constant clock_wire_height : real := 800.0e-9; --[m] ----------------END LIBRARY USER SETTINGS----------------------------------------------- ---------------------------DO NOT TOUCH ANYTHING BELOW THIS-------------------------- --generic constants constant NParameters : integer := 3; --number of model parameters constant par_PWR : integer := 0; --position of switching power in PARAM_DATA constant par_countCZ : integer := 1; --position of count Clock Zones number in PARAM_DATA constant par_height_layout : integer := 2; --position of the height of the layout in PARAM_DATA --clock constants constant clock_f : real := 1.0/clock_T; --clock frequency [Hz] --base cell constants constant cell_switchingPower : real := cell_switchingEnergy / clock_T; constant DmW_switchingPower : real := DmW_switchingeEnergy / clock_T; constant cell_NInput : integer := 2; --useless constant cell_NOutput : integer := 1; --useless --data type type cellAccess_type is (VERTICAL, NORMAL); --normal= inverting cell, VERTICAL = non inverting cell type wireDirection_type is (FORWARD, BACK); --FORWARD= wire is going in the right direction, BACK: left direction type param_data is array(0 to NParameters -1) of real ; --vector including parameters of the model such as power consumption and area type param_data_vector is array(integer range <>) of param_data; --wire constants constant wire_NclkZones : integer := 1; --extension of a wire, in terms of clock zones constant clock_wire_width : real := real(wire_Nlenght)*cell_width; --[m] number of base cell in a clock zone --constant clock_wire_length : real := 100.0e-7; --[m] *** -------------------------------------------------------------------------------------------------- -- *** depends on the physical structure of the clock: -- if the clock is implemented with a single path, clock_wire_length will be estimated as follows: -- clock_wire_length = (height of the circuit) + 3*clock_wire_width -------------------------------------------------------------------------------------------------- -- procedures definition procedure clock_zones_numb_selector (signal input_params: in param_data_vector; signal critical_path: out real; NInput: in integer); procedure clock_zones_numb_increase (signal input_params: in param_data; direction: in wireDirection_type; signal critical_path: out real); procedure clock_power_estimator (signal N_clock_zones: in real; signal power_consumption: out real; signal input_params: in param_data_vector; NInput: in integer); end NML_definitions; package body NML_definitions is --This procedure gets in input all the param_data elements, extracts their parameter "par_countCZ" --and then provides at its output the greatest of them, which is the local critical path (in terms of clock zones) procedure clock_zones_numb_selector (signal input_params: in param_data_vector; signal critical_path: out real; NInput: in integer) is variable temp_param_in: param_data:= ( others => 0.0 ); --support variable used to extract data from a more complex structure variable temp_number: real := -99.0; begin temp_param_in := input_params(0); --extract the first param_data from the param_data_vector if NInput = 1 then critical_path <= temp_param_in(par_countCZ); --only one input: no need to process data else temp_number := temp_param_in(par_countCZ); --initialization for i in 1 to (NInput-1) loop --this loop finds the biggest number of clock zones in input temp_param_in := input_params(i); if temp_param_in(par_countCZ) > temp_number then temp_number := temp_param_in(par_countCZ); end if; end loop; critical_path <= temp_number; --the biggest number of clock zones belongs to the local critical path end if; end clock_zones_numb_selector; --This procedure increments the number of clock zones when the "token" passes thorough --a register (which emulates a clock zone) procedure clock_zones_numb_increase (signal input_params: in param_data; direction: in wireDirection_type; signal critical_path: out real) is begin if direction = FORWARD then critical_path <= input_params(par_countCZ) + 1.0; elsif direction = BACK then critical_path <= input_params(par_countCZ) - 1.0; end if; end clock_zones_numb_increase; --This procedure computes the power consumption due to the clock procedure clock_power_estimator (signal N_clock_zones: in real; signal power_consumption: out real; signal input_params: in param_data_vector; NInput: in integer) is variable R : real := 0.0; variable temp_param_in: param_data:= ( others => 0.0 ); --support variable used to extract data from a more complex structure variable total_switching_power: real := 0.0; --needed initialization variable clock_wire_length : real := 0.0; begin --this loop sums all the switching power from all the inputs for i in 0 to (NInput-1) loop temp_param_in := input_params(i); total_switching_power := total_switching_power + temp_param_in(par_PWR); end loop; ------------------------------------------------------------ -- clock wire Resistance estimation temp_param_in(par_height_layout) := cell_height*circuit_height; -- height of the layout in [m] (inizializzazione di test, da eliminare dopo l'implementazione) clock_wire_length := temp_param_in(par_height_layout); R := clock_wire_resistivity*(clock_wire_length)/(clock_wire_height*clock_wire_width); --Resistance of the single clock zone ------------------------------------------------------------ --Clock signal shape modelization power_consumption <= N_clock_zones*(R/clock_T)*(((Ih*Ih)*t1/3.0)+((Ih*Ih)*(t2-t1))+((Ih+Ih*(Il-Ih))*(t3-t2))+(((Il-Ih)/3.0)*(t3-t2)*(t3-t2))+(((Il*Il)/3.0)*(t4-clock_T))) + total_switching_power; --power_consumption <= N_clock_zones*(R/2.0)*(Ih*Ih + Il*Il); simpler approximation --rivedere relazione campo-corrente end clock_power_estimator; end NML_definitions;library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; USE ieee.math_real.all; use work.NML_definitions.all; -- DESCRIPTION: -- This package contains all the basic NML blocks, declared as components. -- This file is useful to simplify the writing of VHDL code: insert it in your VHDL code (hence, write -- "use work.NML_components.all" at the beginning of your code). This will avoid you to rewrite -- each time all the NML components (they are so many...it would be a long and boring job!). -- package NML_components is ---------------KERNEL------------- component NML_cell is generic ( delay : time := cell_delay; NInput : integer := cell_NInput; NOutput : integer := cell_NOutput; inputMode : cellAccess_type := NORMAL ); port ( CELL_IN : in std_logic_vector(0 to NInput -1); PARAM_IN : in param_data_vector(0 to NInput -1):= (others => (others=>0.0)); CELL_OUT : out std_logic_vector(0 to NOutput -1); --to avoid fatal errors during simulation PARAM_OUT : out param_data_vector(0 to NOutput -1):= (others => (others=>0.0)) ); end component; component NML_REG is generic(WireDirection : wireDirection_type:= FORWARD ); port ( REG_IN : in std_logic; REG_PARAM_IN : in param_data:= ( others =>0.0); CLK : in std_logic; REG_OUT : out std_logic; REG_PARAM_OUT : out param_data:= ( others =>0.0) ); end component; component NML_DomWall is generic(delay : time := cell_delay; --NInput : integer := cell_NInput; NOutput : integer := cell_NOutput ); port ( CELL_IN : in std_logic;--_vector(0 to NInput -1); PARAM_IN : in param_data :=(others => 0.0);--_vector(0 to NInput -1):= (others => (others=>0.0)); --this initialization is FUNDAMENTAL in order CELL_OUT : out std_logic_vector(0 to NOutput -1); --to avoid fatal errors during simulation PARAM_OUT : out param_data_vector(0 to NOutput -1):= (others => (others=>0.0)) --this initialization is FUNDAMENTAL in order ); --to avoid fatal errors during simulation end component; ----------------BASICS----------------- component nml_basic_and is generic (inputA_access, inputB_access : cellAccess_type:=NORMAL); port ( AND_IN_A : in std_logic; AND_IN_B : in std_logic; A_PARAM_IN : in param_data_vector(0 to 1):=(others => (others=>0.0)); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation AND_OUT : out std_logic; A_PARAM_OUT : out param_data := (others => 0.0) --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation ); end component; component nml_basic_buffer is generic (NOutput : integer := 2); -- 2 <= NOutput <= 3 port( B_IN : in std_logic; B_PARAM_IN : in param_data := (others => 0.0); B_OUT : out std_logic_vector(0 to NOutput -1); B_PARAM_OUT : out param_data_vector(0 to NOutput-1) := (others => (others => 0.0)) ); end component; component nml_basic_crosswire is generic (inputA_access, inputB_access : cellAccess_type:=NORMAL); port ( CRW_IN_A : in std_logic; CRW_IN_B : in std_logic; CRW_PARAM_IN : in param_data_vector(0 to 1):=(others => (others=>0.0)); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation CRW_OUT_A : out std_logic; CRW_OUT_B : out std_logic; CRW_PARAM_OUT : out param_data_vector(0 to 1):=(others => (others=>0.0))--this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation ); end component; component nml_basic_mv is generic (inputA_access, inputC_access : cellAccess_type:=NORMAL); port ( MV_IN_A : in std_logic; MV_IN_B : in std_logic; MV_IN_C : in std_logic; MV_PARAM_IN : in param_data_vector(0 to 2):=(others => (others=>0.0)); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation MV_OUT : out std_logic; MV_PARAM_OUT : out param_data := (others => 0.0) --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation ); end component; component nml_basic_or is generic (inputA_access, inputB_access : cellAccess_type:=NORMAL); port ( Or_IN_A : in std_logic; OR_IN_B : in std_logic; O_PARAM_IN : in param_data_vector(0 to 1):=(others => (others=>0.0)); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation OR_OUT : out std_logic; O_PARAM_OUT : out param_data := ( others =>0.0) --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation ); end component; component nml_basic_wire is generic ( Nlength : integer := wire_Nlenght; input_access : cellAccess_type:=NORMAL; WireDirection : WireDirection_type:= FORWARD); port ( WIRE_IN : in std_logic; W_PARAM_IN : in param_data:= (others => 0.0); WIRE_OUT : out std_logic; W_PARAM_OUT : out param_data:= (others => 0.0) ); end component; ----------------EXTERNAL UNITS----------- component Power_Management_Unit is generic (NInput : integer := 2); port (PARAM_IN: in param_data_vector(0 to NInput -1):= (others => (others=>0.0)); --this initialization is FUNDAMENTAL in order NUMBER_OF_CLOCK_ZONES: out real := -99.0; --this initialization is useful to find errors POWER_DISSIPATION: out real := -99.0 --this initialization is useful to find errors ); end component; end NML_components; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.NML_definitions.all; -- DESCRIPTION: -- This element is the model of a simple nanomagnet. -- It has one entity, but multiple architecture: each one covers one possible -- role covered by a nanomagnet. -- BE CAREFUL: when using it, always specify the architecture of a component, in order -- to avoid strange errors during simulation. -- entity NML_cell is generic(delay : time := cell_delay; NInput : integer := cell_NInput; NOutput : integer := cell_NOutput; inputMode : cellAccess_type := NORMAL ); port ( CELL_IN : in std_logic_vector(0 to NInput -1); PARAM_IN : in param_data_vector(0 to NInput -1):= (others => (others=>0.0)); --this initialization is FUNDAMENTAL in order CELL_OUT : out std_logic_vector(0 to NOutput -1); --to avoid fatal errors during simulation PARAM_OUT : out param_data_vector(0 to NOutput -1):= (others => (others=>0.0)) --this initialization is FUNDAMENTAL in order ); --to avoid fatal errors during simulation end NML_cell; ------------------------------------------------------------ architecture NML_baseCell of NML_cell is signal param_temp_in : param_data:= ( others =>0.0); --support signal used to extract data from a more complex structure signal param_temp_out : param_data:= ( others =>0.0); --support signal used to extract data from a more complex structure begin --POWER ESTIMATOR param_temp_in <= PARAM_IN(0); --extract data from a more complex structure param_temp_out(par_PWR) <= param_temp_in(par_PWR) + cell_switchingPower; --propagates the power consumption data to the end of the circuit param_temp_out(par_countCZ) <= param_temp_in(par_countCZ); --propagates the number of clock zones to the end of the circuit PARAM_OUT(0) <= param_temp_out; --LOGIC FUNCTION CELL_OUT(0) <= not CELL_IN(0) after delay when inputMode = NORMAL else CELL_IN(0) after delay when inputMode = VERTICAL; end NML_baseCell; ------------------------------------------------------------ architecture NML_cellOR of NML_cell is -- ! up to now this gate has only two inputs signal param_temp_in_A : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure signal param_temp_in_B : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure signal param_temp_out : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure begin --POWER ESTIMATOR param_temp_in_A <= PARAM_IN(0); --extract data from a more complex structure param_temp_in_B <= PARAM_IN(NInput-1); --extract data from a more complex structure param_temp_out(par_PWR) <= param_temp_in_A(par_PWR) + param_temp_in_B(par_PWR) + cell_switchingPower; --propagates the power consumption data to the end of the circuit clock_zones_numb_selector (PARAM_IN, param_temp_out(par_countCZ), NInput); PARAM_OUT(0) <= param_temp_out; --LOGIC FUNCTION CELL_OUT(0) <= not (CELL_IN(0) or CELL_IN(NInput-1)) after delay; end NML_cellOR; ---------------------------------------------------------------- architecture NML_cellMV of NML_cell is signal param_temp_out : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure begin --POWER ESTIMATOR PWR_PROC: process(PARAM_IN) --forse la sensitivity list รจ da migliorare! variable temp : real :=0.0; variable param_temp_in : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure begin temp := cell_switchingPower; for i in 0 to (NInput-1) loop param_temp_in := PARAM_IN(i); temp := temp + param_temp_in(par_PWR); end loop; param_temp_out(par_PWR) <= temp; end process PWR_PROC; clock_zones_numb_selector (PARAM_IN, param_temp_out(par_countCZ), NInput); --IS THIS THE RIGHT PLACE? PARAM_OUT(0) <= param_temp_out; --LOGIC FUNCTION process(CELL_IN) variable countZeros, countOnes : integer range 0 to NInput; variable enableOut: integer range 0 to 1; --support variable, used to handle when inputs are 'U' and so on begin countZeros := 0; countOnes := 0; enableOut := 0; for i in 0 to NInput -1 loop if CELL_IN(i) = '0' then countZeros := countZeros + 1; enableOut := 1; else if CELL_IN(i) = '1' then countOnes := countOnes + 1; enableOut := 1; end if; end if; end loop; if enableOut = 1 then if countZeros > countOnes then CELL_OUT(0) <= '0' after delay; --being a voter, it is not contemplated a case of draw else CELL_OUT(0) <= '1' after delay; end if; end if; end process; end NML_cellMV; ------------------------------------------------------------ architecture NML_cellAND of NML_cell is -- ! up to now this gate has only two inputs signal param_temp_in_A : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure signal param_temp_in_B : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure signal param_temp_out : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure begin --POWER ESTIMATOR param_temp_in_A <= PARAM_IN(0); --extract data from a more complex structure param_temp_in_B <= PARAM_IN(NInput-1); --extract data from a more complex structure param_temp_out(par_PWR) <= param_temp_in_A(par_PWR) + param_temp_in_B(par_PWR) + cell_switchingPower; --propagates the power consumption data to the end of the circuit clock_zones_numb_selector (PARAM_IN, param_temp_out(par_countCZ), NInput); PARAM_OUT(0) <= param_temp_out; --LOGIC FUNCTION CELL_OUT(0) <= not (CELL_IN(0) and CELL_IN(NInput-1)) after delay; end NML_cellAND; -------------------------------------------------------------- architecture NML_buffer of NML_cell is signal param_temp_in : param_data:= ( others =>0.0); --support signal used to extract data from a more complex structure signal param_temp_out : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure begin param_temp_in <= PARAM_IN(0); --extract data from a more complex structure param_temp_out(par_PWR) <= ( param_temp_in(par_PWR) + cell_switchingPower) / Real(NOutput);--split evenly the switching power param_temp_out(par_countCZ) <= param_temp_in(par_countCZ); --propagates the number of clock zones to the end of the circuit assign: for i in 0 to (NOutput-1) generate CELL_OUT(i) <= not CELL_IN(0); PARAM_OUT(i) <= param_temp_out; end generate; end NML_buffer; ---------------------------------------------------------------- architecture NML_Cellcrosswire of NML_cell is -- signal declaration signal param_temp_in_A : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure signal param_temp_in_B : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure signal param_temp_out_A : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure signal param_temp_out_B : param_data:= ( others => 0.0 ); --support signal used to extract data from a more complex structure begin --LOGIC FUNCTION process(CELL_IN) begin CELL_OUT(0) <= not CELL_IN(NInput-1) after delay; -- switch the output signals respect to the input configuration CELL_OUT(Noutput-1) <= not CELL_IN(0) after delay; -- nevertheless, inputs are inverted because it is a magnet end process; --PARAMETERS PROPAGATION -- power estimator param_temp_in_A <= PARAM_IN(0); param_temp_in_B <= PARAM_IN(NInput-1); param_temp_out_A(par_PWR) <= param_temp_in_A(par_PWR) + cell_switchingPower; param_temp_out_B(par_PWR) <= param_temp_in_B(par_PWR) + cell_switchingPower; param_temp_out_a(par_countCZ) <= param_temp_in_A(par_countCZ); --propagates the number of clock zones to the end of the circuit param_temp_out_b(par_countCZ) <= param_temp_in_B(par_countCZ); --propagates the number of clock zones to the end of the circuit ------------------------------------------------------------------------- PARAM_OUT(0) <= param_temp_out_B; -- switch the output parameters respect to the input configuration PARAM_OUT(Noutput-1) <= param_temp_out_A; end NML_Cellcrosswire; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.NML_definitions.all; entity NML_DomWall is generic(delay : time := cell_delay; NOutput : integer := cell_NOutput ); port ( CELL_IN : in std_logic;--_vector(0 to NInput -1); PARAM_IN : in param_data := (others => 0.0);--_vector(0 to NInput -1):= (others => (others=>0.0)); --this initialization is FUNDAMENTAL in order CELL_OUT : out std_logic_vector(0 to NOutput -1); --to avoid fatal errors during simulation PARAM_OUT : out param_data_vector(0 to NOutput -1):= (others => (others=>0.0)) --this initialization is FUNDAMENTAL in order ); --to avoid fatal errors during simulation end NML_DomWall; ------------------------------------------------------------ architecture NML_DWbase of NML_DomWall is signal param_temp_in : param_data:= ( others =>0.0); --support signal used to extract data from a more complex structure signal param_temp_out : param_data:= ( others =>0.0); --support signal used to extract data from a more complex structure begin --POWER ESTIMATOR param_temp_in <= PARAM_IN; --extract data from a more complex structure param_temp_out(par_PWR) <= (param_temp_in(par_PWR) + DmW_switchingPower)/ Real(NOutput); --propagates the power consumption data to the end of the circuit param_temp_out(par_countCZ) <= param_temp_in(par_countCZ); --propagates the number of clock zones to the end of the circuit assign: for j in 0 to NOutput-1 generate CELL_OUT(j) <= CELL_IN after delay; PARAM_OUT(j) <= param_temp_out; end generate; end NML_DWbase; library ieee; use ieee.std_logic_1164.all; use work.NML_definitions.all; -- DESCRIPTION: -- This is the fictional register at the end of a clock zone. When the -- clock is high the reg goes in an undefined state, simulating the reset -- state of the nanomagnets inside a clock zone. -- On the falling edge of the clock the reg samples the LOGIC input and its LOGIC output is then valid. -- The PARAM input, instead, is propagated combinatorially -- entity NML_REG is generic(wireDirection: wireDirection_Type := FORWARD); port ( REG_IN : in std_logic; REG_PARAM_IN : in param_data:= (others => 0.0); CLK : in std_logic; REG_OUT : out std_logic; REG_PARAM_OUT : out param_data:= (others => 0.0) ); end NML_REG; architecture Behavior of NML_REG is begin process (CLK) begin if (CLK'event and CLK = '1') then --rising edge -> reset state REG_OUT <= 'Z'; elsif (CLK'event and CLK = '0') then --falling edge -> valid output REG_OUT <= REG_IN; end if; end process; REG_PARAM_OUT(par_PWR) <= REG_PARAM_IN(par_PWR); clock_zones_numb_increase (REG_PARAM_IN, wireDirection ,REG_PARAM_OUT(par_countCZ)); --increments the number of clock zones end Behavior; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.NML_definitions.all; use work.NML_components.all; -- DESCRIPTION: -- This component contains the minimum number of cells to perform the -- AND logic function. It occupies less than one clock zone -- entity nml_basic_and is generic (inputA_access, inputB_access : cellAccess_type:=NORMAL); port ( AND_IN_A : in std_logic; AND_IN_B : in std_logic; A_PARAM_IN : in param_data_vector(0 to 1):=(others => (others=>0.0)); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation AND_OUT : out std_logic; A_PARAM_OUT : out param_data := (others => 0.0) --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation ); end nml_basic_and; architecture AND_model of nml_basic_and is --cell A, cell B signal inputA_out, inputB_out: std_logic; signal inputA_paramOut, inputB_paramOut: param_data :=( others => 0.0 ); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation --cell AND signal cellAND_in: std_logic_vector(0 to 1); signal cellAND_out: std_logic; signal cellAND_paramIn: param_data_vector(0 to 1):= ( others => (others =>0.0 )); --this is a support signal; its initialization is FUNDAMENTAL signal cellAND_paramOut: param_data := (others => 0.0); -- CONFIGURATIONS -- for inputA: NML_cell use entity work.NML_cell(NML_baseCell); for inputB: NML_cell use entity work.NML_cell(NML_baseCell); for cellAND: NML_cell use entity work.NML_cell(NML_cellAnd); begin --Inputs cells inputA: NML_cell generic map( NInput => 1,NOutput => 1, inputMode => VERTICAL) port map(CELL_IN(0) => AND_IN_A, PARAM_IN(0) => A_PARAM_IN(0), CELL_OUT(0) => inputA_out, PARAM_OUT(0) => inputA_paramOut); inputB: NML_cell generic map( NInput => 1,NOutput => 1, inputMode => VERTICAL) port map(CELL_IN(0) => AND_IN_B, PARAM_IN(0) => A_PARAM_IN(1), CELL_OUT(0) => inputB_out, PARAM_OUT(0) => inputB_paramOut); cellAND_in <= inputA_out & inputB_out; cellAND_paramIn(0) <= inputA_paramOut; cellAND_paramIn(1) <= inputB_paramOut; --basic cell which works as an and cell cellAND: NML_cell generic map( NInput => 2, NOutput => 1) port map(CELL_IN => cellAND_in, PARAM_IN => cellAND_paramIn, CELL_OUT(0) => cellAND_out, PARAM_OUT(0) => cellAND_paramOut); --Output AND_OUT <= cellAND_out; A_PARAM_OUT <= cellAND_paramOut; end AND_model; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.NML_definitions.all; use work.NML_components.all; -- DESCRIPTION: -- This component splits the input into 2 or 3 different outputs. -- It has been designed in order to be NON inverting, hence the outputs are -- equal to the input. -- This component occupies less than a clock zone. -- The buffer with 2 outputs is realized in pure NML. Instead, the buffer with -- 3 outputs is realized employing also a Domain wall. There's a little sketch -- below, in the code -- -- STRUCTURE -- ##> -- ># -- ##> entity nml_basic_buffer is generic (NOutput : integer := 4); -- 2 <= NOutput <= 3 port( B_IN : in std_logic; B_PARAM_IN : in param_data := (others => 0.0); B_OUT : out std_logic_vector(0 to NOutput -1); B_PARAM_OUT : out param_data_vector(0 to NOutput-1) := (others => (others => 0.0)) ); end nml_basic_buffer; architecture buffer_model of nml_basic_buffer is signal buffCell_out: std_logic_vector(0 to NOutput-1); signal buffCell_paramOut: param_data_vector(0 to NOutput-1) := (others => (others => 0.0)); signal buffCell_dwout: std_logic_vector(0 to NOutput-1); signal buffCell_dwparamOut: param_data_vector(0 to NOutput-1) := (others => (others => 0.0)); signal vCellUp_out :std_logic; signal vCellUp_paramOut : param_data := (others => 0.0); signal vCellDown_out :std_logic; signal vCellDown_paramOut : param_data := (others => 0.0); begin bc_2_out_buffer: if NOutput = 2 generate for buffCell: NML_cell use entity work.NML_cell(NML_buffer); for vCellUp: NML_cell use entity work.NML_cell(NML_baseCell); for vCellOutUp: NML_cell use entity work.NML_cell(NML_baseCell); for vCellDown: NML_cell use entity work.NML_cell(NML_baseCell); for vCellOutDown: NML_cell use entity work.NML_cell(NML_baseCell); begin --input cell buffCell: NML_cell generic map(NInput => 1, NOutput => NOutput) port map(CELL_IN(0) => B_IN, PARAM_IN(0) => B_PARAM_IN, CELL_OUT => buffCell_out, PARAM_OUT => buffCell_paramOut); --vertical cell over the buffer cell vCellUp: NML_cell generic map(NInput => 1, NOutput => 1, inputMode => VERTICAL) port map(CELL_IN(0) => buffCell_out(0), PARAM_IN(0) => buffCell_paramOut(0), CELL_OUT(0) => vCellUp_out, PARAM_OUT(0) => vCellUp_paramOut); --output cell above vCellOutUp: NML_cell generic map(NInput => 1, NOutput => 1, inputMode => NORMAL) port map(CELL_IN(0) => vCellUp_out, PARAM_IN(0) => vCellUp_paramOut, CELL_OUT(0) => B_OUT(0), PARAM_OUT(0) => B_PARAM_OUT(0)); --vertical cell under the buffer cell vCellDown: NML_cell generic map(NInput => 1, NOutput => 1, inputMode => VERTICAL) port map(CELL_IN(0) => buffCell_out(1), PARAM_IN(0) => buffCell_paramOut(1), CELL_OUT(0) => vCellDown_out, PARAM_OUT(0) => vCellDown_paramOut); --output cell below vCelloutDown:NML_cell generic map(NInput => 1, NOutput => 1, inputMode => NORMAL) port map(CELL_IN(0) => vCellDown_out, PARAM_IN(0) => vCellDown_paramOut, CELL_OUT(0) => B_OUT(1), PARAM_OUT(0) => B_PARAM_OUT(1)); end generate bc_2_out_buffer; ---------------------------------------------------------------------------------------------- -- |IN|| | -> schematic representation of the 3-way buffer -- | | -- |DW| -- | | -- | | -- : : -- | | DW_3_out_buffer: if NOutput = 3 generate for v_cell: NML_cell use entity work.NML_cell(NML_baseCell); begin DWcell: NML_DomWall generic map(NOutput => NOutput) port map(CELL_IN => B_IN, PARAM_IN => B_PARAM_IN, CELL_OUT => buffCell_dwout ,PARAM_OUT => buffCell_dwparamOut); v_cell: NML_cell generic map(NInput => 1, NOutput => 1,inputMode => VERTICAL) port map(CELL_IN(0) => buffCell_dwout(2), PARAM_IN(0) => buffCell_dwparamOut(2), CELL_OUT(0) => B_OUT(2), PARAM_OUT(0) => B_PARAM_OUT(2)); B_OUT(0) <= buffCell_dwout(0); B_OUT(1) <= buffCell_dwout(1); B_PARAM_OUT(0 to 1) <= buffCell_dwparamOut(0 to 1); end generate DW_3_out_buffer; end buffer_model; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.NML_definitions.all; use work.NML_components.all; -- DESCRIPTION: -- This component allows to signals to cross on the same region, without interference -- between them. -- It occupies an entire clock zone -- entity nml_basic_crosswire is generic (inputA_access, inputB_access : cellAccess_type:=NORMAL); port ( CRW_IN_A : in std_logic; CRW_IN_B : in std_logic; CRW_PARAM_IN : in param_data_vector(0 to 1):=(others => (others=>0.0)); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation CRW_OUT_A : out std_logic; CRW_OUT_B : out std_logic; CRW_PARAM_OUT : out param_data_vector(0 to 1):=(others => (others=>0.0))--this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation ); end nml_basic_crosswire; architecture CROSSWIRE_model of nml_basic_crosswire is --cell CROSSWIRE signal cellCRW_in: std_logic_vector(0 to 1); signal cellCRW_out: std_logic_vector(0 to 1); signal cellCRW_paramIn: param_data_vector(0 to 1) := ( others => (others =>0.0 )); --this is a support signal; its initialization is FUNDAMENTAL signal cellCRW_paramOut: param_data_vector(0 to 1) := ( others => (others =>0.0 )); -- CONFIGURATIONS -- for cellA: NML_cell use entity work.NML_cell(NML_baseCell); for cellB: NML_cell use entity work.NML_cell(NML_baseCell); for cellC: NML_cell use entity work.NML_cell(NML_baseCell); for cellD: NML_cell use entity work.NML_cell(NML_baseCell); for cellCRW: NML_cell use entity work.NML_cell(NML_Cellcrosswire); -- structural description of the crosswire begin --Inputs cells cellA: NML_cell generic map( NInput => 1,NOutput => 1, inputMode => inputA_access) port map(CELL_IN(0) => CRW_IN_A, PARAM_IN(0) => CRW_PARAM_IN(0), CELL_OUT(0) => cellCRW_in(0), PARAM_OUT(0) => cellCRW_paramIn(0)); cellB: NML_cell generic map( NInput => 1,NOutput => 1, inputMode => inputB_access) port map(CELL_IN(0) => CRW_IN_B, PARAM_IN(0) => CRW_PARAM_IN(1), CELL_OUT(0) => cellCRW_in(1), PARAM_OUT(0) => cellCRW_paramIn(1)); --crosswire cell cellCRW: NML_cell generic map( NInput => 2,NOutput => 2) port map(CELL_IN => cellCRW_in, PARAM_IN => cellCRW_paramIn, CELL_OUT => cellCRW_out, PARAM_OUT => cellCRW_paramout); --Output cells cellC: NML_cell generic map( NInput => 1,NOutput => 1) port map(CELL_IN(0) => cellCRW_out(0), PARAM_IN(0) => cellCRW_paramout(0), CELL_OUT(0) => CRW_OUT_A, PARAM_OUT(0) => CRW_PARAM_OUT(0)); cellD: NML_cell generic map( NInput => 1,NOutput => 1) port map(CELL_IN(0) => cellCRW_out(1), PARAM_IN(0) => cellCRW_paramout(1), CELL_OUT(0) => CRW_OUT_B, PARAM_OUT(0) => CRW_PARAM_OUT(1)); end CROSSWIRE_model; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.NML_definitions.all; use work.NML_components.all; -- DESCRIPTION: -- This component contains the minimum number of cells to perform the -- Majority Voter function. It occupies less than one clock zone -- entity nml_basic_mv is generic (inputA_access, inputC_access : cellAccess_type:=NORMAL); port ( MV_IN_A : in std_logic; MV_IN_B : in std_logic; MV_IN_C : in std_logic; MV_PARAM_IN : in param_data_vector(0 to 2):=(others => (others=>0.0)); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation MV_OUT : out std_logic; MV_PARAM_OUT : out param_data := (others => 0.0) --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation ); end nml_basic_mv; architecture MV_model of nml_basic_mv is --cells inputA, A2, A3, B, inputC, C2, C3 signal inputA_out, cellA2_out, cellA3_out, cellB_out, inputC_out, cellC2_out, cellC3_out: std_logic; signal inputA_paramOut, cellA2_paramOut, cellA3_paramOut, cellB_paramOut, inputC_paramOut, cellC2_paramOut, cellC3_paramOut: param_data :=( others => 0.0 ); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation --cell MV signal cellMV_in: std_logic_vector(0 to 2); signal cellMV_paramIn: param_data_vector(0 to 2) := ( others => (others =>0.0 )); --this is a support signal; its initialization is FUNDAMENTAL -- CONFIGURATIONS ----------------------------------------------- for inputA: NML_cell use entity work.NML_cell(NML_baseCell); for cellA2: NML_cell use entity work.NML_cell(NML_baseCell); for cellA3: NML_cell use entity work.NML_cell(NML_baseCell); for inputB: NML_cell use entity work.NML_cell(NML_baseCell); for cellMV: NML_cell use entity work.NML_cell(NML_cellMV); for inputC: NML_cell use entity work.NML_cell(NML_baseCell); for cellC2: NML_cell use entity work.NML_cell(NML_baseCell); for cellC3: NML_cell use entity work.NML_cell(NML_baseCell); ----------------------------------------------------------------- begin inputA: NML_cell generic map( NInput => 1, NOutput => 1, inputMode => inputA_access) port map(CELL_IN(0) => MV_IN_A, PARAM_IN(0) => MV_PARAM_IN(0), CELL_OUT(0) => inputA_out, PARAM_OUT(0) => inputA_paramOut); cellA2: NML_cell generic map( NInput => 1, NOutput => 1) port map(CELL_IN(0) => inputA_out, PARAM_IN(0) => inputA_paramOut, CELL_OUT(0) => cellA2_out, PARAM_OUT(0) => cellA2_paramOut); cellA3: NML_cell generic map( NInput => 1, NOutput => 1, inputMode => VERTICAL) port map(CELL_IN(0) => cellA2_out, PARAM_IN(0) => cellA2_paramOut, CELL_OUT(0) => cellA3_out, PARAM_OUT(0) => cellA3_paramOut); inputB: NML_cell generic map( NInput => 1, NOutput => 1) port map(CELL_IN(0) => MV_IN_B, PARAM_IN(0) => MV_PARAM_IN(1), CELL_OUT(0) => cellB_out, PARAM_OUT(0) => cellB_paramOut); inputC: NML_cell generic map( NInput => 1, NOutput => 1, inputMode => inputC_access) port map(CELL_IN(0) => MV_IN_C, PARAM_IN(0) => MV_PARAM_IN(2), CELL_OUT(0) => inputC_out, PARAM_OUT(0) => inputC_paramOut); cellC2: NML_cell generic map( NInput => 1, NOutput => 1) port map(CELL_IN(0) => inputC_out, PARAM_IN(0) => inputC_paramOut, CELL_OUT(0) => cellC2_out, PARAM_OUT(0) => cellC2_paramOut); cellC3: NML_cell generic map( NInput => 1, NOutput => 1,inputMode => VERTICAL) port map(CELL_IN(0) => cellC2_out, PARAM_IN(0) => cellC2_paramOut, CELL_OUT(0) => cellC3_out, PARAM_OUT(0) => cellC3_paramOut); cellMV_in <= cellA3_out & not(cellB_out) & cellC3_out; --some tricks to let this cell behave as a MV, according to the cell layout cellMV_paramIn(0) <= cellA3_paramOut; cellMV_paramIn(1) <= cellB_paramOut; cellMV_paramIn(2) <= cellC3_paramOut; --basic cell which works as MV cell cellMV: NML_cell generic map( NInput => 3, NOutput => 1) port map(CELL_IN => cellMV_in, PARAM_IN => cellMV_paramIn, CELL_OUT(0) => MV_OUT, PARAM_OUT(0) => MV_PARAM_OUT); end MV_model; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.NML_definitions.all; use work.NML_components.all; -- DESCRIPTION: -- This component contains the minimum number of cells to perform the -- OR logic function. It occupies less than one clock zone -- entity nml_basic_or is generic (inputA_access, inputB_access : cellAccess_type:=NORMAL); port ( OR_IN_A : in std_logic; OR_IN_B : in std_logic; O_PARAM_IN : in param_data_vector(0 to 1):=(others => (others=>0.0)); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation OR_OUT : out std_logic; O_PARAM_OUT : out param_data := ( others =>0.0) --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation ); end nml_basic_or; architecture OR_model of nml_basic_or is --cell A, cell B signal inputA_out, inputB_out: std_logic; signal inputA_paramOut, inputB_paramOut: param_data :=( others => 0.0 ); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation --cell OR signal cellOR_in: std_logic_vector(0 to 1); signal cellOR_out: std_logic; signal cellOR_paramIn: param_data_vector(0 to 1) := ( others => (others =>0.0 )); --this is a support signal; its initialization is FUNDAMENTAL signal cellOR_paramOut: param_data :=( others => 0.0 ); --this initialization is FUNDAMENTAL in order to avoid fatal errors during simulation -- CONFIGURATIONS -- for inputA: NML_cell use entity work.NML_cell(NML_baseCell); for inputB: NML_cell use entity work.NML_cell(NML_baseCell); for cellOR: NML_cell use entity work.NML_cell(NML_cellOR); begin --These cells link the signal from the output to the OR cell inputA: NML_cell generic map( NInput => 1, NOutput => 1, inputMode => VERTICAL) port map(CELL_IN(0) => OR_IN_A, PARAM_IN(0) => O_PARAM_IN(0), CELL_OUT(0) => inputA_out, PARAM_OUT(0) => inputA_paramOut); inputB: NML_cell generic map( NInput => 1, NOutput => 1, inputMode => VERTICAL) port map(CELL_IN(0) => OR_IN_B, PARAM_IN(0) => O_PARAM_IN(1), CELL_OUT(0) => inputB_out, PARAM_OUT(0) => inputB_paramOut); cellOR_in <= inputA_out & inputB_out; cellOR_paramIn(0) <= inputA_paramOut; cellOR_paramIn(1) <= inputB_paramOut; --basic cell which works as or cell cellOR: NML_cell generic map( NInput => 2, NOutput => 1) port map(CELL_IN => cellOR_in, PARAM_IN => cellOR_paramIn, CELL_OUT(0) => cellOR_out, PARAM_OUT(0) => cellOR_paramOut); --Output OR_OUT <= cellOR_out; O_PARAM_OUT <= cellOR_paramOut; end architecture; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.NML_definitions.all; use work.NML_components.all; -- DESCRIPTION: -- Model of a nanomagnetic wire composed by Nlength nanomagnets in series and terminated with a flip flop -- which simulates the clock zone. -- This component occupies an entire clock zone. -- entity nml_basic_wire is generic ( Nlength : integer := wire_Nlenght; input_access : cellAccess_type:=NORMAL; WireDirection : WireDirection_type := FORWARD); port ( WIRE_IN : in std_logic; W_PARAM_IN : in param_data:= (others => 0.0); WIRE_OUT : out std_logic; W_PARAM_OUT : out param_data:= (others => 0.0) ); end nml_basic_wire; architecture wire_model of nml_basic_wire is signal wire_signal: std_logic_vector(0 to Nlength - 1); --used to propagate the logic value between the nanomagnets signal wire_param: param_data_vector(0 to Nlength - 1) := (others => (others => 0.0)); --used to propagate the parameters between the nanomagnets --for incell : NML_cell use entity work.NML_cell(NML_baseCell); for outcell : NML_cell use entity work.NML_cell(NML_baseCell); begin --connecting the inputs wire_signal(0) <= WIRE_IN; wire_param(0) <= W_PARAM_IN; --generate the wire gen_wire: for i in 0 to (Nlength-2) generate --the first cell has to be distinguished: its input can be VERTICAL or NORMAL first_cell_gen: if i = 0 generate for first_cell: NML_cell use entity work.NML_cell(NML_baseCell); --configuration of a basic cell ('not' logic function) begin first_cell: NML_cell generic map(NInput => 1, inputMode => input_access) port map(CELL_IN(0) => wire_signal(0), PARAM_IN(0) => wire_param(0), CELL_OUT(0) => wire_signal(1), PARAM_OUT(0) => wire_param(1)); end generate first_cell_gen; --the other cells have certainly their "cellAccess_type" parameter of value NORMAL: generate them all together other_cells_gen: if i /= 0 generate for other_cells : NML_cell use entity work.NML_cell(NML_baseCell); --configuration of a basic cell ('not' logic function) begin other_cells: NML_cell generic map(NInput => 1, inputMode => NORMAL) port map(CELL_IN(0) => wire_signal(i), PARAM_IN(0) => wire_param(i), CELL_OUT(0) => wire_signal(i+1), PARAM_OUT(0) => wire_param(i+1)); end generate other_cells_gen; end generate gen_wire; -- First cell --incell: -- Output cell outcell: NML_cell generic map(NInput => 1, inputMode => NORMAL) port map(CELL_IN(0) => wire_signal(Nlength-1), PARAM_IN(0) => wire_param(Nlength-1), CELL_OUT(0) => WIRE_OUT, PARAM_OUT(0) => W_PARAM_OUT); end wire_model; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.NML_definitions.all; -- DESCRIPTION: -- This component the one which processes the parametric data coming from the layout. -- It has to be used in testbenches, not to describe circuits -- entity Power_Management_Unit is generic (NInput : integer := 2); port (PARAM_IN: in param_data_vector(0 to NInput -1):= (others => (others=>0.0)); --this initialization is FUNDAMENTAL in order NUMBER_OF_CLOCK_ZONES: out real := -99.0; --this initialization is useful to find errors POWER_DISSIPATION: out real := -99.0 --this initialization is useful to find errors ); end Power_Management_Unit; architecture Behavioral of Power_Management_Unit is signal numb_of_clock_zones: real := -100.0; --this initialization is useful to find errors begin clock_zones_numb_selector (PARAM_IN, numb_of_clock_zones, NInput); NUMBER_OF_CLOCK_ZONES <= numb_of_clock_zones; clock_power_estimator(numb_of_clock_zones, POWER_DISSIPATION, PARAM_IN, NInput); end Behavioral;