XST: suppressing incorrect optimizations in VHDL code

Hi all,

The following VHDL code does not synthesize using XST 6.2.03:

----- start of fragment

-- The challenge is to define an entity that replicates

-- an input port (push button) to an output port (LED),

-- without declaring them in the entity's ports.

library ieee, unisim;

use ieee.std_logic_1164.all, unisim.vcomponents.all;

entity toplevel is -- wire input button to output LED -- without using a port declaration end entity toplevel;

architecture arch of toplevel is

signal BUTTON : std_logic; signal LED : std_logic; signal sig_led : std_logic; signal sig_button : std_logic;

attribute LOC : string;

attribute LOC of BUTTON : signal is "P22"; attribute LOC of LED : signal is "P20";

component OBUF is port (O: out std_ulogic; I: in std_ulogic); end component OBUF;

component IBUF is port (O: out std_ulogic; I: in std_ulogic); end component IBUF;

begin

button_buf : component IBUF port map(O => sig_button , I => BUTTON); led_buf : component OBUF port map(O => LED , I => not sig_led);

sig_led

Reply to
Sidney Cadot
Loading thread data ...

But you must actually connect it to an outside pin. All you have done is name the net on the other side of the IBUF or OBUF, you have not connected it to the outside world. That is what the port definition is for. Look at it from the perspective of the VHDL compiler. Your signal button has no driver specifed for it. You are expecting the compiler to figure out that an IBUF connects to the outside world. You have to tell it that by using a port definition.

--
Rick "rickman" Collins

rick.collins@XYarius.com
 Click to see the full signature
Reply to
rickman

Maybe I am being a little dense today, but I still don't understand. If your IO functions are the same why would you need different ports? What is different between the boards that you can't just describe the differences in the IO pin assigments in the UCF file? Even if you don't use a port, don't you still need different top level files?

Instantiating the IO pads is a good idea. If that doesn't work nothing will.

--
Rick "rickman" Collins

rick.collins@XYarius.com
 Click to see the full signature
Reply to
rickman

The Designer's Guide To VHDL 2'nd Edition Peter J. Ashenden Page 8 "Using VHDL terminology, we call the module reg4 a design entity, and the inputs and outputs are ports. Figure 1-7 shows a VHDL description of the interface to the entity. This is an example of an entity declaration. It introduces a name for the entity and lists the input and output ports, specifying that they carry bit values ('0' or '1') into and out of the entity. From this we see that an entity declaration describes the external view of the entity."

If one were to be able to snake a signal out, without mapping it thru a port, then the entity declaration would not describe the external view of the entity.

Newman

Reply to
newman

This isn't the perfect solution, but in verilog you could do something like use a define to set the board type and then a bunch of ifdef's to monkey with the port lists on the higher level modules. You could even use an ifdef to instantiate the correct hardware specific low-level module. If you don't want to contaminate the top-level files, you can include the portions that are different out of other files. Basically, the idea is to use the pre-processor rather than the HDL's abstraction model to hide the hardware details. I'm sure there's a similar mechanism in VHDL?

Okay, it's not perfect, but it works for C programmers writing multi-platform code... (What's really cool is if you run the whole thing with a makefile, you can pass the matching parameters not only to the hdl complier, but also to the compiler of the software that runs on your SoC)

Chris

PS - these spartan 3 kits are fun... with the addition of one chip and a bunch of resistors, I have one of the digilent ones pulling pictures off an IDE hard drive and generating a color composite NTSC signal to drive a little LCD tv...

Reply to
Chris Stratton

I failed to make that particularly clear (sorry). There are hardware differences, e.g.

  • The number of seven-segment displays 0/1/4
  • The number of LEDs 4/8/8
  • The number of push-buttons: 2/3/4
  • The number of sliding switches: 0/4/8
  • The availability of AD/DA's on the development board
  • The interface to memory residing on the memory board

I don't see why that would be necessary.

Unfortunately, it didn't work - apparently the IPAD components are not contained in the UNISIM library, and just instantiated implicitly. This rhymes with another tidbit I found in the IPAD docs (Library Guide):

