# explanation of VHDL Coding

Status
Not open for further replies.

#### knjr

##### Newbie level 6 library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity my_counter5 is
port(count: Out std_logic_vector(7 downto 0);
clk: in std_logic;
reset: in std_logic);
end my_counter5;

architecture behav_my_counter5 of my_counter5 is

signal c : std_logic_vector(7 downto 0) := "00000000";

begin

ctr:

process(clk,reset)
variable carry : std_logic_vector(7 downto 0) := "00000000";
begin

if reset'event and(reset = '1') then
c <= (others => '0');

elsif clk'event and (clk = '1') then
--i am adding "00000001" to 'c'.
--this is done using basic logic gates.
-- the equation for full adder is simplified and written below.
--full adder equations are:
-- sum = A xor B xor Carry.
-- carry = (A and B) or (A and carry) or (B and carry).
--subsititue B with "00000001" here and you will get the below equations.
c(0) <= not c(0);
carry(0) := c(0);
c(1)<= c(1) xor carry(0);
carry(1) := c(1) and carry(0);
c(2)<= c(2) xor carry(1);
carry(2) := c(2) and carry(1);
c(3)<= c(3) xor carry(2);
carry(3) := c(3) and carry(2);
c(4)<= c(4) xor carry(3);
carry(4) := c(4) and carry(3);
c(5)<= c(5) xor carry(4);
carry(5) := c(5) and carry(4);
c(6)<= c(6) xor carry(5);
carry(6) := c(6) and carry(5);
c(7)<= c(7) xor carry(6);
carry(7) := c(7) and carry(6);

end if;

end process;

count <= c;

end behav_my_counter5;

Hi there, can someone explain the whole coding to me? Because i don't know what's going on. As I just get to know that there's such coding last month only. & I'm urgently need help in it. Thanks alot!

#### yousufislahi

##### Newbie level 4 Basically the program is for the counter, whnever clock goes high the counter is incremented.
see the comments below..

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity my_counter5 is
port(count: Out std_logic_vector(7 downto 0);
clk: in std_logic;
reset: in std_logic);
end my_counter5;

architecture behav_my_counter5 of my_counter5 is

signal c : std_logic_vector(7 downto 0) := "00000000";

begin

ctr:

process(clk,reset)
variable carry : std_logic_vector(7 downto 0) := "00000000";
begin

if reset'event and(reset = '1') then // if the reset button is high or if it is pressed than set the counter to "00000000"

c <= (others => '0');

elsif clk'event and (clk = '1') then // if clk =1, rising edge of the clock update the counter

--i am adding "00000001" to 'c'.
--this is done using basic logic gates.
-- the equation for full adder is simplified and written below.
--full adder equations are:
-- sum = A xor B xor Carry.
-- carry = (A and B) or (A and carry) or (B and carry).
--subsititue B with "00000001" here and you will get the below equations.
c(0) <= not c(0);
carry(0) := c(0);
c(1)<= c(1) xor carry(0);
carry(1) := c(1) and carry(0);
c(2)<= c(2) xor carry(1);
carry(2) := c(2) and carry(1);
c(3)<= c(3) xor carry(2); // this complete code is fulladder implementattion as your code gives the explanation

carry(3) := c(3) and carry(2);
c(4)<= c(4) xor carry(3);
carry(4) := c(4) and carry(3);
c(5)<= c(5) xor carry(4);
carry(5) := c(5) and carry(4);
c(6)<= c(6) xor carry(5);
carry(6) := c(6) and carry(5);
c(7)<= c(7) xor carry(6);
carry(7) := c(7) and carry(6);

end if;

end process;

count <= c;

end behav_my_counter5;

just see the comment and try to analyze the code atill if you didinot understand than post reply.
Thank you

#### knjr

##### Newbie level 6 Sorry, is it possible to explain from the top onwards?

#### FvM

