0

I've got a problem with a synthesis of that code. The error which is shown is "Signal blk_pointer 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 want to save communication messages between two devices. The part with falling_edge and rising_edge is to find a current part of message, and create a pointer to that part (msg_pointer, blk_pointer). Then I want to save the current value to a buffer.

It works when I delete the last part ( that with for loop).

process(com_delayed)
variable msg_pointer : INTEGER range 0 to 20:=0;    --pointing to a number of message block 
variable blk_pointer : INTEGER range 0 to 50:=0;    --pointing to a number of bit from the current block
variable buf_pointer : INTEGER range 0 to 13:=0;    --pointing to a number of bit in the output S14T7C7_TEMP buf
variable S14T7C7_TEMP : STD_LOGIC_VECTOR (13 downto 0):="00000000000000";
variable nzer : INTEGER range 0 to 9:=0;
variable njed : INTEGER range 0 to 9:=0;
variable copy : STD_LOGIC;

begin
    if falling_edge(com_delayed) then
        if com_level_time > 4500 then
            msg_pointer := 0;
            blk_pointer := 0;
            buf_pointer := 0;
        elsif ( com_level_time < 4500 ) and ( com_level_time > 630 ) then
            msg_pointer := 1;
            blk_pointer := 0;
            buf_pointer := 0; 
        elsif blk_pointer >= 9 then
            blk_pointer:=0; 
            if msg_pointer<6 then
                msg_pointer:=msg_pointer+1;
            end if;
        elsif com_level_time <= 80 then
            blk_pointer:=blk_pointer+1;
            njed:=1;
            copy:='1';
        elsif (com_level_time>80 and com_level_time<=142) then
            blk_pointer:=blk_pointer+2;
            njed:=2;
            copy:='1';
        elsif (com_level_time>142 and com_level_time<=200) then
            blk_pointer:=blk_pointer+3;
            njed:=3;
            copy:='1';
        elsif (com_level_time>200 and com_level_time<=274) then
            blk_pointer:=blk_pointer+4;
            njed:=4;
            copy:='1';
        elsif (com_level_time>274 and com_level_time<=336) then
            blk_pointer:=blk_pointer+5;
            njed:=5;
            copy:='1';
        elsif (com_level_time>336 and com_level_time<=396) then
            blk_pointer:=blk_pointer+6;
            njed:=6;
            copy:='1';
        elsif (com_level_time>396 and com_level_time<=460) then
            blk_pointer:=blk_pointer+7;
            njed:=7;
            copy:='1';
        elsif (com_level_time>460 and com_level_time<=526) then
            blk_pointer:=blk_pointer+8;
            njed:=8;
            copy:='1';
        elsif (com_level_time>526 and com_level_time<=630) then
            blk_pointer:=blk_pointer+9;
            njed:=9;
            copy:='1';
        end if;         
    end if;


    if rising_edge(com_delayed) then
        if com_level_time <= 80 then
            blk_pointer:=blk_pointer+1;
            nzer:=1;
            copy:='1';
        elsif (com_level_time>80 and com_level_time<=142) then
            blk_pointer:=blk_pointer+2;
            nzer:=2;
            copy:='1';
        elsif (com_level_time>142 and com_level_time<=200) then
            blk_pointer:=blk_pointer+3;
            nzer:=3;
            copy:='1';
        elsif (com_level_time>200 and com_level_time<=274) then
            blk_pointer:=blk_pointer+4;
            nzer:=4;
            copy:='1';
        elsif (com_level_time>274 and com_level_time<=336) then
            blk_pointer:=blk_pointer+5;
            nzer:=5;
            copy:='1';
        elsif (com_level_time>336 and com_level_time<=396) then
            blk_pointer:=blk_pointer+6;
            nzer:=6;
            copy:='1';
        elsif (com_level_time>396 and com_level_time<=460) then
            blk_pointer:=blk_pointer+7;
            nzer:=7;
            copy:='1';
        elsif (com_level_time>460 and com_level_time<=526) then
            blk_pointer:=blk_pointer+8;
            nzer:=8;
            copy:='1';
        elsif (com_level_time>526 and com_level_time<=630) then
            blk_pointer:=blk_pointer+9;
            nzer:=9;
            copy:='1';
        end if;
    end if;

    msg_pointer_ext:=msg_pointer;
    blk_pointer_ext:=blk_pointer;

    if copy='1' then        
        For it in 1 to 9 loop
            if nzer/=0 then
                message1(msg_pointer_ext)(blk_pointer_ext-nzer):='0';
                nzer:=nzer-1;
            end if;
        end loop;
    end if;
    copy:='0';
