2
\$\begingroup\$

I am bit new to VHDL, and hope some of you guys could help me here.

I trying to establish a connection between an ADC, LED, and control component.

The purpose of this application is to convert an analog value measured on the ADC, and then output to the LED.

The way i've designed the communication is as follows.

The LED set and signal high (start_adc) Which the ADC read, and start the ADC.

When the ADC is done, it sets the signal read high, which Control then reads, and then read the ADC_value ( a binary value - std_logic_vector (9 down to 0)).

This ADC_value is kept within control, but the LED has to change its state. So Control set the signal next_state high, which LED reads and changes its state to something else. The problem here is how do i turn off next_state?.

My solution entailed the use of a signal named received which would be set high, if an rising_egde(next_state)was seen such that, if control saw an rising_edge(received), it could then turn off next_stateand then when LED shaw and falling_edge(next_state) it could set received low again, and then start_adc high.

code wise it looks like this

state_changer: process(clk,state)
variable count: integer range 0 to 500000000 :=0;
begin
     if falling_edge(next_state) then
       received <= '0'; 
       start_adc <= '1';
     elsif rising_edge(next_state) then 
       received <= '1';
        count := 0;
        start_adc <= '0';
     end if; 
     count := count +1;  
end process;  

but as you can see the problem is that the same signal is set either at rising and falling.. how do I work around this issue?..

Notice count is also important.

\$\endgroup\$
6
  • 4
    \$\begingroup\$ Unless you have a specialist CPLD, FPGAs only have single edge flip flops, they can't do things on both edges. \$\endgroup\$ Commented Oct 28, 2015 at 23:34
  • 2
    \$\begingroup\$ Generally you would simply have a clock which is twice as fast as you need, and then have a clock enable. The logic that needs to be done on both rising and falling is instead done on a rising edge of the fast clock. Every fast clock cycle your clock enable register toggles and you use that to determine when things that go at half the speed should be done. \$\endgroup\$ Commented Oct 28, 2015 at 23:37
  • 2
    \$\begingroup\$ I think though looking at your code you need to go back to basics. Start by drawing a state machine on paper of what your control signals need to do based on what inputs. \$\endgroup\$ Commented Oct 28, 2015 at 23:38
  • \$\begingroup\$ I resolved the issue, by using the read signal if read = '1' then next_state <= '0'; end if; \$\endgroup\$ Commented Oct 28, 2015 at 23:42
  • \$\begingroup\$ As others noted, FPGAs only allow specific signals to be used as clocks. Sometimes you can do tricks with dedicated DDR primitives, but I think this is just a matter of your misunderstanding. \$\endgroup\$ Commented Oct 29, 2015 at 0:37

2 Answers 2

1
\$\begingroup\$

your problem is not complex... assuming your ADC code is working correctly..

you can use 2 edge detector circuit to generate a pulse: one on rising edge and one falling edge.. this will simplify your process...

http://fpgacenter.com/examples/basic/edge_detector.php

your process should have a reset condition and set initial value for the variables...

\$\endgroup\$
0
\$\begingroup\$

I'd check if the FPGA has DDR logic in the I/O blocks, this is quite common. This would give you two signals per input pin, one sampled at rising edge, one sampled at falling edge.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.