Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

SPI on FPGA - output 1 byte from one port?

Status
Not open for further replies.
I am having some issues it seems with the input i've received.. It doesn't seem to be arranged it correct way as it supposed..

I tested with this piece of code

Code:
if RX = "0111111111" then
                    tx_pwm <= "11";
                elsif RX = "000000000" then
                    tx_pwm <= "00";
                else
                    tx_pwm <= "10";
                end if;

But it seems to keep showing value of others.. Instead what i provide it with.

Am i storing the bit incorrectly ?


Code:
SPI_state: process(newClock)
begin
   if falling_edge(newClock) then      
        case state is   
            when start =>
                debug_TX <= "00000001";
                CS <= '1';
                MOSI <= '0';
                RX <= "0000000000";
            state <= state2;
            when state2 => -- Send init bits. 
                CS <= '0';
                shift_counter <= shift_counter - 1;
                TX <= TX(N-1 downto 0) & TX(N); 
                MOSI <= TX(N);
                if shift_counter = 0 then 
                   MOSI <= '0';
                   shift_counter<= 10;
                   state <= state3;
                end if;
            when state3 =>
                MOSI <= '0';
                CS <= '0';              -- Last bit init bit;
                state <= state4; 
            when state4=>
                CS <= '0';              --T_sample from falling - falling
                state <= state6; 
            when state6=>
               CS <= '0';              -- Read
               shift_counter <= shift_counter - 1;
                RX <=  RX(8 downto 0) & MISO;
                if shift_counter = 0 then
                    MOSI <= '0';
                    shift_counter<= N;
                    state <= start;
                end if;
            when others =>    
                state <= start;           
        end case;
    end if;  
end process;

- - - Updated - - -

For instance

V_ref = V_dd = CH0 = 3.3 V from FPGA

But the output DOUT = 0111111011.. or something like that.. it never bed 1111111111...
 

hi kidi3.
1. please explain exactly what is your problem (it is very unclear what you are trying to do)
so people could understand clearly.
2. please attach full code (not samples) , and the testbench for your design, in he proper code syntax.
3. please show your timing design. i.e the waveforms of your design.
4. thanks a lot.
arui.
 

I am simply trying to use the MPC3008 as ADC to convert an analog signal to a digital signal => binary value.
The problem is when Vdd = Vref = CH0 = 3.3V i don't get an binary value of 1111111111 , but rather something like 1111110111, or something like that , point being never a stream of only ones.


Full code:
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_logic_unsigned.all;
use ieee.numeric_std.all;


-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity main is
    Port ( MISO : in STD_LOGIC;
           MOSI : out STD_LOGIC;
           CS : out STD_LOGIC;
           SCLK : out STD_LOGIC;
           CLK : in STD_LOGIC;
           debug_TX: out std_logic_vector(3 downto 0);
           tx_pwm: out std_logic_vector(1 downto 0);
           work: out std_logic;
           rx_led: out std_logic_vector(9 downto 0)
           );
end main;

architecture Behavioral of main is
--signal prescaler : integer range 0 to 3500000 := 3500000 ;
constant N : integer := 4;
signal prescaler_counter : integer range 0 to 50000000 := 0;
signal newClock : std_logic := '0';
signal TX :std_logic_vector(N downto 0) := "11000";
signal RX : std_logic_vector(9 downto 0) := "0000000000";
type state_type is (start,state2,state3,state5);  --type of state machine.
type TXRX  is (waiting, working); 
signal state : state_type := start;
signal busy: std_logic:= '0';
signal shift_counter: integer range 0 to 750:= N;
begin

prescaler01: process(clk, newClock)
begin
    if rising_edge(clk) then 
        if prescaler_counter < 5000000 then -- 14
            prescaler_counter <= prescaler_counter + 1;
        else
            newClock <= not newClock;
            prescaler_counter <= 0;
       end if;
    end if;            
end process;

SCLK <= newClock;

-- FPGA transmit data on falling_edge
-- FPGA reads data on rising_edge


