Код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library unisim;
use unisim.vcomponents.all;
------------------------------------------------------------------------------------
entity adc_dac_top is
Port ( spi_sck : out std_logic :='0';
spi_sdo : in std_logic;
spi_sdi : out std_logic := '0';
spi_rom_cs : out std_logic := '1';
spi_amp_cs : out std_logic := '1';
spi_adc_conv : out std_logic := '0';
spi_dac_cs : out std_logic := '1';
spi_amp_shdn : out std_logic := '0';
spi_amp_sdo : in std_logic;
spi_dac_clr : out std_logic := '1';
strataflash_oe : out std_logic := '1';
strataflash_ce : out std_logic := '1';
strataflash_we : out std_logic := '1';
platformflash_oe : out std_logic := '0';
led : out std_logic_vector(7 downto 0);
clk50 : in std_logic);
end adc_dac_top;
------------------------------------------------------------------------------------
-- Start of test architecture
architecture Behavioral of adc_dac_top is
signal int_count : integer range 0 to 63 :=0;
signal clka : std_logic := '1';
signal dac_B_en, dac_set_en, dac_en, amp_en, adc_en ,val_data, dac_set_tmp_en : std_logic :='0';
signal amp_count, adc_count, dac_count : integer range -1 to 62 :=0;
signal arb_count : integer range 0 to 16383 :=0;
signal data, dac_B_data, dac_A_data, orig_ADC_data, ADC_data_plus,ADC_data_minus : std_logic_vector(11 downto 0);
signal tmp1 : std_logic_vector(10 downto 0);
signal tmp2 : std_logic_vector(9 downto 0);
signal tmp3 : std_logic_vector(7 downto 0);
signal dac_data : std_logic_vector(19 downto 0);
signal adc_data, reg : std_logic_vector(13 downto 0);
signal clk : std_logic:='0';
signal dac_spi_sdi, amp_spi_sdi : std_logic:='0';
signal v_up, v_dn :boolean :=false;
signal dac_set, dac_set_tmp :integer range 1 to 3 :=2;
constant cc :integer :=7;
constant ca :integer :=0;
signal data_en : std_logic :='0';
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Start of circuit description
begin
----------------------------------------------------------------------------------------------------------------------------------
-- Clock for Amp
----------------------------------------------------------------------------------------------------------------------------------
clkaa: process(clk50)
begin
if (clk50'event and clk50='1') then
if int_count=50 then
int_count <= 0;
clka <= not clka;
else
int_count <= int_count + 1;
end if;
end if;
end process clkaa;
----------------------------------------------------------------------------------------------------------------------------------
-- Amp
----------------------------------------------------------------------------------------------------------------------------------
amp_clk: process(clka, amp_en)
begin
if (clka'event and clka='1') then
if amp_en='1' then
amp_count <= amp_count + 1;
else
amp_count <= 0;
end if;
end if;
end process amp_clk;
amp: process(clka, amp_count)
begin
if (clka'event and clka='0') then
case amp_count-1 is
when 0 =>
spi_amp_cs <= '0';
amp_spi_sdi <= '0';
when 1 =>
spi_amp_cs <= '0';
amp_spi_sdi <= '0';
when 2 =>
spi_amp_cs <= '0';
amp_spi_sdi <= '0';
when 3 =>
spi_amp_cs <= '0';
amp_spi_sdi <= '1';
when 4 =>
spi_amp_cs <= '0';
amp_spi_sdi <= '0';
when 5 =>
spi_amp_cs <= '0';
amp_spi_sdi <= '0';
when 6 =>
spi_amp_cs <= '0';
amp_spi_sdi <= '0';
when 7 =>
spi_amp_cs <= '0';
amp_spi_sdi <= '1';
when 8 =>
spi_amp_cs <= '1';
amp_spi_sdi <= 'Z';
when others =>
null;
end case;
end if;
end process amp;
----------------------------------------------------------------------------------------------------------------------------------
-- Serial to Parallel
----------------------------------------------------------------------------------------------------------------------------------
-- s_to_p: process(clk, val_data)
-- begin
-- if clk'event and clk='0' and adc_en='1' then
-- reg <= reg (1 to 13) & spi_sdo;
-- end if;
-- end process s_to_p;
----------------------------------------------------------------------------------------------------------------------------------
-- ADC
----------------------------------------------------------------------------------------------------------------------------------
adc_clk: process(clk, adc_en)
begin
if (clk'event and clk='1') then
if adc_en='1' then
adc_count <= adc_count + 1;
else
adc_count <= 0;
end if;
end if;
end process adc_clk;
adc:process(clk, adc_count)
begin
if (clk'event and clk='0') then
case adc_count-1 is
when 0 =>
data_en <='0';
spi_adc_conv <= '1';
when 1 =>
data_en <='0';
spi_adc_conv <= '0';
when 4=>
data_en <='0';
spi_adc_conv <= '0';
reg(13) <= spi_sdo;
when 5=>
data_en <='0';
spi_adc_conv <= '0';
reg(12) <= spi_sdo;
when 6=>
data_en <='0';
spi_adc_conv <= '0';
reg(11) <= spi_sdo;
when 7=>
data_en <='0';
spi_adc_conv <= '0';
reg(10) <= spi_sdo;
when 8=>
data_en <='0';
spi_adc_conv <= '0';
reg(9) <= spi_sdo;
when 9=>
data_en <='0';
spi_adc_conv <= '0';
reg(8) <= spi_sdo;
when 10=>
data_en <='0';
spi_adc_conv <= '0';
reg(7) <= spi_sdo;
when 11=>
data_en <='0';
spi_adc_conv <= '0';
reg(6) <= spi_sdo;
when 12=>
data_en <='0';
spi_adc_conv <= '0';
reg(5) <= spi_sdo;
when 13=>
data_en <='0';
spi_adc_conv <= '0';
reg(4) <= spi_sdo;
when 14=>
data_en <='0';
spi_adc_conv <= '0';
reg(3) <= spi_sdo;
when 15=>
data_en <='0';
spi_adc_conv <= '0';
reg(2) <= spi_sdo;
when 16=>
data_en <='0';
spi_adc_conv <= '0';
reg(1) <= spi_sdo;
when 17=>
data_en <='1';
spi_adc_conv <= '0';
reg(0) <= spi_sdo;
when 18=>
data_en <='0';
spi_adc_conv <= '0';
when others =>
null;
end case;
end if;
end process adc;
----------------------------------------------------------------------------------------------------------------------------------
-- DAC
----------------------------------------------------------------------------------------------------------------------------------
dac_clk: process(clk, dac_en)
begin
if clk'event and clk='0' then
if dac_en='1' then
dac_count <= dac_count + 1;
else
dac_count <= 0;
end if;
end if;
end process dac_clk;
dac: process(dac_count)
begin
case dac_count-1 is
when 0 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(19);
when 1 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(18);
when 2 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(17);
when 3 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(16);
when 4 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(15);
when 5 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(14);
when 6 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(13);
when 7 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(12);
when 8 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(11);
when 9 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(10);
when 10 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(9);
when 11 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(8);
when 12 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(7);
when 13 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(6);
when 14 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(5);
when 15 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(4);
when 16 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(3);
when 17 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(2);
when 18 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(1);
when 19 =>
spi_dac_cs <='0';
dac_spi_sdi <= dac_data(0);
when 20 =>
spi_dac_cs <='0';
dac_spi_sdi <= 'Z';
when 24 =>
spi_dac_cs <='1';
dac_spi_sdi <= 'Z';
when others =>
null;
end case;
end process dac;
----------------------------------------------------------------------------------------------------------------------------------
-- Arbitor
----------------------------------------------------------------------------------------------------------------------------------
spi_sdi <= amp_spi_sdi when amp_en = '1' else dac_spi_sdi;
arbitor: process(clk)
begin
if clk'event and clk='0' then
arb_count <= arb_count+1;
case arb_count is
when 1 =>
dac_set_en <='0';
amp_en <= '1';
adc_en <= '0';
dac_en <= '0';
dac_B_en <='0';
dac_set_tmp_en <='0';
when 1000 => -- start loop ADC
dac_set_en <='0';
amp_en <= '0';
adc_en <='1';
dac_en <='0';
dac_B_en <='0';
dac_set_tmp_en <='0';
when 1019+cc => -- DAC B
dac_set_en <='1';
amp_en <= '0';
adc_en <='0';
dac_en <='1';
dac_B_en <='1';
dac_set_tmp_en <='0';
when 1020+cc => -- DAC B
dac_set_en <='0';
amp_en <= '0';
adc_en <='0';
dac_en <='1';
dac_B_en <='1';
dac_set_tmp_en <='1';
when 1021+cc => -- DAC B
dac_set_en <='0';
amp_en <= '0';
adc_en <='0';
dac_en <='1';
dac_B_en <='1';
dac_set_tmp_en <='0';
when 1044+cc => -- restart DAC
dac_set_en <='0';
amp_en <= '0';
adc_en <='0';
dac_en <='0';
dac_B_en <='0';
dac_set_tmp_en <='0';
when 1045+cc => -- DAC A
dac_set_en <='0';
amp_en <= '0';
adc_en <='0';
dac_en <='1';
dac_B_en <='0';
dac_set_tmp_en <='0';
when 1070+cc => -- return 1069
dac_set_en <='0';
amp_en <= '0';
adc_en <='0';
dac_en <='0';
dac_B_en <='0';
dac_set_tmp_en <='0';
when 16383 => -- return 1069
dac_set_en <='0';
amp_en <= '0';
adc_en <='0';
dac_en <='0';
dac_B_en <='0';
dac_set_tmp_en <='0';
arb_count <= 1000;
when others =>
null;
end case;
end if;
end process arbitor;
adc_data <= reg when data_en='1' else adc_data;
----------------------------------------------------------------------------------------------------------------------------------
-- SPI CLOCK
----------------------------------------------------------------------------------------------------------------------------------
clk <= clk50;
spi_sck <= clka when amp_en='1' else clk;
data <= adc_data(13 downto 2) xor "100000000000";
led <= data(11 downto 4);
tmp1 <= not data(11 downto 1);
tmp2 <= tmp1(10 downto 1);
orig_ADC_data <= "000111110000" + tmp1 + tmp2;
ADC_data_plus <= orig_ADC_data + "001001101100";
ADC_data_minus <= orig_ADC_data - "001001101100";
dac_A_data <= ADC_data_minus when dac_set=1 else
ADC_data_plus when dac_set=3 else
orig_ADC_data;
dac_data <= "00100001" & dac_B_data when dac_B_en='1' else "00100000" & dac_A_data;
tmp3 <= data(11 downto 4);
v_up <= true when tmp3 < "00111101" else false; --ADC > 2.3
v_dn <= true when tmp3 > "11100010" else false; --ADC < 0.7
dac_B_data <= "010011011001" when dac_set=1 else --DAC_B = 1
"100110110010" when dac_set=3 else --DAC_B = 2
"011101000101"; --DAC_B = 1.5
dac_set_tmp <=
1 when dac_set_en = '1' and v_up and dac_set=2 else
2 when dac_set_en = '1' and v_up and dac_set=3 else
3 when dac_set_en = '1' and v_dn and dac_set=2 else
2 when dac_set_en = '1' and v_dn and dac_set=1;
dac_set <= dac_set_tmp when dac_set_tmp_en='1' else dac_set;
spi_rom_cs <= '1';
spi_amp_shdn <= '0';
spi_dac_clr <= '1';
strataflash_oe <= '1';
strataflash_ce <= '1';
strataflash_we <= '1';
platformflash_oe <= '0';
end Behavioral;
попробую пояснить, что этот дизайн делает.
1. Есть арбитр (счетчик arb_count), который управляет 2мя spi устройтсвамм (АЦП и ЦАП).
2. происходит считывание данных их АЦП.
3. производиться некоторая АСИНХРОННАЯ обработка данных, после чего получается два кода для ЦАП.
4. Первый код передается на ЦАП - устанавливает заданное кодом напряжение на первом выходе ЦАП
5. Второй код передается на ЦАП - устанавливает заданное кодом напряжение на втором выходе ЦАП
6. переход на шаг 2 при достижении счетчиком определнного значения.
Так вот если умешать разрядность счетчика arb_count - перестает адекватно АЦП на изменение напряжения работать - выдает не правильные данные. Такая же ситуация происходит если увеличивать число тактов между работой АЦП и ЦАП. Вот такая ситуевина :\ хочеться дизайн усложнить, а начинаешь что-то менять престает правильно работать %\