end process;

New two processes:

process(com_delayed)
variable msg_pointer : INTEGER range 0 to 20:=0;    --pointing to a number of message block 
variable blk_pointer : INTEGER range 0 to 50:=0;    --pointing to a number of bit from the current block
variable nzer : INTEGER range 0 to 9:=0;
variable njed : INTEGER range 0 to 9:=0;
variable copy : STD_LOGIC;

begin
    if rising_edge(com_delayed) then
        msg_pointer:=msg_pointer_ext;
        blk_pointer:=blk_pointer_ext;
        if com_level_time <= 80 then
            blk_pointer:=blk_pointer+1;
            nzer:=1;
            copy:='1';
        elsif (com_level_time>80 and com_level_time<=142) then
            blk_pointer:=blk_pointer+2;
            nzer:=2;
            copy:='1';
        elsif (com_level_time>142 and com_level_time<=200) then
            blk_pointer:=blk_pointer+3;
            nzer:=3;
            copy:='1';
        elsif (com_level_time>200 and com_level_time<=274) then
            blk_pointer:=blk_pointer+4;
            nzer:=4;
            copy:='1';
        elsif (com_level_time>274 and com_level_time<=336) then
            blk_pointer:=blk_pointer+5;
            nzer:=5;
            copy:='1';
        elsif (com_level_time>336 and com_level_time<=396) then
            blk_pointer:=blk_pointer+6;
            nzer:=6;
            copy:='1';
        elsif (com_level_time>396 and com_level_time<=460) then
            blk_pointer:=blk_pointer+7;
            nzer:=7;
            copy:='1';
        elsif (com_level_time>460 and com_level_time<=526) then
            blk_pointer:=blk_pointer+8;
            nzer:=8;
            copy:='1';
        elsif (com_level_time>526 and com_level_time<=630) then
            blk_pointer:=blk_pointer+9;
            nzer:=9;
            copy:='1';
        end if;

        if copy='1' then        
            For it in 1 to 9 loop
                if nzer/=0 then
                    message1(msg_pointer)(blk_pointer-nzer):='0';
                    nzer:=nzer-1;
                end if;
            end loop;
        end if;
        copy:='0';

        msg_pointer_ext:=msg_pointer;
        blk_pointer_ext:=blk_pointer;
    end if;

end process;


process(com_delayed)
variable msg_pointer : INTEGER range 0 to 20:=0;    --pointing to a number of message block 
variable blk_pointer : INTEGER range 0 to 50:=0;    --pointing to a number of bit from the current block
variable nzer : INTEGER range 0 to 9:=0;
variable njed : INTEGER range 0 to 9:=0;
variable copy : STD_LOGIC;

