Functions And Procedure
Functions:
Verilog में हमारे पास bitwise reduction operators होते हैं जैसे & या |, जो किसी multi-bit signal को एक single bit में reduce कर सकते हैं।
उदाहरण के लिए, अगर कोई signal 8 bit चौड़ा है, तो &signal लिखने से एक output bit मिलेगा जो उन सभी 8 bits का AND होगा।
इसी तरह |signal लिखने से एक output bit मिलेगा जो उन सभी 8 bits का OR होगा।
लेकिन VHDL में ऐसे reduction operators directly available नहीं होते, इसलिए हम अक्सर इन्हें करने के लिए function लिखते हैं।
Function multi-bit input लेता है, उस पर bitwise AND/OR (या XOR) करता है और एक single bit result के रूप में return करता है।
Hardware में यह function gates में synthesize हो जाता है। Function लिखने का फायदा ये है कि हमें बार–बार वही code दोहराना नहीं पड़ता, बल्कि उसी function को बार-बार call करके काम हो जाता है।
यानी VHDL में function एक reusable code block है, जो हमेशा एक value return करता है।
Example: 8 bit Parity Detector
VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity parity_detector_8 is
port (
A : in STD_LOGIC_VECTOR(7 downto 0);
Parity_odd: out STD_LOGIC; -- जब A में '1' की गिनती odd हो
Parity_even: out STD_LOGIC -- जब A में '1' की गिनती even हो
);
end entity;
architecture rtl of parity_detector_8 is
-- Function declare किया गया है architecture के अंदर
function reduce_xor(vec : STD_LOGIC_VECTOR) return STD_LOGIC is
variable r : STD_LOGIC := '0';
begin
for i in vec'range loop
-- xor accumulative reduction
r := r xor vec(i);
end loop;
return r; -- अगर '1' की गिनती odd है तो '1' return करेगा, वरना '0'
end function;
begin
-- Function call
Parity_odd <= reduce_xor(A);
Parity_even <= not reduce_xor(A);
end architecture;
Elaborated Diagram:

Synthesis:

Simulation:

यह एक parity detector का उदाहरण है, जो error detection का एक आसान तरीका है।
Parity checking industry में functional safety के लिए बहुत उपयोगी है। CRC, SECDED, sniffers जैसी और techniques भी होती हैं, लेकिन parity सबसे basic और general circuit है।
ऊपर के example में हमने odd और even दोनों parity निकाले।
क्योंकि design में कई जगह parity की ज़रूरत पड़ सकती है, हमने इसे function में लिखा।
हर बार function call करने पर यह logic execute होता है और hardware generate करता है।
इससे code clean और reusable हो जाता है।
Functions कहाँ declare किए जाते हैं?
VHDL में function declare करने के दो तरीके हैं:
Package के अंदर
इससे function reusable हो जाता है। कोई भी design package को use work.pkg_name.all; लिखकर function call कर सकता है।
VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package reduction_pkg is
function reduce_and(vec : STD_LOGIC_VECTOR) return STD_LOGIC;
function reduce_or(vec : STD_LOGIC_VECTOR) return STD_LOGIC;
function reduce_xor(vec : STD_LOGIC_VECTOR) return STD_LOGIC;
end package;
package body reduction_pkg is
function reduce_and(vec : STD_LOGIC_VECTOR) return STD_LOGIC is
variable result : STD_LOGIC := '1';
begin
for i in vec'range loop
result := result and vec(i);
end loop;
return result;
end function;
function reduce_or(vec : STD_LOGIC_VECTOR) return STD_LOGIC is
variable result : STD_LOGIC := '0';
begin
for i in vec'range loop
result := result or vec(i);
end loop;
return result;
end function;
function reduce_xor(vec : STD_LOGIC_VECTOR) return STD_LOGIC is
variable result : STD_LOGIC := '0';
begin
for i in vec'range loop
result := result xor vec(i);
end loop;
return result;
end function;
end package body;
Design File में Package का उपयोग:
VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.reduction_pkg.all; -- import package
entity reduction_example is
port (
A : in STD_LOGIC_VECTOR(7 downto 0);
Y_and : out STD_LOGIC;
Y_or : out STD_LOGIC;
Y_xor : out STD_LOGIC
);
end entity;
architecture rtl of reduction_example is
begin
-- Function calls
Y_and <= reduce_and(A); -- Verilog &A जैसा
Y_or <= reduce_or(A); -- Verilog |A जैसा
Y_xor <= reduce_xor(A); -- Verilog ^A जैसा
end architecture;
Elaborated Diagram:

Synthesis:

Simulation:

दूसरा तरीका यह है कि फ़ंक्शन को किसी entity की architecture के अंदर घोषित किया जाए। इस स्थिति में, फ़ंक्शन केवल उसी entity के लिए उपलब्ध रहेगा और अन्य जगह पर पुनः उपयोग नहीं किया जा सकता। हमने यह ऊपर parity detector के उदाहरण में देखा है।
नोट: फ़ंक्शन की घोषणा compilation समय पर होगी, लेकिन synthesis और execution फ़ंक्शन के कॉल किए जाने के समय पर होगा।
जब Function सब कर सकता है तो Procedure क्यों?
VHDL में function और procedure देखने में मिलते-जुलते हैं, पर काम अलग है।
-
Function हमेशा सिर्फ एक value return करता है। Function के अंदर return keyword का मतलब है – “ये मेरा final answer है।”
-
Procedure multiple outputs दे सकता है, और ये outputs उसके parameters (out या inout) से मिलते हैं।
Procedure में return; लिखने का मतलब value देना नहीं, बल्कि “execution यहीं खत्म करो और बाहर निकल जाओ” होता है।
अगर बीच में return; लिखा है, तो उसके बाद का code skip हो जाएगा।
सोचना आसान बनाने के लिए:
-
Function = एक answer sheet जिसमें हमेशा एक final result लिखा होगा।
-
Procedure = एक teacher जो कई students को अलग-अलग answers एक साथ दे सकता है। अगर teacher अचानक बोले “class खत्म” (यानी return;), तो lecture वहीं रुक जाएगा, लेकिन जो answers अब तक दिए गए हैं वो students के पास रहेंगे।
VHDL
library ieee;
use ieee.std_logic_1164.all;
entity proc_example is
port(
data : in std_logic_vector(7 downto 0);
high4 : out std_logic_vector(3 downto 0);
low4 : out std_logic_vector(3 downto 0)
);
end entity;
architecture rtl of proc_example is
procedure split_nibbles (
signal x : in std_logic_vector(7 downto 0);
signal upper : out std_logic_vector(3 downto 0);
signal lower : out std_logic_vector(3 downto 0)
) is
begin
-- अगर input "00000000" है तो जल्दी exit कर दो
if x = "00000000" then
upper <= "0000";
lower <= "0000";
return; -- procedure यहीं खत्म
end if;
-- वरना 8-bit को upper और lower 4 bits में split करो
upper <= x(7 downto 4);
lower <= x(3 downto 0);
end procedure;
begin
-- Procedure call
process(data)
begin
split_nibbles(data, high4, low4);
end process;
end rtl;
Behavior:
-
अगर data = "00000000" है → दोनों outputs "0000" होंगे और procedure वहीं exit हो जाएगा।
-
अगर data non-zero है → upper nibble और lower nibble assign होंगे।