Forum Discussion

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

Problem with a 5-bit counter programme

Design a 5-bit up/down counter with synchronous counting, asynchronous preset and asynchronous master reset. Write a VHDL design description of the counter based on the following criteria:

a) The counter increments or decrements on a positive clock edge only if its active-HIGH enable (EN) is asserted.

b) The master reset (MR) is an active-HIGH input that resets the counter to 00000 state.

c) The counter can be preset to the logic levels present on the parallel data inputs (P4P3P2P1P0) by activating the parallel load input (file:///C:/DOCUME%7E1/Arpah/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image002.gif ) from HIGH to LOW.

d) The count outputs are Q4Q3Q2Q1Q0 where Q0 is the LSB and Q3 is the MSB.

e) A LOW at UP_DW input causes the counter to decrement. For up counting, a HIGH at the UP_DW input.

This is the our programme:

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

entity d1 is

port (clk, MR, EN,UP_DW, p_load: in std_logic;

p : in std_logic_vector (4 downto 0);

q : out std_logic_vector (4 downto 0));

end d1;

architecture flow of d1 is

signal count_sig: unsigned (4 downto 0);

begin

process (clk, MR)

begin

if (MR='1') then

count_sig <= "00000";

elsif (p_load='0') then

case p is

when "00000"=>count_sig<="00000";

when "00001"=>count_sig<="00001";

when "00010"=>count_sig<="00010";

when "00011"=>count_sig<="00011";

when "00100"=>count_sig<="00100";

when "00101"=>count_sig<="00101";

when "00110"=>count_sig<="00110";

when "00111"=>count_sig<="00111";

when "01000"=>count_sig<="01000";

when "01001"=>count_sig<="01001";

when "01010"=>count_sig<="01010";

when "01011"=>count_sig<="01011";

when "01100"=>count_sig<="01100";

when "01101"=>count_sig<="01101";

when "01110"=>count_sig<="01110";

when "01111"=>count_sig<="01111";

when "10000"=>count_sig<="10000";

when "10001"=>count_sig<="10001";

when "10010"=>count_sig<="10010";

when "10011"=>count_sig<="10011";

when "10100"=>count_sig<="10100";

when "10101"=>count_sig<="10101";

when "10110"=>count_sig<="10110";

when "10111"=>count_sig<="10111";

when "11000"=>count_sig<="11000";

when "11001"=>count_sig<="11001";

when "11010"=>count_sig<="11010";

when "11011"=>count_sig<="11011";

when "11100"=>count_sig<="11100";

when "11101"=>count_sig<="11101";

when "11110"=>count_sig<="11110";

when "11111"=>count_sig<="11111";

when others=>count_sig<=count_sig;

end case;

elsif (p_load='1') then

count_sig<=count_sig;

if (EN='0') then

count_sig<=count_sig;

elsif rising_edge(clk) then

case UP_DW is

when '1'=>count_sig<=count_sig +1;

when '0'=>count_sig<=count_sig -1;

end case;

end if;

end if;

end process;

q<= std_logic_vector (count_sig);

end flow;

May i know why my waveform is not the same as the expected answer. Thanks

7 Replies

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

    Is it possible that u can't place a rising_edge in a if - elsif structure.

    Re-write it as:

    if risin_edge ... then
    if reset then 
    count_value <= 0;
    elsif load then 
    count_value <= load_value
    elsif count_up then
    count_value <= count_value + 1;
    elsif count_dwn then
    count_value <= count_value -1;
    end if;
    end if;
     

    i didn't read the whole text to forfill ur teachers question :)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I think it's possible to make it like

    
    if reset
     
    elsif load
     
    else 
       if rising_edge
       end if;
    end if;
    

    Now put count up and down under the rising edge

    to make reset and load async and up and down sync.

    But rising edge in if - else structure is not done ;-)

    cauze inpout is a clock

    you only can use it like:

    if rising_edge then

    end if;

    and not like

    if rising_edge then

    else

    end if;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    your input P is 7, so the q value takes 7 as the active low load signal loads it.

    There are many redundant lines in your code. you never need to assign count_sig to itself.

    Here is a much tidier version of your code. I have removed the asynchronous enable because you want to use it synchronously:

    
    begin
      process (clk, MR, p_load, p)
        begin
        if (MR='1') then
          count_sig <= "00000";
        
        elsif (p_load='0') then
          count_sig <= unsigned(p);
        
        elsif rising_edge(clk) then
          if EN = '1' then
            case UP_DW is
              when '1'=>count_sig<=count_sig +1;
              when '0'=>count_sig<=count_sig -1;
              when others => count_sig <= "XXXXX";
            end case;
        
          end if;
        end if;
      
      
      end process;
      q<= std_logic_vector (count_sig);
    end flow;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Is it possible that u can't place a rising_edge in a if - elsif structure.

    --- Quote End ---

    Yes, elsif rising_edge(clock) is fine, else how would you have asynchronous resets or loads?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Yes, elsif rising_edge(clock) is fine, else how would you have asynchronous resets or loads?

    --- Quote End ---

    True. My second post is the same like "elsif rising_edge" but i never write it like that.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    your input P is 7, so the q value takes 7 as the active low load signal loads it.

    There are many redundant lines in your code. you never need to assign count_sig to itself.

    Here is a much tidier version of your code. I have removed the asynchronous enable because you want to use it synchronously:

    
    begin
      process (clk, MR, p_load, p)
        begin
        if (MR='1') then
          count_sig <= "00000";
        
        elsif (p_load='0') then
          count_sig <= unsigned(p);
        
        elsif rising_edge(clk) then
          if EN = '1' then
            case UP_DW is
              when '1'=>count_sig<=count_sig +1;
              when '0'=>count_sig<=count_sig -1;
              when others => count_sig <= "XXXXX";
            end case;
        
          end if;
        end if;
      
      
      end process;
      q<= std_logic_vector (count_sig);
    end flow;
    

    --- Quote End ---

    I just tried this code just now. However it still can't give the graph of the expected outcome.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The problem isnt with the code. I just tidied up your version. The problem is that you load 7 onto count_sig at the start of the simulation. P_load has preference over the clock. The problem lies with your testbench.