I have to following code which to my understanding should be trivial to be implemented via a fast output enable register. However, the FAST_OUTPUT_ENABLE_REGISTER assignment to the pin is ignored.
entity test_comp is port( irq : out std_logic; ... ); end entity; architecture rtl of test_comp is signal irq_assert : std_logic; begin irq <= '0' when irq_assert else 'Z'; -- fast output enable is ignored. ... process(reset,clk) begin if reset then irq_assert <= '0'; elsif rising_edge(clk) then ... if some_condition then irq_assert <= '1'; else irq_assert <= '0'; end if; ... end if; end process; ... end architecture rtl;The following slight modification does not have the problem. The assignment is accepted.
entity test_comp is port( irq : out std_logic; ... ); end entity; architecture rtl of test_comp is signal irq_assert : std_logic; signal irq_level : std_logic; -- must use irq_level somehow or assign syn_keep attribute to avoid it being removed. attribute syn_keep: boolean; attribute syn_keep of irq_level : signal is true; begin irq <= irq_level when irq_assert else 'Z'; ... process(reset,clk) begin if reset then elsif rising_edge(clk) then ... if some_condition then irq_assert <= '1'; else irq_assert <= '0'; end if; ... end if; end process; ... end architecture rtl;As requested I have extended the sample by some code to drive the irq_assert signal. It really is that simple. A single condtion either sets the bit or clears it in a clocked process with the regular asynchronous reset. I really don't see anything fancy here. Can someone clarify what is happening here?
Fast Output Enable Register tells the fitter to put the output enable into the IO cell.As Kaz points out, you didn't show that irq_assert is a register. If it's not, there's nothing the fitter can do. Second, how are you determining if it's working or not? Finally, I stopped using Fast IO assignments many years ago. The fitter is quite good at looking at timing constraints and determining if it needs to put the register in the IO cell to meet timing or not. So I would start with putting in correct timing constraints and seeing if it passes. (If it passes but doesn't use the IO register, that's fine). If it fails, then go into the timing report and determine if it's not using the IO register. If it's not, then I would look at making the assignment. (I think that's the more thorough, correct way to do it. I know it's easier to just tell it to use the IO register, which should get you the fastest OE timing, and at that point it is what it is. Or you may have pretty easy IO timing and you just want to put it there to feel comfortable that the fitter won't do something dumb like put the OE register on the other side of the device. These are reasonable ways to do it and generally work too.)