Bidirectional Pin FPGA (Parallel ADC)

Aug 25, 2014 9 Replies

Hey guys(and gals)



FPGA convert here trying to use bidirectional pins on an Altera Board within a data acquisition project. What are the ways to implement such a design in VHDL or Verilog? Thanks!



Olu


Declare the pin as bidirectional. Drive the pin with a tristate driver. Ignore data coming in to the pin while the tristate is enabled.

Andy

Hi,

here is a random example for a design with tristate IOs:

formatting link

the following lines: inout [15:0] sdram_dq, .. assign sdram_dq = (state == WRITE) ? wr_data : 16'hZ;

--------------------------------------- Posted through

formatting link

an Altera Board within a data acquisition project. What are the ways to imp lement such a design in VHDL or Verilog? Thanks! Olu

Thanks, guys. I have actually been going the tri-state route with not much success and I was hoping there was a different way to implement bidirection al signals on an FPGA. To clarify further, my HDL simulates fine but my syn thesis leaves much to be desired. I have disparate write and read cycles co ntrolled by an FSM but for some reason, whatever I write into the ADC durin g the write cycle is being "echoed back" to me during my read(to read ADC d ata) cycle. Here is my current Verilog code

inout [11:0] adc_data_pin_top, assign adc_data_pin_top = ~write_adc_data ? written_data_temp : 12'b z; assign data_from_adc = converted_datas;

always @ (posedge adc_clock) begin converted_datas

What is controlling the signal write_adc_data? That signal should be low when writing data and high when reading. What is driving the signal written_data_adc? Do you really need to register it?

Can you explain why the ADC bus needs to be written? Is there setup data that needs to be sent to it or are you talking to another device like a DAC?

Rick

Hey Rick,

Thanks for your response. The write_adc_data is a low enable signal generat ed by a Finite State Machine and yes, it is low when writing and high the r est of the time. My read requires an additional enable, though. You are pro bably right about the need to register the separate input/output signals--t he IO cell has an inbuilt register I was trying to use, but there is a line that bypasses that(meaning I could probably get away with a continuous ass ignment statement). How does the register/no register impact my design besi des timing?

-4, wrote: >> Hey guys(and gals) FPGA convert here trying to use bidirectio nal pins on an Altera Board within a data acquisition project. What are the ways to implement such a design in VHDL or Verilog? Thanks! Olu > > Thanks , guys. I have actually been going the tri-state route with not much succes s and I was hoping there was a different way to implement bidirectional sig nals on an FPGA. To clarify further, my HDL simulates fine but my synthesis leaves much to be desired. I have disparate write and read cycles controll ed by an FSM but for some reason, whatever I write into the ADC during the write cycle is being "echoed back" to me during my read(to read ADC data) c ycle. Here is my current Verilog code > > inout [11:0] adc_data_pin_top, > assign adc_data_pin_top = ~write_adc_data ? written_data_temp : 12'bz; > assign data_from_adc = converted_datas; > > always @ (posedge adc_clock)

signal should be low when writing data and high when reading. What is drivi ng the signal written_data_adc? Do you really need to register it? Can you explain why the ADC bus needs to be written? Is there setup data that needs to be sent to it or are you talking to another device like a DAC? -- Rick

And if you change this to 12'bzzzzzzzzzzzz ? I had problems of that sort once.

Before reading from a bidirectional pin, make sure you "release" the pin to tristate first. Similarly, wait for the peripheral (connected to your FPGA) to be ready to read your data, before driving the pin to any deterministic value ('0' or '1').

E.g.:

entity bidir is port(adc_data_pin_top: inout std_ulogic_vector(11 downto 0)); end entity bidir;

architecture rtl of bidir is signal write_adc_data: boolean; -- flag to enable writing. begin adc_data_pin_top 'Z');

process(adc_clock) is begin if rising_edge(adc_clock) then converted_datas

Here, the slave's readiness to read data from your FPGA may be used to determine the value of write_adc_data.

This.

I'm fairly certain that the code the OP originally wrote would assign adc_data_pin_top to 12'b0000_0000_000z when write_adc_data == 1. Instead of the desired all tri-state. Later versions of verilog (2001, or maybe it's systemverilog, I don't recall) had some kind of syntactic sugar that's interpreted as "z-extend" the top bits (instead of the default 0 fill).

Instead of the long string of Z's I use the verilog replication operator i.e.

assign adc_data_pin_top = ( ~write_adc_data ) ? written_data_temp : { 12 { 1'bz } };

Regards,

Mark

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required