Questions about single process coding style

M

Mike Treseler

Questions about single process coding style from JaysonL
Reference link
http://home.comcast.net/~mike_treseler/

Q1: Have the single process coding style been synthesized with synopsys tools?

Not that I know of. See the fine print on the web page.
I tried to synthesis the Uart example with Synopsys Design_Analyzer but failure.
A error message “ try to use synchronized value”.
Dose synopsys not support this coding style or just my tool is too old, 2005 version?
Q2: What does the warning message in Xilinx ise mean?
I synthesized the UART example with ISE7.1 successfully,
but a lot of warning messages for variables in design.
The warning message is “Potential simulation mismatch,
variable ABC declared in block A is assigned in block B”.
What is the risk in this warning?

The synthesis is correct.
The warnings are inappropriate in my opinion.
Quartus makes no such warnings.
Q3: Does the testbench in reference link work?

It has been tested on Modelsim, and NC-Sim.
I try simulation the Uart example but it wouldn’t run.
The error message is “Simulator:222 - Generated C++ compilation was unsuccessful”.
Is my ISE7.1 is too old or there is errors in testbench?
Could someone please fix it for ISE7.1?

For ISE, the testbench was only tested on the modelsim simulator.
 
Y

yves.770905

Not that I know of. See the fine print on the web page.


The synthesis is correct.
The warnings are inappropriate in my opinion.
Quartus makes no such warnings.


It has been tested on Modelsim, and NC-Sim.


For ISE, the testbench was only tested on the modelsim simulator.



- Tekst uit oorspronkelijk bericht weergeven -

Hi Mike,

I have seen that you have synthesized the uart code with different
tools, but not with Xilinx ISE.
Since I am writing this kind of code for several years and for
different ASICSs and FPGAs now, I can tell you that Xilinx ISE can not
handle the fact that we are assigning to variables from within
different procedures.
It just gives a warning for a possible simulation mismatch (not even
an error) while synthesizing with XST and if you try to simulate the
netlist it will indeed not work.
I did not do a lot of investigation on what exactly is going wrong
with XST, but it seems that it only "sees" the assignment in the first
procedure where the variable is assigned and it forgets about every
other assignment to that variable.

The only way around it in ISE is to declare every variable that you
are trying to write from within those procedures on the parameter list
as an inout parameter. That way it will synthesize correctly.

