24 timmars klocka i VHDL - testbänken.
Jag håller på med två inlämningsuppgifter i VHDL vilket är ett språk jag precis börjat med, dessutom är språk inget som faller sig naturligt för mig. Jag får fel i testbänken i ModelSIM och jag använder Quartus priums lite 18 free. Vi skall göra en timer/klocka som tickar på från 00:00:00 till 23:59:59 för att sedan slå om till 00:00:00 och börja om. All tid skall visas på de sex stycken 7-segments displayer..
Detta fungerar på FPGA kortet utan problem med de funktioner som krävs. pause, stopp/start och nollställning.
Men testbänken får jag inte till. Dessa kompileringsfel får jag upp i ModelSIM.
Ta gärna koden och testkör hos er om så är så det inte är ett problem hos mig.
-------------------------------------------------------------
-- Definering utav libraries. ---TESTBÄNKEN---
-------------------------------------------------------------
library IEEE; -- IEEE: Standard biblioteksgruppen
use IEEE.std_logic_1164.all; -- Bibilioteken för logiska funktioner.
use IEEE.numeric_std.all; -- Biblioteket för numeriska operationer så som count.
-------------------------------------------------------------
-- 2. Här beskrivs min entity med in- och utgångar
-- OBS! Tom entitet för testbänk! Vi har inte in- och utgångar
-------------------------------------------------------------
entity digital_clock_tb is
end entity digital_clock_tb;
-------------------------------------------------------------
-- Architecture för klockan
-------------------------------------------------------------
architecture testbench of digital_clock_tb is
-- a) Definition av komponenten. Koden är identisk med enditeten för
-- HW-beskrivningen, förutom att nyckelordet entity är bytt mot component
component digital_clock is
port
(
clk, reset_n, key_n : in std_logic;
seconds1, seconds2 : out std_logic_vector(6 downto 0);
minutes1, minutes2 : out std_logic_vector(6 downto 0);
hours1, hours2 : out std_logic_vector(6 downto 0)
);
end component digital_clock;
-----------------------------------------------------------------------------------
--
--
-----------------------------------------------------------------------------------
signal clk, reset_n, key_n : std_logic;
signal clk_tick : std_logic := '0';
signal sec1,sec2 : std_logic_vector(6 downto 0) ;
signal min1,min2 : std_logic_vector(6 downto 0) ;
signal hour1,hour2 : std_logic_vector(6 downto 0) ;
begin
-- instantiera Unit Under Test
UUT : digital_clock
-- Portmappning är till för att koppla samman alla "trådar"
-- Testat att "byta håll" utan resultat.
-- "pilen" visar inte riktningen utan bara kopplingen.
port map
(
clk => clk,
reset_n => reset_n,
key_n => key_n,
seconds1 => seconds1,
seconds2 => seconds2,
minutes1 => minutes1,
minutes2 => minutes2,
hours1 => hours1,
hours2 => hours2
);
clock_process: process is
begin
for i in 0 to 100 loop
clk <='0';
wait for 20 ns;
clk <='1';
wait for 20 ns;
end loop;
end process;
paus_process: process is
begin
-- Simulerar en pauseknapp för klockan så man kan starta och återuppta uppräkningen.
key_n <='0';
wait for 1000 ns;
end process;
-- Simulering utav att trycka ner resetknappen.
reset_n_process: process is
begin
reset_n <='1';
wait for 20 ns;
reset_n <='0';
wait for 20 ns;
reset_n <='1';
wait for 4960 ns;
assert false report "Test: OK" severity failure; -- Med denna funktion stannar simuleringen.
end process;
end architecture;
Här är själva koden till till klockan som fungerar på FPGA.
--------------------------------------------------------------------------
-- Prijekt 2 i Digitalteknik - VHDL.
-- Skapa en klocka med vilken skall räkna upp till 24tim(23:59:59) för
-- att sedan starta om från noll.
--------------------------------------------------------------------------
library IEEE; -- Standard biblioteksgruppen
use IEEE.std_logic_1164.all; -- Bibilioteken för
use IEEE.numeric_std.all; -- Biblioteket för numeriska operationer så som count.
--------------------------------------------------------------------------
-- Entity är där I/O defineras för vad som är in resp utgångar.
-- std_logic_vector är till för att skapa vektorer så man kan få flera
-- in/utgångar på ett "kommando"
--
--------------------------------------------------------------------------
entity digital_clock is
port (
clk, reset_n, key_n : in std_logic;
seconds1 : out std_logic_vector(6 downto 0);
seconds2 : out std_logic_vector(6 downto 0);
minutes1 : out std_logic_vector(6 downto 0);
minutes2 : out std_logic_vector(6 downto 0);
hours1 : out std_logic_vector(6 downto 0);
hours2 : out std_logic_vector(6 downto 0)
);
end digital_clock;
--------------------------------------------------------------------------
-- Architecture - är där allt spännande sker.
-- signal används när något skall hantera både som ut och ingång t.ex
-- constant är ett sätt att tilldela ett värde till en "variabel"
-- variabler finns i VHDL med.
-- constant time_scale är till för justera tiden på klockan så att 24tim
-- räknas upp på ca 30sek genom att count sätts till 16500 uppräkningar
-- innan clock_tick skickar signalen till klockräknare att stega 1sek.
-- 86400s / 30s = 2853 // 50MHZ / 2853 = 19357 uppräk/sek.
-- I det verkliga programmet så används 16500 uppräk/sek vilket ger en
-- dygnstid på ca 30s för då används 3kHz alltså 3000sekunder per sek.
--------------------------------------------------------------------------
architecture Behavior of digital_clock is
signal clk_tick : std_logic := '0'; -- clock_tick är för varje puls i uppräkningen.
signal count : integer := 1;
signal sec1, sec2 : integer ;
signal min1, min2 : integer ;
signal hour1,hour2 : integer ;
constant delorean : integer := 16500; -- Motsvara ca 3kHz // 24tim på knappt 30sek.
begin
--------------------------------------------------------------------------
-- Clock_devider är till för att dela upp 50MHz signalen vilken generas
-- från kortets "externa" klocka. Dess korta periodtid måste förlängas
-- annars ser vi bara åttor på displayerna. Vid 50MHz kommer klockans
-- dygn passeras ca 580 gånger per sekund, därför sker en uppräkning
-- till 16500 innan nästa steg räknas vilket sänker clockans takt till
-- 24tim på ca 30sek.
--------------------------------------------------------------------------
Clock_divider : process (clk, reset_n)
begin
if (reset_n = '0') then -- Var en 0 tidigare
count <= 1;
elsif rising_edge(clk) then -- 'event betyder prim event. om clk är 1
count <= count + 1;
if (count = delorean) then
if (key_n = '0') then
clk_tick <= '1';
else
clk_tick <= '0';
end if;
count <= 1;
else
clk_tick <= '0';
end if;
end if;
end process Clock_divider;
clock: process (clk_tick, reset_n)
begin
if (reset_n = '0') then
sec1 <= 0; sec2 <= 0; min1 <= 0; min2 <= 0; hour1 <= 0; hour2 <= 0;
elsif rising_edge (clk_tick) then
sec1 <= sec1 + 1;
if (sec1 = 9) then
sec1 <= 0;
sec2 <= sec2 + 1;
end if;
if (sec2 = 5 and sec1 = 9) then
sec2 <= 0;
min1 <= min1 + 1;
end if;
if (min1 = 9 and sec2 = 5 and sec1 = 9) then
min1 <= 0;
min2 <= min2 +1;
end if;
if (min2 = 5 and min1 = 9 and sec2 = 5 and sec1= 9) then
min2 <= 0;
hour1 <= hour1 + 1;
end if;
if (hour1 = 9 and min2 = 5 and min1 = 9 and sec2 = 5 and sec1= 9) then
hour1 <= 0;
hour2 <= hour2 + 1;
end if;
if (hour2 = 2 and hour1 = 3 and min2 = 5 and min1 = 9 and sec2 = 5 and sec1= 9) then
sec1 <= 0; sec2 <= 0; min1 <= 0; min2 <= 0; hour1 <= 0; hour2 <= 0;
end if;
end if;
end process;
Output_logic : process (clk)
begin
--------------------------------------------------------------------------
--
--
--------------------------------------------------------------------------
-- Sekunder 1
if (sec1 = 0) then seconds1 <= "1000000";
elsif (sec1 = 1) then seconds1 <= "1111001";
elsif (sec1 = 2) then seconds1 <= "0100100";
elsif (sec1 = 3) then seconds1 <= "0110000";
elsif (sec1 = 4) then seconds1 <= "0011001";
elsif (sec1 = 5) then seconds1 <= "0010010";
elsif (sec1 = 6) then seconds1 <= "0000010";
elsif (sec1 = 7) then seconds1 <= "1111000";
elsif (sec1 = 8) then seconds1 <= "0000000";
elsif (sec1 = 9) then seconds1 <= "0010000";
end if;
-- Sekunder 2
if (sec2 = 0) then seconds2 <= "1000000";
elsif (sec2 = 1) then seconds2 <= "1111001";
elsif (sec2 = 2) then seconds2 <= "0100100";
elsif (sec2 = 3) then seconds2 <= "0110000";
elsif (sec2 = 4) then seconds2 <= "0011001";
elsif (sec2 = 5) then seconds2 <= "0010010";
end if;
-- Minuter 1
if (min1 = 0) then minutes1 <= "1000000";
elsif (min1 = 1) then minutes1 <= "1111001";
elsif (min1 = 2) then minutes1 <= "0100100";
elsif (min1 = 3) then minutes1 <= "0110000";
elsif (min1 = 4) then minutes1 <= "0011001";
elsif (min1 = 5) then minutes1 <= "0010010";
elsif (min1 = 6) then minutes1 <= "0000010";
elsif (min1 = 7) then minutes1 <= "1111000";
elsif (min1 = 8) then minutes1 <= "0000000";
elsif (min1 = 9) then minutes1 <= "0010000";
end if;
-- Minuter 2
if (min2 = 0) then minutes2 <= "1000000";
elsif (min2 = 1) then minutes2 <= "1111001";
elsif (min2 = 2) then minutes2 <= "0100100";
elsif (min2 = 3) then minutes2 <= "0110000";
elsif (min2 = 4) then minutes2 <= "0011001";
elsif (min2 = 5) then minutes2 <= "0010010";
end if;
-- Timmar 1
if (hour1 = 0) then hours1 <= "1000000";
elsif (hour1 = 1) then hours1 <= "1111001";
elsif (hour1 = 2) then hours1 <= "0100100";
elsif (hour1 = 3) then hours1 <= "0110000";
elsif (hour1 = 4) then hours1 <= "0011001";
elsif (hour1 = 5) then hours1 <= "0010010";
elsif (hour1 = 6) then hours1 <= "0000010";
elsif (hour1 = 7) then hours1 <= "1111000";
elsif (hour1 = 8) then hours1 <= "0000000";
elsif (hour1 = 9) then hours1 <= "0010000";
end if;
-- Timmar 2
if (hour2 = 0) then hours2 <= "1000000";
elsif (hour2 = 1) then hours2 <= "1111001";
elsif (hour2 = 2) then hours2 <= "0100100";
end if;
end process Output_logic;
end architecture;
Du har en uppsättning namn sec1, min1 osv. Ska det kanske vara de namnen?
Hejsan.
Jag har prövat att lägga till, tagit bort osv.
seconds1 => sec1 // sec1 => sec1 ingen skillnad.
"pilens" riktning har ingen betydelse om jag inte missuppfattat det,
men har även prövat att ändra riktning utan resultat.
Tillägg: jag får Unknown identifier eller Unknown formal ident....