Merge branch 'master' into dev

This commit is contained in:
Charles Papon 2020-01-29 12:50:41 +01:00
commit b5374433a5
50 changed files with 2483 additions and 146 deletions

View File

@ -8,8 +8,8 @@
- [Regression tests](#regression-tests)
- [Interactive debug of the simulated CPU via GDB OpenOCD and Verilator](#interactive-debug-of-the-simulated-cpu-via-gdb-openocd-and-verilator)
- [Using Eclipse to run the software and debug it](#using-Eclipse-to-run-the-software-and-debug-it)
* [By using Zylin plugin](#by-using-zylin-plugin)
* [By using FreedomStudio](#by-using-freedomstudio)
* [By using gnu-mcu-eclipse](#by-using-gnu-mcu-eclipse)
* [By using Zylin plugin (old)](#by-using-zylin-plugin-old)
- [Briey SoC](#briey-soc)
- [Murax SoC](#murax-soc)
- [Running Linux](#running-linux)

View File

@ -0,0 +1,129 @@
This example is for the Digilent ARTY A7 35T board.
# Using the example
## Before Starting
You should make sure you have the following tools installed:
* vivado 2018.1 or later
* riscv toolchain (riscv64-unknown-elf)
* sbt
## Board setup
Make sure you have a rev E board. If you have a later version check that the
flash part is S25FL128SAGMF100.
Jumper settings for board rev E:
* Disconnect anything from the connectors (Pmod, Arduino)
* Jumpers: JP1 and JP2 on, others off.
## Building
You should be able to just type `make` and get output similar to this;
```
...
Memory region Used Size Region Size %age Used
RAM: 896 B 2 KB 43.75%
...
---------------------------------------------------------------------------------
Finished RTL Elaboration : Time (s): cpu = 00:00:08 ; elapsed = 00:00:09 . Memory (MB): peak = 1457.785 ; gain = 243.430 ; free physical = 17940 ; free virtual = 57159
---------------------------------------------------------------------------------
...
---------------------------------------------------------------------------------
Finished Technology Mapping : Time (s): cpu = 00:02:42 ; elapsed = 00:02:58 . Memory (MB): peak = 1986.879 ; gain = 772.523 ; free physical = 17454 ; free virtual = 56670
---------------------------------------------------------------------------------
...
---------------------------------------------------------------------------------
Finished Writing Synthesis Report : Time (s): cpu = 00:02:45 ; elapsed = 00:03:01 . Memory (MB): peak = 1986.879 ; gain = 772.523 ; free physical = 17457 ; free virtual = 56673
---------------------------------------------------------------------------------
...
Writing bitstream ./toplevel.bit...
...
mmi files generated
...
********************************************
./soc_latest_sw.bit correctly generated
********************************************
...
********************************************
./soc_latest_sw.mcs correctly generated
********************************************
INFO: [Common 17-206] Exiting Vivado at Thu Nov 28 04:00:50 2019...
```
The process should take around 8 minutes on a reasonably fast computer.
## Programming
### Direct FPGA RAM programming
Run `make prog` to program the bit file directly to FPGA RAM.
You should get output like the following;
```
...
****** Xilinx hw_server v2018.1
**** Build date : Apr 4 2018-18:56:09
** Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
INFO: [Labtoolstcl 44-466] Opening hw_target localhost:3121/xilinx_tcf/Digilent/210319AB569AA
INFO: [Labtools 27-1434] Device xc7a35t (JTAG device index = 0) is programmed with a design that has no supported debug core(s) in it.
WARNING: [Labtools 27-3361] The debug hub core was not detected.
Resolution:
1. Make sure the clock connected to the debug hub (dbg_hub) core is a free running clock and is active.
2. Make sure the BSCAN_SWITCH_USER_MASK device property in Vivado Hardware Manager reflects the user scan chain setting in the design and refresh the device. To determine the user scan chain setting in the design, open the implemented design and use 'get_property C_USER_SCAN_CHAIN [get_debug_cores dbg_hub]'.
For more details on setting the scan chain property, consult the Vivado Debug and Programming User Guide (UG908).
INFO: [Labtools 27-3164] End of startup status: HIGH
INFO: [Common 17-206] Exiting Vivado at Thu Nov 28 04:01:36 2019...
```
After programming the LED4~LED7 shall show some activity.
### QSPI flash programming
Run `make flash` to program the bit file to the QSPI flash.
You should get output like the following;
```
...
****** Xilinx hw_server v2018.1
**** Build date : Apr 4 2018-18:56:09
** Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
INFO: [Labtoolstcl 44-466] Opening hw_target localhost:3121/xilinx_tcf/Digilent/210319AB569AA
INFO: [Labtools 27-1434] Device xc7a35t (JTAG device index = 0) is programmed with a design that has no supported debug core(s) in it.
...
INFO: [Labtools 27-3164] End of startup status: HIGH
Mfg ID : 1 Memory Type : 20 Memory Capacity : 18 Device ID 1 : 0 Device ID 2 : 0
Performing Erase Operation...
Erase Operation successful.
Performing Program and Verify Operations...
Program/Verify Operation successful.
INFO: [Labtoolstcl 44-377] Flash programming completed successfully
program_hw_cfgmem: Time (s): cpu = 00:00:00.11 ; elapsed = 00:00:52 . Memory (MB): peak = 1792.711 ; gain = 8.000 ; free physical = 17712 ; free virtual = 56943
INFO: [Labtoolstcl 44-464] Closing hw_target localhost:3121/xilinx_tcf/Digilent/210319AB569AA
...
INFO: [Common 17-206] Exiting Vivado at Thu Nov 28 04:06:28 2019...
```
After programming the flash you need to press the "PROG" button on the board. Then after a second or so the "DONE" LED shall be ON and LED4~LED7 shall show some activity.
## Connect
After programming you should be able to connect to the serial port and have some output.
On Linux you can do this using a command like `screen /dev/ttyUSB1`. Other good alternatives:
* moserial (GUI)
* picocom (can be launched via the file "picocom_arty")
Parameters:
* port is : /dev/ttyUSB1
* flowcontrol : none
* baudrate is : 115200
* parity is : none
* databits are : 8
* stopbits are : 1

View File

@ -0,0 +1,366 @@
set_property PACKAGE_PIN F4 [get_ports tck]
set_property IOSTANDARD LVCMOS33 [get_ports tck]
set_property PACKAGE_PIN D2 [get_ports tms]
set_property IOSTANDARD LVCMOS33 [get_ports tms]
set_property PACKAGE_PIN D4 [get_ports tdo]
set_property IOSTANDARD LVCMOS33 [get_ports tdo]
set_property PULLUP true [get_ports tdo]
set_property PACKAGE_PIN E2 [get_ports tdi]
set_property IOSTANDARD LVCMOS33 [get_ports tdi]
set_property PACKAGE_PIN D3 [get_ports trst]
set_property IOSTANDARD LVCMOS33 [get_ports trst]
set_property PULLUP true [get_ports trst]
## serial:0.tx
set_property PACKAGE_PIN D10 [get_ports serial_tx]
set_property IOSTANDARD LVCMOS33 [get_ports serial_tx]
## serial:0.rx
set_property PACKAGE_PIN A9 [get_ports serial_rx]
set_property IOSTANDARD LVCMOS33 [get_ports serial_rx]
## clk100:0
set_property PACKAGE_PIN E3 [get_ports clk100]
set_property IOSTANDARD LVCMOS33 [get_ports clk100]
## cpu_reset:0
set_property PACKAGE_PIN C2 [get_ports cpu_reset]
set_property IOSTANDARD LVCMOS33 [get_ports cpu_reset]
## eth_ref_clk:0
#set_property LOC G18 [get_ports eth_ref_clk]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_ref_clk]
## user_led:0
set_property PACKAGE_PIN H5 [get_ports user_led0]
set_property IOSTANDARD LVCMOS33 [get_ports user_led0]
## user_led:1
set_property PACKAGE_PIN J5 [get_ports user_led1]
set_property IOSTANDARD LVCMOS33 [get_ports user_led1]
## user_led:2
set_property PACKAGE_PIN T9 [get_ports user_led2]
set_property IOSTANDARD LVCMOS33 [get_ports user_led2]
## user_led:3
set_property PACKAGE_PIN T10 [get_ports user_led3]
set_property IOSTANDARD LVCMOS33 [get_ports user_led3]
## user_sw:0
set_property PACKAGE_PIN A8 [get_ports user_sw0]
set_property IOSTANDARD LVCMOS33 [get_ports user_sw0]
## user_sw:1
set_property PACKAGE_PIN C11 [get_ports user_sw1]
set_property IOSTANDARD LVCMOS33 [get_ports user_sw1]
## user_sw:2
set_property PACKAGE_PIN C10 [get_ports user_sw2]
set_property IOSTANDARD LVCMOS33 [get_ports user_sw2]
## user_sw:3
set_property PACKAGE_PIN A10 [get_ports user_sw3]
set_property IOSTANDARD LVCMOS33 [get_ports user_sw3]
## user_btn:0
set_property PACKAGE_PIN D9 [get_ports user_btn0]
set_property IOSTANDARD LVCMOS33 [get_ports user_btn0]
## user_btn:1
set_property PACKAGE_PIN C9 [get_ports user_btn1]
set_property IOSTANDARD LVCMOS33 [get_ports user_btn1]
## user_btn:2
set_property PACKAGE_PIN B9 [get_ports user_btn2]
set_property IOSTANDARD LVCMOS33 [get_ports user_btn2]
## user_btn:3
set_property PACKAGE_PIN B8 [get_ports user_btn3]
set_property IOSTANDARD LVCMOS33 [get_ports user_btn3]
## spiflash_1x:0.cs_n
#set_property LOC L13 [get_ports spiflash_1x_cs_n]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_cs_n]
# ## spiflash_1x:0.mosi
#set_property LOC K17 [get_ports spiflash_1x_mosi]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_mosi]
# ## spiflash_1x:0.miso
#set_property LOC K18 [get_ports spiflash_1x_miso]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_miso]
# ## spiflash_1x:0.wp
#set_property LOC L14 [get_ports spiflash_1x_wp]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_wp]
# ## spiflash_1x:0.hold
#set_property LOC M14 [get_ports spiflash_1x_hold]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_hold]
# ## ddram:0.a
#set_property LOC R2 [get_ports ddram_a[0]]
#set_property SLEW FAST [get_ports ddram_a[0]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[0]]
# ## ddram:0.a
#set_property LOC M6 [get_ports ddram_a[1]]
#set_property SLEW FAST [get_ports ddram_a[1]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[1]]
# ## ddram:0.a
#set_property LOC N4 [get_ports ddram_a[2]]
#set_property SLEW FAST [get_ports ddram_a[2]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[2]]
# ## ddram:0.a
#set_property LOC T1 [get_ports ddram_a[3]]
#set_property SLEW FAST [get_ports ddram_a[3]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[3]]
# ## ddram:0.a
#set_property LOC N6 [get_ports ddram_a[4]]
#set_property SLEW FAST [get_ports ddram_a[4]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[4]]
# ## ddram:0.a
#set_property LOC R7 [get_ports ddram_a[5]]
#set_property SLEW FAST [get_ports ddram_a[5]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[5]]
# ## ddram:0.a
#set_property LOC V6 [get_ports ddram_a[6]]
#set_property SLEW FAST [get_ports ddram_a[6]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[6]]
# ## ddram:0.a
#set_property LOC U7 [get_ports ddram_a[7]]
#set_property SLEW FAST [get_ports ddram_a[7]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[7]]
# ## ddram:0.a
#set_property LOC R8 [get_ports ddram_a[8]]
#set_property SLEW FAST [get_ports ddram_a[8]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[8]]
# ## ddram:0.a
#set_property LOC V7 [get_ports ddram_a[9]]
#set_property SLEW FAST [get_ports ddram_a[9]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[9]]
# ## ddram:0.a
#set_property LOC R6 [get_ports ddram_a[10]]
#set_property SLEW FAST [get_ports ddram_a[10]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[10]]
# ## ddram:0.a
#set_property LOC U6 [get_ports ddram_a[11]]
#set_property SLEW FAST [get_ports ddram_a[11]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[11]]
# ## ddram:0.a
#set_property LOC T6 [get_ports ddram_a[12]]
#set_property SLEW FAST [get_ports ddram_a[12]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[12]]
# ## ddram:0.a
#set_property LOC T8 [get_ports ddram_a[13]]
#set_property SLEW FAST [get_ports ddram_a[13]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[13]]
# ## ddram:0.ba
#set_property LOC R1 [get_ports ddram_ba[0]]
#set_property SLEW FAST [get_ports ddram_ba[0]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_ba[0]]
# ## ddram:0.ba
#set_property LOC P4 [get_ports ddram_ba[1]]
#set_property SLEW FAST [get_ports ddram_ba[1]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_ba[1]]
# ## ddram:0.ba
#set_property LOC P2 [get_ports ddram_ba[2]]
#set_property SLEW FAST [get_ports ddram_ba[2]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_ba[2]]
# ## ddram:0.ras_n
#set_property LOC P3 [get_ports ddram_ras_n]
#set_property SLEW FAST [get_ports ddram_ras_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_ras_n]
# ## ddram:0.cas_n
#set_property LOC M4 [get_ports ddram_cas_n]
#set_property SLEW FAST [get_ports ddram_cas_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_cas_n]
# ## ddram:0.we_n
#set_property LOC P5 [get_ports ddram_we_n]
#set_property SLEW FAST [get_ports ddram_we_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_we_n]
# ## ddram:0.cs_n
#set_property LOC U8 [get_ports ddram_cs_n]
#set_property SLEW FAST [get_ports ddram_cs_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_cs_n]
# ## ddram:0.dm
#set_property LOC L1 [get_ports ddram_dm[0]]
#set_property SLEW FAST [get_ports ddram_dm[0]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dm[0]]
# ## ddram:0.dm
#set_property LOC U1 [get_ports ddram_dm[1]]
#set_property SLEW FAST [get_ports ddram_dm[1]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dm[1]]
# ## ddram:0.dq
#set_property LOC K5 [get_ports ddram_dq[0]]
#set_property SLEW FAST [get_ports ddram_dq[0]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[0]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[0]]
# ## ddram:0.dq
#set_property LOC L3 [get_ports ddram_dq[1]]
#set_property SLEW FAST [get_ports ddram_dq[1]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[1]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[1]]
# ## ddram:0.dq
#set_property LOC K3 [get_ports ddram_dq[2]]
#set_property SLEW FAST [get_ports ddram_dq[2]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[2]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[2]]
# ## ddram:0.dq
#set_property LOC L6 [get_ports ddram_dq[3]]
#set_property SLEW FAST [get_ports ddram_dq[3]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[3]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[3]]
# ## ddram:0.dq
#set_property LOC M3 [get_ports ddram_dq[4]]
#set_property SLEW FAST [get_ports ddram_dq[4]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[4]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[4]]
# ## ddram:0.dq
#set_property LOC M1 [get_ports ddram_dq[5]]
#set_property SLEW FAST [get_ports ddram_dq[5]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[5]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[5]]
# ## ddram:0.dq
#set_property LOC L4 [get_ports ddram_dq[6]]
#set_property SLEW FAST [get_ports ddram_dq[6]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[6]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[6]]
# ## ddram:0.dq
#set_property LOC M2 [get_ports ddram_dq[7]]
#set_property SLEW FAST [get_ports ddram_dq[7]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[7]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[7]]
# ## ddram:0.dq
#set_property LOC V4 [get_ports ddram_dq[8]]
#set_property SLEW FAST [get_ports ddram_dq[8]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[8]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[8]]
# ## ddram:0.dq
#set_property LOC T5 [get_ports ddram_dq[9]]
#set_property SLEW FAST [get_ports ddram_dq[9]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[9]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[9]]
# ## ddram:0.dq
#set_property LOC U4 [get_ports ddram_dq[10]]
#set_property SLEW FAST [get_ports ddram_dq[10]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[10]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[10]]
# ## ddram:0.dq
#set_property LOC V5 [get_ports ddram_dq[11]]
#set_property SLEW FAST [get_ports ddram_dq[11]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[11]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[11]]
# ## ddram:0.dq
#set_property LOC V1 [get_ports ddram_dq[12]]
#set_property SLEW FAST [get_ports ddram_dq[12]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[12]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[12]]
# ## ddram:0.dq
#set_property LOC T3 [get_ports ddram_dq[13]]
#set_property SLEW FAST [get_ports ddram_dq[13]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[13]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[13]]
# ## ddram:0.dq
#set_property LOC U3 [get_ports ddram_dq[14]]
#set_property SLEW FAST [get_ports ddram_dq[14]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[14]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[14]]
# ## ddram:0.dq
#set_property LOC R3 [get_ports ddram_dq[15]]
#set_property SLEW FAST [get_ports ddram_dq[15]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[15]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[15]]
# ## ddram:0.dqs_p
#set_property LOC N2 [get_ports ddram_dqs_p[0]]
#set_property SLEW FAST [get_ports ddram_dqs_p[0]]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_p[0]]
# ## ddram:0.dqs_p
#set_property LOC U2 [get_ports ddram_dqs_p[1]]
#set_property SLEW FAST [get_ports ddram_dqs_p[1]]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_p[1]]
# ## ddram:0.dqs_n
#set_property LOC N1 [get_ports ddram_dqs_n[0]]
#set_property SLEW FAST [get_ports ddram_dqs_n[0]]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_n[0]]
# ## ddram:0.dqs_n
#set_property LOC V2 [get_ports ddram_dqs_n[1]]
#set_property SLEW FAST [get_ports ddram_dqs_n[1]]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_n[1]]
# ## ddram:0.clk_p
#set_property LOC U9 [get_ports ddram_clk_p]
#set_property SLEW FAST [get_ports ddram_clk_p]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_clk_p]
# ## ddram:0.clk_n
#set_property LOC V9 [get_ports ddram_clk_n]
#set_property SLEW FAST [get_ports ddram_clk_n]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_clk_n]
# ## ddram:0.cke
#set_property LOC N5 [get_ports ddram_cke]
#set_property SLEW FAST [get_ports ddram_cke]
#set_property IOSTANDARD SSTL15 [get_ports ddram_cke]
# ## ddram:0.odt
#set_property LOC R5 [get_ports ddram_odt]
#set_property SLEW FAST [get_ports ddram_odt]
#set_property IOSTANDARD SSTL15 [get_ports ddram_odt]
# ## ddram:0.reset_n
#set_property LOC K6 [get_ports ddram_reset_n]
#set_property SLEW FAST [get_ports ddram_reset_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_reset_n]
# ## eth_clocks:0.tx
#set_property LOC H16 [get_ports eth_clocks_tx]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_clocks_tx]
# ## eth_clocks:0.rx
#set_property LOC F15 [get_ports eth_clocks_rx]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_clocks_rx]
# ## eth:0.rst_n
#set_property LOC C16 [get_ports eth_rst_n]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rst_n]
# ## eth:0.mdio
#set_property LOC K13 [get_ports eth_mdio]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_mdio]
# ## eth:0.mdc
#set_property LOC F16 [get_ports eth_mdc]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_mdc]
# ## eth:0.rx_dv
#set_property LOC G16 [get_ports eth_rx_dv]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_dv]
# ## eth:0.rx_er
#set_property LOC C17 [get_ports eth_rx_er]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_er]
# ## eth:0.rx_data
#set_property LOC D18 [get_ports eth_rx_data[0]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_data[0]]
# ## eth:0.rx_data
#set_property LOC E17 [get_ports eth_rx_data[1]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_data[1]]
# ## eth:0.rx_data
#set_property LOC E18 [get_ports eth_rx_data[2]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_data[2]]
# ## eth:0.rx_data
#set_property LOC G17 [get_ports eth_rx_data[3]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_data[3]]
# ## eth:0.tx_en
#set_property LOC H15 [get_ports eth_tx_en]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_en]
# ## eth:0.tx_data
#set_property LOC H14 [get_ports eth_tx_data[0]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_data[0]]
# ## eth:0.tx_data
#set_property LOC J14 [get_ports eth_tx_data[1]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_data[1]]
# ## eth:0.tx_data
#set_property LOC J13 [get_ports eth_tx_data[2]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_data[2]]
# ## eth:0.tx_data
#set_property LOC H17 [get_ports eth_tx_data[3]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_data[3]]
# ## eth:0.col
#set_property LOC D17 [get_ports eth_col]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_col]
# ## eth:0.crs
#set_property LOC G14 [get_ports eth_crs]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_crs]
set_property INTERNAL_VREF 0.75 [get_iobanks 34]
create_clock -period 10.000 -name clk100 [get_nets clk100]
#create_clock -name eth_rx_clk -period 40.0 [get_nets eth_rx_clk]
#create_clock -name eth_tx_clk -period 40.0 [get_nets eth_tx_clk]
#set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_rx_clk]] -asynchronous
#set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_tx_clk]] -asynchronous
#set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets eth_rx_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_tx_clk]] -asynchronous
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]

View File

@ -0,0 +1,350 @@
## serial:0.tx
set_property LOC D10 [get_ports serial_tx]
set_property IOSTANDARD LVCMOS33 [get_ports serial_tx]
## serial:0.rx
set_property LOC A9 [get_ports serial_rx]
set_property IOSTANDARD LVCMOS33 [get_ports serial_rx]
## clk100:0
set_property LOC E3 [get_ports clk100]
set_property IOSTANDARD LVCMOS33 [get_ports clk100]
## cpu_reset:0
set_property LOC C2 [get_ports cpu_reset]
set_property IOSTANDARD LVCMOS33 [get_ports cpu_reset]
## eth_ref_clk:0
#set_property LOC G18 [get_ports eth_ref_clk]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_ref_clk]
## user_led:0
set_property LOC H5 [get_ports user_led0]
set_property IOSTANDARD LVCMOS33 [get_ports user_led0]
## user_led:1
set_property LOC J5 [get_ports user_led1]
set_property IOSTANDARD LVCMOS33 [get_ports user_led1]
## user_led:2
set_property LOC T9 [get_ports user_led2]
set_property IOSTANDARD LVCMOS33 [get_ports user_led2]
## user_led:3
set_property LOC T10 [get_ports user_led3]
set_property IOSTANDARD LVCMOS33 [get_ports user_led3]
## user_sw:0
set_property LOC A8 [get_ports user_sw0]
set_property IOSTANDARD LVCMOS33 [get_ports user_sw0]
## user_sw:1
set_property LOC C11 [get_ports user_sw1]
set_property IOSTANDARD LVCMOS33 [get_ports user_sw1]
## user_sw:2
set_property LOC C10 [get_ports user_sw2]
set_property IOSTANDARD LVCMOS33 [get_ports user_sw2]
## user_sw:3
set_property LOC A10 [get_ports user_sw3]
set_property IOSTANDARD LVCMOS33 [get_ports user_sw3]
## user_btn:0
set_property LOC D9 [get_ports user_btn0]
set_property IOSTANDARD LVCMOS33 [get_ports user_btn0]
## user_btn:1
set_property LOC C9 [get_ports user_btn1]
set_property IOSTANDARD LVCMOS33 [get_ports user_btn1]
## user_btn:2
set_property LOC B9 [get_ports user_btn2]
set_property IOSTANDARD LVCMOS33 [get_ports user_btn2]
## user_btn:3
set_property LOC B8 [get_ports user_btn3]
set_property IOSTANDARD LVCMOS33 [get_ports user_btn3]
## spiflash_1x:0.cs_n
#set_property LOC L13 [get_ports spiflash_1x_cs_n]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_cs_n]
# ## spiflash_1x:0.mosi
#set_property LOC K17 [get_ports spiflash_1x_mosi]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_mosi]
# ## spiflash_1x:0.miso
#set_property LOC K18 [get_ports spiflash_1x_miso]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_miso]
# ## spiflash_1x:0.wp
#set_property LOC L14 [get_ports spiflash_1x_wp]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_wp]
# ## spiflash_1x:0.hold
#set_property LOC M14 [get_ports spiflash_1x_hold]
#set_property IOSTANDARD LVCMOS33 [get_ports spiflash_1x_hold]
# ## ddram:0.a
#set_property LOC R2 [get_ports ddram_a[0]]
#set_property SLEW FAST [get_ports ddram_a[0]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[0]]
# ## ddram:0.a
#set_property LOC M6 [get_ports ddram_a[1]]
#set_property SLEW FAST [get_ports ddram_a[1]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[1]]
# ## ddram:0.a
#set_property LOC N4 [get_ports ddram_a[2]]
#set_property SLEW FAST [get_ports ddram_a[2]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[2]]
# ## ddram:0.a
#set_property LOC T1 [get_ports ddram_a[3]]
#set_property SLEW FAST [get_ports ddram_a[3]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[3]]
# ## ddram:0.a
#set_property LOC N6 [get_ports ddram_a[4]]
#set_property SLEW FAST [get_ports ddram_a[4]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[4]]
# ## ddram:0.a
#set_property LOC R7 [get_ports ddram_a[5]]
#set_property SLEW FAST [get_ports ddram_a[5]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[5]]
# ## ddram:0.a
#set_property LOC V6 [get_ports ddram_a[6]]
#set_property SLEW FAST [get_ports ddram_a[6]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[6]]
# ## ddram:0.a
#set_property LOC U7 [get_ports ddram_a[7]]
#set_property SLEW FAST [get_ports ddram_a[7]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[7]]
# ## ddram:0.a
#set_property LOC R8 [get_ports ddram_a[8]]
#set_property SLEW FAST [get_ports ddram_a[8]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[8]]
# ## ddram:0.a
#set_property LOC V7 [get_ports ddram_a[9]]
#set_property SLEW FAST [get_ports ddram_a[9]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[9]]
# ## ddram:0.a
#set_property LOC R6 [get_ports ddram_a[10]]
#set_property SLEW FAST [get_ports ddram_a[10]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[10]]
# ## ddram:0.a
#set_property LOC U6 [get_ports ddram_a[11]]
#set_property SLEW FAST [get_ports ddram_a[11]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[11]]
# ## ddram:0.a
#set_property LOC T6 [get_ports ddram_a[12]]
#set_property SLEW FAST [get_ports ddram_a[12]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[12]]
# ## ddram:0.a
#set_property LOC T8 [get_ports ddram_a[13]]
#set_property SLEW FAST [get_ports ddram_a[13]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_a[13]]
# ## ddram:0.ba
#set_property LOC R1 [get_ports ddram_ba[0]]
#set_property SLEW FAST [get_ports ddram_ba[0]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_ba[0]]
# ## ddram:0.ba
#set_property LOC P4 [get_ports ddram_ba[1]]
#set_property SLEW FAST [get_ports ddram_ba[1]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_ba[1]]
# ## ddram:0.ba
#set_property LOC P2 [get_ports ddram_ba[2]]
#set_property SLEW FAST [get_ports ddram_ba[2]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_ba[2]]
# ## ddram:0.ras_n
#set_property LOC P3 [get_ports ddram_ras_n]
#set_property SLEW FAST [get_ports ddram_ras_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_ras_n]
# ## ddram:0.cas_n
#set_property LOC M4 [get_ports ddram_cas_n]
#set_property SLEW FAST [get_ports ddram_cas_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_cas_n]
# ## ddram:0.we_n
#set_property LOC P5 [get_ports ddram_we_n]
#set_property SLEW FAST [get_ports ddram_we_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_we_n]
# ## ddram:0.cs_n
#set_property LOC U8 [get_ports ddram_cs_n]
#set_property SLEW FAST [get_ports ddram_cs_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_cs_n]
# ## ddram:0.dm
#set_property LOC L1 [get_ports ddram_dm[0]]
#set_property SLEW FAST [get_ports ddram_dm[0]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dm[0]]
# ## ddram:0.dm
#set_property LOC U1 [get_ports ddram_dm[1]]
#set_property SLEW FAST [get_ports ddram_dm[1]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dm[1]]
# ## ddram:0.dq
#set_property LOC K5 [get_ports ddram_dq[0]]
#set_property SLEW FAST [get_ports ddram_dq[0]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[0]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[0]]
# ## ddram:0.dq
#set_property LOC L3 [get_ports ddram_dq[1]]
#set_property SLEW FAST [get_ports ddram_dq[1]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[1]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[1]]
# ## ddram:0.dq
#set_property LOC K3 [get_ports ddram_dq[2]]
#set_property SLEW FAST [get_ports ddram_dq[2]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[2]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[2]]
# ## ddram:0.dq
#set_property LOC L6 [get_ports ddram_dq[3]]
#set_property SLEW FAST [get_ports ddram_dq[3]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[3]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[3]]
# ## ddram:0.dq
#set_property LOC M3 [get_ports ddram_dq[4]]
#set_property SLEW FAST [get_ports ddram_dq[4]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[4]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[4]]
# ## ddram:0.dq
#set_property LOC M1 [get_ports ddram_dq[5]]
#set_property SLEW FAST [get_ports ddram_dq[5]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[5]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[5]]
# ## ddram:0.dq
#set_property LOC L4 [get_ports ddram_dq[6]]
#set_property SLEW FAST [get_ports ddram_dq[6]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[6]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[6]]
# ## ddram:0.dq
#set_property LOC M2 [get_ports ddram_dq[7]]
#set_property SLEW FAST [get_ports ddram_dq[7]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[7]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[7]]
# ## ddram:0.dq
#set_property LOC V4 [get_ports ddram_dq[8]]
#set_property SLEW FAST [get_ports ddram_dq[8]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[8]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[8]]
# ## ddram:0.dq
#set_property LOC T5 [get_ports ddram_dq[9]]
#set_property SLEW FAST [get_ports ddram_dq[9]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[9]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[9]]
# ## ddram:0.dq
#set_property LOC U4 [get_ports ddram_dq[10]]
#set_property SLEW FAST [get_ports ddram_dq[10]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[10]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[10]]
# ## ddram:0.dq
#set_property LOC V5 [get_ports ddram_dq[11]]
#set_property SLEW FAST [get_ports ddram_dq[11]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[11]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[11]]
# ## ddram:0.dq
#set_property LOC V1 [get_ports ddram_dq[12]]
#set_property SLEW FAST [get_ports ddram_dq[12]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[12]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[12]]
# ## ddram:0.dq
#set_property LOC T3 [get_ports ddram_dq[13]]
#set_property SLEW FAST [get_ports ddram_dq[13]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[13]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[13]]
# ## ddram:0.dq
#set_property LOC U3 [get_ports ddram_dq[14]]
#set_property SLEW FAST [get_ports ddram_dq[14]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[14]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[14]]
# ## ddram:0.dq
#set_property LOC R3 [get_ports ddram_dq[15]]
#set_property SLEW FAST [get_ports ddram_dq[15]]
#set_property IOSTANDARD SSTL15 [get_ports ddram_dq[15]]
#set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[15]]
# ## ddram:0.dqs_p
#set_property LOC N2 [get_ports ddram_dqs_p[0]]
#set_property SLEW FAST [get_ports ddram_dqs_p[0]]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_p[0]]
# ## ddram:0.dqs_p
#set_property LOC U2 [get_ports ddram_dqs_p[1]]
#set_property SLEW FAST [get_ports ddram_dqs_p[1]]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_p[1]]
# ## ddram:0.dqs_n
#set_property LOC N1 [get_ports ddram_dqs_n[0]]
#set_property SLEW FAST [get_ports ddram_dqs_n[0]]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_n[0]]
# ## ddram:0.dqs_n
#set_property LOC V2 [get_ports ddram_dqs_n[1]]
#set_property SLEW FAST [get_ports ddram_dqs_n[1]]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_n[1]]
# ## ddram:0.clk_p
#set_property LOC U9 [get_ports ddram_clk_p]
#set_property SLEW FAST [get_ports ddram_clk_p]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_clk_p]
# ## ddram:0.clk_n
#set_property LOC V9 [get_ports ddram_clk_n]
#set_property SLEW FAST [get_ports ddram_clk_n]
#set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_clk_n]
# ## ddram:0.cke
#set_property LOC N5 [get_ports ddram_cke]
#set_property SLEW FAST [get_ports ddram_cke]
#set_property IOSTANDARD SSTL15 [get_ports ddram_cke]
# ## ddram:0.odt
#set_property LOC R5 [get_ports ddram_odt]
#set_property SLEW FAST [get_ports ddram_odt]
#set_property IOSTANDARD SSTL15 [get_ports ddram_odt]
# ## ddram:0.reset_n
#set_property LOC K6 [get_ports ddram_reset_n]
#set_property SLEW FAST [get_ports ddram_reset_n]
#set_property IOSTANDARD SSTL15 [get_ports ddram_reset_n]
# ## eth_clocks:0.tx
#set_property LOC H16 [get_ports eth_clocks_tx]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_clocks_tx]
# ## eth_clocks:0.rx
#set_property LOC F15 [get_ports eth_clocks_rx]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_clocks_rx]
# ## eth:0.rst_n
#set_property LOC C16 [get_ports eth_rst_n]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rst_n]
# ## eth:0.mdio
#set_property LOC K13 [get_ports eth_mdio]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_mdio]
# ## eth:0.mdc
#set_property LOC F16 [get_ports eth_mdc]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_mdc]
# ## eth:0.rx_dv
#set_property LOC G16 [get_ports eth_rx_dv]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_dv]
# ## eth:0.rx_er
#set_property LOC C17 [get_ports eth_rx_er]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_er]
# ## eth:0.rx_data
#set_property LOC D18 [get_ports eth_rx_data[0]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_data[0]]
# ## eth:0.rx_data
#set_property LOC E17 [get_ports eth_rx_data[1]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_data[1]]
# ## eth:0.rx_data
#set_property LOC E18 [get_ports eth_rx_data[2]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_data[2]]
# ## eth:0.rx_data
#set_property LOC G17 [get_ports eth_rx_data[3]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_rx_data[3]]
# ## eth:0.tx_en
#set_property LOC H15 [get_ports eth_tx_en]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_en]
# ## eth:0.tx_data
#set_property LOC H14 [get_ports eth_tx_data[0]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_data[0]]
# ## eth:0.tx_data
#set_property LOC J14 [get_ports eth_tx_data[1]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_data[1]]
# ## eth:0.tx_data
#set_property LOC J13 [get_ports eth_tx_data[2]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_data[2]]
# ## eth:0.tx_data
#set_property LOC H17 [get_ports eth_tx_data[3]]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_tx_data[3]]
# ## eth:0.col
#set_property LOC D17 [get_ports eth_col]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_col]
# ## eth:0.crs
#set_property LOC G14 [get_ports eth_crs]
#set_property IOSTANDARD LVCMOS33 [get_ports eth_crs]
set_property INTERNAL_VREF 0.750 [get_iobanks 34]
create_clock -name sys_clk -period 10.0 [get_nets sys_clk]
create_clock -name clk100 -period 10.0 [get_nets clk100]
#create_clock -name eth_rx_clk -period 40.0 [get_nets eth_rx_clk]
#create_clock -name eth_tx_clk -period 40.0 [get_nets eth_tx_clk]
#set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_rx_clk]] -asynchronous
#set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_tx_clk]] -asynchronous
#set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets eth_rx_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_tx_clk]] -asynchronous
set_false_path -quiet -to [get_nets -quiet -filter {mr_ff == TRUE}]
set_false_path -quiet -to [get_pins -quiet -filter {REF_PIN_NAME == PRE} -of [get_cells -quiet -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]
set_max_delay 2 -quiet -from [get_pins -quiet -filter {REF_PIN_NAME == Q} -of [get_cells -quiet -filter {ars_ff1 == TRUE}]] -to [get_pins -quiet -filter {REF_PIN_NAME == D} -of [get_cells -quiet -filter {ars_ff2 == TRUE}]]

View File

@ -0,0 +1,50 @@
# Input files
set mmi_file "./soc.mmi"
set elf_file "./soc.elf"
set source_bit_file "./soc.bit"
# Output files
set output_bit_file "./soc_latest_sw.bit"
# Enable to turn on debug
set updatemem_debug 0
# Assemble bit file that can be downloaded to device directly
# Combine the original bit file, mmi file, and software elf to create the full bitstream
# Delete target file
file delete -force $output_bit_file
# Determine if the user has built the project and has the target source file
# If not, then use the reference bit file shipped with the project
if { ![file exists $source_bit_file] } {
puts "\n********************************************"
puts "INFO - File $source_bit_file doesn't exist as project has not been built"
puts " Using $reference_bit_file instead\n"
puts "********************************************/n"
set source_bit_file $reference_bit_file
}
# Banner message to console as there is no output for a few seconds
puts " Running updatemem ..."
if { $updatemem_debug } {
set error [catch {exec updatemem --debug --force --meminfo $mmi_file --data $elf_file --bit $source_bit_file --proc dummy --out $output_bit_file} result]
} else {
set error [catch {exec updatemem --force --meminfo $mmi_file --data $elf_file --bit $source_bit_file --proc dummy --out $output_bit_file} result]
}
# Print the stdout from updatemem
puts $result
# Updatemem returns 0 even when there is an error, so cannot trap on error. Having deleted output file to start, then
# detect if it now exists, else exit.
if { ![file exists $output_bit_file] } {
puts "ERROR - $output_bit_file not made"
return -1
} else {
puts "\n********************************************"
puts " $output_bit_file correctly generated"
puts "********************************************\n"
}

View File

@ -0,0 +1,6 @@
#!/bin/sh
#Create mcs file for QSPI flash
cd ./build
vivado -mode batch -source ../make_mcs_file.tcl -notrace

View File

@ -0,0 +1,31 @@
# Input file
set source_bit_file "./latest.bit"
# Output file
set output_mcs_file "./latest.mcs"
# Delete target file
file delete -force $output_mcs_file
# Determine if the user has built the project and has the target source file
# If not, then use the reference bit file shipped with the project
if { ![file exists $source_bit_file] } {
puts "\n********************************************"
puts "INFO - File $source_bit_file doesn't exist as project has not been built\n"
puts "********************************************/n"
error
}
# Create MCS file for base board QSPI flash memory
write_cfgmem -force -format MCS -size 16 -interface SPIx4 -loadbit " up 0 $source_bit_file" $output_mcs_file
# Check MCS was correctly made
if { ![file exists $output_mcs_file] } {
puts "ERROR - $output_bit_file not made"
return -1
} else {
puts "\n********************************************"
puts " $output_mcs_file correctly generated"
puts "********************************************\n"
}

View File

@ -0,0 +1,4 @@
#!/bin/sh
cd ./build
vivado -mode batch -source ../make_mmi_files.tcl -notrace

View File

@ -0,0 +1,6 @@
source [file join [file dirname [file normalize [info script]]] vivado_params.tcl]
open_project -read_only $outputdir/$projectName
open_run impl_1
source $base/soc_mmi.tcl
puts "mmi files generated"

View File

@ -0,0 +1,9 @@
#!/bin/sh
#cannot rm build because it erase software images that the make file copy there
#rm -rf ./build
mkdir ./build
cd ./build
vivado -mode batch -source ../make_vivado_project.tcl -notrace

View File

@ -0,0 +1,46 @@
#Create output directory and clear contents
source [file join [file dirname [file normalize [info script]]] vivado_params.tcl]
file mkdir $outputdir
set files [glob -nocomplain "$outputdir/*"]
if {[llength $files] != 0} {
puts "deleting contents of $outputdir"
file delete -force {*}[glob -directory $outputdir *]; # clear folder contents
} else {
puts "$outputdir is empty"
}
#Create project
create_project -part $part $projectName $outputdir
#add source files to Vivado project
#add_files -fileset sim_1 ./path/to/testbench.vhd
#add_files [glob ./path/to/sources/*.vhd]
#add_files -fileset constrs_1 ./path/to/constraint/constraint.xdc
#add_files [glob ./path/to/library/sources/*.vhd]
#set_property -library userDefined [glob ./path/to/library/sources/*.vhd]
add_files [glob $base/*.v]
add_files [glob $topv]
add_files -fileset constrs_1 $base/arty_a7.xdc
#set top level module and update compile order
set_property top toplevel [current_fileset]
update_compile_order -fileset sources_1
#update_compile_order -fileset sim_1
#launch synthesis
launch_runs synth_1
wait_on_run synth_1
#Run implementation and generate bitstream
set_property STEPS.PHYS_OPT_DESIGN.IS_ENABLED true [get_runs impl_1]
launch_runs impl_1 -to_step write_bitstream
wait_on_run impl_1
puts "Implementation done!"
#reports generated by default
#open_run impl_1
#report_timing_summary -check_timing_verbose -report_unconstrained -file report_timing_summary.rpt
#report_utilization -hierarchical -file report_utilization.rpt
#TODO: add checks about timing, DRC, CDC such that the script give clear indication if design is OK or not

View File

@ -0,0 +1,62 @@
ROOT=../../..
SWBASE=$(ROOT)/src/main/c/murax
SOCSW=hello_world
SOCMEMSRC=$(SWBASE)/$(SOCSW)/build/$(SOCSW).v
SOCMEM=build/soc.mem
TOP=Murax
all : build/latest.bit
../../../$(TOP).v : toplevel.v
(cd ../../..; sbt "runMain vexriscv.demo.Murax_arty")
.PHONY: $(SOCMEMSRC)
$(SOCMEMSRC):
mkdir -p build
make -C $(SWBASE)/$(SOCSW)
$(SOCMEM) : $(SOCMEMSRC)
cp -u $(SOCMEMSRC) $(SOCMEM)
build/vivado_project/fpga.runs/impl_1/toplevel.bit : toplevel.v arty_a7.xdc ../../../$(TOP).v
mkdir -p build
./make_vivado_project
cp build/vivado_project/fpga.runs/impl_1/toplevel.bit build/latest.bit
build/soc.mmi: build/vivado_project/fpga.runs/impl_1/toplevel.bit
./make_mmi_files
build/latest_soc_sw.bit : $(SOCMEM) build/soc.mmi
rm -f updatemem.jou updatemem.log
updatemem -force --meminfo build/soc.mmi --data $(SOCMEM) --bit build/latest.bit --proc dummy --out build/latest_soc_sw.bit
cp build/latest_soc_sw.bit build/latest.bit
build/latest.bit : build/latest_soc_sw.bit
build/latest.mcs : build/latest.bit
./make_mcs_file
prog : build/latest.bit
./write_fpga
flash : build/latest.mcs
./write_flash
clean-soc-sw:
make -C $(SWBASE)/$(SOCSW) clean-all
soc-sw: clean-soc-sw $(SOCMEM)
.PHONY: clean
clean :
rm -rf build
mkdir build
rm -f updatemem.jou
rm -f updatemem.log
clean-sw: clean-soc-sw
clean-all : clean clean-sw
rm -f ../../../$(TOP).v
rm -f ../../../$(TOP).v_*

View File

@ -0,0 +1,4 @@
#!/bin/sh
cd ./build
vivado -mode batch -source ../open_vivado_project.tcl -notrace

View File

@ -0,0 +1,4 @@
source [file join [file dirname [file normalize [info script]]] vivado_params.tcl]
open_project -read_only $outputdir/$projectName
start_gui

View File

@ -0,0 +1 @@
picocom --baud 115200 --imap lfcrlf /dev/ttyUSB1

View File

@ -0,0 +1,151 @@
#script to update the init values of RAM without re-synthesis
if {![info exists mmi_file]} {
# Set MMI output file name
set mmi_file "soc.mmi"
}
if {![info exists part]} {
set part "xc7a35ticsg324-1L"
}
# Function to swap bits
proc swap_bits { bit } {
if { $bit > 23 } {return [expr {24 + (31 - $bit)}]}
if { $bit > 15 } {return [expr {16 + (23 - $bit)}]}
if { $bit > 7 } {return [expr {8 + (15 - $bit)}]}
return [expr {7 - $bit}]
}
# If run from batch file, will need to open project, then open the run
# open_run impl_1
# Find all the RAMs, place in a list
set rams [get_cells -hier -regexp {.*core/system_ram/.*} -filter {REF_NAME =~ RAMB36E1}]
puts "[llength $rams] RAMs in total"
foreach m $rams {puts $m}
set mems [dict create]
foreach m $rams {
set numbers [regexp -all -inline -- {[0-9]+} $m]
dict set mems $numbers $m
}
set keys [dict keys $mems]
#set keys [lsort -integer $keys]
set rams []
foreach key $keys {
set m [dict get $mems $key]
puts "$key -> $m"
lappend rams $m
}
puts "after sort:"
foreach m $rams {puts $m}
puts $rams
if { [llength $rams] == 0 } {
puts "Error - no memories found"
return -1
}
if { [expr {[llength $rams] % 4}] != 0 } {
puts "Error - Number of memories not divisible by 4"
return -1
}
set size_bytes [expr {4096*[llength $rams]}]
puts "Instruction memory size $size_bytes"
# Currently only support memory sizes between 16kB, (one byte per mem), and 128kB, (one bit per mem)
if { ($size_bytes < (4*4096)) || ($size_bytes > (32*4096)) } {
puts "Error - Memory size of $size_bytes out of range"
puts " Script only supports memory sizes between 16kB and 128kB"
return -1
}
# Create and open target mmi file
set fp [open $mmi_file {WRONLY CREAT TRUNC}]
if { $fp == 0 } {
puts "Error - Unable to open $mmi_file for writing"
return -1
}
# Write the file header
puts $fp "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
puts $fp "<MemInfo Version=\"1\" Minor=\"15\">"
puts $fp " <Processor Endianness=\"ignored\" InstPath=\"dummy\">"
puts $fp " <AddressSpace Name=\"soc_side\" Begin=\"[expr {0x80000000}]\" End=\"[expr {0x80000000 + $size_bytes-1}]\">"
puts $fp " <BusBlock>"
# Calculate the expected number of bits per memory
set mem_bits [expr {32/[llength $rams]}]
puts "mem_bits = $mem_bits"
set mem_info [dict create]
set i 0
foreach ram $rams {
# Get the RAM location
set loc_val [get_property LOC [get_cells $ram]]
regexp -- {(RAMB36_)([0-9XY]+)} $loc_val full ram_name loc_xy
set memi [dict create ram $ram loc $loc_xy]
set numbers [regexp -all -inline -- {[0-9]+} $ram]
if { [llength $numbers] == 2 } {
dict lappend mem_info [lindex $numbers 0] $memi
} else {
dict lappend mem_info [expr $i/4] $memi
}
incr i
}
set sorted_mem_info [dict create]
foreach {idx mems} $mem_info {
foreach mem [lreverse $mems] {
dict lappend sorted_mem_info $idx $mem
}
}
foreach mems $sorted_mem_info {
foreach mem $mems {
puts $mem
}
}
set lsb 0
set memlen [ expr 4096*8 / $mem_bits ]
foreach {idx mems} $sorted_mem_info {
puts "idx=$idx"
foreach mem $mems {
puts "mem=$mem"
set ram [dict get $mem ram]
set loc [dict get $mem loc]
set msb [expr $lsb+$mem_bits-1]
set addr_start 0
set addr_end [expr $memlen-1]
puts "ram=$ram loc=$loc lsb=$lsb msb=$msb addr_start=$addr_start addr_end=$addr_end"
puts $fp " <!-- $ram -->"
puts $fp " <BitLane MemType=\"RAMB36\" Placement=\"$loc\">"
puts $fp " <DataWidth MSB=\"$msb\" LSB=\"$lsb\"/>"
puts $fp " <!--not used!--><AddressRange Begin=\"$addr_start\" End=\"$addr_end\"/>"
puts $fp " <Parity ON=\"false\" NumBits=\"0\"/>"
puts $fp " </BitLane>"
set lsb [expr ($msb+1)%32]
}
}
puts $fp " </BusBlock>"
puts $fp " </AddressSpace>"
puts $fp " </Processor>"
puts $fp " <Config>"
puts $fp " <Option Name=\"Part\" Val=\"$part\"/>"
puts $fp " </Config>"
puts $fp " <DRC>"
puts $fp " <Rule Name=\"RDADDRCHANGE\" Val=\"false\"/>"
puts $fp " </DRC>"
puts $fp "</MemInfo>"
close $fp

View File

@ -0,0 +1,66 @@
`timescale 1ns / 1ps
module toplevel(
input wire clk100,
input wire cpu_reset,//active low
input wire tck,
input wire tms,
input wire tdi,
input wire trst,//ignored
output reg tdo,
input wire serial_rx,
output wire serial_tx,
input wire user_sw0,
input wire user_sw1,
input wire user_sw2,
input wire user_sw3,
input wire user_btn0,
input wire user_btn1,
input wire user_btn2,
input wire user_btn3,
output wire user_led0,
output wire user_led1,
output wire user_led2,
output wire user_led3
);
wire [31:0] io_gpioA_read;
wire [31:0] io_gpioA_write;
wire [31:0] io_gpioA_writeEnable;
wire io_asyncReset = ~cpu_reset;
assign {user_led3,user_led2,user_led1,user_led0} = io_gpioA_write[3 : 0];
assign io_gpioA_read[3:0] = {user_sw3,user_sw2,user_sw1,user_sw0};
assign io_gpioA_read[7:4] = {user_btn3,user_btn2,user_btn1,user_btn0};
assign io_gpioA_read[11:8] = {tck,tms,tdi,trst};
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
Murax core (
.io_asyncReset(io_asyncReset),
.io_mainClk (clk100 ),
.io_jtag_tck(soc_tck),
.io_jtag_tdi(soc_tdi),
.io_jtag_tdo(soc_tdo),
.io_jtag_tms(soc_tms),
.io_gpioA_read (io_gpioA_read),
.io_gpioA_write (io_gpioA_write),
.io_gpioA_writeEnable(io_gpioA_writeEnable),
.io_uart_txd(serial_tx),
.io_uart_rxd(serial_rx)
);
endmodule

View File

@ -0,0 +1,5 @@
set outputdir ./vivado_project
set part "xc7a35ticsg324-1L"
set base ".."
set projectName "fpga"
set topv "$base/../../../Murax.v"

View File

@ -0,0 +1,3 @@
#!/bin/sh
cd ./build
vivado -mode batch -source ../write_flash.tcl -notrace

View File

@ -0,0 +1,26 @@
open_hw
connect_hw_server
open_hw_target
current_hw_device [get_hw_devices xc7a35t_0]
refresh_hw_device -update_hw_probes false [lindex [get_hw_devices xc7a35t_0] 0]
create_hw_cfgmem -hw_device [lindex [get_hw_devices] 0] -mem_dev [lindex [get_cfgmem_parts {s25fl128sxxxxxx0-spi-x1_x2_x4}] 0]
set_property PROBES.FILE {} [get_hw_devices xc7a35t_0]
set_property FULL_PROBES.FILE {} [get_hw_devices xc7a35t_0]
refresh_hw_device [lindex [get_hw_devices xc7a35t_0] 0]
set_property PROGRAM.ADDRESS_RANGE {use_file} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
set_property PROGRAM.FILES [list "latest.mcs" ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
set_property PROGRAM.PRM_FILE {} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
set_property PROGRAM.CHECKSUM 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
if {![string equal [get_property PROGRAM.HW_CFGMEM_TYPE [lindex [get_hw_devices xc7a35t_0] 0]] [get_property MEM_TYPE [get_property CFGMEM_PART [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]]]] } { create_hw_bitstream -hw_device [lindex [get_hw_devices xc7a35t_0] 0] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices xc7a35t_0] 0]]; program_hw_devices [lindex [get_hw_devices xc7a35t_0] 0]; };
program_hw_cfgmem -hw_cfgmem [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
close_hw_target
close_hw

View File

@ -0,0 +1,3 @@
#!/bin/sh
cd ./build
vivado -mode batch -source ../write_fpga.tcl -notrace

View File

@ -0,0 +1,10 @@
open_hw
connect_hw_server
open_hw_target
current_hw_device [get_hw_devices xc7a35t_0]
refresh_hw_device -update_hw_probes false [lindex [get_hw_devices xc7a35t_0] 0]
set_property PROBES.FILE {} [get_hw_devices xc7a35t_0]
set_property FULL_PROBES.FILE {} [get_hw_devices xc7a35t_0]
set_property PROGRAM.FILE {latest.bit} [get_hw_devices xc7a35t_0]
program_hw_devices [get_hw_devices xc7a35t_0]
disconnect_hw_server

View File

@ -1,19 +1,21 @@
VBASE = ../../..
VNAME = Murax_iCE40_hx8k_breakout_board_xip
VERILOG = ${VBASE}/${VNAME}.v
VERILOG = ../../../Murax_iCE40_hx8k_breakout_board_xip.v
all: prog
generate :
#(cd ../../..; sbt "runMain vexriscv.demo.Murax_iCE40_hx8k_breakout_board_xip")
${VERILOG} :
(cd ${VBASE}; sbt "runMain vexriscv.demo.${VNAME}")
../../../Murax_iCE40_hx8k_breakout_board_xip.v :
#(cd ../../..; sbt "runMain vexriscv.demo.Murax_iCE40_hx8k_breakout_board_xip")
generate : ${VERILOG}
../../../Murax_iCE40_hx8k_breakout_board_xip.v*.bin:
${VERILOG}*.bin:
bin/Murax_iCE40_hx8k_breakout_board_xip.blif : ${VERILOG} ../../../Murax_iCE40_hx8k_breakout_board_xip.v*.bin
bin/Murax_iCE40_hx8k_breakout_board_xip.blif : ${VERILOG} ${VERILOG}*.bin
mkdir -p bin
rm -f Murax_iCE40_hx8k_breakout_board_xip.v*.bin
cp ../../../Murax_iCE40_hx8k_breakout_board_xip.v*.bin . | true
cp ${VERILOG}*.bin . | true
yosys -v3 -p "synth_ice40 -top Murax_iCE40_hx8k_breakout_board_xip -blif bin/Murax_iCE40_hx8k_breakout_board_xip.blif" ${VERILOG}
bin/Murax_iCE40_hx8k_breakout_board_xip.asc : Murax_iCE40_hx8k_breakout_board_xip.pcf bin/Murax_iCE40_hx8k_breakout_board_xip.blif
@ -28,11 +30,15 @@ time: bin/Murax_iCE40_hx8k_breakout_board_xip.bin
icetime -tmd hx8k bin/Murax_iCE40_hx8k_breakout_board_xip.asc
prog : bin/Murax_iCE40_hx8k_breakout_board_xip.bin
lsusb -d 0403:6010
iceprog -S bin/Murax_iCE40_hx8k_breakout_board_xip.bin
sudo-prog : bin/Murax_iCE40_hx8k_breakout_board_xip.bin
sudo lsusb -d 0403:6010
sudo iceprog -S bin/Murax_iCE40_hx8k_breakout_board_xip.bin
clean :
rm -rf bin
rm -f Murax_iCE40_hx8k_breakout_board_xip.v*.bin
rm -f ${VERILOG}*.bin
rm -f ${VERILOG}

View File

@ -1,12 +1,12 @@
## iCE40-hx8k breakout board
set_io io_J3 J3
set_io io_H16 H16
set_io io_G15 G15
set_io io_G16 G16
set_io io_F15 F15
set_io io_B12 B12
set_io io_B10 B10
set_io io_mainClk J3
set_io io_jtag_tck H16
set_io io_jtag_tdi G15
set_io io_jtag_tdo G16
set_io io_jtag_tms F15
set_io io_uart_txd B12
set_io io_uart_rxd B10
set_io io_led[0] B5
set_io io_led[1] B4
set_io io_led[2] A2
@ -17,7 +17,7 @@ set_io io_led[6] B3
set_io io_led[7] C3
#XIP
set_io io_P12 P12
set_io io_P11 P11
set_io io_R11 R11
set_io io_R12 R12
set_io io_miso P12
set_io io_mosi P11
set_io io_sclk R11
set_io io_spis R12

View File

@ -9,6 +9,10 @@ This board can be purchased for ~$USD 49 directly from Lattice and is supported
by the IceStorm
[`iceprog`](https://github.com/cliffordwolf/icestorm/tree/master/iceprog) tool.
# Bootloader operations
A bootloader is implemented in a ROM within the FPGA bitfile. It configure the SPI and attempt to read the first word in 'XIP' area of the flash (0xE0040000 in CPU address space, 0x40000 in flash). If this first word is not 0xFFFFFFFF and the same value is read 3 times,
then the bootloader jump at 0xE0040000.
# Using the example
@ -59,12 +63,29 @@ The process should take around 30 seconds on a reasonable fast computer.
## Programming
Make sure the FPGA board is the only USB peripheral with ID 0403:6010
For example, this is bad:
```
user@lafite:~$ lsusb -d 0403:6010
Bus 001 Device 088: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
Bus 001 Device 090: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
```
This is good:
```
user@lafite:~$ lsusb -d 0403:6010
Bus 001 Device 088: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
```
After building you should be able to run `make prog`. You may need to run `make
sudo-prog` if root is needed to access your USB devices.
You should get output like the following;
```
iceprog -S bin/toplevel.bin
lsusb -d 0403:6010
Bus 001 Device 088: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
iceprog -S bin/Murax_iCE40_hx8k_breakout_board_xip.bin
init..
cdone: high
reset..
@ -74,13 +95,113 @@ cdone: high
Bye.
```
After programming the LEDs at the top of the board should start flashing in an
interesting pattern.
WARNING: having this output does NOT guarantee you actually programmed anything in the FPGA!
## Connect
After programming nothing visual will happen, except the LEDs being off.
The bootloader is waiting for a valid content in the flash (see Bootloader operations).
After programming you should be able to connect to the serial port and have the
output echoed back to you.
## Programming flash image
On Linux you can do this using a command like `screen /dev/ttyUSB1`. Then as
you type you should get back the same characters.
### Connect JTAG
We will use vexrisc JTAG to program the flash, so you need openocd and a
suitable JTAG dongle.
Pin-out:
```
TCK: H16 aka J2.25
TDO: G16 aka J2.26
TDI: G15 aka J2.27
TMS: F15 aka J2.28
```
In addition you need to connect the ground and VTarget aka VIO: J2.2 on the
board.
### Start GDB server / OpenOCD
Make sure to use https://github.com/SpinalHDL/openocd_riscv
Make sure to select the configuration file which match your JTAG dongle.
An example with the dongle "ft2232h_breakout":
```
src/openocd -f tcl/interface/ftdi/ft2232h_breakout.cfg -c "set MURAX_CPU0_YAML ../VexRiscv/cpu0.yaml" -f tcl/target/murax_xip.cfg
```
You should get an output like below:
```
Open On-Chip Debugger 0.10.0+dev-01214-g0ace94f (2019-10-02-18:23)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
../VexRiscv/cpu0.yaml
adapter speed: 100 kHz
adapter_nsrst_delay: 260
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
jtag_ntrst_delay: 250
Info : set servers polling period to 50ms
Error: libusb_get_string_descriptor_ascii() failed with LIBUSB_ERROR_INVALID_PARAM
Info : clock speed 100 kHz
Info : JTAG tap: fpga_spinal.bridge tap/device found: 0x10001fff (mfg: 0x7ff (<invalid>), part: 0x0001, ver: 0x1)
Info : Listening on port 3333 for gdb connections
requesting target halt and executing a soft reset
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
```
### Loading the flash with telnet
First we connect and stop execution on the device:
```
user@lafite:~/Downloads/vexrisc_full/VexRiscv/src/main/c/murax/xipBootloader$ telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
> reset
JTAG tap: fpga_spinal.bridge tap/device found: 0x10001fff (mfg: 0x7ff (<invalid>), part: 0x0001, ver: 0x1)
>
```
Now we can safely connect the J7 jumper on the board to be able to access the flash.
After that, we can load the program in flash:
```
> flash erase_sector 0 4 4
erased sectors 4 through 4 on flash bank 0 in 0.872235s
> flash write_bank 0 /home/user/dev/vexrisc_fork/VexRiscv/src/main/c/murax/xipBootloader/demo_xip.bin 0x40000
wrote 48 bytes from file /home/user/dev/vexrisc_fork/VexRiscv/src/main/c/murax/xipBootloader/demo_xip.bin to flash bank 0 at offset 0x00040000 in 0.285539s (0.164 KiB/s)
> flash verify_bank 0 /home/user/dev/vexrisc_fork/VexRiscv/src/main/c/murax/xipBootloader/demo_xip.bin 0x40000
read 48 bytes from file /home/user/dev/vexrisc_fork/VexRiscv/src/main/c/murax/xipBootloader/demo_xip.bin and flash bank 0 at offset 0x00040000 in 0.192036s (0.244 KiB/s)
contents match
> reset
JTAG tap: fpga_spinal.bridge tap/device found: 0x10001fff (mfg: 0x7ff (<invalid>), part: 0x0001, ver: 0x1)
> resume
> exit
Connection closed by foreign host.
```
From now the device runs the code from flash, LEDs shall display a dot moving from D9 to D2.
### Loading flash using GDB / eclipse
```
src/openocd -f tcl/interface/ftdi/ft2232h_breakout.cfg -c "set MURAX_CPU0_YAML ../VexRiscv/cpu0.yaml" -f tcl/target/murax_xip.cfg
```
- Make sure J7 is connected.
- Connect to GDB / eclipse as usual.
From there code loading, step, break points works as usual (including software break points in flash).
## Update hardware/bootloader
- Stop any OpenOCD connection
- Remove J7, then:
```
make clean prog
```
- Remember to check a single FTDI device is listed in the output. If not:
- Disconnect the other devices
```
make prog
```
- Connect J7, flash software shall start executing.
## Flash software
Refer to "Loading the flash with telnet" or "Loading flash using GDB / eclipse".

View File

@ -0,0 +1,134 @@
PROJ_NAME=hello_world
DEBUG=no
BENCH=no
MULDIV=no
SRCS = $(wildcard src/*.c) \
$(wildcard src/*.cpp) \
$(wildcard src/*.S)
OBJDIR = build
INC =
LIBS =
LIBSINC = -L$(OBJDIR)
LDSCRIPT = ./src/linker.ld
#include ../../../resources/gcc.mk
# Set it to yes if you are using the sifive precompiled GCC pack
SIFIVE_GCC_PACK ?= yes
ifeq ($(SIFIVE_GCC_PACK),yes)
RISCV_NAME ?= riscv64-unknown-elf
RISCV_PATH ?= /opt/riscv/
else
RISCV_NAME ?= riscv32-unknown-elf
ifeq ($(MULDIV),yes)
RISCV_PATH ?= /opt/riscv32im/
else
RISCV_PATH ?= /opt/riscv32i/
endif
endif
MABI=ilp32
MARCH := rv32i
ifeq ($(MULDIV),yes)
MARCH := $(MARCH)m
endif
ifeq ($(COMPRESSED),yes)
MARCH := $(MARCH)ac
endif
CFLAGS += -march=$(MARCH) -mabi=$(MABI) -DNDEBUG
LDFLAGS += -march=$(MARCH) -mabi=$(MABI)
#include ../../../resources/subproject.mk
ifeq ($(DEBUG),yes)
CFLAGS += -g3 -O0
endif
ifeq ($(DEBUG),no)
CFLAGS += -g -Os
endif
ifeq ($(BENCH),yes)
CFLAGS += -fno-inline
endif
ifeq ($(SIFIVE_GCC_PACK),yes)
RISCV_CLIB=$(RISCV_PATH)/$(RISCV_NAME)/lib/$(MARCH)/$(MABI)/
else
RISCV_CLIB=$(RISCV_PATH)/$(RISCV_NAME)/lib/
endif
RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy
RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump
RISCV_CC=$(RISCV_PATH)/bin/$(RISCV_NAME)-gcc
CFLAGS += -MD -fstrict-volatile-bitfields -fno-strict-aliasing
LDFLAGS += -nostdlib -lgcc -mcmodel=medany -nostartfiles -ffreestanding -Wl,-Bstatic,-T,$(LDSCRIPT),-Map,$(OBJDIR)/$(PROJ_NAME).map,--print-memory-usage
#LDFLAGS += -lgcc -lc -lg -nostdlib -lgcc -msave-restore --strip-debug,
OBJS := $(SRCS)
OBJS := $(OBJS:.c=.o)
OBJS := $(OBJS:.cpp=.o)
OBJS := $(OBJS:.S=.o)
OBJS := $(OBJS:..=miaou)
OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
all: $(OBJDIR)/$(PROJ_NAME).elf $(OBJDIR)/$(PROJ_NAME).hex $(OBJDIR)/$(PROJ_NAME).asm $(OBJDIR)/$(PROJ_NAME).v
$(OBJDIR)/%.elf: $(OBJS) | $(OBJDIR)
$(RISCV_CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBSINC) $(LIBS)
%.hex: %.elf
$(RISCV_OBJCOPY) -O ihex $^ $@
%.bin: %.elf
$(RISCV_OBJCOPY) -O binary $^ $@
%.v: %.elf
$(RISCV_OBJCOPY) -O verilog $^ $@
%.asm: %.elf
$(RISCV_OBJDUMP) -S -d $^ > $@
$(OBJDIR)/%.o: %.c
mkdir -p $(dir $@)
$(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
$(RISCV_CC) -S $(CFLAGS) $(INC) -o $@.disasm $^
$(OBJDIR)/%.o: %.cpp
mkdir -p $(dir $@)
$(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
$(OBJDIR)/%.o: %.S
mkdir -p $(dir $@)
$(RISCV_CC) -c $(CFLAGS) -o $@ $^ -D__ASSEMBLY__=1
$(OBJDIR):
mkdir -p $@
.PHONY: clean
clean:
rm -rf $(OBJDIR)/src
rm -f $(OBJDIR)/$(PROJ_NAME).elf
rm -f $(OBJDIR)/$(PROJ_NAME).hex
rm -f $(OBJDIR)/$(PROJ_NAME).map
rm -f $(OBJDIR)/$(PROJ_NAME).v
rm -f $(OBJDIR)/$(PROJ_NAME).asm
find $(OBJDIR) -type f -name '*.o' -print0 | xargs -0 -r rm
find $(OBJDIR) -type f -name '*.d' -print0 | xargs -0 -r rm
clean-all : clean
.SECONDARY: $(OBJS)

View File

@ -0,0 +1,98 @@
.global crtStart
.global main
.global irqCallback
.section .start_jump,"ax",@progbits
crtStart:
//long jump to allow crtInit to be anywhere
//do it always in 12 bytes
lui x2, %hi(crtInit)
addi x2, x2, %lo(crtInit)
jalr x1,x2
nop
.section .text
.global trap_entry
.align 5
trap_entry:
sw x1, - 1*4(sp)
sw x5, - 2*4(sp)
sw x6, - 3*4(sp)
sw x7, - 4*4(sp)
sw x10, - 5*4(sp)
sw x11, - 6*4(sp)
sw x12, - 7*4(sp)
sw x13, - 8*4(sp)
sw x14, - 9*4(sp)
sw x15, -10*4(sp)
sw x16, -11*4(sp)
sw x17, -12*4(sp)
sw x28, -13*4(sp)
sw x29, -14*4(sp)
sw x30, -15*4(sp)
sw x31, -16*4(sp)
addi sp,sp,-16*4
call irqCallback
lw x1 , 15*4(sp)
lw x5, 14*4(sp)
lw x6, 13*4(sp)
lw x7, 12*4(sp)
lw x10, 11*4(sp)
lw x11, 10*4(sp)
lw x12, 9*4(sp)
lw x13, 8*4(sp)
lw x14, 7*4(sp)
lw x15, 6*4(sp)
lw x16, 5*4(sp)
lw x17, 4*4(sp)
lw x28, 3*4(sp)
lw x29, 2*4(sp)
lw x30, 1*4(sp)
lw x31, 0*4(sp)
addi sp,sp,16*4
mret
.text
crtInit:
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _stack_start
bss_init:
la a0, _bss_start
la a1, _bss_end
bss_loop:
beq a0,a1,bss_done
sw zero,0(a0)
add a0,a0,4
j bss_loop
bss_done:
ctors_init:
la a0, _ctors_start
addi sp,sp,-4
ctors_loop:
la a1, _ctors_end
beq a0,a1,ctors_done
lw a3,0(a0)
add a0,a0,4
sw a0,0(sp)
jalr a3
lw a0,0(sp)
j ctors_loop
ctors_done:
addi sp,sp,4
li a0, 0x880 //880 enable timer + external interrupts
csrw mie,a0
li a0, 0x1808 //1808 enable interrupts
csrw mstatus,a0
call main
infinitLoop:
j infinitLoop

View File

@ -0,0 +1,15 @@
#ifndef GPIO_H_
#define GPIO_H_
typedef struct
{
volatile uint32_t INPUT;
volatile uint32_t OUTPUT;
volatile uint32_t OUTPUT_ENABLE;
} Gpio_Reg;
#endif /* GPIO_H_ */

View File

@ -0,0 +1,17 @@
#ifndef INTERRUPTCTRL_H_
#define INTERRUPTCTRL_H_
#include <stdint.h>
typedef struct
{
volatile uint32_t PENDINGS;
volatile uint32_t MASKS;
} InterruptCtrl_Reg;
static void interruptCtrl_init(InterruptCtrl_Reg* reg){
reg->MASKS = 0;
reg->PENDINGS = 0xFFFFFFFF;
}
#endif /* INTERRUPTCTRL_H_ */

View File

@ -0,0 +1,110 @@
/*
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
*/
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(crtStart)
MEMORY {
RAM (rwx): ORIGIN = 0x80000000, LENGTH = 2k
}
_stack_size = DEFINED(_stack_size) ? _stack_size : 256;
_heap_size = DEFINED(_heap_size) ? _heap_size : 0;
SECTIONS {
._vector ORIGIN(RAM): {
*crt.o(.start_jump);
*crt.o(.text);
} > RAM
._user_heap (NOLOAD):
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
PROVIDE ( _heap_start = .);
. = . + _heap_size;
. = ALIGN(8);
PROVIDE ( _heap_end = .);
} > RAM
._stack (NOLOAD):
{
. = ALIGN(16);
PROVIDE (_stack_end = .);
. = . + _stack_size;
. = ALIGN(16);
PROVIDE (_stack_start = .);
} > RAM
.data :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} > RAM
.bss (NOLOAD) : {
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_bss_start = .;
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_bss_end = .;
} > RAM
.rodata :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
} > RAM
.noinit (NOLOAD) : {
. = ALIGN(4);
*(.noinit .noinit.*)
. = ALIGN(4);
} > RAM
.memory : {
*(.text);
end = .;
} > RAM
.ctors :
{
. = ALIGN(4);
_ctors_start = .;
KEEP(*(.init_array*))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4);
_ctors_end = .;
PROVIDE ( END_OF_SW_IMAGE = . );
} > RAM
}

View File

@ -0,0 +1,42 @@
//#include "stddefs.h"
#include <stdint.h>
#include "murax.h"
void print(const char*str){
while(*str){
uart_write(UART,*str);
str++;
}
}
void println(const char*str){
print(str);
uart_write(UART,'\n');
}
void delay(uint32_t loops){
for(int i=0;i<loops;i++){
int tmp = GPIO_A->OUTPUT;
}
}
void main() {
GPIO_A->OUTPUT_ENABLE = 0x0000000F;
GPIO_A->OUTPUT = 0x00000001;
println("hello world arty a7 v1");
const int nleds = 4;
const int nloops = 2000000;
while(1){
for(unsigned int i=0;i<nleds-1;i++){
GPIO_A->OUTPUT = 1<<i;
delay(nloops);
}
for(unsigned int i=0;i<nleds-1;i++){
GPIO_A->OUTPUT = (1<<(nleds-1))>>i;
delay(nloops);
}
}
}
void irqCallback(){
}

View File

@ -0,0 +1,17 @@
#ifndef __MURAX_H__
#define __MURAX_H__
#include "timer.h"
#include "prescaler.h"
#include "interrupt.h"
#include "gpio.h"
#include "uart.h"
#define GPIO_A ((Gpio_Reg*)(0xF0000000))
#define TIMER_PRESCALER ((Prescaler_Reg*)0xF0020000)
#define TIMER_INTERRUPT ((InterruptCtrl_Reg*)0xF0020010)
#define TIMER_A ((Timer_Reg*)0xF0020040)
#define TIMER_B ((Timer_Reg*)0xF0020050)
#define UART ((Uart_Reg*)(0xF0010000))
#endif /* __MURAX_H__ */

View File

@ -0,0 +1,16 @@
#ifndef PRESCALERCTRL_H_
#define PRESCALERCTRL_H_
#include <stdint.h>
typedef struct
{
volatile uint32_t LIMIT;
} Prescaler_Reg;
static void prescaler_init(Prescaler_Reg* reg){
}
#endif /* PRESCALERCTRL_H_ */

View File

@ -0,0 +1,20 @@
#ifndef TIMERCTRL_H_
#define TIMERCTRL_H_
#include <stdint.h>
typedef struct
{
volatile uint32_t CLEARS_TICKS;
volatile uint32_t LIMIT;
volatile uint32_t VALUE;
} Timer_Reg;
static void timer_init(Timer_Reg *reg){
reg->CLEARS_TICKS = 0;
reg->VALUE = 0;
}
#endif /* TIMERCTRL_H_ */

View File

@ -0,0 +1,42 @@
#ifndef UART_H_
#define UART_H_
typedef struct
{
volatile uint32_t DATA;
volatile uint32_t STATUS;
volatile uint32_t CLOCK_DIVIDER;
volatile uint32_t FRAME_CONFIG;
} Uart_Reg;
enum UartParity {NONE = 0,EVEN = 1,ODD = 2};
enum UartStop {ONE = 0,TWO = 1};
typedef struct {
uint32_t dataLength;
enum UartParity parity;
enum UartStop stop;
uint32_t clockDivider;
} Uart_Config;
static uint32_t uart_writeAvailability(Uart_Reg *reg){
return (reg->STATUS >> 16) & 0xFF;
}
static uint32_t uart_readOccupancy(Uart_Reg *reg){
return reg->STATUS >> 24;
}
static void uart_write(Uart_Reg *reg, uint32_t data){
while(uart_writeAvailability(reg) == 0);
reg->DATA = data;
}
static void uart_applyConfig(Uart_Reg *reg, Uart_Config *config){
reg->CLOCK_DIVIDER = config->clockDivider;
reg->FRAME_CONFIG = ((config->dataLength-1) << 0) | (config->parity << 8) | (config->stop << 16);
}
#endif /* UART_H_ */

View File

@ -42,13 +42,33 @@ crtStart:
li t0, 0x1
sw t0, CTRL_XIP_CONFIG(CTRL)
li t0, XIP_BASE
lw t1, (t0)
li t2, 0xFFFFFFFF
xor t3,t1,t2
beqz t3,retry
//if we are here we have read a value from flash which is not all ones
lw t2, (t0)
xor t3,t1,t2
bnez t3,retry
lw t2, (t0)
xor t3,t1,t2
bnez t3,retry
//if we are here we have read the same value 3 times, so flash seems good, lets's jump
jr t0
retry:
li a0, 0x800
call spiWrite
li t1,100000
loop:
addi t1,t1,-1
bnez t1, loop
j crtStart
spiWrite:
sw a0,CTRL_DATA(CTRL)
spiWrite_wait:
lw t0,CTRL_STATUS(CTRL)
srli t0,t0,0x10
slli t0,t0,0x10
beqz t0,spiWrite_wait
ret

View File

@ -7,18 +7,21 @@
crtStart:
li x31, 0x12340000 // magic word expected by bootloader
li x31, GPIO_BASE
li t0, 0x000000FF
sw t0, GPIO_OUTPUT_ENABLE(x31)
li t0,0
li t0,1
redo:
sw t0, GPIO_OUTPUT(x31)
li t1,10000
addi t0,t0,1
slli t0,t0,1
andi t0,t0,0xFF
bnez t0, loop
li t0,1
loop:
addi t1,t1,-1
bnez t1, loop
j redo

View File

@ -4,20 +4,34 @@ LFLAGS= -nostdlib -mcmodel=medany -nostartfiles -ffreestanding -fPIC -fPIE
all: crt.S demo.S
riscv64-unknown-elf-gcc -c $(CFLAGS) -o crt.o crt.S
riscv64-unknown-elf-gcc $(CFLAGS) -o crt.elf crt.o $(LFLAGS) -Wl,-Bstatic,-T,mapping.ld,-Map,crt.map,--print-memory-usage
riscv64-unknown-elf-gcc $(CFLAGS) -o crt.elf crt.o $(LFLAGS) -Wl,-Bstatic,-T,mapping_rom.ld,-Map,crt.map,--print-memory-usage
riscv64-unknown-elf-objdump -S -d crt.elf > crt.asm
riscv64-unknown-elf-objcopy -O binary crt.elf crt.bin
riscv64-unknown-elf-gcc $(CFLAGS) -o crt_ram.elf crt.o $(LFLAGS) -Wl,-Bstatic,-T,mapping.ld,-Map,crt_ram.map,--print-memory-usage
riscv64-unknown-elf-objdump -S -d crt_ram.elf > crt_ram.asm
riscv64-unknown-elf-objcopy -O binary crt_ram.elf crt_ram.bin
riscv64-unknown-elf-gcc -c $(CFLAGS) -o demo.o demo.S
riscv64-unknown-elf-gcc $(CFLAGS) -o demo.elf demo.o $(LFLAGS) -Wl,-Bstatic,-T,mapping.ld,-Map,demo.map,--print-memory-usage
riscv64-unknown-elf-objdump -S -d demo.elf > demo.asm
riscv64-unknown-elf-objcopy -O binary demo.elf demo.bin
riscv64-unknown-elf-gcc $(CFLAGS) -o demo_rom.elf demo.o $(LFLAGS) -Wl,-Bstatic,-T,mapping_rom.ld,-Map,demo_rom.map,--print-memory-usage
riscv64-unknown-elf-objdump -S -d demo_rom.elf > demo_rom.asm
riscv64-unknown-elf-objcopy -O binary demo_rom.elf demo_rom.bin
riscv64-unknown-elf-gcc $(CFLAGS) -o demo_xip.elf demo.o $(LFLAGS) -Wl,-Bstatic,-T,mapping_xip.ld,-Map,demo_xip.map,--print-memory-usage
riscv64-unknown-elf-objdump -S -d demo_xip.elf > demo_xip.asm
riscv64-unknown-elf-objcopy -O binary demo_xip.elf demo_xip.bin
clean:
clean-for-commit:
rm -f *.o
rm -f *.bin
rm -f *.elf
rm -f *.asm
rm -f *.map
rm -f *.map
rm -f *.d
rm demo_rom.bin demo.bin crt_ram.bin
clean: clean-for-commit
rm -f *.bin

View File

@ -0,0 +1,96 @@
/*
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
*/
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(crtStart)
MEMORY {
mem : ORIGIN = 0x80000000, LENGTH = 0x00000400
rom : ORIGIN = 0xF001E000, LENGTH = 0x00000400
}
_stack_size = DEFINED(_stack_size) ? _stack_size : 0;
SECTIONS {
.vector : {
*crt.o(.text);
} > rom
.memory : {
*(.text);
end = .;
} > rom
.rodata :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
} > rom
.ctors :
{
. = ALIGN(4);
_ctors_start = .;
KEEP(*(.init_array*))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4);
_ctors_end = .;
} > rom
.data :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} > rom
.bss (NOLOAD) : {
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_bss_start = .;
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_bss_end = .;
} > mem
.noinit (NOLOAD) : {
. = ALIGN(4);
*(.noinit .noinit.*)
. = ALIGN(4);
} > mem
._stack (NOLOAD):
{
. = ALIGN(16);
PROVIDE (_stack_end = .);
. = . + _stack_size;
. = ALIGN(16);
PROVIDE (_stack_start = .);
} > mem
}

View File

@ -0,0 +1,96 @@
/*
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
*/
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(crtStart)
MEMORY {
mem : ORIGIN = 0x80000000, LENGTH = 0x00000400
xip : ORIGIN = 0xE0040000, LENGTH = 0x00000400
}
_stack_size = DEFINED(_stack_size) ? _stack_size : 0;
SECTIONS {
.vector : {
*crt.o(.text);
} > xip
.memory : {
*(.text);
end = .;
} > xip
.rodata :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
} > xip
.ctors :
{
. = ALIGN(4);
_ctors_start = .;
KEEP(*(.init_array*))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4);
_ctors_end = .;
} > xip
.data :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} > xip
.bss (NOLOAD) : {
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_bss_start = .;
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_bss_end = .;
} > mem
.noinit (NOLOAD) : {
. = ALIGN(4);
*(.noinit .noinit.*)
. = ALIGN(4);
} > mem
._stack (NOLOAD):
{
. = ALIGN(16);
PROVIDE (_stack_end = .);
. = . + _stack_size;
. = ALIGN(16);
PROVIDE (_stack_start = .);
} > mem
}

View File

@ -362,57 +362,55 @@ object Murax_iCE40_hx8k_breakout_board_xip{
case class Murax_iCE40_hx8k_breakout_board_xip() extends Component{
val io = new Bundle {
val J3 = in Bool()
val H16 = in Bool()
val G15 = in Bool()
val G16 = out Bool()
val F15 = in Bool()
val B12 = out Bool()
val B10 = in Bool()
val mainClk = in Bool()
val jtag_tck = in Bool()
val jtag_tdi = in Bool()
val jtag_tdo = out Bool()
val jtag_tms = in Bool()
val uart_txd = out Bool()
val uart_rxd = in Bool()
//p12 as mosi mean flash config
val P12 = inout(Analog(Bool))
val P11 = inout(Analog(Bool))
val R11 = out Bool()
val R12 = out Bool()
val mosi = inout(Analog(Bool))
val miso = inout(Analog(Bool))
val sclk = out Bool()
val spis = out Bool()
val led = out Bits(8 bits)
}
val murax = Murax(MuraxConfig.default(withXip = true))
val murax = Murax(MuraxConfig.default(withXip = true).copy(onChipRamSize = 8 kB))
murax.io.asyncReset := False
val mainClkBuffer = SB_GB()
mainClkBuffer.USER_SIGNAL_TO_GLOBAL_BUFFER <> io.J3
mainClkBuffer.USER_SIGNAL_TO_GLOBAL_BUFFER <> io.mainClk
mainClkBuffer.GLOBAL_BUFFER_OUTPUT <> murax.io.mainClk
val jtagClkBuffer = SB_GB()
jtagClkBuffer.USER_SIGNAL_TO_GLOBAL_BUFFER <> io.H16
jtagClkBuffer.USER_SIGNAL_TO_GLOBAL_BUFFER <> io.jtag_tck
jtagClkBuffer.GLOBAL_BUFFER_OUTPUT <> murax.io.jtag.tck
io.led <> murax.io.gpioA.write(7 downto 0)
murax.io.jtag.tdi <> io.G15
murax.io.jtag.tdo <> io.G16
murax.io.jtag.tms <> io.F15
murax.io.jtag.tdi <> io.jtag_tdi
murax.io.jtag.tdo <> io.jtag_tdo
murax.io.jtag.tms <> io.jtag_tms
murax.io.gpioA.read <> 0
murax.io.uart.txd <> io.B12
murax.io.uart.rxd <> io.B10
murax.io.uart.txd <> io.uart_txd
murax.io.uart.rxd <> io.uart_rxd
val xip = new ClockingArea(murax.systemClockDomain) {
RegNext(murax.io.xip.ss.asBool) <> io.R12
RegNext(murax.io.xip.ss.asBool) <> io.spis
val sclkIo = SB_IO_SCLK()
sclkIo.PACKAGE_PIN <> io.R11
sclkIo.PACKAGE_PIN <> io.sclk
sclkIo.CLOCK_ENABLE := True
sclkIo.OUTPUT_CLK := ClockDomain.current.readClockWire
sclkIo.D_OUT_0 <> murax.io.xip.sclk.write(0)
sclkIo.D_OUT_1 <> RegNext(murax.io.xip.sclk.write(1))
val datas = for ((data, pin) <- (murax.io.xip.data, List(io.P12, io.P11).reverse).zipped) yield new Area {
val datas = for ((data, pin) <- (murax.io.xip.data, List(io.mosi, io.miso)).zipped) yield new Area {
val dataIo = SB_IO_DATA()
dataIo.PACKAGE_PIN := pin
dataIo.CLOCK_ENABLE := True
@ -432,45 +430,6 @@ object Murax_iCE40_hx8k_breakout_board_xip{
def main(args: Array[String]) {
SpinalVerilog(Murax_iCE40_hx8k_breakout_board_xip())
/*SpinalVerilog{
val c = Murax(MuraxConfig.default(withXip = true))
c.rework {
c.resetCtrlClockDomain {
c.io.xip.setAsDirectionLess.allowDirectionLessIo.flattenForeach(_.unsetName())
out(RegNext(c.io.xip.ss)).setName("io_xip_ss")
val sclk = SB_IO_SCLK()
sclk.PACKAGE_PIN := inout(Analog(Bool)).setName("io_xip_sclk")
sclk.CLOCK_ENABLE := True
sclk.OUTPUT_CLK := ClockDomain.current.readClockWire
sclk.D_OUT_0 <> c.io.xip.sclk.write(0)
sclk.D_OUT_1 <> RegNext(c.io.xip.sclk.write(1))
for (i <- 0 until c.io.xip.p.dataWidth) {
val data = c.io.xip.data(i)
val bb = SB_IO_DATA()
bb.PACKAGE_PIN := inout(Analog(Bool)).setName(s"io_xip_data_$i" )
bb.CLOCK_ENABLE := True
bb.OUTPUT_CLK := ClockDomain.current.readClockWire
bb.OUTPUT_ENABLE <> data.writeEnable
bb.D_OUT_0 <> data.write(0)
bb.D_OUT_1 <> RegNext(data.write(1))
bb.INPUT_CLK := ClockDomain.current.readClockWire
data.read(0) := bb.D_IN_0
data.read(1) := RegNext(bb.D_IN_1)
}
}
}
c
}*/
}
}
@ -512,3 +471,10 @@ object MuraxWithRamInit{
SpinalVerilog(Murax(MuraxConfig.default.copy(onChipRamSize = 4 kB, onChipRamHexFile = "src/main/ressource/hex/muraxDemo.hex")))
}
}
object Murax_arty{
def main(args: Array[String]) {
val hex = "src/main/c/murax/hello_world/build/hello_world.hex"
SpinalVerilog(Murax(MuraxConfig.default(false).copy(coreFrequency = 100 MHz,onChipRamSize = 32 kB, onChipRamHexFile = hex)))
}
}

View File

@ -24,8 +24,9 @@ case class DataCacheConfig(cacheSize : Int,
earlyDataMux : Boolean = false,
tagSizeShift : Int = 0, //Used to force infering ram
withLrSc : Boolean = false,
withAmo : Boolean = false){
withAmo : Boolean = false,
mergeExecuteMemory : Boolean = false){
assert(!(mergeExecuteMemory && (earlyDataMux || earlyWaysHits)))
assert(!(earlyDataMux && !earlyWaysHits))
def burstSize = bytePerLine*8/memDataWidth
val burstLength = bytePerLine/(memDataWidth/8)
@ -447,7 +448,7 @@ class DataCache(p : DataCacheConfig) extends Component{
}
val stageA = new Area{
def stagePipe[T <: Data](that : T) = RegNextWhen(that, !io.cpu.memory.isStuck)
def stagePipe[T <: Data](that : T) = if(mergeExecuteMemory) CombInit(that) else RegNextWhen(that, !io.cpu.memory.isStuck)
val request = stagePipe(io.cpu.execute.args)
val mask = stagePipe(stage0.mask)
io.cpu.memory.mmuBus.cmd.isValid := io.cpu.memory.isValid
@ -458,16 +459,22 @@ class DataCache(p : DataCacheConfig) extends Component{
val wayHits = earlyWaysHits generate ways.map(way => (io.cpu.memory.mmuBus.rsp.physicalAddress(tagRange) === way.tagsReadRsp.address && way.tagsReadRsp.valid))
val dataMux = earlyDataMux generate MuxOH(wayHits, ways.map(_.dataReadRsp))
val colisions = stagePipe(stage0.colisions) | collisionProcess(io.cpu.memory.address(lineRange.high downto wordRange.low), mask) //Assume the writeback stage will never be unstall memory acces while memory stage is stalled
val colisions = if(mergeExecuteMemory){
stagePipe(stage0.colisions)
} else {
//Assume the writeback stage will never be unstall memory acces while memory stage is stalled
stagePipe(stage0.colisions) | collisionProcess(io.cpu.memory.address(lineRange.high downto wordRange.low), mask)
}
}
val stageB = new Area {
def stagePipe[T <: Data](that : T) = RegNextWhen(that, !io.cpu.writeBack.isStuck)
def ramPipe[T <: Data](that : T) = if(mergeExecuteMemory) CombInit(that) else RegNextWhen(that, !io.cpu.writeBack.isStuck)
val request = RegNextWhen(stageA.request, !io.cpu.writeBack.isStuck)
val mmuRspFreeze = False
val mmuRsp = RegNextWhen(io.cpu.memory.mmuBus.rsp, !io.cpu.writeBack.isStuck && !mmuRspFreeze)
val tagsReadRsp = ways.map(w => stagePipe(w.tagsReadRsp))
val dataReadRsp = !earlyDataMux generate ways.map(w => stagePipe(w.dataReadRsp))
val tagsReadRsp = ways.map(w => ramPipe(w.tagsReadRsp))
val dataReadRsp = !earlyDataMux generate ways.map(w => ramPipe(w.dataReadRsp))
val waysHits = if(earlyWaysHits) stagePipe(B(stageA.wayHits)) else B(tagsReadRsp.map(tag => mmuRsp.physicalAddress(tagRange) === tag.address && tag.valid).asBits())
val waysHit = waysHits.orR
val dataMux = if(earlyDataMux) stagePipe(stageA.dataMux) else MuxOH(waysHits, dataReadRsp)

View File

@ -148,7 +148,7 @@ class DBusCachedPlugin(val config : DataCacheConfig,
redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(if(pipeline.writeBack != null) pipeline.writeBack else pipeline.execute)
if(catchSomething)
exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(pipeline.writeBack)
exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(if(pipeline.writeBack == null) pipeline.memory else pipeline.writeBack)
if(pipeline.serviceExist(classOf[PrivilegeService]))
privilegeService = pipeline.service(classOf[PrivilegeService])
@ -162,7 +162,9 @@ class DBusCachedPlugin(val config : DataCacheConfig,
dBus = master(DataCacheMemBus(this.config)).setName("dBus")
val cache = new DataCache(this.config)
val cache = new DataCache(this.config.copy(
mergeExecuteMemory = writeBack == null
))
//Interconnect the plugin dBus with the cache dBus with some optional pipelining
def optionPipe[T](cond : Boolean, on : T)(f : T => T) : T = if(cond) f(on) else on
@ -229,19 +231,22 @@ class DBusCachedPlugin(val config : DataCacheConfig,
}
}
memory plug new Area{
import memory._
val mmuAndBufferStage = if(writeBack != null) memory else execute
mmuAndBufferStage plug new Area {
import mmuAndBufferStage._
cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE)
cache.io.cpu.memory.isStuck := arbitration.isStuck
cache.io.cpu.memory.isRemoved := arbitration.removeIt
cache.io.cpu.memory.address := (if(relaxedMemoryTranslationRegister) input(MEMORY_VIRTUAL_ADDRESS) else U(input(REGFILE_WRITE_DATA)))
cache.io.cpu.memory.address := (if(relaxedMemoryTranslationRegister) input(MEMORY_VIRTUAL_ADDRESS) else if(mmuAndBufferStage == execute) cache.io.cpu.execute.address else U(input(REGFILE_WRITE_DATA)))
cache.io.cpu.memory.mmuBus <> mmuBus
cache.io.cpu.memory.mmuBus.rsp.isIoAccess setWhen(pipeline(DEBUG_BYPASS_CACHE) && !cache.io.cpu.memory.isWrite)
}
writeBack plug new Area{
import writeBack._
val managementStage = stages.last
managementStage plug new Area{
import managementStage._
cache.io.cpu.writeBack.isValid := arbitration.isValid && input(MEMORY_ENABLE)
cache.io.cpu.writeBack.isStuck := arbitration.isStuck
cache.io.cpu.writeBack.isUser := (if(privilegeService != null) privilegeService.isUser() else False)
@ -326,10 +331,10 @@ class DBusCachedPlugin(val config : DataCacheConfig,
execute.insert(IS_DBUS_SHARING) := dBusAccess.cmd.fire
mmuBus.cmd.bypassTranslation setWhen(memory.input(IS_DBUS_SHARING))
cache.io.cpu.memory.isValid setWhen(memory.input(IS_DBUS_SHARING))
cache.io.cpu.writeBack.isValid setWhen(writeBack.input(IS_DBUS_SHARING))
dBusAccess.rsp.valid := writeBack.input(IS_DBUS_SHARING) && !cache.io.cpu.writeBack.isWrite && (cache.io.cpu.redo || !cache.io.cpu.writeBack.haltIt)
mmuBus.cmd.bypassTranslation setWhen(mmuAndBufferStage.input(IS_DBUS_SHARING))
if(mmuAndBufferStage != execute) (cache.io.cpu.memory.isValid setWhen(mmuAndBufferStage.input(IS_DBUS_SHARING)))
cache.io.cpu.writeBack.isValid setWhen(managementStage.input(IS_DBUS_SHARING))
dBusAccess.rsp.valid := managementStage.input(IS_DBUS_SHARING) && !cache.io.cpu.writeBack.isWrite && (cache.io.cpu.redo || !cache.io.cpu.writeBack.haltIt)
dBusAccess.rsp.data := cache.io.cpu.writeBack.data
dBusAccess.rsp.error := cache.io.cpu.writeBack.unalignedAccess || cache.io.cpu.writeBack.accessError
dBusAccess.rsp.redo := cache.io.cpu.redo
@ -337,10 +342,10 @@ class DBusCachedPlugin(val config : DataCacheConfig,
when(forceDatapath){
execute.output(REGFILE_WRITE_DATA) := dBusAccess.cmd.address.asBits
}
memory.input(IS_DBUS_SHARING) init(False)
writeBack.input(IS_DBUS_SHARING) init(False)
if(mmuAndBufferStage != execute) mmuAndBufferStage.input(IS_DBUS_SHARING) init(False)
managementStage.input(IS_DBUS_SHARING) init(False)
when(dBusAccess.rsp.valid){
writeBack.input(IS_DBUS_SHARING).getDrivingReg := False
managementStage.input(IS_DBUS_SHARING).getDrivingReg := False
}
}
}

View File

@ -95,7 +95,7 @@ class HazardSimplePlugin(bypassExecute : Boolean = false,
}
if(withWriteBackStage) trackHazardWithStage(writeBack,bypassWriteBack,null)
if(withMemoryStage) trackHazardWithStage(memory ,bypassMemory ,BYPASSABLE_MEMORY_STAGE)
if(withMemoryStage) trackHazardWithStage(memory ,bypassMemory, if(stages.last == memory) null else BYPASSABLE_MEMORY_STAGE)
if(readStage != execute) trackHazardWithStage(execute ,bypassExecute , if(stages.last == execute) null else BYPASSABLE_EXECUTE_STAGE)

View File

@ -0,0 +1,119 @@
package vexriscv.plugin
import vexriscv._
import vexriscv.plugin._
import spinal.core._
/**
* A multiplication plugin using only 16-bit multiplications
*/
class Mul16Plugin extends Plugin[VexRiscv]{
object MUL_LL extends Stageable(UInt(32 bits))
object MUL_LH extends Stageable(UInt(32 bits))
object MUL_HL extends Stageable(UInt(32 bits))
object MUL_HH extends Stageable(UInt(32 bits))
object MUL extends Stageable(Bits(64 bits))
object IS_MUL extends Stageable(Bool)
override def setup(pipeline: VexRiscv): Unit = {
import Riscv._
import pipeline.config._
val actions = List[(Stageable[_ <: BaseType],Any)](
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> False,
RS1_USE -> True,
RS2_USE -> True,
IS_MUL -> True
)
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.addDefault(IS_MUL, False)
decoderService.add(List(
MULX -> actions
))
}
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
// Prepare signed inputs for the multiplier in the next stage.
// This will map them best to an FPGA DSP.
execute plug new Area {
import execute._
val a,b = Bits(32 bit)
a := input(SRC1)
b := input(SRC2)
val aLow = a(15 downto 0).asUInt
val bLow = b(15 downto 0).asUInt
val aHigh = a(31 downto 16).asUInt
val bHigh = b(31 downto 16).asUInt
insert(MUL_LL) := aLow * bLow
insert(MUL_LH) := aLow * bHigh
insert(MUL_HL) := aHigh * bLow
insert(MUL_HH) := aHigh * bHigh
}
memory plug new Area {
import memory._
val ll = UInt(32 bits)
val lh = UInt(33 bits)
val hl = UInt(32 bits)
val hh = UInt(32 bits)
ll := input(MUL_LL)
lh := input(MUL_LH).resized
hl := input(MUL_HL)
hh := input(MUL_HH)
val hllh = lh + hl
insert(MUL) := ((hh ## ll(31 downto 16)).asUInt + hllh) ## ll(15 downto 0)
}
writeBack plug new Area {
import writeBack._
val aSigned,bSigned = Bool
switch(input(INSTRUCTION)(13 downto 12)) {
is(B"01") {
aSigned := True
bSigned := True
}
is(B"10") {
aSigned := True
bSigned := False
}
default {
aSigned := False
bSigned := False
}
}
val a = (aSigned && input(SRC1).msb) ? input(SRC2).asUInt | U(0)
val b = (bSigned && input(SRC2).msb) ? input(SRC1).asUInt | U(0)
when(arbitration.isValid && input(IS_MUL)){
switch(input(INSTRUCTION)(13 downto 12)){
is(B"00"){
output(REGFILE_WRITE_DATA) := input(MUL)(31 downto 0)
}
is(B"01",B"10",B"11"){
output(REGFILE_WRITE_DATA) := (((input(MUL)(63 downto 32)).asUInt + ~a) + (~b + 2)).asBits
}
}
}
}
}
}

View File

@ -31,7 +31,7 @@ class MulDivIterativePlugin(genMul : Boolean = true,
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_EXECUTE_STAGE -> Bool(pipeline.stages.last == pipeline.execute),
BYPASSABLE_MEMORY_STAGE -> True,
RS1_USE -> True,
RS2_USE -> True
@ -69,21 +69,28 @@ class MulDivIterativePlugin(genMul : Boolean = true,
import pipeline.config._
if(!genMul && !genDiv) return
memory plug new Area {
import memory._
val flushStage = if(memory != null) memory else execute
flushStage plug new Area {
import flushStage._
//Shared ressources
val rs1 = Reg(UInt(33 bits))
val rs2 = Reg(UInt(32 bits))
val accumulator = Reg(UInt(65 bits))
//FrontendOK is only used for CPU configs without memory/writeback stages, were it is required to wait one extra cycle
// to let's the frontend process rs1 rs2 registers
val frontendOk = if(flushStage != execute) True else RegInit(False) setWhen(arbitration.isValid && !pipeline.service(classOf[HazardService]).hazardOnExecuteRS && ((if(genDiv) input(IS_DIV) else False) || (if(genMul) input(IS_MUL) else False))) clearWhen(arbitration.isMoving)
val mul = ifGen(genMul) (if(customMul != null) customMul(rs1,rs2,memory,pipeline) else new Area{
assert(isPow2(mulUnrollFactor))
val counter = Counter(32 / mulUnrollFactor + 1)
val done = counter.willOverflowIfInc
when(arbitration.isValid && input(IS_MUL)){
when(!done){
when(!frontendOk || !done){
arbitration.haltItself := True
}
when(frontendOk && !done){
arbitration.haltItself := True
counter.increment()
rs2 := rs2 |>> mulUnrollFactor
@ -112,8 +119,10 @@ class MulDivIterativePlugin(genMul : Boolean = true,
val done = Reg(Bool) setWhen(counter === counter.end-1) clearWhen(!arbitration.isStuck)
val result = Reg(Bits(32 bits))
when(arbitration.isValid && input(IS_DIV)){
when(!done){
when(!frontendOk || !done){
arbitration.haltItself := True
}
when(frontendOk && !done){
counter.increment()
def stages(inNumerator: UInt, inRemainder: UInt, stage: Int): Unit = stage match {
@ -139,16 +148,11 @@ class MulDivIterativePlugin(genMul : Boolean = true,
}
output(REGFILE_WRITE_DATA) := result
// when(input(INSTRUCTION)(13 downto 12) === "00" && counter === 0 && rs2 =/= 0 && rs1 < 16 && rs2 < 16 && !input(RS1).msb && !input(RS2).msb) {
// output(REGFILE_WRITE_DATA) := B(rs1(3 downto 0) / rs2(3 downto 0)).resized
// counter.willIncrement := False
// arbitration.haltItself := False
// }
}
})
//Execute stage logic to drive memory stage's input regs
when(!arbitration.isStuck){
when(if(flushStage != execute) !arbitration.isStuck else !frontendOk){
accumulator := 0
def twoComplement(that : Bits, enable: Bool): UInt = (Mux(enable, ~that, that).asUInt + enable.asUInt)
val rs2NeedRevert = execute.input(RS2).msb && execute.input(IS_RS2_SIGNED)

View File

@ -19,8 +19,8 @@ class MulSimplePlugin extends Plugin[VexRiscv]{
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> False,
BYPASSABLE_EXECUTE_STAGE -> Bool(pipeline.stages.last == pipeline.execute),
BYPASSABLE_MEMORY_STAGE -> Bool(pipeline.stages.last == pipeline.memory),
RS1_USE -> True,
RS2_USE -> True,
IS_MUL -> True
@ -66,14 +66,16 @@ class MulSimplePlugin extends Plugin[VexRiscv]{
insert(MUL_OPB) := ((bSigned ? b.msb | False) ## b).asSInt
}
memory plug new Area {
import memory._
val injectionStage = if(pipeline.memory != null) pipeline.memory else pipeline.execute
injectionStage plug new Area {
import injectionStage._
insert(MUL) := (input(MUL_OPA) * input(MUL_OPB))(63 downto 0).asBits
}
writeBack plug new Area {
import writeBack._
val memStage = stages.last
memStage plug new Area {
import memStage._
when(arbitration.isValid && input(IS_MUL)){
switch(input(INSTRUCTION)(13 downto 12)){

View File

@ -99,6 +99,35 @@ class MulDivDimension extends VexRiscvDimension("MulDiv") {
val noWriteBack = universes.contains(VexRiscvUniverse.NO_WRITEBACK)
var l = List[VexRiscvPosition]()
l = new VexRiscvPosition("MulDivFpgaSimple") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
config.plugins += new MulSimplePlugin
config.plugins += new MulDivIterativePlugin(
genMul = false,
genDiv = true,
mulUnrollFactor = 32,
divUnrollFactor = 1
)
}
} :: l
if(!noMemory && !noWriteBack) l = new VexRiscvPosition("MulDivFpga16BitsDsp") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
config.plugins += new Mul16Plugin
config.plugins += new MulDivIterativePlugin(
genMul = false,
genDiv = true,
mulUnrollFactor = 32,
divUnrollFactor = 1
)
}
} :: l
if(!noMemory) {
l = new VexRiscvPosition("MulDivAsic") {
override def testParam = "MUL=yes DIV=yes"
@ -376,7 +405,7 @@ class DBusDimension extends VexRiscvDimension("DBus") {
if(r.nextDouble() < 0.4 || noMemory || noWriteBack){
if(r.nextDouble() < 0.4 || noMemory){
val withLrSc = catchAll
val earlyInjection = r.nextBoolean() && !universes.contains(VexRiscvUniverse.NO_WRITEBACK)
new VexRiscvPosition("Simple" + (if(earlyInjection) "Early" else "Late")) {
@ -396,7 +425,8 @@ class DBusDimension extends VexRiscvDimension("DBus") {
var wayCount = 0
val withLrSc = catchAll
val withAmo = catchAll && r.nextBoolean()
val dBusRspSlavePipe, relaxedMemoryTranslationRegister, earlyWaysHits = r.nextBoolean()
val dBusRspSlavePipe, relaxedMemoryTranslationRegister = r.nextBoolean()
val earlyWaysHits = r.nextBoolean() && !noWriteBack
val dBusCmdMasterPipe, dBusCmdSlavePipe = false //As it create test bench issues
do{
@ -600,11 +630,11 @@ class TestIndividualFeatures extends FunSuite {
val testId : Option[mutable.HashSet[Int]] = None
val seed = sys.env.getOrElse("VEXRISCV_REGRESSION_SEED", Random.nextLong().toString).toLong
//
// val testId = Some(mutable.HashSet(3,4,9,11,13,16,18,19,20,21))
// val testId = Some(mutable.HashSet(24, 43, 49))
// val testId = Some(mutable.HashSet(11))
// val seed = -8309068850561113754l
// val testId = Some(mutable.HashSet(11))
// val testId = Some(mutable.HashSet(4, 11))
// val seed = 6592877339343561798l
val rand = new Random(seed)
@ -622,11 +652,16 @@ class TestIndividualFeatures extends FunSuite {
universe += VexRiscvUniverse.MMU
universe += VexRiscvUniverse.FORCE_MULDIV
universe += VexRiscvUniverse.SUPERVISOR
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEMW_RATE", "0.6").toDouble < rand.nextDouble()){
universe += VexRiscvUniverse.NO_WRITEBACK
}
} else {
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE", "0.5").toDouble > rand.nextDouble()) {
universe += VexRiscvUniverse.CATCH_ALL
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEMW_RATE", "0.6").toDouble < rand.nextDouble()){
universe += VexRiscvUniverse.NO_WRITEBACK
}
}
var tmp = rand.nextDouble()
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEMW_RATE", "0.6").toDouble > rand.nextDouble()){
}else if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEM_RATE", "0.5").toDouble > rand.nextDouble()){
universe += VexRiscvUniverse.NO_WRITEBACK