FPGARelated.com
Forums

Bidirectional Pin FPGA (Parallel ADC)

Started by Unknown August 25, 2014
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
<osodipe@eng.ucsd.edu> wrote in message 
news:5f2f4946-2e38-4875-9e0e-e27c70128514@googlegroups.com...
> 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:
http://ladybug.xs4all.nl/arlet/fpga/source/sdram.v

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

	   
					
---------------------------------------		
Posted through http://www.FPGARelated.com
On Monday, August 25, 2014 9:18:59 AM UTC-4, oso...@eng.ucsd.edu wrote:
> 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 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 =3D ~write_adc_data ? written_data_temp : 12'b= z; assign data_from_adc =3D converted_datas; always @ (posedge adc_clock) begin converted_datas <=3D adc_data_pin_top; written_data_temp <=3D written_data_adc; end
On 8/25/2014 1:57 PM, osodipe@eng.ucsd.edu wrote:
> On Monday, August 25, 2014 9:18:59 AM UTC-4, oso...@eng.ucsd.edu wrote: >> 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 > > 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 bidirectional signals 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 controlled 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) 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'bz; > assign data_from_adc = converted_datas; > > always @ (posedge adc_clock) > begin > converted_datas <= adc_data_pin_top; > written_data_temp <= written_data_adc; > end
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?


On Monday, August 25, 2014 4:32:49 PM UTC-4, rickman wrote:
> On 8/25/2014 1:57 PM, wrote: > On Monday, August 25, 2014 9:18:59 AM UTC=
-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 =3D ~write_adc_data ? written_data_temp : 12'bz; > = assign data_from_adc =3D converted_datas; > > always @ (posedge adc_clock) =
> begin > converted_datas <=3D adc_data_pin_top; > written_data_temp <=3D w=
ritten_data_adc; > end What is controlling the signal write_adc_data? That = 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
On Mon, 25 Aug 2014 10:57:47 -0700, osodipe wrote:

> assign adc_data_pin_top = ~write_adc_data ? written_data_temp : 12'bz;
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 <= written_data_temp when write_adc_data else (others=>'Z');

    process(adc_clock) is begin
        if rising_edge(adc_clock) then
            converted_datas <= adc_data_pin_top when not write_adc_data;    -- use if-else if your tool doesn't yet support this.
            written_data_temp <= written_data_adc;
        end if;
    end process;
end architecture rtl;

It's better to have both the write and read as synchronous clocked processes though.

-dan
On Wednesday, 27 August 2014 04:05:38 UTC+8, Daniel Kho  wrote:

> adc_data_pin_top <= written_data_temp when write_adc_data else (others=>'Z'); >
Here, the slave's readiness to read data from your FPGA may be used to determine the value of write_adc_data.
> converted_datas <= adc_data_pin_top when not write_adc_data; -- use if-else if your tool doesn't yet support this. >
Save the data only when the line has already been released to (others=>'Z') by the driver process, and the slave is sending data. You may add additional checks here.
In article <lti4vv$984$2@speranza.aioe.org>,
Aleksandar Kuktin  <akuktin@gmail.com> wrote:
>On Mon, 25 Aug 2014 10:57:47 -0700, osodipe wrote: > >> assign adc_data_pin_top = ~write_adc_data ? written_data_temp : 12'bz; > >And if you change this to 12'bzzzzzzzzzzzz ? I had problems of that sort >once.
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