FPGARelated.com
Forums

More beginner's verilog questions

Started by Reza Naima December 19, 2005
Before I start replying to people, I was just wondering, how is it
possible such that I can assign a high-impedence state to an output
using the code I wrote?   Can I do it using the same number of inputs,
or do I have to add another input and implement it in this way..

always @(posedge clear)
    out[index] <= z

or something like that?

Jason -

Yep, this did the trick, and managed to piss me off at the same time.
I don't see how this code is logically any different from the code that
I posted!   Several people posted about hints and priorities for
coding, but in my reading, I never came across references to these
things.  Does anyone have any good pointers or references?

Ray -

Is it acceptible to use asynchronous code in fpga's/cpld's if you are
going to be working at very low speeds?  I'm not looking for a high
performance design, rather, a super-low-power deisgn that'll save me
pins on a microcontroller.   I just want the ability to program one of
32 outputs using a minimal set of microcontroller pins.

With regards to switch bouncing, as it'll be switched from a
microcontroller, I dont have to deal with debounce, right?

Finally, I'm not sure what the reset/startup up hazards are -- I'll do
some googling after I post this.  The reset I use is just to reset the
counter to zero.  Will this be problematic?


Andy -

Thanks for  the hint about the falling edge of the enable pin.  Can you
provide me with some some pointers as to why this behaviour is the way
it is - or a starting point when I'm going through the manual.

This behaviour makes no logical sense again, just as this notion of
having to fllow templates and priorities.  Is there any benefit for
such a strict structure?  If a reset is higher in priority, why doesn't
the compiler/synthesizer just take care of it.  Why not just give me a
warning rather than a hard error.

 I also checked my course schedule, and there are not classes called
Digital Electronic Design or anything like that.  What material would
such a course cover?  Also, the project can't wait.  If it can't be
done in a CPLD, we'll have to do it using either a larger
microcontroller or discrete multiplexers/counters.  We're building an
implantable wireless neural recording device to record and transmit
data from a 32 channel probe, and the key factors are size and power
consuption (in that order).  The entire device should be no bigger than
two quarters stacked on top of each other - which is why I wanted to go
with a CPLD rather than a large microcontroller or several discrete
components.  


Thanks everyone for your help so far!
Reza

Reza Naima wrote:
> Before I start replying to people, I was just wondering, how is it > possible such that I can assign a high-impedence state to an output > using the code I wrote? Can I do it using the same number of inputs, > or do I have to add another input and implement it in this way.. > > always @(posedge clear) > out[index] <= z > > or something like that?
I guess that depends on whether you're trying to tri-state an output pad from the FGPA itself or an internal node. Are you trying to create a tri-state bus WITHIN the FPGA? I've never tried to synthesize something like that but I guess you'd have to use the 'z' constant. Never tried it. If you're tristating an output I'd expect a tri-state enable connection to the pad itself. That will be much more tool specific.
> Yep, this did the trick, and managed to piss me off at the same time. > I don't see how this code is logically any different from the code that > I posted! Several people posted about hints and priorities for > coding, but in my reading, I never came across references to these > things. Does anyone have any good pointers or references? >
Well, synthesis tools usually infer priority to if-else constructs. Now, you can argue that with a single condition to the 'if-else' that neither block has higher priority. But with nested trees of if-else's there is a definite priority. So the synthesizer has to map the code to cells existing in the FPGA. With an asynchronous reset to a FF it's really a level sensitive input. Anytime that the reset is asserted the output should be driven to the reset state. Might not seem like a level sensitive input, but it is. If 'posedge clk' occurs it should not be able to set the outputs, hence the highest priority portion of the 'if' structure is the comparision against the asynchronous reset. But the way that you had it written it had the non-reset case as the highest priority in the if-else statement. I've argued in the past with people that there is NO priority for a simple two segment if-else since there is no nesting of branches, but it's kinda semantic.
> This behaviour makes no logical sense again, just as this notion of > having to fllow templates and priorities. Is there any benefit for > such a strict structure? If a reset is higher in priority, why doesn't > the compiler/synthesizer just take care of it. Why not just give me a > warning rather than a hard error.
One of the issues is that you're not creating new base cells. Just mapping to existing ones. As for the 'template' type aspect, it's a matter of strict logical correctness. If it can't map the behaviour that you've specified to an existing cell, what else can it do? Also, don't forget that someone had to code the synthesizer :->
Ray Andraka wrote:
> Asynchronous logic does not belong in FPGAs. They are not designed > for it and the tools don't support it (especially static timing > analysis).
I recently needed a data path with a 56-bit adder/subtractor with binary and BCD modes. I thought I might have to pipeline it, but was pleasantly surprised that the Xilinx tools did a very good job with it as purely combinatorial logic. The inputs come from a mux from one of five registers or a few other sources, and the outputs can be loaded into any of four registers. As an additional complication, the arithmetic operation may be performed on any subrange of four-bit digits of the 56-bit word, which means that there is a 14:1 mux for carry out, and 2:1 muxes in the carry of each digit. I designed a four-bit slice using three ripple-carry adders: one to generate the one's or nine's complement of the subtrahend, one for the binary addition, and one for the for the BCD correction of the result. For each digit, I use two of those slices, one with the carry-in tied high, and one with it tied low. The carry outs of those act as the generate and propogate outputs for a carry lookahead scheme. And the data outputs feed a multiplexer selected by the carry-in computed by the lookahead carry logic, so they act as carry-select adders. When I set the mapper to use timing-directed mapping, and the PAR to high effort, ISE 8.1i was able to reduce it to ten levels of logic (including the input muxing), and static timing analysis says it will run with under 20 ns clock cycle in an XC3S1000-4 (the slower speed grade). I was not expecting the tools to be able to optimize it this well, especially as synthesis translated the carry-lookahead code, which I'd carefully written describing very flat logic, into a thirteen-deep tree. But apparently the mapper and PAR were smart enough to flatten it again. The static timing analysis had to analyze an immense number of paths. But I don't have any feedback loops in the logic, so I guess analysis of it isn't particularly difficult, just a large combinatorial problem. A pipelined design would probably achieve better throughput, but worse latency, and for my purposes latency was important. I'm not very experienced with complex data path and arithmetic design, so perhaps there are more efficient ways to implement a binary/BCD add/subtract slice, but even so I don't expect that it's possible to reduce the number of levels of logic of the purely combinatorial approach much.
I'm trying to get a tri-state output  ([31:0] out).  Any idea how to
implement it?

