vhdl manual clock hour set - vhdl

I am trying to make an alarm clock for a final project in one of my classes. I am using push buttons on a DE1 Altera board to manually increment hours and mins. The mins work but I can not get the hours to increment manually. All pin assignments are correct.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ClkMain is port (
clk,pb_hr,pb_min,clk_set,almr_enbl: in std_logic;
almr_hr: in integer range 0 to 23;
almr_min: in integer range 0 to 59;
clk_min : out integer range 0 to 59;
clk_hr : out integer range 0 to 23;
almr_indct : out bit
);
end ClkMain;
architecture Behavioral of ClkMain is
signal sec, min: integer range 0 to 60 :=0;
signal hr: integer range 0 to 24 := 0;
begin
clk_min <= min;
clk_hr <= hr;
process(clk) --normal clock operation
begin
if(clk'event and clk='1') then
sec <= sec + 1;
if(sec + 1 = 60 or (pb_min = '1' and clk_set = '1') ) then
sec <= 0;
min <= min + 1;
if (min + 1 = almr_min and hr = almr_hr and almr_enbl = '1') then
almr_indct <= '1';
else
almr_indct <= '0';
end if;
if(min + 1 = 60 ) then
hr <= hr + 1;
min <= 0;
if(hr + 1 = 24) then
hr <= 0;
if (clk'event and clk='1' and pb_hr = '1' and clk_set = '1')then
hr <= hr + 1;
end if;
end if;
end if;
end if;
end if;
end process;
end Behavioral;

You can see where the error is by indenting properly:
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_arith.all;
-- use ieee.std_logic_unsigned.all;
entity ClkMain is
port (
clk,pb_hr,pb_min,clk_set,almr_enbl: in std_logic;
almr_hr: in integer range 0 to 23;
almr_min: in integer range 0 to 59;
clk_min: out integer range 0 to 59;
clk_hr: out integer range 0 to 23;
almr_indct : out bit
);
end ClkMain;
architecture Behavioral of ClkMain is
signal sec, min: integer range 0 to 60 :=0;
signal hr: integer range 0 to 24 := 0;
begin
clk_min <= min;
clk_hr <= hr;
process(clk) --normal clock operation
begin
if clk'event and clk = '1' then
sec <= sec + 1;
if sec + 1 = 60 or (pb_min = '1' and clk_set = '1') then
sec <= 0;
min <= min + 1;
if min + 1 = almr_min and hr = almr_hr and almr_enbl = '1' then
almr_indct <= '1';
else
almr_indct <= '0';
end if;
if min + 1 = 60 then
hr <= hr + 1;
min <= 0;
if hr + 1 = 24 then
hr <= 0;
if clk'event and clk = '1' and pb_hr = '1' and clk_set = '1' then
hr <= hr + 1;
end if;
end if;
end if;
end if;
end if;
end process;
end Behavioral;
The clk condition is enclosed in the outermost if statement and isn't necessary:
if clk'event and clk = '1' and pb_hr = '1' and clk_set = '1' then
Should be
if pb_hr = '1' and clk_set = '1' then
And that brings us to what's wrong. pb_hr is only evaluated at 11 PM:
if hr + 1 = 24 then
hr <= 0;
if pb_hr = '1' and clk_set = '1' then
hr <= hr + 1;
end if;
end if;
At a minimum these two if statements need to be at the same nesting level.
Unfortunately it also makes you take a look up the if statement nesting levels where you notice you can only set hours at 23:59:59, or you're also holding down pb_min and clk_set is true.
Also notice you almr_indct is true for a minute no matter what you do. I'd suggest moving the sets and alarm detection outside the enclosing if statement with the clock condition (keep them in the same process). It should also be invalidated when clk_set is true.
Looking even further back:
if sec + 1 = 60 or (pb_min = '1' and clk_set = '1') then
sec <= 0;
min <= min + 1;
We see you could reach 60 for a button push. That all needs to be fixed. It's also possible to move the alarm comparison outside of the counters and disable during clock set.
So you could manipulate the process statement:
architecture foo of clkmain is
signal sec, min: integer range 0 to 59 := 0;
signal hr: integer range 0 to 23 := 0;
signal sec_neq_59: std_logic;
signal min_neq_59: std_logic;
signal hr_neq_23: std_logic;
begin
clk_min <= min;
clk_hr <= hr;
sec_neq_59 <= '0' when sec = 59 else '1';
min_neq_59 <= '0' when min = 59 else '1';
hr_neq_23 <= '0' when hr = 23 else '1';
CLOCK_PROCESS:
process(clk)
begin
if clk'event and clk = '1' then
ALARM_INDICATON:
if min = almr_min and hr = almr_hr and almr_enbl = '1' then
almr_indct <= to_bit(not clk_set);
else
almr_indct <= '0';
end if;
SET_MINUTES:
if pb_min = '1' and clk_set = '1' then
if min_neq_59 = '1' then
min <= min + 1;
else
min <= 0;
end if;
SET_HOURS:
elsif pb_hr = '1' and clk_set = '1' then
if hr_neq_23 = '1' then
hr <= hr + 1;
else
hr <= 0;
end if;
INCREMENT_SECONDS:
elsif sec_neq_59 = '1' then
sec <= sec + 1;
else -- sec = 59
sec <= 0;
INCREMENT_MINUTES:
if min_neq_59 = '1' then
min <= min + 1;
else -- :59:59
min <= 0;
INCREMENT_HOURS:
if hr_neq_23 = '1' then
hr <= hr + 1;
else -- 23:59:59
hr <= 0;
end if;
end if;
end if;
end if;
end process;
end architecture foo;
And with the opportunity I fixed the range for the sec, min and hr counters. The secret is evaluating before incrementing, you intercept a terminal count with a synchronous load.
Also switched to equality comparisons to specific values, separated them to reduce hardware by having one set and prioritized the push buttons over the clock operation by using elsif.
So now push buttons can't cause range errors in minutes and hours, and are independent of actual clock time.
I don't think it's valid to reset seconds when incrementing minutes with the push button. It might be valid to keep seconds at 0 while clock_set is true, which would stop the clock from running when being set. That doesn't work if you're only fixing daylight savings time or changing time zones, though.
I haven't simulated this. It analyzes and elaborates. Range errors in assignment would show up during simulation.
I left almr_indct as type bit, but did use clk_set as a condition for the alarm indication.

Related

How to correct a phase shift using a clock divider in VHDL?

I want to make a UART receiver that reads 8 consecutives bits with a parity bit at the end and with a simple stop bit. My FPGA have a clock of 100Mhz and the data that are transmitted to the uart have a rate of 56700 bauds. The dividing factor is 1736 (56700 * 1736 ≈ 100Mhz). The two outputs are the message of the input decoded by the uart and an error signal that indicates if the uart have correctly read the input. This is what I have :
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
entity uart_receiver is
generic (
clksPerBit : integer := 1736 -- Needs to be set correctly
);
port (
clk : in std_logic;
clk_en_uart : in std_logic ;
reset : in std_logic;
uart_rx : in std_logic;
error : out std_logic;
char : out std_logic_vector(7 downto 0)
);
end uart_receiver;
architecture uart_receiver_arch of uart_receiver is
type etat is (init, start_bit, receiving_bits, parity_bit,
stop_bit );
signal current_state : etat := init ;
signal error_signal : std_logic := '0';
signal clk_count : integer range 0 to clksPerBit-1 := 0;
signal bit_index : integer range 0 to 7 := 0; -- 8 Bits Total
signal data_byte : std_logic_vector(7 downto 0) := (others => '0');
begin
process (clk_en_uart)
begin
if rising_edge(clk_en_uart) then
end if;
end process;
process (clk,reset)
variable check_parity : integer range 0 to 7 := 0;
begin
if (reset = '1') then
current_state <= init;
error_signal <= '0';
clk_count <= 0;
bit_index <= 0;
data_byte <= (others => '0');
elsif rising_edge(clk) then
case current_state is
when init =>
clk_count <= 0;
Bit_Index <= 0;
if uart_rx = '0' then -- Start bit detected
current_state <= start_bit;
else
current_state <= init;
end if;
when start_bit =>
if clk_count = (clksPerBit-1)/2 then
if uart_rx = '0' then
clk_count <= 0; -- reset counter since we found the middle
current_state <= receiving_bits;
else
current_state <= init;
end if;
else
clk_count <= clk_count + 1;
current_state <= start_bit;
end if;
when receiving_bits =>
if clk_count < clksPerBit-1 then
clk_count <= clk_count + 1;
current_state <= receiving_bits;
else
clk_count <= 0;
data_byte(bit_index) <= uart_rx;
if bit_index < 7 then
bit_index <= bit_index + 1;
current_state <= receiving_bits ;
else
bit_index <= 0;
current_state <= parity_bit;
end if;
end if;
when parity_bit =>
if clk_count < clksPerBit-1 then
clk_count <= clk_count + 1;
current_state <= parity_bit;
else
for k in 0 to 7 loop
if ( data_byte(k) = '1' ) then
check_parity := check_parity + 1 ;
end if;
end loop;
if((uart_rx = '1' and check_parity mod 2 = 0) or (uart_rx = '0' and check_parity mod 2 = 1)) then
error_signal <= '1' ;
else
error_signal <= '0';
end if ;
current_state <= stop_bit;
end if;
when stop_bit =>
if clk_count < clksPerBit-1 then
clk_count <= clk_count + 1;
current_state <= stop_bit ;
else
clk_count <= 0;
current_state <= init;
end if;
when others =>
current_state <= init;
end case;
end if;
char <= data_byte ;
error <= error_signal ;
end process;
end uart_receiver_arch;
So there's a phase shift between the data that is transmitted to the uart and his clock. If there's a phase shift, I'm not reading the data at the right time. I think that this code is sufficient to solve this problem. But, I've created a clock_divider and I can't seem to find a way to use it in this code. This is my clock divider :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity clock_divider is
generic (divfactor : positive := 1736);
Port (clk,clk2, reset : in STD_LOGIC ;
clkdiv, activationsig : out STD_LOGIC );
end clock_divider;
architecture clock_divider_arch of clock_divider is
begin
process(clk,reset)
variable clksigv : std_logic := '0' ;
variable activationsigv : std_logic := '0' ;
variable count : integer := 0 ;
begin
if (reset = '1') then
clksigv := '0' ;
activationsigv := '0' ;
count := 0 ;
elsif ( rising_edge(clk) ) then
count := count + 2 ;
if (activationsigv = '1') then
activationsigv := '0';
end if;
if ( count >= divfactor - 1 ) then
clksigv := not(clksigv) ;
if ( clksigv = '1' ) then
activationsigv := '1' ;
end if;
count := 0 ;
end if ;
end if ;
clkdiv <= clksigv ;
activationsig <= activationsigv;
end process ;
end clock_divider_arch;
The outputs of this clock divider are the clock divided and the activation signal that, when it is at '1', I have to read the data in the uart. So, the two outputs should also be inputs of the uart. In the uart_recevier, clk_en_uart is actually the clock divided, but I'm not using it because I don't know how.
I think that the solution is to 'activate' this divided clock when I enter in the start_bit case so that I have two clocks with the same phase and the same frequency, but I also think that it impossible to set a phase for a clock.
I'm not sure that I've clearly adressed my problem. If there's something that you don't understand in my code or in my explanation, feel free to ask questions.
Thank you for your help, hoping that I find a solution.
Sounds like the suggested solution is complicated for this problem.
A usual approach is that the receiver justs look for the falling edge of the start bit, then count for half a bit time (1736 / 2 cycles in your case), then samples the start bit value there, and subsequently samples the data, parity and stop bit values after each full bit time (1736 cycles in your case). After that start over looking for a new falling edge of the start bit.
The difference between the transmitter and receiver frequencies are then (usually) so small that the sample time will be practically in the middle for messages of only 11 bits at relative low bitrate, and the counter restart at falling edge of start bit ensures that any effect of long time frequency difference is removed.

Need advice for my vhdl code

I am working on my college project a digital clock on altera board. the problem i am facing is my hours goes to 29 instead of 24! I am using integer type for my hours right digit ranging 0 to 9; i got if statement that when my hours left digit is 2 and hours right digit is 3 i want my second, minutes and hours 00:00:00.. But its not implementing why? Need some advice... Thanks
here is my code :
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity master is
port(
clk : in std_logic;
hrs_lft : out std_logic_vector(1 downto 0 );
hrs_rght : out std_logic_vector(3 downto 0 );
min_lft : out std_logic_vector(2 downto 0 );
min_rght : out std_logic_vector(3 downto 0 );
second_lft: out std_logic_vector(2 downto 0);
second_rght : out std_logic_vector( 3 downto 0)
);
end master;
architecture bhv of master is
signal second_lft_int : integer range 0 to 5;
signal second_rght_int : integer range 0 to 9;
signal min_lft_int : integer range 0 to 5;
signal min_rght_int : integer range 0 to 9;
signal hrs_lft_int : integer range 0 to 2;
signal hrs_rght_int : integer range 0 to 9;
begin
process(clk)
begin
if (rising_edge(clk)) then
second_rght_int <= second_rght_int + 1;
if second_rght_int = 9 then
second_lft_int <= second_lft_int + 1;
second_rght_int <= 0;
if second_lft_int = 5 then
second_lft_int <= 0;
min_rght_int <= min_rght_int + 1;
if min_rght_int = 9 then
min_lft_int <= min_lft_int + 1;
min_rght_int <= 0;
if min_rght_int = 5 then
hrs_rght_int <= hrs_rght_int + 1;
min_rght_int <= 0;
if hrs_rght_int = 9 then
hrs_lft_int <= hrs_lft_int + 1;
if (hrs_rght_int = 3 and hrs_lft_int = 2) then
hrs_lft_int <= 0;
hrs_rght_int <= 0;
min_lft_int <= 0;
min_rght_int <= 0;
second_rght_int <= 0;
second_lft_int <= 0;
end if ;
end if;
end if;
end if;
end if;
end if;
end if;
end process;
second_rght<= std_logic_vector(to_unsigned(second_rght_int,second_rght'length));
second_lft<=std_logic_vector(to_unsigned(second_lft_int,second_lft'length));
min_rght<= std_logic_vector(to_unsigned(min_rght_int,min_rght 'length));
min_lft <= std_logic_vector(to_unsigned(min_lft_int,min_lft'length));
hrs_rght<= std_logic_vector(to_unsigned(hrs_rght_int,hrs_rght 'length));
hrs_lft <= std_logic_vector(to_unsigned(hrs_lft_int,hrs_lft'length));
end bhv;
You process didn't look right, so I wrote it de novo:
process (clk)
begin
if rising_edge(clk) then
if second_rght_int = 9 then
second_rght_int <= 0;
if second_lft_int = 5 then
second_lft_int <= 0;
if min_rght_int = 9 then
min_rght_int <= 0;
if min_lft_int = 5 then
min_lft_int <= 0;
if (hrs_lft_int = 2 and hrs_rght_int = 4)
or hrs_rght_int = 9 then
hrs_rght_int <= 0;
if hrs_lft_int = 2 then
hrs_lft_int <= 0;
else
hrs_lft_int <= hrs_lft_int + 1;
end if;
else
hrs_rght_int <= hrs_rght_int + 1;
end if;
else
min_lft_int <= min_lft_int + 1;
end if;
else
min_rght_int <= min_rght_int + 1;
end if;
else
second_lft_int <= second_lft_int + 1;
end if;
else
second_rght_int <= second_rght_int + 1;
end if;
end if;
end process;
And that gives:
In VHDL "+" for integer is defined as an operation on a type integer and not a modular integer, you have to check for the boundary condition yourself.
You might also notice I set the clk rate to 1 ps in simulation. A bit excessive but I wanted to search for roll over events.
A testbench can consist of as little as a direct entity instantiation with a single port association for the clk. (The waveforms are from the Device Under Test).

VHDL : Signal s Cannot be Synthesised

line 62: Signal s cannot be synthesized, bad synchronous description.
The description style you are using to describe a synchronous element
(register, memory, etc.) is not supported in the current software
release.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity clock is
Port ( start : in STD_LOGIC;
reset : in STD_LOGIC;
CLOCK : in STD_LOGIC;
setH, setM, setS : in STD_LOGIC;
alarmH, alarmM, alarmS : in STD_LOGIC;
Alarm_On : in STD_LOGIC;
Buzzer_Stop : in STD_LOGIC;
BUZZER : out STD_LOGIC;
hh, mm, ss : out INTEGER);
end clock;
architecture Behavioral of clock is
signal h, m, s : INTEGER range 0 to 60 := 0;
signal hA, mA, sA : INTEGER range 0 to 60 := 0;
signal clk : std_logic :='0';
signal count : integer :=1;
begin
Frequency_Reducer : process(CLOCK) --Reducing Frequency From 40MHz to 1Hz
begin
if rising_edge(CLOCK) then
count <= count + 1;
if(count = 20000000) then
clk <= not clk;
count <=1;
end if;
end if;
end process;
Clock_Logic : process(start, reset, clk)
begin
if reset = '1' then
h <= 00;
m <= 00;
s <= 0;
end if;
if start = '1' then
if rising_edge(clk) then --Clock Logic Start
s <= s + 1;
end if;
end if;
if s = 60 then
s <= 0;
m <= m + 1;
end if;
if m = 60 then
m <= 0;
h <= h + 1;
end if;
if h = 24 then
h <= 0;
end if; --Clock Logic End
if setH = '1' then --Set Time Logic Start
h <= h + 1;
end if;
if setM = '1' then
m <= m + 1;
end if;
if setS = '1' then
s <= s + 1;
end if; -- Set Time Logic End
end process;
hh <= h;
mm <= m;
ss <= s;
end Behavioral;
Let's take a look at the assignments of signal s only:
Clock_Logic : process(start, reset, clk)
begin
if reset = '1' then
s <= 0;
end if;
if start = '1' then
if rising_edge(clk) then --Clock Logic Start
s <= s + 1;
end if;
end if;
if s = 60 then
s <= 0;
end if;
if setS = '1' then
s <= s + 1;
end if; -- Set Time Logic End
end process;
In the last assignment, you are requesting that s is incremented when setS is high and the process is executed (resumed). The process is executed initially after system startup and every time when one of the signals in the sensitivity list changes. Thus, you are requesting flipf-flops clocked on both edges of three signals start, reset and clock. I suspect, that this increment should be done only on the rising edge of the clock:
if rising_edge(clk) then --Clock Logic Start
if setS = '1' then
s <= s + 1;
end if; -- Set Time Logic End
end if;
The asynchronous reset of s when s reaches 60 is possible, but error prone due to glitches. s is is multi-bit signal in hardware. Thus, when it is incremented it could be equal to 60 for short moments in time even when the final value is below 60! You should reset it synchronously to 0, when current value is 59.
The increment of s when start is high and a rising-edge on the clock occur is ok, but synthesis tool often request to re-arrange this so that the outer if block checks for the rising edge:
if rising_edge(clk) then --Clock Logic Start
if start = '1' then
s <= s + 1;
end if;
end if;
Finally, the asynchronous reset (or set) inputs on flip-flops have always a higher priority then the synchronous data inputs. Thus, you must arrange it either this way:
Clock_Logic : process(reset, clk)
begin
if reset = '1' then
-- asynchronous part
s <= 0;
elsif rising_edge(clk) then
-- synchronous part (add more conditions if required)
s <= s + 1;
end if;
end process;
or this way:
Clock_Logic : process(reset, clk)
begin
if rising_edge(clk) then
-- synchronous part (add more conditions if required)
s <= s + 1;
end if;
if reset = '1' then
-- asynchronous part
s <= 0;
end if;
end process;
The synchronous assignments can be more complex. For example, if you want to synchronously reset a counter when it reaches 59 and to increment it otherwise when the signal setS is high:
Clock_Logic : process(reset, clk)
begin
if reset = '1' then
-- asynchronous part
s <= 0;
elsif rising_edge(clk) then
-- synchronous part
if s = 59 then
s <= 0;
elsif setS = '1' then
s <= s + 1;
end if;
end if;
end process;

Signal parameter in a subprogram is not supported error

My code is about a ping pang game using VHDL and maxplus2. I can't get it complied.
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_unsigned.all;
-- use ieee.std_logic_arith.all;
entity center is
port (
clk: in std_logic;
ca: in std_logic;
cb: in std_logic;
enable: in std_logic;
a: in std_logic;
b: in std_logic;
ball: out std_logic_vector(16 downto 0);
sa: out std_ulogic;
sb: out std_ulogic;
over: inout std_ulogic
);
end center;
architecture behavior of center is
signal direction : integer range 0 to 2;
signal num : integer range -1 to 17;
begin
process (enable,ca,cb,a,b,clk)
begin
if enable = '0' then
over <= '0';
sa <= '0';
sb <= '0';
elsif enable = '1' and rising_edge(clk) then
if direction = 2 then
if ca = '1' then
direction <= 0;
num <= 1;
elsif cb = '1' then
direction <= 1;
num <= 16;
else
direction <= 2;
num <= 8;
end if;
elsif direction = 0 and num > 0 then
if b = '1' then
if num < 2 then
num <= num - 1;
direction <= 1;
else
direction <= 2;
sa <= '1' after 10 ns;
sb <= '0' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
elsif direction = 1 and num <= 16 then
if a = '1' then
if num >= 14 then
num <= num + 1;
direction <= 2;
else
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
elsif direction = 0 and num = -1 then
num <= 8;
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
elsif direction = 0 and num = -1 then
num <= 8;
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
end process;
end architecture behavior;
But I get a error:
signal parameter in a subprogram is not supported
I am confused, I don't know why I get this error.
I think as David also said you need to provide more information.
What it looks like for me is that your are writing a test bench the above code cannot be synthesized correctly. ISE will tell you that your syntax is ok but the delays are ignored IE the after keyword. The after keyword is only used in simulation.
That said i would also clean up the code there are a lot of redundancies. FX
The last two elsif statements. only one is needed. and the sensitivity list. only clk and enable should be there.
I've tried to clean up your code:
process (enable,clk)
begin
if enable = '0' then
over <= '0';
sa <= '0';
sb <= '0';
elsif rising_edge(clk) then
case( direction ) is
when 0 =>
if num > 0 then
if b = '1' then
if num < 2 then
num <= num - 1;
direction <= 1;
else
direction <= 2;
sa <= '1' after 10 ns;
sb <= '0' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
elsif num = -1 then
num <= 8;
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
end if;
when 1 =>
if num <= 16 then
if a = '1' then
if num >= 14 then
num <= num + 1;
direction <= 2;
else
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
end if;
when 2 =>
if ca = '1' then
direction <= 0;
num <= 1;
elsif cb = '1' then
direction <= 1;
num <= 16;
else
direction <= 2;
num <= 8;
end if;
when others => NULL;
end case ;
end if;
end process;
Try and remove your after keywords and see if it will compile then.

Vhdl rising_edge statement not synthesizable

I am writing a little program for use on my Zybo FPGA, its supposedly a variable frequency divider with 10 different steps.
However on the last line when I try to output my clock to an LED for testing purposes it gives me this error: Line 137: statement is not synthesizable since it does not hold its value under NOT(clock-edge) condition
Here is my code
entity StappenMotor is
Port ( Reset, CLK : in STD_LOGIC;
X1, X2 : in STD_LOGIC;
Z1 : out STD_LOGIC);
end StappenMotor;
architecture Behavioral of StappenMotor is
signal speed : integer := 0;
signal puls : STD_LOGIC;
begin
speed_proc: process(X1, X2) is
begin
if (rising_edge(X1) and speed < 10) then
speed <= speed + 1;
elsif (rising_edge(X2) and speed > 0) then
speed <= speed - 1;
end if;
end process speed_proc;
freq_proc: process(CLK) is
variable int : integer := 0;
begin
if rising_edge(CLK) then
int := int + 1;
end if;
case speed is
when 0 =>
if int = 250000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 1 =>
if int = 200000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 2 =>
if int = 175000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 3 =>
if int = 150000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 4 =>
if int = 125000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 5 =>
if int = 100000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 6 =>
if int = 75000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 7 =>
if int = 62500000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 8 =>
if int = 50000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 9 =>
if int = 35000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when 10 =>
if int = 25000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
when others =>
if int = 10000000 then
puls <= '1';
int := 0;
else puls <= '0';
end if;
end case;
end process freq_proc;
test: process(puls) is
begin
if rising_edge(puls) then
Z1 <= '1';
else Z1 <= '0';
end if;
end process test;
end Behavioral;
Error occurs on the line:
if rising_edge(puls) then
Anyone got a clue?
Kind regards.
All of your processes have some issues, though the compiler may not complain about them as loudly as the one in test.
In speed_proc, you are qualifying rising_edge() with an additional comparison. I would recommend nesting if statements instead (put the comparison if inside the rising_edge() if). You're also trying to clock the same register with 2 separate clocks. You probably need to find a different way to do this.
In freq_proc, only your variable increment is inside the rising_edge() check - I don't see a reason not to put the rest in as well. It's more standard, and it should generally lead to fewer unexpected problems.
In test, as #Chiggs mentioned, what you're trying to accomplish is invalid. If you want to toggle Z1 every clock cycle, you can do:
if rising_edge(puls) then
Z1 <= not Z1;
end if;
(For simulation, you'd need to initialize Z1 to see a valid output.)
The problem is the whole test process, not just the single line you've mentioned.
test: process(puls) is
begin
if rising_edge(puls) then
Z1 <= '1';
else Z1 <= '0';
end if;
end process test;
If you think about what you've described here, you're asking to drive Z1 high whenever there's a rising edge on the clock and drive it low whenever puls changes but isn't a rising edge (which includes Z->1, 1->0, Z->0 transitions).
This generally isn't possible in an FPGA and therefore is not synthesisable, hence the tool complaining.

Resources