##### Super Moderator
Staff member Sorry, is it possible to explain from the top onwards?
I think, reading a VHDL text book may be more effective.

To understand the code's functionality, I would refer to this equivalent form:
Code:
process(clk,reset)
begin
if reset = '1' then
c <= (others => '0');
elsif clk'event and (clk = '1') then
c <= c + 1;
end if;
end process;
The original code isn't synthesizable due to this line
Code:
if reset'event and(reset = '1') then
It defines a second edge sensitive event for c, corresponding to flip-flops with two clock inputs, that don't exist. It has to be replaced by a asynchronous or synchronous reset. The basic counter can be found in any VHDL tect book, I guess.

The original code uses low level adders to make the counter respectively the "+1" addition. May be for educational purposes. If you are interested in this topic, you should read about adders, see e.g. ). It's not particularly a VHDL problem.

#### knjr

##### Newbie level 6 Hi, I understand the coding for the +1. Now i don't understand the part that is
What does each line tells?

c(0) <= not c(0);
carry(0) := c(0);
c(1)<= c(1) xor carry(0);
carry(1) := c(1) and carry(0);
c(2)<= c(2) xor carry(1);
carry(2) := c(2) and carry(1);
c(3)<= c(3) xor carry(2); // this complete code is fulladder implementattion as your code gives the explanation

carry(3) := c(3) and carry(2);
c(4)<= c(4) xor carry(3);
carry(4) := c(4) and carry(3);
c(5)<= c(5) xor carry(4);
carry(5) := c(5) and carry(4);
c(6)<= c(6) xor carry(5);
carry(6) := c(6) and carry(5);
c(7)<= c(7) xor carry(6);
carry(7) := c(7) and carry(6);

#### lucbra

##### Advanced Member level 2 Really, look at the link that FvM gave. It explains what has been coded.

PS you can also try googling 'Full Adder'

#### knjr

##### Newbie level 6 Hi, I try to read but it seem like I can't understand it clearly.
Can roughly what does each lines does?

#### lucbra

##### Advanced Member level 2 Hi, I try to read but it seem like I can't understand it clearly.
Can roughly what does each lines does?

Of course I can, but you won't be any wiser

compare the schematics of the full adder on wikipedia with what has been coded.
Maybe you'll find some similarities. As such you will probably understand it.

2nd option: (actually the first thing you need to do) Take a book about VHDL, study the easy examples about and, or, FF, ... (these are usually in the first chapters) and you will certainly understand the code for a full adder

#### knjr

##### Newbie level 6 Alright, I will give it a try. Because I got no time to read a book of vhdl book as my assignment soon need to be hand in. Thanks anyway #### lucbra

##### Advanced Member level 2 Alright, I will give it a try. Because I got no time to read a book of vhdl book as my assignment soon need to be hand in. Thanks anyway The time you spend on writing and responding here could have been used for reading the first couple of chapters

• FvM

### FvM

Points: 2

#### FvM

##### Super Moderator
Staff member There's of course a small difference to the general full adder. B="00000001" is added here. So different from the full adder in the link, constant "1" respectively "0" is put in for the B bits and the logic is reduced respectively.

#### knjr

##### Newbie level 6 Code:
		c(0) <= not c(0);
carry(0) := c(0);

c(1) <= c(1) xor carry(0);
carry(1) := c(1) and carry(0);

c(2)<= c(2) xor carry(1);
carry(2) := c(2) and carry(1);

Hi, I could get the waveform from 00000000, 00000001, 000000010, 00000011.
But I don't understand how it get with the coding above. I understand the first 2 lines.
But from 3rd lines onwards, I couldn't understand.

When i work out, I get c(1) = '1' - 00000010
carry(1) = '1' - 00000010

c(2) = '1' - 00000100
carry(2) = '1' 00000100

Is this the correct way of doing?

#### lucbra

##### Advanced Member level 2 do you know what XOR and AND means? If you don't, see XOR gate and AND gate

