Update Readme

This commit is contained in:
Pradeep2004 2021-05-03 17:34:50 +02:00 committed by GitHub
parent 1470069dbd
commit b1fd24665e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 103 additions and 45 deletions

View File

@ -1,6 +1,6 @@
1. INTRODUCTION
The traditional way of debugging an SoC which is programmed inside a FPGA was by using a JTAG Adapter which comes with an FTDI Chip. In recent times, modern FPGAs come with an integrated FTDI chip which makes debugging easy with only a USB cable.
In recent times, modern FPGAs come with an integrated FTDI chip which makes debugging easy with only a USB cable, thereby reducing an unnecessary extra hardware (JTAG Adapter).
In this document, I am going to guide you through the steps in an experiment which I conducted along with my supervisor to debug an SoC named MURAX without using an external JTAG adapter on ARTY A7 FPGA.
@ -8,73 +8,131 @@ In this document, I am going to guide you through the steps in an experiment whi
The BSCANE2 allows access between the internal FPGA logic and the JTAG Boundary Scan logic controller. This allows for communication between the internal running design and the dedicated JTAG pins of the FPGA.
2.1 Steps to create Bscane2
Steps to create Bscane2
After cloning all the files from https://github.com/SpinalHDL/VexRiscv, go to this path : src/main/scala/vexriscv/demo and find the Murax.scala file.
After cloning all the files from https://github.com/SpinalHDL/VexRiscv, go to this path : src/main/scala/vexriscv/demo and find the Murax.scala file.
Comment out the following lines to remove the toplevel jtag I/O pins in Murax.scala file
val jtag = slave(Jtag())
val jtagClkBuffer = SB_GB()
jtagClkBuffer.USER_SIGNAL_TO_GLOBAL_BUFFER <> io.jtag_tck
jtagClkBuffer.GLOBAL_BUFFER_OUTPUT <> murax.io.jtag.tck
murax.io.jtag.tdi <> io.jtag_tdi
murax.io.jtag.tdo <> io.jtag_tdo
murax.io.jtag.tms <> io.jtag_tms
Comment out the following lines to remove the toplevel jtag I/O pins in Murax.scala
val jtag = slave(Jtag())
val jtagClkBuffer = SB_GB()
jtagClkBuffer.USER_SIGNAL_TO_GLOBAL_BUFFER <> io.jtag_tck
jtagClkBuffer.GLOBAL_BUFFER_OUTPUT <> murax.io.jtag.tck
murax.io.jtag.tdi <> io.jtag_tdi
murax.io.jtag.tdo <> io.jtag_tdo
murax.io.jtag.tms <> io.jtag_tms
• In the Murax.scala file, delete line number 253 and add the following lines :
val jtagCtrl = JtagTapInstructionCtrl()
val tap = jtagCtrl.fromXilinxBscane2(userId = 2)
jtagCtrl <> plugin.io.bus.fromJtagInstructionCtrl(ClockDomain(tap.TCK))
• In the Murax.scala file, delete the below line:
io.jtag <> plugin.io.bus.fromJtag()
And add the following lines :
val jtagCtrl = JtagTapInstructionCtrl()
val tap = jtagCtrl.fromXilinxBscane2(userId = 2)
jtagCtrl <> plugin.io.bus.fromJtagInstructionCtrl(ClockDomain(tap.TCK))
• Add the following import statement at the beginning in Murax.scala :
import spinal.lib.com.jtag.JtagTapInstructionCtrl
By deleting the line (io.jtag <> plugin.io.bus.fromJtag() ) and adding the above lines, the Murax SoCs Jtag ports are removed and a Bscane2 bridge will be created inside the Murax SoC itself, thereby avoiding to add the Bscane2 IP while programming the FPGA.
• Then to generate the SoC with a demo program already in ram, run:
sbt "runMain vexriscv.demo.MuraxWithRamInit"
• Add the following import statement at the beginning in Murax.scala :
import spinal.lib.com.jtag.JtagTapInstructionCtrl
• Then to generate the SoC with a demo program already in ram, run:
sbt "runMain vexriscv.demo.MuraxWithRamInit"
• A verilog file will be generated with the name Murax.v and four .bin files will be generated inside VexRiscv folder which can be used to program the FPGA. Inside the Murax.v file, we can see that the Bscane2 ports will be instantiated, confirming that the Bscane2 has been created within the Murax SoC to debug it.
• A verilog file will be generated with the name Murax.v and four .bin files will be generated inside VexRiscv folder which can be used to program the FPGA. Inside the Murax.v file, we can see that the Bscane2 ports will be instantiated, confirming that the Bscane2 has been created within the Murax SoC to debug it.
3. Programming Arty A7 FPGA
There are many applications to program a FPGA. I am using Xilinx Vivado 2020 Application to program the FPGA.
There are many applications to program a FPGA. I am using Xilinx Vivado 2020 Application to program the FPGA, which is an open source application and is readily available in Xilinx website and free of cost to download.
3.1 Steps involved to program the FPGA
Steps involved to program the FPGA
Create a new project and choose the board which are using and choose the constraint file.
Create a new project and choose the board which are using and choose the constraint file.
As, I mentioned in the previous section a verilog file and four .bin files will be generated in the Vexriscv folder. Copy these files and paste them inside your vivado project in this path : project_name.srcs\sources_1\imports\Downloads
As, I mentioned in the previous section a verilog file and four .bin files will be generated in the Vexriscv folder. Copy these files and paste them inside your vivado project in this path : project_name.srcs\sources_1\imports\Downloads
Create a toplevel file by instantiating Murax I/O ports in it to blink the LEDs on the FPGA. (Note : The program to blink the LEDs is already present in Murax.v file). The toplevel file and constraint file, if required can be found here : https://github.com/SpinalHDL/VexRiscv/tree/master/scripts/Murax/arty_a7 , but make sure all the jtag ports of Murax are commented or deleted in the toplevel file.
Create a toplevel file by instantiating Murax I/O ports in it to blink the LEDs on the FPGA. (Note : The program to blink the LEDs is already present in Murax.v file). The toplevel file and constraint file, if required can be found in this path :VexRiscv/scripts/Murax/arty_a7 , but make sure all the jtag ports of Murax are commented or deleted in the toplevel file.
• Next, click Generate Bitstream and program the FPGA with the bit file. You can see the LEDs blink and Murax SoC has been programmed into the FPGA.
• The lines to remove from toplevel file are :
reg tesic_tck,tesic_tms,tesic_tdi;
wire tesic_tdo;
reg soc_tck,soc_tms,soc_tdi;
wire soc_tdo;
always @(*) begin
{soc_tck, soc_tms, soc_tdi } = {tck,tms,tdi};
tdo = soc_tdo;
end
.io_jtag_tck(soc_tck),
.io_jtag_tdi(soc_tdi),
.io_jtag_tdo(soc_tdo),
.io_jtag_tms(soc_tms),
• Next, click Generate Bitstream and program the FPGA with the bit file. You can see the LEDs blink and Murax SoC has been programmed into the FPGA.
4. Debugging via OpenOCD GDB in Linux
• In a new terminal in Linux, after cloning and setting up openocd with the steps provided in this link : https://github.com/SpinalHDL/openocd_riscv , run the below command to establish a openocd connection with Jtag of FPGA.
• To run openocd :
Use the below command :
src/openocd -c "set CPU0_YAML ..VexRiscv/cpu0.yaml" -f tcl/interface/usb_connect.cfg -f tcl/interface/soc_init.cfg
• In a new terminal in Linux, after cloning and setting up openocd with the steps provided in this link : https://github.com/SpinalHDL/openocd_riscv , run the below command to establish a openocd connection with JTAG of FPGA.
• You basically have to provide 2 files.
• You basically have to provide 2 files.
usb_connect.cfg => interface configuration
soc_init.cfg => take over the control of the CPU.
soc_init.cfg => take over the control of the CPU
• For usb_connect.cfg
you can take it from https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/bsp/digilent/ArtyA7SmpLinux/openocd/usb_connect.cfg (without modifications i would say)
• For usb_connect.cfg
you can take it from https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/bsp/digilent/ArtyA7SmpLinux/openocd/usb_connect.cfg (without modifications I would say, but make sure to check the entire path in your system for the files
xilinx-xc7.cfg and jtagspi.cfg) and write it as below, remove the word “find” and the square brackets.
source ../openocd_riscv/tcl/cpld/xilinx-xc7.cfg
source .. /openocd_riscv/tcl/cpld/jtagspi.cfg
• For soc_init.cfg
• For soc_init.cfg
https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/bsp/digilent/ArtyA7SmpLinux/openocd/soc_init.cfg
You can take it but you need to : set cpu_count to 1 and remove Line 22 to 35.
You can take it but you need to : set cpu_count to 1 and remove Line 22 to 35 as shown below :
set cpu_count 1
• Then, after openocd is running, in new terminal, follow the below commands in VexriscvSocSoftware folder ( https://github.com/SpinalHDL/VexRiscvSocSoftware )
for {set i 0} {$i < $cpu_count} {incr i} {
target create saxon.cpu$i vexriscv -endian little -chain-position $TAP_NAME -coreid $i -dbgbase [expr $i*0x1000+0x10B80000]
vexriscv readWaitCycles 40
vexriscv cpuConfigFile $CPU0_YAML
if {$SPINAL_SIM != "yes"} {
vexriscv jtagMapping 3 3 0 1 2 2
}
}
• Go to the path VexRiscvSocSoftware/projects/murax/demo/build and then give the below commands :
for {set i 0} {$i < $cpu_count} {incr i} {
targets saxon.cpu$i
poll_period 50
init
soft_reset_halt
}
puts done
• To run openocd :
Use the below command :
src/openocd -c "set CPU0_YAML ../VexRiscv/cpu0.yaml" -f tcl/interface/usb_connect.cfg -f tcl/interface/soc_init.cfg
• Prequisites to have before executing the next steps can be found here :
https://github.com/riscv/riscv-gnu-toolchain
• Then, after openocd is running, in new terminal, follow the below commands in VexriscvSocSoftware folder ( https://github.com/SpinalHDL/VexRiscvSocSoftware ).
• Go to the path VexRiscvSocSoftware/projects/murax/demo/build and then give the below commands :
riscv64-unknown-elf-gdb demo.elf
- This command will initiate the already written demo program to blink the LEDs on the FPGA.
target remote localhost:3333
- This command will connect the GDB server
load
- This command will load the program into the FPGA
riscv64-unknown-elf-gdb demo.elf
target remote localhost:3333
monitor reset halt
load
continue
- This command will halt the blinking of LEDs
• After giving the monitor reset halt command you can see that the LEDs stop blinking and when the continue command is given the LEDs start continuing from the point where they stopped.
continue
- This command will continue the blinking of LEDs from the point it stopped.
By,
Pradeep Krishnamurthy - Research Assistant, Offis e.V
Frank Poppen - Senior Research Engineer, Offis e.V