Im writing a VHDL code that allows connect ADC7475 (12 bit with 4 leading zeros(total 16 bit)) to FPGA board. My target is displaying the digital output value of ADC on 7 segment when provide analog signal (Vin pin of ADC). Here is my program:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
-----Interface-----
entity interface is port (
clk : in std_logic;
rst : in std_logic;
cs : out std_logic;
sclk : out std_logic;
digital_sig_in : in bit;
digital_sig_out: out integer);
end interface;
architecture Behavior of interface is
signal outclk : std_logic;
signal int_cs : std_logic;
signal counter1 : integer range 0 to 500 :=1;
signal counter2 : integer range 0 to 50 :=0;
signal cnt : integer range 0 to 50 :=0;
signal data_vector : std_logic_vector(15 downto 0) :="0000000000000000";
begin
process(clk, rst) --Clock generation clk=50Mhz -> sclk=50Khz
begin
if (rst='1') then
counter1 <= 0;
outclk <= '0';
elsif (clk = '1' and clk'event) then
counter1 <= counter1 + 1;
if (counter1 = 500) then
counter1 <= 0;
outclk <= not outclk;
end if;
end if;
end process;
sclk <= outclk;
process (outclk, rst) --CS generation
begin
if (rst='1') then
counter2 <= 0;
int_cs <='1';
elsif (outclk = '0' and outclk'event) then
counter2 <= counter2 + 1;
if (counter2 = 15) then
int_cs <= not int_cs;
counter2 <= 0;
cs <= int_cs;
end if;
end if;
end process;
process (outclk, int_cs, rst) --Serial signal assigning
variable i : integer range 15 downto 0 :=0;
variable data_temp : bit_vector(15 downto 0);
begin
if (rst = '1') then
i := 0;
data_temp := "0000000000000000";
elsif (int_cs = '0') then
if (outclk = '0' and outclk'event) then
i := i+1;
data_temp(15 downto 0) := digital_sig_in&data_temp(15 downto 1);
if (i=15) then
data_vector <= to_stdlogicvector(data_temp);
end if;
end if;
end if;
digital_sig_out <= conv_integer(data_vector);
end process;
end Behavior;
-----Segment-----
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity segment is port (
clk, rst: in std_logic;
data_in : in integer;
sel : out std_logic_vector(3 downto 0);
fnd : out std_logic_vector(7 downto 0));
end segment;
architecture Behavior of segment is
signal counter1: integer range 0 to 1500 :=0;
signal counter : integer range 0 to 3 :=0;
signal outclk : std_logic;
signal fnd_1,fnd_2,fnd_3,fnd_4 : std_logic_vector(7 downto 0);
function fnd_seg(num: integer range 0 to 9) return std_logic_vector is
begin
case num is
when 0 => return "11111100";
when 1 => return "01100000";
when 2 => return "11011010";
when 3 => return "11110010";
when 4 => return "01100110";
when 5 => return "10110110";
when 6 => return "10111110";
when 7 => return "11100100";
when 8 => return "11111110";
when 9 => return "11110110";
when others => return "11111100";
end case;
return "00000000";
end;
begin
fnd_1 <= fnd_seg((data_in/1000 ) mod 10);
fnd_2 <= fnd_seg((data_in/100) mod 10);
fnd_3 <= fnd_seg((data_in/10) mod 10);
fnd_4 <= fnd_seg(data_in mod 10);
clk_gen : process(clk, rst)
begin
if (rst='1') then
counter1 <= 0;
outclk <= '0';
elsif (clk = '1' and clk'event) then
if (counter1 >= 1000) then
counter1 <= 0;
outclk <= not outclk;
else
counter1 <= counter1 + 1;
outclk <= '0';
end if;
end if;
end process clk_gen;
fndsel : process(outclk, rst)
begin
if (rst='1') then
sel <= (others => '0');
fnd <= (others => '1');
elsif (outclk = '1' and outclk'event) then
counter <= counter + 1;
case counter is
when 0 => sel <="0111"; fnd <= fnd_1;
when 1 => sel <="1011"; fnd <= fnd_2;
when 2 => sel <="1101"; fnd <= fnd_3;
when others => sel <="1110"; fnd <= fnd_4;
end case;
end if;
end process fndsel;
end Behavior;
-----Top-Level Entity-----
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity adc is port (
--interface--
clk : in std_logic;
rst : in std_logic;
cs : out std_logic;
sclk : out std_logic;
digital_sig_in : in bit;
digital_sig_out: out integer;
--segment--
data_in: in integer;
sel : out std_logic_vector(3 downto 0);
fnd : out std_logic_vector(7 downto 0));
end adc;
architecture Behavior of adc is
signal data_temp: integer;
component interface
port (
clk : in std_logic;
rst : in std_logic;
cs : out std_logic;
sclk : out std_logic;
digital_sig_in : in bit;
digital_sig_out: out integer);
end component;
component segment
port(
clk : in std_logic;
rst : in std_logic;
data_in: in integer;
sel : out std_logic_vector(3 downto 0);
fnd : out std_logic_vector(7 downto 0));
end component;
begin
U0 : interface port map (clk, rst, cs, sclk, digital_sig_in, data_temp);
U1 : segment port map (clk, rst, data_temp, sel, fnd);
end Behavior;
There is no error but my 7 segment does not show up any value. It blinks on all segment. I've tried to test my segment entity separately, it works well. So I guess there is some problem with my "Serial signal assigning" process in interface entity. The clock and chip select signal out (sclk and cs) are checked by oscilloscope, they are correct also.
What is problem with my program? Any opinions are appreciated! Thank you.