SPI_state: process(newClock)
begin
   if rising_edge(newClock) then      -- ADC læser på rising, derfor sendes på falling edge  
        case state is   
            when start =>
                debug_tx <= "0001";
                CS <= '1';
                MOSI <= '0';
                busy <= '1';
                RX <= "0000000000";
            state <= state2;
            when state2 => -- Send init bits. 
                debug_tx <= "0010";
                CS <= '0';
                shift_counter <= shift_counter - 1;
                TX <= TX(N-1 downto 0) & TX(N); 
                MOSI <= TX(N);
                if shift_counter = 0 then 
                   MOSI <= '0';
                   shift_counter<= 11;
                   state <= state3;
                end if;
            when state3 =>
                debug_tx <= "0100";
                --MOSI <= '0';
                CS <= '0';              -- Last bit init bit;
                state <= state5; 
            --when state4=>
            --    debug_tx <= "1000";
            --    CS <= '0';              --T_sample from falling - falling
            --    state <= state5;     
            when state5=>
               debug_tx <= "1001";
               CS <= '0';              -- Read
               shift_counter <= shift_counter - 1;
                RX <=  RX(8 downto 0) & MISO;

                if shift_counter = 0 then
                    MOSI <= '0';
                    shift_counter<= N;
                    busy <= '0';
                    state <= start;
                end if;
            when others =>   
                 debug_tx <= "1111"; 
                state <= start;           
        end case;
    end if;  
end process;

TB:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity adc_tb is
end adc_tb;

architecture arch of adc_tb is

  -- Component declaration of the tested unit
  component main
    port(
      clk      : in  std_logic;
      sclk     : out std_logic;
      miso     : in  std_logic;
      mosi     : out std_logic;
      cs       : out std_logic;
      debug_tx : out std_logic_vector(3 downto 0);
      RX_LEd: out std_logic_vector(9 downto 0)
      );
  end component;

  -- Stimulus signals - signals mapped to the input and inout ports of tested entity
  signal sclk  : std_logic := '0'; -- the sample clock

  signal clk  : std_logic := '0';
  signal dout : std_logic := 'Z';
  signal din  : std_logic;
  signal debug_tx: std_logic_vector (3 downto 0) := "0000";
  signal RX_LEd:  std_logic_vector(9 downto 0) := "0000000000";
  
  -- Observed signals - signals mapped to the output ports of tested entity
  signal cs       : std_logic;
  signal adc_data : std_logic_vector(9 downto 0);

  -- clock period
  constant period : time := 20 ns; -- 50 MHz clock

  -- constant data set that will be sent back as the ADC data  
  constant FIXED_DATA : std_logic_vector(9 downto 0) := std_logic_vector(to_unsigned(1023,10));

  -- timing parameters from the datasheet
  constant T_HI   : time := 125 ns;     -- CLK high time
  constant T_LO   : time := 125 ns;     -- CLK low time
  constant T_SUCS : time := 100 ns;     -- CS Fall to first rising CLK edge
  constant T_DO   : time := 125 ns;  -- CLK fall to output data valid ( 125ns at 5V )
  constant T_EN   : time := 125 ns;  -- CLK fall to output enable ( 125ns at 5V )
  constant T_DIS  : time := 100 ns;     -- CS Rise to output disable
  constant T_CSH  : time := 270 ns;     -- CS disable time
  constant T_R    : time := 100 ns;     -- D_OUT rise time
  constant T_F    : time := 100 ns;     -- D_OUT fall time

