Altera_Forum
Honored Contributor
12 years agoMulti cycle path trough combinatoric logic circuit
Hi, i have an issue to fully understand and constraint multi cycle path for particular vhdl file.
I created pipeline tree adder with enable input. This pipeline tree adder is created using recursion approach (see VHDL code). Enable signal is used to reduce calculation speed of this digital circuit, by allowing pipeline data to change only when enable signal's value is high. Such approach is used because the main system's clock is higher than the input data rate. Enable signal appears only once in every fifth clock (as fast as the input data), thus reducing the calculation speed by 5x times, allowing this circuit to work in the same clock domain as the main circuit.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library lib_packages;
use lib_packages.util_pkg.all;
library arith;
use arith.arith_lib.all;
library altera;
use altera.altera_primitives_components.all;
entity pipeline_tree_adder_signed_with_en is
generic
(
P : natural := 4; -- Number of inputs
DATA_WIDTH : natural := 1 -- Data width
);
port
(
clk : in std_logic;
wr_req_in : in std_logic;
en_in : in std_logic;
data_in_2d : in std_logic_2d(P-1 downto 0, DATA_WIDTH-1 downto 0);
data_out : out std_logic_vector(DATA_WIDTH-1+log2c(P) downto 0);
wr_req_out : out std_logic
);
end entity;
architecture rtl of pipeline_tree_adder_signed_with_en is
subtype ubyte is signed(DATA_WIDTH-1 downto 0);
type u_1d_array is array(natural range <>) of ubyte;
subtype ubytew is signed(DATA_WIDTH downto 0);
type u_1d_array_w is array(natural range <>) of ubytew;
signal data_1d_reg, data_1d_next : u_1d_array(P-1 downto 0);
signal sum_1d : u_1d_array_w(((P-(P mod 2))/2 + (P mod 2))-1 downto 0);
signal sum_2d : std_logic_2d(((P-(P mod 2))/2 + (P mod 2))-1 downto 0, DATA_WIDTH downto 0);
signal wr_req_in_reg, wr_req_tmp_reg, wr_req_tmp : std_logic := '0';
signal output_signal : std_logic_vector(DATA_WIDTH-1+log2c(P) downto 0) := (others => '0');
signal en_temp : std_logic := '0';
component signed_adder is
generic
(
DATA_WIDTH : natural
);
port
(
a : in signed (DATA_WIDTH-1 downto 0);
b : in signed (DATA_WIDTH-1 downto 0);
result : out signed (DATA_WIDTH-1 downto 0)
);
end component;
begin
process(data_in_2d)
begin
for i in P-1 downto 0 loop
for l in DATA_WIDTH-1 downto 0 loop
data_1d_next(i)(l) <= data_in_2d(i, l);
end loop;
end loop;
end process;
process(clk)
begin
if rising_edge(clk) then
if (en_in = '1') then
wr_req_in_reg <= wr_req_in;
else
wr_req_in_reg <= wr_req_in_reg;
end if;
end if;
end process;
en_temp <= en_in and wr_req_in;
-- component's
process(clk)
begin
if rising_edge(clk) then
if (en_temp = '1') then
data_1d_reg <= data_1d_next;
else
data_1d_reg <= data_1d_reg;
end if;
end if;
end process;
sadder_gen :
for i in 0 to ((P-(P mod 2))/2-1) generate
sadder : signed_adder
generic map (DATA_WIDTH => (DATA_WIDTH+1))
port map (a => (data_1d_reg(i*2)((data_1d_reg(i*2)'length)-1) & data_1d_reg(i*2)), b => (data_1d_reg(i*2+1)((data_1d_reg(i*2+1)'length)-1) & data_1d_reg(i*2+1)), result => sum_1d(i));
end generate;
--1. if P = 2
Output_stage_gen:
if (P = 2) generate
output_signal <= std_logic_vector(sum_1d(0));
wr_req_out <= wr_req_in_reg;
end generate;
int_gen:
if (P > 2) generate
process(sum_1d)
begin
for i in (((P-(P mod 2))/2 + (P mod 2))-1) downto 0 loop
for l in DATA_WIDTH downto 0 loop
sum_2d(i,l) <= sum_1d(i)(l);
end loop;
end loop;
end process;
Even_stage_gen:
if (P mod 2 = 0) generate
even_gen: pipeline_tree_adder_signed_with_en
generic map (P => P/2, DATA_WIDTH => DATA_WIDTH + 1)
port map (clk => clk, wr_req_in => wr_req_in_reg, en_in => en_in, data_in_2d => sum_2d, data_out => output_signal, wr_req_out => wr_req_out);
end generate;
Odd_stage_gen:
if (P mod 2 = 1) generate
sum_1d(((P-(P mod 2))/2 + (P mod 2))-1) <= data_1d_reg(P-1)((data_1d_reg(P-1)'length)-1) & data_1d_reg(P-1);
odd_gen: pipeline_tree_adder_signed_with_en
generic map (P => (P-1)/2+1, DATA_WIDTH => DATA_WIDTH + 1)
port map (clk => clk, wr_req_in => wr_req_in_reg, en_in => en_in, data_in_2d => sum_2d, data_out => output_signal, wr_req_out => wr_req_out);
end generate;
end generate;
data_out <= output_signal;
end architecture;
Respective VHDL RTL: https://www.alteraforum.com/forum/attachment.php?attachmentid=8322 My question is: how do i constraint multi cycle path for such design where is one common clock with short enable impulses. How to correctly specify in SDC file that enable_in signal appears every fifth clock cycle and is only 1 clock cycle long? See timing diagrams. https://www.alteraforum.com/forum/attachment.php?attachmentid=8323 To constraint multi cycle path i have been using such SDC command, but it didn't work... # set_multicycle_path 3 -to [get_fanouts [get_pins -hier *en*|q*] -through [get_pins -hier *|*ena*]] In top level entity i have register what generates enable impulses. Regards, Rinalds