Good morning,Am relatively new to FPGA development and am working through RTFM issues. Please bear with any dumb questions. I've been successful at getting the DE2-115 up and have exercised all of the peripherals using the NIOS OS. I need to develop some custom FPGA code around the NIOS but don't quite understand how to integrate the custom code with the NIOS. The custom VHDL needs to monitor the HSMC and GPIO ports and write to a block of FPGA memory when a specific event occurs. I can manage almost all of this. However, I have four integration questions: 1) (New VHDL Developer Question) - How do I specify a base address for the FPGA memory as part of my code so that I can memory map it to the processor? 2) How do I actually go about "connecting" it to the processor. Do I need to create a custom component in SOPC builder? Or is there a "better" way? 3) Do I need to arbitrate between my custom code and the processor accessing this memory (I'm guessing I do)? 4) How do I connect my custom FPGA to a NIOS interrupt. Not trying to get someone to write the code. However, I've not been successful at finding a tutorial or examples that deal with this topic. Any help is greatly appreciated. ME
The answer to all your questions is mostly: you need to create a new SOPC component.There are however, a few different ways to go about it. a) make your component just an Avalon-MM slave and put the memory in your component (FPGA internal memory). You expose that memory block to the processor, plus whatever configuration register you need, through the slave interface b) make your component an Avalon-MM master, which writes to another Avalon-MM memory slave component (FPGA internal RAM, board SRAM, board DRAM). Most likely, it will also need an Avalon-MM slave interface for configuration (ie, which memory address will it write to) c) make our component an Avalon-ST source and use a SGDMA component to write to another Avalon-MM memory slave (FPGA internal RAM, board SRAM, board DRAM). "a" or "c" are probably the best, depending on your needs For the interrupt, same thing: your component needs to have an Avalon Interrupt interface as well. You probably need to skim through the Avalon and SOPC documentation.
One more Q. Once my application is developed and debugged, I assume there is a method to program DE2-115 NVM with the executable. I've review the generic Altera FLASH prgrammers user guide. IS there more specific guidance?
Thanks again for all of the help...I worked through the SOPC Builder and Avalon documentation. The process seems straight forward enough. I'm sure I'll stumble a few times on the implementation. If I could bother you with an implementation Q (and a bit of background).... We're using the DE2-115 HSMC interface through a custom connector to collect high speed parallel data (Address Bus) on another CPU card (20 year old CPU). I've validated that we receive the HSMC data correctly. I would like to do nothing more than simply set a bit in a memory array for each address that is collected. The CPU address spaces is 0x3ffff. My thought was to create a 0x3ffff by 1 memory element. Once the data has been collected, the Nios would process the data. My first thought was to use the provided DP RAM. However, it looks like the minimum data width is 8 bits. I could use this and shift bits around in the interface VHDL. But, I was wondering if you might provide some design guidance on: 1) Is it possible to create the 0x3ffffx1 array that can be accessed by the nios processor through the avalon interface. 2) Or, is there a better design approach, based on your experience.... Again, apologies for the sophomoric Qs (Still learning) Much appreciated......
The M9K RAM blocks in the FPGA can implement a DP RAM with suitable widths, ie 1 bit write port and 8 bit read port.What you can't do is to expose a 1 bit interface to the Avalon bus -- needs to be 8, 16 or 32 bit wide. So, what you should do is to place the DP RAM inside your custom component and expose the 8 (or 16 or 32) read port through the slave interface.
Hey rbugalho,Thanks for all of the guidance. I've been working through the tool chain using your advice and think I have the paradigm under control. However, I've been not making quite as much progress in the implementation as I had hoped. If possible, could you provide some guidance. Below is a description of what I am attempting to do and the problems I am encountering. I'll be as brief as possible. Again, thanks in advance for any help. The system is using the DE2-115 HSMC and GPIO connectors. They attach to the address, data and a single control line of an embedded Intel 80196 processor. Address and Data are valid when the control line goes low. The overall Quartus project is based on the Simple Socket Server example. The custom component contains an interface to the HSMC/GPIO connectors, a 0x3ffff by 1 RAM, an interface to the NIOS processor and an interrupt. The intent is to write a 1 to the RAM location specified by the 80196 address lines when the control line goes low. I added the interrupt to "ping" the SW ever few thousand 80196 instructions. When I am done collecting 80196 addresses, the NIOS reads the RAM. Note that the 80196 and NIOS are NOT accessing RAM at the same time. I've attached the VHDL file generated by SOPC builder and augmented with code I hope would trigger an interrupt. My struggle has been with finding implementation examples. I would appreciate any implementation guidance. Questions/Issues: 1) (VHDL Newbie Q) I created the interface to the HSMC/GPIO as exports in SOPC Builder. The intent is to connect them to a handful of HDMC/GPIO pins. The HSMC/GPIO pins are allocated in the pin map. What is the syntax for allocating the coe_tdrinterface_xxx ports to specific HDMC/GPIO pins? 2) You'll notice that I tried to implement something to simply toggle one of the LEDs. The intent was to connect it to the red LED component. I would assume I do this with a Avalon MM. However, when I add the MM interface, it doesn't specify any address/data/control lines. 3) I implemented a interrupt_sender which appears in SOPC builder (and the subsequent system.h BSP file) as INT10 and implemented the SW in the attached C file. It appears that the SW initializes the interrupt. It may even be firing. But the SW goes into the weeds when Line 31 executes (Note that I have the interrupt mask cleared to disable all interrupts...?). I have similar interrupts configured for the button DE2-115 button presses. They work. If I look at the button and switch components in SOPC builder, they appear to given me control over interrupt polarity, etc. However, the interrupt sender does not. Sorry for the lengthy post. Again, many thanks in advance.... ME
Uhm... I'm not sure if I get your questions correctly.Once you've setup your SOPC, with the NIOS, memory, your StatementCoverage component, what SOPC builder will produce is a VHDL module, which you can use however you like. The NIOS component, RAM component, StatementCoverage component, etc and the interconnect between them will all be kept within the SOPC generated module. That module will only have as ports the external signals: clk, reset, exported conduit interfaces (such as your coe_tdrinterface_xxx signals). Then you can use that module as any other module. You can make it the top level module in your design or you can instantiate it from another module. So, to sum up, you need to create a StatementCoverage component which has - conduit interfaces with all the signals you need to connect to the outisde world (HSMC, LEDs, etc) - Avalon-MM slave interfaces with enough address space for all the functions you need (ie, the bit RAM, registers to control the LEDs, etc) - An Avalon Interrupt interface. Then setup your SOPC, export the StatementCoverage's conduit interfaces and generate the SOPC module. Then you could make the SOPC generated module the top level module in your design and proceed to assign it's I/O ports to FPGA pins. However, since you're working with a DE2-115 board, I suspect you've already found an empty project with the pin assignment already done. So, I suggested you begin with that empty project as top level and then instantiate the SOPC generated module within it.
Sorry about that. I think I confused the issue......Sorry for the long winded response as well. I just wanted to say thank you. After a couple of drinks last night, I was able to shift paradigms a little bit. I think the shift will make things more efficient and keep me from asking dumb, esoteric Q's....Many thanks for all of your guidance.You comments made me wonder if I wasn't executing the tool chain correctly. I went back last night and created a second, different component in Component Builder, integrated it into SOPC Builder and then built the FPGA image in Quartus. I can see the component in the Quartus Project Navigator. So I am assuming that I am executing the tool chain correctly (Please feel free to advise if not). I also see the component# defines show up in the system.h BSP file. The intent of integrating the LED control into StatementCoverage was nothing more than an attempt to debug my VHDL. The SOPC Builder environment accesses the LEDs (and other board peripherals) through a clock_crossing_io component (Base Address 0x09000000). The CPU Data Master connects to the CC IO Slave. The CC IO Master then connects to the peripherals. I added a MM Master in StatementCoverage with the intent to connect to the CC IO MM Slave. Instinct tells me I am OK on the tool chain and a basic understanding of how to build interfaces and connect components. What I believe I'm missing is an understanding of the implementation of any specific component. I also think I am compromising myself as all of the template HDL is written in Verilog and not VHDL (VHDL was legacy suggestion from someone else). I think there are enough .V examples to generate the StatementCoverage component in Verilog. Since I'm an HDL newbie, it won't take me long to shift gears.....