How do you implement multiple DDR2 MIG cores in a single design? I guess the first question is how do you implement and integrate a single MIG core? I have been using the Core Generator from within ISE to add cores to my design. A MIG core is added by creating the core from within ISE which also automatically adds the generated xco file to the project. What does this mean for a MIG core? Let's assume you've named the core mig_a. A MIG core is open source - it creates all the sources under the folder
ipcore_dir/mig_a/user_design/rtl
or
ipcore_dir/mig_a/example_design/rtl
When you compile your project with the mig_a.xco file in your project, then it's just like you've added all of the rtl sources manually. This will enable you to instantiate the module mig_a.
Remember that you must take the UCF constraints as created in
ipcore_dir/mig_a/user_design/par/mig_a.ucf
and copy them over to your main UCF file.
In order to implement two DDR2 cores you would create mig_a.xco and mig_b.xco. The first issue you run into is with conflicting UCF constraints due to both mig_a and mig_b using identically named constraints. This is easy to solve, and shouldn't cause too much of a headache. If someone knows of a better way to do this I'd love a comment explaining.
The next issue is conflicting source component names. Here's the simple trick to solve those. DON'T USE THE XCO FILES! The DDR2 cores' source files are identical! The only difference in them are the parameters used at the top level instantiation file. Insert the files
ipcore_dir/mig_a/user_design/rtl/*.v and
ipcore_dir/mig_b/user_design/rtl/mig_b.v.
The final issue is the conflicting IODELAY_GRP name which by default in MIG's cores is set as "IODELAY_MIG." This should be changed in mig_a.v or mig_b.v but preferably in both for clarity's sake so that they don't conflict with each other. Use names like "IODELAY_MIG_A" and "IODELAY_MIG_B."
This solves all the conflicting component issues. You can now freely update your cores from MIG 3.0 to 3.1 without having to manually modify any files. You are using the Xilinx created files just as they are and without any ugly conflicts.
bye
Monday, June 29, 2009
Sunday, June 21, 2009
multi-dimensional array ports and variable bit selects
As a software programmer who moved to VHDL and then to Verilog, I have always found Verilog's language limitations to be very frustrating. One of my biggest complaints is Verilog's inability to use multi-dimensional arrays in port declarations.
For example:
module test(
input reg [7:0] a [2:0]
);
is illegal in Verilog. The only way to do this is:
module test(
input reg [23:0] a
);
What I had previously found myself doing was declaring the port level array as flat, and then converting it inside a standard generate block to the originally intended multi-dimensional array.
This is much clunkier than necessary. Variable bit-selects in Verilog allow for a much easier design. You can easily access the bits you require with this:
always @(posedge clk) begin : indexing process
integer i, index, found;
found = 0;
for(i = 0; i < 3; i = i + 1) begin
if(!found) begin
if(get_this_index[i]) begin
index = i;
found = 1;
end
end
end
if(found) begin
my_data <= a[index * 8+:8];
// my_data <= a_non_flat[index];
end
end
*** Note the +: notation. The first value is the start bit in the array, and the second value is the number of bits going up the array ( -: would go down the array). This shouldn't be confused with normal x:y notation. This is what makes pulling the correct bits out so easy.
This easily allows for parameterized modules with both compile-time bit widths and compile-time number of elements. The lack of multi-dimensional ports is made up for by variable bit selects. Of course you do need to remember the size of each "index" of data otherwise you'll be accessing the wrong bits...
Be enlightened,
For example:
module test(
input reg [7:0] a [2:0]
);
is illegal in Verilog. The only way to do this is:
module test(
input reg [23:0] a
);
What I had previously found myself doing was declaring the port level array as flat, and then converting it inside a standard generate block to the originally intended multi-dimensional array.
This is much clunkier than necessary. Variable bit-selects in Verilog allow for a much easier design. You can easily access the bits you require with this:
always @(posedge clk) begin : indexing process
integer i, index, found;
found = 0;
for(i = 0; i < 3; i = i + 1) begin
if(!found) begin
if(get_this_index[i]) begin
index = i;
found = 1;
end
end
end
if(found) begin
my_data <= a[index * 8+:8];
// my_data <= a_non_flat[index];
end
end
*** Note the +: notation. The first value is the start bit in the array, and the second value is the number of bits going up the array ( -: would go down the array). This shouldn't be confused with normal x:y notation. This is what makes pulling the correct bits out so easy.
This easily allows for parameterized modules with both compile-time bit widths and compile-time number of elements. The lack of multi-dimensional ports is made up for by variable bit selects. Of course you do need to remember the size of each "index" of data otherwise you'll be accessing the wrong bits...
Be enlightened,
Thursday, June 11, 2009
ISE internal infrastructure - does it exist?
I've been using ISE 11.1 for a couple months now and I must say that it makes me cringe when I think about the code that created this monster.
The good - Everything done outside of ISE. I have noticed that the tools which are the backend of ISE and everything they do are very reliable. At least from all of my experience. I'm guessing this is because they are pretty simple single threaded programs who know how to do the work they were built to do.
The bad - ISE. I am very sympathetic to the pains of writing a GUI which has to synchronize all sorts of other tasks. I know this is a very difficult task. You never know when the user will click something or when he might stop a process. ISE has to keep track of temporary files, source file changes, statuses and lots of other things. It's clear that the job is not easy. On the other hand Xilinx is a huge company and has the resources and responsibility to provide its users with a much better product.
In my experience ISE has many stability issues and quirks. I have learned to take them in stride. What I find shocking is that these bugs come from a very bad low-level infrastructure in the program, and not just a random assortment of small mistakes. (This is a huge assumption, but it is based both on my extensive experience with software and multithreaded applications, and on my experience with ISE.)
Example: When you change your source files in an external editor you see that ISE processes those changes only once you change focus back to ISE. Why??? That must be the strangest thing ever. It can actually take ISE seconds (why so long???) before it updates it's statuses - and you can see that in the ISE Processes window. If you click Generate Bitstream, or Synthesize before it has processed and updates its status then it will be ignored ostensibly because the files are up-to-date. This strikes me as an extraordinarily bad way to update internal ISE project status. Once a file is changed ISE should immediately process that and mark that file and all subsequent files as out-of-date.
Hoping for better with ISE 11.2 but seriously doubting it
The good - Everything done outside of ISE. I have noticed that the tools which are the backend of ISE and everything they do are very reliable. At least from all of my experience. I'm guessing this is because they are pretty simple single threaded programs who know how to do the work they were built to do.
The bad - ISE. I am very sympathetic to the pains of writing a GUI which has to synchronize all sorts of other tasks. I know this is a very difficult task. You never know when the user will click something or when he might stop a process. ISE has to keep track of temporary files, source file changes, statuses and lots of other things. It's clear that the job is not easy. On the other hand Xilinx is a huge company and has the resources and responsibility to provide its users with a much better product.
In my experience ISE has many stability issues and quirks. I have learned to take them in stride. What I find shocking is that these bugs come from a very bad low-level infrastructure in the program, and not just a random assortment of small mistakes. (This is a huge assumption, but it is based both on my extensive experience with software and multithreaded applications, and on my experience with ISE.)
Example: When you change your source files in an external editor you see that ISE processes those changes only once you change focus back to ISE. Why??? That must be the strangest thing ever. It can actually take ISE seconds (why so long???) before it updates it's statuses - and you can see that in the ISE Processes window. If you click Generate Bitstream, or Synthesize before it has processed and updates its status then it will be ignored ostensibly because the files are up-to-date. This strikes me as an extraordinarily bad way to update internal ISE project status. Once a file is changed ISE should immediately process that and mark that file and all subsequent files as out-of-date.
Hoping for better with ISE 11.2 but seriously doubting it
Friday, May 29, 2009
Chipscope - pleasantly surprised
I have been using Chipscope since I started working with Xilinx FPGAs a few months back. At first I was very disappointed by it's inability to detect custom types and state machines. I think it would be nice if they could find a way of adding this feature, but all in all I have become very satisfied with it's performance and abilities.
Caveat: If you change the signals from Inserter then it's worthwhile creating a new Analyzer project instead of letting Chipscope detect and try to deal with the changes. That has never worked well for me.
Chipscope is Xilinx's attempt to build a true logic analyzer. They avoided trying to delve too deep into what your project was about (ie they don't learn custom types or even buses), and instead they work generically with the project and this allows Chipscope to be very stable.
The analyzer allows you to import the signal names from the Inserter project. The names could've been inserted automatically but that would have required some form of matching scheme to know that the FPGA is compiled with specific signal information.
Background comparison of alternate FPGA logic analyzer:
Lattice's Reveal:
Reveal allows you to do the same basic things as chipscope. One main difference is that Reveal will learn the types you are adding in it's inserter, and it's analyzer will automatically detect those types and states. This allows Reveal's analyzer to automatically build buses, and support state machines, and even show state names in the logic window. There are numerous disadvantages to this scheme. Reveal doesn't support all types of signals. For example integers, and custom types other than state machines aren't supported from what I've seen. Those signals are kept grey within the Inserter program. Another major issue is that Reveal needs to use some form of matching scheme between the compiled core and the inserter project used to create it. If Reveal detects that there isn't a match then it won't open the core for analysis at all. This can easily happen if I add a single signal to the end of the data list and then I want to analyze both the new compiled FPGA and the old one. The old compiled FPGA will no longer be able to be analyzed without the old Reveal project files which match it.
Back to Xilinx:
Chipscope allows you to add every signal that exists in the design, regardless of how it is created. It is listed in XST format so that multi-dimensional buses become signal_0_0 and signal_0_1 and so on. At least this way I can add them, and I can create the buses properly within Chipscope Analyzer. Regarding bus-creation I find that Chipscope 11.1 has a huge advantage over previous versions with it's Auto Create Buses option. It builds buses based on their names. If it builds it incorrectly then of course the bus can be recreated properly, but I have yet to see it build a bus incorrectly. It doesn't yet manage to build bus arrays so build them myself. The biggest set-back is it's lack of support for simple state machine's, but Chipscope does have a good way of working around this. You need to use token files. If you give your state machine's set values for their states then you can use a token file to tell the Analyzer what each state's value means, and to display it with the token (ie name) in the logic window.
Chipscope has all the basic support like many other analyzers, plus some nice advanced ones. It supports multiple analysis cores, multiple match units, triggers, sequencers, counters, and many other functions. Although what makes it stand out beyond Lattice's Reveal is it's ability to store information based on a match unit, and display it only after a distant trigger. This is a very useful function. I have just recently used this to great success in debugging what turns out to be an XST compiler issue (that's discussed in my post about for-loop and exit support). I triggered 65000 clocks in the future but still had the information I needed to debug the issue.
Nice job Chipscope team - keep up the great work!
Caveat: If you change the signals from Inserter then it's worthwhile creating a new Analyzer project instead of letting Chipscope detect and try to deal with the changes. That has never worked well for me.
Chipscope is Xilinx's attempt to build a true logic analyzer. They avoided trying to delve too deep into what your project was about (ie they don't learn custom types or even buses), and instead they work generically with the project and this allows Chipscope to be very stable.
The analyzer allows you to import the signal names from the Inserter project. The names could've been inserted automatically but that would have required some form of matching scheme to know that the FPGA is compiled with specific signal information.
Background comparison of alternate FPGA logic analyzer:
Lattice's Reveal:
Reveal allows you to do the same basic things as chipscope. One main difference is that Reveal will learn the types you are adding in it's inserter, and it's analyzer will automatically detect those types and states. This allows Reveal's analyzer to automatically build buses, and support state machines, and even show state names in the logic window. There are numerous disadvantages to this scheme. Reveal doesn't support all types of signals. For example integers, and custom types other than state machines aren't supported from what I've seen. Those signals are kept grey within the Inserter program. Another major issue is that Reveal needs to use some form of matching scheme between the compiled core and the inserter project used to create it. If Reveal detects that there isn't a match then it won't open the core for analysis at all. This can easily happen if I add a single signal to the end of the data list and then I want to analyze both the new compiled FPGA and the old one. The old compiled FPGA will no longer be able to be analyzed without the old Reveal project files which match it.
Back to Xilinx:
Chipscope allows you to add every signal that exists in the design, regardless of how it is created. It is listed in XST format so that multi-dimensional buses become signal_0_0 and signal_0_1 and so on. At least this way I can add them, and I can create the buses properly within Chipscope Analyzer. Regarding bus-creation I find that Chipscope 11.1 has a huge advantage over previous versions with it's Auto Create Buses option. It builds buses based on their names. If it builds it incorrectly then of course the bus can be recreated properly, but I have yet to see it build a bus incorrectly. It doesn't yet manage to build bus arrays so build them myself. The biggest set-back is it's lack of support for simple state machine's, but Chipscope does have a good way of working around this. You need to use token files. If you give your state machine's set values for their states then you can use a token file to tell the Analyzer what each state's value means, and to display it with the token (ie name) in the logic window.
Chipscope has all the basic support like many other analyzers, plus some nice advanced ones. It supports multiple analysis cores, multiple match units, triggers, sequencers, counters, and many other functions. Although what makes it stand out beyond Lattice's Reveal is it's ability to store information based on a match unit, and display it only after a distant trigger. This is a very useful function. I have just recently used this to great success in debugging what turns out to be an XST compiler issue (that's discussed in my post about for-loop and exit support). I triggered 65000 clocks in the future but still had the information I needed to debug the issue.
Nice job Chipscope team - keep up the great work!
ISE 11.1 stability issues
I have been using ISE 11.1 for about a month now. There are numerous stability issues from crashes and freezes to messages no longer being updated in the Design Report view. I find that running Rerun All is always a crap shoot as it brings ISE down much of the time. I have gotten coregen to freeze on occasion when invoking it within the ISE project. ISE's tracking of source file states and build states is hit or miss. Sometimes it decides that Synthesis isn't up to date, but shockingly Map and P&R are. I change source files and it's completely unwilling to restart the process of compilation. This requires the infamous Rerun or Rerun All commands. Then it has those times when the compilation just won't work unless you "Cleanup Project Files" and then try again. I know that there are lots of temporary files being used during FPGA synthesis, and plenty of intermediate files created, but is it so difficult to check the state of the source files and if one has been updated recently to set build state back to zero?
These issues only strengthen the argument against ISE keeping an open handle to its configured external editor. See my post on problems when using an external editor from ISE.
Seems to me that Xilinx needs their GUI team updated.
These issues only strengthen the argument against ISE keeping an open handle to its configured external editor. See my post on problems when using an external editor from ISE.
Seems to me that Xilinx needs their GUI team updated.
Xilinx XST for loop and disable keyword support
Xilinx once again fails bady when it comes to quality of tool issues. Recently I converted my PCI Express block from static to parametrized. This required lots arrays and multi-dimensional arrays, lots of parameters, and plenty of assign statements to take arrays out of and into modules (since module ports don't support multi-dimensional arrays). I implemented plenty of generate statements for conditional instantiation of FIFOs and also for loops for conditional processing of blocks.
The language specific way of breaking out of loops in Verilog is by using the "disable" statement. Sadly XST 11.1 doesn't support the disable statement from within a "for loop". The recommended workaround as shown in AR #22177 is to increment the "for loop" iterator to it's exit value. This works some of the time, and doesn't work other times. I stronly recommend against doing this as it clear to me that support for exiting a for loop early is shaky at best. I found that using a while statement with manual iteration worked better. I set the iterator to the exit value and it actually exited the loop properly.
Hoping that your experience is better than mine,
The language specific way of breaking out of loops in Verilog is by using the "disable" statement. Sadly XST 11.1 doesn't support the disable statement from within a "for loop". The recommended workaround as shown in AR #22177 is to increment the "for loop" iterator to it's exit value. This works some of the time, and doesn't work other times. I stronly recommend against doing this as it clear to me that support for exiting a for loop early is shaky at best. I found that using a while statement with manual iteration worked better. I set the iterator to the exit value and it actually exited the loop properly.
Hoping that your experience is better than mine,
Saturday, May 16, 2009
Xilinx ISE using an external editor (not a good idea)
I like to use GViM for editing files in Windows. Given that ISE supports using an external editor I immediately went about setting it to use my preferred editor. What I discovered with ISE 10.1 was that ISE keeps an open handle to the editor when editing files. This is stupid! The issue is very problematic because ISE has a tendency to crash, and with an open handle to the editor, it brings the editor down with it (at least with gvim.exe). ISE 11.1 was recently released and sadly it has the same issue. The CR (Change Request) I got filed with Xilinx to fix it will only be done with ISE 12.1. What I do for now is open gvim outside of ISE, and then double clicks in ISE will open in the same gvim that I'm using without having that handle connecting gvim's existence with that of ISE.
ISE crashes - gvim lives :)
This relates to my post about ISE stability issues.
ISE crashes - gvim lives :)
This relates to my post about ISE stability issues.
Subscribe to:
Posts (Atom)