"For HDL, it is not necessary to use these elements in the design. They will be added automatically."

Why are you so sure? I still have some hope :)

Regards, Sidney

Reply to
Sidney Cadot

There are two answers to this: a philosophical one and a practical one.

(1) Philosophical

The "external view" (VHDL wise) of my "mmapped_io" component is basically that it acts like a RAM block, i.e., it has a data bus and an address bus, and R/W control bits. The fact that these happen to do some interesting things to hardware, should be of no concern to the VHDL modules that instantiate an "mmapped_io" component, that's the whole point of having memory mapped I/O.

My mmapped I/O defines a 4K aperture to hardware. My "RAM" components describe a 4K aperture to RAM. At a higher level in my design, I should be able to interchange them without any changes except for the instantiated component name I think.

(2) Practical

Ashenden notwithstanding, the VHDL program shown below demonstrates that XST can in fact bypass ports, at least for outgoing signals. Despite the fact that it is not declared in the entity's port section, the LED does blink when I synthesize and upload this.

All I am asking is for a way to coerce XST to handle input signals in a similar way.

Regards, Sidney

----------------------------------- blingbling.vhdl library ieee, unisim;

use ieee.std_logic_1164.all, ieee.std_logic_unsigned.all, unisim.vcomponents.all;

entity toplevel is port(CLK: in std_logic); end entity toplevel;

architecture arch of toplevel is

signal LED : std_logic; signal sig_led : std_logic;

attribute LOC : string;

attribute LOC of CLK : signal is "P184"; attribute LOC of LED : signal is "P20";

component OBUF is port (O: out std_ulogic; I: in std_ulogic); end component OBUF;

signal counter: std_logic_vector(23 downto 0); begin

led_buf: component OBUF port map (O => LED, I => not sig_led); process (CLK) is begin if rising_edge(CLK) then counter

Reply to
Sidney Cadot

You could select between these with active internal logic, or if you know the difference at compile time, with generate statements or by passing generic values into the entities, right?

I still must be missing something... I don't see how pushing the pin location assignments deep into the hierarchy makes anything easier. You can always make the bus wider need it needs to be to the top level - the tools will optimized it down to the correct width.

Unless it is necessary because some tools require it. :-) I don't pretend to know if VHDL requires the ports to be at the top level or not, but it would not surprise me if some of the tools don't handle it correctly.

Have fun,

Marc

Reply to
Marc Randolph

I am missing something. Are you planning to instantiate your IO ports in low level modules or in the top module? The example you gave is using the top module, but I guess that was a simplification.

If you are trying to put the IOs into lower level modules, you may find this is a bit difficult to keep track of. But that is just a style preference.

--
Rick "rickman" Collins

rick.collins@XYarius.com
 Click to see the full signature
Reply to
rickman

It enhances the maintainability of the code, by concentrating all the knowledge about the particular hardware devices available in one place. For example, adding support for yet another board is then a matter of making one "mmapped_io_.vhdl" and recompiling.

This is one of many options to work around the problem.

That's very true. The fact that XST seems to handle non-toplevel outgoing signals fine but isn't able to recognize incoming signals as drivers suggests the possibility that it is just a problem in XST.

Cheers, Sidney

Reply to
Sidney Cadot

As others have already mentioned, one can use generic and conditional generate statements to customize the designs.

I'm not aware that standard VHDL has a preprocessor #ifdef mechanism. There appear to be some third party offerings. One may easily write one that does the job with sed (less than 10 lines).

The method that you are pursuing may not work in future version of the tools, but that is really for you to decide. A possible solution to get around the dilemma you face is to use an IOBUF instead of an IBUF, and strap the T pin so the output is always tristated. I personnally do not recommend going this route, but it is really your call.

Newman

Reply to
newman

Hi Chris,

I'm afraid there is no mechanism analogous to textual preprocessing like we have in C for VHDL. Nothing is keeping me from using a preprocessor despite that, of course, but life would be just so much easier if I can solve this at the VHDL level.