begin

  ---- Unit Under Test port map
  UUT : main
    port map (
      clk      => clk,
      sclk     => sclk,
      miso     => dout,
      mosi     => din,
      cs       => cs,
      debug_tx => debug_tx,
      RX_LEd => RX_LEd
      );

  -- generate the clock                     
  clk <= not clk after period/2;

  -- emulate what the MCP3001 ADC is doing, by sending back some test data
  -- this process uses the timing diagram (Fig. 1) from 21293C.pdf
  process
    variable differential : boolean := false;
    variable channel_sel : unsigned(2 downto 0) := "000";
  begin
    -- Set the data line to HI-Z
    dout <= 'Z';

    -- wait until the CS is brought to '0', this starts the conversion.
    -- also check for an error where there is a rising edge that happens
    -- less than 100 ns after CS is brought to '0'
    wait until falling_edge(cs);
    if sclk = '0' then
      wait for T_SUCS;
      assert sclk = '0'
        report "Timing constraint Tsucs=100ns violated, clock rising edge must come atleast 100ns after CS transitions to '0'"
        severity error;
    else
      wait for T_SUCS;
    end if;

    -- wait for the start bit
    if din = '0' then
      wait until rising_edge(din);
    end if;

    -- handle the input mode and channel select
    -- setup and hold times are not checked
    wait until falling_edge(sclk);
    wait until rising_edge(sclk);
    if din = '1' then
      differential := false;
    else
      differential := true;
    end if;
    for i in 2 downto 0 loop
      wait until rising_edge(sclk);
      channel_sel(i) := din;
    end loop;
    if differential then
      report "sampling in differential mode on channel " & integer'image(to_integer(channel_sel));
    else
      report "sampling in differential mode on channel " & integer'image(to_integer(channel_sel));
    end if;

    -- sample time...
    wait until falling_edge(sclk);
    wait until falling_edge(sclk);
    wait for T_EN; -- small delay time after falling edge from datasheet
    dout <= '0';

    -- output the converted data MSB first after every falling edge.
    -- also check for a likely problem where the CS is not held at '0' while
    -- reading all 10 bits of data.
    for i in 9 downto 0 loop
      wait until falling_edge(sclk);
      wait for T_DO; -- small delay time after falling edge from datasheet
      dout <= FIXED_DATA(i);
      assert cs = '0'
        report "CS needs to be held at '0', not all bits have been transmitted"
        severity warning;
    end loop;

    -- wait for CS to go back high then disable the output
    wait until rising_edge(cs);
    wait for T_DIS;
    dout <= 'Z';

    -- wait for the minimum delay time before the start of the next sample.
    -- also check for a likely error, where CS is only '1' for a single
    -- 320ns clock period
    wait for T_CSH-T_DIS;
    assert cs = '1'
      report "Timing Constraint Tcsh=350ns violated, CS needs to be held to '1' for atleast 350ns before transitioning to '0'"
      severity error;

  end process;

end arch;


Timing in simulation:
Skærmbillede 2015-10-25 kl. 14.59.31.png
 

hi.

if you can please put code syntax (vhdl):

see the following instructions :



this will make the code much more easier to read!.

thanks
 
Last edited:

I am simply trying to use the MPC3008 as ADC to convert an analog signal to a digital signal => binary value.
The problem is when Vdd = Vref = CH0 = 3.3V i don't get an binary value of 1111111111 , but rather something like 1111110111, or something like that , point being never a stream of only ones.


Full code:

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_logic_unsigned.all;
use ieee.numeric_std.all;
 
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
 
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity main is
    Port ( MISO : in STD_LOGIC;
           MOSI : out STD_LOGIC;
           CS : out STD_LOGIC;
           SCLK : out STD_LOGIC;
           CLK : in STD_LOGIC;
           debug_TX: out std_logic_vector(3 downto 0);
           tx_pwm: out std_logic_vector(1 downto 0);
           work: out std_logic;
           rx_led: out std_logic_vector(9 downto 0)
           );
end main;
 
architecture Behavioral of main is
--signal prescaler : integer range 0 to 3500000 := 3500000 ;
constant N : integer := 4;
signal prescaler_counter : integer range 0 to 50000000 := 0;
signal newClock : std_logic := '0';
signal TX :std_logic_vector(N downto 0) := "11000";
signal RX : std_logic_vector(9 downto 0) := "0000000000";
type state_type is (start,state2,state3,state5);  --type of state machine.
type TXRX  is (waiting, working); 
signal state : state_type := start;
signal busy: std_logic:= '0';
signal shift_counter: integer range 0 to 750:= N;
begin
 
prescaler01: process(clk, newClock)
begin
    if rising_edge(clk) then 
        if prescaler_counter < 5000000 then -- 14
            prescaler_counter <= prescaler_counter + 1;
        else
            newClock <= not newClock;
            prescaler_counter <= 0;
       end if;
    end if;            
end process;
 
SCLK <= newClock;
 