This bug is already in XST from version 6 onwards, and now they are
already at version 9 and it is still present :-(

Kind regards,

Yves
 
M

Mike Treseler

Hi Mike,

I have seen that you have synthesized the uart code with different
tools, but not with Xilinx ISE.

No. It works fine with ISE.
-------------------------------------------------------------------------------
-- Quartus 6 src=1.49 363 MHz 52 FF 85 ALUT ep2s15sf484C3
-- Quartus 5.0 SP2 216 MHz 50 FF 73 ALUT ep2s15sf484c3
-- Synplify 8.4+5.0 405 MHz 50 FF 74 ALUT ep2s15sf484c3
-- Quartus 5.1 356 MHz 52 FF 72 ALUT eps15sf484c3
-- Leo 2005b.24 est 194 MHz 48 FF 62 ALUT default
-- Synplify Pro 8.4 408 MHz 93 FF 126 LUTS xc4vlx15sf363-12
-- Synplify Pro 8.0 216 MHz -? FF 94 LUTS xc3s50tq144-4
-- ISE 7.1 288 MHz 50 FF 107 LUTS xc2vp40fg676-6
-- ISE 8.1 277 MHz 50 FF 84 LUTS xc2v40cs144-6
-- ISE 8.1 388 MHz 50 FF 80 LUTS xc4vfx12sf363-12

Since I am writing this kind of code for several years and for
different ASICSs and FPGAs now, I can tell you that Xilinx ISE can not
handle the fact that we are assigning to variables from within
different procedures.

Variables have process scope.
That is why I use a single process.

-- Mike Treseler
 
J

jasonL

Hi Mike,

I have seen that you have synthesized the uart code with different
tools, but not with Xilinx ISE.
Since I am writing this kind of code for several years and for
different ASICSs and FPGAs now, I can tell you that Xilinx ISE can not
handle the fact that we are assigning to variables from within
different procedures.
It just gives a warning for a possible simulation mismatch (not even
an error) while synthesizing with XST and if you try to simulate the
netlist it will indeed not work.
I did not do a lot of investigation on what exactly is going wrong
with XST, but it seems that it only "sees" the assignment in the first
procedure where the variable is assigned and it forgets about every
other assignment to that variable.

The only way around it in ISE is to declare every variable that you
are trying to write from within those procedures on the parameter list
as an inout parameter. That way it will synthesize correctly.

This bug is already in XST from version 6 onwards, and now they are
already at version 9 and it is still present :-(

Kind regards,

Yves- Hide quoted text -

- Show quoted text -

Thanks Yves
Since I am writing this kind of code for several years and for
different ASICSs and FPGAs now, I can tell you that Xilinx ISE can not
handle the fact that we are assigning to variables from within
different procedures.

What kinds of tools you are using?
 
J

jasonL

Variables have process scope.
That is why I use a single process.

Thanks Mike,

I agree with you that Variables have process scope and ISE should
sythesize correctly. However, in the project I am doing, I have a mis-
match problem between pre-synthesis behavior simulation and post-
synthesis net-list simulation. the simulation does function
verification only, no timing constrains.

In ISE synthesis reprot, It seems that ISE could not recognize a big
FSM and keep complaint some variable is used but not assigned. I am
still not sure it is bugs in my code or ISE cause this problem.
 
M

Mike Treseler

It just gives a warning for a possible simulation mismatch (not even
an error) while synthesizing with XST and if you try to simulate the
netlist it will indeed not work.

I just don't see that.
See the gate sim run below.
I did not do a lot of investigation on what exactly is going wrong
with XST, but it seems that it only "sees" the assignment in the first
procedure where the variable is assigned and it forgets about every
other assignment to that variable.

Post a simple example, and I'll have a look.

-- Mike Treseler
_____________________________________________________________
# 6.2a
# vsim -do {run -all; exit} -c test_uart
# ** Note: (vsim-3812) Design is being optimized...
# Loading /flip/usr1/modeltech/linux/../std.standard
# Loading /flip/usr1/modeltech/linux/../ieee.std_logic_1164(body)
# Loading /flip/usr1/modeltech/linux/../ieee.numeric_std(body)
# Loading work.uart_pkg
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.vcomponents
# Loading /flip/usr1/modeltech/linux/../std.textio(body)
# Loading /flip/usr1/modeltech/linux/../ieee.vital_timing(body)
# Loading /flip/usr1/modeltech/linux/../ieee.vital_primitives(body)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.vpkg(body)
# ** Warning: (vsim-3479) Time unit 'ps' is less than the simulator
resolution (1ns).
# Time: 0 ns Iteration: 0 Region: /
# Loading work.test_uart(sim)#1
# Loading work.uart(structure)#1
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.fdc(fdc_v)#1
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.fdp(fdp_v)#1
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.fdc(fdc_v)#2
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.fdce(fdce_v)#1
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.fdp(fdp_v)#2
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.lut2(lut2_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.lut3(lut3_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.lut4(lut4_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.ibuf(ibuf_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.obuf(obuf_v)#1
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.muxf5(muxf5_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.bufgp(bufgp_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.vcc(vcc_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.gnd(gnd_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.lut3_l(lut3_l_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.lut4_d(lut4_d_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.lut4_l(lut4_l_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.lut3_d(lut3_d_v)
# Loading /evtfs/home/tres/vhdl/xilinx/src/unisim.lut2_l(lut2_l_v)
# run -all
# ** Note: Saw reset rise and fall OK
# Time: 105 ns Iteration: 1 Instance: /test_uart
# ** Note: Using fixed_delay_c = 1080 ns That's 108 ticks.
# Time: 105 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 0
# Time: 1275 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 36 as expected
# Time: 1275 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 1
# Time: 2445 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 199 as expected
# Time: 2445 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 2
# Time: 3615 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 24 as expected
# Time: 3615 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 3
# Time: 4785 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 131 as expected
# Time: 4785 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 4
# Time: 5955 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 211 as expected
# Time: 5955 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 5
# Time: 7125 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 217 as expected
# Time: 7125 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 6
# Time: 8295 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 58 as expected
# Time: 8295 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 7
# Time: 9465 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 229 as expected
# Time: 9465 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 8
# Time: 9985 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 229 as expected
# Time: 9985 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 9
# Time: 10505 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 72 as expected
# Time: 10505 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 10
# Time: 11025 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 12 as expected
# Time: 11025 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 11
# Time: 11545 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 217 as expected
# Time: 11545 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 12
# Time: 12065 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 251 as expected
# Time: 12065 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 13
# Time: 12585 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 18 as expected
# Time: 12585 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 14
# Time: 13105 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 131 as expected
# Time: 13105 ns Iteration: 1 Instance: /test_uart
# ** Note: ___Step 15
# Time: 13625 ns Iteration: 1 Instance: /test_uart
# ** Note: ____________ saw 116 as expected
# Time: 13625 ns Iteration: 1 Instance: /test_uart
# ** Note: ___ALL PASS___
# Time: 13625 ns Iteration: 1 Instance: /test_uart
# exit
75 Mon Jun 04
/evtfs/home/tres/vhdl/ref_design/uart_ise/uart_ise/netgen/synthesis>
 
M

Mike Treseler

jasonL said:
Are there any particular reasons for no synthesis with synopsys? just
for my curiosity.

Don't know.
If you have to use synopsys, learn verilog.

-- Mike Treseler
 
Y

yves.770905

Post a simple example, and I'll have a look.

Hello Mike,

This is a simple thing that fails synthesising using ISE 9.1.03i.
It takes 2 control signals, both active high: incr, decr.

When incr is asserted it should increment the internal 8 bit counter.
When decr is asserted it should decrement the internal 8 bit counter.
When none or both of incr and decr are asserted the counter should not
change.

After synthesising I changed the name of the netlist to
procedureTest_syn, so I could instantiate both the RTL and netlist in
the accompanying testbench.

You will find that the behaviour of the netlist is somehow different.
When incr is asserted it will increment the internal 8 bit counter,
regardless of the decr control signal.
When incr is not asserted and decr is asserted it will decrement the 8
bit counter.
When none are asserted the counter stays the same.

Kind regards,

Yves

PS: this is the answer record of Xilinx on that matter. It is a known
issue since version 6.1i
http://www.xilinx.com/xlnx/xil_ans_display.jsp?iLanguageID=1&iCountryID=1&getPagePath=18452

-------------------------------------
-- RTL code
-------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity procedureTest is
port (
clk : in std_logic;
rst : in std_logic;
incr : in std_logic;
decr : in std_logic;
data : out std_logic_vector(7 downto 0)
);
end entity;

library ieee;
use ieee.numeric_std.all;

architecture RTL of procedureTest is
begin

p_main: process (clk, rst)
variable count : unsigned(data'range);

procedure increment is
begin
count := count + 1;
end procedure;

procedure decrement is
begin
count := count - 1;
end procedure;

begin
if rst = '1' then
data <= (others => '0');
count := (others => '0');
elsif rising_edge(clk) then

if incr = '1' then
increment;
end if;

if decr = '1' then
decrement;
end if;

data <= std_logic_vector(count);

end if;
end process;

end RTL;

-------------------------------------
-- testbench code
-------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb is
end entity;

architecture beh of tb is

signal clk : std_logic := '0';
signal rst : std_logic;
signal incr : std_logic;
signal decr : std_logic;
signal data : std_logic_vector(7 downto 0);
signal data_syn : std_logic_vector(7 downto 0);

component procedureTest_syn
port (
clk : in std_logic;
rst : in std_logic;
incr : in std_logic;
decr : in std_logic;
data : out std_logic_vector(7 downto 0)
);
end component;

component procedureTest
port (
clk : in std_logic;
rst : in std_logic;
incr : in std_logic;
decr : in std_logic;
data : out std_logic_vector(7 downto 0)
);
end component;

begin
clk <= not clk after 5 ns;
rst <= '1', '0' after 100 ns;

p_stimuli: process(clk, rst)
variable count : unsigned(5 downto 0);
begin
if rst = '1' then
count := (others => '0');
incr <= '0';
decr <= '0';
elsif rising_edge(clk) then
count := count + 1;
incr <= count(3);
decr <= count(5);
assert data_syn = data report "data mismatch" severity error;
end if;
end process;

i_DUT: procedureTest
port map (
clk => clk,
rst => rst,
incr => incr,
decr => decr,
data => data
);

i_SYN: procedureTest_syn
port map (
clk => clk,
rst => rst,
incr => incr,
decr => decr,
data => data_syn
);

end beh;
 
Y

yves.770905

Not that I know of. See the fine print on the web page.

We have been synthesizing this coding style with synopsys, I can't
remember which version of Synopsys we were using back then (read: the
year 2004 :) )
 
M

Mike Treseler

We have been synthesizing this coding style with synopsys, I can't
remember which version of Synopsys we were using back then (read: the
year 2004 :) )

If you still have access to a license,
please give my reference design a spin.
Thanks.

-- Mike Treseler
 
M

Mike Treseler

This is a simple thing that fails synthesizing using ISE 9.1.03i.
...
i_SYN: procedureTest_syn

I will assume that the line above was supposed to be

i_SYN: procedureTest

Because this allows default binding and makes
your testbench run without error.

-- Mike Treseler
 
Y

yves.770905

I will assume that the line above was supposed to be

i_SYN: procedureTest

Because this allows default binding and makes
your testbench run without error.

-- Mike Treseler

Hi Mike,

For instantiating both the RTL and the netlist in the same testbench,
I just renamed the entity of the netlist to procedureTest_syn, that
was a quick and dirty solution and not having to think about writing a
configuration ;-)

Kind regards,

Yves
 
M

Mike Treseler

answer record reference:
http://www.xilinx.com/xlnx/xil_ans_display.jsp?iLanguageID=1&iCountryID=1&getPagePath=18452
You will find that the behaviour of the netlist is somehow different.
When incr is asserted it will increment the internal 8 bit counter,
regardless of the decr control signal.

With my test case here
http://home.comcast.net/~mike_treseler/proc_demo.vhd
I saw decrement priority instead, but yes this is a nasty bug.
At least there is a warning.

Here is the troublesome section:

procedure update_regs_bug is
begin -- procedure update_regs
if incr = '1' then
increment;
end if;
if decr = '1' then
decrement;
end if;
end procedure update_regs_bug;

ISE gets the logic wrong on the up counter like this:
http://home.comcast.net/~mike_treseler/proc_demo_ise_bug.pdf

Quartus counts up and down to cover the "both inputs asserted" case.
http://home.comcast.net/~mike_treseler/proc_demo_quartus.pdf
This probably isn't the optimum solution, but it is logically correct.

Here's a work around:

procedure update_regs_fix is
begin -- procedure update_regs
if incr = '1' and decr = '0'
then
increment;
elsif incr = '0' and decr = '1'
then
decrement;
end if;
end procedure update_regs_fix;

By describing the active cases explicitly,
ise gets the hint:
http://home.comcast.net/~mike_treseler/proc_demo_ise_fix.pdf
In my opinion, this is a clearer description
but I agree that either one ought to work.


Thanks for the posting Yves!
This is a good reminder to me
to read ALL of the synthesis warnings.

-- Mike Treseler
 
Y

yves.770905

(e-mail address removed) wrote:

...


With my test case here
http://home.comcast.net/~mike_treseler/proc_demo.vhd
I saw decrement priority instead, but yes this is a nasty bug.
At least there is a warning.

Here is the troublesome section:

procedure update_regs_bug is
begin -- procedure update_regs
if incr = '1' then
increment;
end if;
if decr = '1' then
decrement;
end if;
end procedure update_regs_bug;

ISE gets the logic wrong on the up counter like this:
http://home.comcast.net/~mike_treseler/proc_demo_ise_bug.pdf

Quartus counts up and down to cover the "both inputs asserted" case.
http://home.comcast.net/~mike_treseler/proc_demo_quartus.pdf
This probably isn't the optimum solution, but it is logically correct.

Here's a work around:

procedure update_regs_fix is
begin -- procedure update_regs
if incr = '1' and decr = '0'
then
increment;
elsif incr = '0' and decr = '1'
then
decrement;
end if;
end procedure update_regs_fix;

By describing the active cases explicitly,
ise gets the hint:http://home.comcast.net/~mike_treseler/proc_demo_ise_fix.pdf
In my opinion, this is a clearer description
but I agree that either one ought to work.

Thanks for the posting Yves!
This is a good reminder to me
to read ALL of the synthesis warnings.

-- Mike Treseler

Hi Mike,
Another way to fix it is defining the procedures like this:

procedure increment(cnt: inout unsigned(count'range)) is
begin
cnt := cnt + 1;
end procedure;
procedure decrement(cnt: inout unsigned(count'range)) is
begin
cnt := cnt + 1;
end procedure;

Then xst will understand it correctly :)

Kind regards,

Yves
 
Y

yves.770905

If you still have access to a license,
please give my reference design a spin.
Thanks.

-- Mike Treseler

Unfortunately I don't have access to synopsys any more :-(
I will ask around to hear if some of my ex-coworkers still have
access.

Yves
 
M

Mike Treseler

Hi Mike,
Another way to fix it is defining the procedures like this:

procedure increment(cnt: inout unsigned(count'range)) is
begin
cnt := cnt + 1;
end procedure;
procedure decrement(cnt: inout unsigned(count'range)) is
begin
cnt := cnt + 1;
end procedure;

Oh my.
I'm a big fan of subprograms, but having to pass
a variable to an in-scope procedure is over
my verbosity limit.

I see that this is the "work-around"
offered in the answer record but it
is not a practical one in my book.

-- Mike Treseler
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top