1 | c(0) <= not c(0); |
2 | carry(0) := c(0); |
3 | c(1)<= c(1) xor carry(0); |
4 | carry(1) := c(1) and carry(0); |
5 | c(2)<= c(2) xor carry(1); |
6 | carry(2) := c(2) and carry(1); |
7 | c(3)<= c(3) xor carry(2); |
8 | carry(3) := c(3) and carry(2); |
9 | c(4)<= c(4) xor carry(3); |
10 | carry(4) := c(4) and carry(3); |
11 | c(5)<= c(5) xor carry(4); |
12 | carry(5) := c(5) and carry(4); |
13 | c(6)<= c(6) xor carry(5); |
14 | carry(6) := c(6) and carry(5); |
15 | c(7)<= c(7) xor carry(6); |
16 | carry(7) := c(7) and carry(6); |
Hi there, anyone can explain the whole coding above for me? I need each explanation for each line. Thanks alot.
Is the code snipped above in a clocked process ? Maybe you are able to post the whole code, so we can see it in connection. best regards Tobias
1 | library IEEE; |
2 | use IEEE.std_logic_1164.all; |
3 | use IEEE.std_logic_unsigned.all; |
4 | entity my_counter is |
5 | port(count: Out std_logic_vector(7 downto 0); |
6 | clk: in std_logic; |
7 | reset: in std_logic); |
8 | end my_counter; |
9 | |
10 | architecture behav_my_counter of my_counter is |
11 | |
12 | signal c : std_logic_vector(7 downto 0) := "00000000"; |
13 | |
14 | begin
|
15 | |
16 | ctr: |
17 | |
18 | process(clk,reset) |
19 | variable carry : std_logic_vector(7 downto 0) := "00000000"; |
20 | begin
|
21 | |
22 | if reset'event and(reset = '1') then |
23 | c <= (others => '0'); |
24 | |
25 | elsif clk'event and (clk = '1') then |
26 | --i am adding "00000001" to 'c'.
|
27 | --this is done using basic logic gates.
|
28 | -- the equation for full adder is simplified and written below.
|
29 | --full adder equations are:
|
30 | -- sum = A xor B xor Carry.
|
31 | -- carry = (A and B) or (A and carry) or (B and carry).
|
32 | --subsititue B with "00000001" here and you will get the below equations.
|
33 | c(0) <= not c(0); |
34 | carry(0) := c(0); |
35 | c(1)<= c(1) xor carry(0); |
36 | carry(1) := c(1) and carry(0); |
37 | c(2)<= c(2) xor carry(1); |
38 | carry(2) := c(2) and carry(1); |
39 | c(3)<= c(3) xor carry(2); |
40 | carry(3) := c(3) and carry(2); |
41 | c(4)<= c(4) xor carry(3); |
42 | carry(4) := c(4) and carry(3); |
43 | c(5)<= c(5) xor carry(4); |
44 | carry(5) := c(5) and carry(4); |
45 | c(6)<= c(6) xor carry(5); |
46 | carry(6) := c(6) and carry(5); |
47 | c(7)<= c(7) xor carry(6); |
48 | carry(7) := c(7) and carry(6); |
49 | |
50 | end if; |
51 | |
52 | end process; |
53 | count <= c; |
54 | |
55 | |
56 | end behav_my_counter; |
This is the full coding. You want me to post the test bench too?
Kelly N. wrote: > Hi there, anyone can explain the whole coding above for me? > I need each explanation for each line. I don't think that makes any sense, because each line itself describes, what it does... :-o Much more useful is a description, what the whole thing does... It is a synchronous counter: http://faculty.kfupm.edu.sa/COE/ashraf/RichFilesTeaching/COE022_200/Chapter%205.htm http://tams-www.informatik.uni-hamburg.de/applets/hades/webdemos/30-counters/30-sync/sync-dff_print.html
Like I still don't understand how it works. Why is the coding like this. & why we need to c(0) <= not c(0); in the first place.
if you count up, the LSB is always alternating. this is what this particular line does. all other lines represent adders. carry(x) holds the carry of the addition 'before' the bit. c(1)<= c(1) xor carry(0); carry(1) := c(1) and carry(0); 0+0 = 00 1+0 = 01 0+1 = 01 1+1 = 10 the XOR calculates the LSB, the AND the MSB of each addition.
Alright. This applies to all the lines after that right? But why in the first place they need c(0) <= not c(0); the initial of c(0) is 00000000 am I right?
Kelly N. wrote: > the initial of c(0) is 00000000 am I right? Ist is only one bit and therefore just '0'... :-/ > Like I still don't understand how it works. > Why is the coding like this. > & why we need to > c(0) <= not c(0); > > in the first place. Did you have a look for http://tams-www.informatik.uni-hamburg.de/applets/hades/webdemos/30-counters/30-sync/sync-dff.html Did you see the most left XOR? With the enable signal permanently '1' this is just an inverter. And that results in a simple NOT. If you want to describe the schematic there http://tams-www.informatik.uni-hamburg.de/applets/hades/webdemos/30-counters/30-sync/sync-dff.html you must do it that way (referring to your posted code):
1 | process(clk,reset) |
2 | variable carry : std_logic_vector(7 downto 0) := "00000000"; |
3 | begin
|
4 | if reset = '0' then |
5 | c <= (others => '0'); |
6 | elsif clk'event and (clk = '1') then |
7 | c(0) <= c(0) xor enable; |
8 | carry(0) := c(0) and enable; |
9 | c(1) <= c(1) xor carry(0); |
10 | carry(1) := c(1) and carry(0); |
11 | :
|
BTW: You will not find this component on any FPGA (hardly anywhere on earth):
1 | if reset'event and(reset = '1') then -- not synthesizeable |
2 | :
|
3 | elsif clk'event and (clk = '1') then |
4 | :
|
5 | end if; |
It seems to me thats Verilog thinking: always @(posedge reset)... But you will not find a flipflop, thats sensitive to two (different) clock signals!!! Instead the Reset is level sensitive:
1 | if reset = '0' then -- as long as reset is '0' |
2 | :
|
3 | elsif clk'event and clk = '1' then |
4 | :
|
5 | end if; |
Whats your question? What do you not understand? > But why in the first place they need > c(0) <= not c(0); If you pick any stage in the middle of the code and do a slightliy reformatting, then you see
1 | :
|
2 | c(2) <= c(2) xor carry(1); |
3 | carry(2) := c(2) and carry(1); |
4 | c(3) <= c(3) xor carry(2); |
5 | carry(3) := c(3) and carry(2); |
6 | :
|
Each stage refers to the previous stage. So for a 212 bit witdh the last entries will be
1 | |
2 | :
|
3 | c(210) <= c(210) xor carry(209); |
4 | carry(210) := c(210) and carry(209); |
5 | c(211) <= c(211) xor carry(210); |
6 | carry(211) := c(211) and carry(210); |
Its easy, isn't it? And now: what to do with stage 0?
1 | c(0) <= c(0) xor carry(-1); |
2 | carry(0) := c(0) and carry(-1); |
3 | c(1) <= c(1) xor carry(0); |
4 | carry(1) := c(1) and carry(0); |
5 | :
|
And because we don't have a stage '-1' we substitute it with a logic '1':
1 | c(0) <= c(0) xor '1'; |
2 | carry(0) := c(0) and '1'; |
3 | c(1) <= c(1) xor carry(0); |
4 | carry(1) := c(1) and carry(0); |
5 | :
|
And now a little bit boolean equation magic: What is XX AND '1'? Correct answer: XX What is YY XOR '1'? Correct answer: NOT YY And if you take this knowledge into your code it results in:
1 | c(0) <= NOT c(0); |
2 | carry(0) := c(0); |
3 | c(1) <= c(1) xor carry(0); |
4 | carry(1) := c(1) and carry(0); |
5 | :
|
I think somehow I understand. But I want to ask one very stupid question. <= & := what's the different & means?
> <= & := what's the different & means?
Take ANY VHDL book and have a look for the different behaviuor of
signals and variables.
And after that: as a VHDL beginner forget_variables for (at least) the
next half year!
1 | c(0) <= not c(0); |
2 | carry(0) := c(0); |
3 | c(1) <= c(1) xor carry(0); |
4 | carry(1) := c(1) and carry(0); |
5 | |
6 | c(2)<= c(2) xor carry(1); |
7 | 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?
> I understand the first 2 lines.
I'm not sure with that...
Lets say we start with values like this:
s is a std_logic signal
v is a std_logic variable
Lets define:
Both of them start with a value '0', so we have s = '0' and v = '0'
And now we add a clock and enter a process like this:
1 | signal s : std_logic := '0'; |
2 | |
3 | process (clk) |
4 | variable v : std_logic := '0'; |
5 | begin
|
6 | if rising_edge(clk) then |
7 | s <= '1'; |
8 | v := s; |
9 | end if; |
10 | end process; |
So tell me: whats the value of s and v after one rising edge of clk? And now the same here:
1 | signal s : std_logic := '0'; |
2 | |
3 | process (clk) |
4 | variable v : std_logic := '0'; |
5 | begin
|
6 | if rising_edge(clk) then |
7 | v := '1'; |
8 | s <= v; |
9 | end if; |
10 | end process; |
Again: telle me whats the value of s and v after one rising edge of clk?
> c(2) = '1' - 00000100
This is nonsense: you cannot subtract a vector from one bit!
But I understand what you mean... ;-)
signal s : std_logic := '0';
process (clk)
variable v : std_logic := '0';
begin
if rising_edge(clk) then
s <= '1';
v := s;
end if;
end process;
So tell me: whats the value of s and v after one rising edge of clk?
s = 1
v = 1 ?
signal s : std_logic := '0';
process (clk)
variable v : std_logic := '0';
begin
if rising_edge(clk) then
v := '1';
s <= v;
end if;
end process;
Again: telle me whats the value of s and v after one rising edge of clk?
s = 1
v = 1 ?
> c(2) = '1' - 00000100
This is nonsense: you cannot subtract a vector from one bit!
But I understand what you mean... ;-)
I mean c(2) = 00000100 not 1-00000100. :D
But is it correcT?
> Again: telle me whats ... s = 1 v = 1 ? The second one you got correct. > So tell me: whats the value .... s = 1 v = 1 ? Wrong! In the first sample we have s = '1' and v = '0'. Thats the behaviour of signals!!! (And your problem at the moment!) The value of each signal remains throughout the whole process. The assignment of the signals "new" value is done at "end process". So check this:
1 | signal a,b,c : std_logic := '0'; |
2 | |
3 | process (clk) |
4 | variable x,y,z : std_logic := '0'; |
5 | begin
|
6 | if rising_edge(clk) then |
7 | a <= '1'; |
8 | b <= a; |
9 | x := b; |
10 | y := '1'; |
11 | c <= y; |
12 | z := c; |
13 | end if; |
14 | end process; |
Whats the result?
Kelly N. wrote: > s = 1 > v = 1 ? > ... > s = 1 > v = 1 ? This is your guess. What is the result from your simulator? Duke
> What is the result from your simulator?
One should not need a simulator for this...
But it could be a tool to come behind the (different) behaviour of
signals and variables in a process ;-)
1 | So check this: |
2 | signal a,b,c : std_logic := '0'; |
3 | process (clk) |
4 | variable x,y,z : std_logic := '0'; |
5 | begin |
6 | if rising_edge(clk) then |
7 | a <= '1'; |
8 | b <= a; |
9 | x := b; |
10 | y := '1'; |
11 | c <= y; |
12 | z := c; |
13 | end if; |
14 | end process; |
15 | Whats the result? |
a = 1 b = 1 x = 0 y = 0 c = 1 z = 0 Correct?
> Correct? Whats your simulators opinion? > Correct? No... :-( This is the result: a = 1 b = 0 !! x = 0 y = 1 !! c = 1 z = 0 The short way: Variables take over the new value immediately. Signals take over the last assigned value at the end of the process.
> We should look at the operator (<= / :=) or ?
Not particular!
The assignment token is just a indication for a signal or a variable.
The := is the assignment symbol necessary for variables, the <= is the
one for the signals.
You must know the difference of the behaviour between signals and
variables, not the difference of the assignment tokens. If you ause the
:= instead of the <= then your simulator/synthesizer generates a error.
But if you use a variable where you should use a signal, then no error
is generated, but you get a different behaviour...
I don't know the behaviour of signals and variables. Can explain a bit to me?
> I don't know the behaviour of signals and variables. > Can explain a bit to me? I did already... :-/ But here once more: a signal keeps its entry value throughout the whole process. At the end of the process it takes over the last assigned value. A variable takes immediately over the assigned value. See this:
1 | signal s integer := 123; |
2 | |
3 | process (clk) |
4 | variable v : integer := 987; |
5 | begin
|
6 | if rising_edge(clk) then |
7 | s <= 345; -- next_s = 345, current_s = 123 |
8 | s <= 876; -- next_s = 876, current_s = 123 |
9 | v := s; -- v = current_s = 123 |
10 | s <= 555; -- next_s = 555, current_s = 123 |
11 | v := 777; -- v = 777 |
12 | s <= v; -- next_s = v = 777; |
13 | end if; |
14 | end process; -- assign s = next_s |
So at the end of this process we have s = 777, v = 777 And now you must take any book about VHDL and a simulator and check it out for yourself.
Sorry, I got question on my coding. Let's say
1 | c(1) <= c(1) xor carry(0); |
2 | carry(1) := c(1) and carry(0); |
c(1) = '0' carry(0) = '1' I need find out carry (1) c(1) <= c(1) xor carry(0); 0 xor 1 = 1 So c(1) <= next = 1, current = 0 ? am I right? Then when I need to find the carry (1) := c(1) and carry(0); the c(1) which value should I use?
> the c(1) which value should I use? c is a signal and therefore it does not change its value until the end of the process. Then it will get the last assigned value. > c(1) = '0' > carry(0) = '1' > I need find out carry (1)
1 | c(1) <= c(1) xor carry(0); -- c(1)_current='0' --> c(1)_next='1' |
2 | carry(1) := c(1) and carry(0); -- c(1)_current='0' --> carry(1) ='0' |
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. The coding start with 00 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.