-- FPGA transmit data on falling_edge
-- FPGA reads data on rising_edge
 
 
SPI_state: process(newClock)
begin
   if rising_edge(newClock) then      -- ADC læser på rising, derfor sendes på falling edge  
        case state is   
            when start =>
                debug_tx <= "0001";
                CS <= '1';
                MOSI <= '0';
                busy <= '1';
                RX <= "0000000000";
            state <= state2;
            when state2 => -- Send init bits. 
                debug_tx <= "0010";
                CS <= '0';
                shift_counter <= shift_counter - 1;
                TX <= TX(N-1 downto 0) & TX(N); 
                MOSI <= TX(N);
                if shift_counter = 0 then 
                   MOSI <= '0';
                   shift_counter<= 11;
                   state <= state3;
                end if;
            when state3 =>
                debug_tx <= "0100";
                --MOSI <= '0';
                CS <= '0';              -- Last bit init bit;
                state <= state5; 
            --when state4=>
            --    debug_tx <= "1000";
            --    CS <= '0';              --T_sample from falling - falling
            --    state <= state5;     
            when state5=>
               debug_tx <= "1001";
               CS <= '0';              -- Read
               shift_counter <= shift_counter - 1;
                RX <=  RX(8 downto 0) & MISO;
 
                if shift_counter = 0 then
                    MOSI <= '0';
                    shift_counter<= N;
                    busy <= '0';
                    state <= start;
                end if;
            when others =>   
                 debug_tx <= "1111"; 
                state <= start;           
        end case;
    end if;  
end process;



TB:

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity adc_tb is
end adc_tb;
 
architecture arch of adc_tb is
 
  -- Component declaration of the tested unit
  component main
    port(
      clk      : in  std_logic;
      sclk     : out std_logic;
      miso     : in  std_logic;
      mosi     : out std_logic;
      cs       : out std_logic;
      debug_tx : out std_logic_vector(3 downto 0);
      RX_LEd: out std_logic_vector(9 downto 0)
      );
  end component;
 
  -- Stimulus signals - signals mapped to the input and inout ports of tested entity
  signal sclk  : std_logic := '0'; -- the sample clock
 
  signal clk  : std_logic := '0';
  signal dout : std_logic := 'Z';
  signal din  : std_logic;
  signal debug_tx: std_logic_vector (3 downto 0) := "0000";
  signal RX_LEd:  std_logic_vector(9 downto 0) := "0000000000";
  
  -- Observed signals - signals mapped to the output ports of tested entity
  signal cs       : std_logic;
  signal adc_data : std_logic_vector(9 downto 0);
 
  -- clock period
  constant period : time := 20 ns; -- 50 MHz clock
 
  -- constant data set that will be sent back as the ADC data  
  constant FIXED_DATA : std_logic_vector(9 downto 0) := std_logic_vector(to_unsigned(1023,10));
 
  -- timing parameters from the datasheet
  constant T_HI   : time := 125 ns;     -- CLK high time
  constant T_LO   : time := 125 ns;     -- CLK low time
  constant T_SUCS : time := 100 ns;     -- CS Fall to first rising CLK edge
  constant T_DO   : time := 125 ns;  -- CLK fall to output data valid ( 125ns at 5V )
  constant T_EN   : time := 125 ns;  -- CLK fall to output enable ( 125ns at 5V )
  constant T_DIS  : time := 100 ns;     -- CS Rise to output disable
  constant T_CSH  : time := 270 ns;     -- CS disable time
  constant T_R    : time := 100 ns;     -- D_OUT rise time
  constant T_F    : time := 100 ns;     -- D_OUT fall time
 
