![]() |
|
|
|||||||
![]() |
VHDL - Xilinx ISE collapsing registers, how can I prevent it? |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
Hi everyone, I'm using Xilinx tools again for the first time in a few
years so I'm hoping this is something simple I'm doing wrong in the options, so I'll ask first before I actually post any code. Basically, I have a design that implements an asynchronous EMIF bus interface to a Virtex-4. In the Virtex-4 is logic that controls some other peripherals in the system using state machine and also has configuration registers for those devices embedded in it so that the processor can do configuration of the devices over the EMIF bus. My VHDL top-level is two instantiated components, 1) my EMIF bus interface, 2) the control system. The EMIF interface just takes data from the bus and latches it onto the appropriate latches based on the address. The latch outputs are just tied directly to the inputs of the control system. Many of these are control signals that are simply passed through the FPGA and out to the devices's configuration pins. One register is used to load a count load value for an internal counter in the control system. Basically, the counter continuously counts down from the load value, and whenever the count is lower than 600 it raises an external signal high, otherwise the signal is low. This all works fine behaviorally, but after I implement everything it seems the tools are removing a bytes worth of the load value latches as well as many of the configuration latches that just pass through the device. I'm not sure if it's doing this to the load value latches due to the <= comparison to 600 or not, but I was hoping someone could tell me if there was some kind of option I'm overlooking that can prevent this kind of removal of signals. I'm optimizing for speed, not area, and setting all the usual normal synthesis options as well. When I view the design in the Floorplanner after the PAR alot of these apparently removed latches are present in the latch listing, but don't actually show up in the graphic display, so I'm assuming that even though they're listed they've actually been removed (which seems to be born out by my post-route simulation. Does anyone have any ideas. I could post some simplified code if anyone needs to see it to get a better idea. Thanks. creon100@yahoo.com |
|
|
|
|
#2 |
|
Posts: n/a
|
Check to see if the latches are getting packed into the I/O cells.
If the very 1st thing you do to a signal is latch it with system clock, they will get moved there. Which is a good thing. If you don't like this, there is an option to prevent it. Hope that helps. ghelbig@lycos.com |
|
|
|
#3 |
|
Posts: n/a
|
Thanks, I'll check, and I don't mind if they're moved to the I/O cells,
but I don't just mean I can't find them, I mean they appear to be completely gone during post-synthesis simulation. My 32-bit counter is turned into a 10-bit counter for instance, which completely makes using it unfeasible. I'd imagine the software simply moving the latches to the I/O cells wouldnt' exhibit such behavior? creon100@yahoo.com |
|
|
|
#4 |
|
Posts: n/a
|
What you are describing looks like a normal part of optimization. If
the tool figures out that there are no downstream gates dependent on the output of a f-f, it will optimize it away. This is good, because you can write more generic code, and let the tools deal with creating a minimal circuit. In your case, what was downstream from your 32-bit counter? Were all 32-bits being used? radarman |
|
|
|
#5 |
|
Posts: n/a
|
Yes, I guess I didn't word my question correctly, since I realized it
was probably optimizing them out, I just didn't know if I was maybe missing some software option to better control the optimizations it tries to do. Looking more closely it seems the actual counter itself isn't being optimized smaller, but instead the register I use to load it is. I have a 32-bit register (or that's the length it should be) named RATE, which is used to continuously load the counter, this register is accessible to the system's DSP via the bus interface so that it can write new values to it to change the pulse rate of the output signal. So in my control system component I have two processes, one to count and one to generate the signal based on the count (this is just pseudo code): 1) count process: if(clk'event and clk=0) if reset then counter <= RATE; elsif system_enabled = 1 then if counter = 0 then counter <= RATE; else counter <= counter - 1; end if; end process; 2) signal generate process: if(clk'event and clk=0) then if system_enabled = 1 then if counter <= 600 then output <= '1'; else output <= '0'; end if; else output <= '1'; end if; end if; end process; What it seems to be doing is truncating the RATE register to 10-bits. This obviously won't work if I need to write out a count value larger than 10-bits from the DSP (which thankfully I was doing in my testbench or else I wouldn't have noticed the issue). The next largest register I have in the interface system is 10-bits, so I'm not sure if it's truncating because it's matching to that other register or if it's truncating because it see the <= 600 comparison and knows it needs only 10-bits for that comparison. If it were the latter I'd think it would truncate the counter though and not just the RATE register. In any case, playing with the code in both places (changing all the other registers to 32-bit even though the unused bits will get optimized out anyway, and playing with the <= 600 comparison so that it involves the upper bytes of the count through some different ways of doing the comparison) don't do anything to solve the problem. creon100@yahoo.com |
|
|
|
#6 |
|
Posts: n/a
|
wrote:
> Yes, I guess I didn't word my question correctly, since I realized it > was probably optimizing them out, I just didn't know if I was maybe > missing some software option to better control the optimizations it > tries to do. > > Looking more closely it seems the actual counter itself isn't being > optimized smaller, but instead the register I use to load it is. I > have a 32-bit register (or that's the length it should be) named RATE, > which is used to continuously load the counter, this register is > accessible to the system's DSP via the bus interface so that it can > write new values to it to change the pulse rate of the output signal. > > So in my control system component I have two processes, one to count > and one to generate the signal based on the count (this is just pseudo > code): > > 1) count process: > if(clk'event and clk=0) > if reset then > counter <= RATE; > elsif system_enabled = 1 then > if counter = 0 then > counter <= RATE; > else > counter <= counter - 1; > end if; > end process; > > 2) signal generate process: > if(clk'event and clk=0) then > if system_enabled = 1 then > if counter <= 600 then > output <= '1'; > else > output <= '0'; > end if; > else > output <= '1'; > end if; > end if; > end process; > > What it seems to be doing is truncating the RATE register to 10-bits. > This obviously won't work if I need to write out a count value larger > than 10-bits from the DSP (which thankfully I was doing in my testbench > or else I wouldn't have noticed the issue). The next largest register > I have in the interface system is 10-bits, so I'm not sure if it's > truncating because it's matching to that other register or if it's > truncating because it see the <= 600 comparison and knows it needs only > 10-bits for that comparison. If it were the latter I'd think it would > truncate the counter though and not just the RATE register. In any > case, playing with the code in both places (changing all the other > registers to 32-bit even though the unused bits will get optimized out > anyway, and playing with the <= 600 comparison so that it involves the > upper bytes of the count through some different ways of doing the > comparison) don't do anything to solve the problem. I created the following VHDL code from your descriptions. I used ISE 7.1 (sp4) and Modelsim IIXE 5.7g. The 32-bit registers stayed 32-bits long. -------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.all; entity top is Port ( reset : in std_logic; data_in : in std_logic_vector(31 downto 0); rate_ld : in std_logic; system_enabled : in std_logic; clk : in std_logic; output : out std_logic ); end top; architecture Behavioral of top is signal rate : unsigned(31 downto 0); signal counter : unsigned(31 downto 0); begin process ( reset, clk ) is begin if reset = '1' then rate <= (others => '0'); elsif falling_edge( clk ) then if rate_ld = '1' then rate <= unsigned(data_in); end if; end if; end process; count: process ( reset, clk ) is begin if falling_edge( clk ) then if reset = '1' then counter <= RATE; elsif system_enabled = '1' then if counter = 0 then counter <= RATE; else counter <= counter - 1; end if; end if; end if; end process; signal_generate: process ( clk ) is begin if falling_edge( clk ) then if system_enabled = '1' then if counter <= 600 then output <= '1'; else output <= '0'; end if; else output <= '0'; end if; end if; end process; end Behavioral; HTH -Dave Pollum Dave Pollum |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| VHDL (Assigning pins in xilinx) | amanpervaiz | Hardware | 3 | 12-02-2006 04:37 PM |