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).
Related
I have a simple VHDL code which has two process. The second process updates the output port m_LED based on the state CF value. In simulation I see the behavior as expected. But when I program the FPGA I noticed that, the output port m_LED is producing some random values which is not even assigned in the code. I am totally clueless from where these values are coming. Any hint will be much appreciated!
entity monitor is
Port (
io_LED: in std_logic_vector(3 downto 0);
m_LED: out std_logic_vector(3 downto 0)
);
end monitor;
architecture Behavioral of monitor is
type state_type is (s0, s1, s2,s3);
signal state: state_type :=s0;
signal nrst:std_logic:='1';
begin
Process (io_LED)
begin
if (nrst= '0') then
state<= s0;
else
case state is
when s1 =>
if (io_LED = "0000") then
state <= s2;
end if;
when others => state <= s0;
end case;
end if;
end Process;
Process(io_LED)
begin
m_LED<="0000";
case state is
when s0 =>
m_LED<="0000";
when s1 =>
m_LED<="0001";
when others => m_LED<="0000";
end case;
end Process;
end Behavioral;
I believe that what you are doing is a very long combinational path for a state machine. State machines are better implemented using a register to actually keep the state.
The downside is that you will need to provide a clock for the state register to sample the input and launch the output.
Changes:
CF is made as a register CF_r, to hold the state.\
First process is a sequential process, with the CF_r register holding the code { i, t, f,e } as defined by the input.
CF is the only element in the second process sensitivity list as it is a combinational output based only on the state.
-- Synchronous reset
entity monitor is
Port (
io_LED: in std_logic_vector(3 downto 0);
monit_LED: out std_logic_vector(3 downto 0)
);
end monitor;
architecture Behavioral of monitor is
type Code is (i, t, f,e);
signal CF_r: Code:=i;
signal nrst:std_logic:='1';
begin
-- Synchronous reset
Process (clk)
begin
if rising_edge(clk) then
if (nrst= '0') then --should be adapted to postive logic
CF_r <= t; --reset
else
case CF_r is
when i =>
if (io_LED = "0000") then
CF_r <= t;
end if;
when t =>
if (io_LED = "0001") then
CF_r <= f;
else
CF_r <=e;
end if;
when f =>
if (io_LED = "0010") then
CF_r <= t;
else
CF_r <=e;
end if;
when others => CF_r <= i;
end case;
end if;
end if;
end Process;
-- The output depends only on the state
Process(CF_r)
begin
case CF_r is
when i =>
monit_LED<="0000";
when t =>
monit_LED<="0001";
when f =>
monit_LED<="0010";
when e =>
monit_LED<="1111";
when others => monit_LED<="0000";
end case;
end Process;
end Behavioral;
I don't know where I am going wrong, or how to fix it. I am basically building a state counter and it starts at 33 and counts down to 0 before resetting but 29,28,19,18,9 and 8 all miss. I am stuck on where I am going wrong.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity sequencer is
PORT(clk: IN std_logic;
count : out unsigned (5 downto 0));
End sequencer;
ARCHITECTURE behavior OF sequencer IS
SIGNAL dSig, qSig : unsigned (5 downto 0);
BEGIN
PROCESS (clk, dSig)
BEGIN
dSig <= "011011";
if rising_edge(clk) Then
qSig <= dSig;
end if;
if qSig = "000000" then
dSig <= "011011";
else
dSig <= qSig - 1 ;
End if;
count <= qSig;
End Process;
END behavior;
The whole process can be simplified to
process (clk, reset)
begin
if reset then -- use an asynchronous reset for initial value
dSig <= "011011";
elsif rising_edge(clk) Then -- keep everything else within the synchronized block
count <= dSig;
if dSig = "000000" then
dSig <= "011011";
else
dSig <= dSig - 1 ;
end if;
end if;
end process;
Work with one counter signal and keep everything within the synchronized block of your process, or is there a reason for the async output evaluation?
I suspect this is because of your mixing synchronous and asynchronous elements inside the same process, and glitches are causing the counter to skip. I suggest making it wholly synchronous.
ARCHITECTURE behavior OF sequencer IS
SIGNAL count_i : unsigned (5 downto 0) := (others => '0')
BEGIN
PROCESS (clk)
BEGIN
if rising_edge(clk) Then
count_i <= count_i + 1;
end if;
End Process;
count <= count_i;
END behavior;
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.
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;
I am getting a warning that an arithmetic operation have X so the result is will always be X, although I am initializing my signals to 0s. Can anyone help?
N.B. I am getting X for Z_count and RC_count_var
--RC counter
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
Entity RC_counter2 is
Port(load, Cplus, Cminus : In Std_logic;
X: In std_logic_vector (3 downto 0) :="0000";
Z_count: Out std_logic_vector (3 downto 0) :="0000");
end Entity;
Architecture behav of RC_counter2 is
signal RC_count_var: std_logic_vector(3 downto 0):="0000";
Begin
process(Cplus, load)
--variable RC_count_var: std_logic_vector(3 downto 0):="0000";
Begin
if load = '1' then
RC_count_var <= X;
end if;
if (Cplus'EVENT and Cplus = '1') then
RC_count_var <= RC_count_var + 1;
else
RC_count_var <= RC_count_var;
end if;
end process;
process(Cminus, load)
Begin
if load = '1' then
RC_count_var <= X;
end if;
if (Cminus'EVENT and Cminus = '1') then
RC_count_var <= RC_count_var - 1;
else
RC_count_var <=RC_count_var;
end if;
end process;
Z_count <= RC_count_var;
end Architecture;
The value of RC_Count_var becomes invalid because it has multiple conflicting drivers.
In VHDL, whenever a signal is assigned in more than one process, it implies multiple drivers. These are usually not supported for synthesis and not recommended altogether. To make sure you do not have multiple drivers, simply makes all assignations to a signal in a single process.
Moreover, while not exactly wrong or problematic, I suggest you modify the following code:
if load = '1' then
RC_count_var <= X;
end if;
if (Cplus'EVENT and Cplus = '1') then
RC_count_var <= RC_count_var + 1;
else
RC_count_var <= RC_count_var;
end if;
This doesn't gives multiple drivers, but has several problems. First, successive assignments to the same signal in a process overrides previous one. Thus, if cplus is rising and load is '1', the value doesn't get loaded. It is much better and cleaner to use elsif or else. Also, synthesis target doesn't usually support asynchronous load. Asynchronous set/reset is fine, but asynchronous load to the value X, in your case, is likely problematic.