Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

Problem with VHDL code

Hi I'm really really new to VHDL codes and I'm having this problem with a very simple program of mine. The code is as shown below:

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

entity cc is

port (

enter : in std_logic;

reset : in std_logic;

input : in signed (7 downto 0);

output : out signed (7 downto 0)

);

end cc;

architecture cc_arch of cc is

signal a : signed (7 downto 0);

signal b : signed (7 downto 0);

signal total: signed (7 downto 0);

signal c : std_logic;

signal d : std_logic;

begin

process (enter,reset)

begin

if (reset = '0' and enter = '1') then

total <= "00000000";

end if;

if (enter = '1' and reset = '1') then

a <= input;

b <= total;

elsif (enter = '0' and reset = '1') then

total <= a + b;

end if;

end process;

output <= total;

end cc_arch;

The program is supposed to act as a simple calculator which calculates 2's complement. The buttons RESET and ENTER are active low buttons. "Input" is a 8 bit DIP switch.

I intended the program to function as shown below:

When RESET button is pressed, total is set to 0.

Then "Input" is put into "a" and total is put into "b" when no button is pressed.

When ENTER button is pressed the total is set to (a + b). When it is released, "Input" is put into "a" again and total is put into "b".

When the ENTER button is pressed again and again, total is supposed to be incremented with whatever is at "Input".

However when I simulated it, by setting Input to "00000002" as a simple example i get:

http://img300.imageshack.us/img300/6630/waveformfd6.jpg (http://imageshack.us)

http://img300.imageshack.us/img300/waveformfd6.jpg/1/w640.png (http://g.imageshack.us/img300/waveformfd6.jpg/1/)

Please help I'm not exactly sure what's happening.

http://img442.imageshack.us/img442/59536805yw2.jpg/1/w320.png (http://g.imageshack.us/img442/59536805yw2.jpg/1/)

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    process (enter,reset)

    begin

    if (reset = '0' and enter = '1') then

    total <= "00000000";

    end if;

    if (enter = '1' and reset = '1') then

    a <= input;

    b <= total;

    elsif (enter = '0' and reset = '1') then

    total <= a + b;

    end if;

    end process;

    --- Quote End ---

    You are trying to imply storage i.e. a FlipFlop for and b.

    The process above is not correct coding for a synchronous process and hence will not synthesize to any flipflops.

    I suggest you read up about synchronous design for VHDL.

    BUT....

    Something like

    process (clk)

    begin

    if (clk'event and clk= '1') then

    if (reset = '0' and enter = '1') then

    total <= "00000000";

    elsif (enter = '1' and reset = '1') then

    a <= input;

    b <= total;

    elsif (enter = '0' and reset = '1') then

    total <= a + b;

    end if;

    end if;

    end process;

    might be a start.

    The line if (clk'event and clk= '1') then effectively means wait for a rising edge on the clk signal.

    You will need to provide a clock generator to your design.

    Hope this gives you some clues!

    Let me know how you get on
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    * I advice you to use reset_n to indicate an active low signal.

    * to use std_(u)logic and std_(u)logic_vector only for ports

    * Use indent for better readability (if not), comments (not too much)...

    * You can find VHDL coding style in altera Web site or otherwhere.

    * In process sensibility list (if it is not a process clk), you must enter all input process signals if you don't want to infer latches.

    process (reset_n,order_n, input, a, b)

    @Vernmid : there is NO clock signal. So no process(clk)

    2) you should initialize all signals at reset_n and make reset_n the most priority signal

    [darkred]begin

    if reset_n = '0' then -- only reset_n

    --all initializations here

    total <= "00000000";

    a <= 0;

    b <= 0;

    elsif enter_n = '1' then -- (obviously reset_n = '1')

    a <= input;

    b <= total;

    else -- imply (enter = '0' and reset = '1')

    total <= a + b;

    end if;

    end process;

    * The behaviour above is asynchronous : you have glitches, combin. loops (very instable), sometimes latches.

    Very hard to debug if contains loops.

    Asynchronous design is usually used to make decoders, MUX, RS, tristate bus ...

    As Vernmid said, you are recommanded to use

    process(reset_n, clk)
    begin
    if reset_n = '0' then 
    ...
    elsif rising_edge(clk) then
    if enter_n = '0' then
    ...
    else
    ...
    end if;
    end if;
    end process;

    Quartus give templates.

    Keep in mind that you create logic design.

    May the force be with you :-)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi.. Thanks for all your help.. I've tried adding:

    if (clk'event and clk ='1') then

    .

    .

    .

    .

    end if;

    And now the program works fine.. Thanks loads..