-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
1,122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#Ignore vivado project files generated by the tcl script | ||
**/.Xil/* | ||
**/reports/* | ||
**/*.cache/* | ||
**/*.hw/* | ||
**/*.ip_user_files/* | ||
**/*.runs/* | ||
**/*.sim/* | ||
**/*.srcs/* | ||
*.edf | ||
*.xpr | ||
*.jou | ||
*.log | ||
|
||
.cxl.* | ||
|
||
*_stub.v | ||
gmon.out | ||
|
||
/pulpissimo-nexys_video/**/pulpissimo.bit | ||
|
||
**/xdc/constraints.xdc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
include fpga-settings.mk | ||
|
||
PROJECT:=pulpissimo-$(BOARD) | ||
VIVADO ?= vivado | ||
|
||
.DEFAULT_GOAL:=help | ||
|
||
.PHONY: help all gui ips clean-ips clk clean-clk clean | ||
|
||
#Make sure BENDER environment variable is available for subprocesses in Make | ||
export BENDER | ||
|
||
all: ips ## Generate the bitstream for pulpissimo with vivado in batch mode. The vivado invocation command may be overriden with the env variable VIVADO. | ||
$(VIVADO) -mode batch -source tcl/run.tcl | ||
|
||
gui: ips ## Generates the bitstream for pulpissimo with vivado in GUI mode. The vivado invocation command may be overriden with the env variable VIVADO. | ||
$(VIVADO) -mode gui -source tcl/run.tcl & | ||
|
||
ips: clk ## Synthesizes necessary xilinx IP | ||
|
||
clean-ips: clean-clk ## Clean all IPs | ||
|
||
clk: ## Synthesizes the Xilinx Clocking Manager IPs | ||
$(MAKE) -C ips/xilinx_clk_mngr all | ||
$(MAKE) -C ips/xilinx_slow_clk_mngr all | ||
|
||
clean-clk: ## Removes all Clocking Wizard IP outputs | ||
$(MAKE) -C ips/xilinx_clk_mngr clean | ||
$(MAKE) -C ips/xilinx_slow_clk_mngr clean | ||
|
||
clean: clean-ips ## Removes all bitstreams, *.log files and vivado related files (rm -rf vivado*) | ||
rm -rf ${PROJECT}.*[^'bit'] | ||
rm -rf ${PROJECT}.*[^'bin'] | ||
rm -rf *.log | ||
rm -rf vivado* | ||
|
||
download: ## Download the bitstream into the FPGA | ||
$(VIVADO) -mode batch -source tcl/download_bitstream.tcl -tclargs $(PROJECT).runs/impl_1/xilinx_pulpissimo.bit pulpissimo_$(BOARD).bit | ||
|
||
help: | ||
@grep -E -h '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# PULPissimo on the ZyboZ7 | ||
[\[Documentation\]](https://digilent.com/reference/programmable-logic/zybo-z7/start) | ||
|
||
## Bitstream Generation | ||
In the `fpga` folder, run | ||
```Shell | ||
make zyboz7 | ||
``` | ||
which will generate `pulpissimo_zyboz7.bit`. | ||
|
||
## Bitstream Download | ||
To download this bitstream into the FPGA connect the PROG USB header, turn the board on and run | ||
```Shell | ||
make -C pulpissimo-zyboz7 download | ||
``` | ||
|
||
TODO | ||
|
||
|
||
## Default Frequencies | ||
|
||
By default the clock generating IPs are synthesized from the 100 MHz input (IC17 via Y9) to provide the following frequencies to PULPissimo. | ||
The SoC Frequency is fed into all peripherals as `periph_clk_i`. | ||
|
||
| Clock Domain | Frequency | | ||
|----------------|-----------| | ||
| Core Frequency | 20 MHz | | ||
| SoC Frequency | 10 MHz | | ||
|
||
|
||
## Peripherals | ||
If in doubt please review constraint file for current peripheral mapping in `constraints/zedboard.xdc`. | ||
|
||
### Reset Button | ||
The BTNC is connected as reset button. | ||
|
||
### JTAG | ||
Since there is no way of connecting the RISC-V core to the on-board FTDI USB JTAG programmer you have to attach an external device PMOD A to do so. | ||
|
||
| JTAG Signal | PMOD Pin | | ||
|-------------|----------| | ||
| TMS | JA1 | | ||
| TDI | JA2 | | ||
| TDO | JA3 | | ||
| TCK | JA4 | | ||
| GND | JA5 | | ||
| VCC (trgt) | JA6 | | ||
|
||
The directory holding this README contains OpenOCD configuration files for some known-working adapters. | ||
The commands below are to be executed from within the `fpga` directory. | ||
|
||
#### Digilent HS-2 | ||
|
||
The HS-2 uses the same FTDI chip as the ZedBoard's JTAG port. | ||
So to make it work change the serial number in provided | ||
`openocd-zedboard-hs2.cfg` if you want to have it connected simultaneously with ZedBoard. If you have | ||
Vivado running remember to disconnect the target and close HW Manager before attempting to use OpenOCD. | ||
Otherwise there will be an error about target being busy. | ||
|
||
```Shell | ||
$OPENOCD/bin/openocd -f pulpissimo-zedboard/openocd-zedboard-hs2.cfg | ||
``` | ||
|
||
#### Altera USB Blaster | ||
|
||
After connecting the adapter with 6 jumper wires, simply run: | ||
|
||
```Shell | ||
$OPENOCD/bin/openocd -f pulpissimo-zedboard/openocd-zedboard-usbblaster.cfg | ||
``` | ||
|
||
### UART | ||
|
||
There are UART pins connected to the same PMOD as the JTAG signals (PMOD A), which are utilized by the stdio driver of the PULP SDK (e.g., for the hello example). | ||
The following list depicts the signals (from the FPGA's point of view). | ||
|
||
| UART Signal | PMOD Pin | | ||
|-------------|----------| | ||
| RXD | JA7 | | ||
| TXD | JA8 | | ||
| RTS | JA9 | | ||
| CTS | JA10 | | ||
| GND | JA11 | | ||
|
||
### I2C | ||
|
||
Two pairs of I2C signals are available on PMOD B: | ||
|
||
| Signal | PMOD Pin | | ||
|-----------|----------| | ||
| I2C0_SCL | JB1 | | ||
| I2C0_SDA | JB2 | | ||
| I2C1_SCL | JB3 | | ||
| I2C1_SDA | JB4 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
####################################### | ||
# _______ _ _ # | ||
# |__ __(_) (_) # | ||
# | | _ _ __ ___ _ _ __ __ _ # | ||
# | | | | '_ ` _ \| | '_ \ / _` | # | ||
# | | | | | | | | | | | | | (_| | # | ||
# |_| |_|_| |_| |_|_|_| |_|\__, | # | ||
# __/ | # | ||
# |___/ # | ||
####################################### | ||
|
||
|
||
#Create constraint for the clock input of the ZyboZ7 | ||
create_clock -period 8.000 -name ref_clk_i [get_ports ref_clk_i] | ||
set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets ref_clk] | ||
|
||
## JTAG | ||
create_clock -period 100.000 -name tck -waveform {0.000 50.000} [get_ports pad_jtag_tck] | ||
set_input_jitter tck 1.000 | ||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets i_pulpissimo/i_padframe/i_pulpissimo_pads/i_all_pads/i_all_pads_pads/i_pad_jtag_tck/O] | ||
|
||
|
||
# minimize routing delay | ||
set_input_delay -clock tck -clock_fall 5.000 [get_ports pad_jtag_tdi] | ||
set_input_delay -clock tck -clock_fall 5.000 [get_ports pad_jtag_tms] | ||
set_output_delay -clock tck 5.000 [get_ports pad_jtag_tdo] | ||
|
||
set_max_delay -to [get_ports pad_jtag_tdo] 20.000 | ||
set_max_delay -from [get_ports pad_jtag_tms] 20.000 | ||
set_max_delay -from [get_ports pad_jtag_tdi] 20.000 | ||
|
||
set_max_delay -datapath_only -from [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/data_src_q_reg*/C] -to [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/data_dst_q_reg*/D] 20.000 | ||
set_max_delay -datapath_only -from [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/req_src_q_reg/C] -to [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/req_dst_q_reg/D] 20.000 | ||
set_max_delay -datapath_only -from [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_dst/ack_dst_q_reg/C] -to [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_src/ack_src_q_reg/D] 20.000 | ||
|
||
|
||
# reset signal | ||
set_false_path -from [get_ports pad_reset] | ||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets pad_reset_n_IBUF] | ||
|
||
set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets i_pulpissimo/i_clock_gen/i_slow_clk_div/i_clk_mux/clk_o] | ||
set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets i_pulpissimo/i_clock_gen/i_slow_clk_mngr/inst/clk_out1] | ||
|
||
# increase MTBF | ||
set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_adv_timer/u_tim0/u_in_stage/r_ls_clk_sync_reg*] | ||
set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_adv_timer/u_tim1/u_in_stage/r_ls_clk_sync_reg*] | ||
set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_adv_timer/u_tim2/u_in_stage/r_ls_clk_sync_reg*] | ||
set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_adv_timer/u_tim3/u_in_stage/r_ls_clk_sync_reg*] | ||
set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_timer_unit/s_ref_clk*] | ||
set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_ref_clk_sync/i_pulp_sync/r_reg_reg*] | ||
set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/u_evnt_gen/r_ls_sync_reg*] | ||
|
||
# Create asynchronous clock group between slow-clk and SoC clock. Those clocks | ||
# are considered asynchronously and proper synchronization regs are in place | ||
set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/slow_clk_o]] \ | ||
-group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/i_clk_manager/clk_out1]] | ||
|
||
# Create asynchronous clock group between Per Clock and SoC clock. Those clocks | ||
# are considered asynchronously and proper synchronization regs are in place | ||
set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/i_clk_manager/clk_out1]] \ | ||
-group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/i_clk_manager/clk_out2]] | ||
|
||
# Create asynchronous clock group between JTAG TCK and SoC clock. | ||
set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/pad_jtag_tck]] \ | ||
-group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/i_clk_manager/clk_out1]] | ||
|
||
# Create asynchronous clock group between JTAG TCK and per clock. | ||
set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/pad_jtag_tck]] \ | ||
-group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/i_clk_manager/clk_out2]] | ||
|
||
# Create asynchronous clock group between slow clock and JTAG TCK. | ||
set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/slow_clk_o]] \ | ||
-group [get_clocks -of_objects [get_pins i_pulpissimo/pad_jtag_tck]] | ||
|
||
############################################################# | ||
# _____ ____ _____ _ _ _ # | ||
# |_ _/ __ \ / ____| | | | | (_) # | ||
# | || | | |_____| (___ ___| |_| |_ _ _ __ __ _ ___ # | ||
# | || | | |______\___ \ / _ \ __| __| | '_ \ / _` / __| # | ||
# _| || |__| | ____) | __/ |_| |_| | | | | (_| \__ \ # | ||
# |_____\____/ |_____/ \___|\__|\__|_|_| |_|\__, |___/ # | ||
# __/ | # | ||
# |___/ # | ||
############################################################# | ||
|
||
## Sys clock | ||
set_property -dict {PACKAGE_PIN K17 IOSTANDARD LVCMOS33} [get_ports ref_clk_i] | ||
|
||
## Reset | ||
set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports pad_reset] | ||
|
||
## Buttons | ||
set_property -dict {PACKAGE_PIN P16 IOSTANDARD LVCMOS33} [get_ports btn1_i] | ||
set_property -dict {PACKAGE_PIN K19 IOSTANDARD LVCMOS33} [get_ports btn2_i] | ||
set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVCMOS33} [get_ports btn3_i] | ||
|
||
## PMOD JE | ||
set_property -dict {PACKAGE_PIN V12 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tms] | ||
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdi] | ||
set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdo] | ||
set_property -dict {PACKAGE_PIN H15 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tck] | ||
set_property -dict {PACKAGE_PIN V13 IOSTANDARD LVCMOS33} [get_ports pad_uart_rx] | ||
set_property -dict {PACKAGE_PIN U17 IOSTANDARD LVCMOS33} [get_ports pad_uart_tx] | ||
set_property -dict {PACKAGE_PIN T17 IOSTANDARD LVCMOS33} [get_ports pad_uart_rts] | ||
set_property -dict {PACKAGE_PIN Y17 IOSTANDARD LVCMOS33} [get_ports pad_uart_cts] | ||
|
||
## PMOD JB | ||
set_property -dict {PACKAGE_PIN V8 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_1] | ||
set_property -dict {PACKAGE_PIN W8 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_2] | ||
set_property -dict {PACKAGE_PIN U7 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_3] | ||
set_property -dict {PACKAGE_PIN V7 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_4] | ||
set_property -dict {PACKAGE_PIN Y7 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_7] | ||
set_property -dict {PACKAGE_PIN Y6 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_8] | ||
set_property -dict {PACKAGE_PIN V6 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_9] | ||
set_property -dict {PACKAGE_PIN W6 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_10] | ||
|
||
## LEDs | ||
set_property -dict {PACKAGE_PIN M14 IOSTANDARD LVCMOS33} [get_ports led0_o] | ||
set_property -dict {PACKAGE_PIN M15 IOSTANDARD LVCMOS33} [get_ports led1_o] | ||
set_property -dict {PACKAGE_PIN G14 IOSTANDARD LVCMOS33} [get_ports led2_o] | ||
set_property -dict {PACKAGE_PIN D18 IOSTANDARD LVCMOS33} [get_ports led3_o] | ||
|
||
## PMOD JC | ||
set_property -dict {PACKAGE_PIN V15 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_1] | ||
set_property -dict {PACKAGE_PIN W15 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_2] | ||
set_property -dict {PACKAGE_PIN T11 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_3] | ||
set_property -dict {PACKAGE_PIN T10 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_4] | ||
set_property -dict {PACKAGE_PIN W14 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_7] | ||
set_property -dict {PACKAGE_PIN Y14 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_8] | ||
set_property -dict {PACKAGE_PIN T12 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_9] | ||
set_property -dict {PACKAGE_PIN U12 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_10] | ||
|
||
## PMOD JD | ||
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports pad_pmodd_1] | ||
set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports test_clk_o] | ||
set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVCMOS33} [get_ports obs1_o] | ||
set_property -dict {PACKAGE_PIN R14 IOSTANDARD LVCMOS33} [get_ports obs2_o] | ||
|
||
## Switches | ||
set_property -dict {PACKAGE_PIN G15 IOSTANDARD LVCMOS33} [get_ports switch0_i] | ||
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports switch1_i] | ||
set_property -dict {PACKAGE_PIN W13 IOSTANDARD LVCMOS33} [get_ports switch2_i] | ||
set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports switch3_i] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export BOARD=zyboz7 | ||
export XILINX_PART=xc7z020clg400-1 | ||
export XILINX_BOARD=digilentinc.com:zybo-z7-20:part0:1.0 | ||
export FC_CLK_PERIOD_NS=62.5 | ||
export PER_CLK_PERIOD_NS=100 | ||
export SLOW_CLK_PERIOD_NS=30517 | ||
$(info Setting environment variables for $(BOARD) board) |
21 changes: 21 additions & 0 deletions
21
target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#Ignore vivado project files generated by the tcl script | ||
**/.Xil/* | ||
**/reports/* | ||
**/*.cache/* | ||
**/*.hw/* | ||
**/*.ip_user_files/* | ||
**/*.runs/* | ||
**/*.sim/* | ||
**/*.srcs/* | ||
*.edf | ||
*.xpr | ||
*.jou | ||
*.log | ||
|
||
.cxl.* | ||
|
||
*ip | ||
|
||
*_stub.v | ||
gmon.out | ||
|
32 changes: 32 additions & 0 deletions
32
target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
PROJECT:=xilinx_clk_mngr | ||
VIVADO ?= vivado | ||
VIVADOFLAGS ?= -nojournal -mode batch -source scripts/prologue.tcl | ||
MODE=batch | ||
|
||
include ../../fpga-settings.mk | ||
|
||
.DEFAULT_GOAL:=help | ||
|
||
.PHONY: help all gui clean | ||
|
||
all: MODE=batch ## Create and synthesize the IP in batch mode. | ||
|
||
gui: MODE=gui ## Create and synthesize the IP in GUI mode. | ||
|
||
all gui: $(PROJECT).xpr | ||
|
||
$(PROJECT).xpr: ../../fpga-settings.mk tcl/run.tcl | ||
$(MAKE) clean | ||
$(VIVADO) -mode $(MODE) -source tcl/run.tcl | ||
|
||
clean: ## Remove all build products | ||
rm -rf ${PROJECT}.* | ||
rm -rf component.xml | ||
rm -rf vivado*.jou | ||
rm -rf vivado*.log | ||
rm -rf vivado*.str | ||
rm -rf xgui | ||
rm -rf .Xil | ||
|
||
help: ## Shows this help message | ||
@grep -E -h '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' |
Oops, something went wrong.