Thnx,
Reza

> I guess that depends on whether you're trying to tri-state an output pad from the FGPA itself or > an internal node. Are you trying to create a tri-state bus WITHIN the FPGA? I've never tried to > synthesize something like that but I guess you'd have to use the 'z' constant. Never tried it. > > If you're tristating an output I'd expect a tri-state enable connection to the pad itself. That > will be much more tool specific. >
Reza -

I suggest you do some studying on your own rather than asking this
group to design your circuit.

On your tri-state question, try Google "verilog tristate", then do some
reading.

John Providenza

John,

I'm just trying to use the usenet as a resource to learn.  In reading
other sources, it seems that I could output a 'z' in order to achieve a
tri-state -- however, as I've found out, there is a lot of strange
behaviour in actually going from verilog syntax to application and
implementation.  I wanted to see if there were any gotcha's in this
approach.  I also wanted to know if it was possible for a physical
input to read 'z' if I configure the microcontroller's pin as an input
(putting it in tri-state), or if I would have to add another pin (say,
enable_Z) to specify when I want the output to be equal to 'z'.  I'm
also not sure about the implementation differences - say, between
xilinx and altera, and if one supports a certain mode of opperation
that the other does not.

I'll do some more googling on verilog and tristate, however, I also
find that there are people willing to help answer questions, which I
greatly appreciate.  I'm not asking anyone to design my circuit -
though people have helped with some of the debugging issues which has
been invaluable.

Another aspect of my questions is trying to understand the strange
behaviour.  I still don't see why the synthesizer has a problem
equating these two constructs :

If A do a else do b
If !A do b else do a

they seem identical to me, and I'll have to do some more research and
re-read some of the replies to this thread to try to figure it out.

In any case, thanks,
Reza

Both Altera and Xilinx give the ability to look at the RTL schematic which 
will show you what the synthesizer did with your code.  I don't know if the 
free versions give you this ability????

Your question about whether or not your microprocessor can read a 'z' 
clearly tells us that you're not an engineer working in industry.

"Reza Naima" <google@reza.net> wrote in message 
news:1135219926.957661.32390@g47g2000cwa.googlegroups.com...
> John, > > I'm just trying to use the usenet as a resource to learn. In reading > other sources, it seems that I could output a 'z' in order to achieve a > tri-state -- however, as I've found out, there is a lot of strange > behaviour in actually going from verilog syntax to application and > implementation. I wanted to see if there were any gotcha's in this > approach. I also wanted to know if it was possible for a physical > input to read 'z' if I configure the microcontroller's pin as an input > (putting it in tri-state), or if I would have to add another pin (say, > enable_Z) to specify when I want the output to be equal to 'z'. I'm > also not sure about the implementation differences - say, between > xilinx and altera, and if one supports a certain mode of opperation > that the other does not. > > I'll do some more googling on verilog and tristate, however, I also > find that there are people willing to help answer questions, which I > greatly appreciate. I'm not asking anyone to design my circuit - > though people have helped with some of the debugging issues which has > been invaluable. > > Another aspect of my questions is trying to understand the strange > behaviour. I still don't see why the synthesizer has a problem > equating these two constructs : > > If A do a else do b > If !A do b else do a > > they seem identical to me, and I'll have to do some more research and > re-read some of the replies to this thread to try to figure it out. > > In any case, thanks, > Reza >
Reza Naima wrote:

