- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've been reading "RTL Hardware Design Using VHDL: Coding for Efficiency, Portability, and Scalability" by Pong P. Chu. I'm in section 9.1.2 ("Misuse of gated clocks"), which explains that we should not manipulate the clock signal in RT-level design. The author proposes as example a binary counter with enable input signal. He shows two architectures. Listing 9.3 uses a bad RT-level design practice, which is a gated clock to suspend system operation. Listing 9.4 essentially routes the register output as a possible input and solves the "poor design".
However, when I tried to compile using Quartus II had a very strange "FMAX" results.
- Listing 9.3 – Area: 5 LE. FMAX: 761.04 MHz
- Listing 9.4 – Area: 5 LE. FMAX: 171.7 MHz
Why is FMAX so different? I couldn't explain it.
More info:
- Quartus Version: Version 18.1.0 Build 625 09/12/2018 SJ SE
- Device: EP4CE115F29C7
- Clock Constraint (SDC): create_clock -name clk -period 50MHz [get_ports {*}]
--=============================
-- Listing 9.3 gated clock
--=============================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity binary_counter is
port(
clk, reset: in std_logic;
en: in std_logic;
q: out std_logic_vector(3 downto 0)
);
end binary_counter;
architecture gated_clk_arch of binary_counter is
signal r_reg: unsigned(3 downto 0);
signal r_next: unsigned(3 downto 0);
signal gated_clk: std_logic;
begin
-- register
process(gated_clk,reset)
begin
if (reset='1') then
r_reg <= (others=>'0');
elsif (gated_clk'event and gated_clk='1') then
r_reg <= r_next;
end if;
end process;
-- gated clock
gated_clk <= clk and en;
-- next-state logic
r_next <= r_reg + 1;
-- output logic
q <= std_logic_vector(r_reg);
end gated_clk_arch;
--=============================
-- Listing 9.4
--=============================
architecture two_seg_arch of binary_counter is
signal r_reg: unsigned(3 downto 0);
signal r_next: unsigned(3 downto 0);
begin
-- register
process(clk,reset)
begin
if (reset='1') then
r_reg <= (others=>'0');
elsif (clk'event and clk='1') then
r_reg <= r_next;
end if;
end process;
-- next-state logic
r_next <= r_reg + 1 when en='1' else
r_reg;
-- output logic
q <= std_logic_vector(r_reg);
end two_seg_arch;
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The constraint should be create_clock -name clk -period 50MHz [get_ports {clk}]
Note that the result might vary even if the same design is compiled for several times due to different placement and routing.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I changed the SDC and had the same strange results. The "gated_clk_arch" architecture has a FMAX much bigger than "two_seg_arch" architecture.
I always get the same results whether I use the same Quartus Version and same vhd, even on Linux or Windows. Doesn't matter how many times I compile the design. I get different placement and routing just when I change the constraints (*.SDC), the code (*.VHD) or some Quartus configuration (Optimization Technique, Logic Lock, etc.) .
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Listing 9.3: Referring to Line 30, gated_clk <= clk and en; , en is added to control the gated_clk. The data delay from r_reg[*] to r_reg[*] is smaller compared to Listing 9.4
Listing 9.4: Referring to Line 54: r_next <= r_reg + 1 when en='1' else , en is added to control the register. The data delay from r_reg[*] to r_reg[*] is larger due to the additional combi logic between the register. This is why Listing 9.3 has better Fmax.
Thanks

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page