FPGARelated.com
Forums

Expecting sequential output, but RTL shows concurrent implementation.

Started by Sharath Raju May 11, 2010
Hi,

I am trying to implement autocorrelation operation on an FPGA.
Autocorrelation can be written as: Phi(n) =3D Summation { x(k) * x(n-
k) }
Essentially, the signal x(k) is multiplied with a delayed version of
itself and the product is accumulated over a finite range of x(k)
samples.

I have written VHDL code, where the delay, multiply and accumulate
operations are carried out sequentially at the rising edge of the
clock.

{link to code http://sites.google.com/site/brsharath/sdmac_approach0_1.vhd?=
attredirects=3D0&d=3D1
}

In the clock process, I expect the statements within the "if block" to
execute sequentially. However, in the RTL description,

{link
http://5483477158486903344-a-1802744773732722657-s-sites.googlegroups.com/s=
ite/brsharath/sdmac_approach0_1.png?attachauth=3DANoY7cp-FCHAwKIai7JuTsVPgv=
AENU4ou15FLhplgwxKlODHsz3G3sNsTOC2xPAoaNE8IntPEYP7T9A76ACM5Ry9o6rRLdbvVtI0n=
VThp84mEtGt6bGuw2RmVcTG9sEmAQ2ULQXNYqR4xlihAZlDayHEaw7u-PsfE4HqAbgtr8fRUFm2=
2PjwSkiLrtj5rMvP5WyDwMGxA31ByVc3sdISyWa1fQClsMXTlw%3D%3D&attredirects=3D0}
 it is seen that the adder and output D flip-flop of the multiplier
triggered by the same clock signal, without any delay between the two.
This causes the adder block to operate even before the multiplier
output reaches the adder input.  Why is this so ? Further, in the
functional simulation, I see that the output of the DMAC unit is
updated after two clock cycles. My requirement is that the delay,
multiply and accumulate operations happen sequentially and within the
same clock cycle.

If the above description is not clear, please let me know, I may be
able to explain in a simpler manner.

Thanks,
Sharath
On 11 Mai, 06:32, Sharath Raju <brshar...@gmail.com> wrote:
> Hi, > > I am trying to implement autocorrelation operation on an FPGA. > Autocorrelation can be written as: Phi(n) =3D Summation { x(k) * x(n- > k) } > Essentially, the signal x(k) is multiplied with a delayed version of > itself and the product is accumulated over a finite range of x(k) > samples. > > I have written VHDL code, where the delay, multiply and accumulate > operations are carried out sequentially at the rising edge of the > clock. > > {link to codehttp://sites.google.com/site/brsharath/sdmac_approach0_1.vhd=
?attredir...
> > } > > In the clock process, I expect the statements within the "if block" to > execute sequentially. However, in the RTL description, > > {linkhttp://5483477158486903344-a-1802744773732722657-s-sites.googlegroup=
s...}
> =A0it is seen that the adder and output D flip-flop of the multiplier > triggered by the same clock signal, without any delay between the two. > This causes the adder block to operate even before the multiplier > output reaches the adder input. =A0Why is this so ? Further, in the > functional simulation, I see that the output of the DMAC unit is > updated after two clock cycles. My requirement is that the delay, > multiply and accumulate operations happen sequentially and within the > same clock cycle. > > If the above description is not clear, please let me know, I may be > able to explain in a simpler manner. > > Thanks, > Sharath
Hi Sharath, I wonder that your code synthesizes at all. Normally a process with two different clock triggers (rising edge and falling edge) would cause an error, Maybe you got luck, because your signal del_2_x doesn't appear in the other clock region. Anyway, this half clock delay is unnecessary. Make it a full cycle or leave it away. Also you have no reset scheme, just default assignments in the declarations. Xilinx ISE can handle that, but other tools ignore it. Now to your implementation, do you know about pipelining? This is what's happening in your code. It's nothing bad, just something to be considered. Remember the driver/reader concept of VHDL signals? So when you are assigning to some signal ,the value is writen to the signals driver, but other assignments that use this signal in the same process take the old value from the signals reader. Every assignment in a clocked process creates a register, so you have to take care that your datapath has proper delays for all signals, to put the right data at the right time at the inputs of yor arithmetic operators. Did you make a time schedule plan for your data? There you can see which signals need extra delay Have a nice simulation Eilert
On Mon, 10 May 2010 23:31:23 -0700 (PDT)
backhus <goouse99@googlemail.com> wrote:

