vhdl loop must terminate within 10,000 iteration error despite having a count to 1000 - while-loop

My task is to create a GCD calculator using a state machine in VHDL. Part of the task description says to use a while loop while(tempA /= tempB). When I used this loop I get following compilation error:
Error (10536): VHDL Loop Statement error at GCD_FSM.vhd(64): loop must terminate within 10,000 iterations
After doing some research online, I tried to fix this by implementing a count variable: loop_count, which increments on each iteration upto 10,000. Initially I still got the same error so tried reducing the max count value to only 1,000, which is the current set up in my code below.
For some reason that I cant understand I still get the same error, does anyone know why this is or have a solution? I am using Quartus II 13.1 as that is the latest edition with Cyclone III which is what we use at uni.
-- output function
process(current_state)
variable loop_count : integer range 0 to 10000 := 0;
begin
if current_state = STATE_load then
tempA <= unsigned(A);
tempB <= unsigned(B);
elsif current_state = STATE_calculate then
while (tempA /= tempB and loop_count < 1000) loop
if tempA < tempB then
tempB <= tempA - tempB;
else
tempA <= tempA - tempB;
end if;
loop_count := loop_count + 1;
end loop;
elsif current_state = STATE_done then
GCD <= std_logic_vector(tempA);
DONE <= '1';
end if;
end process;
Updating to add the full code for context below:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--use ieee.std_logic_unsigned.all;
entity GCD_FSM is
port(
A, B : in std_logic_vector(15 downto 0);
CLK, RESET, START : in std_logic;
GCD : out std_logic_vector(15 downto 0);
DONE : inout std_logic
);
end entity GCD_FSM;
architecture moore_machine of GCD_FSM is
type STATE is (
STATE_idle, STATE_load,
STATE_calculate, STATE_done
);
signal current_state, next_state : STATE;
signal tempA, tempB : unsigned(15 downto 0) := (others => '0');
begin
-- next state fuction
process(A, B, current_state)
begin
case current_state is
when STATE_idle =>
if START = '1' then
if (unsigned(A) /= 0) and (unsigned(B) /= 0) then
next_state <= STATE_load;
end if;
end if;
when STATE_load =>
next_state <= STATE_calculate;
when STATE_calculate =>
if tempA = tempB then
next_state <= STATE_done;
end if;
when STATE_done =>
next_state <= STATE_idle;
end case;
end process;
-- state register
process(CLK, RESET)
begin
if RESET = '0' then
current_state <= STATE_idle;
elsif rising_edge(CLK) then
current_state <= next_state;
end if;
end process;
-- output function
process(current_state)
variable loop_count : integer range 0 to 10000 := 0;
begin
if current_state = STATE_load then
tempA <= unsigned(A);
tempB <= unsigned(B);
elsif current_state = STATE_calculate then
while (tempA /= tempB and loop_count < 1000) loop
if tempA < tempB then
tempB <= tempA - tempB;
else
tempA <= tempA - tempB;
end if;
loop_count := loop_count + 1;
end loop;
elsif current_state = STATE_done then
GCD <= std_logic_vector(tempA);
DONE <= '1';
end if;
end process;
end architecture moore_machine;

Related

ORA-06502: PL/SQL: numeric or value error: character string buffer too small only three numbers

create or replace FUNCTION "FNC_CALCULATE_MOD11" (P_VALOR IN NUMBER)
return number is
Result number;
begin
DECLARE
-- LOCAL VARIABLES HERE
V_PROCESSO VARCHAR2(30);
V_PESO NUMBER := 2;
V_SOMA NUMBER := 0;
V_RESTO NUMBER := 0;
BEGIN
V_PROCESSO := TO_CHAR(P_VALOR);
WHILE LENGTH(V_PROCESSO) < 6 --Popular com zeros no inicio até 6
LOOP
V_PROCESSO := '0'||V_PROCESSO;
END LOOP;
--accuses error on this line
FOR I IN REVERSE 1 .. LENGTH(V_PROCESSO)
LOOP
V_SOMA := TO_CHAR (V_SOMA) + TO_NUMBER(SUBSTR(V_PROCESSO,i,1))*V_PESO;
IF V_PESO = 9 THEN --repetir peso se for necessario
V_PESO := 2;
ELSE
V_PESO := V_PESO + 1;
END IF;
END LOOP;
V_RESTO := MOD(V_SOMA, 11);
Result := 11 - V_RESTO;
IF ((Result = 0) OR (Result = 1) OR (Result >= 10)) THEN
Result := 1;
END IF;
END;
return(Result);
end FNC_CALCULATE_MOD11;
Try to change V_PROCESSO to a bigger size, for example V_PROCESSO VARCHAR2(300);

