Bidirectional Pin FPGA (Parallel ADC)

Guest
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
 
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
 
<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 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 generated by a Finite State Machine and yes, it is low when writing and high the rest of the time. My read requires an additional enable, though. You are probably right about the need to register the separate input/output signals--the 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 assignment statement). How does the register/no register impact my design besides 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 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
 
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
 

Welcome to EDABoard.com

Sponsor

Back
Top