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;
Related
I know this error has been encountered several times on SO, but as a beginner I am still unable to see how to solve this error in my own code. The error and code are both printed below, thank you to anyone for their input.
Error (10818): Can't infer register for count[0] at 5bit_PHreg_vhdl.vhd(21) because it does not hold its value outside the clock edge
The error is repeated for each bit of 'count' and refers to the line noted in the code.
ARCHITECTURE behavioral OF 5bit_PHreg_vhdl IS
SIGNAL count : STD_LOGIC_VECTOR(4 DOWNTO 0);
BEGIN
PROCESS(reset, clk, SHR_EN)
BEGIN
-- Check if asynchronous reset is 0
IF reset = '0' THEN --ERROR OCCURS HERE
count <= "00000";
-- Check if rising edge
ELSIF (clk'EVENT AND clk = '1') THEN
IF LD_EN = '1' THEN
count <= FA_in;
END IF;
-- Check if SHR_EN is active
ELSIF (SHR_EN = '1') THEN
count(4) <= c_in;
count(3) <= count(4);
count(2) <= count(3);
count(1) <= count(2);
count(0) <= count(1);
c_out <= count(0);
END IF;
END PROCESS;
PH_reg_out <= count;
END behavioral;
ELSIF (SHR_EN = '1') THEN is outside the reset and clock edge conditions, it's form not recognized for synthesis.
Move it and the following assignments inside the preceding end if so it's registered. Remove SHR_EN from the process sensitivity list.
Also in VHDL a name can't start with a number, 5bit_PHreg_vhdl is invalid as an entity name.
Fixing these and filling in the missing entity declaration:
library ieee;
use ieee.std_logic_1164.all;
entity PH_reg_5_bit is
port (
reset: in std_logic;
clk: in std_logic;
LD_EN: in std_logic;
SHR_EN: in std_logic;
FA_in: in std_logic_vector (4 downto 0);
c_in: in std_logic;
c_out: out std_logic;
PH_reg_out: out std_logic_vector (4 downto 0)
);
end entity;
ARCHITECTURE behavioral OF PH_reg_5_bit IS
SIGNAL count : STD_LOGIC_VECTOR(4 DOWNTO 0);
BEGIN
PROCESS (reset, clk) -- , SHR_EN)
BEGIN
-- Check if asynchronous reset is 0
IF reset = '0' THEN --ERROR OCCURS HERE
count <= "00000";
-- Check if rising edge
ELSIF (clk'EVENT AND clk = '1') THEN
IF LD_EN = '1' THEN
count <= FA_in;
-- Check if SHR_EN is active
ELSIF (SHR_EN = '1') THEN
count(4) <= c_in;
count(3) <= count(4);
count(2) <= count(3);
count(1) <= count(2);
count(0) <= count(1);
END IF;
-- -- Check if SHR_EN is active
-- ELSIF (SHR_EN = '1') THEN
-- count(4) <= c_in;
-- count(3) <= count(4);
-- count(2) <= count(3);
-- count(1) <= count(2);
-- count(0) <= count(1);
-- c_out <= count(0);
END IF;
END PROCESS;
c_out <= count(0); -- c_out not separately registered
PH_reg_out <= count;
END behavioral;
and your code analyzes successfully.
The entity name is a good indication you haven't simulated your design.
Note the order of conditions implies loading has priority over shifting.
I'd suspect c_out should not be registered allowing shift register instances to be concatenated into a larger shift register using c_in and c_out. This means it's assignment should be outside the if statement containing the clock edge event, it can go next to the other output pin assignment.
This is a branch off of a separate question I asked. I am going to explain more in depth on what I am trying to do and what it is not liking. This is a school project and doesn't need to follow standards.
I am attempting to make the SIMON game. Right now, what I am trying to do is use a switch case for levels and each level is supposed to be faster (hence different frequency dividers). The first level is supposed to be the first frequency and a pattern of LEDs is supposed to light up and disappear. Before I put in a switch case, the first level was by itself (no second level stuff) and it lit up and disappeared like it should. I also used compare = 0 in order to compare in output to an input. (The user is supposed to flip up the switches in the light pattern they saw). This worked when the first level was by itself but now that it is in a switch case, it doesn't like compare. I'm not sure how to get around that in order to compare an output to an input.
The errors I am getting are similar to before:
Error (10821): HDL error at FP.vhd(75): can't infer register for "compare" because its behavior does not match any supported register model
Error (10821): HDL error at FP.vhd(75): can't infer register for "count[0]" because its behavior does not match any supported register model
Error (10821): HDL error at FP.vhd(75): can't infer register for "count[1]" because its behavior does not match any supported register model
Error (10821): HDL error at FP.vhd(75): can't infer register for "count[2]" because its behavior does not match any supported register model
Error (10822): HDL error at FP.vhd(80): couldn't implement registers for assignments on this clock edge
Error (10822): HDL error at FP.vhd(102): couldn't implement registers for assignments on this clock edge
Error (12153): Can't elaborate top-level user hierarchy
I also understand that it doesn't like the rising_edge(toggle) but I need that in order to make the LED pattern light up and disappear.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity FP is
port(
clk, reset : in std_logic;
QF : out std_logic_vector (3 downto 0);
checkbtn : in std_logic;
Switch : in std_logic_vector(3 downto 0);
sel : in std_logic_vector (1 downto 0);
score : out std_logic_vector (6 downto 0)
);
end FP;
architecture behavior of FP is
signal time_count: integer:=0;
signal toggle : std_logic;
signal toggle1 : std_logic;
signal count : std_logic_vector (2 downto 0);
signal seg : std_logic_vector (3 downto 0);
signal compare : integer range 0 to 1:=0;
type STATE_TYPE is (level1, level2);
signal level : STATE_TYPE;
--signal input : std_logic_vector (3 downto 0);
--signal sev : std_logic_vector (6 downto 0);
begin
process (clk, reset, sel)
begin
if (reset = '0') then
time_count <= 0;
toggle <= '0';
elsif rising_edge (clk) then
case sel is
when "00" =>
if (time_count = 1249999) then
toggle <= not toggle;
time_count <= 0;
else
time_count <= time_count+1;
end if;
when "01" =>
if (time_count = 2499999) then
toggle1 <= not toggle1;
time_count <= 0;
else
time_count <= time_count+1;
end if;
when "10" =>
if (time_count = 4999999) then
toggle <= not toggle;
time_count <= 0;
else
time_count <= time_count+1;
end if;
when "11" =>
if (time_count = 12499999) then
toggle <= not toggle;
time_count <= 0;
else
time_count <= time_count+1;
end if;
end case;
end if;
end process;
Process (toggle, compare, switch)
begin
case level is
when level1 =>
if sel = "00" then
count <= "001";
seg <= "1000";
elsif (rising_edge (toggle)) then
count <= "001";
compare <= 0;
if (count = "001") then
count <= "000";
else
count <= "000";
end if;
end if;
if (switch = "1000") and (compare = 0) and (checkbtn <= '0') then
score <= "1111001";
level <= level2;
else
score <= "1000000";
level <= level1;
end if;
when level2 =>
if sel = "01" then
count <= "010";
seg <= "0100";
elsif (rising_edge (toggle1)) then
count <= "010";
compare <= 1;
if (count = "010") then
count <= "000";
else
count <= "000";
end if;
end if;
if (switch = "0100") and (compare = 1) and (checkbtn <= '0') then
score <= "0100100";
else
score <= "1000000";
level <= level1;
end if;
end case;
case count is
when "000"=>seg<="0000";
when "001"=>seg<="1000";
when "010"=>seg<="0100";
when "011"=>seg<="0110";
when "100"=>seg<="0011";
when others=>seg<="0000";
end case;
end process;
QF <= seg;
end behavior;
Thanks again in advance!
Well... it is hard to tell what is wrong, because this state machine is written in wrong way. You should look for references about proper modeling of FSM in VHDL. One good example is here.
If you use Quartus, you could also look for Altera's description on how to model FSM specifically for their compiler.
I will now give you just two advices. First is that you shouldn't (or mabye even you can't) use is two
if rising_edge (clk)
checks in one process. If your process is supposed to be sensitive on clock edge, write it once at the beginning.
Second thing is that if you want to model FSM with one process with synchronous reset, then put just clk on sensitivity list.
EDIT after question and code edit:
Ok, much better now. But another few things:
Your FSM is still not like it should. Look again at the example in the source I gave you above and edit it to be like there, or make it one process FSM like in example in this link.
Intends! Very important. I couldn't spot some of obvious errors, before I made proper intendation in your code. This leads me to...
Look at the places, there you assign values to count, in particular the if statements. No mater what, you assign the same value of "000".
Similar story with another signal - seg. You assign to it some value in the process, and then at the end of this process there is case statement in which you assign to it some other value, making this previous assignments irrelevant.
Use rising_edge only once in the process, only to clock, and only at the very beginning of the process, or in the way you did in the first process, that has asynchronous reset. In second process you did all this three things.
In sequential process with rising_edge, like the first one, you don't have to put to sensitivity list anything more than clock, and reset if it is asynchronous, like in your case.
Sensitivity list in second process. It is parallel process, so you should put there signals, that you check in a process, and can change outside of it. It is not the case for compare. But there should be signals: level, sel and toggle1.
As I'm still not sure what are you trying to achieve, I will not tell you what exactly to do. Fix your code according to points above, then maybe it will just work.
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'm trying to do a VHDL code with the objective to make a 8 bit LFSR and show all the random states, and after one cycle (when the last state be the same seed value) it stop. But I'm have a problems, keep saying: "loop must terminate within 10,000 iterations". I'm using Quartus II-Altera.
Code:
entity lfsr_8bit is
--generic ( n : integer := 2**8 );
port (
clk : in bit;
rst : in bit;
lfsr : out bit_vector(7 downto 0)
);
end lfsr_8bit;
architecture behaviour of lfsr_8bit is
--signal i : integer := 0;
--signal seed : bit_vector(7 downto 0) := "10000000";
signal rand : bit_vector(7 downto 0);
begin
ciclo : process (clk,rst)
begin
loop
if (rst='0') then
rand <= "10000000";
elsif (clk'event and clk='1') then
rand(0) <= rand(6) xor rand(7);
rand(7 downto 1) <= rand(6 downto 0);
end if;
-- wait until rand = "10000000" for 100 ns;
exit when rand = "10000000";
-- case rand is
-- when "10000000" => EXIT;
-- when others => NULL;
-- end case;
-- i <= i +1;
end loop;
lfsr <= rand(7 downto 0);
end process ciclo;
end behaviour;
Thank you for all help.
Get rid of that loop, that loop does not work the way you think it does! Stop thinking like a software designer and think like a hardware designer. Loops in hardware are used to replicate logic. So that loop of yours is literally trying to generate 10,000 LFSRs!
I don't believe that you need to be using that loop there at all. If you remove it your LFSR should work as intended. You may need to add a control signal to enable/disable the LFSR, but definitely do not use a loop.
Here's some example code demonstrating this. Change the default value of rand to something else or the LFSR will never run! It will immediately set the lfsr_done signal.
ciclo : process (clk,rst)
begin
if (rst='0') then
rand <= "10000000"; -- SET THIS TO SOMETHING DIFFERENT
lfsr_done <= '0';
elsif (clk'event and clk='1') then
if rand = "10000000" then
lfsr_done <= '1';
end if;
if lfsr_done = '0' then
rand(0) <= rand(6) xor rand(7);
rand(7 downto 1) <= rand(6 downto 0);
end if;
end if;
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;