Forum: FPGA, VHDL & Co. Probleme mit Zähler


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Justus B. (justus_b)


Angehängte Dateien:

Lesenswert?

Hallo,
ich soll einen Zähler realisieren, welcher sowohl hoch, als auch runter 
zählen kann bis zu einem voreingestellten Wert. Also z.b 
0,1,2,3,4,5,1,2,3,4,5,1....
Im folgenden ist mein Entity Code:
1
library IEEE;
2
3
use IEEE.STD_LOGIC_1164.ALL;
4
5
use IEEE.Numeric_STD_UNSIGNED.ALL;
6
7
entity counter_3bit is
8
    Port ( clk : in STD_LOGIC;
9
           rst : in STD_LOGIC;
10
           enb : in STD_LOGIC;
11
           dir : in STD_LOGIC;
12
           ceil : in STD_LOGIC_VECTOR (2 downto 0);
13
           count : out STD_LOGIC_VECTOR (2 downto 0));
14
end counter_3bit;
15
16
architecture Behavioral of counter_3bit is
17
    signal next_count : std_logic_vector (2 downto 0);
18
19
begin
20
   
21
    sync_process: process (clk, rst)
22
    begin
23
        if rst = '1' then
24
            count <= (others => '0');
25
        elsif rising_edge(clk) then
26
            count <= next_count;
27
        end if;
28
    end process;
29
30
31
comb_process: process (enb, dir, ceil, count)
32
begin
33
       if enb = '1' then
34
        if dir = '1' then  -- Zählen aufwärts
35
            if count < ceil then
36
                next_count <= count + 1;
37
            else
38
                next_count <= "001";  
39
            end if;
40
        else  
41
            if count > "000" then
42
                next_count <= count - 1;
43
            else
44
                next_count <= ceil;  
45
            end if;
46
        end if;
47
    else
48
        next_count <= count;  -- Keine Änderung, wenn deaktiviert
49
    end if;
50
end process;








Meine Testbench folgt :

1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use std.env.finish;
4
5
entity counter_3bit_tb is
6
end counter_3bit_tb;
7
8
architecture Behavioral of counter_3bit_tb is
9
    component counter_3bit
10
        port (
11
            clk : in std_logic;
12
            rst : in std_logic;
13
            enb : in std_logic;
14
            dir : in std_logic;
15
            ceil : in std_logic_vector(2 downto 0);
16
            count : out std_logic_vector(2 downto 0)
17
        );
18
    end component;
19
20
    constant CLK_PERIOD : time := 10ns; -- Periodendauer fuer clk
21
    signal clk_count : integer := 0; -- Zaehler fuer durchlaufene Taktzyklen
22
    signal clk, rst, dir, enb : std_logic;
23
    signal ceil, count : std_logic_vector(2 downto 0);
24
begin
25
    DUT: counter_3bit port map(
26
        clk => clk,
27
        rst => rst,
28
        enb => enb,
29
        ceil => ceil,
30
        dir => dir,
31
        count => count
32
    );
33
34
    -- Taktgenerator mit Zaehler fuer Taktzyklen
35
    clk_generator: process begin
36
        clk <= '0';
37
        wait for CLK_PERIOD/2;
38
        clk <= '1';
39
        wait for CLK_PERIOD/2;
40
        clk_count <= clk_count + 1; -- Taktzyklen zaehlen
41
    end process;
42
43
    -- Den Zaehler testen
44
    test_process: process(clk_count) is begin
45
        case clk_count is
46
            ----------------------
47
            -- enb testen
48
            ----------------------
49
            when 0 => -- Vor der ersten Taktlanke
50
                rst <= '1', '0' after 2ns; -- DUT zuruecksetzen, count ist 0
51
                enb <= '1'; -- enable 1 setzen
52
                dir <= '1'; -- dir 1 setzen (vorwaerts)
53
                ceil <= "111"; -- ceil auf 7 setzen
54
            when 2 => -- nach zweiter Taktflanke
55
                 -- enb war 1, count muss 2 sein
56
                assert count = "010" report "enb test failed" severity failure;
57
                enb <= '0'; --enb 0 setzen;
58
            when 3 => -- nach dritter Taktflanke
59
                -- enb war 0, count muss immernoch 2 sein
60
                assert count = "010" report "enb test failed" severity failure;
61
            ----------------------
62
            -- ceil und dir testen
63
            ----------------------
64
            when 4 => -- nach [4] Taktflanke
65
                rst <= '1', '0' after 2ns; 
66
                enb <= '1'; 
67
                ceil <= "101"; -- ceil auf 5 setzten
68
                dir <= '1'; -- dir 1 setzen (vorwaerts)
69
            when 9 => -- nach [9] Taktflanke
70
                -- count muss nun 0->1->2->3->4->5->[1] sein
71
                assert count = "001" report "ceil test failed" severity failure;
72
                dir <= '0'; --dir low schalten (rueckwaerts)
73
            when 10 => -- nach [10] Taktflanke
74
                -- count muss nun 1->[5] sein (rueckwaerts)
75
                assert count = "101" report "ceil test failed" severity failure;
76
            when others => -- nichts tun
77
        end case;
78
    end process;
79
end Behavioral;

In Screenshot 11 ist zu sehen wie die Simulation aussehen muss, jedoch 
ist mein Problem jetzt, dass die Simulation einen Fehler bei assert 
count = "001" report "ceil test failed" severity failure gibt. Das 
heißt, dass der Zähler nicht auf die 1 zurücksetzt. Ich habe die Zeile 
auch mal rausgenommen un man sieht er resetet auf 0. Das anschließende 
runterzählen klappt wunderbar. Meine Simulation ist in Screenshot 12 zu 
sehen. Was mache ich falsch?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Justus B. schrieb:
> Was mache ich falsch?
Ist dir klar, dass dein test_process zwei mal pro clk Periode aufgerufen 
wird? Da kann ich mir den einen oder anderen Seiteneffekt vorstellen. 
Bezeichnenderweise bleibt deine Simu dann auch an einemm völlig 
uninteressanten Punkt, nämlich bei der inaktiven Flanke stehen.

> Meine Simulation ist in Screenshot 12 zu sehen.
Zeig mal, wie sie aussieht, wenn sie nicht unterbrochen wird. Und lass 
dir doch einfach mal auch den next_count anzeigen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.