Low level DFB is very interesting for me but this very very hard programming. More example will be better.
P.S. sorry i not help you but very interesting theme
I have modified your code (below). I hope this is what you are expecting.
The code works as follows:
Value is loaded from Staging register A (Bus 1). This value is multiplied, Sem 0 is set and multiplied result is written to holding register.
1. All DFB registers are 24 bit. The filter coefficients should be converted to the appropriate format and loaded in the 24 bit Staging registers. If all the coefficients are less than +/-1, then all the calculations will result in 23 bits for decimal points and one for sign format. This simplifies the calculations inside DFB as no shift operation is needed at intermediate nodes so as to align the data in the same format.
2. Please read the datasheet for adding appropriate wait cycles for specific instructions wherever required
// Clear ACU modflag and clear ACU
acu(clear,clear) dmux(sa,sa) alu(set0) mac(hold)
acu(hold,hold) dmux(sa,sa) alu(hold) mac(clra) jmp(eob, waitfordata)
// Wait for data in Channel 1 Input Register
acu(hold,hold) dmux(sa,sa) alu(hold) mac(hold) jmpl(in1,write_bus)
acu(hold,hold) addr(1) dmux(ba,sa) alu(seta) mac(hold) // Load value from staging register A
acu(hold,hold) dmux(sa,sa) alu(hold) mac(clra) // Multiply
acu(hold,hold) dmux(sm,sa) alu(seta) mac(hold) // Move MAC o/p to ALU
acu(hold,hold) dmux(sa,sa) alu(hold) mac(hold) // Wait for 1 cycle
acu(hold,hold)addr(1) dmux(sa,sa) alu(hold) mac(hold) write(abus) // Write the result to holding register
acu(hold,hold)addr(1) dmux(sa,sa) alu(setsem,001) mac(hold) // Set Sem 0
acu(hold,hold) dmux(sa,sa) alu(hold) mac(hold) jmp(eob,waitfordata)
Whoa, where did you find the assembler reference/mneumonics for the DFB itself? I too would love to be able to use the DFB for things other than just digital filtering per se.
DFB datasheet mentions about the assembler reference/mnemonics. Please refer "DFB Assembler" section in the datasheet. You might also want to read the TRM to understand the hardware as well.
I am very interested in offloading some multiplications to the DFB MACC (using PSOC5 LP). I am currently writing a 16 bit number to the holding register, which I want to square (A*A) and then write the output to the staging register. I have a decent understanding of the assembler instructions however I have never been able to see a value in the simulation output other than the values that are on Bus1 or Bus2 (Bus values used for simulation purposes) .
I have tried many combination of pipeline delays, MACC, DMUX commands etc and have never seen evidence of a multiply in the simulator. I have also tried all of the assembler code that I could find written by others, including the code above, and never see a multiplied value or output. Can anyone point me to code that will work in the simulator?
Any help will be greatly appreciated.
I guess you meant that you are feeding input to staging register and reading the output through holding register.
Here is the general DFB assembler code used for multiplying two numbers. In this case, giving the same input to both staging registers A and B would give you the square of that number.
acu(clear, clear) dmux(sa,sa) alu(set0) mac(hold)
acu(setmod, setmod) dmux(sa,sa) alu(hold) mac(clra) jmp(eob, waitForNew)
// Wait for data to be written to Staging Registers
acu(hold,hold) dmux(sa,sa) alu(hold) mac(hold) jmpl(in1,in2,dataRead)
// Read New Data from Staging Register and multilpy and put dat to holding register B
acu(hold, hold) addr(1) dmux(ba,sa) alu(seta) mac(hold) //Move data from staging register A to ALU o/p
acu(hold, hold) dmux(sa,sa) alu(hold) mac(hold) //Wait for ALU output
acu(hold, hold) addr(0) dmux(sa,ba) alu(hold) mac(clra) //Multiply staging register B & ALU o/p
acu(hold, hold) dmux(sm,sa) alu(seta) mac(hold) //Move MAC o/p to ALU
acu(hold, hold) dmux(sa,sa) alu(hold) mac(hold) //Wait for ALU output
acu(hold, hold) addr(0) dmux(sa,sa) alu(hold) mac(hold) write(bus) jmp(eob,waitForNew) // Write the result to holding //register B"
Kindly test the same and let us know if you are able to square a number.
Thanks for the quick response.
Your right I got the registers mixed up in my previous post. I have tried your code in the DFB assembler. I'm still having issues. Here is my process.
- Paste Code into assembler
- Input a value into Bus1 Line1 and Bus2 Line2 (e.g. 0xA and 0xA to represent a square)
- Click Assemble (Completes with no errors)
- Click Simulate
--------------- Simulation Started: 09/06/2013 08:17:05 ---------------
DFB Simulator version 3.0.0
--------------- Input data ---------------
Cycle RamA RamB Ram CFSM Aaddr Baddr A2Mux B2Mux MacOut AluOut ShiftOut
sel state next next
0 0 2 A 0 0 0 0 0 0 0 0
1 1 2 A 1 0 0 0 0 0 0 0
2 3 2 B 2 0 0 0 0 0 0 0
3 3 2 A 2 0 0 0 0 0 0 0
4 4 2 A 2 0 0 A 0 0 0 0
5 5 2 A 2 0 0 A A 0 A A
6 6 2 A 2 0 0 A A 0 A A
7 7 2 A 2 0 0 A A 0 A A
8 8 2 A 1 0 0 0 0 0 0 0
9 3 2 B 2 0 0 0 0 0 0 0 busr1= 0
10 3 2 A 2 0 0 0 0 0 0 0
Bus input data exhausted: Simulation terminating.
--------------- Simulation Complete: 06/09/2013 08:17:05 ---------------I'm unsure if the simulation output is correct. Anyway I have wrote some simple C code to check to see if it works once programmed to my PSOC5LP.DFB_1_LoadInputValue(1,0xA);DFB_1_LoadInputValue(0,0xA);DFB_1_GetOutputValue(0);I have removed the initialisation code from this post. Maybe it would be easier if I uploaded my project here.I'm not getting any multiplied output from this at the moment. Any ideas?Thanks, Ollie.
DFB block returns only the upper 24 bit output of the 48-bit MAC unit. Here, since your inputs are "0x0A" and "0x0A", 48-bit MAC's output is 0x000000000064. Since the DFB block can provide only the upper 24 bit output, the output which you notice will be 0.
So, try out with a different number (say 0x300000) where you can get an upper 24 bit output..
FYI, the MAC unit in DFB shifts the result of its computation to the left side by 1 bit since there will be 2 bits corresponding to sign when I multiply two signed numbers.
Hi, I am new to PSoC and for my internship I am trying to get the following logical operation carried out using the DFB:
There are two inputs A and B (A, B can be 0 or 1) and one output (0 or 1). If A is 0, output nothing; if A is 1, output B.
A B Output
0 0 -
0 1 -
1 0 0
1 1 1
The output is supposed to be stored in the local (DFB) memory in form of a sequence of 0s and 1s. I believe I require a simple Compare and Jmp operation, which determines whether to store B or discard the value by checking the value of A, and another Shift and Add operation to keep adding the new bit to a register by shifting the existing sequence to the left by 1 bit. When the DFB registers are full I need to generate an interrupt and transfer the data in DFB memory to main memory.
While I know some assembly language programming, I find the DFB assembler quite confusing. Can anyone who's familiar with the DFB assembly suggest how to execute this? Thank you for your help in advance!
This looks like a simple AND and would best be done with an AND-gate or a look-up table (LUT) component. No job for the digital filter block which is used to manipulate frequencies within a digitized input stream.
Thanks for your quick reply!
I did not know about the LUT (I'm really a beginner lol). It looks promising!
Now the reason I wanted to use DFB in the first place is because it has its own ALU,MAC and memory. As I mentioned I need to store the output sequence continuously in a register and then simultaneously output them through the UART when memory is full, without interrupting the collection of data (this is essential to the experiment I am doing).
Can you suggest a way of storing the output sequence without involving the main CPU which can carry out data transfer operations?
Again, thanks a lot for helping out!
The underlying CPU is a 32-bit ARM M3 core which is a powerful device, so sometimes there is no need to save cpu power.
Data transfer can be done with DMA without CPU intervention after it has been set up. Transferring data via UART is a comparable slow process and is often done interrupt driven.
A PSoC contains a lot of hardware you may use for your purpose, besides the DFB there are 24(!!!) programmable ALUs working on 8-bit items which may be of some more interest for your solution
Can you tell us a bit (or byte) more about your experiment, where come the data from, at which speed, kind of signal(analog or digital) digital width of signal etc.