📄 dac.vhd
字号:
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- The Free IP Project
-- VHDL Free-DAC Core
-- (c) 2000, The Free IP Project and David Kessner
--
--
-- FREE IP GENERAL PUBLIC LICENSE
-- TERMS AND CONDITIONS FOR USE, COPYING, DISTRIBUTION, AND MODIFICATION
--
-- 1. You may copy and distribute verbatim copies of this core, as long
-- as this file, and the other associated files, remain intact and
-- unmodified. Modifications are outlined below.
-- 2. You may use this core in any way, be it academic, commercial, or
-- military. Modified or not.
-- 3. Distribution of this core must be free of charge. Charging is
-- allowed only for value added services. Value added services
-- would include copying fees, modifications, customizations, and
-- inclusion in other products.
-- 4. If a modified source code is distributed, the original unmodified
-- source code must also be included (or a link to the Free IP web
-- site). In the modified source code there must be clear
-- identification of the modified version.
-- 5. Visit the Free IP web site for additional information.
-- http://www.free-ip.com
--
----------------------------------------------------------------------------
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
package free_dac_lib is
component dac_ds
generic (n_bits :integer);
port (reset :in std_logic;
clk :in std_logic;
din :in std_logic_vector (n_bits-1 downto 0);
dout :out std_logic
);
end component;
component dac_pwm
generic (n_bits :integer);
port (reset :in std_logic;
clk :in std_logic;
din :in std_logic_vector (n_bits-1 downto 0);
dout :out std_logic
);
end component;
component dac_pwm2
generic (n_bits :integer);
port (reset :in std_logic;
clk :in std_logic;
period :in std_logic_vector (n_bits-1 downto 0);
width :in std_logic_vector (n_bits-1 downto 0);
dout :out std_logic
);
end component;
end package;
-----------------------------------------------------------------------------
-- First Order Delta Sigma DAC
-----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.free_dac_lib.all;
entity dac_ds is
generic (n_bits :integer);
port (reset :in std_logic;
clk :in std_logic;
din :in std_logic_vector (n_bits-1 downto 0); -- Signed integer
dout :out std_logic
);
end dac_ds;
architecture arch_dac_ds of dac_ds is
signal error :std_logic_vector (n_bits+1 downto 0); -- Error accumulator is 2 bits larger
constant zeros :std_logic_vector (n_bits-1 downto 0) := (others=>'0');
begin
process (reset, clk, din)
variable val :std_logic_vector (n_bits+1 downto 0);
begin
if reset='1' then
error <= (others=>'0');
dout <= '0';
elsif clk'event and clk='1' then
-- val := din + error; din is sign extended to nbits+2
val := (din(din'high) & din(din'high) & din) + error;
if val(val'high) = '0' then
dout <= '1';
error <= val + ("11" & zeros);
else
dout <= '0';
error <= val + ("01" & zeros);
end if;
end if;
end process;
end arch_dac_ds;
-----------------------------------------------------------------------------
-- DAC via Pulse Width Modulation
-----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.free_dac_lib.all;
entity dac_pwm is
generic (n_bits :integer);
port (reset :in std_logic;
clk :in std_logic;
din :in std_logic_vector (n_bits-1 downto 0); -- unsigned integer
dout :out std_logic
);
end dac_pwm;
architecture arch_dac_pwm of dac_pwm is
signal period_counter :std_logic_vector (din'range);
signal width_counter :std_logic_vector (din'range);
signal last :std_logic;
signal last_d :std_logic;
signal width_flag :std_logic;
constant zeros :std_logic_vector (n_bits-2 downto 0) := (others=>'0');
begin
-- The period counter
process (reset, clk)
begin
if reset='1' then
period_counter <= (others=>'1');
elsif clk'event and clk='1' then
period_counter <= period_counter - 1;
end if;
end process;
-- The last cycle flag. Active on the last cycle of the period
process (reset, clk)
begin
if reset='1' then
last <= '0';
last_d <= '0';
elsif clk'event and clk='1' then
last_d <= last;
if period_counter = (zeros & "1") then
last <= '1';
else
last <= '0';
end if;
end if;
end process;
-- The width coutner
process (reset, clk)
begin
if reset='1' then
width_counter <= (others=>'0');
width_flag <= '0';
elsif clk'event and clk='1' then
if width_counter = (zeros & "0") then
width_flag <= '1';
else
width_flag <= '0';
end if;
if last='1' then
width_counter <= din;
else
width_counter <= width_counter-1;
end if;
end if;
end process;
-- The output
process (reset, clk)
begin
if reset='1' then
dout <= '0';
elsif clk'event and clk='1' then
if last='1' then
dout <= '1';
elsif width_flag='1' then
dout <= '0';
end if;
end if;
end process;
end arch_dac_pwm;
-----------------------------------------------------------------------------
-- DAC via Pulse Width Modulation - with variable pulse frequency
-----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.free_dac_lib.all;
entity dac_pwm2 is
generic (n_bits :integer);
port (reset :in std_logic;
clk :in std_logic;
period :in std_logic_vector (n_bits-1 downto 0); -- unsigned
width :in std_logic_vector (n_bits-1 downto 0); -- unsigned
dout :out std_logic
);
end dac_pwm2;
architecture arch_dac_pwm2 of dac_pwm2 is
signal period_counter :std_logic_vector (period'range);
signal width_counter :std_logic_vector (period'range);
signal last :std_logic;
signal last_d :std_logic;
signal width_flag :std_logic;
constant zeros :std_logic_vector (n_bits-2 downto 0) := (others=>'0');
begin
-- The period counter
process (reset, clk)
begin
if reset='1' then
period_counter <= (others=>'1');
elsif clk'event and clk='1' then
if last='1' then
period_counter <= period;
else
period_counter <= period_counter - 1;
end if;
end if;
end process;
-- The last cycle flag. Active on the last cycle of the period
process (reset, clk)
begin
if reset='1' then
last <= '0';
last_d <= '0';
elsif clk'event and clk='1' then
last_d <= last;
if period_counter = (zeros & "1") then
last <= '1';
else
last <= '0';
end if;
end if;
end process;
-- The width coutner
process (reset, clk)
begin
if reset='1' then
width_counter <= (others=>'0');
width_flag <= '0';
elsif clk'event and clk='1' then
if width_counter = (zeros & "0") then
width_flag <= '1';
else
width_flag <= '0';
end if;
if last='1' then
width_counter <= width;
else
width_counter <= width_counter-1;
end if;
end if;
end process;
-- The output
process (reset, clk)
begin
if reset='1' then
dout <= '0';
elsif clk'event and clk='1' then
if last='1' then
dout <= '1';
elsif width_flag='1' then
dout <= '0';
end if;
end if;
end process;
end arch_dac_pwm2;
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -