07-31-2015 01:26 PM
So I tend to use the pattern below quite alot.
However I also Hate it.... There are alot of problems with the pattern:
- If i change the Enum the Registers are not changed with it.
- If i change the register cluster the enum does not change with it.
- The Case and the selected Cluster element do not necessarly have to match.
- Basically changes do not propigate well
- It takes alot of time to make sure ENUM matches Cluster Element
- Alot of duplicated code / most of it is the same except selected cluster element changes.
It, however allows me to programmitcally select / read write to the register on the labview FPGA. I have some of these with ALOT of cases.
I have A vi that produces register cluster's like the one above. One for each channel on my testing device. I cycle between channels when reading input's (they are muxed)
IS THERE A BETTER WAY?
Thanks for listening!
08-01-2015 10:55 PM
I don't know too much about your application, but perhaps you can use memory items.
http://zone.ni.com/reference/en-XX/help/371599K-01/lvfpgaconcepts/fpga_memory_items/
Instead of having X registers, you can have one memory item where your "enum" input is replaced by an address. If there is a reason you cannot use memory addresse please tell us why and we can try to offer up alternatives.
08-02-2015 10:01 AM
You could do something like this:
1. Place 4 Register 'Read' methods in vertical way (each method is associated with different register of course)
2. Combine 4 registers using "Build Array" to make a numeric array of 4 elements
3. Connect the array to the "Replace Array Subset". Connect index to your enum. Connect your value to the new element input.
4. Wire the output of 'Replace Array Subset' to index array primitive with 4 outputs
5. Place 4 Register 'Write' methods in vertical way, and connect each wire from 'index array' to each of them.
hope it helps
08-02-2015 10:54 AM
I had a clever idea, but at the last step, it failed. I'm hoping the failure is because I don't have the Viwiths that define Register 1, Register 2, etc. What I did was build a Get-Set Register Action Engine, driven by the Enum (I renamed the cases Register 1, Register 2, ...). You run the Set Registers first, which builds an array of Registers and saves it internally. When you want a Register, you call this VI with the default Get Register Action (if it's the default, you don't need to even wire it), give it the Register Enum you want, and it gives you (from its internal Array) the Register you requested. The only thing I couldn't do was to create the Register Out indicator -- Create Indicator was greyed out. Here's the code ...
When you change the Register ID Enum, you'll need to come to this sub-VI and edit it to add the matching Registers, but you only do this when you change the Enum. Since this includes a Case Statement wired to Register ID, changing the number if Enum cases will automatically "break" this VI, so you'll need to edit it anyway to include the extra Enum cases, so it shouldn't be a big pain to also include the new Register specification.
BS
08-02-2015 04:41 PM - edited 08-02-2015 04:42 PM
@Jacobson
Yes that would be a nice thing to do. However its not quite the same when it comes to arbitrating reads and writes. If you arbitrate an array only one item can access it at a time. but by using registers. I can read often and update values without the added race conditions.
08-02-2015 04:51 PM
Not all FPGA targets support an Array of register items.... at least the 7046R daq doesnt. 😞