diff --git a/rtl/extras_2008/pipelining_2008.vhdl b/rtl/extras_2008/pipelining_2008.vhdl index a844292..4800981 100644 --- a/rtl/extras_2008/pipelining_2008.vhdl +++ b/rtl/extras_2008/pipelining_2008.vhdl @@ -70,18 +70,16 @@ --# field_2 : std_ulogic; --# end record my_record; --# ---# function reset_my_record( rec : my_record ) return my_record is ---# begin ---# return ((others => '0'), '0'); ---# end function reset_my_record; +--# constant MY_EMPTY_RECORD : my_record := ((others => '0'), '0')' --# ... --# pipeline_inst : pipeline_universal --# generic map ( --# ELEMENT_TYPE => my_record, ---# RESET_ELEMENT => reset_my_record, +--# DEFAULT_ELEMENT => MY_EMPTY_RECORD, --# PIPELINE_STAGES => 3, --# ATTR_REG_BALANCING => "backward", ---# RESET_ACTIVE_LEVEL => '1' ) +--# RESET_ACTIVE_LEVEL => '1', +--# RESET_TYPE => "async") --# port map (Clock, Reset, sig_1, sig_2); --# --# RETIMING: Here are notes on how to activate retiming in various synthesis @@ -110,15 +108,16 @@ package pipelining is component pipeline_universal is generic ( type ELEMENT_TYPE; --## Type of pipeline element - function RESET_ELEMENT ( element : ELEMENT_TYPE ) return ELEMENT_TYPE; --## Defines how to reset pipeline element + DEFAULT_ELEMENT : ELEMENT_TYPE; --## Reset pipeline element PIPELINE_STAGES : positive; --# Number of pipeline stages to insert - ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction (Xilinx only) - RESET_ACTIVE_LEVEL : std_ulogic := '1' --# Asynch. reset control level + ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction ("backward", "forward" or "no", Xilinx only) + RESET_ACTIVE_LEVEL : std_ulogic := '1'; --# Reset control level + RESET_TYPE : string := "async" --# Reset type: asynchronous ("async") or synchronous ("sync") ); port ( --# {{clocks|}} Clock : in std_ulogic; --# System clock - Reset : in std_ulogic; --# Asynchronous reset + Reset : in std_ulogic; --# Reset --# {{data|}} Sig_in : in ELEMENT_TYPE; --# Signal from block to be pipelined Sig_out : out ELEMENT_TYPE --# Pipelined result @@ -129,13 +128,14 @@ package pipelining is component pipeline_ul is generic ( PIPELINE_STAGES : positive; --# Number of pipeline stages to insert - ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction (Xilinx only) - RESET_ACTIVE_LEVEL : std_ulogic := '1' --# Asynch. reset control level + ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction ("backward", "forward" or "no", Xilinx only) + RESET_ACTIVE_LEVEL : std_ulogic := '1'; --# Reset control level + RESET_TYPE : string := "async" --# Reset type: asynchronous ("async") or synchronous ("sync") ); port ( --# {{clocks|}} Clock : in std_ulogic; --# System clock - Reset : in std_ulogic; --# Asynchronous reset + Reset : in std_ulogic; --# Reset --# {{data|}} Sig_in : in std_ulogic; --# Signal from block to be pipelined Sig_out : out std_ulogic --# Pipelined result @@ -146,13 +146,14 @@ package pipelining is component pipeline_sulv is generic ( PIPELINE_STAGES : positive; --# Number of pipeline stages to insert - ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction (Xilinx only) - RESET_ACTIVE_LEVEL : std_ulogic := '1' --# Asynch. reset control level + ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction ("backward", "forward" or "no", Xilinx only) + RESET_ACTIVE_LEVEL : std_ulogic := '1'; --# Reset control level + RESET_TYPE : string := "async" --# Reset type: asynchronous ("async") or synchronous ("sync") ); port ( --# {{clocks|}} Clock : in std_ulogic; --# System clock - Reset : in std_ulogic; --# Asynchronous reset + Reset : in std_ulogic; --# Reset --# {{data|}} Sig_in : in std_ulogic_vector; --# Signal from block to be pipelined Sig_out : out std_ulogic_vector --# Pipelined result @@ -166,8 +167,9 @@ package pipelining is component pipeline_u is generic ( PIPELINE_STAGES : positive; --# Number of pipeline stages to insert - ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction (Xilinx only) - RESET_ACTIVE_LEVEL : std_ulogic := '1' --# Asynch. reset control level + ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction ("backward", "forward" or "no", Xilinx only) + RESET_ACTIVE_LEVEL : std_ulogic := '1'; --# Reset control level + RESET_TYPE : string := "async" --# Reset type: asynchronous ("async") or synchronous ("sync") ); port ( --# {{clocks|}} @@ -183,13 +185,14 @@ package pipelining is component pipeline_s is generic ( PIPELINE_STAGES : positive; --# Number of pipeline stages to insert - ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction (Xilinx only) - RESET_ACTIVE_LEVEL : std_ulogic := '1' --# Asynch. reset control level + ATTR_REG_BALANCING : string := "backward"; --# Control propagation direction ("backward", "forward" or "no", Xilinx only) + RESET_ACTIVE_LEVEL : std_ulogic := '1'; --# Reset control level + RESET_TYPE : string := "async" --# Reset type: asynchronous ("async") or synchronous ("sync") ); port ( --# {{clocks|}} Clock : in std_ulogic; --# System clock - Reset : in std_ulogic; --# Asynchronous reset + Reset : in std_ulogic; --# Reset --# {{data|}} Sig_in : in u_signed; --# Signal from block to be pipelined Sig_out : out u_signed --# Pipelined result @@ -201,7 +204,10 @@ package pipelining is component fixed_delay_line_universal is generic ( type ELEMENT_TYPE; --# Type of the element being delayed - STAGES : natural --# Number of delay stages (0 for short circuit) + DEFAULT_ELEMENT : ELEMENT_TYPE; --# Default value for an element initialization + STAGES : natural; --# Number of delay stages (0 for short circuit) + ATTR_SRL_STYLE : string := "auto"; --# Shift reg. style (Xilinx only; auto, register, srl, srl_reg, reg_srl, reg_srl_reg, or block) + NEED_INIT : boolean := true --# Initialize delay line with DEFAULT_ELEMENT ); port ( --# {{clocks|}} @@ -220,7 +226,9 @@ package pipelining is --## Fixed delay line for std_ulogic data. component fixed_delay_line is generic ( - STAGES : natural --# Number of delay stages (0 for short circuit) + STAGES : natural; --# Number of delay stages (0 for short circuit) + ATTR_SRL_STYLE : string := "auto"; --# Shift reg. style (Xilinx only; auto, register, srl, srl_reg, reg_srl, reg_srl_reg, or block) + NEED_INIT : boolean := true --# Initialize delay line with DEFAULT_ELEMENT ); port ( --# {{clocks|}} @@ -239,7 +247,9 @@ package pipelining is --## Fixed delay line for std_ulogic_vector data. component fixed_delay_line_sulv is generic ( - STAGES : natural --# Number of delay stages (0 for short circuit) + STAGES : natural; --# Number of delay stages (0 for short circuit) + ATTR_SRL_STYLE : string := "auto"; --# Shift reg. style (Xilinx only; auto, register, srl, srl_reg, reg_srl, reg_srl_reg, or block) + NEED_INIT : boolean := true --# Initialize delay line with DEFAULT_ELEMENT ); port ( --# {{clocks|}} @@ -258,7 +268,9 @@ package pipelining is --## Fixed delay line for signed data. component fixed_delay_line_signed is generic ( - STAGES : natural --# Number of delay stages (0 for short circuit) + STAGES : natural; --# Number of delay stages (0 for short circuit) + ATTR_SRL_STYLE : string := "auto"; --# Shift reg. style (Xilinx only; auto, register, srl, srl_reg, reg_srl, reg_srl_reg, or block) + NEED_INIT : boolean := true --# Initialize delay line with DEFAULT_ELEMENT ); port ( --# {{clocks|}} @@ -277,7 +289,9 @@ package pipelining is --## Fixed delay line for unsigned data. component fixed_delay_line_unsigned is generic ( - STAGES : natural --# Number of delay stages (0 for short circuit) + STAGES : natural; --# Number of delay stages (0 for short circuit) + ATTR_SRL_STYLE : string := "auto"; --# Shift reg. style (Xilinx only; auto, register, srl, srl_reg, reg_srl, reg_srl_reg, or block) + NEED_INIT : boolean := true --# Initialize delay line with DEFAULT_ELEMENT ); port ( --# {{clocks|}} @@ -391,10 +405,11 @@ use ieee.std_logic_1164.all; entity pipeline_universal is generic ( type ELEMENT_TYPE; - function RESET_ELEMENT ( element : ELEMENT_TYPE ) return ELEMENT_TYPE; + DEFAULT_ELEMENT : ELEMENT_TYPE; PIPELINE_STAGES : positive; ATTR_REG_BALANCING : string := "backward"; - RESET_ACTIVE_LEVEL : std_ulogic := '1' + RESET_ACTIVE_LEVEL : std_ulogic := '1'; + RESET_TYPE : string := "async" ); port ( Clock : in std_ulogic; @@ -405,24 +420,73 @@ entity pipeline_universal is end entity; architecture rtl of pipeline_universal is - attribute register_balancing : string; + function is_forward(attr_str : string) return integer is + variable r : integer; + begin + r := 1 when (attr_str = "forward") else 0; + return r; + end function; + + function is_backward(attr_str : string) return integer is + variable r : integer; + begin + r := 1 when (attr_str = "backward") else 0; + return r; + end function; + attribute syn_allow_retiming : boolean; - attribute register_balancing of Sig_out : signal is ATTR_REG_BALANCING; attribute syn_allow_retiming of Sig_out : signal is true; + + attribute retiming_forward : integer; + attribute retiming_forward of Sig_out : signal is + is_forward(ATTR_REG_BALANCING); + + attribute retiming_backward : integer; + attribute retiming_backward of Sig_out : signal is + is_backward(ATTR_REG_BALANCING); begin + + assert (ATTR_REG_BALANCING = "backward") or + (ATTR_REG_BALANCING = "forward") or + (ATTR_REG_BALANCING = "no") + report + "Unknown retiming attribute. Must be forward or backward." + severity FAILURE; + + assert (RESET_TYPE = "async") or (RESET_TYPE = "sync") + report + "Unknown reset type. Must be sync or async." + severity FAILURE; + reg: process(Clock, Reset) type sig_word_vector is array ( natural range <> ) of ELEMENT_TYPE; variable pl_regs : sig_word_vector(1 to PIPELINE_STAGES); begin - if Reset = RESET_ACTIVE_LEVEL then - for i in pl_regs'range loop - pl_regs(i) := RESET_ELEMENT(pl_regs(i)); - end loop; - elsif rising_edge(Clock) then - if PIPELINE_STAGES = 1 then - pl_regs(1) := Sig_in; - else - pl_regs := Sig_in & pl_regs(1 to pl_regs'high-1); + if RESET_TYPE = "async" then + if Reset = RESET_ACTIVE_LEVEL then + for i in pl_regs'range loop + pl_regs(i) := DEFAULT_ELEMENT; + end loop; + elsif rising_edge(Clock) then + if PIPELINE_STAGES = 1 then + pl_regs(1) := Sig_in; + else + pl_regs := Sig_in & pl_regs(1 to pl_regs'high-1); + end if; + end if; + elsif RESET_TYPE = "sync" then + if rising_edge(Clock) then + if Reset = RESET_ACTIVE_LEVEL then + for i in pl_regs'range loop + pl_regs(i) := DEFAULT_ELEMENT; + end loop; + else + if PIPELINE_STAGES = 1 then + pl_regs(1) := Sig_in; + else + pl_regs := Sig_in & pl_regs(1 to pl_regs'high-1); + end if; + end if; end if; end if; @@ -438,7 +502,8 @@ entity pipeline_ul is generic ( PIPELINE_STAGES : positive; ATTR_REG_BALANCING : string := "backward"; - RESET_ACTIVE_LEVEL : std_ulogic := '1' + RESET_ACTIVE_LEVEL : std_ulogic := '1'; + RESET_TYPE : string := "async" ); port ( Clock : in std_ulogic; @@ -449,18 +514,16 @@ entity pipeline_ul is end entity; architecture rtl of pipeline_ul is - function reset_ul (ul : std_ulogic) return std_ulogic is - begin - return '0'; - end function; + constant ZERO : std_ulogic := '0'; begin pipeline_inst : entity work.pipeline_universal(rtl) generic map ( ELEMENT_TYPE => Sig_in'subtype, - RESET_ELEMENT => reset_ul, + DEFAULT_ELEMENT => ZERO, PIPELINE_STAGES => PIPELINE_STAGES, ATTR_REG_BALANCING => ATTR_REG_BALANCING, - RESET_ACTIVE_LEVEL => RESET_ACTIVE_LEVEL) + RESET_ACTIVE_LEVEL => RESET_ACTIVE_LEVEL, + RESET_TYPE => RESET_TYPE) port map (Clock, Reset, Sig_in, Sig_out); end architecture; @@ -472,7 +535,8 @@ entity pipeline_sulv is generic ( PIPELINE_STAGES : positive; ATTR_REG_BALANCING : string := "backward"; - RESET_ACTIVE_LEVEL : std_ulogic := '1' + RESET_ACTIVE_LEVEL : std_ulogic := '1'; + RESET_TYPE : string := "async" ); port ( Clock : in std_ulogic; @@ -483,18 +547,17 @@ entity pipeline_sulv is end entity; architecture rtl of pipeline_sulv is - function reset_sulv (ul : std_ulogic_vector) return std_ulogic_vector is - begin - return (ul'range => '0'); - end function; + constant ZEROS : std_ulogic_vector(Sig_in'range) := + (Sig_in'range => '0'); begin pipeline_inst : entity work.pipeline_universal(rtl) generic map ( ELEMENT_TYPE => Sig_in'subtype, - RESET_ELEMENT => reset_sulv, + DEFAULT_ELEMENT => ZEROS, PIPELINE_STAGES => PIPELINE_STAGES, ATTR_REG_BALANCING => ATTR_REG_BALANCING, - RESET_ACTIVE_LEVEL => RESET_ACTIVE_LEVEL) + RESET_ACTIVE_LEVEL => RESET_ACTIVE_LEVEL, + RESET_TYPE => RESET_TYPE) port map (Clock, Reset, Sig_in, Sig_out); end architecture; @@ -507,7 +570,8 @@ entity pipeline_u is generic ( PIPELINE_STAGES : positive; ATTR_REG_BALANCING : string := "backward"; - RESET_ACTIVE_LEVEL : std_ulogic := '1' + RESET_ACTIVE_LEVEL : std_ulogic := '1'; + RESET_TYPE : string := "async" ); port ( Clock : in std_ulogic; @@ -522,7 +586,8 @@ architecture rtl of pipeline_u is begin s1 <= std_ulogic_vector(Sig_in); pipeline_inst : entity work.pipeline_sulv(rtl) - generic map (PIPELINE_STAGES, ATTR_REG_BALANCING, RESET_ACTIVE_LEVEL) + generic map (PIPELINE_STAGES, ATTR_REG_BALANCING, + RESET_ACTIVE_LEVEL, RESET_TYPE) port map (Clock => Clock, Reset => Reset, Sig_in => s1, Sig_out => s2); Sig_out <= u_unsigned(s2); end architecture; @@ -536,7 +601,8 @@ entity pipeline_s is generic ( PIPELINE_STAGES : positive; ATTR_REG_BALANCING : string := "backward"; - RESET_ACTIVE_LEVEL : std_ulogic := '1' + RESET_ACTIVE_LEVEL : std_ulogic := '1'; + RESET_TYPE : string := "async" ); port ( Clock : in std_ulogic; @@ -551,7 +617,8 @@ architecture rtl of pipeline_s is begin s1 <= std_ulogic_vector(Sig_in); pipeline_inst : entity work.pipeline_sulv(rtl) - generic map (PIPELINE_STAGES, ATTR_REG_BALANCING, RESET_ACTIVE_LEVEL) + generic map (PIPELINE_STAGES, ATTR_REG_BALANCING, + RESET_ACTIVE_LEVEL, RESET_TYPE) port map (Clock => Clock, Reset => Reset, Sig_in => s1, Sig_out => s2); Sig_out <= u_signed(s2); end architecture; @@ -564,7 +631,10 @@ use ieee.std_logic_1164.all; entity fixed_delay_line_universal is generic ( type ELEMENT_TYPE; - STAGES : natural + DEFAULT_ELEMENT : ELEMENT_TYPE; + STAGES : natural; + ATTR_SRL_STYLE : string := "auto"; + NEED_INIT : boolean := true ); port ( Clock : in std_ulogic; @@ -575,23 +645,88 @@ entity fixed_delay_line_universal is end entity; architecture rtl of fixed_delay_line_universal is + function is_auto(attr_gen : string) return boolean is + constant str_auto : string := "auto"; + begin + if attr_gen'length /= str_auto'length then + return false; + else + return (attr_gen = str_auto); + end if; + end function; + type elements_vector is array ( natural range <> ) of ELEMENT_TYPE; - signal dly : elements_vector(0 to STAGES-1); begin g : if STAGES = 0 generate Data_out <= Data_in; elsif STAGES > 0 generate - delay: process(Clock) is + + g2 : if (not is_auto(ATTR_SRL_STYLE)) and (not NEED_INIT) generate + signal dly : elements_vector(0 to STAGES-1); + attribute srl_style : string; + attribute srl_style of dly : signal is ATTR_SRL_STYLE; begin - if rising_edge(Clock) then - if Enable = '1' then - dly <= Data_in & dly(0 to dly'high-1); + + delay: process(Clock) is + begin + if rising_edge(Clock) then + if Enable = '1' then + dly <= Data_in & dly(0 to dly'high-1); + end if; end if; - end if; - end process; + end process; + + Data_out <= dly(dly'high); + + elsif (not is_auto(ATTR_SRL_STYLE)) and NEED_INIT generate + signal dly : elements_vector(0 to STAGES-1) := (others => DEFAULT_ELEMENT); + attribute srl_style : string; + attribute srl_style of dly : signal is ATTR_SRL_STYLE; + begin + + delay: process(Clock) is + begin + if rising_edge(Clock) then + if Enable = '1' then + dly <= Data_in & dly(0 to dly'high-1); + end if; + end if; + end process; + + Data_out <= dly(dly'high); + + elsif is_auto(ATTR_SRL_STYLE) and NEED_INIT generate + signal dly : elements_vector(0 to STAGES-1) := (others => DEFAULT_ELEMENT); + begin + + delay: process(Clock) is + begin + if rising_edge(Clock) then + if Enable = '1' then + dly <= Data_in & dly(0 to dly'high-1); + end if; + end if; + end process; + + Data_out <= dly(dly'high); + + elsif is_auto(ATTR_SRL_STYLE) and (not NEED_INIT) generate + signal dly : elements_vector(0 to STAGES-1); + begin + + delay: process(Clock) is + begin + if rising_edge(Clock) then + if Enable = '1' then + dly <= Data_in & dly(0 to dly'high-1); + end if; + end if; + end process; + + Data_out <= dly(dly'high); - Data_out <= dly(dly'high); + end generate g2; end generate; end architecture; @@ -602,7 +737,9 @@ use ieee.std_logic_1164.all; entity fixed_delay_line is generic ( - STAGES : natural + STAGES : natural; + ATTR_SRL_STYLE : string := "auto"; + NEED_INIT : boolean := true ); port ( Clock : in std_ulogic; @@ -613,9 +750,12 @@ entity fixed_delay_line is end entity; architecture rtl of fixed_delay_line is + constant ZERO : std_ulogic := '0'; begin dl_inst : entity work.fixed_delay_line_universal(rtl) - generic map (ELEMENT_TYPE => Data_in'subtype, STAGES => STAGES) + generic map (ELEMENT_TYPE => Data_in'subtype, DEFAULT_ELEMENT => ZERO, + STAGES => STAGES, + ATTR_SRL_STYLE => ATTR_SRL_STYLE, NEED_INIT => NEED_INIT) port map (Clock, Enable, Data_in, Data_out); end architecture; @@ -625,7 +765,9 @@ use ieee.std_logic_1164.all; entity fixed_delay_line_sulv is generic ( - STAGES : natural + STAGES : natural; + ATTR_SRL_STYLE : string := "auto"; + NEED_INIT : boolean := true ); port ( Clock : in std_ulogic; @@ -636,9 +778,13 @@ entity fixed_delay_line_sulv is end entity; architecture rtl of fixed_delay_line_sulv is + constant ZEROS : std_ulogic_vector(Data_in'range) := + (Data_in'range => '0'); begin dl_inst : entity work.fixed_delay_line_universal(rtl) - generic map (ELEMENT_TYPE => Data_in'subtype, STAGES => STAGES) + generic map (ELEMENT_TYPE => Data_in'subtype, DEFAULT_ELEMENT => ZEROS, + STAGES => STAGES, + ATTR_SRL_STYLE => ATTR_SRL_STYLE, NEED_INIT => NEED_INIT) port map (Clock, Enable, Data_in, Data_out); end architecture; @@ -649,7 +795,9 @@ use ieee.numeric_std.all; entity fixed_delay_line_signed is generic ( - STAGES : natural + STAGES : natural; + ATTR_SRL_STYLE : string := "auto"; + NEED_INIT : boolean := true ); port ( Clock : in std_ulogic; @@ -660,9 +808,13 @@ entity fixed_delay_line_signed is end entity; architecture rtl of fixed_delay_line_signed is + constant ZEROS : u_signed(Data_in'range) := + (Data_in'range => '0'); begin dl_inst : entity work.fixed_delay_line_universal(rtl) - generic map (ELEMENT_TYPE => Data_in'subtype, STAGES => STAGES) + generic map (ELEMENT_TYPE => Data_in'subtype, DEFAULT_ELEMENT => ZEROS, + STAGES => STAGES, + ATTR_SRL_STYLE => ATTR_SRL_STYLE, NEED_INIT => NEED_INIT) port map (Clock, Enable, Data_in, Data_out); end architecture; @@ -673,7 +825,9 @@ use ieee.numeric_std.all; entity fixed_delay_line_unsigned is generic ( - STAGES : natural + STAGES : natural; + ATTR_SRL_STYLE : string := "auto"; + NEED_INIT : boolean := true ); port ( Clock : in std_ulogic; @@ -684,9 +838,13 @@ entity fixed_delay_line_unsigned is end entity; architecture rtl of fixed_delay_line_unsigned is + constant ZEROS : u_unsigned(Data_in'range) := + (Data_in'range => '0'); begin dl_inst : entity work.fixed_delay_line_universal(rtl) - generic map (ELEMENT_TYPE => Data_in'subtype, STAGES => STAGES) + generic map (ELEMENT_TYPE => Data_in'subtype, DEFAULT_ELEMENT => ZEROS, + STAGES => STAGES, + ATTR_SRL_STYLE => ATTR_SRL_STYLE, NEED_INIT => NEED_INIT) port map (Clock, Enable, Data_in, Data_out); end architecture;