EmbDev.net

Forum: FPGA, VHDL & Verilog VHDL synthesis result is not equal to behavioral


von Michal (Guest)


Attached files:

Rate this post
useful
not useful
Hello,
I have to write program in VHDL which calculate sqrt using Newton 
method. I wrote the code which seems to me to be ok but it does not 
work. Behavioral simulation gives proper output value but post synthesis 
(and launched on hardware) not. Program was implemented as state 
machine. Input value is an integer (used format is std_logic_vector), 
and output is fixed point (for calculation purposes input value was 
multiplied by 64^2 so output value has 6 LSB bits are fractional part).
I used function to divide in vhdl from vhdlguru blogspot. In behavioral 
simulation calculating sqrt takes about 350 ns (Tclk=10 ns) but in post 
synthesis only 50 ns.
1
 
2
library ieee;
3
use ieee.std_logic_1164.all;
4
use ieee.std_logic_arith.all;
5
use ieee.std_logic_unsigned.all;
6
7
        entity moore_sqrt is
8
port (clk : in std_logic;
9
      enable : in std_logic;
10
      input : in std_logic_vector (15 downto 0);
11
      data_ready : out std_logic;
12
      output : out std_logic_vector (31 downto 0)
13
  );
14
end moore_sqrt;
15
16
architecture behavioral of moore_sqrt is
17
------------------------------------------------------------
18
function  division  (x : std_logic_vector; y : std_logic_vector) return std_logic_vector is
19
variable a1 : std_logic_vector(x'length-1 downto 0):=x;
20
variable b1 : std_logic_vector(y'length-1 downto 0):=y;
21
variable p1 : std_logic_vector(y'length downto 0):= (others => '0');
22
variable i : integer:=0;
23
    begin
24
        for i in 0 to y'length-1 loop
25
            p1(y'length-1 downto 1) := p1(y'length-2 downto 0);
26
            p1(0) := a1(x'length-1);
27
            a1(x'length-1 downto 1) := a1(x'length-2 downto 0);
28
            p1 := p1-b1;
29
            if(p1(y'length-1) ='1') then
30
                a1(0) :='0';
31
                p1 := p1+b1;
32
            else
33
                a1(0) :='1';
34
            end if;
35
        end loop;
36
return a1;
37
end division;
38
-------------------------------------------------------------- 
39
type state_type is (s0, s1, s2, s3, s4, s5, s6);  --type of state machine
40
signal current_state,next_state: state_type;  --current and next state declaration
41
42
signal xk : std_logic_vector (31 downto 0);
43
signal temp : std_logic_vector (31 downto 0);
44
signal latched_input : std_logic_vector (15 downto 0);
45
signal iterations : integer := 0;
46
signal max_iterations : integer := 10;  --corresponds with accuracy
47
48
begin
49
50
process (clk,enable)
51
begin
52
if enable = '0' then
53
    current_state <= s0; 
54
elsif clk'event and clk = '1' then
55
    current_state <= next_state;   --state change
56
end if;
57
end process;
58
59
--state machine
60
process (current_state)
61
begin
62
  case current_state is
63
    when s0 =>          -- reset       
64
        output <= "00000000000000000000000000000000";
65
        data_ready <= '0';
66
        next_state <= s1;
67
    when s1 =>          -- latching input data
68
        latched_input <= input;
69
        next_state <= s2;        
70
     when s2 =>         -- start calculating
71
        -- initial value is set as a half of input data
72
        output <= "00000000000000000000000000000000";
73
        data_ready <= '0';
74
        xk <= "0000000000000000" & division(latched_input, "0000000000000010");
75
        next_state <= s3;
76
        iterations <= 0;
77
    when s3 =>         -- division
78
        temp <= division ("0000" & latched_input & "000000000000", xk);
79
        next_state <= s4;
80
    when s4 =>          -- calculating 
81
        if(iterations < max_iterations) then
82
            xk <= xk + temp;
83
            next_state <= s5;
84
            iterations <= iterations + 1;
85
        else
86
            next_state <= s6;
87
        end if;
88
    when s5 =>          -- shift logic right by 1
89
            xk <= division(xk, "00000000000000000000000000000010");
90
            next_state <= s3;       
91
    when s6 =>             -- stop - proper data
92
--          output <= division(xk, "00000000000000000000000001000000");  --the nearest integer value
93
            output <= xk;    -- fixed point 24.6, sqrt = output/64;
94
            data_ready <= '1';
95
    end case;
96
end process;
97
end behavioral;

I have only little experience with VHDL and I have no idea what can I do 
to fix problem. I tried to exclude other process which was for 
calculation but it also did not work.

I attached printscreens of results behavioral and post -synthesis 
simulations

I hope you can help me.
Platform: Zynq ZedBoard
IDE: Vivado 2014.4

Regards,
Michal

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Michal wrote:
> I used function to divide in vhdl from vhdlguru blogspot.
Did you check how fast is that incredible bunch of logic you implemented 
there? Just to get an impression: have a look at the RTL schematic.

> (Tclk=10 ns)
I'm fairly sure that your huge division algorithm is much(!!!!) slower. 
Did you set a timing constraint for that clock?

Just to be sure: run your timing simulation with a 1MHz clock...

: Edited by Moderator
von Michal (Guest)


Rate this post
useful
not useful
I've checked this before - time constraints were ok. I launch 
post-synthesis simulation with 1 MHz clock but result is the same as 
with 100 MHz.

von Lattice User (Guest)


Rate this post
useful
not useful
The mismatch between the simulations is caused by the incomplete 
sensitivity list of your 2nd process. This process is full of latches 
and combinatorial loops which are hidden by the incomplete list in the 
behavioral simulation but will show up in the hardware implementation.

The easiest way to fix the problem, is to get rid of the two process 
implementation of your state machine. Use only one clocked process.

Once you have don this, the problem Lothar mentioned will show up, that 
is your design will only run at lower clock speeds.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Lattice User wrote:
> This process is full of latches and combinatorial loops
Ouch....

@Michal: the synthesizer must have shown a big bunch of messages you 
should analyze. To keep it short: you can neglect errors, warnings and 
even infos from the synthesizer only when you understand the according 
message fully and you want such a behaviour.

For combinatorial loops try that with Google translator:
http://www.lothar-miller.de/s9y/categories/36-Kombinatorische-Schleife
And this here is your problem:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.