04-24-2014 02:11 PM
I'm new to this forum, but quite experienced in VHDL, Xilinx tools and since some month in the PicoBlaze designs and it's UART components. I would like to use this thread to share some of my add-on components and scripts with the PicoBlaze community.
My first post will describe how to improve a simulation of a PicoBlaze in iSim (ISE simulator).
First of all, the PicoBlaze offers some advanced calculations in it's core to translate each instruction back into a human readable string, which can be displayed in the waveform window of iSim. But iSim will only show an array of characters.
The assembler code "LOAD s0, s0" will be translated into 0x000 which will become
['L', 'O', 'A', 'D', '', 's', '0', ',', '', 's', '0', '', '', '', ''........ '', '', ']
in the iSim window.
So it's hard to follow your assembler code in the editor (e.g. Notepad++, see below for a syntax file) and simulation windows, because you don't know in with codeline / function / file you are. To improve the readability, I thought it might help to know the current executed function. See the next image for details.
In this screenshot you can see a PicoBlaze executing some instructions, the provided instruction as a character array and my NEW signal pb_functionname, displaying to current executed function.
This signal is an enum of type T_PB_FUNCTIONS which will serve as a source of short and human readable "strings" in iSim. To display the correct function name over time I have implemented a VHDL function which translates PicoBlaze instruction addresses into an enum member. Because I needed a valid VHDL identifier name, I prefixed all function names with the character 'f'.
BUT, it's very time consuming to implement this enum and all decoder entries in the function by hand, especially to keep the VHDL package in sync to the assembler code. So I wrote a small python script to parse the KCPSM6 assembler log file and extract the address ranges of functions and to rewrite them into a VHDL package with an enum declaration and a translation function. In order to do this, I annotate all functions with special comment lines (starting with a double semicolon), which will serve the parser as markers for a beginning and ending of a function. (NOTE: not all lables in assemlber are function entry points).
The syntax is as follows:
;; function myAssemblerFunction
;; end function
myAssemblerFunction sould be a valid VHDL identifier, including a underline character in the beginning
=> DONT use double underline charcaters, this is not allowd in VHDL ;(
Example of a stack operation:
;; function _push_arg0
SUB REG_SP, 01
STORE REG_ARG_0, (REG_SP)
;; end function
1. write your assembler code
2. run KCPSM6 assembler
3. run psmProcessor.py
4. add the generated VHDL package to your project
5. add a signal and one line of code to your design (see below for details)
6. run iSim
7. debug your system
8. change your psm code
9. rerun assembler and script => or use compile.cmd
10. relaunch (recompile) iSim simulation
11. goto 7 :)
Changes to your project?
1. Add the generate VHDL file to your project and add a use statement to your design:
e.g. use picoblaze.pb_main.all; if you organize all your PicoBlaze files in a seperate library called picoblaze
2. Add a signal to your design:
e.g. signal PB_FunctionName : T_PB_FUNCTIONS;
3. Assign this signal with the translated value:
4. Compile your simulation and drag the new signal into the waveform window
- PicoBlaze.udl.xml => syntax highlighting rules for the Notepad++ editor
- psmProcessor.py => parse log file and generate a VHDL package
- lib_Sleep.psm => a short example
KCPSM6.exe -c4096 main.psm
Python.exe psmProcessor.py -vd main.log
Did I forget something?
Feel free to ask questions !
See you soon
04-25-2014 02:32 AM
Thank you for sharing your work with the PicoBlaze community.
I agree that the display in iSim is less than ideal. iSim used to display strings nicely in an earlier versions but unfortunately something must have changed and it has looked ugly ever since! On a positive note, I can report that the simulator in Vivado is displaying the text strings in the clean way that we would all want them to be shown.
07-23-2014 12:05 PM
Today I would like to present a ChipScope ILA IP-Core as a TraceUnit and some ChipScope token files to improve the PicoBlaze debugging. The described and attached files are configured for a Kintex-7 device (K325T) and were tested on a KC705 board, but they can be back ported to a Virtex-5/6 or Spartan-6 device as well.
- Part 1 - a PicoBlaze TraceUnit
- Part 2 - ChipScope Analyzer Waveform improvements
- Part 3 – Token files for
- KCPSM6 instructions (e.g. MOV_Arg0_Tmp4, OUT_Reg3_P34)
- AddressMapping (e.g. WR_LCD, RD_UART)
- Assembler subroutine names (e.g. UART_Reset, UART_SendByte, Sleep)
I created a ChipScope ILA IP-Core with Xilinx CoreGenerator to capture all necessary data from PicoBlaze:
- Data bits = 59
- Reset from JTAGLoader
Triggers = 4 (each of 4 units)
Capture depth = 32k cycles
-> BlockRAM usage: 60 of 445 (13,5%) of a K325T device
The IP-Cores xco-file is included in my attachment and can be recreated on your machine. I have also included a partial cdc-file to import the signal names into ChipScope Analyzer.
Please connect this ILA-Core to your KCPSM6 instance and also to an existing ChipScope ICON IP-Core. Or if you don’t have any ICON in your design, recreate one with my supplied xil_ChipScopeICON_1.xco file.
After synthesizing your design, you should find a new ILA instance in ChipScope Analyzer.
Import the partial cdc-file into the new ILA unit in your ChipScope Analyzer GUI.
Now it’s time to modify your Analyzer waveform view:
(1) Add the signals ‘Int’ (bit 57) and ‘Reset’(bit 58) to a new bus called ‘System’
(2) Add the bits 0..11 to a new bus called ‘InstAdr’ with radix hex and also to a second new bus called ‘InstCode’.
(3) Add the bits 12..29 to a new bus called ‘Code’ with radix hex and also to a second new bus called ‘Function’.
(4) Add the bits 30..37 and 54, 56, 55 (in this order) to a new bus called ‘PortID’
(5) Add the bits 38..45 to a new bus called ‘DataIn’
(6) Add the bits 46..53 to a new bus called ‘DataOut’
- May be you have to split a bus before you can recreate, move or reassemble the bits.
- Of cause, you can choose other signal/bus names :)
What have we achieved so far?
InstructionAddress and Instruction are two times listed in the waveform, one of each has a hex radix and the other one will be assign with a “token radix” soon. The PortID is prefixed with 3 strobe signals [WriteStrobeK, ReadStrobe, WriteStrobe] which offers the possibility to define a token file entries for PortIDs as well.
It’s hard to read KCPSM6 instructions in ChipScope when they are in hex format. So I created a python script, which generates a token file with all possible KCPSM6 instructions.
If you run the attached script again, you can define your desired register names like this:
regNames = ["Arg0", "Arg1", "Arg2", "Arg3", "Tmp0", "Tmp1", "Tmp2", "Tmp3", "Tmp4", "Tmp5", "PtrL", "PtrH", "sC", "sD", "LaR", "SP"]
You can also override the token name creation by modifying the op_* functions. By default I use
The resulting token file looks like this:
How does it work?
I defined one format function per instruction format e.g. 00xy0 (LOAD sX sY) will be formatted by op_sXsY(…). Each instruction is formatted by one or more op_* function calls. All generated token file entries are concatenated and save in a kcpsm6.tok file (~ 2,2 MiByte).
Here is the call for the first 3 instructions:
tokenFileContent += op_sXsY("MOVE", "00") # LOAD sX, sY
tokenFileContent += op_sXkk("CONST", "01") # LOAD sX, kk
tokenFileContent += op_sXsY("STAR", "16") # STAR sX, sY
“00”, “01”, “16” are the particular opcodes.
As described in part 2, the Analyzer waveform shows a PortID bus of 11 bits (PortID + 3x strobe). The 3-bit prefix can be used to determine the port access and direction (address space).
Lets say: A UART module has 2 registers mapped to PortIDs 30 and 31 (0x20, 0x21) and PortID 31 is also accessible by OUTPUTK on PortID 8. Now it’s possible to write a token files which uses the 3-bit prefix [WriteStrobeK, ReadStrobe, WriteStrobe] to choose a direction:
Write = 001’b
Read = 010’b
WriteK = 100’b
If we write all possible combinations into a token file, we will get something like this:
# UART at 0x20, 0x21 and 0x8
Attention: OUTPUTK operation use only bits 3..0 in PortID, so our token file has to cover all possibilities for the bits 7..4.
I used the prefixes WR for write, RD for read and WK for WriteK.
As described in my last post (see thread start), I wrote a python script which generates a VHDL package. This packages allows me to see the current executed assembler subroutine (function) in simulation. I extended this script to generate a token file as well, which can be imported into ChipScope to display the current executed function there as well.
This token file looks like this snippet:
So that’s all for today :)
If you are interested in including some of this modules, files or scripts into the next KCPSM release, you can do so. May be it’s possible to provide a ChipScope enhanced example design like your IIC example.
See you soon
10-26-2014 09:24 AM