for the rest, pretty straightforward.
C and carry are two vectors ( arrays of std_logic).
bit 1 of vector c (c(0)) will be assigned the value of itself (c(1)) exor'ed with the zeroth bit of the carry vector (carry(0))
in other words : c(1) <= c(1) XOR carry(0)

#### knjr

##### Newbie level 6 Hi, I know what does XOR and AND means.
I know how it works. Just that I don't know how it get to jump from 00000001 to 00000010 to 00000011. When I work out the coding, I only could get 00000001. 00000010

#### FvM

##### Super Moderator
Staff member Unfortunately, you don't show which input vector c is described in your example. If it's "00000010", then there will be no carry. I guess, you don't consider the behaviour of signal assignments <=. The signals are updated after the process is finished, while variable assignments := get effective immediately.

#### knjr

##### Newbie level 6 Hi, I got question.

Code:
C(0) <= NOT c(0);
Carry(0) := c(0);

C(1) <= c(1) XOR carry (0)
Carry(1) := c(1) AND c(0)

If I were to keep contiune process. I would need to run again and again.
I got mix up.

00
01
10
11

I should get this result
I try to work it out but I got confuse.

C(0) <= NOT c(0);     -- c(0) = current: 0.  Next: 1
Carry(0) := c(0);  -- carry(0)= 0

C(1) <= c(1) XOR carry (0). -- c(1) = current: 0.  Next: 0
Carry(1) := c(1) AND c(0) -- carry(1)= 0

Am I right?

Which value should I use when I execute again? I got confuse by this.

#### FvM

##### Super Moderator
Staff member It's right this way. The values you marked as "next" get effective in the next clock cycle. So the counter is counting up with an increment of 1.

#### knjr

##### Newbie level 6 Ok. Thanks Do you have any idea on how to explain on why I use XOR gate instead of others gates for the c.

#### FvM

##### Super Moderator
Staff member how to explain on why I use XOR gate
It's briefly explained in the previously quoted Wikipedia article, and I guess, in most text books that discuss adders.

#### anjusvasu

##### Newbie level 1 sir
i am priya. i got a frequency counter program can u explan that code in detail. plz the replay in my
toay itself i want that explanation

[CODE]library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity stepone is
port ( inp_clk1 : inout std_logic;
inp_clk2 : inout std_logic;
inp_clk3 : inout std_logic;
inp_clk4 : inout std_logic;
ref_clk : in std_logic;
rst : in std_logic;
ref_clk1_rising_pin : out std_logic;

--------------------------------------------------------------
CHANNELSEL: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
--------------------------------------------------------
DATA : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
RS,RW,E : OUT STD_LOGIC

);

end stepone;

architecture Behavioral of stepone is

type b is array (5 downto 0) of integer;
signal a:integer;
signal ll:integer;
signal count : std_logic_vector(15 downto 0);
signal ref_clk1_sync_reg : std_logic_vector(1 downto 0);
signal ref_clk1_rising : std_logic;
signal ref_clk1 : std_logic;
signal count1 : std_logic_vector(15 downto 0); ------- for the divider
----------------------------------------------------
signal inp_clk:std_logic;

signal oup_freq:std_logic_vector((15) downto 0);
SIGNAL C1,C2,C3,C4,C5,A1 :STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL SIGA: STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";

-----------------------------------------------
SIGNAL S: STD_LOGIC_VECTOR(18 DOWNTO 0):= (OTHERS=>'0');
SIGNAL SIGL: STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
SIGNAL CLKDIV : STD_LOGIC:='0';

signal D1: std_logic_vector(15 downto 0);
signal D2: std_logic_vector(15 downto 0);
signal D3: std_logic_vector(15 downto 0);
signal D4: std_logic_vector(15 downto 0);
signal D5: std_logic_vector(15 downto 0);

SIGNAL CH:STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL CHANNEL: STD_LOGIC_VECTOR(7 DOWNTO 0);

