Question

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.

Was it helpful?

Solution

I am quite sure that you mixed up something with clocks. Is 50 kHz clock made for counting the value? If you are making SSD counter (for example, from 0 to 99), blinking may be caused by the fact that you are updating it too fast and your eye can't catch it up. I've had similar problem and I just made it update slower.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top