begin
 
  ---- Unit Under Test port map
  UUT : main
    port map (
      clk      => clk,
      sclk     => sclk,
      miso     => dout,
      mosi     => din,
      cs       => cs,
      debug_tx => debug_tx,
      RX_LEd => RX_LEd
      );
 
  -- generate the clock                     
  clk <= not clk after period/2;
 
  -- emulate what the MCP3001 ADC is doing, by sending back some test data
  -- this process uses the timing diagram (Fig. 1) from 21293C.pdf
  process
    variable differential : boolean := false;
    variable channel_sel : unsigned(2 downto 0) := "000";
  begin
    -- Set the data line to HI-Z
    dout <= 'Z';
 
    -- wait until the CS is brought to '0', this starts the conversion.
    -- also check for an error where there is a rising edge that happens
    -- less than 100 ns after CS is brought to '0'
    wait until falling_edge(cs);
    if sclk = '0' then
      wait for T_SUCS;
      assert sclk = '0'
        report "Timing constraint Tsucs=100ns violated, clock rising edge must come atleast 100ns after CS transitions to '0'"
        severity error;
    else
      wait for T_SUCS;
    end if;
 
    -- wait for the start bit
    if din = '0' then
      wait until rising_edge(din);
    end if;
 
    -- handle the input mode and channel select
    -- setup and hold times are not checked
    wait until falling_edge(sclk);
    wait until rising_edge(sclk);
    if din = '1' then
      differential := false;
    else
      differential := true;
    end if;
    for i in 2 downto 0 loop
      wait until rising_edge(sclk);
      channel_sel(i) := din;
    end loop;
    if differential then
      report "sampling in differential mode on channel " & integer'image(to_integer(channel_sel));
    else
      report "sampling in differential mode on channel " & integer'image(to_integer(channel_sel));
    end if;
 
    -- sample time...
    wait until falling_edge(sclk);
    wait until falling_edge(sclk);
    wait for T_EN; -- small delay time after falling edge from datasheet
    dout <= '0';
 
    -- output the converted data MSB first after every falling edge.
    -- also check for a likely problem where the CS is not held at '0' while
    -- reading all 10 bits of data.
    for i in 9 downto 0 loop
      wait until falling_edge(sclk);
      wait for T_DO; -- small delay time after falling edge from datasheet
      dout <= FIXED_DATA(i);
      assert cs = '0'
        report "CS needs to be held at '0', not all bits have been transmitted"
        severity warning;
    end loop;
 
    -- wait for CS to go back high then disable the output
    wait until rising_edge(cs);
    wait for T_DIS;
    dout <= 'Z';
 
    -- wait for the minimum delay time before the start of the next sample.
    -- also check for a likely error, where CS is only '1' for a single
    -- 320ns clock period
    wait for T_CSH-T_DIS;
    assert cs = '1'
      report "Timing Constraint Tcsh=350ns violated, CS needs to be held to '1' for atleast 350ns before transitioning to '0'"
      severity error;
 
  end process;
 
end arch;




Timing in simulation:
View attachment 122621[/QUOTE]
 

Hi,

The problem is when Vdd = Vref = CH0 = 3.3V i don't get an binary value of 1111111111 , but rather something like 1111110111, or something like that , point being never a stream of only ones.

In decimal you expect 1023, but you get 1015, this is 8 LSBs off. Just an error of 0.8%.

What is the specifications of gain error and offset error?
If you add both? Is your error more than the specified?

****

In general I don't recommend to use the complete range of an ADC and expect the ADC has no error.

Example:
An ADC input offset error is specified with +/-10mV, at an input range of 0...3.3V and 10 bits resolution.

Now assume your ADC has +7V offset error. It is within specification.
Connect 0.0V to it's input and perform a conversion.
It will output a digital value of "2".
But you expect "0"... What can you do to get an output of "0"? You have to input -7mV.. But this is often not possible, because you don't have negative voltage ... Or this simply is beyond ADC input range....

So how to overcome this problem?
I usually add an analog value more than the ADC offset voltage. Maybe 20mV.
Then the conversion always gives a true value.
During initialisation process a pull my input to 0V and perform a conversion. The value I store in the eeprom an subtract it from all following conversions..

The same is with max input.
If I want an useful input range of 3.3V, then I extend it to let's say 3.5V. The correction for this is just using another multiplying factor in the software.
You may say with this I'm loosing resolution. Let's calculate it:
3.3V range: resolution is 3.3V /1024 = 3.220mV
My range: 3.5V / 1024 = 3.418mV
Do the 0.2mV really matter?

Klaus
 

hi KlausST

if you look carefully
you will see that kidi3 is injecting by simulation series of '1's (which actually look ok)
so we are not talking about the "real world" yet.

for the code itself :

kidi3 please note :


