相关推荐recommended
vivado Convergent Rounding (LSB CorrectionTechnique)
作者:mmseoamin日期:2024-02-20

DSP块基元利用模式检测电路来计算收敛舍入(要么为偶数,要么为奇数)。以下是收敛舍入推理的示例,它在块满时进行推理并且还推断出2输入and门(1 LUT)以实现LSB校正。

Rounding to Even (Verilog) Filename: convergentRoundingEven.v // Convergent rounding(Even) Example which makes use of pattern detect // File: convergentRoundingEven.v module convergentRoundingEven ( input clk, input [23:0] a, input [15:0] b, output reg signed [23:0] zlast ); reg signed [23:0] areg; reg signed [15:0] breg; reg signed [39:0] z1; reg pattern_detect; wire [15:0] pattern = 16'b0000000000000000; wire [39:0] c = 40'b0000000000000000000000000111111111111111; // 15 ones wire signed [39:0] multadd; wire signed [15:0] zero; reg signed [39:0] multadd_reg; // Convergent Rounding: LSB Correction Technique // --------------------------------------------- // For static convergent rounding, the pattern detector can be used // to detect the midpoint case. For example, in an 8-bit round, if // the decimal place is set at 4, the C input should be set to // 0000.0111. Round to even rounding should use CARRYIN = "1" and // check for PATTERN "XXXX.0000" and replace the units place with 0 // if the pattern is matched. See UG193 for more details. assign multadd = z1 + c + 1'b1; always @(posedge clk) begin areg <= a; breg <= b; z1 <= areg * breg; pattern_detect <= multadd[15:0] == pattern ? 1'b1 : 1'b0; multadd_reg <= multadd; end // Unit bit replaced with 0 if pattern is detected always @(posedge clk) zlast <= pattern_detect ? {multadd_reg[39:17],1'b0} : multadd_reg[39:16]; endmodule // convergentRoundingEven Rounding to Even (VHDL) Filename: convergentRoundingEven.vhd -- Convergent rounding(Even) Example which makes use of pattern detect -- File: convergentRoundingEven.vhd library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity convergentRoundingEven is port (clk : in std_logic; a : in std_logic_vector (23 downto 0); b : in std_logic_vector (15 downto 0); zlast : out std_logic_vector (23 downto 0)); end convergentRoundingEven; architecture beh of convergentRoundingEven is signal ar : signed(a'range); signal br : signed(b'range); signal z1 : signed(a'length + b'length - 1 downto 0); signal multaddr : signed(a'length + b'length - 1 downto 0); signal multadd : signed(a'length + b'length - 1 downto 0); signal pattern_detect : boolean; constant pattern : signed(15 downto 0) := (others => '0'); constant c : signed := "0000000000000000000000000111111111111111"; -- Convergent Rounding: LSB Correction Technique -- --------------------------------------------- -- For static convergent rounding, the pattern detector can be used -- to detect the midpoint case. For example, in an 8-bit round, if -- the decimal place is set at 4, the C input should be set to -- 0000.0111. Round to even rounding should use CARRYIN = "1" and -- check for PATTERN "XXXX.0000" and replace the units place with 0 -- if the pattern is matched. See UG193 for more details. begin multadd <= z1 + c + 1; process(clk) begin if rising_edge(clk) then ar <= signed(a); br <= signed(b); z1 <= ar * br; multaddr <= multadd; if multadd(15 downto 0) = pattern then pattern_detect <= true; else pattern_detect <= false; end if; end if; end process; -- Unit bit replaced with 0 if pattern is detected process(clk) begin if rising_edge(clk) then if pattern_detect = true then zlast <= std_logic_vector(multaddr(39 downto 17)) & "0"; else zlast <= std_logic_vector(multaddr(39 downto 16)); end if; end if; end process; end beh; Rounding to Odd (Verilog) Filename: convergentRoundingOdd.v // Convergent rounding(Odd) Example which makes use of pattern detect // File: convergentRoundingOdd.v module convergentRoundingOdd ( input clk, input [23:0] a, input [15:0] b, output reg signed [23:0] zlast ); reg signed [23:0] areg; reg signed [15:0] breg; reg signed [39:0] z1; reg pattern_detect; wire [15:0] pattern = 16'b1111111111111111; wire [39:0] c = 40'b0000000000000000000000000111111111111111; // 15 ones wire signed [39:0] multadd; wire signed [15:0] zero; reg signed [39:0] multadd_reg; // Convergent Rounding: LSB Correction Technique // --------------------------------------------- // For static convergent rounding, the pattern detector can be // used to detect the midpoint case. For example, in an 8-bit // round, if the decimal place is set at 4, the C input should // be set to 0000.0111. Round to odd rounding should use // CARRYIN = "0" and check for PATTERN "XXXX.1111" and then // replace the units place bit with 1 if the pattern is // matched. See UG193 for details assign multadd = z1 + c; always @(posedge clk) begin areg <= a; breg <= b; z1 <= areg * breg; pattern_detect <= multadd[15:0] == pattern ? 1'b1 : 1'b0; multadd_reg <= multadd; end always @(posedge clk) zlast <= pattern_detect ? {multadd_reg[39:17],1'b1} : multadd_reg[39:16]; endmodule // convergentRoundingOdd Rounding to Odd (VHDL) Filename: convergentRoundingOdd.vhd -- Convergent rounding(Odd) Example which makes use of pattern detect -- File: convergentRoundingOdd.vhd library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity convergentRoundingOdd is port (clk : in std_logic; a : in std_logic_vector (23 downto 0); b : in std_logic_vector (15 downto 0); zlast : out std_logic_vector (23 downto 0)); end convergentRoundingOdd; architecture beh of convergentRoundingOdd is signal ar : signed(a'range); signal br : signed(b'range); signal z1 : signed(a'length + b'length - 1 downto 0); signal multadd, multaddr : signed(a'length + b'length - 1 downto 0); signal pattern_detect : boolean; constant pattern : signed(15 downto 0) := (others => '1'); constant c : signed := "0000000000000000000000000111111111111111"; -- Convergent Rounding: LSB Correction Technique -- --------------------------------------------- -- For static convergent rounding, the pattern detector can be -- used to detect the midpoint case. For example, in an 8-bit -- round, if the decimal place is set at 4, the C input should -- be set to 0000.0111. Round to odd rounding should use -- CARRYIN = "0" and check for PATTERN "XXXX.1111" and then -- replace the units place bit with 1 if the pattern is -- matched. See UG193 for details begin multadd <= z1 + c; process(clk) begin if rising_edge(clk) then ar <= signed(a); br <= signed(b); z1 <= ar * br; multaddr <= multadd; if multadd(15 downto 0) = pattern then pattern_detect <= true; else pattern_detect <= false; end if; end if; end process; process(clk) begin if rising_edge(clk) then if pattern_detect = true then zlast <= std_logic_vector(multaddr(39 downto 17)) & "1"; else zlast <= std_logic_vector(multaddr(39 downto 16)); end if; end if; end process; end beh;