Help - Search - Members - Calendar
Full Version: Designing Genbus.tcl
Impulse Support Forums > Impulse Forums > Impulse C Support Forum
cenl
Hi,

I wanna ask some advise on designing the genbus.tcl.
I've created a VHDL wrapper for the Nallatech BenNuey FPGA. The wrapper basically connects the DMA interface from the Nallatech Communications Core code with an Impulse input and output stream.


The wrapper flow is some what similar to the genbus.tcl from the Dimetalk PSP. I'm trying to modify the genbus.tcl to include the Wrapper code with customized port naming using information from iname - con[2]. I dont intend to include the Comm Core code in genbus.tcl. Instead, i'll combine it with the generated VHDL codes from Impulse in Xilinx ISE using export.tcl which also automates impulse library addition, synthesis and implementation.

Based from previous advise from Ralph, I'm trying to use a debugger to step through the genbus.tcl to see how it works. I'm currently using RamDebugger.I'm trying to put some dummy parameters to genbus.tcl but i'm not sure what to put as the "connections" object. So, i tried to do a remote debug to see what parameters are being passed to genbus.tcl from Impulse C but i couldn't get it to work yet.(still trying) blink.gif

I'm still new to Tcl so forgive me if the questions below seems amatuerish.
[1] Please verify if the following is accurate.
The impulse_arch.exe calls the GenerateBUS in genbus.tcl to generate the bus wrapper while passing certain parameters. The HDL Interface Generation API definition is made available to genbus.tcl from the libraries tcl83.dll and tk83.dll in the bin folder.

[2] If i were to write a genbus.tcl script from scratch and run it independently from Impulse C, i would have to include tcl83.dll and tk83.dll to the Tcl library folder to enable the HDL Interface Generation API?

[3] The debugger arguments for genbus.tcl are the parameters for GenerateBUS which are outdir, name and connections. The correct way to write the arguments in the debugger arguments list is:

  • "hw" "HelloWorld" "{conn[1] conn[2] conn[3] conn[4] conn[5]} {conn[1] conn[2] conn[3] conn[4] conn[5]}"
  • "hw" "HelloWorld" "conn[1] conn[2] conn[3] conn[4] conn[5] conn[1] conn[2] conn[3] conn[4] conn[5]"
  • hw HelloWorld "conn[1] conn[2] conn[3] conn[4] conn[5]" "nn[1] conn[2] conn[3] conn[4] conn[5]"
  • any other way?
[4] Have anyone tried any other debugger to remote debug any tcl scripts in Impulse C?

Please advise on the questions above. I appreciate any other advice and tips that would help me. wink.gif

Thanks laugh.gif

Sincerely,
Justin
RalphBodenner
Hi Justin,

Nice diagram!

QUOTE (cenl @ Apr 16 2009, 02:44 AM) *
The impulse_arch.exe calls the GenerateBUS in genbus.tcl to generate the bus wrapper while passing certain parameters. The HDL Interface Generation API definition is made available to genbus.tcl from the libraries tcl83.dll and tk83.dll in the bin folder.

Yes--and no. The HDL Interface Generation API is provided by impulse_arch.exe, and this makes debugging more difficult (see below).

QUOTE (cenl @ Apr 16 2009, 02:44 AM) *
If i were to write a genbus.tcl script from scratch and run it independently from Impulse C, i would have to include tcl83.dll and tk83.dll to the Tcl library folder to enable the HDL Interface Generation API?

Not exactly. You need a Tcl interpreter (tclsh, for example) to run a Tcl program. impulse_arch.exe includes such an interpreter (which in turn depends on the DLLs you mention). If you run genbus.tcl by itself, and not in the context of an executing impulse_arch.exe, you will see many errors about undefined procedures.

Since genbus.tcl calls the API functions that are hidden within impulse_arch.exe, you will want to invoke impulse_arch.exe for remote debugging in RamDebugger and pass it command-line arguments so that it pulls in your genbus.tcl. Specifically, the '-a' argument should point to your PSP. Look in the Build Transcript window in CoDeveloper after you've done "Generate HDL" to see an example command line for impulse_arch.

