Hi, it's me again!
I have modified my code and I use signals now, and I think it is better like that (even if I don't use a shift register):
LIBRARY ieee;
USE IEEE.std_logic_1164.all;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE work.AD9854_DDFS;
ENTITY Serial_Interface_V3 IS GENERIC(Nb_ddfs:AD9854_DDFS.DEVICE_ID:=4);
PORT (clkin: IN STD_LOGIC ; -- external clock
reg_addr: IN AD9854_DDFS.SERIAL_ADDRESS;
reg_data : IN AD9854_DDFS.SERIAL_DATA;
load: IN STD_LOGIC;-- WHEN HIGH, reg_to_program HAS A NEW VALUE
mask: IN STD_LOGIC_VECTOR (1 TO Nb_ddfs);
busy: OUT STD_LOGIC; -- WHEN HIGH THE ENTITY IS BUSY TO TRANSMIT AND CAN NOT MANAGE ANY OTHER load
io_reset:OUT STD_LOGIC_VECTOR (1 TO Nb_ddfs):=(OTHERS=>'1'); -- VECTOR TO ALL io_reset OUTPUT
csbOUT: OUT STD_LOGIC_VECTOR (1 TO Nb_ddfs); -- VECTOR TO ALL csbOUT OUTPUT
sdclk:OUT STD_LOGIC_VECTOR (1 TO Nb_ddfs);-- VECTOR TO ALL sdclk OUTPUT
sdio:OUT STD_LOGIC; -- POSSIBLY SHARED OUTPUT TO DDFS
sdo: OUT STD_LOGIC-- POSSIBLY SHARED OUTPUT TO DDFS to earn pins, sdo pins on ddfs could be stuck to ground on pcb
);
------------------------------------------------------------------------------
END Serial_Interface_V3;
-- Architecture Body
ARCHITECTURE Serial_Interface_V3_Architecture OF Serial_Interface_V3 IS
SIGNAL transmiting: STD_LOGIC:='0';
SIGNAL active_lines : STD_LOGIC_VECTOR(1 TO Nb_ddfs);
SIGNAL local_mask: STD_LOGIC_VECTOR(1 TO Nb_ddfs);
SIGNAL bit_number: NATURAL RANGE 0 TO 56:=0;
SIGNAL frame_size: NATURAL RANGE 0 TO 56;
SIGNAL frame : STD_LOGIC_VECTOR(0 TO 55);
BEGIN
busy<=transmiting;
active_lines<=(1 TO Nb_ddfs=>transmiting) AND local_mask;
csbOUT<=NOT active_lines;
io_reset<=NOT active_lines;
sdclk<= active_lines AND (1 TO Nb_ddfs =>NOT clkin);
sdo<='0';
PROCESS (clkin) IS BEGIN
IF clkin='1' THEN
IF transmiting='0' AND load='1' THEN
local_mask<=mask;
frame<="0000" & reg_addr & reg_data;
frame_size<=8*(1+AD9854_DDFS.size_of_register(reg_addr));
bit_number<=1;
sdio<=frame(0);
transmiting<='1';
ELSIF transmiting='1' AND bit_number<frame_size THEN
sdio<=frame(bit_number);
bit_number<=bit_number+1;
ELSE
local_mask<=(OTHERS=>'0');
frame<=(OTHERS=>'0');
frame_size<=0;
bit_number<=1;
sdio<='0';
transmiting<='0';
END IF;
END IF;
END PROCESS;
END Serial_Interface_V3_Architecture;
I have tested this entity with several combination of input and it is working properly, counter counts in the right order and everything. But it is the case when I test it without my others blocks!
When I use this entity in my complete design, the counter can count in the right order or not (and then counter has a value greater than frame_size, the transmission stops before the end of the frame) .
As you said it previously:
--- Quote Start ---
It may be the case, that you are reading an internal counter value, that is using a different internal coding due to optimizations.
--- Quote End ---
The problem is that even if the internal coding is different,
the behaviour should not be affected, shouldn't it?
Because this entity has been tested separatly and is good now, I do not want to use a shift register which will only postpone this trouble (I have other counters in my design which have sometimes the same trouble).
Do you know if the behaviour is affected by the internal coding, if yes is there any mean to disable this optimization feature?
thanks for your time.
Denis