How to read & write to fifo from Microblaze? - fpga

I have made my project and i have added a microblaze processor to my project.I have also added a H/W core that has a FIFO to my project.I want to read and write to the FIFO from the processor(by writing a c code in SDK).What should I do?

I have used Microblazed with customs IP's that use FIFO's to communicate with the Microblaze (EDK 14.7).
When you set up the Microblaze, it asks you to specify some "Software Registers". This software registers are located at the "user_logic.vhd" that is created automatically when you try to "Import as Peripheral" your custom IP (for example your FIFO). Choose the number of software registers that is appropriate for your project and connect them (in the user_logic.vhd) with the signaling of your FIFO (Inpout/Output/Empty/Full), in order to control the contents of the FIFO (Read and Write transactions). When you generate the bitstream of your hardware implementation and download it to your FPGA, in your project file there will also be created a file named "drivers" which contains all the library files with implemented functions to Read and Write at the software registers of the Microblaze.
Now you can import those drivers in your C project in the SDK enviroment, in order to use those automatically implemented functions and access the Software Registers (and through them, your FIFO).
Nassos

Normally an I/O device, like your FIFO, is memory-mapped to one address or to a memory-address range.
If it's mapped to one address you should use multiple read or write instructions to the same address like this:
// example address for the FIFO
void myFifo = 0x0000AB00;
// write
*myFifo = dataToWrite;
//read
dataFromFifo = *myFifo;
If your FIFO is mapped to an address-range, then myFifo would represent the FIFO's base address and you can use memcpy to copy multiple bytes/words to the FIFO.
The address mapping can be done by this pseudo code:
single address:
fifo_write <= '1' when (bus_address = x"0000AB00") and (bus_we = '1') else '0';
address-range:
fifo_write <= '1' when (bus_address(31 downto 8) = x"0000AB") and (bus_we = '1') else '0';
In case 2. the lowest 8 bits are don't care and any write access is translated to a FIFO write operation.

Related

Difference between PORT and LAT on an PIC18F

I am currently working on a PIC18F and I wonder what the difference is between a PORT and a LAT because looking at the documentation of the PIC18F they both do the same thing.
A write to the PORTx register writes the data value to the port latch.
A write to the LATx register writes the data value to the port latch.
A read of the PORTx register reads the data value on the I/O pin.
A read of the LATx register reads the data value on the port latch.
Use LATx: to write to an output pin
Use PORTx: to read an input pin
For all PICs with LATx registers, all INPUT must be from PORTx and all OUTPUT should be to LATx, which totally avoids the problem of flipping bits when you write to a single bit of the port.

chisel asynch fifo / multiple clocks.

Does Chisel support multiple clocks in a design, yet? If I wanted to implement an asynchronous fifo how would one going about doing that in Chisel?
Yes Chisel support multiple clocks in a design. If you want to use an asynchronous fifo you can import module ChiselUtil, it contain an asynchronous fifo :
https://github.com/ucb-bar/chisel/blob/master/src/main/scala/ChiselUtil.scala#L599
To change clock domain for a register, use the argument clock of Reg() :
val s1 = Reg(init = UInt(0), clock = clockB)
See more information in tutorial chapter 16.

How to detect on which Altera FPGA I am from software running on NIOS2 processor