I've never used RamDebugger, but I suspect that if you just start impulse_arch.exe as it suggests, that program will run to completion before you can hook it for debugging. So you may want to insert a 'gets stdin' statement in your genbus.tcl so impulse_arch.exe will be forced to pause at that point.

QUOTE
The debugger arguments for genbus.tcl are the parameters for GenerateBUS which are outdir, name and connections. The correct way to write the arguments in the debugger arguments list is:[/b][/i]
  • "hw" "HelloWorld" "{conn[1] conn[2] conn[3] conn[4] conn[5]} {conn[1] conn[2] conn[3] conn[4] conn[5]}"
  • "hw" "HelloWorld" "conn[1] conn[2] conn[3] conn[4] conn[5] conn[1] conn[2] conn[3] conn[4] conn[5]"
  • hw HelloWorld "conn[1] conn[2] conn[3] conn[4] conn[5]" "nn[1] conn[2] conn[3] conn[4] conn[5]"
  • any other way?

Rather than passing the parameters directly to genbus.tcl, you will be running impulse_arch.exe. Therefore, the connections list will come from a .xic file, which is in an Impulse C compiler intermediate format. The best way to create a .xic is to generate HDL for an Impulse C project. So, finally, the way to get a connections list for your genbus.tcl is to write an Impulse C project that uses the connections you'd like to test. Kind of a roundabout way to get where you're going, I know blink.gif

If all else fails and you can't get debugging impulse_arch.exe to work, my next suggestion would be to do "puts debugging"--run impulse_arch.exe by itself, and sprinkle 'puts' statements into your genbus.tcl. Not as nice as a GUI debugger, but it'll help.

You could also try forcing impulse_arch.exe into the Tcl shell during execution--see the last answer in this thread:

http://stackoverflow.com/questions/18326/t...bug-environment

Regards,
Ralph
cenl
Hi Mr. Ralph,

My sincere thanks for taking time to explain and offer me advice. rolleyes.gif I now have a better understanding of what i'm dealing with.

I included the "gets stdin" in genbus.tcl to force impulse_arch.exe to pause so that i can link the RamDebugger with genbus.tcl but there are errors regarding the linking packages from RamDebugger. It works if the tcl script is standalone though.

Not feeling too adventurous today to debug that issue, so i resorted to the "puts debugging". Its a much simpler approach to what i'm trying to accomplish above, although it might be a bit more messy.

Thus, i'm on my way writing the appropriate genbus.tcl for my PSP.

I have some questions relating to the DimeTalk PSP genbus.tcl:
[1] I just wanna confirm that if the processes below are defined but not used in the genbus.tcl or they are used by some API function?
  • proc makeVec {val width}
  • proc genDTSignals {fd connections}
[2] (This is gonna sound very student-ish) huh.gif The proc genDTAttributes generates the attributes list in the entity declaration. I've not used attributes before in my vhdl designs, so i'm not really sure about it does. Even after reading some info about vhdl attributes i'm still a bit confused. I tried synthesizing a Impulse-Dimetalk FIR example after commenting out the attributes but it yielded errors. I've checked a few other genbus scripts but none of them generates attributes. Could you describe what is the function of the attributes section in the overall Dimetalk design?

[3] (Another student-ish question) huh.gif How do i get the arguments/options list that can be used with impulse_arch.exe? or the example in the build transcript window has it all?

Please advise. laugh.gif

Sincerely,
Justin
RalphBodenner
Hi Justin,

If you do feel adventurous, I'd love to hear if the breakpoint method from that StackOverflow post works. In any case, I'm glad you're on your way again!

QUOTE (cenl @ Apr 17 2009, 02:05 AM) *
I just wanna confirm that if the processes below are defined but not used in the genbus.tcl or they are used by some API function?
[/i][/b]
  • proc makeVec {val width}
  • proc genDTSignals {fd connections}