PL/SQL exception not reached, function doesn't return

I have a PL/SQL function and it doesn't seem to reach an exception when I encounter no_data_found. I have looked through and tried to add my select statement into its own begin block but I alway get syntax errors. Where do I need to put the exception ? Thank you
create or replace FUNCTION is_artikl_eligible_for_zamjena (
--input vars
inSifraArtikla IN A_ZAMJENA_ARTIKLI.SIFRA_ARTIKLA%type,
inDatumPocetak IN VARCHAR2,
inSkladiste IN A_ZAMJENA.SKL%type,
inProdavaonice IN A_ZAMJENA.POPIS_PROD%type
)
RETURN NUMBER
is
existingSifraArtikla A_ZAMJENA_ARTIKLI.SIFRA_ARTIKLA%type;
existingBrojZamjene A_ZAMJENA.BROJ_ZAMJENE%type;
existingDatumKraj A_ZAMJENA.DATUM_KRAJ%type;
existingSkladiste A_ZAMJENA.SKL%type;
existingProdavaonice A_ZAMJENA.POPIS_PROD%type;
BEGIN
dbms_output.enable();
--check if there is sifra_artikla in a_zamjena_artikli where a_zamjena.datumKraj != null or a_zamjena.datumKraj > sysdate
for i IN (
SELECT azam.BROJ_ZAMJENE, azam.DATUM_KRAJ, azam.SKL, azam.POPIS_PROD, azamAr.SIFRA_ARTIKLA
FROM A_ZAMJENA azam JOIN A_ZAMJENA_ARTIKLI azamAr
ON azam.BROJ_ZAMJENE = azamAr.BROJ_ZAMJENE
WHERE azamAr.SIFRA_ARTIKLA = inSifraArtikla
)
LOOP
existingBrojZamjene :=i.BROJ_ZAMJENE;
--existingDatumKraj := TO_CHAR(COALESCE(i.DATUM_KRAJ,'21-01-25 00:00'));
existingDatumKraj := i.DATUM_KRAJ;
existingSkladiste := COALESCE(i.SKL, '0');
existingProdavaonice := COALESCE(i.POPIS_PROD, 0);
existingSifraArtikla := i.SIFRA_ARTIKLA;
if existingDatumKraj IS NOT NULL AND existingDatumKraj < (sysdate -1) then --level 0
dbms_output.put_line('Datum kraj postojeće zamjene nije null ali je završio');
return 1;
else
if (existingDatumKraj IS NULL) OR (existingDatumKraj > sysdate) then --level 1
dbms_output.put_line('Zamjene imaju preklapajuće datume, provjeravam da li su na istim skladištima ili prodavaonicama');
if existingSkladiste != inSkladiste OR existingProdavaonice != inProdavaonice then -- level 2
dbms_output.put_line('Zamjene imaju preklapajuće datume ali nisu na istim skladištima ili prodavaonicama');
return 1;
else -- level 2
return 0;
end if; --level 2
else --else za datum kraj, level 1
dbms_output.put_line('Zamjene nemaju preklapajuće datume');
return 1;
end if; --level 1
end if; --level 0
END LOOP;
EXCEPTION WHEN NO_DATA_FOUND THEN
dbms_output.put_line('nema retka');
RETURN 1;
END;
Untested, but I would probably use a local variable to check whether my cursor loop found any rows, and check that at the end. (It could be a Boolean or a counter or something else. I've used a counter below.)
create or replace function is_artikl_eligible_for_zamjena
( insifraartikla in a_zamjena_artikli.sifra_artikla%type
, indatumpocetak in varchar2
, inskladiste in a_zamjena.skl%type
, inprodavaonice in a_zamjena.popis_prod%type )
return number
is
rows_found pls_integer := 0;
begin
dbms_output.enable();
-- check if there is sifra_artikla in a_zamjena_artikli where a_zamjena.datumKraj != null or a_zamjena.datumKraj > sysdate
for i in (
select azam.broj_zamjene
, azam.datum_kraj
, coalesce(azam.skl,'0') as skl
, coalesce(azam.popis_prod,0) as popis_prod
, azamar.sifra_artikla
from a_zamjena azam
join a_zamjena_artikli azamar
on azamar.broj_zamjene = azam.broj_zamjene
where azamar.sifra_artikla = insifraartikla
)
loop
rows_found := rows_found +1;
if i.datum_kraj < sysdate - 1 then
--level 0
dbms_output.put_line('Datum kraj postojeće zamjene nije null ali je završio');
return 1;
else
if i.datum_kraj is null or i.datum_kraj > sysdate then
--level 1
dbms_output.put_line('Zamjene imaju preklapajuće datume, provjeravam da li su na istim skladištima ili prodavaonicama');
if i.skl != inskladiste or i.popis_prod != inprodavaonice then
-- level 2
dbms_output.put_line('Zamjene imaju preklapajuće datume ali nisu na istim skladištima ili prodavaonicama');
return 1;
else
-- level 2
return 0;
end if; --level 2
else
--else za datum kraj, level 1
dbms_output.put_line('Zamjene nemaju preklapajuće datume');
return 1;
end if; --level 1
end if; --level 0
end loop;
if rows_found = 0 then
raise no_data_found;
end;
exception
when no_data_found then
dbms_output.put_line('nema retka');
return 1;
end;
I'm not sure raising a no_data_found exception is a particularly good approach here, though. In fact I'm not keen on a return inside a loop either. Maybe the problem goes away if you just assign the value you want to return to a local variable during the loop, and check it at the end, handling the case where it has no value.
With a local variable and a single return point instead of manipulating exception handlers, it would look something like this:
create or replace function is_artikl_eligible_for_zamjena
( insifraartikla in a_zamjena_artikli.sifra_artikla%type
, indatumpocetak in varchar2
, inskladiste in a_zamjena.skl%type
, inprodavaonice in a_zamjena.popis_prod%type )
return number
is
l_result number;
begin
dbms_output.enable();
-- check if there is sifra_artikla in a_zamjena_artikli where a_zamjena.datumKraj != null or a_zamjena.datumKraj > sysdate
for i in (
select azam.broj_zamjene
, azam.datum_kraj
, coalesce(azam.skl,'0') as skl
, coalesce(azam.popis_prod,0) as popis_prod
, azamar.sifra_artikla
from a_zamjena azam
join a_zamjena_artikli azamar
on azam.broj_zamjene = azamar.broj_zamjene
where azamar.sifra_artikla = insifraartikla
)
loop
if i.datum_kraj < sysdate - 1 then
--level 0
dbms_output.put_line('Datum kraj postojeće zamjene nije null ali je završio');
l_result := 1;
else
if i.datum_kraj is null or i.datum_kraj > sysdate then
--level 1
dbms_output.put_line('Zamjene imaju preklapajuće datume, provjeravam da li su na istim skladištima ili prodavaonicama');
if i.skl != inskladiste or i.popis_prod != inprodavaonice then
-- level 2
dbms_output.put_line('Zamjene imaju preklapajuće datume ali nisu na istim skladištima ili prodavaonicama');
l_result := 1;
else
-- level 2
l_result := 0;
end if; --level 2
else
--else za datum kraj, level 1
dbms_output.put_line('Zamjene nemaju preklapajuće datume');
l_result := 1;
end if; --level 1
end if; --level 0
end loop;
if l_result is then
dbms_output.put_line('nema retka');
l_result := 1;
end;
return l_result;
end;
I'm not sure what the dbms_output.put_line calls are doing, but that's another question.
You simply cannot raise a NO_DATA_FOUND exception using a for loop. You can do using a goto statement for insatance. See below example.
DECLARE
v_attr char(88);
CURSOR SELECT_USERS IS
SELECT id
FROM USER_TABLE
WHERE USERTYPE = 'X';
BEGIN
FOR user_rec IN SELECT_USERS
LOOP
BEGIN
SELECT attr
INTO v_attr
FROM ATTRIBUTE_TABLE
WHERE user_id = user_rec.id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- user does not have attribute, continue loop to next record.
goto end_loop; ---Adding a label
END;
<<end_loop>> --Label
null;
END LOOP;
END;

FT600 Interfacing with FPGA

I am interfacing with a FT600 16-bit chip for USB3.0 communication. The computer will communicate through the FT600 to the FPGA and vice versa. I have created an FSM to assert appropriate signals and write Data to memory.
Problem: I assume the problem is with the FPGA code and not the hardware but it looks like only every other byte is correctly recorded into memory.
The timing diagram I am referring to is on page 16: http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT600Q-FT601Q%20IC%20Datasheet.pdf
This is my FSM code:
parameter [4:0] S1 = 5'd0, //Neutral state
S2 = 5'd1, //Data transfer from FPGA to Computer
SA_1 = 5'd8,
SA_2 = 5'd9,
S3 = 5'd2, //Data transfer from Computer to FPGA
S4 = 5'd3,
S5 = 5'd4,
S6 = 5'd5,
S7 = 5'd6,
S8 = 5'd7;
reg [4:0] state=0;
reg [4:0] nstate=0;
//wire [15:0] wdata;
wire [15:0] rdata;
//Counter c1 (wdata, Cclock);
assign rdata = (state == S5) ? DATA_I : rdata; //Holds the recieved data on DATA
assign DATA_O = (state == S7) ? rdata : 16'bz; //rdata : 16'bz; //{8'h41,8'h41} : 16'bz; //Sends the transmitted data on DATA
reg OE_N_reg = 1;//Confirmation signal when Computer writes data to FPGA
reg RD_N_reg = 1;//Confirmation signal when Computer writes data to FPGA
reg WR_N_reg = 1;//Confirmation signal when FPGA writes data to Computer
assign OE_N = OE_N_reg;
assign RD_N = RD_N_reg;
assign WR_N = WR_N_reg;
//ByteEnable configuration based on state
assign BE[0] = (state == S3) ? 1'bz : 1;
assign BE[1] = (state == S3) ? 1'bz : 1;
//Debugging outputs
//assign GPIO_O[7:3] = 0;
//assign GPIO_O[2] = OE_N;
//assign GPIO_O[3] = RD_N;
//assign GPIO_O[4] = WR_N;
//assign GPIO_O[7:5] = DATA[2:0];
//State Logic
always#(*)
begin
case(state)
S1:if(TXE_N == 0)
begin
nstate <= S2;
end
else
begin
if(RXF_N == 0)
begin
nstate <= SA_1;
end
else
begin
nstate <= S1;
end
end
S2:if(TXE_N == 0)
begin
nstate <= SA_2;
end
else
begin
nstate <= S1;
end
SA_1: if(RXF_N == 0)
begin
nstate <= S3;
end
else
begin
nstate <= S1;
end
S3:if(RXF_N == 0)
begin
nstate <= S4;
end
else
begin
nstate <= S1;
end
S4:if(RXF_N == 0)
begin
nstate <= S5;
end
else
begin
nstate <= S1;
end
S5:if(RXF_N == 0)
begin
nstate <= S5;
end
else
begin
nstate <= S6;
end
S6: nstate <= S1;
SA_2: if(TXE_N == 0)
begin
nstate <= S7;
end
else
begin
nstate <= S1;
end
S7: if(TXE_N == 0)
begin
nstate <= S7;
end
else
begin
nstate <= S8;
end
S8: nstate <= S1;
default: nstate <= S1;
endcase
end
//Output Assignment
always#(negedge S_AXI_ACLK)
begin
case(state)
S1: begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 1;
DATA_T <= 1;
end
S2: begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 1;
DATA_T <= 1;
end
SA_1: begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 1;
DATA_T <= 1;
end
S3: begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 1;
DATA_T <= 1;
end
S4: begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 0;
DATA_T <= 1;
end
S5: begin
RD_N_reg <= 0;
WR_N_reg <= 1;
OE_N_reg <= 0;
DATA_T <= 1;
end
S6: begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 1;
DATA_T <= 1;
end
SA_2: begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 1;
DATA_T <= 1;
end
S7: begin
RD_N_reg <= 1;
WR_N_reg <= 0;
OE_N_reg <= 1;
DATA_T <= 0;
end
S8: begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 1;
DATA_T <= 1;
end
default: begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 1;
DATA_T <= 1;
end
endcase
end
//Update states
always#(negedge S_AXI_ACLK)
begin
state <= nstate;
end
//RECORD rdata INTO MEM:
always #(negedge Bus2IP_Clk)
begin
if((RD_N == 0)) begin
s <= s+(11'd15);
ram[0][0][s] <= rdata[15:0];
end
read_address <= mem_address; //AXI4 stuff
end
Any ideas/suggestions? If there already exists simple code for the FT600 as an example I would appreciate a link.
Here's a tip: replace the huge case statement with this. It does exactly the same thing, but takes up far less space and is easier to understand:
always#(negedge S_AXI_ACLK)
begin
RD_N_reg <= 1;
WR_N_reg <= 1;
OE_N_reg <= 1;
DATA_T <= 1;
case(state)
S4: OE_N_reg <= 0;
S5: begin
RD_N_reg <= 0;
OE_N_reg <= 0;
end
S7: begin
WR_N_reg <= 0;
DATA_T <= 0;
end
endcase
end
The four assignments at the top of the block are called default assignments and are often useful to make code more compact and easier to understand.

PLSQL Printing prime numbers

I want to print prime numbers between 1 to 50. But I don't understand what I am doing wrong in my code. After BEGIN, SQLDeveloper says I had an error because it expected another sign and not = .
SET SERVEROUTPUT ON
DECLARE
i NUMBER;
counter NUMBER;
n NUMBER;
k NUMBER;
BEGIN
i := 2;
counter := 0;
n := 50;
k := n/2;
FOR i IN 1..k LOOP
IF (n%i := 0 ) THEN
counter := 1;
END IF;
IF (counter := 0) THEN
DBMS_OUTPUT.PUT_LINE(n||' is prime number');
END IF;
END LOOP;
END;
SET SERVEROUTPUT ON
DECLARE
i NUMBER;
counter NUMBER;
n NUMBER;
k NUMBER;
BEGIN
i := 2;
counter := 0;
n := 50;
k := floor(n/2);
FOR i IN 1..k LOOP
IF (mod(n, i) = 0 ) THEN
counter := 1;
END IF;
IF (counter = 0) THEN
DBMS_OUTPUT.PUT_LINE(n||' is prime number');
END IF;
END LOOP;
END;
k := n/2; -- added FLOOR (k is NUMBER, by default it's NUMBER(38, max_scale))
IF (n%i := 0 ) THEN -> IF (mod(n, i) = 0 ) THEN
Oracle has MOD function for remainder + to compare you need to use =,
:= is for assignment.
DECLARE
counter NUMBER;
k NUMBER;
BEGIN
FOR n IN 1..50 LOOP
counter := 0;
k := floor(n/2);
FOR i IN 2..k LOOP
IF (mod(n, i) = 0 ) THEN
counter := 1;
END IF;
END LOOP;
IF (counter = 0) THEN
DBMS_OUTPUT.PUT_LINE(n||' is prime number');
END IF;
END LOOP;
END;
In your IF clause you are assigning the value instead of comparison. You are using := operator, where you shd be using =
It shud be like (IF counter = 0) then
......
Also I dont think n%i would work, you could do IF (trunc(n) = n) then ... or IF (mod (n,i) =0) then ...
--this function is check prime number.
create or replace function prime_a(x number) return
varchar2 is
n integer;
ans varchar2(50);
begin
n:=(x/2);
for i in 2..n loop
if mod(x,i)=0
then ans:='not a prime';
exit;
else ans:='prime';
end if;
end loop;
return ans;
end;
/
step-1:
create table tob(prime number);
step-2:
create or replace procedure ro(m number,n number)
is
a integer;
co Boolean;
begin
for j in m..n loop
co:=false;
co:=(j=1 );
a:=(j/2);
for i in 2..a loop
co:=(mod(j,i)=0);
exit when co;
end loop;
if(not co) then
insert into tob values(J);
end if;
end loop;
commit;
end;
/
step-3:
exec ro(1,50);
step-4: check:-
select * from tob;
You should create or replace in your source code:
function prime_a(x number) return
varchar2 is
n integer;
ans varchar2(50);
begin
n:=(x/2);
for i in 2..n loop
if mod(x,i)=0
then ans:='not a prime';
exit;
else ans:='prime';
end if;
end loop;
return ans;
end;
/
Why don't you just check for previous prime divisibility?
create table prime (primeno bigint)
declare #counter bigint
set #counter = 2
while #counter < 1000000
begin
if not exists(select top 1 primeno from prime where #counter % primeno = 0)
insert into prime select #counter
set #counter = #counter + 1
end
select * from prime order by 1
You could certainly cap the numbers you are checking against in the where condition to reduce your overheads further.
declare
i number;
j number;
k number:=0;
begin
for i in 1..50
loop
for j in 2..i-1
loop
if mod(i,j)=0 then
k:=1;
exit;
end if;
end loop;
if k=0 then
dbms_output.put_line(i);
end if;
k:=0;
end loop;
end;
/
create or replace function prime_a(x number) return varchar2 is
n integer;
ans varchar2(50);
begin
n:=(x/2);
for i in 2..n loop
if mod(x,i)=0 then
ans:='not a prime';
exit;
else
ans:='prime';
end if;
end loop;
return ans;
end;
/

Cause of gated clock

I have this code in VHDL. When I try to compile it - it says "Gated clock net clock_en is sourced by a combinatorial pin." Has anyone an idea how to get rid of this warning?
I have searched all over the internet and cant find the solution. It seems that gated clock is sometimes even useful, but when designing HW it is a warning.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
entity ledc8x8 is
port(
SMCLK: in std_logic;
RESET: in std_logic;
ROW: out std_logic_vector(0 to 7);
LED: out std_logic_vector(0 to 7)
);
end ledc8x8;
architecture behavioral of ledc8x8 is
signal count: std_logic_vector(7 downto 0) := (others => '0'); -- hlavni citac
signal row_count: std_logic_vector(7 downto 0) := "10000000"; -- prepinac radku
signal clock_en: std_logic; -- CE
signal output_logic: std_logic_vector(7 downto 0); -- "vystup"
begin
process(count, SMCLK, RESET, clock_en)
begin
if RESET = '1' then
count <= (others => '0');
elsif SMCLK = '1' and SMCLK'event then
count <= count + 1;
end if;
if count="11111110" then
clock_en <= '1'; else
clock_en <= '0';
end if ;
end process;
process(clock_en, RESET)
begin
if RESET = '1' then
row_count <= "10000000";
elsif clock_en = '1' and clock_en'event then
row_count <= row_count(0) & row_count(7 downto 1);
end if;
end process;
process(row_count)
begin
case row_count is
when "00000001" => output_logic <= "11110110";
-- more switch options
end case;
end process;
ROW <= row_count;
LED <= output_logic;
end behavioral;
Your code has several problems.
As you discovered in your answer, you were using a clock enable as a clock. I would recommend that you write it this way, though:
process(RESET, SMCLK)
begin
if RESET = '1' then
row_count <= "10000000";
elsif SMCLK = '1' and SMCLK'event then
if clock_en = '1' then
row_count <= row_count(0) & row_count(7 downto 1);
end if;
end if;
end process;
It may work the other way (maybe), but it's not conventional to put the enable check on the same line as the rising edge check. Note also that this means you don't need clock_en in your sensitivity list.
Your other clocked process should be rewritten as well. Assuming you want the assignment to clock_en to be combinational, you should really put it in a separate process:
process(RESET, SMCLK)
begin
if RESET = '1' then
count <= (others => '0');
elsif SMCLK = '1' and SMCLK'event then
count <= count + 1;
end if;
end process;
process (count)
begin
if count="11111110" then
clock_en <= '1';
else
clock_en <= '0';
end if ;
end process;
You could also write the second process here as a one-line concurrent statement:
clock_en <= '1' when count = "11111110" else '0';
Combining independent clocked and unclocked code in the same process is not a recommended coding style for various reasons.
The line with clock_en'event - asking for rising edge did the problem. Replaced to ask for rising edge of SMCLK signal.
process(RESET, SMCLK)
begin
if RESET = '1' then
row_count <= "10000000";
elsif clock_en = '1' and SMCLK = '1' and SMCLK'event then
row_count <= row_count(0) & row_count(7 downto 1);
end if;
end if;
end process;