Project

General

Profile

518 markw
---------------------------------------------------------------------------
-- (c) 2017 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
532 markw
use IEEE.STD_LOGIC_MISC.all;
518 markw
-- 3.2MHz to 8 MHz, rather thsn 400KHz...
-- Different data in and data in - is it still i2c?
-- Write data in 16 cycles -> clocked in on rising edge
-- Result in out -> clocked on failling edge
--
-- 16 cycle process
-- data_in is ctrl7,ctrl6,ctrl5,ctrl4,ctrl3,ctrl2,ctrl1,ctrl0,na*8
-- data_out is l,l,l,l,d7,d6,d5,d4,d3,d2,d1,d0,l,l,l,l,l
-- cs-> low, 4 clock cycles then data

ENTITY adc084 IS
PORT
(
CLK : IN STD_LOGIC; -- about 58MHz...
RESET_N : IN STD_LOGIC;

-- ADC side
CS : OUT STD_LOGIC;
SCLK : OUT STD_LOGIC;
DOUT : IN STD_LOGIC;
DIN : OUT STD_LOGIC;

-- SAMPLED side
CH1OUT : OUT STD_LOGIC_VECTOR(7 downto 0);
CH2OUT : OUT STD_LOGIC_VECTOR(7 downto 0);
CH3OUT : OUT STD_LOGIC_VECTOR(7 downto 0);
CH4OUT : OUT STD_LOGIC_VECTOR(7 downto 0)
);
END adc084;

ARCHITECTURE vhdl OF adc084 IS
532 markw
signal cycle_next : std_logic_vector(21 downto 0);
signal cycle_reg : STD_LOGIC_VECTOR(21 DOWNTO 0);
518 markw
signal channel_next : std_logic_vector(1 downto 0);
signal channel_reg : std_logic_vector(1 downto 0);

signal sclk_next : std_logic;
signal sclk_reg : std_logic;

531 markw
signal alt_next : std_logic;
signal alt_reg : std_logic;

518 markw
signal din_next : std_logic;
signal din_reg : std_logic;

signal cs_reg : std_logic;
531 markw
signal cs_next : std_logic;
518 markw
signal enable : std_logic;

signal cap_next : std_logic_vector(7 downto 0);
signal cap_reg : std_logic_vector(7 downto 0);

signal ch1_next : std_logic_vector(7 downto 0);
signal ch2_next : std_logic_vector(7 downto 0);
signal ch3_next : std_logic_vector(7 downto 0);
signal ch4_next : std_logic_vector(7 downto 0);

signal ch1_reg : std_logic_vector(7 downto 0);
signal ch2_reg : std_logic_vector(7 downto 0);
signal ch3_reg : std_logic_vector(7 downto 0);
signal ch4_reg : std_logic_vector(7 downto 0);

signal store : std_logic;
BEGIN
-- regs
process(clk, reset_n)
begin
if (reset_n='0') then
532 markw
cycle_reg <= "0000000000000000000001";
518 markw
channel_reg <= "01";
ch1_reg <= (others=>'0');
ch2_reg <= (others=>'0');
ch3_reg <= (others=>'0');
ch4_reg <= (others=>'0');
cap_reg <= (others=>'0');
529 markw
sclk_reg <= '1';
518 markw
din_reg <= '0';
cs_reg <= '1';
531 markw
alt_reg <= '1';
518 markw
elsif (clk'event and clk='1') then
cycle_reg <= cycle_next;
channel_reg <= channel_next;
ch1_reg <= ch1_next;
ch2_reg <= ch2_next;
ch3_reg <= ch3_next;
ch4_reg <= ch4_next;
cap_reg <= cap_next;
sclk_reg <= sclk_next;
din_reg <= din_next;
531 markw
cs_reg <= cs_next;
alt_reg <= alt_next;
518 markw
end if;
end process;

enable_div_clk : entity work.enable_divider
generic map (COUNT=>8) -- cycle_length
port map(clk=>clk,reset_n=>reset_n,enable_in=>'1',enable_out=>enable);

-- main coms engine
531 markw
process(enable,cycle_reg,cap_reg,din_reg,alt_reg,sclk_reg,cs_reg,channel_reg,dout)
518 markw
begin
cycle_next <= cycle_reg;
cap_next <= cap_reg;
sclk_next <= sclk_reg;
531 markw
alt_next <= alt_reg;
cs_next <= cs_reg;
518 markw
529 markw
din_next <= din_reg;
518 markw
store <= '0';

if (enable='1') then
532 markw
sclk_next <= or_reduce(not(sclk_reg)&cycle_reg(21 downto 16));
cs_next <= or_reduce(cycle_reg(20 downto 17));
531 markw
alt_next <= not(alt_reg);
if (alt_reg = '1') then -- was 1, next is 0 -> falling edge
518 markw
din_next <= (channel_reg(1) and cycle_reg(3)) or (channel_reg(0) and cycle_reg(4));
529 markw
end if;
518 markw
531 markw
if (alt_reg = '0') then -- was 0, next is 1 -> rising edge
532 markw
cycle_next <= cycle_reg(20 downto 0)&cycle_reg(21);
518 markw
cap_next(0) <= dout;

cap_next(7 downto 1) <= cap_reg(6 downto 0);
-- signal cap_next : std_logic_vector(7 downto 0);
-- signal cap_reg : std_logic_vector(7 downto 0);

530 markw
store <= cycle_reg(12);
518 markw
end if;
end if;
end process;

-- store channel
process(store,channel_reg,cap_reg,ch1_reg,ch2_reg,ch3_reg,ch4_reg)
begin
channel_next <= channel_reg;
ch1_next <= ch1_reg;
ch2_next <= ch2_reg;
ch3_next <= ch3_reg;
ch4_next <= ch4_reg;

if (store = '1') then
575 markw
channel_next <= std_logic_vector(unsigned(channel_reg) + 1);
--channel_next <= "01";
--ch2_next <= cap_reg;
518 markw
575 markw
case channel_reg is
when "00" =>
ch4_next <= cap_reg;
when "01" =>
ch1_next <= cap_reg;
when "10" =>
ch2_next <= cap_reg;
when "11" =>
ch3_next <= cap_reg;
when others =>
end case;
518 markw
end if;
end process;

sclk <= sclk_reg;
din <= din_reg;
cs <= cs_reg;
ch1out <= ch1_reg;
ch2out <= ch2_reg;
ch3out <= ch3_reg;
ch4out <= ch4_reg;

END vhdl;