begin
    if falling_edge(com_delayed) then
        msg_pointer:=msg_pointer_ext;
        blk_pointer:=blk_pointer_ext;

        if com_level_time > 4500 then
            msg_pointer := 0;
            blk_pointer := 0;
        elsif ( com_level_time < 4500 ) and ( com_level_time > 630 ) then
            msg_pointer := 1;
            blk_pointer := 0;
        elsif blk_pointer >= 9 then
            blk_pointer:=0; 
            if msg_pointer<6 then
                msg_pointer:=msg_pointer+1;
            end if;
        elsif com_level_time <= 80 then
            blk_pointer:=blk_pointer+1;
            njed:=1;
            copy:='1';
        elsif (com_level_time>80 and com_level_time<=142) then
            blk_pointer:=blk_pointer+2;
            njed:=2;
            copy:='1';
        elsif (com_level_time>142 and com_level_time<=200) then
            blk_pointer:=blk_pointer+3;
            njed:=3;
            copy:='1';
        elsif (com_level_time>200 and com_level_time<=274) then
            blk_pointer:=blk_pointer+4;
            njed:=4;
            copy:='1';
        elsif (com_level_time>274 and com_level_time<=336) then
            blk_pointer:=blk_pointer+5;
            njed:=5;
            copy:='1';
        elsif (com_level_time>336 and com_level_time<=396) then
            blk_pointer:=blk_pointer+6;
            njed:=6;
            copy:='1';
        elsif (com_level_time>396 and com_level_time<=460) then
            blk_pointer:=blk_pointer+7;
            njed:=7;
            copy:='1';
        elsif (com_level_time>460 and com_level_time<=526) then
            blk_pointer:=blk_pointer+8;
            njed:=8;
            copy:='1';
        elsif (com_level_time>526 and com_level_time<=630) then
            blk_pointer:=blk_pointer+9;
            njed:=9;
            copy:='1';
        end if;

        if copy='1' then        
            For it in 1 to 9 loop
                if njed/=0 then
                    message1(msg_pointer)(blk_pointer-njed):='0';
                    njed:=njed-1;
                end if;
            end loop;
        end if;
        copy:='0';

        msg_pointer_ext:=msg_pointer;
        blk_pointer_ext:=blk_pointer;       
    end if;

end process;

Next error is : Multi-Source on Integers in concurrent assignment. (external pointers)

And new version without errors:

process(clk_com, com_ecu38)
    variable com_clear : STD_LOGIC:='0';
    variable tclt : INTEGER range 0 to 32000:=0;
begin
    if rising_edge(clk_com) and tclt /= 31999 then
        tclt := tclt +1;
    end if;

    if com_ecu38'event then
        com_level_time:=tclt;
        com_clear:='1';
    end if;

    if com_clear='1' then 
        tclt:=0;
        com_delayed<=com_ecu38;
    end if;

    com_clear:='0';

end process;



process(com_delayed)
begin
    if rising_edge(com_delayed) then
        if com_level_time>20 and com_level_time<=80 then
            nzer:=1;
        elsif (com_level_time>80 and com_level_time<=142) then
            nzer:=2;
        elsif (com_level_time>142 and com_level_time<=200) then
            nzer:=3;
        elsif (com_level_time>200 and com_level_time<=274) then
            nzer:=4;
        elsif (com_level_time>274 and com_level_time<=336) then
            nzer:=5;
        elsif (com_level_time>336 and com_level_time<=396) then
            nzer:=6;
        elsif (com_level_time>396 and com_level_time<=460) then
            nzer:=7;
        elsif (com_level_time>460 and com_level_time<=526) then
            nzer:=8;
        elsif (com_level_time>526 and com_level_time<=630) then
            nzer:=9;
        else
            nzer:=0;
        end if;
        copy0<=not(copy0);
    end if;
end process;


process(com_delayed)
begin
    if falling_edge(com_delayed) then
        if com_level_time > 4500 then
            njed:=12;
        elsif com_level_time > 630 and com_level_time <= 4500 then
            njed:=11;
        elsif com_level_time>20 and com_level_time<=80 then
            njed:=1;
        elsif (com_level_time>80 and com_level_time<=142) then
            njed:=2;
        elsif (com_level_time>142 and com_level_time<=200) then
            njed:=3;
        elsif (com_level_time>200 and com_level_time<=274) then
            njed:=4;
        elsif (com_level_time>274 and com_level_time<=336) then
            njed:=5;
        elsif (com_level_time>336 and com_level_time<=396) then
            njed:=6;
        elsif (com_level_time>396 and com_level_time<=460) then
            njed:=7;
        elsif (com_level_time>460 and com_level_time<=526) then
            njed:=8;
        elsif (com_level_time>526 and com_level_time<=630) then
            njed:=9;
        else
            njed:=0;
        end if;
        copy1<=not(copy1);
    end if;
