I am trying to interface the DAC of the Spartan-3A board with the FPGA. I have written a VHDL program for the same but it doesn't seem to be working. Can anyone please help me out?
There seems to be lots of problems with your code regarding the interface - SPI - you have.
First and Foremost, tool would not be able to implement that conditions you specified for DAC_CS signal. I mean below one:
DAC_CS <= '0', '1' after 8 ns, '0' after 13 ns;
Just set it to 0 in that state: da_idle.
DAC_CS <= '0';
Second, You are reading the output port SPI_SCK !:-( I am wondering how your tool is going through this basic error you have done!. Or, maybe it fails!. work with that generated clock tmp - use it in your process.
Third, you are better have all signals in the known state at the beginning. So, use a reset signal as input and clear counters and set other signals to their defined start value.
Fourth, make sure that you are giving right value to your parallel register before you shift it out in the starting state: da_idle.
A suggestion is that try simulating your code in cad tools like ModelSim or ISIM simulator first, then go through downloading it to your hardware.
The last one is try to find SPI written sample codes on the web and correct your mistakes accordingly. However, it turns out to me that after applying all those mentioned modifications your code should be working finely. Of course, there are lots of other suggestions that you may apply on your code to get better performance - I would neglect it now on.
Hope this would help out,
Thank you for your reply! I highly appreciate it!
I have made the changes as you have asked me to, but the code still doesn't seem to work. I have used a logic analyzer to display the signals:
Channel 0 : DAC_CLR1
Channel 1 : DAC_CS1
Channel 2 : DAC_OUT1
Channel 3 : SPI_MOSI1
Channel 4 : SPI_SCK1
Can you please tell me what I am doing wrong as I am not able to figure out. The signal DAC_CS amd DAC_CLR should vary once in the whole cycle, but they don't :/
Thanks for your reply :)
You are better first simulate your code. This way you get sure from the code. Although the code is working there are some modifications and improvements you need to apply on your code to get better performance.
First and foremost: the final value of important counter count must be 31 not 32!. change it anywhere you have already miss assigned it.
Second: take that conditional assignment of dac_state_reg signal out of the first if in the dac_send satet!. it wouldn't change the value of dac_state_reg signal!. just examine it in your mind and see if the two nested if conditions would come true any time or not?!
state_clock <= clock_on; if count = 0 then count <= 31; else if count >0 then count <= count - 1; end if; SPI_MOSI <= da_data_reg(count); end if; if count > 0 then dac_state_reg <= dac_send; else dac_state_reg <= da_end; end if;
suggestions for improvement:
The last but not the least: try to change enable signal of first process synchronous. Simply:
process(Clk) begin if (Clk'event and Clk='1') then if Enable = '1' then --write your code here ...... ...... end if; end if; end process;
Hope this will help out,