![]() |
|
|
|
#1 |
|
Hello All,
I've a question with regards to conditional generates. I'm using a 'for generate' to interconnect an array of signals. I'm then using the index of this generate to set the connectivity of the array. The following is an example to demonstrate the problem (A complete example module is described below). It seems that 'Method One' should work, as x-1 is only used when x>0. However, Modelsim complains about the indexing being out of range. If, however, I use method Two, everything is OK. VectorNextLogic : for x in 0 to 7 generate begin -- Method One (doesn't work) dataVector(x) <= dIn(x) xor dataVector(7) when (x=0) else dIn(x) xor dataVector(x-1); -- Method Two (does work) BitConnect0 : if (x=0) generate begin dataVectorNext(x) <= dIn(x) xor dataVector(7); end generate; BitConnect1 : if (x>0) generate begin dataVectorNext(x) <= dIn(x) xor dataVector(x-1); end generate; end generate; I'm guessing that 'Method One' is not legal/valid VHDL, but would like to know for sure. Also, is 'method Two' the only available approach to this problem? It seems far more prone to error, and in the real module in which I need to do this, it would require a great deal more code. Any help/advice/comments much appreciated. Many Thanks Andy References: http://groups.google.co.uk/group/com...ee70d2b0aa9287 For Module: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Test is port ( clk : in std_logic; nReset : in std_logic; dIn : in std_logic_vector(7 downto 0); dOut : out std_logic_vector(7 downto 0)); end Test; architecture General of Test is signal dataVectorNext : std_logic_vector(7 downto 0); signal dataVector : std_logic_vector(7 downto 0); begin dOut <= dataVector; process (clk) begin if (clk'event and clk='1') then if (nReset='0') then dataVector <= (others => '0'); else dataVector <= dataVectorNext; end if; end if; end process; VectorNextLogic : for x in 0 to 7 generate begin -- Method One (doesn't work) dataVector(x) <= dIn(x) xor dataVector(7) when (x=0) else dIn(x) xor dataVector(x-1); -- Method Two (does work) BitGen0 : if (x=0) generate begin dataVectorNext(x) <= dIn(x) xor dataVector(7); end generate; BitGen1 : if (x>0) generate begin dataVectorNext(x) <= dIn(x) xor dataVector(x-1); end generate; end generate; end General; Andy |
|
|
|
|
#2 |
|
Posts: n/a
|
Doesn't directly address the question about the generate but
-- Method Three (might work) dataVector(x) <= dIn(x) xor dataVector((x-1) mod KJ KJ |
|
|
|
#3 |
|
Posts: n/a
|
KJ wrote:
> Doesn't directly address the question about the generate but > > -- Method Three (might work) > dataVector(x) <= dIn(x) xor dataVector((x-1) mod > > KJ > KJ, Thanks for the pointer. That's a trick I've used before when working with arrays that wrap around. Very handy when doing things like cellular Automata. But in this case that doesn't happen. What interests me more is that, x-1 when x=0 should never need to be calculated, so an out of range 'should' never occur. Cheers Andy Andy |
|
|
|
#4 |
|
Posts: n/a
|
Andy wrote:
> -- Method One (doesn't work) > dataVector(x) <= dIn(x) xor dataVector(7) when (x=0) else > dIn(x) xor dataVector(x-1); Try this: http://home.comcast.net/~mike_treseler/no_gen.vhd -- Mike Treseler Mike Treseler |
|
|
|
#5 |
|
Posts: n/a
|
On Mon, 12 Jun 2006 20:51:01 +0100, Andy
<> wrote: > It seems that 'Method One' should >work, as x-1 is only used when x>0. However, Modelsim complains about >the indexing being out of range. If, however, I use method Two, >everything is OK. > >VectorNextLogic : for x in 0 to 7 generate >begin > > -- Method One (doesn't work) > dataVector(x) <= dIn(x) xor dataVector(7) when (x=0) else > dIn(x) xor dataVector(x-1); > > -- Method Two (does work) > BitConnect0 : if (x=0) generate > begin > dataVectorNext(x) <= dIn(x) xor dataVector(7); > end generate; > > BitConnect1 : if (x>0) generate > begin > dataVectorNext(x) <= dIn(x) xor dataVector(x-1); > end generate; > >end generate; I believe ModelSim is right here. The conditional signal assignment works not only with constants but also with any expression as the conditional, so "datavector(x-1)" is part of the overall expression; I know that (x=0) is a constant expression, but that's an optimisation issue. Effectively, one pass of your generate loop gets re-written as dataVector(0) <= dIn(0) xor dataVector(7) when (TRUE) else dIn(0) xor dataVector(-1); and the error is manifest long before anyone gets to deciding that the second branch is unused. I agree that your "Method 2" is tiresome; VHDL's lack of "else" on "if...generate" is pretty painful here. I guess the example you've posted is a simplified version of what you're really trying to do, so you need a reasonably robust fix. How about the following... G: for x in dataVector'range generate datavector(x) <= dIn(x) xor dataVector( index_shuffle(x) ); endgenerate; where "index_shuffle" is a function that takes the integer value x and returns the modified index you want. Now all the messy complexity can be pushed into the function. What's more, you can avoid any compiler warnings by declaring the function so that its return value is of type "dataVector'range", so the body of the generate statement cannot possibly have any out-of-range access. hth -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. Jonathan Bromley |
|
|
|
#6 |
|
Posts: n/a
|
Andy wrote:
> I've a question with regards to conditional generates. Jonathan has provided excellent answers, as usual, but I have another question for anyone interested. What is a possible upside to generating processes and wiring them up vs. using some array type and declaring some variables to be updated every clock in a single processs? So far, I have: 1. A generate could drive a tri-state pin interface. 2. ? The generate loop works and is very popular, but it is also very tedious on the edges and in the wiring. -- Mike Treseler Mike Treseler |
|
|
|
#7 |
|
Posts: n/a
|
On Tue, 13 Jun 2006 11:06:18 -0700, Mike Treseler
<> wrote: >What is a possible upside to generating processes >and wiring them up vs. using some array >type and declaring some variables to be >updated every clock in a single processs? > >So far, I have: > 1. A generate could drive a tri-state pin interface. And, in general, it's rather easier to control what drivers you're creating when using generate. Sometimes that matters. Most times, though, there's an easier way around it. I'm not as completely convinced as Mike of the virtues of big single-process designs - I was brought up on Occam and CSP, so my instinct is to decompose a design into blocks that communicate in a well-structured way - but for anything algorithmic, software-like processes are IMHO something that's worth striving for. > 2. ? My standard answer to that always used to be "because generates allow you to describe variable- sized structures, and allow you to declare the variable- sized interconnects between the parts of those structures". For Verilog, this would be completely true, I think. But in VHDL we have the delights of dynamically-elaborated subprograms - the variables in a function are manufactured only when the function is called - and this does pretty much everything you need for building funny-shaped hardware: trees, jagged arrays and the like. Any interconnect that gets unnecessarily declared will in due course be optimised away by synthesis. So my views on this are increasingly aligned with Mike's. However, you may well be confronted with existing design fragments that are structured as components or processes, and you need to create groupings of those things. In such a case, generate provides an easy way out. >The generate loop works and is very popular, >but it is also very tedious on the edges >and in the wiring. It's hard to disagree. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. Jonathan Bromley |
|
|
|
#8 |
|
Posts: n/a
|
Jonathan Bromley wrote:
> I was brought up on > Occam and CSP, so my instinct is to decompose > a design into blocks that communicate in a > well-structured way - You are ahead of your time. At some high level, communication becomes serial and very well-structured. It used to be cross-country. Buses like PCIe make it happen at a few centimeters. I have no doubt this will become a canned, on-chip "buffer" someday. > but for anything > algorithmic, software-like processes are IMHO > something that's worth striving for. That's a software-like thread describing *parallel* hardware. The point is to get the outputs I really want without mentioning every wire and mux involved. A vhdl process is a fantastic virtual machine with registers arranged and updated however I like. Synthesis maintains this illusion by unwinding procedures, arrays, and loops without complaint. Simulation lets me take a test drive before actual construction has even begun. > However, you may well be confronted with existing > design fragments that are structured as components > or processes, and you need to create groupings of > those things. In such a case, generate provides an > easy way out. That's a fine list item 2. There is plenty of working code around that I prefer to leave in the black box. Thanks for the reply. -- Mike Treseler Mike Treseler |
|
|
|
#9 |
|
Posts: n/a
|
"Mike Treseler" <> wrote in message news:... > Andy wrote: > > What is a possible upside to generating processes > and wiring them up vs. using some array > type and declaring some variables to be > updated every clock in a single processs? > > So far, I have: > > 1. A generate could drive a tri-state pin interface. > 2. ? > This is pretty much along the same lines as Jonathon's earlier reply, but generated processes would seem to fit in better when the 'other' things in the architecture don't fit into that single clocked process model (i.e. the 'other' things being components that need to be instantiated and combinatorial equations). One example that I've used several times is needing a bank of fifos for some purpose. Overall control of that bank tends to be in a clocked process but the actual read and write controls into the fifos tend to be combinatorial since they tend to involve combinatorial gating with the full/empty status bits out of the instantiated fifos. So you end up needing combinatorial equations to connect the process to the instantiated component so why not put all of that inside of the same single generate block instead of putting a single process with a for loop and the 'other' stuff inside the still needed anyway generate block? Then again, even your #1 item about tri-states is just another example of something that doesn't fit into the clocked process model. If the code for the architecture of the entity's required function does fit nicely into the single clocked process model though I agree with you that it is generally better to use the for loops inside the single process...although I might tend to break them up into several basically identical processes with loops, but that's just me. KJ KJ |
|
|
|
#10 |
|
Posts: n/a
|
On Tue, 13 Jun 2006 14:00:54 -0700, Mike Treseler
<> wrote: >Jonathan Bromley wrote: > >> I was brought up on >> Occam and CSP, so my instinct is to decompose >> a design into blocks that communicate in a >> well-structured way - > >You are ahead of your time. >At some high level, communication becomes >serial and very well-structured. It used >to be cross-country. Buses like >PCIe make it happen at a few centimeters. >I have no doubt this will become >a canned, on-chip "buffer" someday. Someday? How about Transputer Links, vintage 1975? Now that's an idea that was ahead of its time (and, in fairness, ahead of the technological capabilities that would have made it genuinely useful). Bromley's First Law of Technology Business asserts that any technology product is certain to fail in the marketplace if it meets the following three criteria: 1) It is technically competent and founded on valid theory. 2) It is ahead of its time by more than 2 years. 3) It is British in origin. SERDES I/Os on modern FPGAs do a nice job, but it would be good if they had a handshaking protocol layered on top of them so that you could use them easily for synchronisation. I'm sure lots of people do exactly that for themselves, already. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. Jonathan Bromley |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| BGP Conditional advertisement with Community attributes | qamar | General Help Related Topics | 0 | 09-15-2009 06:49 AM |
| subprocess.Popen generates defunct | Mswed | Software | 1 | 07-29-2008 03:57 PM |
| Sound Blaster Live Value generates a squeal and locks up for no apparent reason...why? | noobie win2k | A+ Certification | 1 | 01-09-2004 10:44 PM |