Hannes är nöjd med hjälpen
Hannes 25
Postad: 25 jun 2022 14:10

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;


Laguna Online 28587
Postad: 25 jun 2022 20:30

Du har en uppsättning namn sec1, min1 osv. Ska det kanske vara de namnen?

Hannes 25
Postad: 26 jun 2022 08:24 Redigerad: 26 jun 2022 08:26

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....

Svara Avbryt
Close