> Before I start replying to people, I was just wondering, how is it > possible such that I can assign a high-impedence state to an output > using the code I wrote? Can I do it using the same number of inputs, > or do I have to add another input and implement it in this way.. > > always @(posedge clear) > out[index] <= z > > or something like that? > > Jason - > > Yep, this did the trick, and managed to piss me off at the same time. > I don't see how this code is logically any different from the code that > I posted! Several people posted about hints and priorities for > coding, but in my reading, I never came across references to these > things. Does anyone have any good pointers or references? > > Ray - > > Is it acceptible to use asynchronous code in fpga's/cpld's if you are > going to be working at very low speeds? I'm not looking for a high > performance design, rather, a super-low-power deisgn that'll save me > pins on a microcontroller. I just want the ability to program one of > 32 outputs using a minimal set of microcontroller pins. > > With regards to switch bouncing, as it'll be switched from a > microcontroller, I dont have to deal with debounce, right? > > Finally, I'm not sure what the reset/startup up hazards are -- I'll do > some googling after I post this. The reset I use is just to reset the > counter to zero. Will this be problematic? > >
Generally, you should avoid async logic. By using it, you are making your job a lot harder, and substantially increasing the risk of making a grave design error that may not show up until the device is fielded. Yes, asynchronous designs are possible in FPGAs and CPLDs, but it takes a considerable amount of additional design evaluation and verification effort to make sure you did it right. Often times, it also involves hand routing to maintain control of the path delays, and it certainly includes timing analysis by hand because the static timing tools are not suited to async circuit evaluation. I would certainly strongly discourage someone who is having trouble understanding the advantages of a synchronous design taking an asynchronous approach to the design. The issue is not the speed of the design, it is the numerous hazards present in an async design that are eliminated by synchronous design techniques. The fact that the wires connecting the elements have delay in an FPGA and that delay varies significantly for each routing solution makes the analysis of an async design in an FPGA extremely tedious, error prone, and difficult. As soon as you have to make a modification to the design, you basically have to start over on the analysis. If you don't have time to learn how to do a basic synchronous design, you don't have the time to do the async design properly either. The reset/start up hazards in a synchronous design with async reset is that unless the release of reset is done synchronously, you can't guarantee that all affected logic is going to see the release of reset on the same clock cycle, so it can wind up leaving the reset state in an unknown condition. Your reset to zero is OK as long as you can guarantee all of the counter flip-flops will not be clocked until the set-up times to all the flip-flops have been satisfied. Finally, an FPGA or CPLD is generally NOT suitable for an implantable device. Even the static current greatly exceeds the current draw needed for a reasonable battery life, regardless of what the dynamic currents are in your design. The FPGA or CPLD is fine for a prototype, but not for the actual implant. Finally, if speed is not a consideration and power is, there is no reason you can't make the design synchronous and slow the clock down to the minimum clock you need. A 32KHz digital watch crystal will provide a dynamic power that is barely detectable over the static ICC in most FPGAs and CPLDs. Also, the power savings for an async design in and FPGA is largely a mirage. By using synchronous techniques you take advantage of purpose built structures in the FPGA such as the optimized clock tree and fast logic for carry chains, and other arithmetic. Async logic often has to use LUT resources and general purpose routing instead, and because the routing is actually a network of powered switches, the power dissipation is quite a bit higher than you might expect. Also, there have been papers showing that a heavily pipelined (ie very little logic between flip-flops) design shows significant power reductions (on the order of 20-30%) over the same design with fewer pipeline stages. The difference is the flip-flops stop the propagation of glitches, which in turn dissipates a significant amount of power not only in the logic but also in the active routing resources. I strongly encourage you to take a bit of time to learn synchronous design. I'd pick up a basic logic text such as Morris Mano and start reading up on synchronous logic.
Rob,

I never asked if a microprocessor could read a 'z', I asked if a CPLD
could determine if an input was floating or not - though I doubt it
could.  And as I've stated, I'm a graduate student, so I'm obviously
not working in industry.  I take it you like to skim.

I found the RTL schematic viewer - though I sitll am not sure what RTL
stands for.   

Reza

Ray,

Thanks for the excellent advice and help.  A few comments/responses.

- The implant is actually inductivly powered through the skin and there
is no battery.  For the xlinix chips I was looking at, quiesent power
consuption was under 30uA which is perfectly fine.  We're looking at
having about 50-100mA @ 3.3v available to use for all components (amp,
a2d, uC, cpld, telemetry system).

- The async verilog code will only be run once every few days, and will
be controlled from a microcontroller that I can tweak to guarantee
sufficient time between each state change.  I do have a clock available
that I could feed into it to make it a synchronous design - but I'll go
for the async first to see if I can get it to work.

- I'll look into finding a copy of Morris Mano's book.

Thanks,
Reza

p.s. I've added some extra code (see below) that is synthesized just
fine on one of the xilinx CPLDs, but gives errors if I configure it for
another CPLD types.  It says it can't find a matching template for the
other cpld architectures.   I also found that I had to do the posedge
and negedge explicitly.  I thought that if I left that out, any state
change for the signal would initiate the block.

	/* cs toggler - cs goes high for one clock cycle every 17 clk_in
cycles */
	always @(posedge clk_in or negedge clk_in) begin
		sck = !sck;
		spi_counter <= spi_counter + 1;
		if (spi_counter == 16)
			cs <= 1;
		if (spi_counter == 17) begin
			cs <= 0;
			spi_counter <= 0;
		end
	end