I think my title says it all.
I am running a software on a NIOS2 processor on an Altera FPGA.
Is there some way to detect which is the FPGA that the software is running on?
To answer the question in the comment: Why do I care which FPGA I am on?
For production we use a design with EPCS controller to program everything. This programming flow is not sensitive to Quartus versions, unlike the .jic flow using Quartus programmer.
Unfortunately, for new EPCQ devices you have to correctly program the non-volatile register of the EPCQ with the proper wait states and addressing mode so that the FPGA will configure correctly.
The NIOS shell tools don't have the capability to do that (Quartus programmer with .jic flow does it) so I wrote a small piece of software that does that.
There is a table in the EPCQ datasheet that says what the wait states should be according to FPGA family and size of EPCQ.
Size of EPCQ I can ask the EPCQ. FPGA family I don't know who to ask. Thus, now for each project I have its personal piece of software with data hard coded to FPGA type. I want the software to be generic and not FPGA specific thus I need to know which FPGA I am on.
If you have access to the JTAG port of the FPGA, clock through the IDCODE register and decode it.
If you have access to the FPGA bitstream file, (which it seems you must, since you are about to program it) in the sparsely-documented header are bytes which describe the target device. Decode them.
Since the bitstreams will be device specific anyway, expose a custom NIOS instruction, or a known memory location (over the Avalon-MM bus) in the firmware that reports the device type to the NIOS.
Details on the 3rd opion
You could use TCL at synthesis time (e.g. some QSYS magic) to inject the project wide DEVICE_FAMILY property into a HDL module as a parameter (device_family), then switch on this inside the generated logic to output a value for each family.
E.g. this I've based on adv_seu_detection_common.v and adv_seu_detection_core_hw.tcl (find them in the Quartus ip directory):
module crcblock_atom ( regout );
parameter device_family = "Stratix III";
output wire [7:0] regout;
generate
if ( (device_family == "Stratix III") ||
(device_family == "Arria II GZ") ||
(device_family == "Stratix IV") ) begin: generate_crcblock_atom1
assign regout = 1;
end
else if ( (device_family == "Arria V") ||
(device_family == "Cyclone V") ) begin: generate_crcblock_atom2
assign regout = 2;
end
else begin: generate_crcblock_atom
assign regout = 3;
end
endgenerate
endmodule
You then need to set the parameter device_family appropriately. You can do this in the ip-core wrapper by using the following partially-undocumented code in xxxxx_hw.tcl that makes the parameter hidden and auto populates it from the project settings:
# | device_family
add_parameter device_family STRING
set_parameter_property device_family VISIBLE false
set_parameter_property device_family SYSTEM_INFO {DEVICE_FAMILY}
set_parameter_property device_family HDL_PARAMETER true
set_parameter_property device_family AFFECTS_GENERATION true
You'd still have to wrap this up as a custom NIOS instruction, or make it look like an Avalon-MM rom, but you get the idea.
Once you've wired it up in the QSYS system for each project and rebuilt them all, it would do what you've asked. It's still pretty ugly though.
For another treatment of this question see http://www.alteraforum.com/forum/archive/index.php/t-33948.html

Simple Adder Control Signals on Zynq SoC - Zedboard

I am new to the Zedboard and am working up to transferring a complex hardware accelerator I currently have working on a regular FPGA board. Anyway I want to walk before I can run so have done the Zedboard speedway tutorials and am now toying around with small projects. My first of which being an simple adder accelerator:
-Send 2 numbers to the pl(programmable logic), to reg a and b
-the pl adds the numbers
-an interrupt to the PS(CPU) signals the computation has finished.
-In the ISR the PS reads the result from reg c
For this design I am using 3 registers (a,b,c) in the AXI interconnect, I have created the IP templates using CIP.
Basically though what is the best way send a control signal to enable the addition to the PL. So how should I signal to the PL adder that I have loaded the two numbers in reg a and b and now want to add them?
-Should I create a 1bit signal GPIO interconnect, add a 4th 1 bit control register to the IP? or is there a more 'stylish' way to do this by using the BUS2IPdata signals?
-Or is there another way to create custom PS to PL control enable signals?
Many thanks
Sam
Current idea:
-Build a switch in the user_logic HDL based on the BUS2IPWrCE, so when this is asserted to write to reg B I can then signal an enable signal to my adder? Or will I run into some concurrency issues with the data not being fully written straight away?
So to do this I have created the AXI perph using CIP, then modified the used_logic and two new ports, en and interrupt. Following these instructions I employed these external connections.http://www.programmableplanet.com/author.asp?section_id=2142&doc_id=264841
I then connected these two external connections to GPIO interfaces to provide the required functionality.
In your larger designs, it will be difficult to get performance using a GPIOs to control the scheduling of your accelerators. I suggest setting up FIFOs of command blocks between software and hardware.
For example, your peripheral could implement an AXI Stream slave, to receive commands from software, and an AXI Stream master, to send result indications back to software.
It can assert an interrupt to indicate that there are values in the response FIFO.
For higher performance, set up these FIFOs in DRAM and use AXI read/write masters in your peripheral.

Preserving the widths of ports

I am trying to re-use netlists in other designs without the success.
I have a component which is translated to the netlist:
entity c is
port (... sel : in std_logic_vector(31 downto 0); ... );
In the design I am using just sel(4 downto 0).
The synthesis tools notices this behaviour and gives a warning:
'WARNING:Xst:647 - Input sel<31:5> is never used ..
I am generating netlist with properties:
keep hierarchy = true
add I/O buffers = off
Whenever I want to instantiate this netlist as an black-box module in other circuit I got an error:
ERROR:NgdBuild:76 - cannot be merged into block because one or more pins on the block, including pin "sel<31>", were not found in the file.
How can I preserve the size of sel?
I should mention that the sel needs to be 32bits width since it's connected to the bus.
You could try driving the unused input ports to zero.
Can you use the component directly instead of as a pre-synthesised black-box?
You may get things to work by putting a KEEP attribute (see your synth tools manual) on the port. I've only ever tried this on signals, but it may work.
This sort of task is often described as "pushing on the rope" of the synthesiser, as it's such a pain to get it to not be as celever as it wants to be (and then in the next release of tools you need a different attribute :)

Resources