Any procedures defined in genbus.tcl are only used if called directly in genbus.tcl. API functions have no dependencies on the contents of genbus.tcl.

QUOTE (cenl @ Apr 17 2009, 02:05 AM) *
[2] (This is gonna sound very student-ish) huh.gif The proc genDTAttributes generates the attributes list in the entity declaration. I've not used attributes before in my vhdl designs, so i'm not really sure about it does. Even after reading some info about vhdl attributes i'm still a bit confused. I tried synthesizing a Impulse-Dimetalk FIR example after commenting out the attributes but it yielded errors. I've checked a few other genbus scripts but none of them generates attributes. Could you describe what is the function of the attributes section in the overall Dimetalk design?

The DIMEtalk tools use these attributes to know how to connect the Impulse C module into the DIMEtalk network. I do not know the details of the how and why, as this is specific to DIMEtalk. There may be documentation or support you can obtain from Nallatech (who originally developed the DIMEtalk PSP).

QUOTE (cenl @ Apr 17 2009, 02:05 AM) *
[3] (Another student-ish question) huh.gif How do i get the arguments/options list that can be used with impulse_arch.exe? or the example in the build transcript window has it all?

Take a look in the CoDeveloper User's Guide (Help > CoDeveloper User's Guide menu in CoDeveloper). There is a section entitled "CoBuilder Command Line Tools" that describes the shell interface for all the Impulse C compiler tools.

Regards,
Ralph
cenl
Hi Ralph,

Thanks for the tip on the breakpoint method from StackOverflow. It works well. laugh.gif
I just need to add 'bp' on any part of the script and the script will stop there with a tlcsh prompt. Then i can use the basic tcl commands to watch the variable values.
Typing 'c' will continue running the rest of the script until the next breakpoint if any. Typing 'i' will output the list of arguments used up till that point.

Thanks for explaining to me on my previous questions.

Unfortunately, the support for the Nallatech board ended five years ago, long before i started working on it blink.gif . I cant get any info from them about the PSP. There is an application note in their website on how to use Impulse C with Dimetalk but thats about it. Anyway, i dont think i'll be using the attributes in my genbus.tcl. Going through all the available genbus scripts in Impulse C should be able to help me get my script working properly.

Sorry about the question on the impulse_arch command options. I should have checked properly on the Help files before asking you. My bad unsure.gif

I already have some questions in mind that i want to ask you but i'll finish my script first so that i can ask better.

Thanks for your kind help. laugh.gif

Sincerely,
Justin
cenl
I'm about done with my genbus script and it should work as it's just another form of the hardware wrapper i wrote in VHDL, but i need to simulate it first to verify its functionality.

I have a question which i want to ask your advise.

[1] The hardware wrapper i wrote to interface with the Nallatech Comm Core and Impulse streams only supports one I/O stream currently. I'm thinking of modifying my wrapper to enable multiple I/O streams to support better design flexibility,design partitioning and maybe coarse grained parallelism. The Nallactech Comm Core has a 4-bit DMA channel, so i'll decode one channel per-stream.
However, the data transfer from software is through DMA. That means even though i have multiple I/O streams, only one stream will be active at any certain time to send or receive data from the Comm Core. So, it cant be considered as coarse grained parallelism right? since the I/O streams do not run simultaneously.

Please advise.

Justin
RalphBodenner
Yes, multiple streams between host CPU and the FPGA likely won't transfer in parallel, so there is no coarse-grained parallelism there. However, coarse-grained parallelism is possible within the FPGA, using multiple processes that operate on the single concurrent channel from the CPU. Your applications could include a hardware process that splits incoming data between many processes doing the important computation.

Modifying the PSP to support multiple streams (using, for example, multiplexers in the bus wrapper) is still a good idea for supporting more a flexible software model. Application code may be more readable and portable if you can use multiple streams when targeting the Nallatech platform.