end process;


process(copy1, copy0)
variable n                  : INTEGER range 0 to 9:=0;
variable bit_to_write   : STD_LOGIC;
variable inc_msg            : STD_LOGIC;
variable c1                 : STD_LOGIC;
variable c0                 : STD_LOGIC;
variable msg_pointer    : INTEGER range 0 to 20:=0; --pointing to a number of message block 
variable blk_pointer    : INTEGER range 0 to 50:=0; --pointing to a number of bit from the current block

begin       
    if copy1'event then 
        n:=njed;
        c1:='1';
    elsif copy0'event then
        n:=nzer;
        c0:='1';
    end if;

    msg_pointer:=msg_pointer_ext;
    blk_pointer:=blk_pointer_ext;

    if c1='1' then
        bit_to_write:='1';
    elsif c0='1' then
        bit_to_write:='0';
    end if;

    if n=12 then
        msg_pointer:=0;
        blk_pointer:=0;
        com_ch_out<=not(com_ch_out);
    elsif n=11 then
        msg_pointer:=1;
        blk_pointer:=0;
    else
        if blk_pointer + n <9 then
            blk_pointer:=blk_pointer+n;
        else
            n:=9-blk_pointer;
            inc_msg:='1';
            blk_pointer:=9;
        end if;
        For it in 1 to 9 loop
            if n/=0 then
                message1(msg_pointer)(blk_pointer-n):=bit_to_write;
                n:=n-1;
            end if;
        end loop;
    end if;

    if inc_msg='1' then
        if msg_pointer<5 then
            blk_pointer_ext:=0;
            msg_pointer_ext:=msg_pointer+1;
        end if;
    else
        msg_pointer_ext:=msg_pointer;
        blk_pointer_ext:=blk_pointer;
    end if;

    n:=0;
    inc_msg:='0';
    c1:='0';
    c0:='0';

end process;

process(com_ch_out)
begin
    if com_ch_out'event then
        if latch_outputs='0' then
            if stc_decide = '0' then
                S14T7C7(0)<=message1(1)(1);
                S14T7C7(1)<=message1(1)(2);
                S14T7C7(2)<=message1(1)(3);
                S14T7C7(3)<=message1(1)(4);
                S14T7C7(4)<=message1(1)(5);
                S14T7C7(5)<=message1(1)(6);
                S14T7C7(6)<=message1(1)(7);
                S14T7C7(7)<=message1(2)(1);
                S14T7C7(8)<=message1(2)(2);
                S14T7C7(9)<=message1(2)(3);
                S14T7C7(10)<=message1(2)(4);
                S14T7C7(11)<=message1(2)(5);
                S14T7C7(12)<=message1(2)(6);
                S14T7C7(13)<=message1(2)(7);
            else
                S14T7C7(0)<=message1(4)(1);
                S14T7C7(1)<=message1(4)(2);
                S14T7C7(2)<=message1(4)(3);
                S14T7C7(3)<=message1(4)(4);
                S14T7C7(4)<=message1(4)(5);
                S14T7C7(5)<=message1(4)(6);
                S14T7C7(6)<=message1(4)(7);
                S14T7C7(7)<=C7I(0);
                S14T7C7(8)<=C7I(1);
                S14T7C7(9)<=C7I(2);
                S14T7C7(10)<=C7I(3);
                S14T7C7(11)<=C7I(4);
                S14T7C7(12)<=C7I(5);
                S14T7C7(13)<=C7I(6);        
            end if;
        end if;
    end if;
end process;

strong text

