- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In my project I have some small counters. For example one counter counting up 0,1,2,0,1,2...
This counter is under asynchronous reset and the reset signal is presynchronised (say through register R). The counter output is used as select input to a wide registered mux (say register M) which itself is not under reset. After some compilations quartus says the path from register R to register M violates setup. But I have not put any reset on the mux register. I know it could be some sort of optimisation possibly register retiming but why not respect my reset plan. Applying reset to this wide mux is no good as it does not need it and it is quite wide putting too much work on timing closure. Any idea why quartus doing that and how to stop it. Thanks P.KingLink Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm... can you post the relevant code snippet or something similar?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is the part of code. I don't think you can reproduce the issue as it happens sometime during large project build.
signal counter : integer range 0 to 2 := 0;
-- coefficients
type type1 is array(0 to 13) of integer range -2**15-1 to +2**15-1;
constant polyphase1: type1 := (-10,-56,215,-556,1209,-2527,6966,13025,-2559,939,-319,66,16,-27);
constant polyphase2: type1 := (-27,16,66,-319,939,-2559,13025,6966,-2527,1209,-556,215,-56,-10);
constant polyphase3: type1 := (-56,147,-291,474,-662,804,15552,804,-662,474,-291,147,-56,0);
type type2 is array(0 to 13) of std_logic_vector(15 downto 0);
signal coeffs : type2;
....
....
process(reset,clk)
begin
if reset = '1' then
counter <= 0;
elsif rising_edge(clk) then
if counter = 2 then
counter <= 0;
else
counter <= counter + 1;
end if;
for i in 0 to 13 loop
case counter is
when 0 => coeffs(i) <= std_logic_vector(to_signed(polyphase1(i),16));
when 1 => coeffs(i) <= std_logic_vector(to_signed(polyphase2(i),16));
when 2 => coeffs(i) <= std_logic_vector(to_signed(polyphase3(i),16));
when others => null;
end case;
end loop;
end if;
end process;
Thanks P King
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It may be sufficient.
In the case of your code, when reset = '1', then the coeffs registers *hold* their value. Quartus is implementing it as a clock enable for the coeffs registers. I'm surprised it's hurting you but that seems to be cause of of the path between R and M. Either reset your coeffs register or put them in a different process, without reset.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- It may be sufficient. In the case of your code, when reset = '1', then the coeffs registers *hold* their value. Quartus is implementing it as a clock enable for the coeffs registers. I'm surprised it's hurting you but that seems to be cause of of the path between R and M. Either reset your coeffs register or put them in a different process, without reset. --- Quote End --- Thanks rbugalho. That makes sense indeed since it means if reset = '0' then enable coeffs on every clock edge otherwise hold at last value. While my intention is not that at all. I don't want to apply reset to coeffs in any way but then the code as such broke the classic template and implied enable. I will use a separate process. I was following the advice that says apply reset to control signals only as data reset is useless usually and is burden on timing but here you go it does need separate process. It does hurt speed a lot when you are runnning at ~370MHz with 80% of chip used. Thanks P King
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page