Ralph
cenl
I'm done with my first version of genbus.tcl... Running impulse_arch.exe on the Fir51 example generates the VHDL wrapper successfully.
However, i need to do some modifications to allow only 32 bit streams.

I imported all the design files to Xilinx ISE Foundation to run a simple simulation test.
The wrapper works fine but the input stream is not getting the correct data from the DMA channel.
I didnt read the Generating PSP Application Note thoroughly about it. My bad.
I assumed that as long as the FIFO stream is not full then the rdy signal will always be high.

The simulation shows that the stream rdy signal changes at every one clock cycle. So i must hold the data for 2 clock cycles before updating. Which is the same as the figures in the PSP Application Note.

Currently, the Nallatech PCI Comm Core DMA interface updates data bus every 1 clock cycle.

Currently, I'm not sure how to solve this.
Is there a way where i can change the stream structure so that the stream read/writes synchronizes with the PCI Comm Core DMA?
Or do i have to implement a FIFO or a RAM to hold the data for 2 clock cycles?

Need some major help on this one.

Please advise.

Sincerely,
Justin
RalphBodenner
QUOTE (cenl @ May 7 2009, 02:30 AM) *
I assumed that as long as the FIFO stream is not full then the rdy signal will always be high.

The simulation shows that the stream rdy signal changes at every one clock cycle. So i must hold the data for 2 clock cycles before updating. Which is the same as the figures in the PSP Application Note.

Currently, the Nallatech PCI Comm Core DMA interface updates data bus every 1 clock cycle.

Currently, I'm not sure how to solve this.
Is there a way where i can change the stream structure so that the stream read/writes synchronizes with the PCI Comm Core DMA?
Or do i have to implement a FIFO or a RAM to hold the data for 2 clock cycles?

The _rdy signal may change every clock cycle, or it may stay high for many cycles in a row, or stay low. The behavior of the signal depends on the logic generated for the Impulse C application using the stream. So the PSP should be designed to account for all these possibilities.

Is there a backpressure mechanism, or an "almost full" kind of feedback to the PCI DMA interface? If so, you can insert a FIFO that's big enough to hold as much data as could be in-flight after you assert the "almost full", and deassert that after the stream clears out the FIFO. You could even make this logic measure the stream's data rate and time the "almost full" signal appropriately.

Ralph
cenl
Hi Ralph,

Thanks for your advise. I'm looking in the suggestion you gave.
Unfortunately, the PCI Comm Core has no backpressure mechanism from the user's code side.
The PCI Comm Core only receives the WEN and REN signal from the hardware wrapper.

The PCI Comm Core has 2 internal 16 word deep FIFOs which buffers the reading and writing of data. The Comm Core has FIFO full signals to the user code though. Since the stream_rdy signal goes low for 1 clock cycle after receiving data then goes back high for one clock cycle to read another data, I initially thought of adding the stream_rdy signal to the read/write rule such that the FIFO will only receive/send out data when stream_rdy is high. This is like implementing an asynchronous FIFO. This should not be a problem for the writing data to the PC because the FIFO writes out to the PC faster than it can receive data from the output stream. However, for reading data from the PC, the FIFO reads faster than it can write to the input stream. This will cause the FIFO to be always full which will continually halting the system.

Another idea would be to implement a clock divider from the PCI Comm Core clock source and feed that signal to the streams. Theoretically, i think this should solve the problem for both input and output streams.

Does this look logical to implement?

Please advise.

Sincerely,
Justin
cenl
Hi Ralph,

Please ignore my previous post.... I wasnt thinking it through enough...
The first method i mentioned wont work because the Comm Core is managed by a FSM. Changing anything to the Core will affect the FSM. I'm want to avoid touching the Core codes.
For the second method, i'm suppose to use a clock multiplier(PLL or DCM) not a divider.

The only option so far is to implement two FIFO, one for read and one for write. Since the Comm Core has no backpressure mechanism from the users side, i'll just have to live with that limitation. For example, i would have to specify that this PSP only supports 256 words transfer per one DMA write function, depending on the size of the FIFO i'll be using....

