04-06-2012 10:06 PM
I am using xilinx ISE 13.2 for the synthesis and implementation of my design. I wanted to create RPM of some logic in it, and then instantiate it multiple times so that I know the timings of my design. But I cannot find any proper documentation of RPMs so here are my queries:
1- How do we make RPMs in xilinx? Using PlanAhead or using FPGA editor? There were some guides I found which pointed to some options in floorplanner, but I couldn't see those options in my version of xilinx like (write RPM to UCF).
2- If there's any proper guide, can somebody kindly forward me to that.
3- And I did my own placement for a small design having a BRAM, one FF on the write side of BRAM and one FF on the read side of BRAM. But whenever I re-ran the implementation process, it always changed the mapping even when I changed the properties of components to fixed. And I thought maybe this is how we make RPMs, but I couldn't save it either to be used for other designs.
I shall be thankful to you for that.
04-09-2012 02:39 PM
You'll want to read the RLOC section of the constraints guide:
This appnote covers some other issues that aren't well documented. I wrote it ten years ago using a Virtex-II example, but all of the RPM information is still relevant:
There is a problem with slice based RPMs in that they need to be placed with the origin in the correct slice type to maintain the intended relative slice positions. Automatic placement will only handle this correctly if the variable XIL_PAR_ALIGN_USER_RPMS is set and the macro is constructed around the lower left most slice of a slice tile. See the above appnote for more information about macro origins.
Use FPGA Editor to examine the resulting macros. The list window can be set to "User Defined Macros" and then you can select them from the list to hilight them.
04-11-2012 11:29 PM
I followed the guide and well I managed to place RLOC constraints in verilog for single bit FFs. for example:
(* RLOC_GRID = "GRID" *) // declaring once before module instantiation.
(* RLOC = "X3Y4" *)
and similarly placing on other FFs as well.
The problem is that I can't place RLOC constraints on buses. like
reg [3:0] sample_bus;
XST simply ignores it and maps the components as it likes.
Can you kindly tell me what i might be doing wrong or how can I place RLOC constraints on buses ?
04-12-2012 12:47 AM
And I forgot to mention, my targeted device is spartan3 xc3s4000.
04-12-2012 10:08 AM
That should be "RPM_GRID" not "RLOC_GRID" but that wouldn't make a difference in the macro creation, it only changes how the coordinates are interpreted. I'm not sure why your RLOC constraints aren't getting passed to the FF instances as that's more of a synthesis issue than an implementation issue. You can always use UCF constraints to correct that. Keep in mind that the RLOCs have to be in the same hierarchy block for the default set to be created. If they're not, you need to also apply U_SET constraints. You don't need to use RPM grid if the macro only contains slice logic. See the appnote I referenced earlier for a discussion of that topic.
04-12-2012 10:02 PM - edited 04-13-2012 08:08 AM
I wrote "RLOC_GRID" by mistake, it's "RPM_GRID" but it doesn't matter anyway. And well i couldn't make it work in the verilog file like
(* RLOC = " X3Y4" *)
reg [1:0] sample_reg;
So, I instantiated the DFF macro provided by xilinx and passed it the indidiual bits, and also I switched to ucf for application of RLOC, so yeah that way i have been successful so far. But still BRAM cannot be added to RPM and the following info msg is displayed
Map:91 - aes_sbox symbol "sbox" has an RLOC attribute but the attribute will be ignored because the hierarchy contains no symbols with RLOC attributes.
So, now two issues are at hand,
1- BRAMs are not accepting RLOC.
2- When I instantiate the RPM in the TOP module, the mapping is all random and nothing like I saw in RPM Fpga Editor's window. I don't know where the problem is.
Another thing I was thinking was that in older versions of xilinx ISE 9.1, we used to make RPM and then instantiate the module in larger module and that whole process used to happen before PAR, and we used to write RPM to UCF and generate a new ngc file, so we had ngc file containing RPM info.
Whereas in Xilinx 13.2, everything happens in PAR, which file contains the RPM info?
04-13-2012 09:17 AM - edited 04-13-2012 09:20 AM
It sounds like the BRAM and FF are not in the same hierarchy and so not in the same RPM set by default. You either need to tie them together with RLOCs (x0y0 if you want no additional offset) on the upper hierarchy levels, to the point where they have a common root, or you need to explicitly define the set with U_SET properties.
If the relative placement of the RPMs components doesn't look correct, that's probably because the RPM wasn't placed in the correct site location. See above where I mention the XIL_PAR_ALIGN_USER_RPMS variable which can be used to contol the site type selected by the placer. You can also manually constrain with RLOC_ORIGIN.
04-17-2012 01:36 PM - edited 04-17-2012 01:43 PM
Here's my UCF for the RPM. I have tested it with U_SET and HU_SET but no success.
I have attached the RPM module .v file with this post, I cannot make the sbox BRAM a part of same level as other registers. I have done everything you suggested, maybe i was doing something wrong or maybe I missed something, but can you look at it and see what the problem might be.
INST "sbox" RLOC_ORIGIN = X0Y0 ;
INST "sbox" RLOC = X0Y0 ;
INST "sbox" U_SET = bytemodule;
// INPUT REGS
INST "KeyXorLfsr_bit0" RLOC = X2Y0;
INST "KeyXorLfsr_bit0" U_SET = bytemodule;
INST "KeyXorLfsr_bit1" RLOC = X3Y0;
INST "KeyXorLfsr_bit1" U_SET = bytemodule;
INST "KeyXorLfsr_bit2" RLOC = X2Y2;
INST "KeyXorLfsr_bit2" U_SET = bytemodule;
INST "KeyXorLfsr_bit3" RLOC = X3Y2;
INST "KeyXorLfsr_bit3" U_SET = bytemodule;
INST "KeyXorLfsr_bit4" RLOC = X2Y4;
INST "KeyXorLfsr_bit4" U_SET = bytemodule;
INST "KeyXorLfsr_bit5" RLOC = X3Y4;
INST "KeyXorLfsr_bit5" U_SET = bytemodule;
INST "KeyXorLfsr_bit6" RLOC = X2Y6;
INST "KeyXorLfsr_bit6" U_SET = bytemodule;
INST "KeyXorLfsr_bit7" RLOC = X3Y6;
INST "KeyXorLfsr_bit7" U_SET = bytemodule;
// OUTPUT REGS
INST "sbox_sub0" RLOC = X4Y0;
INST "sbox_sub0" U_SET = bytemodule;
INST "sbox_sub1" RLOC = X5Y0;
INST "sbox_sub1" U_SET = bytemodule;
INST "sbox_sub2" RLOC = X4Y2;
INST "sbox_sub2" U_SET = bytemodule;
INST "sbox_sub3" RLOC = X5Y2;
INST "sbox_sub3" U_SET = bytemodule;
INST "sbox_sub4" RLOC = X4Y4;
INST "sbox_sub4" U_SET = bytemodule;
INST "sbox_sub5" RLOC = X5Y4;
INST "sbox_sub5" U_SET = bytemodule;
INST "sbox_sub6" RLOC = X4Y6;
INST "sbox_sub6" U_SET = bytemodule;
INST "sbox_sub7" RLOC = X5Y6;
INST "sbox_sub7" U_SET = bytemodule;
when I instantiate the RPM in the top module, it breaks, I mean the mapping is all random. I have set the environment variable, I tried to lock the macros to X0Y0, but no success. Again, i may have missed something.
One last thing, do I need to instantiate the RPM as a black box in this case or normal instantiation would also work? So far, I have been doing it as a black box thing, I guess I tried it by normal instantiation, it didn't work that way too, will check it again.But what's the right way ?
Kindly, give me some pointers.
04-17-2012 03:07 PM
This design does not compile due to an undefined module. Can you attach that as well?
RROR:HDLCompilers:87 - "../../AES_8bit_RPM.v" line 121 Could not find module/primitive 'aes_sbox'
04-17-2012 07:58 PM - edited 04-17-2012 08:15 PM
Sorry I forgot to attach the BRAM module. I have attached the ip_core folder which contains the aes_sbox BRAM.
Also, when I just instantiate this RPM in a top module, as a black box or as a normal instance, it breaks. I only have one instance of RPM in top module and nothing else.
input [7:0] key;
input [7:0] lfsr;
output [7:0] text_out;
,.KeyXorLfsr (key ^ lfsr)
and here's the UCF for this top module:
NET "clk" TNM_NET = "clk";
TIMESPEC TS_clk = PERIOD "clk" 8 ns HIGH 50 % INPUT_JITTER 1.8 ns;
NET "clk" LOC = AH15;
NET "rst" PULLUP;
NET "rst" LOC = AJ19;
INST "inst0" RLOC_ORIGIN = X0Y0;
INST "inst0" RLOC = X0Y0;
INST "inst0" HU_SET = TopSet;