[snip]
> Also you have no reset scheme, just default assignments in the > declarations. > Xilinx ISE can handle that, but other tools ignore it.
[snip] Sorry for hijacking the thread, but... do you mean that if I write this code: signal foo : std_ulogic_vector(3 downto 0) := "1010"; I would *not* normally expect the FPGA to power up with "1010" in the signal!? I've only ever worked with Xilinx FPGAs using ISE, so I assumed it worked everywhere; is this not the case? (kind of nice to know in case I do some day end up using a different make of FPGA...) Chris
> Sorry for hijacking the thread, but... do you mean that if I write this > code: > signal foo : std_ulogic_vector(3 downto 0) := "1010"; > I would *not* normally expect the FPGA to power up with "1010" in the > signal!? I've only ever worked with Xilinx FPGAs using ISE, so I > assumed it worked everywhere; is this not the case? (kind of nice to > know in case I do some day end up using a different make of FPGA...)
You shouldn't rely in this if you want your designs to be 'portable'. You should also think about active reset logic for your design so that you know everything will definitely power up to a known state. What happens if you have a portion of your design you want to hold in reset until something else is configured properly? I have done this to allow a quick simulation of a module and know that Quartus throws up a warning (although I'm not sure if it does actually implement the reset value). Bottom line is you need a reset mechanism in to set these values. Nial.
On 11 Mai, 09:11, Christopher Head <ch...@cs.ubc.ca> wrote:
> On Mon, 10 May 2010 23:31:23 -0700 (PDT) > > backhus <goous...@googlemail.com> wrote: > > [snip]> Also you have no reset scheme, just default assignments in the > > declarations. > > Xilinx ISE can handle that, but other tools ignore it. > > [snip] > > Sorry for hijacking the thread, but... do you mean that if I write this > code: > > signal foo : std_ulogic_vector(3 downto 0) := "1010"; > > I would *not* normally expect the FPGA to power up with "1010" in the > signal!? I've only ever worked with Xilinx FPGAs using ISE, so I > assumed it worked everywhere; is this not the case? (kind of nice to > know in case I do some day end up using a different make of FPGA...) > > Chris
Hi Chris, That's right. The synthesis standard for VHDL treats assignments at declaration time as "ignored". They work and are intended to use for simulation (e.g. in testbenches). That XST uses these values is due to the fact that they can be held in the programming bitstream, and thus be present at power up for an SRAM based FPGA. Think of ASICs (or antifuse FPGAs) and this is no more true, so, as Neal mentioned, your code isn't portable anymore. Same is if you use a tool that strictly complies with the VHDL simulation standard. I didn't mention how to solve the problem, because that's a tricky question. It depends on many things whether you should do it, and how to do it. e.g. Registers in datapaths don't necessarily need a reset. The values are continuously overwritten. BUT: If you have a feedback path your simulation can stuck with 'X'es. One possible solution is to create Registers with an asynchronous reset, that will be used by ths testbench, and tied to the inactive state for synthesis. So the net will be optimized away and there are no 'X'es in a real chip. :-) For Counters/FSMs and such you have to decide. e.g.: A loadable counter doesn't need a reset, if the first thing that happens is a load operation. Also you should think about asynchronous and synchronous resets. A nice paper about this topic can be found on the Xilinx website. Have a nice synthesis Eilert
On May 12, 10:45=A0am, backhus <goous...@googlemail.com> wrote:
> On 11 Mai, 09:11, Christopher Head <ch...@cs.ubc.ca> wrote: > > > > > On Mon, 10 May 2010 23:31:23 -0700 (PDT) > > > backhus <goous...@googlemail.com> wrote: > > > [snip]> Also you have no reset scheme, just default assignments in the > > > declarations. > > > Xilinx ISE can handle that, but other tools ignore it. > > > [snip] > > > Sorry for hijacking the thread, but... do you mean that if I write this > > code: > > > signal foo : std_ulogic_vector(3 downto 0) :=3D "1010"; > > > I would *not* normally expect the FPGA to power up with "1010" in the > > signal!? I've only ever worked with Xilinx FPGAs using ISE, so I > > assumed it worked everywhere; is this not the case? (kind of nice to > > know in case I do some day end up using a different make of FPGA...) > > > Chris > > Hi Chris, > That's right. > The synthesis standard for VHDL treats assignments at declaration time > as "ignored". > They work and are intended to use for simulation (e.g. in > testbenches). > > That XST uses these values is due to the fact that they can be held in > the programming bitstream, and thus be present at power up for an SRAM > based FPGA. > Think of ASICs (or antifuse FPGAs) and this is no more true, so, as > Neal mentioned, your code isn't portable anymore. > Same is if you use a tool that strictly complies with the VHDL > simulation standard. > > I didn't mention how to solve the problem, because that's a tricky > question. > It depends on many things whether you should do it, and how to do it. > e.g. > Registers in datapaths don't necessarily need a reset. The values are > continuously overwritten. > BUT: > =A0 If you have a feedback path your simulation can stuck with 'X'es. > One possible solution is to create Registers with an asynchronous > reset, that will be used by ths testbench, and tied to the inactive > state for synthesis. > So the net will be optimized away and there are no 'X'es in a real > chip. :-) > > For Counters/FSMs and such you have to decide. > e.g.: A loadable counter doesn't need a reset, if the first thing that > happens is a load operation. > Also you should think about asynchronous and synchronous resets. > > A nice paper about this topic can be found on the Xilinx website. > > Have a nice synthesis > =A0 =A0Eilert
On May 11, 1:24 pm, "Nial Stewart" <nial*REMOVE_TH...@nialstewartdevelopments.co.uk> wrote:
> > Sorry for hijacking the thread, but... do you mean that if I write this > > code: > > signal foo : std_ulogic_vector(3 downto 0) :=3D "1010"; > > I would *not* normally expect the FPGA to power up with "1010" in the > > signal!? I've only ever worked with Xilinx FPGAs using ISE, so I > > assumed it worked everywhere; is this not the case? (kind of nice to > > know in case I do some day end up using a different make of FPGA...) > > You shouldn't rely in this if you want your designs to be 'portable'. > > You should also think about active reset logic for your design so that > you know everything will definitely power up to a known state. What > happens if you have a portion of your design you want to hold in reset > until something else is configured properly? > > I have done this to allow a quick simulation of a module and > know that Quartus throws up a warning (although I'm not sure if it does a=
ctually
> implement the reset value). > > Bottom line is you need a reset mechanism in to set these values. > > Nial.
Thanks for all the inputs, particularly bachus. I paid careful attention to the signal driver concept, and rewrote the code {link: http://sites.google.com/site/brsharath/sdmac_signal_sched.vhd?a= ttredirects=3D0&d=3D1 } The resulting RTL schematic is posted here: {link:http:// 5483477158486903344-a-1802744773732722657-s-sites.googlegroups.com/ site/brsharath/RTL.png? attachauth=3DANoY7coSXbMoJLHb5mbgwSAjgt3QN8FYgvT7itNF1lC3peoLOlSNRh7dgnAlxJ= ClWwXFP8uTl6q387V0zZBmAdQIH5F79SuOJV9mtBqSiAR0s0dCCeGvDqrI- JlaMoF6x5YETpEBkFYsEPFvVwDq-YKMLvzfo- r8wz0ByGeZAHE7DP_rFJKDcEFTzDm2ez4o_2m8OlDzqFR5&attredirects=3D0 } Please have a look and let me know if you have something to say. The clock updates in the same clock cycle, without any delay. However, I did not understand what you mean by a Reset scheme and a time schedule plan. Are you simply referring to having an idea about "which signals should change when and under what conditions" ? Thanks, Sharath
On May 11, 3:11 am, Christopher Head <ch...@cs.ubc.ca> wrote:
> On Mon, 10 May 2010 23:31:23 -0700 (PDT) > > backhus <goous...@googlemail.com> wrote: > > [snip]> Also you have no reset scheme, just default assignments in the > > declarations. > > Xilinx ISE can handle that, but other tools ignore it. > > [snip] > > Sorry for hijacking the thread, but... do you mean that if I write this > code: > > signal foo : std_ulogic_vector(3 downto 0) := "1010"; > > I would *not* normally expect the FPGA to power up with "1010" in the > signal!? I've only ever worked with Xilinx FPGAs using ISE, so I > assumed it worked everywhere; is this not the case? (kind of nice to > know in case I do some day end up using a different make of FPGA...) > > Chris
I can't say for sure, but I think the reason *why* declaration assignments are not used in synthesis is because they are not associated with any sort of signal. If you want FFs in an FPGA to initialize to a known state, this has to be done on the power up reset which is normally done through a global Set/Reset signal. The synthesis tools understand this signal and the fact that it can be driven externally as well as by a power up reset. The declaration assignment only sets the signal value on start up which is not the same thing, so it is just ignored. I find that to prevent warnings in functions like std_match I do need declaration assignments so that there are no 'u'/'x'/'-' states in buses at simulation startup when everything gets run. After that signals have values according to the code. This can mask missing reset assignments, but I believe the tools I am using give a warning on such things, it's not a very loud warning. It often hides in all the other warnings I need to ignore. Rick
On 12 Mai, 10:49, Sharath Raju <brshar...@gmail.com> wrote:
> On May 12, 10:45=A0am, backhus <goous...@googlemail.com> wrote: > > > > > On 11 Mai, 09:11, Christopher Head <ch...@cs.ubc.ca> wrote: > > > > On Mon, 10 May 2010 23:31:23 -0700 (PDT) > > > > backhus <goous...@googlemail.com> wrote: > > > > [snip]> Also you have no reset scheme, just default assignments in th=
e
> > > > declarations. > > > > Xilinx ISE can handle that, but other tools ignore it. > > > > [snip] > > > > Sorry for hijacking the thread, but... do you mean that if I write th=
is
> > > code: > > > > signal foo : std_ulogic_vector(3 downto 0) :=3D "1010"; > > > > I would *not* normally expect the FPGA to power up with "1010" in the > > > signal!? I've only ever worked with Xilinx FPGAs using ISE, so I > > > assumed it worked everywhere; is this not the case? (kind of nice to > > > know in case I do some day end up using a different make of FPGA...) > > > > Chris > > > Hi Chris, > > That's right. > > The synthesis standard for VHDL treats assignments at declaration time > > as "ignored". > > They work and are intended to use for simulation (e.g. in > > testbenches). > > > That XST uses these values is due to the fact that they can be held in > > the programming bitstream, and thus be present at power up for an SRAM > > based FPGA. > > Think of ASICs (or antifuse FPGAs) and this is no more true, so, as > > Neal mentioned, your code isn't portable anymore. > > Same is if you use a tool that strictly complies with the VHDL > > simulation standard. > > > I didn't mention how to solve the problem, because that's a tricky > > question. > > It depends on many things whether you should do it, and how to do it. > > e.g. > > Registers in datapaths don't necessarily need a reset. The values are > > continuously overwritten. > > BUT: > > =A0 If you have a feedback path your simulation can stuck with 'X'es. > > One possible solution is to create Registers with an asynchronous > > reset, that will be used by ths testbench, and tied to the inactive > > state for synthesis. > > So the net will be optimized away and there are no 'X'es in a real > > chip. :-) > > > For Counters/FSMs and such you have to decide. > > e.g.: A loadable counter doesn't need a reset, if the first thing that > > happens is a load operation. > > Also you should think about asynchronous and synchronous resets. > > > A nice paper about this topic can be found on the Xilinx website. > > > Have a nice synthesis > > =A0 =A0Eilert > > On May 11, 1:24 pm, "Nial Stewart" > > > > <nial*REMOVE_TH...@nialstewartdevelopments.co.uk> wrote: > > > Sorry for hijacking the thread, but... do you mean that if I write th=
is
> > > code: > > > signal foo : std_ulogic_vector(3 downto 0) :=3D "1010"; > > > I would *not* normally expect the FPGA to power up with "1010" in the > > > signal!? I've only ever worked with Xilinx FPGAs using ISE, so I > > > assumed it worked everywhere; is this not the case? (kind of nice to > > > know in case I do some day end up using a different make of FPGA...) > > > You shouldn't rely in this if you want your designs to be 'portable'. > > > You should also think about active reset logic for your design so that > > you know everything will definitely power up to a known state. What > > happens if you have a portion of your design you want to hold in reset > > until something else is configured properly? > > > I have done this to allow a quick simulation of a module and > > know that Quartus throws up a warning (although I'm not sure if it does=
actually
> > implement the reset value). > > > Bottom line is you need a reset mechanism in to set these values. > > > Nial. > > Thanks for all the inputs, particularly bachus. > > I paid careful attention to the signal driver concept, and rewrote the > code {link:http://sites.google.com/site/brsharath/sdmac_signal_sched.vhd?=
attredi...
> > } > > The resulting RTL schematic is posted here: {link:http:// > 5483477158486903344-a-1802744773732722657-s-sites.googlegroups.com/ > site/brsharath/RTL.png? > attachauth=3DANoY7coSXbMoJLHb5mbgwSAjgt3QN8FYgvT7itNF1lC3peoLOlSNRh7dgnAl=
xJClWwXFP8uTl6q387V0zZBmAdQIH5F79SuOJV9mtBqSiAR0s0dCCeGvDqrI-
> JlaMoF6x5YETpEBkFYsEPFvVwDq-YKMLvzfo- > r8wz0ByGeZAHE7DP_rFJKDcEFTzDm2ez4o_2m8OlDzqFR5&attredirects=3D0 } > =A0Please have a look and let me know if you have something to say. The > clock updates in the same clock cycle, without any delay. > > However, I did not understand what you mean by a Reset scheme and a > time schedule plan. Are you simply referring to having an idea about > "which signals should change when and under what conditions" ? > > Thanks, > Sharath
Hi Sharath, your new code has some mistakes: The sensitivity lists in the last two processes are incomplete, rewrite like this: process (Sum,P) process (Inc_cnt, Dec_cnt, Int_count) The last proces will result in latches anyway, which is no good. And still you are triggering on both clock edges in the first process. Look at the Synthesis Templates (light bulb icon) that come with the ISE software: Using a simple asynchronous reset would look like this: Process (reset,clk) is begin If reset =3D '1' then --assign start values for registered signals elsif rising_edge(clk) then -- do something end if; end process; About the time scheduling plan: Not just "having an idea" but a plan. The only condition for signal changes here is the active clock edge. e.g.: clock_cycle | 0 | X | * | P(13 :0) Del_X | XOR | P(14) (There would normally be lines from the inputs to the operators (*,xor) and from there to the outputs. but it's hard to do in ASCII) Also there would be more steps, but in your new code you have moved most everything out of the clocked process, so it's combinatorical stuff, and no longer under clock controll. Even your counter is fully combinatorical now. Crap! This may look nice in behavioral simulation, but makes your code useless in a larger system. No registered outputs mean: No predictable timing behavior in the system, latches and other nasty stuff. With careful scheduling your algorithm needs a three stage pipeline : 1st Stage: generating P adn Del_2_X 2nd Stage: generating ones_compl_P 3rd Stage: adding Sum and ones_compl_P (sumdash is not needed, since sum is a registered signal and can be fed back) This can all be done in one simple clocked process. The counter can either be put in the 3rd stage too, or as an extra process. In any case the signal P has to be delayed once or twice to match the latency of the sum signal (e.g. for generating Inc_cnt anf Dec_cnt ) With such a design you have a beginning latency of three clock cycles but then new results on every clock cycle. Have a nice synthesis Eilert
rickman <gnuarm@gmail.com> writes:

> On May 11, 3:11 am, Christopher Head <ch...@cs.ubc.ca> wrote: >> On Mon, 10 May 2010 23:31:23 -0700 (PDT) >> >> backhus <goous...@googlemail.com> wrote: >> >> [snip]> Also you have no reset scheme, just default assignments in the >> > declarations. >> > Xilinx ISE can handle that, but other tools ignore it. >> >> [snip] >> >> Sorry for hijacking the thread, but... do you mean that if I write this >> code: >> >> signal foo : std_ulogic_vector(3 downto 0) := "1010"; >> >> I would *not* normally expect the FPGA to power up with "1010" in the >> signal!? I've only ever worked with Xilinx FPGAs using ISE, so I >> assumed it worked everywhere; is this not the case? (kind of nice to >> know in case I do some day end up using a different make of FPGA...) >> >> Chris > > I can't say for sure, but I think the reason *why* declaration > assignments are not used in synthesis is because they are not > associated with any sort of signal.
The point is that those assignments *are* used in synthesis by some tools. XST does it for one. It makes no sense for an ASIC, but for FPGAs which have a well defined startup condition defined by the bitstream it makes eminent sense. Now whether you want to take advantage of it depends on how portable to ASIC you want your code to be
> If you want FFs in an FPGA to initialize to a known state, this has > to be done on the power up reset which is normally done through a > global Set/Reset signal. The synthesis tools understand this signal > and the fact that it can be driven externally as well as by a power > up reset.
That's another way of getting (part) of the FPGA back to it's initialised state. But the RAMs will be potentially different. And be aware that this signal is a) slow and b) connected to asynchronous (p)reset ports on the FFs, so you can quite feasibly have parts of your design coming out of reset in one clock cycle and others a tick later if you assert the GSR willy-nilly. And then you can do a "normal ASIC-like" reset explicit in your logic... That is a fundamentally different thing - it's not "initialisation", it's resetting. It's quite feasible to have a FF which inits to '1' and has a reset signal to set it to '0'. Personally I avoid the GSR. I create reset signals which are synchronous to each of my clocks from a single async reset source and distribute those to the flipflops that need them explicitly, and use the synchronously. I occasionally make use of the startup value of the FFs being definable (in my resetn synchroniser for example!). I do arrange the logic to work with them initialising to '0's however, as in the past when synth tools didn't read the intialisation statements, it ensured the simulation matched the "default" behaviour of the FPGA flops.
> The declaration assignment only sets the signal value on start up > which is not the same thing, so it is just ignored. >
IIRC it *is* the same thing - the INIT state of a FF in the bitstream also defines its behaviour when the global set/reset (GSR) is asserted.
> I find that to prevent warnings in functions like std_match I do need > declaration assignments so that there are no 'u'/'x'/'-' states in > buses at simulation startup when everything gets run. After that > signals have values according to the code. This can mask missing > reset assignments, but I believe the tools I am using give a warning > on such things, it's not a very loud warning. It often hides in all > the other warnings I need to ignore. >
With modelsim you can set up a script to turn off the "numeric_std" warnings about those states, run for 0 ns (or a few ticks if you need to get your pipelines filled) and then turn them back on again so you don't miss any others. Cheers, Martin -- martin.j.thompson@trw.com TRW Conekt - Consultancy in Engineering, Knowledge and Technology http://www.conekt.net/electronics.html
On 14/05/2010 09:53, Martin Thompson wrote:
> rickman<gnuarm@gmail.com> writes: > >> On May 11, 3:11 am, Christopher Head<ch...@cs.ubc.ca> wrote: >>> On Mon, 10 May 2010 23:31:23 -0700 (PDT) >>> >>> backhus<goous...@googlemail.com> wrote: >>> >>> [snip]> Also you have no reset scheme, just default assignments in the >>>> declarations. >>>> Xilinx ISE can handle that, but other tools ignore it. >>> >>> [snip] >>> >>> Sorry for hijacking the thread, but... do you mean that if I write this >>> code: >>> >>> signal foo : std_ulogic_vector(3 downto 0) := "1010"; >>> >>> I would *not* normally expect the FPGA to power up with "1010" in the >>> signal!? I've only ever worked with Xilinx FPGAs using ISE, so I >>> assumed it worked everywhere; is this not the case? (kind of nice to >>> know in case I do some day end up using a different make of FPGA...) >>> >>> Chris >> >> I can't say for sure, but I think the reason *why* declaration >> assignments are not used in synthesis is because they are not >> associated with any sort of signal. > > The point is that those assignments *are* used in synthesis by some > tools. XST does it for one. It makes no sense for an ASIC, but for > FPGAs which have a well defined startup condition defined by the > bitstream it makes eminent sense. >
<snip> Just one word of warning - I've been caught out by this using Mentor Precision. Precision *does* support initialisation at declaration, but I had to add an attribute to the (VHDL) code to make it happen. Quartus and ISE seem be ok. Synplify seems to accept initialisations by default (i.e. without extra attibutes). I can't speak for other tools, but I know Synplify will even initialize ROM contents by reading a file into a constant using a function.
> Now whether you want to take advantage of it depends on how portable > to ASIC you want your code to be >
Exactly. I must admit, I still feel happier having a functional reset pin - and if you have a functional reset pin then of course that won't use any initial states, they'll only get applied when the bitstream is downloaded. I suppose you could design a system where the reset procedure was to download the bitstream, of course. regards Alan -- Alan Fitch Senior Consultant Doulos &#4294967295; Developing Design Know-how VHDL * Verilog * SystemVerilog * SystemC * PSL * Perl * Tcl/Tk * Project Services Doulos Ltd. Church Hatch, 22 Marketing Place, Ringwood, Hampshire, BH24 1AW, UK Tel: + 44 (0)1425 471223 Email: alan.fitch@doulos.com Fax: +44 (0)1425 471573 http://www.doulos.com ------------------------------------------------------------------------ This message may contain personal views which are not the views of Doulos, unless specifically stated.