0

I am working on a Program Counter that must be added 4 in each rising edge of a clk:

Code:

if_CounterSum <= MemAddr + 4;

process (Clk, Reset)
begin
    if Reset = '1' then
        MemAddr <= (OTHERS => '0');
    elsif rising_edge(Clk) then 
        MemAddr <= if_CounterSum;
    end if;
end process;

When simulating in ISIM,

After Reset is set to 0:
Initial state:
MemAddr = 0 (0000)
if_CounterSum = 4 (0100)

First CLK rising_edge:
MemAddr = X (0X00)
if_CounterSum = X (XXXX)

I have been working on this "simple" thing for some hours, I have tried:

  1. Change the +4 line to synchronous too (Into the process) but problem kept.
  2. Some other stuff that didn't worked.

How can I fix that X? I have tested other numbers instead of 4 and as I guessed all '1's in if_CounterSim where converted in 'X's after the assignment.

Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
0Zero0
  • 43
  • 7

2 Answers2

1

You have not included all of the code, so below is a guess.

The problem is probably a result of VHLD resolution of the signal, whereby multiple conflicting drivers of the same signals as for example both '0' and '1' will result in 'X', but where two drivers of '0' will result in '0'.

So look for all places in the module where MemAddr and if_CounterSum are assigned, and remove those unnecessary assigns.

Morten Zilmer
  • 15,586
  • 3
  • 30
  • 49
  • 1
    Works,had more than 1 process reseting MemAddr, but as the reset was the 0 I thought there wouldnt be problem. Thanks and solved :9 – 0Zero0 Oct 12 '16 at 12:47
  • 1
    Think hardware. Each process generates a separate lump of hardware, and if several drive MemAddr you have short circuited their outputs together, which as `0x00` tells you, is not a good thing. –  Oct 12 '16 at 14:45
0

When assigning a signal outside a process you literally connect it to the right side of the arrow. When assigning a signal inside a synchronous process you implement flip flops to assign a value to your signal on clock edges.

In your case, I suggest you put if_CounterSum <= MemAddr + 4; in your process. This way, the increment will be done at each clock rising edge.

process (Clk, Reset)
begin
    if Reset = '1' then
        MemAddr <= (OTHERS => '0');
    elsif rising_edge(Clk) then 
        MemAddr <= MemAddr + 4;
    end if;
end process;

If you really need the if_CounterSum you can add if_CounterSum <= MemAddr outside the process this time (because it would be wired).

A. Kieffer
  • 372
  • 2
  • 13
  • I tried that too and it doesnt work, not because of itself, because another assignment was destroying the rest. Thanks you anyway! – 0Zero0 Oct 12 '16 at 12:49