Well I do tie everything together using a Makefile, I could easily insert a preprocessing stage ... but this would make my stuff considerably less easy to re-use for other people (I intend to publish the project on the Web).

Yes, it is great stuff. I implemented a 6502 from scratch, which uses the internal block memory of the Spartan-III .... I implemented a very small machine language monitor program that works via the RS232, and I must say it's really something to type to this little computer and get a response that shows it works - also happy to be able to rehash those old 8-bit skills I picked up 20 years ago :-) I can also run C programs on this thing (using CC65,

formatting link
which is perfect. It's been a very educational project so far, I've had several occasions to think "so _that_'s why they do it like that!" :)

The digilent/xilinx kit is quite fantastic and really a bargain, at a hundred bucks including the JTAG cable and power supply. I was especially happy with the quality of hardware documentation they provide, after horrific experience in this respect with my NuHorizons kit. The Memec kit I have is also nice by the way, I also have their

50 MHz AD converter kit I use for experiments. Great stuff.

Sounds great! I have been thinking about implementing an IDE interface myself, do you have any more info, e.g. did you implement the IDE core yourself?

Regards, Sidney

Reply to
Sidney Cadot

As I think about this more, it looks to me like you're not really architecting this in a way consistent with the philosophy of a hardware description language. Remember, this is sort of a software equivelent to putting chips on boards and wiring them together. So unless one of your chips happens to be something "magic" like a self-contained RF module, nothing gets into or out of a chip unless you provide traces on the board to get it there. Software engineers get pure abstaction; hardware engineers just get 3ghz wire wrap guns.

From that point of view, I think you should think of your universal bits of code as modules with no real-world I/O - for example, your CPU, any on-chip memory, any other internal functional blocks. Build those into a library of general purpose functions that you can use in any of your projects.

Then for each specific FPGA board, create a top-level module with the actual physical I/O ports. This module should then instantiate a mix of both your library of internal functional modules like CPU, and hardware-specific handler modules for the specific board like your memory mapped io function. You will of course have to wire the physical I/O ports through to those modules which need them, possibly leaving any extrnal tri-states in the top level and passing something back up to control them.

And of course if you do system simulation, you would in turn treat the formerly top-level module as just one component in a testbench module where it gets wired up to simulations of whatever your board talks to...

Chris

Reply to
Chris Stratton

Sidney,

I have noticed that XST will remove pins at the top level of a design that are not connected. Hence, you could create a design with the maximum number of pins you need at the top level and then control whether the functionality is in the design or not with generate. Control the generate with constants from a package. Have one package for each board configuration. I am not sure what other synthesis tools do with IOs so this may not work for all synthesis tools.

If you have excess IO, you can be even lazier. Skip the generate statements, implement all of the functionality in the device, but allow unused functionality connect to unused device pins. This works well for outputs, but for inputs, your design may have to be configured to ignore the unused ones. I use this to make some of our lab projects work on different FPGA boards (Xilinx and Actel for now).

VHDL does not have any conditional statements outside of generate, however, it would be simple enough to use CPP as a preprocessor and script your compiles to always use CPP - of course that would mean that everyone that uses the files would have to do this also. I have done some experiments with this and it seems to work easy enough.

Cheers, Jim

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
 Click to see the full signature
Reply to
Jim Lewis

Standard cpp works fine. Everything gets much saner if you have a makefile.

--
The suespammers.org mail server is located in California.  So are all my
other mailboxes.  Please do not send unsolicited bulk e-mail or unsolicited
 Click to see the full signature
Reply to
Hal Murray

But you may not even need different vhdl files if you use your .ucf file (or whatever it is called in XST) to call out pin numbers.

Have fun,

Marc

Reply to
Marc Randolph

Hal, Thanks for the tip. I'll have to try it out sometime. My sed trick worked OK for small design differences, but it raised a few eye-browses because it was so ad-hoc.

Newman

Reply to
newman

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.