Forum Discussion
Filter & decimation implementation on AD7401
Hello everybody!
We have chosen the AD7401 Sigma Delta modulator for our project, translated the Verilog code given by the datasheet into VHDL and are now confused about the results of the simulation. We have attached our translated VHDL code plus the datasheet of AD7401. 1) We will give the master clock from the FPGA to the ADC from one of the I/O pins. The clocks don't seem to be synchronized though, there is a 5nsec latch delay. Should that be ok, or do we have to eliminate that delay somehow? 2) We tried to simulate the data flow inputting only ones '1', but result is really not the expected one. (DATA samples should be at the highest level?!) Yes, but what about overflow? The given interface is permitting that, if such a case comes up. Below are some results of a random inputted bit stream and a only '1' bit stream. http://i252.photobucket.com/albums/hh3/unoturbomk2/samples.jpg http://i252.photobucket.com/albums/hh3/unoturbomk2/samples2.jpg *** Is the code correct? *** We'd appreciate any kind of help! Thanks in advance!27 Replies
- Altera_Forum
Honored Contributor
The original Verilog code is an example of bad coding style, involving word_clk designed as a ripple clock, but it's basically working.
You have confused the code by an adder, that hasn't been there before and apparently act's as a kind of random number generator in your simulation.
The purpose of this combinational code is to assign 0/+1 respectively -1/+1 to ip_data1, not to sum up anything.if mdata1='1' then ip_data1 <= ip_data1 + '1'; else ip_data1 <= ip_data1 - '1'; - Altera_Forum
Honored Contributor
Can you explain to us how that is expressed in VHDL?
Because, for instance, in SBAA094 of ADS1202 it is done the way we did it.ip_data1 <= 1;
Where exactly is our code mistaken, despite the fact that it is bad coding style given by the datasheet itself. Shouldn't vector ip_data1 work as an adder?DELTA1 <= DELTA1 + 1; - Altera_Forum
Honored Contributor
ip_data1 <= conv_std_logic_vector(1,24); - Altera_Forum
Honored Contributor
Ok, we tried to merge in some way the code of ADS1202 and AD7401, and we got really great results of the code which came out.
The first figure is with feeding 0's and then random input, and the second one is with 1s first and then random values. http://i252.photobucket.com/albums/hh3/unoturbomk2/2-3.jpg http://i252.photobucket.com/albums/hh3/unoturbomk2/1-5.jpg As you can see the code responses to the simulation quite well, respecting that it actually takes 2 words/samples for the code to respond to sudden changes of input values, due to the 3rd order sinc filter. The code is attached. If someone could confirm that this is correct, we'd appreciate it! Thank you! - Altera_Forum
Honored Contributor
The results are correct, except for the unhandled arithmetic overflow with mdata = '1'. I suggest to consider it in the code.
if CN5(24) = '1' then DATA(15 downto 0) <= (others => '1'); else DATA(15 downto 0) <= CN5(23 downto 8); end if; - Altera_Forum
Honored Contributor
FvM thank you we corrected that, although we had tried that out, but in a different way!
I think that now we are done with this part! Thanks again! - Altera_Forum
Honored Contributor
In addition, I see a timing violation in my compilation, caused by the previously mentioned ripple clock. Implementing word_clk as a clock enable removes this problem.
- Altera_Forum
Honored Contributor
FvM, I tried to implement it as a clock_enable, but results were terrible!
After that I used clk_en in combination with the system clock directly in the processes where word_clk used to be. Could you please suggest to me some other way of implementing that?process(clk20,reset) begin if reset = '0' then clk_en <= '0'; elsif clk20'event and clk20 = '0' then cnt <= cnt + 1; -- cnt is a 8-bit vector if cnt(7) = '1' then clk_en <= NOT(clk_en); end if; end if; end process; - Altera_Forum
Honored Contributor
A clock enable should be active for one clock cycle, e.g.:
andprocess(word_count) begin if word_count = x"ff" then word_clk <= '1'; else word_clk <= '0'; end if; end process;if reset = '0' then -- elsif clk20'event and clk20 = '1' then if word_clk = '1' then DN0 <= CN2; -- end if; end if; - Altera_Forum
Honored Contributor
Ok FvM I did that and it works great!
I also did the same thing in the last process, where the DATA assignment is done. I think now it works perfectly, most warnings eliminated, except the pin assignment ones! Thank you!process(clk20,reset) begin if reset = '0' then DATA <= (others => '0'); elsif clk20'event and clk20 = '1' then if word_clk = '1' then if CN5(24) = '1' then DATA(15 downto 0) <= (others => '1'); else DATA(15 downto 0) <= CN5(23 downto 8); end if; end if; end if; end process;