Day21_vhdl全加器_哈夫曼编码

VHDL

全加器的四种实现方式

library ieee;
use ieee.std_logic_1164.all;

entity full_adder4th is
    generic(tpd : time := 10 ns);
    port(
        x, y, c_in : in  std_logic;
        sum, c_out : out std_logic
    );
end full_adder4th;

architecture delay_based of full_adder4th is
    -- 中间信号,用于构建逻辑
    signal and_x_y : std_logic;
    signal and_x_cin : std_logic;
    signal and_y_cin : std_logic;
    signal or1_result : std_logic;
    signal or2_result : std_logic;
    signal xor1_result : std_logic;
    signal xor2_result : std_logic;
begin
    -- 计算 x AND y
    and_x_y <= x and y after tpd;
    -- 计算 x AND c_in
    and_x_cin <= x and c_in after tpd;
    -- 计算 y AND c_in
    and_y_cin <= y and c_in after tpd;
    
    -- 计算 (x AND y) OR (x AND c_in)
    or1_result <= and_x_y or and_x_cin after tpd;
    -- 计算 (x AND y) OR (y AND c_in)
    or2_result <= and_x_y or and_y_cin after tpd;
    
    -- 计算 x XOR y
    xor1_result <= x xor y after tpd;
    -- 计算 (x XOR y) XOR c_in 得到 sum
    xor2_result <= xor1_result xor c_in after tpd;
    sum <= xor2_result after tpd;
    
    -- 计算 c_out,这里采用一种不同的逻辑组合方式
    c_out <= or1_result or or2_result after 2*tpd;
end delay_based;
library ieee;
use ieee.std_logic_1164.all;

entity full_adder1 is
  generic(tpd : time := 10 ns);
  port(
    x     : in  std_logic;
    y     : in  std_logic;
    c_in  : in  std_logic;
    sum   : out std_logic;
    c_out : out std_logic
  );
end full_adder1;

architecture behavioural_view of full_adder1 is
begin
  process(x, y, c_in)  
    variable n : integer;
    constant sum_vector  : std_logic_vector(0 to 3) := "0101";
    constant carry_vector: std_logic_vector(0 to 3) := "0011";
  begin
    n := 0;
    if x = '1' then n := n + 1; end if;
    if y = '1' then n := n + 1; end if;
    if c_in = '1' then n := n + 1; end if;
    
    sum   <= sum_vector(n) after 2 * tpd;
    c_out <= carry_vector(n) after 3 * tpd;
  end process;
end behavioural_view;
library ieee;
use ieee.std_logic_1164.all;

entity full_adder2 is
    generic(tpd : time := 10 ns);
    port(
        x, y, c_in : in std_logic;
        sum, c_out : out std_logic
    );
end full_adder2;

architecture dataflow_view of full_adder2 is
    signal s : std_logic;
begin
    s <= x xor y after tpd;
    sum <= s xor c_in after tpd;
    c_out <= (x and y) or (s and c_in) after 2 * tpd;
end dataflow_view;
library ieee;
use ieee.std_logic_1164.all;

entity full_adder3 is
    generic(tpd : time := 10 ns);
    port(
        x, y, c_in : in std_logic;
        sum, c_out : out std_logic
    );
end full_adder3;

architecture structural_view of full_adder3 is
    component half_adder
        port(
            in1, in2 : in std_logic;
            sum, carry : out std_logic
        );
    end component;

    component or_gate
        port(
            in1, in2 : in std_logic;
            out1 : out std_logic
        );
    end component;

    signal a, b, c : std_logic;

begin
    u1 : half_adder port map(x, y, b, a);
    u2 : half_adder port map(c_in, b, sum, c);
    u3 : or_gate port map(c, a, c_out);
end structural_view;

library ieee;
use ieee.std_logic_1164.all;

entity half_adder is
    generic(tpd : time := 10 ns);
    port(
        in1, in2 : in std_logic;
        sum, carry : out std_logic
    );
end half_adder;

architecture behav of half_adder is
begin
    process(in1, in2)
    begin
        sum <= in1 xor in2 after tpd;
        carry <= in1 and in2 after tpd;
    end process;
end behav;


library ieee;
use ieee.std_logic_1164.all;

entity or_gate is
    generic(tpd : time := 10 ns);
    port(
        in1, in2 : in std_logic;
        out1 : out std_logic
    );
end or_gate;

architecture arch1 of or_gate is
begin
    out1 <= in1 or in2 after tpd;
end arch1;

哈夫曼编码

哈夫曼编码是一种基于贪心算法的无损数据压缩方法,由David A. Huffman于1952年提出。其核心思想是为频率高的字符分配较短的编码,频率低的字符分配较长的编码,从而减少整体存储空间。以下是详细介绍及示例:


哈夫曼编码原理

  1. 统计字符频率:统计待编码数据中各字符的出现频率。
  2. 构建优先队列:将每个字符视为一个叶子节点,按频率升序排列。
  3. 合并节点:重复取出频率最小的两个节点,合并为父节点(其频率为子节点之和),将父节点放回队列,直至只剩一个根节点。
  4. 生成编码:从根到叶子的路径标记为0(左)或1(右),路径序列即为字符的哈夫曼编码。

示例说明

假设字符集为 A、B、C、D,频率分别为 A:4,B:2,C:1,D:1

步骤1:统计频率

字符 频率
A 4
B 2
C 1
D 1

步骤2:构建初始队列

按频率升序排列:C(1)、D(1)、B(2)、A(4)

步骤3:合并节点

  1. 第一次合并:C(1) 和 D(1) 合并为父节点 2
    • 新队列:B(2)、2、A(4)
  2. 第二次合并:B(2) 和父节点2合并为父节点 4
    • 新队列:4、A(4)
  3. 第三次合并:4 和 A(4) 合并为根节点 8
    • 队列只剩根节点,构建完成。

步骤4:生成编码

根据树结构分配编码(左为0,右为1):

  • A:根节点左路径 → 0
  • B:根→右→左 → 10
  • C:根→右→右→左 → 110
  • D:根→右→右→右 → 111

最终编码表:

字符 编码
A 0
B 10
C 110
D 111

编码效率分析

  • 平均编码长度

    (1×4)+(2×2)+(3×1)+(3×1)4+2+1+1=148=1.75 位/字符.4+2+1+1(1×4)+(2×2)+(3×1)+(3×1)=814=1.75 位/字符.

  • 定长编码对比:若用2位固定编码(如00,01,10,11),平均长度为2位/字符。哈夫曼编码节省了12.5%的空间。


特点与优势

  1. 前缀编码:无歧义,任何编码都不是其他编码的前缀。
  2. 最优性:在给定字符频率下,哈夫曼编码的平均长度最短。
  3. 应用广泛:ZIP压缩、JPEG图像、MP3音频等均采用哈夫曼编码。

总结

哈夫曼编码通过动态调整编码长度,显著提升压缩效率,尤其适用于字符频率差异较大的场景。其构造过程直观体现了贪心算法的思想,是数据压缩领域的经典算法。

百词斩

posted @ 2025-03-24 22:26  Pikature  阅读(49)  评论(0)    收藏  举报