I'll think this through the weekend. I'll contact you again on Monday.

Thanks for you kind help and attention.

Sincerely,
Justin
cenl
Hi Ralph,

I've been thinking about the FIFO implementation to solve the issue i'm having.

I plan to put one FIFO for data coming in from the Core to the Impulse input stream and another FIFO for data going out from the Impulse output stream to the Core.

Theoretically, it should work. However, getting it to work with using DMA channels to support multiple stream seems tricky.
I'm a bit concern about the EOS signal for the input stream.

Could you explain a bit about the behaviour of the stream in regards to the EOS signal?
For example, what happens to the stream if EOS is never high? Can i put the EOS to be high once after several DMA writes instead of putting the EOS high after every DMA write?

Please advise.

Sincerely,
Justin
RalphBodenner
QUOTE (cenl @ May 13 2009, 09:11 AM) *
Hi Ralph,

I've been thinking about the FIFO implementation to solve the issue i'm having.

I plan to put one FIFO for data coming in from the Core to the Impulse input stream and another FIFO for data going out from the Impulse output stream to the Core.

Theoretically, it should work. However, getting it to work with using DMA channels to support multiple stream seems tricky.
I'm a bit concern about the EOS signal for the input stream.

Could you explain a bit about the behaviour of the stream in regards to the EOS signal?
For example, what happens to the stream if EOS is never high? Can i put the EOS to be high once after several DMA writes instead of putting the EOS high after every DMA write?

Please advise.

Sincerely,
Justin


Hi Justin,

EOS should be asserted when the stream is closed. This corresponds to co_stream_close in the Impulse C API, and seeing an EOS causes a non-zero return value from co_stream_read. If a hardware process reading a stream does not check EOS (using the return value from co_stream_read, or from co_stream_eos), then there's no problem--it'll just block reading forever if there is no data.

Ralph
cenl
Hi Ralph,

I'm having some issues with my design interface to the impulse streams. I've created an ImpulseC project using the default template for "one input stream, one output stream" and generated the hw files using the Generic (VHDL) genbus.tcl. The stream depth is 10. I've linked the input and out streams to 2 seperate FIFOs as seen in the simple diagram below:


When simulating writing data into the stream, i've encountered a problem where the impulse process does not write out the last data of the DMA write. For example, if i write 5 data during the first DMA write, only 4 data gets written out. The last data is held in the Impulse Process. If i continue another DMA write of 5 data, 5 data will be written out but the first data is from the first DMA write. Now the last data of the second DMA write will be held inside the Impulse Process mellow.gif . This is better explained with the simulation waveform below:


Need your directions on how to solve this.... laugh.gif

Please advise.

sincerely,
justin
etrexel
Hi Justin,
Does your process have a pipelined loop? If so, you may be seeing "pipeline stalling" caused by IO operations within a pipeline: Basically all stages within a pipeline cannot transition until ALL stages are ready including IO calls like co_stream_read/write(). This can cause a stall on a write until a read comes back with data effectively "pushing" data out of the pipeline. In your example you should see evidence of this if you were to write 6 times and still only be able to read 5.

Best Regards,
Ed
cenl
Hi Ed,

Firstly, i would like to apologize for the sudden silence. The solution you gave is correct. The issue i was having is caused by the pipeline looping.
The simulation showed the expected results after i commented out '#pragma CO PIPELINE' in the hw file.

Looks like there are no other issues with my hw interface.
My genbus.tcl is more or less done(hopefully....) laugh.gif
I just need to add some script to do some checking for consistency purposes...

I've tried a simple dma data transfer test using the bitstream generated from vhdl files from my genbus.tcl.
It works fine at the moment.

I've got some questions on the sw interface but i'll ask in the other topic that i started:
Designing genlib.tcl

Thanks again for all the help.

sincerely,
justin
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2010 Invision Power Services, Inc.