begin

PROCESS(ref_clk,CHANNELSEL)
BEGIN
IF (RISING_EDGE(ref_clk)) THEN

CASE CHANNELSEL IS
WHEN "0001"=>
CH<="00";
inp_clk<=inp_clk1;
WHEN "0010"=>
CH<="01";
inp_clk<=inp_clk2;
WHEN "0100"=>
CH<="10";
inp_clk<=inp_clk3;
WHEN "1000"=>
CH<="11";
inp_clk<=inp_clk4;
WHEN OTHERS=> NULL;
END CASE;
END IF;
END PROCESS;
------------ generating 1KHz from 48 MHz ------

process(rst,ref_clk)
begin
if(rst='0')then
count1<=(others=>'0');
elsif(ref_clk'event and ref_clk='1')then
if(count1 = 48000)then
count1<= (others=>'0');
else
count1<= count1 + 1;
end if;
end if;
end process;
ref_clk1 <= count1(15);

----------- synchronizing inp_clk with ref_clk--------------

process(inp_clk,ref_clk1)
begin
if(inp_clk'event and inp_clk='1')then
ref_clk1_sync_reg <= ref_clk1_sync_reg(0) & ref_clk1;
end if;
end process;

--------------- finding rising edge --------------

ref_clk1_rising <= not(ref_clk1_sync_reg(1)) and ref_clk1_sync_reg(0);
ref_clk1_rising_pin <= ref_clk1_rising;

--------------- freq_counter -------

process(rst,inp_clk,ref_clk1_rising)

begin
if(rst='0')then
count <= (others=>'0');
oup_freq <= (others=>'0');
elsif(inp_clk'event and inp_clk='1')then
count <= count+1;
if(ref_clk1_rising ='1')then
count <= (others=>'0');
oup_freq <= count;

end if;
end if;
end process;

--------------------------------asciii--------------------
PROCESS(ref_clk,oup_freq)
BEGIN
IF (RISING_EDGE(ref_clk)) THEN
SIGA<=SIGA+1;
CASE SIGA IS
WHEN "0001"=>
C1<="0000000000000000";
C2<="0000000000000000";
C3<="0000000000000000";
C4<="0000000000000000";
C5<="0000000000000000";
A1<=oup_freq;

WHEN "0010"=>
IF A1>="0010011100010000" THEN ---10000
SIGA<="0011";
ELSE
SIGA<="0100";
END IF;

WHEN "0011"=>
A1<=A1-"0010011100010000";
C1<=C1+1;
SIGA<="0010";

WHEN "0100"=>
IF A1>="0000001111101000" THEN --1000
SIGA<="0101";
ELSE
SIGA<="0110";
END IF;

WHEN "0101"=>
A1<=A1-"0000001111101000";
C2<=C2+1;
SIGA<="0100";

WHEN "0110"=>
IF A1>="0000000001100100" THEN --100
SIGA<="0111";
ELSE
SIGA<="1000";
END IF;

WHEN "0111"=>
A1<=A1-"0000000001100100";
C3<=C3+1;
SIGA<="0110";

WHEN "1000"=>

IF A1>="0000000000001010" THEN --10
SIGA<="1001";
ELSE
SIGA<="1010";
END IF;

WHEN "1001"=>
A1<=A1-"0000000000001010";
C4<=C4+1;
SIGA<="1000";

WHEN "1010"=>

C5<=A1;

WHEN "1011"=>
D1<=C1+"0000000000110000";
D2<=C2+"0000000000110000";
D3<=C3+"0000000000110000";
D4<=C4+"0000000000110000";
D5<=C5+"0000000000110000";

SIGA<="0000";

WHEN OTHERS=> NULL;
END CASE;
END IF;
END PROCESS;

---------------------------------------------------lcd-------------------------
PROCESS(ref_clk)
BEGIN
IF (RISING_EDGE(ref_clk)) THEN
S<=S+1;
IF S(18 DOWNTO 17)="01" THEN
CLKDIV<= '1';
ELSIF S(18 DOWNTO 17)="10" THEN
CLKDIV<= '0';
S<= (OTHERS=>'0');
END IF;
END IF;
END PROCESS;

-------------------------------------
PROCESS(CLKDIV)
BEGIN
IF(RISING_EDGE(CLKDIV)) THEN
SIGL<= SIGL+1;

CASE SIGL IS

WHEN "00000001" => RS<= '0';
RW<= '0';
CHANNEL<="000000" & CH;

WHEN "00000010" => DATA<= "00000011"; --0X03
WHEN "00000011" => E<='1';
WHEN "00000100" => E<= '0';
-- WHEN "00000101" => DATA<= "0011";
-- WHEN "00000110" => E<='1';
-- WHEN "00000111" => E<= '0';

WHEN "00000111" => DATA<= "00000011"; --0X03
WHEN "00001000" => E<='1';
WHEN "00001001" => E<= '0';
-- WHEN "00001101" => DATA<= "0011";
-- WHEN "00001110" => E<='1';
-- WHEN "00001111" => E<='0';

WHEN "00001100" => DATA<= "00000011"; --0X03
WHEN "00001101" => E<='1';
WHEN "00001110" => E<='0';
--WHEN "00010101" => DATA<= "0011";
-- WHEN "00010110" => E<='1';
-- WHEN "00010111" => E<='0';

WHEN "00010001" => DATA<= "00111000"; --0X28
WHEN "00010010" => E<='1';
WHEN "00010011" => E<='0';
-- WHEN "00011011" => DATA<= "1000";
-- WHEN "00011100" => E<='1';
-- WHEN "00011101" => E<='0';

WHEN "00010110" => DATA<= "00000110"; --0X06
WHEN "00010111" => E<='1';
WHEN "00011000" => E<='0';
-- WHEN "00100001" => DATA<= "0110";
-- WHEN "00100010" => E<='1';
-- WHEN "00100011" => E<='0';

WHEN "00011011" => DATA<= "00000001"; --0X0C
WHEN "00011100" => E<='1';
WHEN "00011101" => E<='0';
-- WHEN "00100111" => DATA<= "1100";
-- WHEN "00101000" => E<='1';
-- WHEN "00101001" => E<='0';

WHEN "00100000" => DATA<= "00001111"; --0X01
WHEN "00100001" => E<='1';
WHEN "00100010" => E<='0';
--WHEN "00101101" => DATA<= "0001";
--WHEN "00101110" => E<='1';
-- WHEN "00101111" => E<='0';

WHEN "00100101" => DATA<= "10000000"; --0X80
WHEN "00100110" => E<='1';
WHEN "00100111" => E<='0';
-- WHEN "00110011" => DATA<= "0000";
-- WHEN "00110100" => E<='1';
-- WHEN "00110101" => E<='0';

WHEN "00101000" => RS<= '1';

WHEN "00101001" => DATA<= "01000011"; --DATA 'C' 0X43
WHEN "00101010" => E<='1';
WHEN "00101011" => E<='0';
-- WHEN "00111010" => DATA<= "0011";
-- WHEN "00111011" => E<='1';
-- WHEN "00111100" => E<='0';

WHEN "00101110" => DATA<= "01001000"; --DATA 'H' 0X48
WHEN "00101111" => E<='1';
WHEN "00110000" => E<='0';
-- WHEN "01000000" => DATA<= "1000";
-- WHEN "01000001" => E<='1';
-- WHEN "01000010" => E<='0';

WHEN "00110011" => DATA<= "01000001"; --DATA 'A' 0X41
WHEN "00110100" => E<='1';
WHEN "00110101" => E<='0';
-- WHEN "01000110" => DATA<= "0001";
-- WHEN "01000111" => E<='1';
-- WHEN "01001000" => E<='0';
--
WHEN "00111000" => DATA<= "01001110"; --DATA 'N' 0X4E
WHEN "00111001" => E<='1';
WHEN "00111010" => E<='0';
-- WHEN "01001100" => DATA<= "1110";
-- WHEN "01001101" => E<='1';
-- WHEN "01001110" => E<='0';

WHEN "00111101" => DATA<= "01001110"; --DATA 'N' 0X4E
WHEN "00111110" => E<='1';
WHEN "00111111" => E<='0';
-- WHEN "01010010" => DATA<= "1110";
-- WHEN "01010011" => E<='1';
-- WHEN "01010100" => E<='0';

WHEN "01000010" => DATA<= "01000101"; --DATA 'E' 0X45
WHEN "01000011" => E<='1';
WHEN "01000100" => E<='0';
-- WHEN "01011000" => DATA<= "0101";
-- WHEN "01011001" => E<='1';
-- WHEN "01011010" => E<='0';
--

WHEN "01000111" => DATA<= "01001100"; --DATA 'L' 0X4C
WHEN "01001000" => E<='1';
WHEN "01001001" => E<='0';
-- WHEN "01100100" => DATA<= "1100";
-- WHEN "01100101" => E<='1';
-- WHEN "01100110" => E<='0';

WHEN "01001010" => DATA<= CHANNEL; --DATA CHANNEL
WHEN "01001011" => E<='1';
WHEN "01001100" => E<='0';
-- WHEN "01101010" => DATA<= CHANNEL;
-- WHEN "01101011" => E<='1';
-- WHEN "01101100" => E<='0';
--
WHEN "01001101" => RS<='0';

WHEN "01001111" => DATA<= "11000000"; --0XC0
WHEN "01010000" => E<='1';
WHEN "01010001" => E<='0';
-- WHEN "01110001" => DATA<= "0000";
-- WHEN "01110010" => E<='1';
-- WHEN "01110011" => E<='0';

WHEN "01010010" => RS<='1';

WHEN "01010011" => DATA<= D1(7 DOWNTO 0); --D1
WHEN "01010100" => E<='1';
WHEN "01010101" => E<='0';
-- WHEN "01111000" => DATA<= D1(3 DOWNTO 0); --D1
-- WHEN "01111001" => E<='1';
-- WHEN "01111010" => E<='0';
--
WHEN "01010110" => DATA<= D2(7 DOWNTO 0); --D2
WHEN "01010111" => E<='1';
WHEN "01011000" => E<='0';
-- WHEN "01111110" => DATA<= D2(3 DOWNTO 0); --D2
-- WHEN "01111111" => E<='1';
-- WHEN "10000000" => E<='0';

WHEN "01011001" => DATA<= D3(7 DOWNTO 0); --D3
WHEN "01011010" => E<='1';
WHEN "01011011" => E<='0';
-- WHEN "10000100" => DATA<= D3(3 DOWNTO 0); --D3
-- WHEN "10000101" => E<='1';
-- WHEN "10000110" => E<='0';

WHEN "01011100" => DATA<= D4(7 DOWNTO 0); --D4
WHEN "01011101" => E<='1';
WHEN "01011110" => E<='0';
-- WHEN "10001010" => DATA<= D4(7 DOWNTO 0); --D4
-- WHEN "10001011" => E<='1';
-- WHEN "10001100" => E<='0';

WHEN "01011111" => DATA<= D5(7 DOWNTO 0); --D5
WHEN "01100000" => E<='1';
WHEN "01100001" => E<='0';
-- WHEN "10010000" => DATA<= D5(7 DOWNTO 0); --D5
-- WHEN "10010001" => E<='1';
-- WHEN "10010010" => E<='0';
WHEN OTHERS=> NULL;
END CASE;
END IF;
END PROCESS;

end Behavioral;[/CODE]

Last edited by a moderator:

Status
Not open for further replies.