1. there is a really weird clock generator process that have to be changed
(move ext clock generation to tb ?).
2. the waveforms, you gave, dosn't seem to completely belong to the code you attached
(different version ?)
, and why not put the state machine wave itself to be displayed on the waveform ?
3. you should check your shift register because currently it shifts 12 bit instead of 10 bits.
(there is no reason to shift 12 bits if you need 10).


try this and see what happens.
 
Last edited:

Well.. The problem is that the ADC keeps outputting a digital value to another circuit, and I want to assure that the system somehow always sends the correct value as an output..

The chip does have a lot graphs explaining the gain error and offset error vs the temperature and V_ref.
but seems to be that it max. can be 1.5 LSB and 1 LSB..

image provided might be an bit outdated, minor changes to the code. debug_tx outputs the state of the state machine within the simulation .

I don't understand the weird part of the clk generator..


constant period : time := 20 ns; -- 50 MHz clock

clk <= not clk after period/2;

the other parameter ensures that the timing isn't off if it do, if it is, it will say it.




Skærmbillede 2015-10-25 kl. 20.30.39.png

- - - Updated - - -

The 12 bit shifting is also set to 10
 
Last edited:

hi kidi3

try to give same waveforms for the same code.
what is RX_LED final value - it should be all '1's as expected.
(it is not fully shiown on the snapshot).

thanks.
arui
 

it it all ones.. which also would be expected..
about the waveforms, are you looking to an output from a scope.. Or what do mean exactly?
 

hi kidi3

still there is timing problem with DI, acording to datasheet
it should be asserted after falling edge - so you might missing something here.
please try to shift din so it's timing will be like in the datasheet.

thanks.
 

debug_tx = "0010" and debug_tx = "0011"
I added those states as delay such that the T_SUCS time constrain of waiting 100 ns after CS goes low, as it says in the data sheet.

as it is stated in the data sheet page 4.

https://www.adafruit.com/datasheets/MCP3008.pdf

^^Datasheet
 

kidi3 : lets look at din

din has 50ns setup hold, you assert din after rising edge of SCLK, by that you create hold violation at the ADC.
 

Could you specify using the debug_tx?, so i know at which state the problem occurs?

- - - Updated - - -

I changed it so the data will be data will be send on falling edge.. but it seems not to read the last value now.. Skærmbillede 2015-10-25 kl. 22.05.00.png
 

becasue now you don't read the data in the right place ...
you need to start read it 2 cycles after you finished sending your 5 bit data command.
what you need to do is to add internal signals like the state machine, and counter to your waveform. you don't need this debug signals at all.
then it will be very easy for you to debug your code.
 

Yeah.. I understand that internal signals would help.. but yeah, i use them to know at which state i am in.. at the moment..
Adding the counter wouldn't make that easier..
 

I think my issue has been that while i was testing it, i used a frequency below 10 kHz, (20 hz) rather than the high freq.
I keep outputting the value it read from it with an frequency of 1 hz, would that value be something else than an constant logical high?
 

Your posted code does not match your posted waveforms. What I see is:
- CS goes low at t=300 ms and stays low the rest of the simulation which crashes at t=1.1 sec with a fatal error "Fatal: (vsim-3421) Value -1 is out of range 0 to 750." at the following point in the code
Code:
                when state2 => -- Send init bits. 
                    debug_tx <= "0010";
                    CS <= '0';
                    [COLOR="#FF0000"]shift_counter <= shift_counter - 1; -- Dies here[/COLOR]
- CS switches from high to low at t=300 ms (you show it happening at t=80 ms)
- CS and DIN switch at the rising edge of SCLK (you show it happening at the falling edge)
- Dout stays 'Z'. It looks like this is because the sim crashed (see above) after the 4th falling edge of SCLK which is before the 6th falling edge of SCLK where your sim shows it being driven.

While group debug is a poor and inefficient way to do this sort of debug in the first place, it is simply pointless when the posted code isn't correct. Good luck.

Kevin Jennings
 

The code which i've posted isn't the one i have been Simulating.. I changed the CLK rate at the different post, which i should have notified you... sorry my bad.

about CS i not quite sure where the problem is ?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top