Friday, June 21, 2013

Step 2d: My Experiments with Counter

1. Today, I wrote code for counter is asynchronous reset. Below are the code and RTL schematic generated.

VHDL Code:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

entity CounterSTD is
port 
(
    clk,rst : in std_logic;
    counter : out std_logic_vector(3 downto 0)
);
end CounterSTD;

architecture Behavioral of CounterSTD is
    signal count : std_logic_vector(3 downto 0);

begin

counter0 : process (clk, rst) is
begin
    if rst = '1' then
        count<= (others => '0');
    elsif rising_edge(clk) then
        count <= count + 1;
    end if;
end process counter0;

counter <= count;

end Behavioral;


RTL Schematic



Note: The name of Flip-Flop is fdc => D Flip-flop with Clear Input. Clear => Asynchronous Reset

2. Counter with Synchronous Reset


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity counterwithsyncreset is
    port (
        clk    :    in        std_logic;
        rst    :    in        std_logic;
        counter: out std_logic_vector(3 downto 0)
    );
end entity counterwithsyncreset;

architecture RTL of counterwithsyncreset is
    signal count: std_logic_vector(3 downto 0);
begin
    counter0 : process (clk) is
    begin
        if rising_edge(clk) then
            if rst = '1' then
                count <= ((others => '0'));
            else
                count <= count + 1;
            end if;
        end if;
    end process counter0;
    
counter <= count;
end architecture RTL;




Note: In this case Flip Flop Name: fdr => D Flip Flop with Reset. Reset is connected to Reset Pin.

3. Counters with Integers


library ieee;
use ieee.std_logic_1164.all;

entity counterintegersyncreset is
    port (
        clk    :    in        std_logic;
        rst    :    in        std_logic;
        counter: out     integer range 0 to 10
    );
end entity counterintegersyncreset;

architecture RTL of counterintegersyncreset is
    signal count: integer range 0 to 10;
begin

    counter0 : process (clk) is
    begin
        if rising_edge(clk) then
            if rst = '1' then
                count <= 0;
            else
                count <= count +1 ;
            end if;
        end if;
    end process counter0;
counter <= count;    
end architecture RTL;



Note: The synthesizer automatically figured out the required size for the end output. 
This is a great feature. However, integer usage has it's pros and cons.

Comments from another post:
http://electronics.stackexchange.com/questions/11774/vhdl-integers-for-synthesis
Integers are fine in synthesis, I use them all the time.
I use std_logic at top level ports, but internally I was using ranged integers all over the place
That's fine!
Be aware:
  • You are simulating first aren't you :) - Integer types don't automatically "roll-over" in simulation - it's an error to go out of the range you've specified for them. If you want roll-over behaviour, you have to code it explicitly. 
In the simulation even though integer was constrained for 0 to 100, it went to 997. 

  • They are only specced to go from $-2^{32}-1$ to $+2^{31}-1$ (i.e. not quite the full range of a 32-bit integer, you can't use $-2^{32}$ and remain portable), which is a bit of a pain at times. If you need to use "big" numbers, you'll have to use unsigned and signed.
  • If you don't constrain them, you can sometimes end up with 32-bit counters where less would do (if the synth and subsequent tools can't "see" that they could optimise bits away).
On the upside:
  • They are much faster to simulate than unsigned/signed vectors
  • They don't automatically roll-over in simulation (yes, it's in both lists :). This is handy - for example you get early warning that your counter is too small.
When you do use vector types, you are using ieee.numeric_stdnot ieee.std_logic_arith aren't you?
I use integers where I can, but if I explicitly want "roll-over n-bit counters", I tend to use unsigned.

4. Exericse: Explain why does the circuit gets optimized



library ieee;
use ieee.std_logic_1164.all;

entity counterintegersyncreset is
    port (
        clk    :    in        std_logic;
        rst    :    in        std_logic;
        counter: out     integer range 0 to 10
    );
end entity counterintegersyncreset;

architecture RTL of counterintegersyncreset is
    signal count: integer range 0 to 10;
begin

    counter0 : process (clk) is
    begin
        if rising_edge(clk) then
            if rst = '1' then
                count <= 0;
            else
                if (count = 10) then
                    count <= 0;
                end if;
                count <= count +1 ;
            end if;
        end if;
    end process counter0;
counter <= count;    
end architecture RTL;




No comments:

Post a Comment