--
-- adc_ctrl.vhd
--
-- Control For ADC Module
--
-- Also include simulation data SDRAM
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;
library work;
use work.common_interface.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity adc_ctrl is
port (
clk : in std_logic;
rst : in std_logic;
system_in : in std_logic_vector(system_width-1 downto 0);
system_out : out std_logic_vector(system_width-1 downto 0);
adc_in_0_0 : in std_logic_vector(13 downto 0);
adc_in_0_1 : in std_logic_vector(13 downto 0);
adc_in_0_2 : in std_logic_vector(13 downto 0);
adc_in_1_0 : in std_logic_vector(13 downto 0);
adc_in_1_1 : in std_logic_vector(13 downto 0);
adc_in_1_2 : in std_logic_vector(13 downto 0);
adc_in_2_0 : in std_logic_vector(13 downto 0);
adc_in_2_1 : in std_logic_vector(13 downto 0);
adc_in_2_2 : in std_logic_vector(13 downto 0);
adc_out_0_0 : out std_logic_vector(13 downto 0);
adc_out_0_1 : out std_logic_vector(13 downto 0);
adc_out_0_2 : out std_logic_vector(13 downto 0);
adc_out_1_0 : out std_logic_vector(13 downto 0);
adc_out_1_1 : out std_logic_vector(13 downto 0);
adc_out_1_2 : out std_logic_vector(13 downto 0);
adc_out_2_0 : out std_logic_vector(13 downto 0);
adc_out_2_1 : out std_logic_vector(13 downto 0);
adc_out_2_2 : out std_logic_vector(13 downto 0);
adc_enb : out std_logic_vector(2 downto 0);
syn_rst : out std_logic;
fref_test : out std_logic;
user_leds : out std_logic_vector(1 downto 0));
end adc_ctrl;
architecture rtl of adc_ctrl is
constant ncomponents : integer := 5;
type sys_bus_type is array (0 to ncomponents) of std_logic_vector(system_width-1 downto 0);
signal s : sys_bus_type;
signal adc_control_reg : std_logic_vector(31 downto 0);
signal test_data_control_reg : std_logic_vector(31 downto 0);
signal test_data_length_reg : std_logic_vector(31 downto 0);
signal sdram_q : std_logic_vector(63 downto 0);
signal sdram_addr : std_logic_vector(24 downto 0);
signal sdram_qv : std_logic;
signal sdram_r : std_logic;
signal sdram_busy : std_logic;
signal sdram_gnt : std_logic;
component sync_fifo
generic (
width : natural := 32);
port (
clk : in std_logic;
rst : in std_logic;
wadv : in std_logic;
wdata : in std_logic_vector(width-1 downto 0);
wnfull : out std_logic;
wfull : out std_logic;
hfull : out std_logic;
radv : in std_logic;
rdw_out : out std_logic_vector(width-1 downto 0);
rempty : out std_logic;
rnempty : out std_logic);
end component;
signal start_addr : std_logic_vector(24 downto 0);
signal read_running : std_logic;
signal write_running : std_logic;
signal count : std_logic_vector(24 downto 0);
signal fifo_hfull : std_logic;
signal rf_reg : std_logic;
signal read_fifo : std_logic;
signal fifo_empty : std_logic;
signal fifo_data : std_logic_vector(63 downto 0);
signal adc_sim_data : std_logic_vector(31 downto 0);
signal mem_req : std_logic;
signal adc_status : std_logic_vector(31 downto 0);
begin -- rtl
s(0) <= system_in;
creg0 : readable_control_register
generic map (
width => 32, addr => 1)
port map (
clk => clk, rst => rst, system_in => s(0), system_out => s(1),
control_data => adc_control_reg, control_wstb => open);
creg1 : readable_control_register
generic map (
width => 32, addr => 3)
port map (
clk => clk, rst => rst, system_in => s(1), system_out => s(2),
control_data => test_data_control_reg, control_wstb => open);
creg2 : readable_control_register
generic map (
width => 32, addr => 4)
port map (
clk => clk, rst => rst, system_in => s(2), system_out => s(3),
control_data => test_data_length_reg, control_wstb => open);
sreg2 : status_register
generic map (
width => 32, addr => 5)
port map (
clk => clk, rst => rst, system_in => s(3), system_out => s(4),
status_data => adc_status);
dram3 : external_memory
generic map (
width => 64,
depth => 25,
bank_id => 3)
port map(
clk => clk,
rst => rst,
system_in => s(4),
system_out => s(5),
w => '0',
a => sdram_addr,
d => X"0000000000000000",
q => sdram_q,
qv => sdram_qv,
r => sdram_r,
full => sdram_busy,
req => mem_req,
gnt => sdram_gnt);
system_out <= s(5);
rd_wr_sdram: process (clk, rst)
begin -- process rd_wr_sdram
if rst = '1' then -- asynchronous reset (active low)
sdram_addr <= (others => '0');
sdram_r <= '0';
read_running <= '0';
write_running <= '0';
rf_reg <= '0';
read_fifo <= '0';
adc_sim_data <= (others => '0');
mem_req <= '0';
adc_status <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
start_addr <= test_data_control_reg(24 downto 0);
mem_req <= test_data_control_reg(25);
adc_status <= EXT(sdram_gnt & sdram_busy & fifo_hfull & write_running & read_running & sdram_addr,32);
if test_data_control_reg(25) = '0' then
read_running <= '0';
write_running <= '0';
sdram_r <= '0';
read_fifo <= not fifo_empty;
else
sdram_r <= (not sdram_busy) and (sdram_gnt) and (not fifo_hfull);
if read_running = '0' then
read_running <= '1';
sdram_addr <= test_data_control_reg(24 downto 0);
count <= CONV_STD_LOGIC_VECTOR(1,25);
else
if sdram_busy = '0' and sdram_gnt = '1' and fifo_hfull = '0' then
if count = test_data_length_reg(24 downto 0) then
sdram_addr <= start_addr;
count <= CONV_STD_LOGIC_VECTOR(1,25);
else
count <= count+1;
sdram_addr <= sdram_addr+1;
end if;
end if;
end if;
if write_running = '0' then
if fifo_hfull = '1' then
write_running <= '1';
rf_reg <= '0';
end if;
else
rf_reg <= not rf_reg;
read_fifo <= rf_reg;
if rf_reg = '1' then
adc_sim_data <= fifo_data(31 downto 0);
else
adc_sim_data <= fifo_data(63 downto 32);
end if;
end if;
end if;
end if;
end process rd_wr_sdram;
read_fifo0: sync_fifo
generic map (
width => 64)
port map (
clk => clk,
rst => rst,
wdata => sdram_q,
wadv => sdram_qv,
hfull => fifo_hfull,
wnfull => open,
wfull => open,
radv => read_fifo,
rdw_out => fifo_data,
rempty => fifo_empty);
mux_data: process (clk)
begin -- process mux_data
if clk'event and clk = '1' then -- rising clock edge
fref_test <= adc_sim_data(0);
if adc_control_reg(0) = '1' then
adc_out_0_0 <= adc_in_0_0;
else
adc_out_0_0 <= adc_sim_data(11 downto 1) & "000";
end if;
if adc_control_reg(1) = '1' then
adc_out_0_1 <= adc_in_0_1;
else
adc_out_0_1 <= adc_sim_data(21 downto 12) & "0000" ;
end if;
if adc_control_reg(2) = '1' then
adc_out_0_2 <= adc_in_0_2;
else
adc_out_0_2 <= adc_sim_data(31 downto 22) & "0000";
end if;
if adc_control_reg(3) = '1' then
adc_out_1_0 <= adc_in_1_0;
else
adc_out_1_0 <= adc_sim_data(11 downto 1) & "000";
end if;
if adc_control_reg(4) = '1' then
adc_out_1_1 <= adc_in_1_1;
else
adc_out_1_1 <= adc_sim_data(21 downto 12) & "0000";
end if;
if adc_control_reg(5) = '1' then
adc_out_1_2 <= adc_in_1_2;
else
adc_out_1_2 <= adc_sim_data(31 downto 22) & "0000";
end if;
if adc_control_reg(6) = '1' then
adc_out_2_0 <= adc_in_2_0;
else
adc_out_2_0 <= adc_sim_data(11 downto 1) & "000";
end if;
if adc_control_reg(7) = '1' then
adc_out_2_1 <= adc_in_2_1;
else
adc_out_2_1 <= adc_sim_data(21 downto 12) & "0000";
end if;
if adc_control_reg(8) = '1' then
adc_out_2_2 <= adc_in_2_2;
else
adc_out_2_2 <= adc_sim_data(31 downto 22) & "0000";
end if;
adc_enb <= adc_control_reg(6) & adc_control_reg(3) & adc_control_reg(0);
syn_rst <= adc_control_reg(9);
user_leds <= adc_control_reg(11 downto 10);
end if;
end process mux_data;
end rtl;