EmbDev.net

Forum: FPGA, VHDL & Verilog ADC on DEO NANO not working


von chinmaye (Guest)


Rate this post
useful
not useful
Hello,

I am trying to get the ADC on the DEO Nano board working. I am dividing 
the 50 MHz clock to 1MHz and trying to read channel zero. But it doesn't 
seem to be working. Here is the code. The simulation works fine. But it 
is not showing up on the board.
I am trying to give the analog input through a POT and trying to get the 
output on LEDS. The LEDs simply do not glow for any input.

I have connected the IGO key to the dip switch. I am not sure if it 
works. Plz help.
1
`timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// Company: 
4
// Engineer: 
5
// 
6
// Create Date:    17:04:43 03/19/2018 
7
// Design Name: 
8
// Module Name:    adc 
9
// Project Name: 
10
// Target Devices: 
11
// Tool versions: 
12
// Description: 
13
//
14
// Dependencies: 
15
//
16
// Revision: 
17
// Revision 0.01 - File Created
18
// Additional Comments: 
19
//
20
//////////////////////////////////////////////////////////////////////////////////
21
module ADC_CNTRL  (  
22
          iRST,
23
          CLK,
24
          //iCLK_n,
25
          iGO,
26
          //iCH,
27
          oLED,
28
          
29
          oDIN,
30
          oCS_n,
31
          oSCLK,
32
          iDOUT
33
        
34
          
35
        );
36
          
37
input        iRST;
38
input        CLK;
39
//input        iCLK_n;
40
input        iGO;
41
//input  [2:0]    iCH;
42
output  [7:0]    oLED;
43
//output [3:0] m_cont;
44
output        oDIN;
45
output        oCS_n;
46
output        oSCLK;
47
input        iDOUT;
48
49
reg          data;
50
reg          go_en;
51
wire  [2:0]    ch_sel;
52
reg          sclk;
53
reg    [3:0]    cont;
54
reg    [3:0]    m_cont;
55
reg    [11:0]    adc_data;
56
reg    [11:0]    led;
57
//reg [2:0] iCH;
58
reg iCLK = 0, iCLK_n = 1;
59
parameter sys_clk = 50000000;  // 50 MHz system clock
60
parameter clk_out = 1000000;  // 1 MHz clock output
61
parameter max = sys_clk / (2*clk_out); // max-counter size
62
63
reg [4:0]counter = 0; // 5-bit counter size
64
always@(posedge CLK) begin
65
  if (counter == max-1)
66
    begin
67
    counter <= 0;
68
    iCLK <= ~iCLK;
69
    iCLK_n <= ~iCLK_n;
70
    end
71
  else
72
    begin
73
    counter <= counter + 1'd1;
74
    end
75
  //Clk_out <= (counter == 5'd0);
76
  end
77
78
79
80
81
assign  oCS_n    =  ~go_en;
82
assign  oSCLK    =  (go_en)? iCLK:1;
83
assign  oDIN    =  data;
84
//assign  ch_sel    =  iCH;
85
assign  oLED    =  led;
86
87
always@(posedge iGO or negedge iRST)
88
begin
89
  if(!iRST)
90
    go_en  <=  0;
91
  else
92
  begin
93
    if(iGO)
94
      go_en  <=  1;
95
  end
96
end
97
98
always@(posedge iCLK or negedge go_en)
99
begin
100
  if(!go_en)
101
    cont  <=  0;
102
  else
103
  begin
104
    if(iCLK)
105
      cont  <=  cont + 1;
106
  end
107
end
108
109
always@(posedge iCLK_n)
110
begin
111
  if(iCLK_n)
112
    m_cont  <=  cont;
113
end
114
115
always@(posedge iCLK_n or negedge go_en)
116
begin
117
  if(!go_en)
118
    data  <=  0;
119
  else
120
  begin
121
    if(iCLK_n)
122
    begin
123
      if (cont == 2)
124
        data  <=  0;
125
      else if (cont == 3)
126
        data  <=  0;
127
      else if (cont == 4)
128
        data  <=  0;
129
      else
130
        data  <=  0;
131
    end
132
  end
133
end
134
135
always@(posedge iCLK or negedge go_en)
136
begin
137
  if(!go_en)
138
  begin
139
    adc_data  <=  0;
140
    led      <=  8'b00;
141
  end
142
  else
143
  begin
144
    if(iCLK)
145
    begin
146
      if (m_cont == 4)
147
        adc_data[11]  <=  iDOUT;
148
      else if (m_cont == 5)
149
        adc_data[10]  <=  iDOUT;
150
      else if (m_cont == 6)
151
        adc_data[9]    <=  iDOUT;
152
      else if (m_cont == 7)
153
        adc_data[8]    <=  iDOUT;
154
      else if (m_cont == 8)
155
        adc_data[7]    <=  iDOUT;
156
      else if (m_cont == 9)
157
        adc_data[6]    <=  iDOUT;
158
      else if (m_cont == 10)
159
        adc_data[5]    <=  iDOUT;
160
      else if (m_cont == 11)
161
        adc_data[4]    <=  iDOUT;
162
      else if (m_cont == 12)
163
        adc_data[3]    <=  iDOUT;
164
      else if (m_cont == 13)
165
        adc_data[2]    <=  iDOUT;
166
      else if (m_cont == 14)
167
        adc_data[1]    <=  iDOUT;
168
      else if (m_cont == 15)
169
        adc_data[0]    <=  iDOUT;
170
      else if (m_cont == 1)
171
        led  <=  adc_data[11:4];
172
    end
173
  end
174
end
175
176
endmodule

von ElKo (Guest)


Rate this post
useful
not useful
Is the demo project working, which Terasic delivers on the CD? (and 
which you copied)

What do the LED show, if you assign "counter" to them?

Is this module your Toplevel? If so, did you change the pin assignments?

von Christian G. (Guest)


Rate this post
useful
not useful
Hi, a few days ago, I tried to get that same example project to run and 
also failed, it just did not work on the real hardware. To be honest I 
have no clue of verilog, so I ended up building my own adc_controller in 
vhdl and it turned out to be surprisingly easy once you read the adc 
datasheet, I used a PLL to create a clock double the speed of the adc 
clock I want than on the falling edge of the adc clock I push out the 
channel I want to read and on the rising edge of the adc clock I read 
the channel data back. It might not be by far the best solution but it 
works :
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity adc_controller is
6
  port
7
  (
8
    clk : in std_logic;    
9
    reset : in std_logic;
10
    output : out std_logic_vector(11 downto 0);
11
    output_valid : out std_logic;
12
    go : in std_logic;
13
    ch_sel : in std_logic_vector(2 downto 0);
14
    adc_clk : out std_logic;          -- The ADC clock (0.8 - 3.2 MHz) will be half the speed of clk !
15
    adc_cs_n : out std_logic;
16
    adc_sadr : out std_logic;
17
    adc_dat : in std_logic
18
  );
19
end entity;
20
21
architecture behavioural of adc_controller is
22
23
  signal adc_data_out : std_logic_vector(15 downto 0) := (others => '0');
24
  signal adc_data_in: std_logic_vector(15 downto 0) := (others => '0');
25
  signal di_counter : natural range 0 to 15 := 0;
26
  signal do_counter : natural range 0 to 15 := 0;
27
  type tstate is (init, start, clock_low, clock_high, last_clock_high, stop);
28
  signal state :tstate := init;
29
  
30
begin
31
32
  process
33
  begin
34
    wait until rising_edge(clk);
35
    if (reset = '1') then
36
      output <= (others => '0');
37
      di_counter <= 15;
38
      do_counter <= 15;
39
      adc_data_in <= (others => '0');
40
      adc_cs_n <= '1';
41
      adc_clk <= '0';
42
      output_valid <= '0';
43
      state <= init;
44
    else
45
      case state is
46
        when init =>
47
          adc_clk <= '1';
48
          adc_cs_n <= '1';
49
          do_counter <= 15;
50
          di_counter <= 15;
51
          adc_sadr <= '0';
52
          adc_data_in <= (others => '0');
53
          adc_data_out <= "00" & ch_sel & "000" & "00000000";
54
          output_valid <= '0';
55
          if (go <= '1') then
56
            state <= start;
57
          else
58
            state <= init;
59
          end if;
60
          
61
        when start =>
62
          adc_cs_n <= '0';
63
          state <= clock_low;
64
65
        when clock_low =>
66
          adc_clk <= '0';
67
          adc_sadr <= adc_data_out(do_counter);
68
          if (di_counter > 0) then
69
            do_counter <= do_counter - 1;
70
            state <= clock_high;
71
          else
72
            state <= last_clock_high;
73
          end if;
74
75
        when clock_high =>
76
          adc_clk <= '1';
77
          adc_sadr <= adc_data_out(do_counter);
78
          adc_data_in(di_counter) <= adc_dat;
79
          di_counter <= di_counter - 1;
80
          state <= clock_low;
81
82
        when last_clock_high =>
83
          adc_clk <= '1';
84
          adc_data_in(di_counter) <= adc_dat;
85
          state <= stop;
86
87
        when stop =>
88
          adc_cs_n <= '1';
89
          output <= adc_data_in(15 downto 4);
90
          output_valid <= '1';
91
          state <= init;
92
          
93
        when others =>
94
          adc_cs_n <= '1';
95
          state <= init;
96
      end case;      
97
    end if;
98
  end process;
99
  
100
end behavioural;

top-level entity:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity adc_test is
6
  port
7
  (
8
    CLK_50 : in std_logic;
9
    BTN_RST : in std_logic;
10
    LED : out std_logic_vector(7 downto 0);
11
    SWITCH : in std_logic_vector(3 downto 0);
12
    ADC_CS : out std_logic;
13
    ADC_DAT_IN : out std_logic;
14
    ADC_DAT_OUT : in std_logic;
15
    ADC_CLK : out std_logic
16
  );
17
end adc_test;
18
19
architecture adc_test_arc of adc_test is
20
21
  component pll_clock IS
22
    PORT
23
    (
24
      inclk0    : IN STD_LOGIC  := '0';
25
      c0    : OUT STD_LOGIC -- I used a 4MHz clock
26
    );
27
  END component;
28
    
29
  component adc_controller is
30
    port
31
    (
32
      clk : in std_logic;
33
      reset : in std_logic;
34
      output : out std_logic_vector(11 downto 0);
35
      output_valid : out std_logic;
36
      go : in std_logic;
37
      ch_sel : in std_logic_vector(2 downto 0);
38
      adc_clk : out std_logic;
39
      adc_cs_n : out std_logic;
40
      adc_sadr : out std_logic;
41
      adc_dat : in std_logic
42
    );
43
  end component;
44
  
45
  signal adc_controller_clk : std_logic := '0';
46
  signal adc_data : std_logic_vector(11 downto 0) := (others => '0');
47
  signal adc_data_valid : std_logic := '0';
48
  signal adc_go : std_logic := '0';
49
  signal rst_btn_sr : std_logic_vector(2 downto 0) := (others =>'0');
50
  signal adc_reset : std_logic := '0';
51
  signal rst_counter : natural := 0;
52
  signal reset_me : std_logic := '0';
53
  
54
begin
55
  
56
  pll_clock_inst : pll_clock port map(
57
    inclk0 => CLK_50,
58
    c0 => adc_controller_clk
59
  );
60
  
61
  adc_controller_inst : adc_controller port map(
62
    clk => adc_controller_clk,
63
    reset => adc_reset,
64
    output => adc_data,
65
    output_valid => adc_data_valid,
66
    go => adc_go,
67
    ch_sel => SWITCH(2 downto 0),
68
    adc_clk => ADC_CLK,
69
    adc_cs_n => ADC_CS,
70
    adc_sadr => ADC_DAT_IN,
71
    adc_dat => ADC_DAT_OUT
72
  );
73
  
74
    
75
-- RESET button process
76
  reset_btn_proc : process
77
  begin
78
    wait until rising_edge(CLK_50);
79
    rst_btn_sr <= rst_btn_sr(1 downto 0) & (NOT BTN_RST);
80
    if (rst_btn_sr = "111") then 
81
      reset_me <= '1'; 
82
    else 
83
      reset_me <= '0';
84
    end if;
85
  end process reset_btn_proc;
86
  
87
--RESET process  
88
  reset_proc :process
89
  begin
90
    wait until rising_edge(CLK_50);
91
    if (reset_me = '1') then
92
      rst_counter <= 100;
93
    end if;
94
    if (rst_counter > 0) then
95
      adc_reset <= '1';
96
      adc_go <= '0';
97
      rst_counter <= rst_counter - 1;
98
    else
99
      adc_reset <= '0';
100
      adc_go <= '1';
101
    end if;
102
  end process reset_proc;
103
  
104
-- LED process
105
  led_proc : process
106
  begin
107
    wait until rising_edge(CLK_50);
108
    if (adc_reset = '1') then
109
      LED <= (others => '0');
110
    else
111
      if (adc_data_valid = '1') then
112
        LED <= adc_data(7 downto 0);
113
      end if;
114
    end if;
115
  end process led_proc;
116
  
117
end adc_test_arc;

von Christian G. (Guest)


Attached files:

Rate this post
useful
not useful
...sorry, had still a few bugs in there...

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.