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年提出。其核心思想是为频率高的字符分配较短的编码,频率低的字符分配较长的编码,从而减少整体存储空间。以下是详细介绍及示例:
哈夫曼编码原理
- 统计字符频率:统计待编码数据中各字符的出现频率。
- 构建优先队列:将每个字符视为一个叶子节点,按频率升序排列。
- 合并节点:重复取出频率最小的两个节点,合并为父节点(其频率为子节点之和),将父节点放回队列,直至只剩一个根节点。
- 生成编码:从根到叶子的路径标记为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:合并节点
- 第一次合并:C(1) 和 D(1) 合并为父节点 2。
- 新队列:B(2)、2、A(4)。
- 第二次合并:B(2) 和父节点2合并为父节点 4。
- 新队列:4、A(4)。
- 第三次合并: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%的空间。
特点与优势
- 前缀编码:无歧义,任何编码都不是其他编码的前缀。
- 最优性:在给定字符频率下,哈夫曼编码的平均长度最短。
- 应用广泛:ZIP压缩、JPEG图像、MP3音频等均采用哈夫曼编码。
总结
哈夫曼编码通过动态调整编码长度,显著提升压缩效率,尤其适用于字符频率差异较大的场景。其构造过程直观体现了贪心算法的思想,是数据压缩领域的经典算法。
百词斩


浙公网安备 33010602011771号