Discussion:
bidirectional delay in verilog?
DJ Delorie
2009-04-22 04:43:35 UTC
Permalink
I want to simulate the propogation delay through the fpga IOBs and the
traces on the board. However, some of the lines are bidirectional
(specifically, the data lines). It's easy enough (I'm assuming) to
assign a delay on a unidirectional line, but what about bidirectional
lines?
John Griessen
2009-04-22 14:02:08 UTC
Permalink
Post by DJ Delorie
I want to simulate the propogation delay through the fpga IOBs and the
traces on the board. However, some of the lines are bidirectional
(specifically, the data lines). It's easy enough (I'm assuming) to
assign a delay on a unidirectional line, but what about bidirectional
lines?
If you want to model the full behavior of the FPGA logic programmed in,
without all the details of logic to do that,
you would make an assignment conditional on the state of the machine
as a bit of procedural code like a case statement embedded in the ordinary verilog
that acts all in parallel to model wires and gates...

If you want to model enough to synthesize gates, you would specify
logic in verilog that has registers and holds states, and the state that switches
the bidir port to one or the other way would cause the
the wire and register switching delays to be assigned as a verilog combination function
of the inputs.

The first way is what they call a behavioral model, and second is register transfer level model (RTL).

John

-
DJ Delorie
2009-04-22 16:41:39 UTC
Permalink
Post by John Griessen
If you want to model the full behavior of the FPGA logic programmed in,
Behavioral is fine, I just don't know the syntax for doing a
bidirectional delay.
c***@public.gmane.org
2009-04-22 15:20:51 UTC
Permalink
----- Original Message -----
From: DJ Delorie
Date: Wednesday, April 22, 2009 12:43 am
Subject: gEDA-user: bidirectional delay in verilog?
Post by DJ Delorie
I want to simulate the propogation delay through the fpga IOBs
and the
traces on the board. However, some of the lines are bidirectional
(specifically, the data lines). It's easy enough (I'm assuming) to
assign a delay on a unidirectional line, but what about bidirectional
lines?
Are you modeling the FPGA and the DRAM (I'm assuming it's the DRAM, not that it
matters so much)? Are you using a test bench to run this? You could do something like
this:

| FPGA | --------- | DRAM |

Make the DRAM a purely functional model, very simple, and add the flight time into to the
input and output delays. You can model the DRAM IO as a dedicated input plus a wire-
or'd tristate output device. So maybe the flight time on the wire is 1 nS, you setup the
DRAM input delay as 1 nS. Then add 1 nS onto the output buffer of the DRAM to model
the flight time back to the FPGA.

Use a test bench to combine the FPGA and the DRAM into one device, wired together as
needed. Then just excercise it anyway you like. It doesn't have to be a test bench per-
se, since a hierarchical verilog source file is the same thing, and you can simulate that
as well.

As for the IOB's. Hmm. One way is to use the timing simulation file that XST creates,
post layout. I think it is in verilog, or can be made in verilog via some selection. You can
just plug it into the setup I was just mentioning. If that is not the case, then you can
model the IOB as a dedicated input and tri-stated output and add the delays you like.
(this is how the fpga builds bidirectional lines anyway, they can't build wire-or inside the
part)

FPGA IOB the wire DRAM IOB

|Tri-state output |->>----------------------- >>-| input buffer|
|Input Buffer |-<<-| <<-| Tristate output |
DJ Delorie
2009-04-22 16:46:07 UTC
Permalink
Post by c***@public.gmane.org
Are you modeling the FPGA and the DRAM
I have a core SDRAM controller module, and Micron's SDRAM model. I
have a testbench that runs under Icarus/gtkwave but it's inaccurate as
it doesn't simulate the IOB delays and signal propogation. When I
model it under Xilinx's simulator, with the pinout connections and
such, it models the IOBs but not the SDRAM, as the SDRAM isn't inside
the FPGA.

So what I'd like to do is get the timing information from ISE and add
it to my icarus testbench, so that icarus can more accurately model
what the whole circuit will do, not just what happens inside the fpga.

Given a 7.5 nS cycle time and ~3nS IOB delays, getting this right is
going to be important.
Post by c***@public.gmane.org
| FPGA | --------- | DRAM |
See http://www.delorie.com/electronics/sdram/
c***@public.gmane.org
2009-04-22 21:15:07 UTC
Permalink
Ok. I peeked at your verilog code, not too closely, just a little so I may make a mistake.
There are 2 IO ports, RamData and mcuData both defined as inout so you can tristate
there outputs to world. Looks like you are connecting ramData to mcuData by latching
one side, then driving out to the other and vise-versa.

XST is going to put those tristate drivers in the IOB's. The registers may or may not be
put into the IOB but I guess probably not. You can get the prop delays from the place
and route results. Use that value in your statements to add the output (IOB) delay to your
code. The synthesizer doesn't care, it'll ignore it. So maybe something like this:

parameter IOB_DELAY = 10;
assign mcu_data = #IOB_DELAY my_mcu_data;
assign ram_data = #IOB_DELAY my_ram_data;

Just remember to setup the correct delay steps at the beginning of your code:
`timescale 1ns/1ps

which is 1ns step size, with 1ps resolution on the simulator.

Modeling your code functionally, with just this simple change will get you the delay for the
IOB. You'll have to check for timing violations manually though.

you could modify the delay time period to include the flight time:
parameter IOB_DELAY = 10;
parameter FLIGHT_TIME = 3;
parameter OUTPUT_DELAY = IOB_DELAY + FLIGHT_TIME:
assign mcu_data = #OUTPUT_DELAY my_mcu_data;
assign ram_data = #DELAY_DELAY my_ram_data;

Something like that. You have the micron verilog code which you could modify to
include the flight times too. If it's too difficult to weed through their code, modify your
code on the input side to include the flight time too:

else if (~mcu_nwr) begin
my_ram_data = #FLIGHT_TIME mcu_data;

Loading...