Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL question - full adder using variable vs signal in Process

Status
Not open for further replies.

jinbow

Newbie level 3
Joined
Aug 19, 2016
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
53
Hi all,

I'm trying to do a 8-bit full adder example in Pedroni's VHDL book.

Below is his code which works when simulated:

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
=================================================
library IEEE;
use IEEE.std_logic_1164.all;
 
entity temp is
    generic(    bits:   positive    := 8);
    port (  cin         : in    std_logic;
            a           : in    std_logic_vector(bits-1 downto 0);
            b           : in    std_logic_vector(bits-1 downto 0);
            sum         : out   std_logic_vector(bits-1 downto 0);
            cout        : out   std_logic);
end entity;
 
architecture arch of temp is
begin
    process(a, b, cin)
        variable c:     std_logic_vector(bits downto 0) := (others => '0');
    begin
        c(0) := cin;
        for i in 0 to bits-1 loop
            sum(i) <= a(i) xor b(i) xor c(i);
            c(i+1) := (a(i) and b(i)) or (a(i) and c(i)) or (b(i) and c(i));
        end loop;
        cout <= c(bits);
    end process;    
end architecture;
=================================================
 
I am trying not to use variable, but use signal as the type for c as shown below:
=================================================
architecture arch of temp is
    signal c:       std_logic_vector(bits downto 0) := (others => '0');
begin
    c(0) <= cin;
    process(a, b, c(0))
    begin
        for i in 0 to bits-1 loop
            sum(i) <= a(i) xor b(i) xor c(i);
            c(i+1) <= (a(i) and b(i)) or (a(i) and c(i)) or (b(i) and c(i));
        end loop;
    end process;
        cout <= c(bits);
end architecture;
=================================================

During simulation, whenever cin is '1', the c[0] is 'X', and causes sum[0] to be 'X'.
Below is the simulation diagram.
Capture.JPG

I know I can use a generate statement to do this outside of a process, but just wanted to know why this happens.

Please advise.

Thanks,
ALbert
 
Last edited by a moderator:

This is an issue to do with loops and the quirks of VHDL.
When you use a signal inside a for or while loop in VHDL, it has no idea which bits are driven and are not driven in C (age old locally/globally static issues). So it assumes All bits of C are driven from inside the process, even though you know they're not.
So C(0) gets driven from inside and outside the process, causing C(0) to be X, which will propogate all the way through sum and C.

I learned this myself a few weeks ago with exactly the same problem (I raised a ticket to mentor about it - they pointed out the LRM).

You can fix it by putting the C(0) assignement inside the process;
 
  • Like
Reactions: jinbow

    jinbow

    Points: 2
    Helpful Answer Positive Rating
Thanks TD, great explanation!!
What is LRM by the way???
 

I think you can also drive all other bits to something like '-' or 'z'. This should allow the resolution function to work. I think xilinx supports this within an entity, but not between entity
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top