entity timer is
Port ( click : in STD_LOGIC;
clear : out STD_LOGIC;
t_unlock : out STD_LOGIC);
end timer;
architecture Behavioral of timer is
signal temp2 : integer range 0 to 20 := 0;
begin
process
begin
if rising_edge(click) then
temp2<=0;
clear<='0';
t_unlock<='0';
else
temp2<=temp2+1 after 15 ns;
end if;
if temp2=6 then
clear<='1';
elsif temp2=20 then
t_unlock<='1';
end if;
end process;
end Behavioral;
I have writted this code.And the complier say:
Signal temp2 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.
I have searched on stackoverflow.They say The error 'bad synchronous description' usually means that you have described a register (clocked element) that does not exist in the hardware.But I don't know how to solve my problem.
The VHDL has to follow some synthesis tool specific coding guidelines, for the tool to be able to translate the VHDL code into the FPGA implementation. For implementation to a flip-flop with asynchronous reset, the style can be:
process (clk, rst) is
begin
-- Clock
if rising_edge(clk) then
... -- Update at clock
end if;
-- Asynchronous reset
if rst = '1' then
... -- Update at reset
end if;
end process;
In the case of your code it looks like you are not using the asynchronous reset, thus the template may be reduced to:
process (clk) is
begin
if rising_edge(clk) then
... -- Update at clock
end if;
end process;
The exercise is now for you to fit your code into that template, and unfortunately it is pretty hard to determine the exact intention based on the provided code.
Your code seems to mix concepts of HDL and "software" languages. I'm not sure what it's supposed to do, but I would refactor it into the code below
architecture Behavioral of timer is
constant COUNTER_VALUE_TO_REACH_15ns : integer := <some value>;
signal temp2 : integer range 0 to 20 := 0;
signal divider : std_logic_vector(7 downto 0) := (others => '0');
begin
process
begin
-- Everything happens when the clock ticks, except for reset
if rising_edge(click) then
temp2 <= 0;
clear <= '0';
t_unlock <= '0';
-- Count how many cycles until we need to increment temp2
if divider = COUNTER_VALUE_TO_REACH_15ns then
temp2 <= temp2 + 1;
divider <= (others => '0'); -- Reset the counter when we reach the required amount of time
else
divider <= divider + 1;
end if;
if temp2 = 6 then
clear <= '1';
elsif temp2 = 20 then
t_unlock <= '1';
end if;
else
end if;
end process;
end Behavioral;
Related
I'm writing a timer using FPGA.
I will use seven segment display to show the numbers, but I also must be able to set a specific time by increasing/decreasing and then once it is set, with another button the clock will start to go down.
signal lock is for preventing the count increases at the speed of the
manual is a button,
I guess the count up is okay, but the problem is when I want it to go down. In the simulation when I put the sentido HIGH then I do not get anything and does not work.
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity counter is
port( clck, reset : in std_logic;
limit : in integer range 0 to 10;
manual: inout std_logic;
sentido: in std_logic;
bitcount : out std_logic_vector(3 downto 0);
clckout : out std_logic);
end counter;
architecture behavior of counter is
signal Cs : std_logic_vector(3 downto 0):="0000";
signal lock: std_logic;
begin
Count : process(clck,reset,manual,lock,sentido)
begin
if(rising_edge(clck))then
if (manual='0' and lock ='0') then
Cs<=Cs+1;
lock<='1';
elsif(manual='1' and lock='1' ) then
lock<='1';
else
lock<='0';
end if;
end if;
if sentido = '1' then
Cs<=Cs-1;
end if;
if (reset = '1') then
Cs <="0000";
end if;
if (Cs = "1010") then
Cs <= "0000";
end if;
end process Count;
bitcount <=Cs;
end behavior;
Your
if sentido = '1'
clause is asycnronous, it works completely independent from clock. This is not synhtesizable in most tools, but might pass thru a simulator checks.
Same goes about all the conditions below.
To fix this, you should fuse them all into your if(rising_edge(clck)) clause like this:
if(rising_edge(clck))then
if (reset = '1') then
Cs <="0000";
elsif (manual='0' and lock ='0') then
if sentido = '1' then
Cs<=Cs-1;
if (Cs = "0000") then --using previous state
Cs <= "1010";
end if;
else
Cs<=Cs+1;
if (Cs = "1001") then --using previous state
Cs <= "0000";
end if;
end if;
lock<='1';
elsif(manual='1' and lock='1' ) then
lock<='1';
else
lock<='0';
end if;
end if;
Oh, and one more thing. You should not include anything but clock in sync process sensitivity list, it will change anything only on clock anyway.
I am completely new to programming CPLDs and I want to program a latch + counter in Xilinx ISE Project Navigator using VHDL language. This is how it must work and it MUST be only this way: this kind of device gets 2 clock signals. When one of them gets from HIGH to LOW state, data input bits get transferred to outputs and they get latched. When the 2nd clock gets from LOW to HIGH state, the output bits get incremented by 1. Unfortunately my code doesn't want to work....
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity counter8bit is
port(CLKDA, CLKLD : in std_logic;
D : in std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0));
end counter8bit;
architecture archi of counter8bit is
signal tmp: std_logic_vector(7 downto 0);
begin
process (CLKDA, CLKLD, D)
begin
if (CLKLD'event and CLKLD='0') then
tmp <= D;
elsif (CLKDA'event and CLKDA='1') then
tmp <= tmp + 1;
end if;
end process;
Q <= tmp;
end archi;
Is there any other way around to achieve this?? Please for replies. Any kind of help/suggestions will be strongly appreciated. Many thanks in advance!!
Based on the added comments on what the counter is for, I came up with the following idea. Whether it would work in reality is hard to decide, because I would need a proper timing diagram for the EPROM interface. Importantly, there could be clock domain crossing issues depending on what restrictions there are on how the two clock signals are asserted; if there can be a falling edge of CLKLD close to a rising edge of CLKDA, the design may not work reliably.
signal new_start_address : std_logic := '0';
signal start_address : std_logic_vector(D'range) := (others => '0');
...
process (CLKLD, CLKDA)
begin
if (CLKDA = '1') then
new_start_address <= '0';
elsif (falling_edge(CLKLD)) then
start_address <= D;
new_start_address <= '1';
end if;
end process;
process (CLKDA)
begin
if (rising_edge(CLKDA)) then
if (new_start_address = '1') then
tmp <= start_address;
else
tmp <= tmp + 1;
end if;
end if;
end process;
I'm not completely clear on the interface, but it could be that the line tmp <= start_address; should become tmp <= start_address + 1;
You may also need to replace your assignment of Q with:
Q <= start_address when new_start_address = '1' else tmp;
Again, it's hard to know for sure without a timing diagram.
I have a error while Synthesize this code in Xillinx. This error is:
Analyzing Entity in library (Architecture ).
ERROR:Xst:827 - "C:/Xilinx92i/Parking/Parking.vhd" line 43: Signal current cannot be synthesized, bad synchronous description.
entity Parking is port(
A, B ,reset: in std_logic;
Capacity : out std_logic_vector(7 downto 0));
end Parking;
architecture Behavioral of Parking is
type state is (NoChange, Aseen, Bseen, ABseen, BAseen, Input, Output, Din, Dout);
signal current, nxt : state ;
signal counter : std_logic_vector (7 downto 0) := "00000000";
begin
p1: process(A, B, reset)
begin
if reset = '1' then
current <= Nochange;
end if;
if(A'event and A='1') then
current <= nxt;
end if;
if(A'event and A='0') then
current <= nxt;
end if;
if(B'event and B='1') then
current <= nxt;
end if;
if(B'event and B='0') then
current <= nxt;
end if;
end process;
p2: process(current, A, B)
begin
case current is
when Aseen =>
if B='1' then
nxt <= ABseen;
else
nxt <= NoChange;
end if;
when others =>
nxt <= Nochange;
end case;
end process;
Capacity <= counter;
end Behavioral;
The error 'bad synchronous description' usually means that you have described a register (clocked element) that does not exist in the hardware.
In the case of your code, you have:
if(A'event and A='1') then
current <= nxt;
end if;
if(A'event and A='0') then
current <= nxt;
end if;
-- etc
inside one process. Synchronous synthesisable processes will typically only have one clock, because there is no element in a real silicon device like an FPGA that can respond to events on two different clocks. A process like the one you are trying to implement would typically look something more like this:
process (clk)
begin
if (rising_edge(clk)) then
if (a = '1') then
current <= nxt;
elsif (a = '0') then
current <= nxt;
end if;
end if;
end process;
Implementing it this way requires that you have:
A clock in your system
Inputs that meet setup/hold times relative to this clock
Side note
If you don't have a meaningful name for a process, you don't have to give it one at all. process (clk) is just as valid as p1 : process(clk).
i am trying to write a code but i get error, i dont understand that, i am new to vhdl, any help would be appreciated.
code:
entity counter is
port
(
upp_down : in std_logic;
rst : in std_logic;
pressed : in std_logic;
count : out std_logic_vector(3 downto 0)
);
end entity;
architecture rtl of counter is
signal count_value: std_logic_vector(3 downto 0);
begin
process (rst,pressed,upp_down)
begin
if(rst'event and rst = '0') then
count <= "0000";
else
if(pressed'event and pressed = '0' ) then
if(upp_down = '1') then
count_value <= count_value + 1;
elsif(upp_down = '0') then
count_value <= count_value - 1;
end if;
end if;
end if;
end process;
count <= count_value;
end rtl;
Errors:
Error (10820): Netlist error at counter.vhd(28): can't infer register for count_value[1] because its behavior depends on the edges of multiple distinct clocks
Error (10822): HDL error at counter.vhd(28): couldn't implement registers for assignments on this clock edge
The first problem is that you're trying to use the edge of two different 'clocks' in one process. A particular process can only respond to one clock.
The second problem is that your code does not translate into any real-world hardware. There's nothing in the FPGA that can respond to there not being an edge of a clock, which is what you have described with your if(rst'event and rst = '0') then else structure.
Nicolas pointed out another problem (which your compiler didn't get as far as), which is that you're assigning count both inside and outside a process; this is not allowed, as signals can only be assigned in one process.
Generally the type of reset it looks like you're trying to implement would be written as in the example below:
process (rst,pressed,upp_down)
begin
if(rst = '0') then
count_value <= "0000";
elsif(pressed'event and pressed = '0' ) then
if(upp_down = '1') then
count_value <= count_value + 1;
elsif(upp_down = '0') then
count_value <= count_value - 1;
end if;
end if;
end process;
count <= count_value;
The reason for changing the reset to affect count_value, is that without this, the effect of your reset would only last one clock cycle, after which the count would resume from where it left off (Thanks #Jim Lewis for this suggestion).
In addition to your compile errors, you should try to use the rising_edge() or falling_edge() functions for edge detection, as they behave better than the 'event style.
The reset can be more easily implemented using count_value <= (others => '0'); this makes all elements '0', no matter how long count is.
Lastly, it looks like you're using the std_logic_arith package. There are many other answers discouraging the use of this package. Instead, you should use the numeric_std package, and have your counter of type unsigned. If your output must be of type std_logic_vector, you can convert to this using a cast: count <= std_logic_vector(count_value);.
One more thing, I just noticed that your counter is not initialised; this can be done in the same way as I suggested for the reset function, using the others syntax.
"count" can't be assigned inside and outside a process.
count <= "0000"; <-- inside process
count <= count_value; <-- outside process.
You should do "count <= count_value;" inside your process :
entity counter is
port
(
upp_down : in std_logic;
rst : in std_logic;
pressed : in std_logic;
count : out std_logic_vector(3 downto 0)
);
end entity;
architecture rtl of counter is
signal count_value: std_logic_vector(3 downto 0);
begin
process (rst,pressed,upp_down)
begin
if(rst'event and rst = '0') then
count <= "0000";
else
if(pressed'event and pressed = '0' ) then
if(upp_down = '1') then
count_value <= count_value + 1;
elsif(upp_down = '0') then
count_value <= count_value - 1;
end if;
count <= count_value;
end if;
end if;
end process;
end rtl;
I am trying to compare two values in a clk cycle
eg:
if(riding_edge(clk)) then
if (some signal = other) then
other<=other+1;
else other<=other;
if(other=3)then
flag=1;
end if;
end if;
The code compiles and runs fine but when I am seeing the simulation window, the flag gets set no matter what is the value of other. Am I doing something wrong or the value of other is fluctuating.
The above is a pseudo code and everything is correct syntactically.
Please Help
Thanks in advance
Without a minimal working example, I could only guess that you're inferring a latch by not specifying what happens to flag when other is not 3. To prevent this, you would specify all cases of any decision tree.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY example IS
PORT (some_signal : IN STD_LOGIC;
other : IN STD_LOGIC;
clk : IN STD_LOGIC;
flag : OUT STD_LOGIC;
);
END example;
ARCHITECTURE minimal OF example IS
BEGIN
minexample:PROCESS(clk)
BEGIN
IF (clk'EVENT and clk='1') THEN
IF some_signal = other THEN
other <= other + '1';
ELSE other <= other;
END IF;
IF(other = '1') THEN
flag <= '1';
ELSE flag <= '0'; -- always specify all cases
END IF;
END IF;
END PROCESS minexample;
END minimal;
I use the code of N8TRO and add an reset to set the signal to zero at the startup and change the signal other to integer (because you like to check on the value 3) and check on rising_edge (should be the better way).
Now the signal flag should raise to high after 4 clocks after the Reset is set to low. Is this the behavior you expect?
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY example IS
PORT (some_signal : IN STD_LOGIC;
other : IN integer range 0 to 3; --this should be an integer 2 bit widht
clk : IN STD_LOGIC;
reset : IN STD_LOGIC;
flag : OUT STD_LOGIC;
);
END example;
ARCHITECTURE minimal OF example IS
BEGIN
minexample:PROCESS(clk,reset)
BEGIN
IF (reset = '1') then --i think a reset is a good idea
flag <= '0';
other <= 0;
ELSIF (rising_edge(clk)) THEN
IF some_signal = other THEN
other <= other + 1;
ELSE
other <= other;
END IF;
IF(other = 3) THEN --other is now an integer, so you can check on 3
flag <= '1';
ELSE
flag <= '0'; -- always specify all cases
END IF;
END IF;
END PROCESS minexample;
END minimal;