Bob Son
  • 1
  • 1
  • That last loop is independent of either rising or falling `com_delayed` clock edge, thus not good synchronous design style. Your best option is to revise that aspect of it. You also have signals written on both clock edges; also not generally good. –  Dec 06 '14 at 21:48
  • Which ISE version and target platform do you use? Try to enable the new VHDL parser: XST Process Preferences -> Other XST Command Line Option = `-use_new_parser yes`. The new parser supports newer VHDL syntax and can translate more description forms to hardware. You can also try to use `elsif rising_edge(...)`or using `if com_delayed'event then` which is triggered on every clock edge. – Paebbels Dec 06 '14 at 21:53
  • DDR flip flops are only supported for input and output (IDDR, ODDR, ... -primitives). – Paebbels Dec 06 '14 at 22:00
  • @BrianDrummond - that last loop is really important, because it is for initializing the change in the buffer according to the value, that was read in rising_edge or falling_edge part. I also need to react on both edges because I want to copy a serial communication message to an std_logic_vector. – Bob Son Dec 07 '14 at 12:22
  • @Paebbels I have tried all the combinations with "'event", "elsif" , etc... :( – Bob Son Dec 07 '14 at 12:28
  • How you revise the design is up to you; the fact remains that you do need to revise both those aspects. I would start by separating the +ve edge and -ve edge operations into their own processes, and unsharing signals they both drive (such as "copy"). Yes they will have to become signals, as they are now inter-process. The good news is that you can easily verify the new design against the old. Simply instantiate both in the testbench and compare both sets of outputs, asserting any time they are differetn, and fix those. –  Dec 07 '14 at 12:28
  • @BrianDrummond I divided them into two processes, but I have to write to external shared variables , because one process has to know how far were the pointers pushed by the another process... The error is "Multi-source on Integers in Concurrent Assignment.". New code is mentioned in my opening post. – Bob Son Dec 07 '14 at 13:04
  • External variables will most likely not synthesise correctly. Start by visualising the hardware that you would generate, and write VHDL to implement that, using the design patterns described in any good synthesis guide, instead of treating this task as a purely software problem. There's a good guide available from ISE's help menu. –  Dec 07 '14 at 13:33
  • But for example 'message1' - its the external message buffer (an array of std_logic_vector). I can write to that buffer (which is shared variable) from two processes and there aren't any faults in synthesis... So what is the difference? – Bob Son Dec 07 '14 at 13:43
  • Did the resulting hardware work as expected? If you don't know, you probably haven't found that problem ... yet. (Or it may be possible that actually writing to different addresses in the same buffer actually works, mapping to dual-port BlockRams) –  Dec 07 '14 at 13:55
  • @BrianDrummond I have finally written version without errors. Can you help me with that? I mean, I am not the professional CPLD developer, and on that time I cannot check if that application works. Can you tell me, what could cause problems? And very important question: Can I create signals inside the device, change them in one process, and make another process reacting on the change of that signal? I mean something like: signal signal1--interior signal process 1 : --change signal1 end process; process2(signal1) --if event of signal 1, then do.... end process; – Bob Son Dec 11 '14 at 12:19
  • It still won't synthesise correctly because of things like `if copy1'event then` which require hardware sensitive to both rising and falling edges (and any other events on those signals) –  Dec 11 '14 at 12:27
  • It is syntetizing correctly in Xilinx ISE. – Bob Son Dec 11 '14 at 12:42
  • @BrianDrummond And coolrunnerII has a bothedge flip-flop reaction. http://www.cs.indiana.edu/hmg/le/project-home/xilinx/ise_7.1/doc/usenglish/de/libs/lib/fdd.pdf http://www.xilinx.com/support/documentation/sw_manuals/help/iseguide/mergedProjects/destech/html/cd_dual_edge_clocking.htm If that's a fact, am I using it right? – Bob Son Dec 11 '14 at 12:44
  • Well, good. The "RTL viewer" tool ought to show the generated hardware, which will let you see if it implements the hardware you expect. –  Dec 11 '14 at 13:26

0 Answers0